b43bcc252823922ab95222f4fee6ae47cb24d59b
[openwrt.git] / target / linux / xburst / patches-2.6.34 / 001-core.patch
1 From 7efb2cae3df49ba749860a0df04933dc522da224 Mon Sep 17 00:00:00 2001
2 From: Lars-Peter Clausen <lars@metafoo.de>
3 Date: Sat, 24 Apr 2010 17:35:05 +0200
4 Subject: [PATCH] Add JZ4740 SoC core support
5
6 ---
7  arch/mips/Kconfig                            |    4 +
8  arch/mips/Makefile                           |    6 +
9  arch/mips/include/asm/bootinfo.h             |    6 +
10  arch/mips/include/asm/cpu.h                  |   13 +-
11  arch/mips/include/asm/mach-jz4740/base.h     |   28 +
12  arch/mips/include/asm/mach-jz4740/clock.h    |   28 +
13  arch/mips/include/asm/mach-jz4740/dma.h      |   90 +++
14  arch/mips/include/asm/mach-jz4740/gpio.h     |  398 +++++++++++
15  arch/mips/include/asm/mach-jz4740/irq.h      |   55 ++
16  arch/mips/include/asm/mach-jz4740/platform.h |   34 +
17  arch/mips/include/asm/mach-jz4740/serial.h   |   30 +
18  arch/mips/include/asm/mach-jz4740/timer.h    |   22 +
19  arch/mips/include/asm/mach-jz4740/war.h      |   25 +
20  arch/mips/jz4740/Kconfig                     |   29 +
21  arch/mips/jz4740/Makefile                    |   17 +
22  arch/mips/jz4740/clock-debugfs.c             |  109 +++
23  arch/mips/jz4740/clock.c                     |  935 ++++++++++++++++++++++++++
24  arch/mips/jz4740/clock.h                     |   75 ++
25  arch/mips/jz4740/dma.c                       |  339 ++++++++++
26  arch/mips/jz4740/gpio.c                      |  598 ++++++++++++++++
27  arch/mips/jz4740/irq.c                       |  174 +++++
28  arch/mips/jz4740/irq.h                       |   21 +
29  arch/mips/jz4740/platform.c                  |  246 +++++++
30  arch/mips/jz4740/pm.c                        |   59 ++
31  arch/mips/jz4740/prom.c                      |   69 ++
32  arch/mips/jz4740/pwm.c                       |  167 +++++
33  arch/mips/jz4740/reset.c                     |   81 +++
34  arch/mips/jz4740/reset.h                     |    7 +
35  arch/mips/jz4740/setup.c                     |   64 ++
36  arch/mips/jz4740/time.c                      |  145 ++++
37  arch/mips/jz4740/timer.c                     |   45 ++
38  arch/mips/jz4740/timer.h                     |  130 ++++
39  arch/mips/kernel/cpu-probe.c                 |   20 +
40  arch/mips/mm/tlbex.c                         |    5 +
41  34 files changed, 4073 insertions(+), 1 deletions(-)
42  create mode 100644 arch/mips/include/asm/mach-jz4740/base.h
43  create mode 100644 arch/mips/include/asm/mach-jz4740/clock.h
44  create mode 100644 arch/mips/include/asm/mach-jz4740/dma.h
45  create mode 100644 arch/mips/include/asm/mach-jz4740/gpio.h
46  create mode 100644 arch/mips/include/asm/mach-jz4740/irq.h
47  create mode 100644 arch/mips/include/asm/mach-jz4740/platform.h
48  create mode 100644 arch/mips/include/asm/mach-jz4740/serial.h
49  create mode 100644 arch/mips/include/asm/mach-jz4740/timer.h
50  create mode 100644 arch/mips/include/asm/mach-jz4740/war.h
51  create mode 100644 arch/mips/jz4740/Kconfig
52  create mode 100644 arch/mips/jz4740/Makefile
53  create mode 100644 arch/mips/jz4740/clock-debugfs.c
54  create mode 100644 arch/mips/jz4740/clock.c
55  create mode 100644 arch/mips/jz4740/clock.h
56  create mode 100644 arch/mips/jz4740/dma.c
57  create mode 100644 arch/mips/jz4740/gpio.c
58  create mode 100644 arch/mips/jz4740/irq.c
59  create mode 100644 arch/mips/jz4740/irq.h
60  create mode 100644 arch/mips/jz4740/platform.c
61  create mode 100644 arch/mips/jz4740/pm.c
62  create mode 100644 arch/mips/jz4740/prom.c
63  create mode 100644 arch/mips/jz4740/pwm.c
64  create mode 100644 arch/mips/jz4740/reset.c
65  create mode 100644 arch/mips/jz4740/reset.h
66  create mode 100644 arch/mips/jz4740/setup.c
67  create mode 100644 arch/mips/jz4740/time.c
68  create mode 100644 arch/mips/jz4740/timer.c
69  create mode 100644 arch/mips/jz4740/timer.h
70
71 diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
72 index 7e6fd1c..e902f02 100644
73 --- a/arch/mips/Kconfig
74 +++ b/arch/mips/Kconfig
75 @@ -162,6 +162,9 @@ config MACH_JAZZ
76          Members include the Acer PICA, MIPS Magnum 4000, MIPS Millennium and
77          Olivetti M700-10 workstations.
78  
79 +config MACH_JZ
80 +       bool "Ingenic JZ4720/JZ4740 based machines"
81 +
82  config LASAT
83         bool "LASAT Networks platforms"
84         select CEVT_R4K
85 @@ -686,6 +689,7 @@ endchoice
86  source "arch/mips/alchemy/Kconfig"
87  source "arch/mips/bcm63xx/Kconfig"
88  source "arch/mips/jazz/Kconfig"
89 +source "arch/mips/jz4740/Kconfig"
90  source "arch/mips/lasat/Kconfig"
91  source "arch/mips/pmc-sierra/Kconfig"
92  source "arch/mips/powertv/Kconfig"
93 diff --git a/arch/mips/Makefile b/arch/mips/Makefile
94 index 0b9c01a..007a82e 100644
95 --- a/arch/mips/Makefile
96 +++ b/arch/mips/Makefile
97 @@ -659,6 +659,12 @@ else
98  load-$(CONFIG_CPU_CAVIUM_OCTEON)       += 0xffffffff81100000
99  endif
100  
101 +# Ingenic JZ4740
102 +#
103 +core-$(CONFIG_SOC_JZ4740)  += arch/mips/jz4740/
104 +cflags-$(CONFIG_SOC_JZ4740)    += -I$(srctree)/arch/mips/include/asm/mach-jz4740
105 +load-$(CONFIG_SOC_JZ4740)  += 0xffffffff80010000
106 +
107  cflags-y                       += -I$(srctree)/arch/mips/include/asm/mach-generic
108  drivers-$(CONFIG_PCI)          += arch/mips/pci/
109  
110 diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
111 index 09eee09..15a8ef0 100644
112 --- a/arch/mips/include/asm/bootinfo.h
113 +++ b/arch/mips/include/asm/bootinfo.h
114 @@ -71,6 +71,12 @@
115  #define MACH_LEMOTE_LL2F       7
116  #define MACH_LOONGSON_END      8
117  
118 +/*
119 + * Valid machtype for group INGENIC
120 + */
121 +#define  MACH_INGENIC_JZ4730   0       /* JZ4730 SOC           */
122 +#define  MACH_INGENIC_JZ4740   1       /* JZ4740 SOC           */
123 +
124  extern char *system_type;
125  const char *get_system_type(void);
126  
127 diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
128 index a5acda4..e67aebb 100644
129 --- a/arch/mips/include/asm/cpu.h
130 +++ b/arch/mips/include/asm/cpu.h
131 @@ -34,7 +34,7 @@
132  #define PRID_COMP_LSI          0x080000
133  #define PRID_COMP_LEXRA                0x0b0000
134  #define PRID_COMP_CAVIUM       0x0d0000
135 -
136 +#define PRID_COMP_INGENIC      0xd00000
137  
138  /*
139   * Assigned values for the product ID register.  In order to detect a
140 @@ -133,6 +133,12 @@
141  #define PRID_IMP_CAVIUM_CN52XX 0x0700
142  
143  /*
144 + * These are the PRID's for when 23:16 == PRID_COMP_INGENIC
145 + */
146 +
147 +#define PRID_IMP_JZRISC        0x0200
148 +
149 +/*
150   * Definitions for 7:0 on legacy processors
151   */
152  
153 @@ -226,6 +232,11 @@ enum cpu_type_enum {
154         CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2,
155         CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS,
156  
157 +       /*
158 +        * Ingenic class processors
159 +        */
160 +       CPU_JZRISC, CPU_XBURST,
161 +
162         CPU_LAST
163  };
164  
165 diff --git a/arch/mips/include/asm/mach-jz4740/base.h b/arch/mips/include/asm/mach-jz4740/base.h
166 new file mode 100644
167 index 0000000..a281972
168 --- /dev/null
169 +++ b/arch/mips/include/asm/mach-jz4740/base.h
170 @@ -0,0 +1,28 @@
171 +#ifndef __JZ4740_BASE_ADDR_H__
172 +#define __JZ4740_BASE_ADDR_H__
173 +
174 +#define        JZ4740_CPM_BASE_ADDR    0xb0000000
175 +#define        JZ4740_INTC_BASE_ADDR   0xb0001000
176 +#define        JZ4740_TCU_BASE_ADDR    0xb0002000
177 +#define        JZ4740_WDT_BASE_ADDR    0xb0002000
178 +#define        JZ4740_RTC_BASE_ADDR    0xb0003000
179 +#define        JZ4740_GPIO_BASE_ADDR   0xb0010000
180 +#define        JZ4740_AIC_BASE_ADDR    0xb0020000
181 +#define        JZ4740_ICDC_BASE_ADDR   0xb0020000
182 +#define        JZ4740_MSC_BASE_ADDR    0xb0021000
183 +#define        JZ4740_UART0_BASE_ADDR  0xb0030000
184 +#define        JZ4740_UART1_BASE_ADDR  0xb0031000
185 +#define        JZ4740_I2C_BASE_ADDR    0xb0042000
186 +#define        JZ4740_SSI_BASE_ADDR    0xb0043000
187 +#define        JZ4740_SADC_BASE_ADDR   0xb0070000
188 +#define        JZ4740_EMC_BASE_ADDR    0xb3010000
189 +#define        JZ4740_DMAC_BASE_ADDR   0xb3020000
190 +#define        JZ4740_UHC_BASE_ADDR    0xb3030000
191 +#define        JZ4740_UDC_BASE_ADDR    0xb3040000
192 +#define        JZ4740_LCD_BASE_ADDR    0xb3050000
193 +#define        JZ4740_SLCD_BASE_ADDR   0xb3050000
194 +#define        JZ4740_CIM_BASE_ADDR    0xb3060000
195 +#define JZ4740_IPU_BASE_ADDR   0xb3080000
196 +#define        JZ4740_ETH_BASE_ADDR    0xb3100000
197 +
198 +#endif
199 diff --git a/arch/mips/include/asm/mach-jz4740/clock.h b/arch/mips/include/asm/mach-jz4740/clock.h
200 new file mode 100644
201 index 0000000..9069727
202 --- /dev/null
203 +++ b/arch/mips/include/asm/mach-jz4740/clock.h
204 @@ -0,0 +1,28 @@
205 +/*
206 + *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
207 + *
208 + *  This program is free software; you can redistribute         it and/or modify it
209 + *  under  the terms of         the GNU General  Public License as published by the
210 + *  Free Software Foundation;  either version 2 of the License, or (at your
211 + *  option) any later version.
212 + *
213 + *  You should have received a copy of the  GNU General Public License along
214 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
215 + *  675 Mass Ave, Cambridge, MA 02139, USA.
216 + *
217 + */
218 +
219 +#ifndef __ASM_JZ4740_CLOCK_H__
220 +#define __ASM_JZ4740_CLOCK_H__
221 +
222 +enum jz4740_wait_mode {
223 +       JZ4740_WAIT_MODE_IDLE,
224 +       JZ4740_WAIT_MODE_SLEEP,
225 +};
226 +
227 +void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode);
228 +
229 +void jz4740_clock_udc_enable_auto_suspend(void);
230 +void jz4740_clock_udc_disable_auto_suspend(void);
231 +
232 +#endif
233 diff --git a/arch/mips/include/asm/mach-jz4740/dma.h b/arch/mips/include/asm/mach-jz4740/dma.h
234 new file mode 100644
235 index 0000000..d31d4e0
236 --- /dev/null
237 +++ b/arch/mips/include/asm/mach-jz4740/dma.h
238 @@ -0,0 +1,90 @@
239 +/*
240 + *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
241 + *  JZ7420/JZ4740 DMA definitions
242 + *
243 + *  This program is free software; you can redistribute         it and/or modify it
244 + *  under  the terms of         the GNU General  Public License as published by the
245 + *  Free Software Foundation;  either version 2 of the License, or (at your
246 + *  option) any later version.
247 + *
248 + *  You should have received a copy of the  GNU General Public License along
249 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
250 + *  675 Mass Ave, Cambridge, MA 02139, USA.
251 + *
252 + */
253 +
254 +#ifndef __ASM_MACH_JZ4740_DMA_H__
255 +#define __ASM_MACH_JZ4740_DMA_H__
256 +
257 +struct jz4740_dma_chan;
258 +
259 +enum jz4740_dma_request_type {
260 +       JZ4740_DMA_TYPE_AUTO_REQUEST =   8,
261 +       JZ4740_DMA_TYPE_UART_TRANSMIT = 20,
262 +       JZ4740_DMA_TYPE_UART_RECEIVE =  21,
263 +       JZ4740_DMA_TYPE_SPI_TRANSMIT =  22,
264 +       JZ4740_DMA_TYPE_SPI_RECEIVE =   23,
265 +       JZ4740_DMA_TYPE_AIC_TRANSMIT =  24,
266 +       JZ4740_DMA_TYPE_AIC_RECEIVE =   25,
267 +       JZ4740_DMA_TYPE_MMC_TRANSMIT =  26,
268 +       JZ4740_DMA_TYPE_MMC_RECEIVE =   27,
269 +       JZ4740_DMA_TYPE_TCU =           28,
270 +       JZ4740_DMA_TYPE_SADC =          29,
271 +       JZ4740_DMA_TYPE_SLCD =          30,
272 +};
273 +
274 +enum jz4740_dma_width {
275 +       JZ4740_DMA_WIDTH_8BIT,
276 +       JZ4740_DMA_WIDTH_16BIT,
277 +       JZ4740_DMA_WIDTH_32BIT,
278 +};
279 +
280 +enum jz4740_dma_transfer_size {
281 +       JZ4740_DMA_TRANSFER_SIZE_4BYTE  = 0,
282 +       JZ4740_DMA_TRANSFER_SIZE_1BYTE  = 1,
283 +       JZ4740_DMA_TRANSFER_SIZE_2BYTE  = 2,
284 +       JZ4740_DMA_TRANSFER_SIZE_16BYTE = 3,
285 +       JZ4740_DMA_TRANSFER_SIZE_32BYTE = 4,
286 +};
287 +
288 +enum jz4740_dma_flags {
289 +       JZ4740_DMA_SRC_AUTOINC = 0x2,
290 +       JZ4740_DMA_DST_AUTOINC = 0x1,
291 +};
292 +
293 +enum jz4740_dma_mode {
294 +       JZ4740_DMA_MODE_SINGLE = 0,
295 +       JZ4740_DMA_MODE_BLOCK = 1,
296 +};
297 +
298 +struct jz4740_dma_config {
299 +       enum jz4740_dma_width src_width;
300 +       enum jz4740_dma_width dst_width;
301 +       enum jz4740_dma_transfer_size transfer_size;
302 +       enum jz4740_dma_request_type request_type;
303 +       enum jz4740_dma_flags flags;
304 +       enum jz4740_dma_mode mode;
305 +};
306 +
307 +typedef void (*jz4740_dma_complete_callback_t)(struct jz4740_dma_chan *, int, void *);
308 +
309 +struct jz4740_dma_chan *jz4740_dma_request(void *dev, const char *name);
310 +void jz4740_dma_free(struct jz4740_dma_chan *dma);
311 +
312 +void jz4740_dma_configure(struct jz4740_dma_chan *dma,
313 +       const struct jz4740_dma_config *config);
314 +
315 +
316 +void jz4740_dma_enable(struct jz4740_dma_chan *dma);
317 +void jz4740_dma_disable(struct jz4740_dma_chan *dma);
318 +
319 +void jz4740_dma_set_src_addr(struct jz4740_dma_chan *dma, dma_addr_t src);
320 +void jz4740_dma_set_dst_addr(struct jz4740_dma_chan *dma, dma_addr_t dst);
321 +void jz4740_dma_set_transfer_count(struct jz4740_dma_chan *dma, uint32_t count);
322 +
323 +uint32_t jz4740_dma_get_residue(const struct jz4740_dma_chan *dma);
324 +
325 +void jz4740_dma_set_complete_cb(struct jz4740_dma_chan *dma,
326 +       jz4740_dma_complete_callback_t cb);
327 +
328 +#endif  /* __ASM_JZ4740_DMA_H__ */
329 diff --git a/arch/mips/include/asm/mach-jz4740/gpio.h b/arch/mips/include/asm/mach-jz4740/gpio.h
330 new file mode 100644
331 index 0000000..5f175d7
332 --- /dev/null
333 +++ b/arch/mips/include/asm/mach-jz4740/gpio.h
334 @@ -0,0 +1,398 @@
335 +/*
336 + *  Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
337 + *  JZ7420/JZ4740 GPIO pin definitions
338 + *
339 + *  This program is free software; you can redistribute         it and/or modify it
340 + *  under  the terms of         the GNU General  Public License as published by the
341 + *  Free Software Foundation;  either version 2 of the License, or (at your
342 + *  option) any later version.
343 + *
344 + *  You should have received a copy of the  GNU General Public License along
345 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
346 + *  675 Mass Ave, Cambridge, MA 02139, USA.
347 + *
348 + */
349 +
350 +#ifndef _JZ_GPIO_H
351 +#define _JZ_GPIO_H
352 +
353 +#include <linux/types.h>
354 +
355 +enum jz_gpio_function {
356 +    JZ_GPIO_FUNC_NONE,
357 +    JZ_GPIO_FUNC1,
358 +    JZ_GPIO_FUNC2,
359 +    JZ_GPIO_FUNC3,
360 +};
361 +
362 +
363 +/*
364 + Usually a driver for a SoC component has to request several gpio pins and
365 + configure them as funcion pins.
366 + jz_gpio_bulk_request can be used to ease this process.
367 + Usually one would do something like:
368 +
369 + const static struct jz_gpio_bulk_request i2c_pins[] = {
370 +       JZ_GPIO_BULK_PIN(I2C_SDA),
371 +       JZ_GPIO_BULK_PIN(I2C_SCK),
372 + };
373 +
374 + inside the probe function:
375 +
376 +    ret = jz_gpio_bulk_request(i2c_pins, ARRAY_SIZE(i2c_pins));
377 +    if (ret) {
378 +       ...
379 +
380 + inside the remove function:
381 +
382 +    jz_gpio_bulk_free(i2c_pins, ARRAY_SIZE(i2c_pins));
383 +
384 +
385 +*/
386 +struct jz_gpio_bulk_request {
387 +       int gpio;
388 +       const char *name;
389 +       enum jz_gpio_function function;
390 +};
391 +
392 +#define JZ_GPIO_BULK_PIN(pin) { \
393 +    .gpio = JZ_GPIO_ ## pin, \
394 +    .name = #pin, \
395 +    .function = JZ_GPIO_FUNC_ ## pin \
396 +}
397 +
398 +int jz_gpio_bulk_request(const struct jz_gpio_bulk_request *request, size_t num);
399 +void jz_gpio_bulk_free(const struct jz_gpio_bulk_request *request, size_t num);
400 +void jz_gpio_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num);
401 +void jz_gpio_bulk_resume(const struct jz_gpio_bulk_request *request, size_t num);
402 +void jz_gpio_enable_pullup(unsigned gpio);
403 +void jz_gpio_disable_pullup(unsigned gpio);
404 +int jz_gpio_set_function(int gpio, enum jz_gpio_function function);
405 +
406 +int jz_gpio_port_direction_input(int port, uint32_t mask);
407 +int jz_gpio_port_direction_output(int port, uint32_t mask);
408 +void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask);
409 +uint32_t jz_gpio_port_get_value(int port, uint32_t mask);
410 +
411 +#include <asm/mach-generic/gpio.h>
412 +
413 +#define JZ_GPIO_PORTA(x) ((x) + 32 * 0)
414 +#define JZ_GPIO_PORTB(x) ((x) + 32 * 1)
415 +#define JZ_GPIO_PORTC(x) ((x) + 32 * 2)
416 +#define JZ_GPIO_PORTD(x) ((x) + 32 * 3)
417 +
418 +/* Port A function pins */
419 +#define JZ_GPIO_MEM_DATA0              JZ_GPIO_PORTA(0)
420 +#define JZ_GPIO_MEM_DATA1              JZ_GPIO_PORTA(1)
421 +#define JZ_GPIO_MEM_DATA2              JZ_GPIO_PORTA(2)
422 +#define JZ_GPIO_MEM_DATA3              JZ_GPIO_PORTA(3)
423 +#define JZ_GPIO_MEM_DATA4              JZ_GPIO_PORTA(4)
424 +#define JZ_GPIO_MEM_DATA5              JZ_GPIO_PORTA(5)
425 +#define JZ_GPIO_MEM_DATA6              JZ_GPIO_PORTA(6)
426 +#define JZ_GPIO_MEM_DATA7              JZ_GPIO_PORTA(7)
427 +#define JZ_GPIO_MEM_DATA8              JZ_GPIO_PORTA(8)
428 +#define JZ_GPIO_MEM_DATA9              JZ_GPIO_PORTA(9)
429 +#define JZ_GPIO_MEM_DATA10             JZ_GPIO_PORTA(10)
430 +#define JZ_GPIO_MEM_DATA11             JZ_GPIO_PORTA(11)
431 +#define JZ_GPIO_MEM_DATA12             JZ_GPIO_PORTA(12)
432 +#define JZ_GPIO_MEM_DATA13             JZ_GPIO_PORTA(13)
433 +#define JZ_GPIO_MEM_DATA14             JZ_GPIO_PORTA(14)
434 +#define JZ_GPIO_MEM_DATA15             JZ_GPIO_PORTA(15)
435 +#define JZ_GPIO_MEM_DATA16             JZ_GPIO_PORTA(16)
436 +#define JZ_GPIO_MEM_DATA17             JZ_GPIO_PORTA(17)
437 +#define JZ_GPIO_MEM_DATA18             JZ_GPIO_PORTA(18)
438 +#define JZ_GPIO_MEM_DATA19             JZ_GPIO_PORTA(19)
439 +#define JZ_GPIO_MEM_DATA20             JZ_GPIO_PORTA(20)
440 +#define JZ_GPIO_MEM_DATA21             JZ_GPIO_PORTA(21)
441 +#define JZ_GPIO_MEM_DATA22             JZ_GPIO_PORTA(22)
442 +#define JZ_GPIO_MEM_DATA23             JZ_GPIO_PORTA(23)
443 +#define JZ_GPIO_MEM_DATA24             JZ_GPIO_PORTA(24)
444 +#define JZ_GPIO_MEM_DATA25             JZ_GPIO_PORTA(25)
445 +#define JZ_GPIO_MEM_DATA26             JZ_GPIO_PORTA(26)
446 +#define JZ_GPIO_MEM_DATA27             JZ_GPIO_PORTA(27)
447 +#define JZ_GPIO_MEM_DATA28             JZ_GPIO_PORTA(28)
448 +#define JZ_GPIO_MEM_DATA29             JZ_GPIO_PORTA(29)
449 +#define JZ_GPIO_MEM_DATA30             JZ_GPIO_PORTA(30)
450 +#define JZ_GPIO_MEM_DATA31             JZ_GPIO_PORTA(31)
451 +
452 +#define JZ_GPIO_FUNC_MEM_DATA0         JZ_GPIO_FUNC1
453 +#define JZ_GPIO_FUNC_MEM_DATA1         JZ_GPIO_FUNC1
454 +#define JZ_GPIO_FUNC_MEM_DATA2         JZ_GPIO_FUNC1
455 +#define JZ_GPIO_FUNC_MEM_DATA3         JZ_GPIO_FUNC1
456 +#define JZ_GPIO_FUNC_MEM_DATA4         JZ_GPIO_FUNC1
457 +#define JZ_GPIO_FUNC_MEM_DATA5         JZ_GPIO_FUNC1
458 +#define JZ_GPIO_FUNC_MEM_DATA6         JZ_GPIO_FUNC1
459 +#define JZ_GPIO_FUNC_MEM_DATA7         JZ_GPIO_FUNC1
460 +#define JZ_GPIO_FUNC_MEM_DATA8         JZ_GPIO_FUNC1
461 +#define JZ_GPIO_FUNC_MEM_DATA9         JZ_GPIO_FUNC1
462 +#define JZ_GPIO_FUNC_MEM_DATA10                JZ_GPIO_FUNC1
463 +#define JZ_GPIO_FUNC_MEM_DATA11                JZ_GPIO_FUNC1
464 +#define JZ_GPIO_FUNC_MEM_DATA12                JZ_GPIO_FUNC1
465 +#define JZ_GPIO_FUNC_MEM_DATA13                JZ_GPIO_FUNC1
466 +#define JZ_GPIO_FUNC_MEM_DATA14                JZ_GPIO_FUNC1
467 +#define JZ_GPIO_FUNC_MEM_DATA15                JZ_GPIO_FUNC1
468 +#define JZ_GPIO_FUNC_MEM_DATA16                JZ_GPIO_FUNC1
469 +#define JZ_GPIO_FUNC_MEM_DATA17                JZ_GPIO_FUNC1
470 +#define JZ_GPIO_FUNC_MEM_DATA18                JZ_GPIO_FUNC1
471 +#define JZ_GPIO_FUNC_MEM_DATA19                JZ_GPIO_FUNC1
472 +#define JZ_GPIO_FUNC_MEM_DATA20                JZ_GPIO_FUNC1
473 +#define JZ_GPIO_FUNC_MEM_DATA21                JZ_GPIO_FUNC1
474 +#define JZ_GPIO_FUNC_MEM_DATA22                JZ_GPIO_FUNC1
475 +#define JZ_GPIO_FUNC_MEM_DATA23                JZ_GPIO_FUNC1
476 +#define JZ_GPIO_FUNC_MEM_DATA24                JZ_GPIO_FUNC1
477 +#define JZ_GPIO_FUNC_MEM_DATA25                JZ_GPIO_FUNC1
478 +#define JZ_GPIO_FUNC_MEM_DATA26                JZ_GPIO_FUNC1
479 +#define JZ_GPIO_FUNC_MEM_DATA27                JZ_GPIO_FUNC1
480 +#define JZ_GPIO_FUNC_MEM_DATA28                JZ_GPIO_FUNC1
481 +#define JZ_GPIO_FUNC_MEM_DATA29                JZ_GPIO_FUNC1
482 +#define JZ_GPIO_FUNC_MEM_DATA30                JZ_GPIO_FUNC1
483 +#define JZ_GPIO_FUNC_MEM_DATA31                JZ_GPIO_FUNC1
484 +
485 +/* Port B function pins */
486 +#define JZ_GPIO_MEM_ADDR0              JZ_GPIO_PORTB(0)
487 +#define JZ_GPIO_MEM_ADDR1              JZ_GPIO_PORTB(1)
488 +#define JZ_GPIO_MEM_ADDR2              JZ_GPIO_PORTB(2)
489 +#define JZ_GPIO_MEM_ADDR3              JZ_GPIO_PORTB(3)
490 +#define JZ_GPIO_MEM_ADDR4              JZ_GPIO_PORTB(4)
491 +#define JZ_GPIO_MEM_ADDR5              JZ_GPIO_PORTB(5)
492 +#define JZ_GPIO_MEM_ADDR6              JZ_GPIO_PORTB(6)
493 +#define JZ_GPIO_MEM_ADDR7              JZ_GPIO_PORTB(7)
494 +#define JZ_GPIO_MEM_ADDR8              JZ_GPIO_PORTB(8)
495 +#define JZ_GPIO_MEM_ADDR9              JZ_GPIO_PORTB(9)
496 +#define JZ_GPIO_MEM_ADDR10             JZ_GPIO_PORTB(10)
497 +#define JZ_GPIO_MEM_ADDR11             JZ_GPIO_PORTB(11)
498 +#define JZ_GPIO_MEM_ADDR12             JZ_GPIO_PORTB(12)
499 +#define JZ_GPIO_MEM_ADDR13             JZ_GPIO_PORTB(13)
500 +#define JZ_GPIO_MEM_ADDR14             JZ_GPIO_PORTB(14)
501 +#define JZ_GPIO_MEM_ADDR15             JZ_GPIO_PORTB(15)
502 +#define JZ_GPIO_MEM_ADDR16             JZ_GPIO_PORTB(16)
503 +#define JZ_GPIO_MEM_CLS                        JZ_GPIO_PORTB(17)
504 +#define JZ_GPIO_MEM_SPL                        JZ_GPIO_PORTB(18)
505 +#define JZ_GPIO_MEM_DCS                        JZ_GPIO_PORTB(19)
506 +#define JZ_GPIO_MEM_RAS                        JZ_GPIO_PORTB(20)
507 +#define JZ_GPIO_MEM_CAS                        JZ_GPIO_PORTB(21)
508 +#define JZ_GPIO_MEM_SDWE               JZ_GPIO_PORTB(22)
509 +#define JZ_GPIO_MEM_CKE                        JZ_GPIO_PORTB(23)
510 +#define JZ_GPIO_MEM_CKO                        JZ_GPIO_PORTB(24)
511 +#define JZ_GPIO_MEM_CS0                        JZ_GPIO_PORTB(25)
512 +#define JZ_GPIO_MEM_CS1                        JZ_GPIO_PORTB(26)
513 +#define JZ_GPIO_MEM_CS2                        JZ_GPIO_PORTB(27)
514 +#define JZ_GPIO_MEM_CS3                        JZ_GPIO_PORTB(28)
515 +#define JZ_GPIO_MEM_RD                 JZ_GPIO_PORTB(29)
516 +#define JZ_GPIO_MEM_WR                 JZ_GPIO_PORTB(30)
517 +#define JZ_GPIO_MEM_WE0                        JZ_GPIO_PORTB(31)
518 +
519 +#define JZ_GPIO_FUNC_MEM_ADDR0         JZ_GPIO_FUNC1
520 +#define JZ_GPIO_FUNC_MEM_ADDR1         JZ_GPIO_FUNC1
521 +#define JZ_GPIO_FUNC_MEM_ADDR2         JZ_GPIO_FUNC1
522 +#define JZ_GPIO_FUNC_MEM_ADDR3         JZ_GPIO_FUNC1
523 +#define JZ_GPIO_FUNC_MEM_ADDR4         JZ_GPIO_FUNC1
524 +#define JZ_GPIO_FUNC_MEM_ADDR5         JZ_GPIO_FUNC1
525 +#define JZ_GPIO_FUNC_MEM_ADDR6         JZ_GPIO_FUNC1
526 +#define JZ_GPIO_FUNC_MEM_ADDR7         JZ_GPIO_FUNC1
527 +#define JZ_GPIO_FUNC_MEM_ADDR8         JZ_GPIO_FUNC1
528 +#define JZ_GPIO_FUNC_MEM_ADDR9         JZ_GPIO_FUNC1
529 +#define JZ_GPIO_FUNC_MEM_ADDR10                JZ_GPIO_FUNC1
530 +#define JZ_GPIO_FUNC_MEM_ADDR11                JZ_GPIO_FUNC1
531 +#define JZ_GPIO_FUNC_MEM_ADDR12                JZ_GPIO_FUNC1
532 +#define JZ_GPIO_FUNC_MEM_ADDR13                JZ_GPIO_FUNC1
533 +#define JZ_GPIO_FUNC_MEM_ADDR14                JZ_GPIO_FUNC1
534 +#define JZ_GPIO_FUNC_MEM_ADDR15                JZ_GPIO_FUNC1
535 +#define JZ_GPIO_FUNC_MEM_ADDR16                JZ_GPIO_FUNC1
536 +#define JZ_GPIO_FUNC_MEM_CLS           JZ_GPIO_FUNC1
537 +#define JZ_GPIO_FUNC_MEM_SPL           JZ_GPIO_FUNC1
538 +#define JZ_GPIO_FUNC_MEM_DCS           JZ_GPIO_FUNC1
539 +#define JZ_GPIO_FUNC_MEM_RAS           JZ_GPIO_FUNC1
540 +#define JZ_GPIO_FUNC_MEM_CAS           JZ_GPIO_FUNC1
541 +#define JZ_GPIO_FUNC_MEM_SDWE          JZ_GPIO_FUNC1
542 +#define JZ_GPIO_FUNC_MEM_CKE           JZ_GPIO_FUNC1
543 +#define JZ_GPIO_FUNC_MEM_CKO           JZ_GPIO_FUNC1
544 +#define JZ_GPIO_FUNC_MEM_CS0           JZ_GPIO_FUNC1
545 +#define JZ_GPIO_FUNC_MEM_CS1           JZ_GPIO_FUNC1
546 +#define JZ_GPIO_FUNC_MEM_CS2           JZ_GPIO_FUNC1
547 +#define JZ_GPIO_FUNC_MEM_CS3           JZ_GPIO_FUNC1
548 +#define JZ_GPIO_FUNC_MEM_RD            JZ_GPIO_FUNC1
549 +#define JZ_GPIO_FUNC_MEM_WR            JZ_GPIO_FUNC1
550 +#define JZ_GPIO_FUNC_MEM_WE0           JZ_GPIO_FUNC1
551 +
552 +
553 +#define JZ_GPIO_MEM_ADDR21             JZ_GPIO_PORTB(17)
554 +#define JZ_GPIO_MEM_ADDR22             JZ_GPIO_PORTB(18)
555 +
556 +#define JZ_GPIO_FUNC_MEM_ADDR21                JZ_GPIO_FUNC2
557 +#define JZ_GPIO_FUNC_MEM_ADDR22                JZ_GPIO_FUNC2
558 +
559 +/* Port C function pins */
560 +#define JZ_GPIO_LCD_DATA0              JZ_GPIO_PORTC(0)
561 +#define JZ_GPIO_LCD_DATA1              JZ_GPIO_PORTC(1)
562 +#define JZ_GPIO_LCD_DATA2              JZ_GPIO_PORTC(2)
563 +#define JZ_GPIO_LCD_DATA3              JZ_GPIO_PORTC(3)
564 +#define JZ_GPIO_LCD_DATA4              JZ_GPIO_PORTC(4)
565 +#define JZ_GPIO_LCD_DATA5              JZ_GPIO_PORTC(5)
566 +#define JZ_GPIO_LCD_DATA6              JZ_GPIO_PORTC(6)
567 +#define JZ_GPIO_LCD_DATA7              JZ_GPIO_PORTC(7)
568 +#define JZ_GPIO_LCD_DATA8              JZ_GPIO_PORTC(8)
569 +#define JZ_GPIO_LCD_DATA9              JZ_GPIO_PORTC(9)
570 +#define JZ_GPIO_LCD_DATA10             JZ_GPIO_PORTC(10)
571 +#define JZ_GPIO_LCD_DATA11             JZ_GPIO_PORTC(11)
572 +#define JZ_GPIO_LCD_DATA12             JZ_GPIO_PORTC(12)
573 +#define JZ_GPIO_LCD_DATA13             JZ_GPIO_PORTC(13)
574 +#define JZ_GPIO_LCD_DATA14             JZ_GPIO_PORTC(14)
575 +#define JZ_GPIO_LCD_DATA15             JZ_GPIO_PORTC(15)
576 +#define JZ_GPIO_LCD_DATA16             JZ_GPIO_PORTC(16)
577 +#define JZ_GPIO_LCD_DATA17             JZ_GPIO_PORTC(17)
578 +#define JZ_GPIO_LCD_PCLK               JZ_GPIO_PORTC(18)
579 +#define JZ_GPIO_LCD_HSYNC              JZ_GPIO_PORTC(19)
580 +#define JZ_GPIO_LCD_VSYNC              JZ_GPIO_PORTC(20)
581 +#define JZ_GPIO_LCD_DE                 JZ_GPIO_PORTC(21)
582 +#define JZ_GPIO_LCD_PS                 JZ_GPIO_PORTC(22)
583 +#define JZ_GPIO_LCD_REV                        JZ_GPIO_PORTC(23)
584 +#define JZ_GPIO_MEM_WE1                        JZ_GPIO_PORTC(24)
585 +#define JZ_GPIO_MEM_WE2                        JZ_GPIO_PORTC(25)
586 +#define JZ_GPIO_MEM_WE3                        JZ_GPIO_PORTC(26)
587 +#define JZ_GPIO_MEM_WAIT               JZ_GPIO_PORTC(27)
588 +#define JZ_GPIO_MEM_FRE                        JZ_GPIO_PORTC(28)
589 +#define JZ_GPIO_MEM_FWE                        JZ_GPIO_PORTC(29)
590 +
591 +#define JZ_GPIO_FUNC_LCD_DATA0         JZ_GPIO_FUNC1
592 +#define JZ_GPIO_FUNC_LCD_DATA1         JZ_GPIO_FUNC1
593 +#define JZ_GPIO_FUNC_LCD_DATA2         JZ_GPIO_FUNC1
594 +#define JZ_GPIO_FUNC_LCD_DATA3         JZ_GPIO_FUNC1
595 +#define JZ_GPIO_FUNC_LCD_DATA4         JZ_GPIO_FUNC1
596 +#define JZ_GPIO_FUNC_LCD_DATA5         JZ_GPIO_FUNC1
597 +#define JZ_GPIO_FUNC_LCD_DATA6         JZ_GPIO_FUNC1
598 +#define JZ_GPIO_FUNC_LCD_DATA7         JZ_GPIO_FUNC1
599 +#define JZ_GPIO_FUNC_LCD_DATA8         JZ_GPIO_FUNC1
600 +#define JZ_GPIO_FUNC_LCD_DATA9         JZ_GPIO_FUNC1
601 +#define JZ_GPIO_FUNC_LCD_DATA10                JZ_GPIO_FUNC1
602 +#define JZ_GPIO_FUNC_LCD_DATA11                JZ_GPIO_FUNC1
603 +#define JZ_GPIO_FUNC_LCD_DATA12                JZ_GPIO_FUNC1
604 +#define JZ_GPIO_FUNC_LCD_DATA13                JZ_GPIO_FUNC1
605 +#define JZ_GPIO_FUNC_LCD_DATA14                JZ_GPIO_FUNC1
606 +#define JZ_GPIO_FUNC_LCD_DATA15                JZ_GPIO_FUNC1
607 +#define JZ_GPIO_FUNC_LCD_DATA16                JZ_GPIO_FUNC1
608 +#define JZ_GPIO_FUNC_LCD_DATA17                JZ_GPIO_FUNC1
609 +#define JZ_GPIO_FUNC_LCD_PCLK          JZ_GPIO_FUNC1
610 +#define JZ_GPIO_FUNC_LCD_VSYNC         JZ_GPIO_FUNC1
611 +#define JZ_GPIO_FUNC_LCD_HSYNC         JZ_GPIO_FUNC1
612 +#define JZ_GPIO_FUNC_LCD_DE            JZ_GPIO_FUNC1
613 +#define JZ_GPIO_FUNC_LCD_PS            JZ_GPIO_FUNC1
614 +#define JZ_GPIO_FUNC_LCD_REV           JZ_GPIO_FUNC1
615 +#define JZ_GPIO_FUNC_MEM_WE1           JZ_GPIO_FUNC1
616 +#define JZ_GPIO_FUNC_MEM_WE2           JZ_GPIO_FUNC1
617 +#define JZ_GPIO_FUNC_MEM_WE3           JZ_GPIO_FUNC1
618 +#define JZ_GPIO_FUNC_MEM_WAIT          JZ_GPIO_FUNC1
619 +#define JZ_GPIO_FUNC_MEM_FRE           JZ_GPIO_FUNC1
620 +#define JZ_GPIO_FUNC_MEM_FWE           JZ_GPIO_FUNC1
621 +
622 +
623 +#define JZ_GPIO_MEM_ADDR19             JZ_GPIO_PORTB(22)
624 +#define JZ_GPIO_MEM_ADDR20             JZ_GPIO_PORTB(23)
625 +
626 +#define JZ_GPIO_FUNC_MEM_ADDR19                JZ_GPIO_FUNC2
627 +#define JZ_GPIO_FUNC_MEM_ADDR20                JZ_GPIO_FUNC2
628 +
629 +/* Port D function pins */
630 +#define JZ_GPIO_CIM_DATA0              JZ_GPIO_PORTD(0)
631 +#define JZ_GPIO_CIM_DATA1              JZ_GPIO_PORTD(1)
632 +#define JZ_GPIO_CIM_DATA2              JZ_GPIO_PORTD(2)
633 +#define JZ_GPIO_CIM_DATA3              JZ_GPIO_PORTD(3)
634 +#define JZ_GPIO_CIM_DATA4              JZ_GPIO_PORTD(4)
635 +#define JZ_GPIO_CIM_DATA5              JZ_GPIO_PORTD(5)
636 +#define JZ_GPIO_CIM_DATA6              JZ_GPIO_PORTD(6)
637 +#define JZ_GPIO_CIM_DATA7              JZ_GPIO_PORTD(7)
638 +#define JZ_GPIO_MSC_CMD                        JZ_GPIO_PORTD(8)
639 +#define JZ_GPIO_MSC_CLK                        JZ_GPIO_PORTD(9)
640 +#define JZ_GPIO_MSC_DATA0              JZ_GPIO_PORTD(10)
641 +#define JZ_GPIO_MSC_DATA1              JZ_GPIO_PORTD(11)
642 +#define JZ_GPIO_MSC_DATA2              JZ_GPIO_PORTD(12)
643 +#define JZ_GPIO_MSC_DATA3              JZ_GPIO_PORTD(13)
644 +#define JZ_GPIO_CIM_MCLK               JZ_GPIO_PORTD(14)
645 +#define JZ_GPIO_CIM_PCLK               JZ_GPIO_PORTD(15)
646 +#define JZ_GPIO_CIM_VSYNC              JZ_GPIO_PORTD(16)
647 +#define JZ_GPIO_CIM_HSYNC              JZ_GPIO_PORTD(17)
648 +#define JZ_GPIO_SPI_CLK                        JZ_GPIO_PORTD(18)
649 +#define JZ_GPIO_SPI_CE0                        JZ_GPIO_PORTD(19)
650 +#define JZ_GPIO_SPI_DT                 JZ_GPIO_PORTD(20)
651 +#define JZ_GPIO_SPI_DR                 JZ_GPIO_PORTD(21)
652 +#define JZ_GPIO_SPI_CE1                        JZ_GPIO_PORTD(22)
653 +#define JZ_GPIO_PWM0                   JZ_GPIO_PORTD(23)
654 +#define JZ_GPIO_PWM1                   JZ_GPIO_PORTD(24)
655 +#define JZ_GPIO_PWM2                   JZ_GPIO_PORTD(25)
656 +#define JZ_GPIO_PWM3                   JZ_GPIO_PORTD(26)
657 +#define JZ_GPIO_PWM4                   JZ_GPIO_PORTD(27)
658 +#define JZ_GPIO_PWM5                   JZ_GPIO_PORTD(28)
659 +#define JZ_GPIO_PWM6                   JZ_GPIO_PORTD(30)
660 +#define JZ_GPIO_PWM7                   JZ_GPIO_PORTD(31)
661 +
662 +#define JZ_GPIO_FUNC_CIM_DATA          JZ_GPIO_FUNC1
663 +#define JZ_GPIO_FUNC_CIM_DATA0         JZ_GPIO_FUNC_CIM_DATA
664 +#define JZ_GPIO_FUNC_CIM_DATA1         JZ_GPIO_FUNC_CIM_DATA
665 +#define JZ_GPIO_FUNC_CIM_DATA2         JZ_GPIO_FUNC_CIM_DATA
666 +#define JZ_GPIO_FUNC_CIM_DATA3         JZ_GPIO_FUNC_CIM_DATA
667 +#define JZ_GPIO_FUNC_CIM_DATA4         JZ_GPIO_FUNC_CIM_DATA
668 +#define JZ_GPIO_FUNC_CIM_DATA5         JZ_GPIO_FUNC_CIM_DATA
669 +#define JZ_GPIO_FUNC_CIM_DATA6         JZ_GPIO_FUNC_CIM_DATA
670 +#define JZ_GPIO_FUNC_CIM_DATA7         JZ_GPIO_FUNC_CIM_DATA
671 +#define JZ_GPIO_FUNC_MSC_CMD           JZ_GPIO_FUNC1
672 +#define JZ_GPIO_FUNC_MSC_CLK           JZ_GPIO_FUNC1
673 +#define JZ_GPIO_FUNC_MSC_DATA          JZ_GPIO_FUNC1
674 +#define JZ_GPIO_FUNC_MSC_DATA0         JZ_GPIO_FUNC_MSC_DATA
675 +#define JZ_GPIO_FUNC_MSC_DATA1         JZ_GPIO_FUNC_MSC_DATA
676 +#define JZ_GPIO_FUNC_MSC_DATA2         JZ_GPIO_FUNC_MSC_DATA
677 +#define JZ_GPIO_FUNC_MSC_DATA3         JZ_GPIO_FUNC_MSC_DATA
678 +#define JZ_GPIO_FUNC_CIM_MCLK          JZ_GPIO_FUNC1
679 +#define JZ_GPIO_FUNC_CIM_PCLK          JZ_GPIO_FUNC1
680 +#define JZ_GPIO_FUNC_CIM_VSYNC         JZ_GPIO_FUNC1
681 +#define JZ_GPIO_FUNC_CIM_HSYNC         JZ_GPIO_FUNC1
682 +#define JZ_GPIO_FUNC_SPI_CLK           JZ_GPIO_FUNC1
683 +#define JZ_GPIO_FUNC_SPI_CE0           JZ_GPIO_FUNC1
684 +#define JZ_GPIO_FUNC_SPI_DT            JZ_GPIO_FUNC1
685 +#define JZ_GPIO_FUNC_SPI_DR            JZ_GPIO_FUNC1
686 +#define JZ_GPIO_FUNC_SPI_CE1           JZ_GPIO_FUNC1
687 +
688 +#define JZ_GPIO_FUNC_PWM               JZ_GPIO_FUNC1
689 +#define JZ_GPIO_FUNC_PWM0              JZ_GPIO_FUNC_PWM
690 +#define JZ_GPIO_FUNC_PWM1              JZ_GPIO_FUNC_PWM
691 +#define JZ_GPIO_FUNC_PWM2              JZ_GPIO_FUNC_PWM
692 +#define JZ_GPIO_FUNC_PWM3              JZ_GPIO_FUNC_PWM
693 +#define JZ_GPIO_FUNC_PWM4              JZ_GPIO_FUNC_PWM
694 +#define JZ_GPIO_FUNC_PWM5              JZ_GPIO_FUNC_PWM
695 +#define JZ_GPIO_FUNC_PWM6              JZ_GPIO_FUNC_PWM
696 +#define JZ_GPIO_FUNC_PWM7              JZ_GPIO_FUNC_PWM
697 +
698 +#define JZ_GPIO_MEM_SCLK_RSTN          JZ_GPIO_PORTD(18)
699 +#define JZ_GPIO_MEM_BCLK               JZ_GPIO_PORTD(19)
700 +#define JZ_GPIO_MEM_SDATO              JZ_GPIO_PORTD(20)
701 +#define JZ_GPIO_MEM_SDATI              JZ_GPIO_PORTD(21)
702 +#define JZ_GPIO_MEM_SYNC               JZ_GPIO_PORTD(22)
703 +#define JZ_GPIO_I2C_SDA                        JZ_GPIO_PORTD(23)
704 +#define JZ_GPIO_I2C_SCK                        JZ_GPIO_PORTD(24)
705 +#define JZ_GPIO_UART0_TXD              JZ_GPIO_PORTD(25)
706 +#define JZ_GPIO_UART0_RXD              JZ_GPIO_PORTD(26)
707 +#define JZ_GPIO_MEM_ADDR17             JZ_GPIO_PORTD(27)
708 +#define JZ_GPIO_MEM_ADDR18             JZ_GPIO_PORTD(28)
709 +#define JZ_GPIO_UART0_CTS              JZ_GPIO_PORTD(30)
710 +#define JZ_GPIO_UART0_RTS              JZ_GPIO_PORTD(31)
711 +
712 +#define JZ_GPIO_FUNC_MEM_SCLK_RSTN     JZ_GPIO_FUNC2
713 +#define JZ_GPIO_FUNC_MEM_BCLK          JZ_GPIO_FUNC2
714 +#define JZ_GPIO_FUNC_MEM_SDATO         JZ_GPIO_FUNC2
715 +#define JZ_GPIO_FUNC_MEM_SDATI         JZ_GPIO_FUNC2
716 +#define JZ_GPIO_FUNC_MEM_SYNC          JZ_GPIO_FUNC2
717 +#define JZ_GPIO_FUNC_I2C_SDA           JZ_GPIO_FUNC2
718 +#define JZ_GPIO_FUNC_I2C_SCK           JZ_GPIO_FUNC2
719 +#define JZ_GPIO_FUNC_UART0_TXD         JZ_GPIO_FUNC2
720 +#define JZ_GPIO_FUNC_UART0_RXD         JZ_GPIO_FUNC2
721 +#define JZ_GPIO_FUNC_MEM_ADDR17                JZ_GPIO_FUNC2
722 +#define JZ_GPIO_FUNC_MEM_ADDR18                JZ_GPIO_FUNC2
723 +#define JZ_GPIO_FUNC_UART0_CTS         JZ_GPIO_FUNC2
724 +#define JZ_GPIO_FUNC_UART0_RTS         JZ_GPIO_FUNC2
725 +
726 +#define JZ_GPIO_UART1_RXD              JZ_GPIO_PORTD(30)
727 +#define JZ_GPIO_UART1_TXD              JZ_GPIO_PORTD(31)
728 +
729 +#define JZ_GPIO_FUNC_UART1_RXD         JZ_GPIO_FUNC3
730 +#define JZ_GPIO_FUNC_UART1_TXD         JZ_GPIO_FUNC3
731 +
732 +#endif
733 diff --git a/arch/mips/include/asm/mach-jz4740/irq.h b/arch/mips/include/asm/mach-jz4740/irq.h
734 new file mode 100644
735 index 0000000..5e27b78
736 --- /dev/null
737 +++ b/arch/mips/include/asm/mach-jz4740/irq.h
738 @@ -0,0 +1,55 @@
739 +/*
740 + *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
741 + *  JZ7420/JZ4740 IRQ definitions
742 + *
743 + *  This program is free software; you can redistribute         it and/or modify it
744 + *  under  the terms of         the GNU General  Public License as published by the
745 + *  Free Software Foundation;  either version 2 of the License, or (at your
746 + *  option) any later version.
747 + *
748 + *  You should have received a copy of the  GNU General Public License along
749 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
750 + *  675 Mass Ave, Cambridge, MA 02139, USA.
751 + *
752 + */
753 +
754 +#ifndef __ASM_MACH_JZ4740_IRQ_H__
755 +#define __ASM_MACH_JZ4740_IRQ_H__
756 +
757 +#define MIPS_CPU_IRQ_BASE 0
758 +#define JZ4740_IRQ_BASE 8
759 +
760 +/* 1st-level interrupts */
761 +#define JZ4740_IRQ(x)  (JZ4740_IRQ_BASE + (x))
762 +#define JZ4740_IRQ_I2C JZ4740_IRQ(1)
763 +#define JZ4740_IRQ_UHC JZ4740_IRQ(3)
764 +#define JZ4740_IRQ_UART1       JZ4740_IRQ(8)
765 +#define JZ4740_IRQ_UART0       JZ4740_IRQ(9)
766 +#define JZ4740_IRQ_SADC        JZ4740_IRQ(12)
767 +#define JZ4740_IRQ_MSC JZ4740_IRQ(14)
768 +#define JZ4740_IRQ_RTC JZ4740_IRQ(15)
769 +#define JZ4740_IRQ_SSI JZ4740_IRQ(16)
770 +#define JZ4740_IRQ_CIM JZ4740_IRQ(17)
771 +#define JZ4740_IRQ_AIC JZ4740_IRQ(18)
772 +#define JZ4740_IRQ_ETH JZ4740_IRQ(19)
773 +#define JZ4740_IRQ_DMAC        JZ4740_IRQ(20)
774 +#define JZ4740_IRQ_TCU2        JZ4740_IRQ(21)
775 +#define JZ4740_IRQ_TCU1        JZ4740_IRQ(22)
776 +#define JZ4740_IRQ_TCU0        JZ4740_IRQ(23)
777 +#define JZ4740_IRQ_UDC JZ4740_IRQ(24)
778 +#define JZ4740_IRQ_GPIO3       JZ4740_IRQ(25)
779 +#define JZ4740_IRQ_GPIO2       JZ4740_IRQ(26)
780 +#define JZ4740_IRQ_GPIO1       JZ4740_IRQ(27)
781 +#define JZ4740_IRQ_GPIO0       JZ4740_IRQ(28)
782 +#define JZ4740_IRQ_IPU JZ4740_IRQ(29)
783 +#define JZ4740_IRQ_LCD JZ4740_IRQ(30)
784 +
785 +/* 2nd-level interrupts */
786 +#define JZ4740_IRQ_DMA(x)      ((x) + JZ4740_IRQ(32))
787 +
788 +#define JZ4740_IRQ_INTC_GPIO(x)        (JZ4740_IRQ_GPIO0 - (x))
789 +#define JZ4740_IRQ_GPIO(x)             (JZ4740_IRQ(48) + (x))
790 +
791 +#define NR_IRQS (JZ4740_IRQ_GPIO(127) + 1)
792 +
793 +#endif
794 diff --git a/arch/mips/include/asm/mach-jz4740/platform.h b/arch/mips/include/asm/mach-jz4740/platform.h
795 new file mode 100644
796 index 0000000..a2e2871
797 --- /dev/null
798 +++ b/arch/mips/include/asm/mach-jz4740/platform.h
799 @@ -0,0 +1,34 @@
800 +/*
801 + *  Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
802 + *  JZ7420/JZ4740 platform device definitions
803 + *
804 + *  This program is free software; you can redistribute         it and/or modify it
805 + *  under  the terms of         the GNU General  Public License as published by the
806 + *  Free Software Foundation;  either version 2 of the License, or (at your
807 + *  option) any later version.
808 + *
809 + *  You should have received a copy of the  GNU General Public License along
810 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
811 + *  675 Mass Ave, Cambridge, MA 02139, USA.
812 + *
813 + */
814 +
815 +
816 +#ifndef __JZ4740_PLATFORM_H
817 +#define __JZ4740_PLATFORM_H
818 +
819 +#include <linux/platform_device.h>
820 +
821 +extern struct platform_device jz4740_usb_ohci_device;
822 +extern struct platform_device jz4740_usb_gdt_device;
823 +extern struct platform_device jz4740_mmc_device;
824 +extern struct platform_device jz4740_rtc_device;
825 +extern struct platform_device jz4740_i2c_device;
826 +extern struct platform_device jz4740_nand_device;
827 +extern struct platform_device jz4740_framebuffer_device;
828 +extern struct platform_device jz4740_i2s_device;
829 +extern struct platform_device jz4740_codec_device;
830 +extern struct platform_device jz4740_adc_device;
831 +extern struct platform_device jz4740_battery_device;
832 +
833 +#endif
834 diff --git a/arch/mips/include/asm/mach-jz4740/serial.h b/arch/mips/include/asm/mach-jz4740/serial.h
835 new file mode 100644
836 index 0000000..c4819b9
837 --- /dev/null
838 +++ b/arch/mips/include/asm/mach-jz4740/serial.h
839 @@ -0,0 +1,30 @@
840 +/*
841 + *  linux/include/asm-mips/mach-jz4740/serial.h
842 + *
843 + *  Ingenic's JZ4740 common include.
844 + *
845 + *  Copyright (C) 2006 - 2007 Ingenic Semiconductor Inc.
846 + *
847 + *  Author: <yliu@ingenic.cn>
848 + *
849 + * This program is free software; you can redistribute it and/or modify
850 + * it under the terms of the GNU General Public License version 2 as
851 + * published by the Free Software Foundation.
852 + */
853 +
854 +#ifndef __ASM_BOARD_SERIAL_H__
855 +#define __ASM_BOARD_SERIAL_H__
856 +
857 +#ifndef CONFIG_SERIAL_MANY_PORTS
858 +#undef RS_TABLE_SIZE
859 +#define RS_TABLE_SIZE  1
860 +#endif
861 +
862 +#define JZ_BASE_BAUD   (12000000/16)
863 +
864 +#define JZ_SERIAL_PORT_DEFNS \
865 +       { .baud_base = JZ_BASE_BAUD, .irq = IRQ_UART0, \
866 +         .flags = STD_COM_FLAGS, .iomem_base = (u8 *)UART0_BASE, \
867 +         .iomem_reg_shift = 2, .io_type = SERIAL_IO_MEM },
868 +
869 +#endif /* __ASM_BORAD_SERIAL_H__ */
870 diff --git a/arch/mips/include/asm/mach-jz4740/timer.h b/arch/mips/include/asm/mach-jz4740/timer.h
871 new file mode 100644
872 index 0000000..30153ff
873 --- /dev/null
874 +++ b/arch/mips/include/asm/mach-jz4740/timer.h
875 @@ -0,0 +1,22 @@
876 +/*
877 + *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
878 + *     JZ4740 platform timer support
879 + *
880 + *  This program is free software; you can redistribute         it and/or modify it
881 + *  under  the terms of         the GNU General  Public License as published by the
882 + *  Free Software Foundation;  either version 2 of the License, or (at your
883 + *  option) any later version.
884 + *
885 + *  You should have received a copy of the  GNU General Public License along
886 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
887 + *  675 Mass Ave, Cambridge, MA 02139, USA.
888 + *
889 + */
890 +
891 +#ifndef __ASM_MACH_JZ4740_TIMER
892 +#define __ASM_MACH_JZ4740_TIMER
893 +
894 +void jz4740_timer_enable_watchdog(void);
895 +void jz4740_timer_disable_watchdog(void);
896 +
897 +#endif
898 diff --git a/arch/mips/include/asm/mach-jz4740/war.h b/arch/mips/include/asm/mach-jz4740/war.h
899 new file mode 100644
900 index 0000000..3a5bc17
901 --- /dev/null
902 +++ b/arch/mips/include/asm/mach-jz4740/war.h
903 @@ -0,0 +1,25 @@
904 +/*
905 + * This file is subject to the terms and conditions of the GNU General Public
906 + * License.  See the file "COPYING" in the main directory of this archive
907 + * for more details.
908 + *
909 + * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
910 + */
911 +#ifndef __ASM_MIPS_MACH_JZ4740_WAR_H
912 +#define __ASM_MIPS_MACH_JZ4740_WAR_H
913 +
914 +#define R4600_V1_INDEX_ICACHEOP_WAR    0
915 +#define R4600_V1_HIT_CACHEOP_WAR       0
916 +#define R4600_V2_HIT_CACHEOP_WAR       0
917 +#define R5432_CP0_INTERRUPT_WAR                0
918 +#define BCM1250_M3_WAR                 0
919 +#define SIBYTE_1956_WAR                        0
920 +#define MIPS4K_ICACHE_REFILL_WAR       0
921 +#define MIPS_CACHE_SYNC_WAR            0
922 +#define TX49XX_ICACHE_INDEX_INV_WAR    0
923 +#define RM9000_CDEX_SMP_WAR            0
924 +#define ICACHE_REFILLS_WORKAROUND_WAR  0
925 +#define R10000_LLSC_WAR                        0
926 +#define MIPS34K_MISSED_ITLB_WAR                0
927 +
928 +#endif /* __ASM_MIPS_MACH_JZ4740_WAR_H */
929 diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig
930 new file mode 100644
931 index 0000000..5f6da09
932 --- /dev/null
933 +++ b/arch/mips/jz4740/Kconfig
934 @@ -0,0 +1,29 @@
935 +choice
936 +    prompt "Machine type"
937 +    depends on MACH_JZ
938 +    default JZ4740_QI_LB60
939 +
940 +endchoice
941 +
942 +config HAVE_PWM
943 +       bool
944 +
945 +config SOC_JZ4740
946 +       bool
947 +       select JZSOC
948 +       select GENERIC_GPIO
949 +       select ARCH_REQUIRE_GPIOLIB
950 +       select SYS_HAS_EARLY_PRINTK
951 +       select SYS_SUPPORTS_LITTLE_ENDIAN
952 +       select IRQ_CPU
953 +       select DMA_NONCOHERENT
954 +       select HAVE_PWM
955 +
956 +config JZSOC
957 +       bool
958 +       select JZRISC
959 +       select SYS_HAS_CPU_MIPS32_R1
960 +       select SYS_SUPPORTS_32BIT_KERNEL
961 +
962 +config JZRISC
963 +       bool
964 diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
965 new file mode 100644
966 index 0000000..e389ddd
967 --- /dev/null
968 +++ b/arch/mips/jz4740/Makefile
969 @@ -0,0 +1,17 @@
970 +#
971 +# Makefile for the Ingenic JZ4740.
972 +#
973 +
974 +# Object file lists.
975 +
976 +obj-y += prom.o irq.o time.o reset.o setup.o dma.o \
977 +       gpio.o clock.o platform.o timer.o pwm.o
978 +
979 +obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o
980 +
981 +# board specific support
982 +
983 +# PM support
984 +
985 +obj-$(CONFIG_PM)         += pm.o
986 +
987 diff --git a/arch/mips/jz4740/clock-debugfs.c b/arch/mips/jz4740/clock-debugfs.c
988 new file mode 100644
989 index 0000000..993b91b
990 --- /dev/null
991 +++ b/arch/mips/jz4740/clock-debugfs.c
992 @@ -0,0 +1,109 @@
993 +/*
994 + *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
995 + *  JZ4740 SoC clock support debugfs entries
996 + *
997 + *  This program is free software; you can redistribute         it and/or modify it
998 + *  under  the terms of         the GNU General  Public License as published by the
999 + *  Free Software Foundation;  either version 2 of the License, or (at your
1000 + *  option) any later version.
1001 + *
1002 + *  You should have received a copy of the  GNU General Public License along
1003 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
1004 + *  675 Mass Ave, Cambridge, MA 02139, USA.
1005 + *
1006 + */
1007 +
1008 +#include <linux/kernel.h>
1009 +#include <linux/module.h>
1010 +#include <linux/clk.h>
1011 +#include <linux/err.h>
1012 +
1013 +#include <linux/debugfs.h>
1014 +#include <linux/uaccess.h>
1015 +
1016 +#include <asm/mach-jz4740/clock.h>
1017 +#include "clock.h"
1018 +
1019 +static struct dentry *jz4740_clock_debugfs;
1020 +
1021 +static int jz4740_clock_debugfs_show_enabled(void *data, uint64_t *value)
1022 +{
1023 +       struct clk *clk = data;
1024 +       *value = clk_is_enabled(clk);
1025 +
1026 +       return 0;
1027 +}
1028 +
1029 +static int jz4740_clock_debugfs_set_enabled(void *data, uint64_t value)
1030 +{
1031 +       struct clk *clk = data;
1032 +
1033 +       if (value)
1034 +               return clk_enable(clk);
1035 +       else
1036 +               clk_disable(clk);
1037 +
1038 +       return 0;
1039 +}
1040 +
1041 +DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_enabled,
1042 +       jz4740_clock_debugfs_show_enabled,
1043 +       jz4740_clock_debugfs_set_enabled,
1044 +       "%llu\n");
1045 +
1046 +static int jz4740_clock_debugfs_show_rate(void *data, uint64_t *value)
1047 +{
1048 +       struct clk *clk = data;
1049 +       *value = clk_get_rate(clk);
1050 +
1051 +       return 0;
1052 +}
1053 +
1054 +DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_rate,
1055 +       jz4740_clock_debugfs_show_rate,
1056 +       NULL,
1057 +       "%llu\n");
1058 +
1059 +void jz4740_clock_debugfs_add_clk(struct clk *clk)
1060 +{
1061 +       if (!jz4740_clock_debugfs)
1062 +               return;
1063 +
1064 +       clk->debugfs_entry = debugfs_create_dir(clk->name, jz4740_clock_debugfs);
1065 +       debugfs_create_file("rate", S_IWUGO | S_IRUGO, clk->debugfs_entry, clk,
1066 +                               &jz4740_clock_debugfs_ops_rate);
1067 +       debugfs_create_file("enabled", S_IRUGO, clk->debugfs_entry, clk,
1068 +                               &jz4740_clock_debugfs_ops_enabled);
1069 +
1070 +       if (clk->parent) {
1071 +               char parent_path[100];
1072 +               snprintf(parent_path, 100, "../%s", clk->parent->name);
1073 +               clk->debugfs_parent_entry = debugfs_create_symlink("parent",
1074 +                                               clk->debugfs_entry,
1075 +                                               parent_path);
1076 +       }
1077 +}
1078 +
1079 +/* TODO: Locking */
1080 +void jz4740_clock_debugfs_update_parent(struct clk *clk)
1081 +{
1082 +       if (clk->debugfs_parent_entry)
1083 +               debugfs_remove(clk->debugfs_parent_entry);
1084 +
1085 +       if (clk->parent) {
1086 +               char parent_path[100];
1087 +               snprintf(parent_path, 100, "../%s", clk->parent->name);
1088 +               clk->debugfs_parent_entry = debugfs_create_symlink("parent",
1089 +                                               clk->debugfs_entry,
1090 +                                               parent_path);
1091 +       } else {
1092 +               clk->debugfs_parent_entry = NULL;
1093 +       }
1094 +}
1095 +
1096 +void jz4740_clock_debugfs_init(void)
1097 +{
1098 +       jz4740_clock_debugfs = debugfs_create_dir("jz4740-clock", NULL);
1099 +       if (IS_ERR(jz4740_clock_debugfs))
1100 +               jz4740_clock_debugfs = NULL;
1101 +}
1102 diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c
1103 new file mode 100644
1104 index 0000000..3954a20
1105 --- /dev/null
1106 +++ b/arch/mips/jz4740/clock.c
1107 @@ -0,0 +1,935 @@
1108 +/*
1109 + *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
1110 + *  JZ4740 SoC clock support
1111 + *
1112 + *  This program is free software; you can redistribute         it and/or modify it
1113 + *  under  the terms of         the GNU General  Public License as published by the
1114 + *  Free Software Foundation;  either version 2 of the License, or (at your
1115 + *  option) any later version.
1116 + *
1117 + *  You should have received a copy of the  GNU General Public License along
1118 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
1119 + *  675 Mass Ave, Cambridge, MA 02139, USA.
1120 + *
1121 + */
1122 +
1123 +#include <linux/kernel.h>
1124 +#include <linux/errno.h>
1125 +#include <linux/clk.h>
1126 +#include <linux/spinlock.h>
1127 +#include <linux/io.h>
1128 +#include <linux/module.h>
1129 +#include <linux/list.h>
1130 +#include <linux/err.h>
1131 +
1132 +#include <asm/mach-jz4740/clock.h>
1133 +#include <asm/mach-jz4740/base.h>
1134 +
1135 +#include "clock.h"
1136 +
1137 +#define JZ_REG_CLOCK_CTRL      0x00
1138 +#define JZ_REG_CLOCK_LOW_POWER 0x04
1139 +#define JZ_REG_CLOCK_PLL       0x10
1140 +#define JZ_REG_CLOCK_GATE      0x20
1141 +#define JZ_REG_CLOCK_SLEEP_CTRL        0x24
1142 +#define JZ_REG_CLOCK_I2S       0x60
1143 +#define JZ_REG_CLOCK_LCD       0x64
1144 +#define JZ_REG_CLOCK_MMC       0x68
1145 +#define JZ_REG_CLOCK_UHC       0x6C
1146 +#define JZ_REG_CLOCK_SPI       0x74
1147 +
1148 +#define JZ_CLOCK_CTRL_I2S_SRC_PLL      BIT(31)
1149 +#define JZ_CLOCK_CTRL_KO_ENABLE                BIT(30)
1150 +#define JZ_CLOCK_CTRL_UDC_SRC_PLL      BIT(29)
1151 +#define JZ_CLOCK_CTRL_UDIV_MASK                0x1f800000
1152 +#define JZ_CLOCK_CTRL_CHANGE_ENABLE    BIT(22)
1153 +#define JZ_CLOCK_CTRL_PLL_HALF         BIT(21)
1154 +#define JZ_CLOCK_CTRL_LDIV_MASK                0x001f0000
1155 +#define JZ_CLOCK_CTRL_UDIV_OFFSET      23
1156 +#define JZ_CLOCK_CTRL_LDIV_OFFSET      16
1157 +#define JZ_CLOCK_CTRL_MDIV_OFFSET      12
1158 +#define JZ_CLOCK_CTRL_PDIV_OFFSET       8
1159 +#define JZ_CLOCK_CTRL_HDIV_OFFSET       4
1160 +#define JZ_CLOCK_CTRL_CDIV_OFFSET       0
1161 +
1162 +#define JZ_CLOCK_GATE_UART0    BIT(0)
1163 +#define JZ_CLOCK_GATE_TCU      BIT(1)
1164 +#define JZ_CLOCK_GATE_RTC      BIT(2)
1165 +#define JZ_CLOCK_GATE_I2C      BIT(3)
1166 +#define JZ_CLOCK_GATE_SPI      BIT(4)
1167 +#define JZ_CLOCK_GATE_AIC      BIT(5)
1168 +#define JZ_CLOCK_GATE_I2S      BIT(6)
1169 +#define JZ_CLOCK_GATE_MMC      BIT(7)
1170 +#define JZ_CLOCK_GATE_ADC      BIT(8)
1171 +#define JZ_CLOCK_GATE_CIM      BIT(9)
1172 +#define JZ_CLOCK_GATE_LCD      BIT(10)
1173 +#define JZ_CLOCK_GATE_UDC      BIT(11)
1174 +#define JZ_CLOCK_GATE_DMAC     BIT(12)
1175 +#define JZ_CLOCK_GATE_IPU      BIT(13)
1176 +#define JZ_CLOCK_GATE_UHC      BIT(14)
1177 +#define JZ_CLOCK_GATE_UART1    BIT(15)
1178 +
1179 +#define JZ_CLOCK_I2S_DIV_MASK          0x01ff
1180 +
1181 +#define JZ_CLOCK_LCD_DIV_MASK          0x01ff
1182 +
1183 +#define JZ_CLOCK_MMC_DIV_MASK          0x001f
1184 +
1185 +#define JZ_CLOCK_UHC_DIV_MASK          0x000f
1186 +
1187 +#define JZ_CLOCK_SPI_SRC_PLL           BIT(31)
1188 +#define JZ_CLOCK_SPI_DIV_MASK          0x000f
1189 +
1190 +#define JZ_CLOCK_PLL_M_MASK            0x01ff
1191 +#define JZ_CLOCK_PLL_N_MASK            0x001f
1192 +#define JZ_CLOCK_PLL_OD_MASK           0x0003
1193 +#define JZ_CLOCK_PLL_STABLE            BIT(10)
1194 +#define JZ_CLOCK_PLL_BYPASS            BIT(9)
1195 +#define JZ_CLOCK_PLL_ENABLED           BIT(8)
1196 +#define JZ_CLOCK_PLL_STABLIZE_MASK     0x000f
1197 +#define JZ_CLOCK_PLL_M_OFFSET          23
1198 +#define JZ_CLOCK_PLL_N_OFFSET          18
1199 +#define JZ_CLOCK_PLL_OD_OFFSET         16
1200 +
1201 +#define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
1202 +#define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
1203 +
1204 +#define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7)
1205 +#define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6)
1206 +
1207 +static void __iomem *jz_clock_base;
1208 +static spinlock_t jz_clock_lock;
1209 +static LIST_HEAD(jz_clocks);
1210 +
1211 +struct main_clk {
1212 +       struct clk clk;
1213 +       uint32_t div_offset;
1214 +};
1215 +
1216 +struct divided_clk {
1217 +       struct clk clk;
1218 +       uint32_t reg;
1219 +       uint32_t mask;
1220 +};
1221 +
1222 +struct static_clk {
1223 +       struct clk clk;
1224 +       unsigned long rate;
1225 +};
1226 +
1227 +static uint32_t jz_clk_reg_read(int reg)
1228 +{
1229 +       return readl(jz_clock_base + reg);
1230 +}
1231 +
1232 +static void jz_clk_reg_write_mask(int reg, uint32_t val, uint32_t mask)
1233 +{
1234 +       uint32_t val2;
1235 +
1236 +       spin_lock(&jz_clock_lock);
1237 +       val2 = readl(jz_clock_base + reg);
1238 +       val2 &= ~mask;
1239 +       val2 |= val;
1240 +       writel(val2, jz_clock_base + reg);
1241 +       spin_unlock(&jz_clock_lock);
1242 +}
1243 +
1244 +static void jz_clk_reg_set_bits(int reg, uint32_t mask)
1245 +{
1246 +       uint32_t val;
1247 +
1248 +       spin_lock(&jz_clock_lock);
1249 +       val = readl(jz_clock_base + reg);
1250 +       val |= mask;
1251 +       writel(val, jz_clock_base + reg);
1252 +       spin_unlock(&jz_clock_lock);
1253 +}
1254 +
1255 +static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
1256 +{
1257 +       uint32_t val;
1258 +
1259 +       spin_lock(&jz_clock_lock);
1260 +       val = readl(jz_clock_base + reg);
1261 +       val &= ~mask;
1262 +       writel(val, jz_clock_base + reg);
1263 +       spin_unlock(&jz_clock_lock);
1264 +}
1265 +
1266 +static int jz_clk_enable_gating(struct clk *clk)
1267 +{
1268 +       if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
1269 +               return -EINVAL;
1270 +
1271 +       jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
1272 +       return 0;
1273 +}
1274 +
1275 +static int jz_clk_disable_gating(struct clk *clk)
1276 +{
1277 +       if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
1278 +               return -EINVAL;
1279 +
1280 +       jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
1281 +       return 0;
1282 +}
1283 +
1284 +static int jz_clk_is_enabled_gating(struct clk *clk)
1285 +{
1286 +       if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
1287 +               return 1;
1288 +
1289 +       return !(jz_clk_reg_read(JZ_REG_CLOCK_GATE) & clk->gate_bit);
1290 +}
1291 +
1292 +static unsigned long jz_clk_static_get_rate(struct clk *clk)
1293 +{
1294 +       return ((struct static_clk *)clk)->rate;
1295 +}
1296 +
1297 +static int jz_clk_ko_enable(struct clk *clk)
1298 +{
1299 +       jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
1300 +       return 0;
1301 +}
1302 +
1303 +static int jz_clk_ko_disable(struct clk *clk)
1304 +{
1305 +       jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
1306 +       return 0;
1307 +}
1308 +
1309 +static int jz_clk_ko_is_enabled(struct clk *clk)
1310 +{
1311 +       return !!(jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_KO_ENABLE);
1312 +}
1313 +
1314 +static const int pllno[] = {1, 2, 2, 4};
1315 +
1316 +static unsigned long jz_clk_pll_get_rate(struct clk *clk)
1317 +{
1318 +       uint32_t val;
1319 +       int m;
1320 +       int n;
1321 +       int od;
1322 +
1323 +       val = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
1324 +
1325 +       if (val & JZ_CLOCK_PLL_BYPASS)
1326 +               return clk_get_rate(clk->parent);
1327 +
1328 +       m = ((val >> 23) & 0x1ff) + 2;
1329 +       n = ((val >> 18) & 0x1f) + 2;
1330 +       od = (val >> 16) & 0x3;
1331 +
1332 +       return clk_get_rate(clk->parent) * (m / n) / pllno[od];
1333 +}
1334 +
1335 +static unsigned long jz_clk_pll_half_get_rate(struct clk *clk)
1336 +{
1337 +       uint32_t reg;
1338 +
1339 +       reg = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
1340 +       if (reg & JZ_CLOCK_CTRL_PLL_HALF)
1341 +               return jz_clk_pll_get_rate(clk->parent);
1342 +       return jz_clk_pll_get_rate(clk->parent) >> 1;
1343 +}
1344 +
1345 +static const int jz_clk_main_divs[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
1346 +
1347 +static unsigned long jz_clk_main_round_rate(struct clk *clk, unsigned long rate)
1348 +{
1349 +       unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
1350 +       int div;
1351 +
1352 +       div = parent_rate / rate;
1353 +       if (div > 32)
1354 +               return parent_rate / 32;
1355 +       else if (div < 1)
1356 +               return parent_rate;
1357 +
1358 +       div &= (0x3 << (ffs(div) - 1));
1359 +
1360 +       return parent_rate / div;
1361 +}
1362 +
1363 +static unsigned long jz_clk_main_get_rate(struct clk *clk)
1364 +{
1365 +       struct main_clk *mclk = (struct main_clk *)clk;
1366 +       uint32_t div;
1367 +
1368 +       div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
1369 +
1370 +       div >>= mclk->div_offset;
1371 +       div &= 0xf;
1372 +
1373 +       if (div >= ARRAY_SIZE(jz_clk_main_divs))
1374 +               div = ARRAY_SIZE(jz_clk_main_divs) - 1;
1375 +
1376 +       return jz_clk_pll_get_rate(clk->parent) / jz_clk_main_divs[div];
1377 +}
1378 +
1379 +static int jz_clk_main_set_rate(struct clk *clk, unsigned long rate)
1380 +{
1381 +       struct main_clk *mclk = (struct main_clk *)clk;
1382 +       int i;
1383 +       int div;
1384 +       unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
1385 +
1386 +       rate = jz_clk_main_round_rate(clk, rate);
1387 +
1388 +       div = parent_rate / rate;
1389 +
1390 +       i = (ffs(div) - 1) << 1;
1391 +       if (i > 0 && !(div & BIT(i-1)))
1392 +               i -= 1;
1393 +
1394 +       jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, i << mclk->div_offset,
1395 +                               0xf << mclk->div_offset);
1396 +
1397 +       return 0;
1398 +}
1399 +
1400 +static struct clk_ops jz_clk_static_ops = {
1401 +       .get_rate = jz_clk_static_get_rate,
1402 +       .enable = jz_clk_enable_gating,
1403 +       .disable = jz_clk_disable_gating,
1404 +       .is_enabled = jz_clk_is_enabled_gating,
1405 +};
1406 +
1407 +static struct static_clk jz_clk_ext = {
1408 +       .clk = {
1409 +               .name = "ext",
1410 +               .gate_bit = JZ4740_CLK_NOT_GATED,
1411 +               .ops = &jz_clk_static_ops,
1412 +       },
1413 +};
1414 +
1415 +static struct clk_ops jz_clk_pll_ops = {
1416 +       .get_rate = jz_clk_static_get_rate,
1417 +};
1418 +
1419 +static struct clk jz_clk_pll = {
1420 +       .name = "pll",
1421 +       .parent = &jz_clk_ext.clk,
1422 +       .ops = &jz_clk_pll_ops,
1423 +};
1424 +
1425 +static struct clk_ops jz_clk_pll_half_ops = {
1426 +       .get_rate = jz_clk_pll_half_get_rate,
1427 +};
1428 +
1429 +static struct clk jz_clk_pll_half = {
1430 +       .name = "pll half",
1431 +       .parent = &jz_clk_pll,
1432 +       .ops = &jz_clk_pll_half_ops,
1433 +};
1434 +
1435 +static const struct clk_ops jz_clk_main_ops = {
1436 +       .get_rate = jz_clk_main_get_rate,
1437 +       .set_rate = jz_clk_main_set_rate,
1438 +       .round_rate = jz_clk_main_round_rate,
1439 +};
1440 +
1441 +static struct main_clk jz_clk_cpu = {
1442 +       .clk = {
1443 +               .name = "cclk",
1444 +               .parent = &jz_clk_pll,
1445 +               .ops = &jz_clk_main_ops,
1446 +       },
1447 +       .div_offset = JZ_CLOCK_CTRL_CDIV_OFFSET,
1448 +};
1449 +
1450 +static struct main_clk jz_clk_memory = {
1451 +       .clk = {
1452 +               .name = "mclk",
1453 +               .parent = &jz_clk_pll,
1454 +               .ops = &jz_clk_main_ops,
1455 +       },
1456 +       .div_offset = JZ_CLOCK_CTRL_MDIV_OFFSET,
1457 +};
1458 +
1459 +static struct main_clk jz_clk_high_speed_peripheral = {
1460 +       .clk = {
1461 +               .name = "hclk",
1462 +               .parent = &jz_clk_pll,
1463 +               .ops = &jz_clk_main_ops,
1464 +       },
1465 +       .div_offset = JZ_CLOCK_CTRL_HDIV_OFFSET,
1466 +};
1467 +
1468 +
1469 +static struct main_clk jz_clk_low_speed_peripheral = {
1470 +       .clk = {
1471 +               .name = "pclk",
1472 +               .parent = &jz_clk_pll,
1473 +               .ops = &jz_clk_main_ops,
1474 +       },
1475 +       .div_offset = JZ_CLOCK_CTRL_PDIV_OFFSET,
1476 +};
1477 +
1478 +static const struct clk_ops jz_clk_ko_ops = {
1479 +       .enable = jz_clk_ko_enable,
1480 +       .disable = jz_clk_ko_disable,
1481 +       .is_enabled = jz_clk_ko_is_enabled,
1482 +};
1483 +
1484 +static struct clk jz_clk_ko = {
1485 +       .name = "cko",
1486 +       .parent = &jz_clk_memory.clk,
1487 +       .ops = &jz_clk_ko_ops,
1488 +};
1489 +
1490 +static int jz_clk_spi_set_parent(struct clk *clk, struct clk *parent)
1491 +{
1492 +       if (parent == &jz_clk_pll)
1493 +               jz_clk_reg_set_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
1494 +       else if (parent == &jz_clk_ext.clk)
1495 +               jz_clk_reg_clear_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
1496 +       else
1497 +               return -EINVAL;
1498 +
1499 +       clk->parent = parent;
1500 +
1501 +       return 0;
1502 +}
1503 +
1504 +static int jz_clk_i2s_set_parent(struct clk *clk, struct clk *parent)
1505 +{
1506 +       if (parent == &jz_clk_pll_half)
1507 +               jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
1508 +       else if (parent == &jz_clk_ext.clk)
1509 +               jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
1510 +       else
1511 +               return -EINVAL;
1512 +
1513 +       clk->parent = parent;
1514 +
1515 +       return 0;
1516 +}
1517 +
1518 +static int jz_clk_udc_enable(struct clk *clk)
1519 +{
1520 +       jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL,
1521 +                       JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
1522 +
1523 +       return 0;
1524 +}
1525 +
1526 +static int jz_clk_udc_disable(struct clk *clk)
1527 +{
1528 +       jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL,
1529 +                       JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
1530 +
1531 +       return 0;
1532 +}
1533 +
1534 +static int jz_clk_udc_is_enabled(struct clk *clk)
1535 +{
1536 +       return !!(jz_clk_reg_read(JZ_REG_CLOCK_SLEEP_CTRL) &
1537 +                       JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
1538 +}
1539 +static int jz_clk_udc_set_parent(struct clk *clk, struct clk *parent)
1540 +{
1541 +       if (parent == &jz_clk_pll_half)
1542 +               jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
1543 +       else if (parent == &jz_clk_ext.clk)
1544 +               jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
1545 +       else
1546 +               return -EINVAL;
1547 +
1548 +       clk->parent = parent;
1549 +
1550 +       return 0;
1551 +}
1552 +
1553 +static int jz_clk_udc_set_rate(struct clk *clk, unsigned long rate)
1554 +{
1555 +       int div;
1556 +
1557 +       if (clk->parent == &jz_clk_ext.clk)
1558 +               return -EINVAL;
1559 +
1560 +       div = clk_get_rate(clk->parent) / rate - 1;
1561 +
1562 +       if (div < 0)
1563 +               div = 0;
1564 +       else if (div > 63)
1565 +               div = 63;
1566 +
1567 +       jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_UDIV_OFFSET,
1568 +                               JZ_CLOCK_CTRL_UDIV_MASK);
1569 +       return 0;
1570 +}
1571 +
1572 +static unsigned long jz_clk_udc_get_rate(struct clk *clk)
1573 +{
1574 +       int div;
1575 +
1576 +       if (clk->parent == &jz_clk_ext.clk)
1577 +               return clk_get_rate(clk->parent);
1578 +
1579 +       div = (jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_UDIV_MASK);
1580 +       div >>= JZ_CLOCK_CTRL_UDIV_OFFSET;
1581 +       div += 1;
1582 +
1583 +       return clk_get_rate(clk->parent) / div;
1584 +}
1585 +
1586 +static unsigned long jz_clk_divided_get_rate(struct clk *clk)
1587 +{
1588 +       struct divided_clk *dclk = (struct divided_clk *)clk;
1589 +       int div;
1590 +
1591 +       if (clk->parent == &jz_clk_ext.clk)
1592 +               return clk_get_rate(clk->parent);
1593 +
1594 +       div = (jz_clk_reg_read(dclk->reg) & dclk->mask) + 1;
1595 +
1596 +       return clk_get_rate(clk->parent) / div;
1597 +}
1598 +
1599 +static int jz_clk_divided_set_rate(struct clk *clk, unsigned long rate)
1600 +{
1601 +       struct divided_clk *dclk = (struct divided_clk *)clk;
1602 +       int div;
1603 +
1604 +       if (clk->parent == &jz_clk_ext.clk)
1605 +               return -EINVAL;
1606 +
1607 +       div = clk_get_rate(clk->parent) / rate - 1;
1608 +
1609 +       if (div < 0)
1610 +               div = 0;
1611 +       else if (div > dclk->mask)
1612 +               div = dclk->mask;
1613 +
1614 +       jz_clk_reg_write_mask(dclk->reg, div, dclk->mask);
1615 +
1616 +       return 0;
1617 +}
1618 +
1619 +static unsigned long jz_clk_ldclk_round_rate(struct clk *clk, unsigned long rate)
1620 +{
1621 +       int div;
1622 +       unsigned long parent_rate = jz_clk_pll_half_get_rate(clk->parent);
1623 +
1624 +       if (rate > 150000000)
1625 +               return 150000000;
1626 +
1627 +       div = parent_rate / rate;
1628 +       if (div < 1)
1629 +               div = 1;
1630 +       else if (div > 32)
1631 +               div = 32;
1632 +
1633 +       return parent_rate / div;
1634 +}
1635 +
1636 +static int jz_clk_ldclk_set_rate(struct clk *clk, unsigned long rate)
1637 +{
1638 +       int div;
1639 +
1640 +       if (rate > 150000000)
1641 +               return -EINVAL;
1642 +
1643 +       div = jz_clk_pll_half_get_rate(clk->parent) / rate - 1;
1644 +       if (div < 0)
1645 +               div = 0;
1646 +       else if (div > 31)
1647 +               div = 31;
1648 +
1649 +       jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_LDIV_OFFSET,
1650 +                               JZ_CLOCK_CTRL_LDIV_MASK);
1651 +
1652 +       return 0;
1653 +}
1654 +
1655 +static unsigned long jz_clk_ldclk_get_rate(struct clk *clk)
1656 +{
1657 +       int div;
1658 +
1659 +       div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_LDIV_MASK;
1660 +       div >>= JZ_CLOCK_CTRL_LDIV_OFFSET;
1661 +
1662 +       return jz_clk_pll_half_get_rate(clk->parent) / (div + 1);
1663 +}
1664 +
1665 +static const struct clk_ops jz_clk_ops_ld = {
1666 +       .set_rate = jz_clk_ldclk_set_rate,
1667 +       .get_rate = jz_clk_ldclk_get_rate,
1668 +       .round_rate = jz_clk_ldclk_round_rate,
1669 +       .enable = jz_clk_enable_gating,
1670 +       .disable = jz_clk_disable_gating,
1671 +       .is_enabled = jz_clk_is_enabled_gating,
1672 +};
1673 +
1674 +static struct clk jz_clk_ld = {
1675 +       .name = "lcd",
1676 +       .gate_bit = JZ_CLOCK_GATE_LCD,
1677 +       .parent = &jz_clk_pll_half,
1678 +       .ops = &jz_clk_ops_ld,
1679 +};
1680 +
1681 +/* TODO: ops!!! */
1682 +static struct clk jz_clk_cim_mclk = {
1683 +       .name = "cim_mclk",
1684 +       .parent = &jz_clk_high_speed_peripheral.clk,
1685 +};
1686 +
1687 +static struct static_clk jz_clk_cim_pclk = {
1688 +       .clk = {
1689 +               .name = "cim_pclk",
1690 +               .gate_bit = JZ_CLOCK_GATE_CIM,
1691 +               .ops = &jz_clk_static_ops,
1692 +       },
1693 +};
1694 +
1695 +static const struct clk_ops jz_clk_i2s_ops = {
1696 +       .set_rate = jz_clk_divided_set_rate,
1697 +       .get_rate = jz_clk_divided_get_rate,
1698 +       .enable = jz_clk_enable_gating,
1699 +       .disable = jz_clk_disable_gating,
1700 +       .is_enabled = jz_clk_is_enabled_gating,
1701 +       .set_parent = jz_clk_i2s_set_parent,
1702 +};
1703 +
1704 +static const struct clk_ops jz_clk_spi_ops = {
1705 +       .set_rate = jz_clk_divided_set_rate,
1706 +       .get_rate = jz_clk_divided_get_rate,
1707 +       .enable = jz_clk_enable_gating,
1708 +       .disable = jz_clk_disable_gating,
1709 +       .is_enabled = jz_clk_is_enabled_gating,
1710 +       .set_parent = jz_clk_spi_set_parent,
1711 +};
1712 +
1713 +static const struct clk_ops jz_clk_divided_ops = {
1714 +       .set_rate = jz_clk_divided_set_rate,
1715 +       .get_rate = jz_clk_divided_get_rate,
1716 +       .enable = jz_clk_enable_gating,
1717 +       .disable = jz_clk_disable_gating,
1718 +       .is_enabled = jz_clk_is_enabled_gating,
1719 +};
1720 +
1721 +static struct divided_clk jz4740_clock_divided_clks[] = {
1722 +       {
1723 +               .clk = {
1724 +                       .name = "lcd_pclk",
1725 +                       .parent = &jz_clk_pll_half,
1726 +                       .gate_bit = JZ4740_CLK_NOT_GATED,
1727 +                       .ops = &jz_clk_divided_ops,
1728 +               },
1729 +               .reg = JZ_REG_CLOCK_LCD,
1730 +               .mask = JZ_CLOCK_LCD_DIV_MASK,
1731 +       },
1732 +       {
1733 +               .clk = {
1734 +                       .name = "i2s",
1735 +                       .parent = &jz_clk_ext.clk,
1736 +                       .gate_bit = JZ_CLOCK_GATE_I2S,
1737 +                       .ops = &jz_clk_i2s_ops,
1738 +               },
1739 +               .reg = JZ_REG_CLOCK_I2S,
1740 +               .mask = JZ_CLOCK_I2S_DIV_MASK,
1741 +       },
1742 +       {
1743 +               .clk = {
1744 +                       .name = "spi",
1745 +                       .parent = &jz_clk_ext.clk,
1746 +                       .gate_bit = JZ_CLOCK_GATE_SPI,
1747 +                       .ops = &jz_clk_spi_ops,
1748 +               },
1749 +               .reg = JZ_REG_CLOCK_SPI,
1750 +               .mask = JZ_CLOCK_SPI_DIV_MASK,
1751 +       },
1752 +       {
1753 +               .clk = {
1754 +                       .name = "mmc",
1755 +                       .parent = &jz_clk_pll_half,
1756 +                       .gate_bit = JZ_CLOCK_GATE_MMC,
1757 +                       .ops = &jz_clk_divided_ops,
1758 +               },
1759 +               .reg = JZ_REG_CLOCK_MMC,
1760 +               .mask = JZ_CLOCK_MMC_DIV_MASK,
1761 +       },
1762 +       {
1763 +               .clk = {
1764 +                       .name = "uhc",
1765 +                       .parent = &jz_clk_pll_half,
1766 +                       .gate_bit = JZ_CLOCK_GATE_UHC,
1767 +                       .ops = &jz_clk_divided_ops,
1768 +               },
1769 +               .reg = JZ_REG_CLOCK_UHC,
1770 +               .mask = JZ_CLOCK_UHC_DIV_MASK,
1771 +       },
1772 +};
1773 +
1774 +static const struct clk_ops jz_clk_udc_ops = {
1775 +       .set_parent = jz_clk_udc_set_parent,
1776 +       .set_rate = jz_clk_udc_set_rate,
1777 +       .get_rate = jz_clk_udc_get_rate,
1778 +       .enable = jz_clk_udc_enable,
1779 +       .disable = jz_clk_udc_disable,
1780 +       .is_enabled = jz_clk_udc_is_enabled,
1781 +};
1782 +
1783 +static const struct clk_ops jz_clk_simple_ops = {
1784 +       .enable = jz_clk_enable_gating,
1785 +       .disable = jz_clk_disable_gating,
1786 +       .is_enabled = jz_clk_is_enabled_gating,
1787 +};
1788 +
1789 +static struct clk jz4740_clock_simple_clks[] = {
1790 +       {
1791 +               .name = "udc",
1792 +               .parent = &jz_clk_ext.clk,
1793 +               .ops = &jz_clk_udc_ops,
1794 +       },
1795 +       {
1796 +               .name = "uart0",
1797 +               .parent = &jz_clk_ext.clk,
1798 +               .gate_bit = JZ_CLOCK_GATE_UART0,
1799 +               .ops = &jz_clk_simple_ops,
1800 +       },
1801 +       {
1802 +               .name = "uart1",
1803 +               .parent = &jz_clk_ext.clk,
1804 +               .gate_bit = JZ_CLOCK_GATE_UART1,
1805 +               .ops = &jz_clk_simple_ops,
1806 +       },
1807 +       {
1808 +               .name = "dma",
1809 +               .parent = &jz_clk_high_speed_peripheral.clk,
1810 +               .gate_bit = JZ_CLOCK_GATE_UART0,
1811 +               .ops = &jz_clk_simple_ops,
1812 +       },
1813 +       {
1814 +               .name = "ipu",
1815 +               .parent = &jz_clk_high_speed_peripheral.clk,
1816 +               .gate_bit = JZ_CLOCK_GATE_IPU,
1817 +               .ops = &jz_clk_simple_ops,
1818 +       },
1819 +       {
1820 +               .name = "adc",
1821 +               .parent = &jz_clk_ext.clk,
1822 +               .gate_bit = JZ_CLOCK_GATE_ADC,
1823 +               .ops = &jz_clk_simple_ops,
1824 +       },
1825 +       {
1826 +               .name = "i2c",
1827 +               .parent = &jz_clk_ext.clk,
1828 +               .gate_bit = JZ_CLOCK_GATE_I2C,
1829 +               .ops = &jz_clk_simple_ops,
1830 +       },
1831 +       {
1832 +               .name = "aic",
1833 +               .parent = &jz_clk_ext.clk,
1834 +               .gate_bit = JZ_CLOCK_GATE_AIC,
1835 +               .ops = &jz_clk_simple_ops,
1836 +       },
1837 +};
1838 +
1839 +static struct static_clk jz_clk_rtc = {
1840 +       .clk = {
1841 +               .name = "rtc",
1842 +               .gate_bit = JZ_CLOCK_GATE_RTC,
1843 +               .ops = &jz_clk_static_ops,
1844 +       },
1845 +       .rate = 32768,
1846 +};
1847 +
1848 +int clk_enable(struct clk *clk)
1849 +{
1850 +       if (!clk->ops->enable)
1851 +               return -EINVAL;
1852 +
1853 +       return clk->ops->enable(clk);
1854 +}
1855 +EXPORT_SYMBOL_GPL(clk_enable);
1856 +
1857 +void clk_disable(struct clk *clk)
1858 +{
1859 +       if (clk->ops->disable)
1860 +               clk->ops->disable(clk);
1861 +}
1862 +EXPORT_SYMBOL_GPL(clk_disable);
1863 +
1864 +int clk_is_enabled(struct clk *clk)
1865 +{
1866 +       if (clk->ops->is_enabled)
1867 +               return clk->ops->is_enabled(clk);
1868 +
1869 +       return 1;
1870 +}
1871 +
1872 +unsigned long clk_get_rate(struct clk *clk)
1873 +{
1874 +       if (clk->ops->get_rate)
1875 +               return clk->ops->get_rate(clk);
1876 +       if (clk->parent)
1877 +               return clk_get_rate(clk->parent);
1878 +
1879 +       return -EINVAL;
1880 +}
1881 +EXPORT_SYMBOL_GPL(clk_get_rate);
1882 +
1883 +int clk_set_rate(struct clk *clk, unsigned long rate)
1884 +{
1885 +       if (!clk->ops->set_rate)
1886 +               return -EINVAL;
1887 +       return clk->ops->set_rate(clk, rate);
1888 +}
1889 +EXPORT_SYMBOL_GPL(clk_set_rate);
1890 +
1891 +long clk_round_rate(struct clk *clk, unsigned long rate)
1892 +{
1893 +       if (clk->ops->round_rate)
1894 +               return clk->ops->round_rate(clk, rate);
1895 +
1896 +       return -EINVAL;
1897 +}
1898 +EXPORT_SYMBOL_GPL(clk_round_rate);
1899 +
1900 +int clk_set_parent(struct clk *clk, struct clk *parent)
1901 +{
1902 +       int ret;
1903 +
1904 +       if (!clk->ops->set_parent)
1905 +               return -EINVAL;
1906 +
1907 +       clk_disable(clk);
1908 +       ret = clk->ops->set_parent(clk, parent);
1909 +       clk_enable(clk);
1910 +
1911 +       jz4740_clock_debugfs_update_parent(clk);
1912 +
1913 +       return ret;
1914 +}
1915 +EXPORT_SYMBOL_GPL(clk_set_parent);
1916 +
1917 +struct clk *clk_get(struct device *dev, const char *name)
1918 +{
1919 +       struct clk *clk;
1920 +
1921 +       list_for_each_entry(clk, &jz_clocks, list) {
1922 +           if (strcmp(clk->name, name) == 0)
1923 +                       return clk;
1924 +       }
1925 +       return ERR_PTR(-ENOENT);
1926 +}
1927 +EXPORT_SYMBOL_GPL(clk_get);
1928 +
1929 +void clk_put(struct clk *clk)
1930 +{
1931 +}
1932 +EXPORT_SYMBOL_GPL(clk_put);
1933 +
1934 +
1935 +static inline void clk_add(struct clk *clk)
1936 +{
1937 +       list_add_tail(&clk->list, &jz_clocks);
1938 +
1939 +       jz4740_clock_debugfs_add_clk(clk);
1940 +}
1941 +
1942 +static void clk_register_clks(void)
1943 +{
1944 +       size_t i;
1945 +
1946 +       clk_add(&jz_clk_ext.clk);
1947 +       clk_add(&jz_clk_pll);
1948 +       clk_add(&jz_clk_pll_half);
1949 +       clk_add(&jz_clk_cpu.clk);
1950 +       clk_add(&jz_clk_high_speed_peripheral.clk);
1951 +       clk_add(&jz_clk_low_speed_peripheral.clk);
1952 +       clk_add(&jz_clk_ko);
1953 +       clk_add(&jz_clk_ld);
1954 +       clk_add(&jz_clk_cim_mclk);
1955 +       clk_add(&jz_clk_cim_pclk.clk);
1956 +       clk_add(&jz_clk_rtc.clk);
1957 +
1958 +       for (i = 0; i < ARRAY_SIZE(jz4740_clock_divided_clks); ++i)
1959 +               clk_add(&jz4740_clock_divided_clks[i].clk);
1960 +
1961 +       for (i = 0; i < ARRAY_SIZE(jz4740_clock_simple_clks); ++i)
1962 +               clk_add(&jz4740_clock_simple_clks[i]);
1963 +}
1964 +
1965 +void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
1966 +{
1967 +       switch (mode) {
1968 +       case JZ4740_WAIT_MODE_IDLE:
1969 +               jz_clk_reg_clear_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
1970 +               break;
1971 +       case JZ4740_WAIT_MODE_SLEEP:
1972 +               jz_clk_reg_set_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
1973 +               break;
1974 +       }
1975 +}
1976 +
1977 +void jz4740_clock_udc_disable_auto_suspend(void)
1978 +{
1979 +       jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
1980 +}
1981 +EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend);
1982 +
1983 +void jz4740_clock_udc_enable_auto_suspend(void)
1984 +{
1985 +       jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
1986 +}
1987 +EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
1988 +
1989 +void jz4740_clock_suspend(void)
1990 +{
1991 +       jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE,
1992 +               JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
1993 +
1994 +       jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
1995 +}
1996 +
1997 +void jz4740_clock_resume(void)
1998 +{
1999 +       uint32_t pll;
2000 +
2001 +       jz_clk_reg_set_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
2002 +
2003 +       do {
2004 +               pll = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
2005 +       } while (!(pll & JZ_CLOCK_PLL_STABLE));
2006 +
2007 +       jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE,
2008 +               JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
2009 +}
2010 +
2011 +int jz4740_clock_init(void)
2012 +{
2013 +       uint32_t val;
2014 +
2015 +       jz_clock_base = ioremap(CPHYSADDR(JZ4740_CPM_BASE_ADDR), 0x100);
2016 +       if (!jz_clock_base)
2017 +               return -EBUSY;
2018 +
2019 +       spin_lock_init(&jz_clock_lock);
2020 +
2021 +       jz_clk_ext.rate = jz4740_clock_bdata.ext_rate;
2022 +       jz_clk_rtc.rate = jz4740_clock_bdata.rtc_rate;
2023 +
2024 +       val = jz_clk_reg_read(JZ_REG_CLOCK_SPI);
2025 +
2026 +       if (val & JZ_CLOCK_SPI_SRC_PLL)
2027 +               jz4740_clock_divided_clks[1].clk.parent = &jz_clk_pll_half;
2028 +
2029 +       val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
2030 +
2031 +       if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL)
2032 +               jz4740_clock_divided_clks[0].clk.parent = &jz_clk_pll_half;
2033 +
2034 +       if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL)
2035 +               jz4740_clock_simple_clks[0].parent = &jz_clk_pll_half;
2036 +
2037 +       jz4740_clock_debugfs_init();
2038 +
2039 +       clk_register_clks();
2040 +
2041 +       return 0;
2042 +}
2043 diff --git a/arch/mips/jz4740/clock.h b/arch/mips/jz4740/clock.h
2044 new file mode 100644
2045 index 0000000..96010a4
2046 --- /dev/null
2047 +++ b/arch/mips/jz4740/clock.h
2048 @@ -0,0 +1,75 @@
2049 +/*
2050 + *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
2051 + *  JZ4740 SoC clock support
2052 + *
2053 + *  This program is free software; you can redistribute         it and/or modify it
2054 + *  under  the terms of         the GNU General  Public License as published by the
2055 + *  Free Software Foundation;  either version 2 of the License, or (at your
2056 + *  option) any later version.
2057 + *
2058 + *  You should have received a copy of the  GNU General Public License along
2059 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
2060 + *  675 Mass Ave, Cambridge, MA 02139, USA.
2061 + *
2062 + */
2063 +
2064 +#ifndef __JZ4740_CLOCK_H__
2065 +#define __JZ4740_CLOCK_H__
2066 +
2067 +struct jz4740_clock_board_data {
2068 +       unsigned long ext_rate;
2069 +       unsigned long rtc_rate;
2070 +};
2071 +
2072 +extern struct jz4740_clock_board_data jz4740_clock_bdata;
2073 +
2074 +int jz4740_clock_init(void);
2075 +void jz4740_clock_suspend(void);
2076 +void jz4740_clock_resume(void);
2077 +
2078 +struct clk;
2079 +
2080 +struct clk_ops {
2081 +       unsigned long (*get_rate)(struct clk *clk);
2082 +       unsigned long (*round_rate)(struct clk *clk, unsigned long rate);
2083 +       int (*set_rate)(struct clk *clk, unsigned long rate);
2084 +       int (*enable)(struct clk *clk);
2085 +       int (*disable)(struct clk *clk);
2086 +       int (*is_enabled)(struct clk *clk);
2087 +
2088 +       int (*set_parent)(struct clk *clk, struct clk *parent);
2089 +
2090 +};
2091 +
2092 +struct clk {
2093 +       const char *name;
2094 +       struct clk *parent;
2095 +
2096 +       uint32_t gate_bit;
2097 +
2098 +       const struct clk_ops *ops;
2099 +
2100 +       struct list_head list;
2101 +
2102 +#ifdef CONFIG_DEBUG_FS
2103 +       struct dentry *debugfs_entry;
2104 +       struct dentry *debugfs_parent_entry;
2105 +#endif
2106 +
2107 +};
2108 +
2109 +#define JZ4740_CLK_NOT_GATED ((uint32_t)-1)
2110 +
2111 +int clk_is_enabled(struct clk *clk);
2112 +
2113 +#ifdef CONFIG_DEBUG_FS
2114 +void jz4740_clock_debugfs_init(void);
2115 +void jz4740_clock_debugfs_add_clk(struct clk *clk);
2116 +void jz4740_clock_debugfs_update_parent(struct clk *clk);
2117 +#else
2118 +static inline void jz4740_clock_debugfs_init(void) {};
2119 +static inline void jz4740_clock_debugfs_add_clk(struct clk *clk) {};
2120 +static inline void jz4740_clock_debugfs_update_parent(struct clk *clk) {};
2121 +#endif
2122 +
2123 +#endif
2124 diff --git a/arch/mips/jz4740/dma.c b/arch/mips/jz4740/dma.c
2125 new file mode 100644
2126 index 0000000..217ddc8
2127 --- /dev/null
2128 +++ b/arch/mips/jz4740/dma.c
2129 @@ -0,0 +1,339 @@
2130 +/*
2131 + *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
2132 + *  JZ4740 SoC DMA support
2133 + *
2134 + *  This program is free software; you can redistribute         it and/or modify it
2135 + *  under  the terms of         the GNU General  Public License as published by the
2136 + *  Free Software Foundation;  either version 2 of the License, or (at your
2137 + *  option) any later version.
2138 + *
2139 + *  You should have received a copy of the  GNU General Public License along
2140 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
2141 + *  675 Mass Ave, Cambridge, MA 02139, USA.
2142 + *
2143 + */
2144 +
2145 +#include <linux/kernel.h>
2146 +#include <linux/module.h>
2147 +#include <linux/spinlock.h>
2148 +#include <linux/interrupt.h>
2149 +
2150 +#include <linux/dma-mapping.h>
2151 +#include <asm/mach-jz4740/dma.h>
2152 +#include <asm/mach-jz4740/base.h>
2153 +
2154 +#define JZ_REG_DMA_SRC_ADDR(x)         (0x00 + (x) * 0x20)
2155 +#define JZ_REG_DMA_DST_ADDR(x)         (0x04 + (x) * 0x20)
2156 +#define JZ_REG_DMA_TRANSFER_COUNT(x)   (0x08 + (x) * 0x20)
2157 +#define JZ_REG_DMA_REQ_TYPE(x)         (0x0C + (x) * 0x20)
2158 +#define JZ_REG_DMA_STATUS_CTRL(x)      (0x10 + (x) * 0x20)
2159 +#define JZ_REG_DMA_CMD(x)              (0x14 + (x) * 0x20)
2160 +#define JZ_REG_DMA_DESC_ADDR(x)                (0x18 + (x) * 0x20)
2161 +
2162 +#define JZ_REG_DMA_CTRL                        0x300
2163 +#define JZ_REG_DMA_IRQ                 0x304
2164 +#define JZ_REG_DMA_DOORBELL            0x308
2165 +#define JZ_REG_DMA_DOORBELL_SET                0x30C
2166 +
2167 +#define JZ_DMA_STATUS_CTRL_NO_DESC             BIT(31)
2168 +#define JZ_DMA_STATUS_CTRL_DESC_INV            BIT(6)
2169 +#define JZ_DMA_STATUS_CTRL_ADDR_ERR            BIT(4)
2170 +#define JZ_DMA_STATUS_CTRL_TRANSFER_DONE       BIT(3)
2171 +#define JZ_DMA_STATUS_CTRL_HALT                        BIT(2)
2172 +#define JZ_DMA_STATUS_CTRL_COUNT_TERMINATE     BIT(1)
2173 +#define JZ_DMA_STATUS_CTRL_ENABLE              BIT(0)
2174 +
2175 +#define JZ_DMA_CMD_SRC_INC                     BIT(23)
2176 +#define JZ_DMA_CMD_DST_INC                     BIT(22)
2177 +#define JZ_DMA_CMD_RDIL_MASK                   (0xf << 16)
2178 +#define JZ_DMA_CMD_SRC_WIDTH_MASK              (0x3 << 14)
2179 +#define JZ_DMA_CMD_DST_WIDTH_MASK              (0x3 << 12)
2180 +#define JZ_DMA_CMD_INTERVAL_LENGTH_MASK                (0x7 << 8)
2181 +#define JZ_DMA_CMD_BLOCK_MODE                  BIT(7)
2182 +#define JZ_DMA_CMD_DESC_VALID                  BIT(4)
2183 +#define JZ_DMA_CMD_DESC_VALID_MODE             BIT(3)
2184 +#define JZ_DMA_CMD_VALID_IRQ_ENABLE            BIT(2)
2185 +#define JZ_DMA_CMD_TRANSFER_IRQ_ENABLE         BIT(1)
2186 +#define JZ_DMA_CMD_LINK_ENABLE                 BIT(0)
2187 +
2188 +#define JZ_DMA_CMD_FLAGS_OFFSET 22
2189 +#define JZ_DMA_CMD_RDIL_OFFSET 16
2190 +#define JZ_DMA_CMD_SRC_WIDTH_OFFSET 14
2191 +#define JZ_DMA_CMD_DST_WIDTH_OFFSET 12
2192 +#define JZ_DMA_CMD_TRANSFER_SIZE_OFFSET 8
2193 +#define JZ_DMA_CMD_MODE_OFFSET 7
2194 +
2195 +#define JZ_DMA_CTRL_PRIORITY_MASK      (0x3 << 8)
2196 +#define JZ_DMA_CTRL_HALT               BIT(3)
2197 +#define JZ_DMA_CTRL_ADDRESS_ERROR      BIT(2)
2198 +#define JZ_DMA_CTRL_ENABLE             BIT(0)
2199 +
2200 +
2201 +static void __iomem *jz4740_dma_base;
2202 +static spinlock_t jz4740_dma_lock;
2203 +
2204 +static inline uint32_t jz4740_dma_read(size_t reg)
2205 +{
2206 +       return readl(jz4740_dma_base + reg);
2207 +}
2208 +
2209 +static inline void jz4740_dma_write(size_t reg, uint32_t val)
2210 +{
2211 +       writel(val, jz4740_dma_base + reg);
2212 +}
2213 +
2214 +static inline void jz4740_dma_write_mask(size_t reg, uint32_t val, uint32_t mask)
2215 +{
2216 +       uint32_t val2;
2217 +       val2 = jz4740_dma_read(reg);
2218 +       val2 &= ~mask;
2219 +       val2 |= val;
2220 +       jz4740_dma_write(reg, val2);
2221 +}
2222 +
2223 +struct jz4740_dma_chan {
2224 +       unsigned int id;
2225 +       void *dev;
2226 +       const char *name;
2227 +
2228 +       enum jz4740_dma_flags flags;
2229 +       uint32_t transfer_shift;
2230 +
2231 +       jz4740_dma_complete_callback_t complete_cb;
2232 +
2233 +       unsigned used:1;
2234 +};
2235 +
2236 +#define JZ4740_DMA_CHANNEL(_id) { .id = _id }
2237 +
2238 +struct jz4740_dma_chan jz4740_dma_channels[] = {
2239 +       JZ4740_DMA_CHANNEL(0),
2240 +       JZ4740_DMA_CHANNEL(1),
2241 +       JZ4740_DMA_CHANNEL(2),
2242 +       JZ4740_DMA_CHANNEL(3),
2243 +       JZ4740_DMA_CHANNEL(4),
2244 +       JZ4740_DMA_CHANNEL(5),
2245 +};
2246 +
2247 +struct jz4740_dma_chan *jz4740_dma_request(void *dev, const char *name)
2248 +{
2249 +       unsigned int i;
2250 +       struct jz4740_dma_chan *dma = NULL;
2251 +
2252 +       spin_lock(&jz4740_dma_lock);
2253 +
2254 +       for (i = 0; i < ARRAY_SIZE(jz4740_dma_channels); ++i) {
2255 +               if (!jz4740_dma_channels[i].used) {
2256 +                       dma = &jz4740_dma_channels[i];
2257 +                       dma->used = 1;
2258 +                       break;
2259 +               }
2260 +       }
2261 +
2262 +       spin_unlock(&jz4740_dma_lock);
2263 +
2264 +       if (!dma)
2265 +               return NULL;
2266 +
2267 +       dma->dev = dev;
2268 +       dma->name = name;
2269 +
2270 +       return dma;
2271 +}
2272 +EXPORT_SYMBOL_GPL(jz4740_dma_request);
2273 +
2274 +void jz4740_dma_configure(struct jz4740_dma_chan *dma,
2275 +       const struct jz4740_dma_config *config)
2276 +{
2277 +       uint32_t cmd;
2278 +       uint32_t ctrl;
2279 +
2280 +       switch (config->transfer_size) {
2281 +       case JZ4740_DMA_TRANSFER_SIZE_2BYTE:
2282 +               dma->transfer_shift = 1;
2283 +               break;
2284 +       case JZ4740_DMA_TRANSFER_SIZE_4BYTE:
2285 +               dma->transfer_shift = 2;
2286 +               break;
2287 +       case JZ4740_DMA_TRANSFER_SIZE_16BYTE:
2288 +               dma->transfer_shift = 4;
2289 +               break;
2290 +       case JZ4740_DMA_TRANSFER_SIZE_32BYTE:
2291 +               dma->transfer_shift = 5;
2292 +               break;
2293 +       default:
2294 +               dma->transfer_shift = 0;
2295 +               break;
2296 +       }
2297 +
2298 +       cmd = config->flags << JZ_DMA_CMD_FLAGS_OFFSET;
2299 +       cmd |= config->src_width << JZ_DMA_CMD_SRC_WIDTH_OFFSET;
2300 +       cmd |= config->dst_width << JZ_DMA_CMD_DST_WIDTH_OFFSET;
2301 +       cmd |= config->transfer_size << JZ_DMA_CMD_TRANSFER_SIZE_OFFSET;
2302 +       cmd |= config->mode << JZ_DMA_CMD_MODE_OFFSET;
2303 +       cmd |= JZ_DMA_CMD_TRANSFER_IRQ_ENABLE;
2304 +
2305 +       ctrl = JZ_DMA_STATUS_CTRL_NO_DESC;
2306 +       ctrl |= JZ_DMA_STATUS_CTRL_HALT;
2307 +
2308 +       jz4740_dma_write(JZ_REG_DMA_CMD(dma->id), cmd);
2309 +       jz4740_dma_write(JZ_REG_DMA_STATUS_CTRL(dma->id), ctrl);
2310 +       jz4740_dma_write(JZ_REG_DMA_REQ_TYPE(dma->id), config->request_type);
2311 +}
2312 +EXPORT_SYMBOL_GPL(jz4740_dma_configure);
2313 +
2314 +void jz4740_dma_set_src_addr(struct jz4740_dma_chan *dma, dma_addr_t src)
2315 +{
2316 +       jz4740_dma_write(JZ_REG_DMA_SRC_ADDR(dma->id), src);
2317 +}
2318 +EXPORT_SYMBOL_GPL(jz4740_dma_set_src_addr);
2319 +
2320 +void jz4740_dma_set_dst_addr(struct jz4740_dma_chan *dma, dma_addr_t dst)
2321 +{
2322 +       jz4740_dma_write(JZ_REG_DMA_DST_ADDR(dma->id), dst);
2323 +}
2324 +EXPORT_SYMBOL_GPL(jz4740_dma_set_dst_addr);
2325 +
2326 +void jz4740_dma_set_transfer_count(struct jz4740_dma_chan *dma, uint32_t count)
2327 +{
2328 +       count >>= dma->transfer_shift;
2329 +       jz4740_dma_write(JZ_REG_DMA_TRANSFER_COUNT(dma->id), count);
2330 +}
2331 +EXPORT_SYMBOL_GPL(jz4740_dma_set_transfer_count);
2332 +
2333 +void jz4740_dma_set_complete_cb(struct jz4740_dma_chan *dma,
2334 +       jz4740_dma_complete_callback_t cb)
2335 +{
2336 +       dma->complete_cb = cb;
2337 +}
2338 +EXPORT_SYMBOL_GPL(jz4740_dma_set_complete_cb);
2339 +
2340 +void jz4740_dma_free(struct jz4740_dma_chan *dma)
2341 +{
2342 +       dma->dev = NULL;
2343 +       dma->complete_cb = NULL;
2344 +       dma->used = 0;
2345 +}
2346 +EXPORT_SYMBOL_GPL(jz4740_dma_free);
2347 +
2348 +void jz4740_dma_enable(struct jz4740_dma_chan *dma)
2349 +{
2350 +       jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id),
2351 +                       JZ_DMA_STATUS_CTRL_ENABLE,
2352 +                       JZ_DMA_STATUS_CTRL_ENABLE | JZ_DMA_STATUS_CTRL_HALT);
2353 +
2354 +       jz4740_dma_write_mask(JZ_REG_DMA_CTRL,
2355 +                       JZ_DMA_CTRL_ENABLE,
2356 +                       JZ_DMA_CTRL_ENABLE | JZ_DMA_CTRL_HALT);
2357 +}
2358 +EXPORT_SYMBOL_GPL(jz4740_dma_enable);
2359 +
2360 +void jz4740_dma_disable(struct jz4740_dma_chan *dma)
2361 +{
2362 +       jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0,
2363 +                       JZ_DMA_STATUS_CTRL_ENABLE);
2364 +}
2365 +EXPORT_SYMBOL_GPL(jz4740_dma_disable);
2366 +
2367 +uint32_t jz4740_dma_get_residue(const struct jz4740_dma_chan *dma)
2368 +{
2369 +       uint32_t residue;
2370 +       residue = jz4740_dma_read(JZ_REG_DMA_TRANSFER_COUNT(dma->id));
2371 +       return residue << dma->transfer_shift;
2372 +}
2373 +EXPORT_SYMBOL_GPL(jz4740_dma_get_residue);
2374 +
2375 +static void jz4740_dma_chan_irq(struct jz4740_dma_chan *dma)
2376 +{
2377 +       uint32_t status;
2378 +
2379 +       status = jz4740_dma_read(JZ_REG_DMA_STATUS_CTRL(dma->id));
2380 +
2381 +       jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0,
2382 +               JZ_DMA_STATUS_CTRL_ENABLE | JZ_DMA_STATUS_CTRL_TRANSFER_DONE);
2383 +
2384 +       if (dma->complete_cb)
2385 +               dma->complete_cb(dma, 0, dma->dev);
2386 +}
2387 +
2388 +static irqreturn_t jz4740_dma_irq(int irq, void *dev_id)
2389 +{
2390 +       uint32_t irq_status;
2391 +       unsigned int i;
2392 +
2393 +       irq_status = readl(jz4740_dma_base + JZ_REG_DMA_IRQ);
2394 +
2395 +       for (i = 0; i < 6; ++i) {
2396 +               if (irq_status & (1 << i))
2397 +                       jz4740_dma_chan_irq(&jz4740_dma_channels[i]);
2398 +       }
2399 +
2400 +       return IRQ_HANDLED;
2401 +}
2402 +
2403 +#if 0
2404 +static struct jz4740_dma_config dma_test_config = {
2405 +       .src_width = JZ4740_DMA_WIDTH_32BIT,
2406 +       .dst_width = JZ4740_DMA_WIDTH_32BIT,
2407 +       .transfer_size = JZ4740_DMA_TRANSFER_SIZE_4BYTE,
2408 +       .request_type = JZ4740_DMA_TYPE_AUTO_REQUEST,
2409 +       .flags = JZ4740_DMA_SRC_AUTOINC | JZ4740_DMA_DST_AUTOINC,
2410 +       .mode = JZ4740_DMA_MODE_BLOCK,
2411 +};
2412 +
2413 +static void jz4740_dma_test(void)
2414 +{
2415 +       uint32_t *buf1, *buf2;
2416 +       dma_addr_t addr1, addr2;
2417 +       struct jz4740_dma_chan *dma = jz4740_dma_request(NULL, "dma test");
2418 +       int i;
2419 +
2420 +       printk("STARTING DMA TEST\n");
2421 +
2422 +       buf1 = dma_alloc_coherent(NULL,
2423 +                                               0x1000,
2424 +                                               &addr1, GFP_KERNEL);
2425 +       buf2 = dma_alloc_coherent(NULL,
2426 +                                               0x1000,
2427 +                                               &addr2, GFP_KERNEL);
2428 +
2429 +       for (i = 0; i < 0x400; ++i)
2430 +               buf1[i] = i;
2431 +
2432 +
2433 +       jz4740_dma_configure(dma, &dma_test_config);
2434 +       jz4740_dma_set_src_addr(dma, addr1);
2435 +       jz4740_dma_set_dst_addr(dma, addr2);
2436 +       jz4740_dma_set_transfer_count(dma, 0x1000);
2437 +
2438 +       jz4740_dma_enable(dma);
2439 +       mdelay(2000);
2440 +
2441 +       for (i = 0; i < 0x400; ++i) {
2442 +               if (buf2[i] != i)
2443 +                       printk("OH MY GOD: %x %x\n", i, buf2[i]);
2444 +       }
2445 +
2446 +       printk("DMA TEST DONE\n");
2447 +}
2448 +#endif
2449 +
2450 +static int jz4740_dma_init(void)
2451 +{
2452 +       unsigned int ret;
2453 +
2454 +       jz4740_dma_base = ioremap(CPHYSADDR(JZ4740_DMAC_BASE_ADDR), 0x400);
2455 +
2456 +       if (!jz4740_dma_base)
2457 +               return -EBUSY;
2458 +
2459 +       spin_lock_init(&jz4740_dma_lock);
2460 +
2461 +       ret = request_irq(JZ4740_IRQ_DMAC, jz4740_dma_irq, 0, "DMA", NULL);
2462 +
2463 +       if (ret)
2464 +               printk(KERN_ERR "JZ4740 DMA: Failed to request irq: %d\n", ret);
2465 +
2466 +       return ret;
2467 +}
2468 +arch_initcall(jz4740_dma_init);
2469 diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c
2470 new file mode 100644
2471 index 0000000..14d8288
2472 --- /dev/null
2473 +++ b/arch/mips/jz4740/gpio.c
2474 @@ -0,0 +1,598 @@
2475 +/*
2476 + *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
2477 + *  JZ4740 platform GPIO support
2478 + *
2479 + *  This program is free software; you can redistribute         it and/or modify it
2480 + *  under  the terms of         the GNU General  Public License as published by the
2481 + *  Free Software Foundation;  either version 2 of the License, or (at your
2482 + *  option) any later version.
2483 + *
2484 + *  You should have received a copy of the  GNU General Public License along
2485 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
2486 + *  675 Mass Ave, Cambridge, MA 02139, USA.
2487 + *
2488 + */
2489 +
2490 +#include <linux/kernel.h>
2491 +#include <linux/module.h>
2492 +#include <linux/init.h>
2493 +
2494 +#include <linux/spinlock.h>
2495 +#include <linux/sysdev.h>
2496 +#include <linux/io.h>
2497 +#include <linux/gpio.h>
2498 +#include <linux/delay.h>
2499 +#include <linux/interrupt.h>
2500 +#include <linux/bitops.h>
2501 +
2502 +#include <linux/debugfs.h>
2503 +#include <linux/seq_file.h>
2504 +
2505 +#include <asm/mach-jz4740/base.h>
2506 +
2507 +#define JZ4740_GPIO_BASE_A (32*0)
2508 +#define JZ4740_GPIO_BASE_B (32*1)
2509 +#define JZ4740_GPIO_BASE_C (32*2)
2510 +#define JZ4740_GPIO_BASE_D (32*3)
2511 +
2512 +#define JZ4740_GPIO_NUM_A 32
2513 +#define JZ4740_GPIO_NUM_B 32
2514 +#define JZ4740_GPIO_NUM_C 31
2515 +#define JZ4740_GPIO_NUM_D 32
2516 +
2517 +#define JZ4740_IRQ_GPIO_BASE_A (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_A)
2518 +#define JZ4740_IRQ_GPIO_BASE_B (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_B)
2519 +#define JZ4740_IRQ_GPIO_BASE_C (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_C)
2520 +#define JZ4740_IRQ_GPIO_BASE_D (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_D)
2521 +
2522 +#define JZ4740_IRQ_GPIO_A(num) (JZ4740_IRQ_GPIO_BASE_A + num)
2523 +#define JZ4740_IRQ_GPIO_B(num) (JZ4740_IRQ_GPIO_BASE_B + num)
2524 +#define JZ4740_IRQ_GPIO_C(num) (JZ4740_IRQ_GPIO_BASE_C + num)
2525 +#define JZ4740_IRQ_GPIO_D(num) (JZ4740_IRQ_GPIO_BASE_D + num)
2526 +
2527 +#define JZ_REG_GPIO_PIN                        0x00
2528 +#define JZ_REG_GPIO_DATA               0x10
2529 +#define JZ_REG_GPIO_DATA_SET           0x14
2530 +#define JZ_REG_GPIO_DATA_CLEAR         0x18
2531 +#define JZ_REG_GPIO_MASK               0x20
2532 +#define JZ_REG_GPIO_MASK_SET           0x24
2533 +#define JZ_REG_GPIO_MASK_CLEAR         0x28
2534 +#define JZ_REG_GPIO_PULL               0x30
2535 +#define JZ_REG_GPIO_PULL_SET           0x34
2536 +#define JZ_REG_GPIO_PULL_CLEAR         0x38
2537 +#define JZ_REG_GPIO_FUNC               0x40
2538 +#define JZ_REG_GPIO_FUNC_SET           0x44
2539 +#define JZ_REG_GPIO_FUNC_CLEAR         0x48
2540 +#define JZ_REG_GPIO_SELECT             0x50
2541 +#define JZ_REG_GPIO_SELECT_SET         0x54
2542 +#define JZ_REG_GPIO_SELECT_CLEAR       0x58
2543 +#define JZ_REG_GPIO_DIRECTION          0x60
2544 +#define JZ_REG_GPIO_DIRECTION_SET      0x64
2545 +#define JZ_REG_GPIO_DIRECTION_CLEAR    0x68
2546 +#define JZ_REG_GPIO_TRIGGER            0x70
2547 +#define JZ_REG_GPIO_TRIGGER_SET                0x74
2548 +#define JZ_REG_GPIO_TRIGGER_CLEAR      0x78
2549 +#define JZ_REG_GPIO_FLAG               0x80
2550 +#define JZ_REG_GPIO_FLAG_CLEAR         0x14
2551 +
2552 +
2553 +#define GPIO_TO_BIT(gpio) BIT(gpio & 0x1f)
2554 +#define GPIO_TO_REG(gpio, reg) (gpio_to_jz_gpio_chip(gpio)->base + (reg))
2555 +#define CHIP_TO_REG(chip, reg) (gpio_chip_to_jz_gpio_chip(chip)->base + (reg))
2556 +
2557 +struct jz_gpio_chip {
2558 +       unsigned int irq;
2559 +       unsigned int irq_base;
2560 +       uint32_t wakeup;
2561 +       uint32_t suspend_mask;
2562 +       uint32_t edge_trigger_both;
2563 +
2564 +       void __iomem *base;
2565 +
2566 +       spinlock_t lock;
2567 +
2568 +       struct gpio_chip gpio_chip;
2569 +       struct irq_chip irq_chip;
2570 +       struct sys_device sysdev;
2571 +};
2572 +
2573 +
2574 +static struct jz_gpio_chip jz4740_gpio_chips[];
2575 +
2576 +static inline struct jz_gpio_chip *gpio_to_jz_gpio_chip(unsigned int gpio)
2577 +{
2578 +       return &jz4740_gpio_chips[gpio >> 5];
2579 +}
2580 +
2581 +static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *gpio_chip)
2582 +{
2583 +       return container_of(gpio_chip, struct jz_gpio_chip, gpio_chip);
2584 +}
2585 +
2586 +static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(unsigned int irq)
2587 +{
2588 +       return get_irq_chip_data(irq);
2589 +}
2590 +
2591 +static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg)
2592 +{
2593 +       writel(GPIO_TO_BIT(gpio), GPIO_TO_REG(gpio, reg));
2594 +}
2595 +
2596 +int jz_gpio_set_function(int gpio, enum jz_gpio_function function)
2597 +{
2598 +       if (function == JZ_GPIO_FUNC_NONE) {
2599 +               jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_CLEAR);
2600 +               jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR);
2601 +               jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR);
2602 +       } else {
2603 +               jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_SET);
2604 +               jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR);
2605 +               switch (function) {
2606 +               case JZ_GPIO_FUNC1:
2607 +                       jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR);
2608 +                       break;
2609 +               case JZ_GPIO_FUNC3:
2610 +                       jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_SET);
2611 +               case JZ_GPIO_FUNC2: /* Falltrough */
2612 +                       jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_SET);
2613 +                       break;
2614 +               default:
2615 +                       BUG();
2616 +                       break;
2617 +               }
2618 +       }
2619 +
2620 +       return 0;
2621 +}
2622 +EXPORT_SYMBOL_GPL(jz_gpio_set_function);
2623 +
2624 +int jz_gpio_bulk_request(const struct jz_gpio_bulk_request *request, size_t num)
2625 +{
2626 +       size_t i;
2627 +       int ret;
2628 +
2629 +       for (i = 0; i < num; ++i, ++request) {
2630 +               ret = gpio_request(request->gpio, request->name);
2631 +               if (ret)
2632 +                       goto err;
2633 +               jz_gpio_set_function(request->gpio, request->function);
2634 +       }
2635 +
2636 +       return 0;
2637 +
2638 +err:
2639 +       for (--request; i > 0; --i, --request) {
2640 +               gpio_free(request->gpio);
2641 +               jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
2642 +       }
2643 +
2644 +       return ret;
2645 +}
2646 +EXPORT_SYMBOL_GPL(jz_gpio_bulk_request);
2647 +
2648 +void jz_gpio_bulk_free(const struct jz_gpio_bulk_request *request, size_t num)
2649 +{
2650 +       size_t i;
2651 +
2652 +       for (i = 0; i < num; ++i, ++request) {
2653 +               gpio_free(request->gpio);
2654 +               jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
2655 +       }
2656 +
2657 +}
2658 +EXPORT_SYMBOL_GPL(jz_gpio_bulk_free);
2659 +
2660 +void jz_gpio_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num)
2661 +{
2662 +       size_t i;
2663 +
2664 +       for (i = 0; i < num; ++i, ++request) {
2665 +               jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
2666 +               jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_DIRECTION_CLEAR);
2667 +               jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_PULL_SET);
2668 +       }
2669 +}
2670 +EXPORT_SYMBOL_GPL(jz_gpio_bulk_suspend);
2671 +
2672 +void jz_gpio_bulk_resume(const struct jz_gpio_bulk_request *request, size_t num)
2673 +{
2674 +       size_t i;
2675 +
2676 +       for (i = 0; i < num; ++i, ++request)
2677 +               jz_gpio_set_function(request->gpio, request->function);
2678 +}
2679 +EXPORT_SYMBOL_GPL(jz_gpio_bulk_resume);
2680 +
2681 +void jz_gpio_enable_pullup(unsigned gpio)
2682 +{
2683 +       jz_gpio_write_bit(gpio, JZ_REG_GPIO_PULL_CLEAR);
2684 +}
2685 +EXPORT_SYMBOL_GPL(jz_gpio_enable_pullup);
2686 +
2687 +void jz_gpio_disable_pullup(unsigned gpio)
2688 +{
2689 +       jz_gpio_write_bit(gpio, JZ_REG_GPIO_PULL_SET);
2690 +}
2691 +EXPORT_SYMBOL_GPL(jz_gpio_disable_pullup);
2692 +
2693 +static int jz_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
2694 +{
2695 +       return !!(readl(CHIP_TO_REG(chip, JZ_REG_GPIO_PIN)) & BIT(gpio));
2696 +}
2697 +
2698 +static void jz_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
2699 +{
2700 +       uint32_t __iomem *reg = CHIP_TO_REG(chip, JZ_REG_GPIO_DATA_SET);
2701 +       reg += !value;
2702 +       writel(BIT(gpio), reg);
2703 +}
2704 +
2705 +static int jz_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
2706 +       int value)
2707 +{
2708 +       writel(BIT(gpio), CHIP_TO_REG(chip, JZ_REG_GPIO_DIRECTION_SET));
2709 +       jz_gpio_set_value(chip, gpio, value);
2710 +
2711 +       return 0;
2712 +}
2713 +
2714 +static int jz_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
2715 +{
2716 +       writel(BIT(gpio), CHIP_TO_REG(chip, JZ_REG_GPIO_DIRECTION_CLEAR));
2717 +
2718 +       return 0;
2719 +}
2720 +
2721 +int jz_gpio_port_direction_input(int port, uint32_t mask)
2722 +{
2723 +       writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_CLEAR));
2724 +
2725 +       return 0;
2726 +}
2727 +EXPORT_SYMBOL(jz_gpio_port_direction_input);
2728 +
2729 +int jz_gpio_port_direction_output(int port, uint32_t mask)
2730 +{
2731 +       writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_SET));
2732 +
2733 +       return 0;
2734 +}
2735 +EXPORT_SYMBOL(jz_gpio_port_direction_output);
2736 +
2737 +void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask)
2738 +{
2739 +       writel(~value & mask, GPIO_TO_REG(port, JZ_REG_GPIO_DATA_CLEAR));
2740 +       writel(value & mask, GPIO_TO_REG(port, JZ_REG_GPIO_DATA_SET));
2741 +}
2742 +EXPORT_SYMBOL(jz_gpio_port_set_value);
2743 +
2744 +uint32_t jz_gpio_port_get_value(int port, uint32_t mask)
2745 +{
2746 +       uint32_t value = readl(GPIO_TO_REG(port, JZ_REG_GPIO_PIN));
2747 +
2748 +       return value & mask;
2749 +}
2750 +EXPORT_SYMBOL(jz_gpio_port_get_value);
2751 +
2752 +
2753 +#define IRQ_TO_GPIO(irq) (irq - JZ4740_IRQ_GPIO(0))
2754 +#define IRQ_TO_BIT(irq) BIT(IRQ_TO_GPIO(irq) & 0x1f)
2755 +
2756 +#define IRQ_TO_REG(irq, reg)  GPIO_TO_REG(IRQ_TO_GPIO(irq), reg)
2757 +
2758 +static void jz_gpio_irq_demux_handler(unsigned int irq, struct irq_desc *desc)
2759 +{
2760 +       uint32_t flag;
2761 +       unsigned int gpio_irq;
2762 +       unsigned int gpio_bank;
2763 +       struct jz_gpio_chip *chip = get_irq_desc_data(desc);
2764 +
2765 +       gpio_bank = JZ4740_IRQ_GPIO0 - irq;
2766 +
2767 +       flag = readl(chip->base + JZ_REG_GPIO_FLAG);
2768 +
2769 +       gpio_irq = ffs(flag) - 1;
2770 +
2771 +       if (chip->edge_trigger_both & BIT(gpio_irq)) {
2772 +               uint32_t value = readl(chip->base + JZ_REG_GPIO_PIN);
2773 +               if (value & BIT(gpio_irq)) {
2774 +                       writel(BIT(gpio_irq),
2775 +                               chip->base + JZ_REG_GPIO_DIRECTION_CLEAR);
2776 +               } else {
2777 +                       writel(BIT(gpio_irq),
2778 +                               chip->base + JZ_REG_GPIO_DIRECTION_SET);
2779 +               }
2780 +       }
2781 +
2782 +       gpio_irq += (gpio_bank << 5) + JZ4740_IRQ_GPIO(0);
2783 +
2784 +       generic_handle_irq(gpio_irq);
2785 +};
2786 +
2787 +static inline void jz_gpio_set_irq_bit(unsigned int irq, unsigned int reg)
2788 +{
2789 +       writel(IRQ_TO_BIT(irq), IRQ_TO_REG(irq, reg));
2790 +}
2791 +
2792 +static void jz_gpio_irq_mask(unsigned int irq)
2793 +{
2794 +       jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_SET);
2795 +};
2796 +
2797 +static void jz_gpio_irq_unmask(unsigned int irq)
2798 +{
2799 +       jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_CLEAR);
2800 +};
2801 +
2802 +
2803 +/* TODO: Check if function is gpio */
2804 +static unsigned int jz_gpio_irq_startup(unsigned int irq)
2805 +{
2806 +       struct irq_desc *desc = irq_to_desc(irq);
2807 +
2808 +       jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_SET);
2809 +
2810 +       desc->status &= ~IRQ_MASKED;
2811 +       jz_gpio_irq_unmask(irq);
2812 +
2813 +       return 0;
2814 +}
2815 +
2816 +static void jz_gpio_irq_shutdown(unsigned int irq)
2817 +{
2818 +       struct irq_desc *desc = irq_to_desc(irq);
2819 +
2820 +       jz_gpio_irq_mask(irq);
2821 +       desc->status |= IRQ_MASKED;
2822 +
2823 +       /* Set direction to input */
2824 +       jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
2825 +       jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_CLEAR);
2826 +}
2827 +
2828 +static void jz_gpio_irq_ack(unsigned int irq)
2829 +{
2830 +       jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_FLAG_CLEAR);
2831 +};
2832 +
2833 +static int jz_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
2834 +{
2835 +       struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq);
2836 +       struct irq_desc *desc = irq_to_desc(irq);
2837 +
2838 +       jz_gpio_irq_mask(irq);
2839 +
2840 +       if (flow_type == IRQ_TYPE_EDGE_BOTH) {
2841 +               uint32_t value = readl(IRQ_TO_REG(irq, JZ_REG_GPIO_PIN));
2842 +               if (value & IRQ_TO_BIT(irq))
2843 +                       flow_type = IRQ_TYPE_EDGE_FALLING;
2844 +               else
2845 +                       flow_type = IRQ_TYPE_EDGE_RISING;
2846 +               chip->edge_trigger_both |= IRQ_TO_BIT(irq);
2847 +       } else {
2848 +               chip->edge_trigger_both &= ~IRQ_TO_BIT(irq);
2849 +       }
2850 +
2851 +       switch (flow_type) {
2852 +       case IRQ_TYPE_EDGE_RISING:
2853 +               jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET);
2854 +               jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET);
2855 +               break;
2856 +       case IRQ_TYPE_EDGE_FALLING:
2857 +               jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
2858 +               jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET);
2859 +               break;
2860 +       case IRQ_TYPE_LEVEL_HIGH:
2861 +               jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET);
2862 +               jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR);
2863 +               break;
2864 +       case IRQ_TYPE_LEVEL_LOW:
2865 +               jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR);
2866 +               jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR);
2867 +               break;
2868 +       default:
2869 +               return -EINVAL;
2870 +       }
2871 +
2872 +       if (!(desc->status & IRQ_MASKED))
2873 +               jz_gpio_irq_unmask(irq);
2874 +
2875 +       return 0;
2876 +}
2877 +
2878 +static int jz_gpio_irq_set_wake(unsigned int irq, unsigned int on)
2879 +{
2880 +       struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq);
2881 +       spin_lock(&chip->lock);
2882 +       if (on)
2883 +               chip->wakeup |= IRQ_TO_BIT(irq);
2884 +       else
2885 +               chip->wakeup &= ~IRQ_TO_BIT(irq);
2886 +       spin_unlock(&chip->lock);
2887 +
2888 +       set_irq_wake(chip->irq, on);
2889 +       return 0;
2890 +}
2891 +
2892 +int gpio_to_irq(unsigned gpio)
2893 +{
2894 +       return JZ4740_IRQ_GPIO(0) + gpio;
2895 +}
2896 +EXPORT_SYMBOL_GPL(gpio_to_irq);
2897 +
2898 +int irq_to_gpio(unsigned gpio)
2899 +{
2900 +       return IRQ_TO_GPIO(gpio);
2901 +}
2902 +EXPORT_SYMBOL_GPL(irq_to_gpio);
2903 +
2904 +/*
2905 + * This lock class tells lockdep that GPIO irqs are in a different
2906 + * category than their parents, so it won't report false recursion.
2907 + */
2908 +static struct lock_class_key gpio_lock_class;
2909 +
2910 +#define JZ4740_GPIO_CHIP(_bank) { \
2911 +       .irq_base = JZ4740_IRQ_GPIO_BASE_ ## _bank, \
2912 +       .gpio_chip = { \
2913 +               .label = "Bank " # _bank, \
2914 +               .owner = THIS_MODULE, \
2915 +               .set = jz_gpio_set_value, \
2916 +               .get = jz_gpio_get_value, \
2917 +               .direction_output = jz_gpio_direction_output, \
2918 +               .direction_input = jz_gpio_direction_input, \
2919 +               .base = JZ4740_GPIO_BASE_ ## _bank, \
2920 +               .ngpio = JZ4740_GPIO_NUM_ ## _bank, \
2921 +       }, \
2922 +       .irq_chip =  { \
2923 +               .name = "GPIO Bank " # _bank, \
2924 +               .mask = jz_gpio_irq_mask, \
2925 +               .unmask = jz_gpio_irq_unmask, \
2926 +               .ack = jz_gpio_irq_ack, \
2927 +               .startup = jz_gpio_irq_startup, \
2928 +               .shutdown = jz_gpio_irq_shutdown, \
2929 +               .set_type = jz_gpio_irq_set_type, \
2930 +               .set_wake = jz_gpio_irq_set_wake, \
2931 +       }, \
2932 +}
2933 +
2934 +static struct jz_gpio_chip jz4740_gpio_chips[] = {
2935 +       JZ4740_GPIO_CHIP(A),
2936 +       JZ4740_GPIO_CHIP(B),
2937 +       JZ4740_GPIO_CHIP(C),
2938 +       JZ4740_GPIO_CHIP(D),
2939 +};
2940 +
2941 +static inline struct jz_gpio_chip *sysdev_to_chip(struct sys_device *dev)
2942 +{
2943 +       return container_of(dev, struct jz_gpio_chip, sysdev);
2944 +}
2945 +
2946 +static int jz4740_gpio_suspend(struct sys_device *dev, pm_message_t state)
2947 +{
2948 +       struct jz_gpio_chip *chip = sysdev_to_chip(dev);
2949 +
2950 +       chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK);
2951 +       writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET);
2952 +       writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR);
2953 +
2954 +       return 0;
2955 +}
2956 +
2957 +static int jz4740_gpio_resume(struct sys_device *dev)
2958 +{
2959 +       struct jz_gpio_chip *chip = sysdev_to_chip(dev);
2960 +       uint32_t mask = chip->suspend_mask;
2961 +
2962 +       writel(~mask, chip->base + JZ_REG_GPIO_MASK_CLEAR);
2963 +       writel(mask, chip->base + JZ_REG_GPIO_MASK_SET);
2964 +
2965 +       return 0;
2966 +}
2967 +
2968 +static struct sysdev_class jz4740_gpio_sysdev_class = {
2969 +       .name = "gpio",
2970 +       .suspend = jz4740_gpio_suspend,
2971 +       .resume = jz4740_gpio_resume,
2972 +};
2973 +
2974 +static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
2975 +{
2976 +       int ret, irq;
2977 +
2978 +       chip->sysdev.id = id;
2979 +       chip->sysdev.cls = &jz4740_gpio_sysdev_class;
2980 +       ret = sysdev_register(&chip->sysdev);
2981 +
2982 +       if (ret)
2983 +           return ret;
2984 +
2985 +       spin_lock_init(&chip->lock);
2986 +
2987 +       chip->base = ioremap(CPHYSADDR(JZ4740_GPIO_BASE_ADDR) + (id * 0x100), 0x100);
2988 +
2989 +       gpiochip_add(&chip->gpio_chip);
2990 +
2991 +       chip->irq = JZ4740_IRQ_INTC_GPIO(id);
2992 +       set_irq_data(chip->irq, chip);
2993 +       set_irq_chained_handler(chip->irq, jz_gpio_irq_demux_handler);
2994 +
2995 +       for (irq = chip->irq_base; irq < chip->irq_base + chip->gpio_chip.ngpio; ++irq) {
2996 +               lockdep_set_class(&irq_desc[irq].lock, &gpio_lock_class);
2997 +               set_irq_chip_and_handler(irq, &chip->irq_chip, handle_level_irq);
2998 +               set_irq_chip_data(irq, chip);
2999 +       }
3000 +
3001 +       return 0;
3002 +}
3003 +
3004 +int __init jz_gpiolib_init(void)
3005 +{
3006 +       unsigned int i;
3007 +       int ret;
3008 +
3009 +       ret = sysdev_class_register(&jz4740_gpio_sysdev_class);
3010 +       if (ret)
3011 +               return ret;
3012 +
3013 +       for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i) {
3014 +           jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i);
3015 +       }
3016 +
3017 +       printk(KERN_INFO "JZ4740 GPIO initalized\n");
3018 +
3019 +       return 0;
3020 +}
3021 +
3022 +#ifdef CONFIG_DEBUG_FS
3023 +
3024 +static inline void gpio_seq_reg(struct seq_file *s, struct jz_gpio_chip *chip,
3025 +       const char *name, unsigned int reg)
3026 +{
3027 +       seq_printf(s, "\t%s: %08x\n", name, readl(chip->base + reg));
3028 +}
3029 +
3030 +
3031 +static int gpio_regs_show(struct seq_file *s, void *unused)
3032 +{
3033 +       struct jz_gpio_chip *chip = jz4740_gpio_chips;
3034 +       int i;
3035 +
3036 +       for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i, ++chip) {
3037 +               seq_printf(s, "GPIO %d: \n", i);
3038 +               gpio_seq_reg(s, chip, "Pin", JZ_REG_GPIO_PIN);
3039 +               gpio_seq_reg(s, chip, "Data", JZ_REG_GPIO_DATA);
3040 +               gpio_seq_reg(s, chip, "Mask", JZ_REG_GPIO_MASK);
3041 +               gpio_seq_reg(s, chip, "Pull", JZ_REG_GPIO_PULL);
3042 +               gpio_seq_reg(s, chip, "Func", JZ_REG_GPIO_FUNC);
3043 +               gpio_seq_reg(s, chip, "Select", JZ_REG_GPIO_SELECT);
3044 +               gpio_seq_reg(s, chip, "Direction", JZ_REG_GPIO_DIRECTION);
3045 +               gpio_seq_reg(s, chip, "Trigger", JZ_REG_GPIO_TRIGGER);
3046 +               gpio_seq_reg(s, chip, "Flag", JZ_REG_GPIO_FLAG);
3047 +       }
3048 +
3049 +       return 0;
3050 +}
3051 +
3052 +static int gpio_regs_open(struct inode *inode, struct file *file)
3053 +{
3054 +       return single_open(file, gpio_regs_show, NULL);
3055 +}
3056 +
3057 +static const struct file_operations gpio_regs_operations = {
3058 +       .open           = gpio_regs_open,
3059 +       .read           = seq_read,
3060 +       .llseek         = seq_lseek,
3061 +       .release        = single_release,
3062 +};
3063 +
3064 +static int __init gpio_debugfs_init(void)
3065 +{
3066 +       (void) debugfs_create_file("jz_regs_gpio", S_IFREG | S_IRUGO,
3067 +                               NULL, NULL, &gpio_regs_operations);
3068 +       return 0;
3069 +}
3070 +subsys_initcall(gpio_debugfs_init);
3071 +
3072 +#endif
3073 diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
3074 new file mode 100644
3075 index 0000000..a8c76af
3076 --- /dev/null
3077 +++ b/arch/mips/jz4740/irq.c
3078 @@ -0,0 +1,174 @@
3079 +/*
3080 + *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
3081 + *  JZ4740 platform IRQ support
3082 + *
3083 + *  This program is free software; you can redistribute         it and/or modify it
3084 + *  under  the terms of         the GNU General  Public License as published by the
3085 + *  Free Software Foundation;  either version 2 of the License, or (at your
3086 + *  option) any later version.
3087 + *
3088 + *  You should have received a copy of the  GNU General Public License along
3089 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
3090 + *  675 Mass Ave, Cambridge, MA 02139, USA.
3091 + *
3092 + */
3093 +
3094 +#include <linux/errno.h>
3095 +#include <linux/init.h>
3096 +#include <linux/types.h>
3097 +#include <linux/interrupt.h>
3098 +#include <linux/ioport.h>
3099 +#include <linux/timex.h>
3100 +#include <linux/slab.h>
3101 +#include <linux/delay.h>
3102 +
3103 +#include <linux/debugfs.h>
3104 +#include <linux/seq_file.h>
3105 +
3106 +#include <asm/io.h>
3107 +#include <asm/mipsregs.h>
3108 +#include <asm/irq_cpu.h>
3109 +
3110 +#include <asm/mach-jz4740/base.h>
3111 +
3112 +static void __iomem *jz_intc_base;
3113 +static uint32_t jz_intc_wakeup;
3114 +static uint32_t jz_intc_saved;
3115 +
3116 +#define JZ_REG_INTC_STATUS     0x00
3117 +#define JZ_REG_INTC_MASK       0x04
3118 +#define JZ_REG_INTC_SET_MASK   0x08
3119 +#define JZ_REG_INTC_CLEAR_MASK 0x0c
3120 +#define JZ_REG_INTC_PENDING    0x10
3121 +
3122 +#define IRQ_BIT(x) BIT((x) - JZ4740_IRQ_BASE)
3123 +
3124 +static void intc_irq_unmask(unsigned int irq)
3125 +{
3126 +       writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
3127 +}
3128 +
3129 +static void intc_irq_mask(unsigned int irq)
3130 +{
3131 +       writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_SET_MASK);
3132 +}
3133 +
3134 +static void intc_irq_ack(unsigned int irq)
3135 +{
3136 +       writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_PENDING);
3137 +}
3138 +
3139 +static int intc_irq_set_wake(unsigned int irq, unsigned int on)
3140 +{
3141 +       if (on)
3142 +               jz_intc_wakeup |= IRQ_BIT(irq);
3143 +       else
3144 +               jz_intc_wakeup &= ~IRQ_BIT(irq);
3145 +
3146 +       return 0;
3147 +}
3148 +
3149 +static struct irq_chip intc_irq_type = {
3150 +       .name =         "INTC",
3151 +       .mask =         intc_irq_mask,
3152 +       .unmask =       intc_irq_unmask,
3153 +       .ack =          intc_irq_ack,
3154 +       .set_wake =     intc_irq_set_wake,
3155 +};
3156 +
3157 +static irqreturn_t jz4740_cascade(int irq, void *data)
3158 +{
3159 +       uint32_t irq_reg;
3160 +       int intc_irq;
3161 +
3162 +       irq_reg = readl(jz_intc_base + JZ_REG_INTC_PENDING);
3163 +       intc_irq = ffs(irq_reg);
3164 +       if (intc_irq)
3165 +               generic_handle_irq(intc_irq - 1 + JZ4740_IRQ_BASE);
3166 +
3167 +       return IRQ_HANDLED;
3168 +}
3169 +
3170 +static struct irqaction jz4740_cascade_action = {
3171 +       .handler = jz4740_cascade,
3172 +       .name = "JZ4740 cascade interrupt",
3173 +       .flags = IRQF_DISABLED,
3174 +};
3175 +
3176 +void __init arch_init_irq(void)
3177 +{
3178 +       int i;
3179 +       mips_cpu_irq_init();
3180 +
3181 +       jz_intc_base = ioremap(CPHYSADDR(JZ4740_INTC_BASE_ADDR), 0x14);
3182 +
3183 +       for (i = JZ4740_IRQ_BASE; i < JZ4740_IRQ_BASE + 32; i++) {
3184 +               intc_irq_mask(i);
3185 +               set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq);
3186 +       }
3187 +
3188 +       setup_irq(2, &jz4740_cascade_action);
3189 +}
3190 +
3191 +asmlinkage void plat_irq_dispatch(void)
3192 +{
3193 +       unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
3194 +       if (pending & STATUSF_IP2)
3195 +               do_IRQ(2);
3196 +       else if (pending & STATUSF_IP3)
3197 +               do_IRQ(3);
3198 +       else
3199 +               spurious_interrupt();
3200 +}
3201 +
3202 +void jz4740_intc_suspend(void)
3203 +{
3204 +       jz_intc_saved = readl(jz_intc_base + JZ_REG_INTC_MASK);
3205 +       writel(~jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_SET_MASK);
3206 +       writel(jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
3207 +}
3208 +
3209 +void jz4740_intc_resume(void)
3210 +{
3211 +       writel(~jz_intc_saved, jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
3212 +       writel(jz_intc_saved, jz_intc_base + JZ_REG_INTC_SET_MASK);
3213 +}
3214 +
3215 +#ifdef CONFIG_DEBUG_FS
3216 +
3217 +static inline void intc_seq_reg(struct seq_file *s, const char *name,
3218 +       unsigned int reg)
3219 +{
3220 +       seq_printf(s, "%s:\t\t%08x\n", name, readl(jz_intc_base + reg));
3221 +}
3222 +
3223 +static int intc_regs_show(struct seq_file *s, void *unused)
3224 +{
3225 +       intc_seq_reg(s, "Status", JZ_REG_INTC_STATUS);
3226 +       intc_seq_reg(s, "Mask", JZ_REG_INTC_MASK);
3227 +       intc_seq_reg(s, "Pending", JZ_REG_INTC_PENDING);
3228 +
3229 +       return 0;
3230 +}
3231 +
3232 +static int intc_regs_open(struct inode *inode, struct file *file)
3233 +{
3234 +       return single_open(file, intc_regs_show, NULL);
3235 +}
3236 +
3237 +static const struct file_operations intc_regs_operations = {
3238 +       .open           = intc_regs_open,
3239 +       .read           = seq_read,
3240 +       .llseek         = seq_lseek,
3241 +       .release        = single_release,
3242 +};
3243 +
3244 +static int __init intc_debugfs_init(void)
3245 +{
3246 +       (void) debugfs_create_file("jz_regs_intc", S_IFREG | S_IRUGO,
3247 +                               NULL, NULL, &intc_regs_operations);
3248 +       return 0;
3249 +}
3250 +subsys_initcall(intc_debugfs_init);
3251 +
3252 +#endif
3253 diff --git a/arch/mips/jz4740/irq.h b/arch/mips/jz4740/irq.h
3254 new file mode 100644
3255 index 0000000..dadbd5f
3256 --- /dev/null
3257 +++ b/arch/mips/jz4740/irq.h
3258 @@ -0,0 +1,21 @@
3259 +/*
3260 + *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3261 + *
3262 + *  This program is free software; you can redistribute         it and/or modify it
3263 + *  under  the terms of         the GNU General  Public License as published by the
3264 + *  Free Software Foundation;  either version 2 of the License, or (at your
3265 + *  option) any later version.
3266 + *
3267 + *  You should have received a copy of the  GNU General Public License along
3268 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
3269 + *  675 Mass Ave, Cambridge, MA 02139, USA.
3270 + *
3271 + */
3272 +
3273 +#ifndef __MIPS_JZ4740_IRQ_H__
3274 +#define __MIPS_JZ4740_IRQ_H__
3275 +
3276 +extern void jz4740_intc_suspend(void);
3277 +extern void jz4740_intc_resume(void);
3278 +
3279 +#endif
3280 diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c
3281 new file mode 100644
3282 index 0000000..6bb0778
3283 --- /dev/null
3284 +++ b/arch/mips/jz4740/platform.c
3285 @@ -0,0 +1,246 @@
3286 +/*
3287 + *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
3288 + *  JZ4740 platform devices
3289 + *
3290 + *  This program is free software; you can redistribute         it and/or modify it
3291 + *  under  the terms of         the GNU General  Public License as published by the
3292 + *  Free Software Foundation;  either version 2 of the License, or (at your
3293 + *  option) any later version.
3294 + *
3295 + *  You should have received a copy of the  GNU General Public License along
3296 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
3297 + *  675 Mass Ave, Cambridge, MA 02139, USA.
3298 + *
3299 + */
3300 +
3301 +#include <linux/device.h>
3302 +#include <linux/platform_device.h>
3303 +#include <linux/kernel.h>
3304 +#include <linux/init.h>
3305 +#include <linux/resource.h>
3306 +
3307 +#include <asm/mach-jz4740/platform.h>
3308 +#include <asm/mach-jz4740/base.h>
3309 +#include <asm/mach-jz4740/irq.h>
3310 +
3311 +/* OHCI (USB full speed host controller) */
3312 +static struct resource jz4740_usb_ohci_resources[] = {
3313 +       [0] = {
3314 +               .start  = CPHYSADDR(JZ4740_UHC_BASE_ADDR),
3315 +               .end    = CPHYSADDR(JZ4740_UHC_BASE_ADDR) + 0x10000 - 1,
3316 +               .flags  = IORESOURCE_MEM,
3317 +       },
3318 +       [1] = {
3319 +               .start  = JZ4740_IRQ_UHC,
3320 +               .end    = JZ4740_IRQ_UHC,
3321 +               .flags  = IORESOURCE_IRQ,
3322 +       },
3323 +};
3324 +
3325 +/* The dmamask must be set for OHCI to work */
3326 +static u64 ohci_dmamask = ~(u32)0;
3327 +
3328 +struct platform_device jz4740_usb_ohci_device = {
3329 +       .name           = "jz4740-ohci",
3330 +       .id             = -1,
3331 +       .dev = {
3332 +               .dma_mask               = &ohci_dmamask,
3333 +               .coherent_dma_mask      = 0xffffffff,
3334 +       },
3335 +       .num_resources  = ARRAY_SIZE(jz4740_usb_ohci_resources),
3336 +       .resource       = jz4740_usb_ohci_resources,
3337 +};
3338 +
3339 +/* UDC (USB gadget controller) */
3340 +static struct resource jz4740_usb_gdt_resources[] = {
3341 +       [0] = {
3342 +               .start  = CPHYSADDR(JZ4740_UDC_BASE_ADDR),
3343 +               .end    = CPHYSADDR(JZ4740_UDC_BASE_ADDR) + 0x10000 - 1,
3344 +               .flags  = IORESOURCE_MEM,
3345 +       },
3346 +       [1] = {
3347 +               .start  = JZ4740_IRQ_UDC,
3348 +               .end    = JZ4740_IRQ_UDC,
3349 +               .flags  = IORESOURCE_IRQ,
3350 +       },
3351 +};
3352 +
3353 +static u64 jz4740_udc_dmamask = ~(u32)0;
3354 +
3355 +struct platform_device jz4740_usb_gdt_device = {
3356 +       .name           = "jz-udc",
3357 +       .id             = -1,
3358 +       .dev = {
3359 +               .dma_mask               = &jz4740_udc_dmamask,
3360 +               .coherent_dma_mask      = 0xffffffff,
3361 +       },
3362 +       .num_resources  = ARRAY_SIZE(jz4740_usb_gdt_resources),
3363 +       .resource       = jz4740_usb_gdt_resources,
3364 +};
3365 +
3366 +/** MMC/SD controller **/
3367 +static struct resource jz4740_mmc_resources[] = {
3368 +       [0] = {
3369 +               .start  = CPHYSADDR(JZ4740_MSC_BASE_ADDR),
3370 +               .end    = CPHYSADDR(JZ4740_MSC_BASE_ADDR) + 0x10000 - 1,
3371 +               .flags  = IORESOURCE_MEM,
3372 +       },
3373 +       [1] = {
3374 +               .start  = JZ4740_IRQ_MSC,
3375 +               .end    = JZ4740_IRQ_MSC,
3376 +               .flags  = IORESOURCE_IRQ,
3377 +       }
3378 +};
3379 +
3380 +static u64 jz4740_mmc_dmamask =  ~(u32)0;
3381 +
3382 +struct platform_device jz4740_mmc_device = {
3383 +       .name = "jz4740-mmc",
3384 +       .id = 0,
3385 +       .dev = {
3386 +               .dma_mask               = &jz4740_mmc_dmamask,
3387 +               .coherent_dma_mask      = 0xffffffff,
3388 +       },
3389 +       .num_resources  = ARRAY_SIZE(jz4740_mmc_resources),
3390 +       .resource       = jz4740_mmc_resources,
3391 +};
3392 +
3393 +static struct resource jz4740_rtc_resources[] = {
3394 +       [0] = {
3395 +               .start  = CPHYSADDR(JZ4740_RTC_BASE_ADDR),
3396 +               .end    = CPHYSADDR(JZ4740_RTC_BASE_ADDR) + 0x38 - 1,
3397 +               .flags  = IORESOURCE_MEM,
3398 +       },
3399 +       [1] = {
3400 +               .start  = JZ4740_IRQ_RTC,
3401 +               .end    = JZ4740_IRQ_RTC,
3402 +               .flags  = IORESOURCE_IRQ,
3403 +       },
3404 +};
3405 +
3406 +struct platform_device jz4740_rtc_device = {
3407 +       .name   = "jz4740-rtc",
3408 +       .id     = -1,
3409 +       .num_resources  = ARRAY_SIZE(jz4740_rtc_resources),
3410 +       .resource       = jz4740_rtc_resources,
3411 +};
3412 +
3413 +/** I2C controller **/
3414 +static struct resource jz4740_i2c_resources[] = {
3415 +       [0] = {
3416 +               .start  = CPHYSADDR(JZ4740_I2C_BASE_ADDR),
3417 +               .end    = CPHYSADDR(JZ4740_I2C_BASE_ADDR) + 0x10000 - 1,
3418 +               .flags  = IORESOURCE_MEM,
3419 +       },
3420 +       [1] = {
3421 +               .start  = JZ4740_IRQ_I2C,
3422 +               .end    = JZ4740_IRQ_I2C,
3423 +               .flags  = IORESOURCE_IRQ,
3424 +       }
3425 +};
3426 +
3427 +static u64 jz4740_i2c_dmamask =  ~(u32)0;
3428 +
3429 +struct platform_device jz4740_i2c_device = {
3430 +       .name = "jz_i2c",
3431 +       .id = 0,
3432 +       .dev = {
3433 +               .dma_mask               = &jz4740_i2c_dmamask,
3434 +               .coherent_dma_mask      = 0xffffffff,
3435 +       },
3436 +       .num_resources  = ARRAY_SIZE(jz4740_i2c_resources),
3437 +       .resource       = jz4740_i2c_resources,
3438 +};
3439 +
3440 +static struct resource jz4740_nand_resources[] = {
3441 +       [0] = {
3442 +               .start  = CPHYSADDR(JZ4740_EMC_BASE_ADDR),
3443 +               .end    = CPHYSADDR(JZ4740_EMC_BASE_ADDR) + 0x10000 - 1,
3444 +               .flags  = IORESOURCE_MEM,
3445 +       },
3446 +};
3447 +
3448 +struct platform_device jz4740_nand_device = {
3449 +       .name = "jz4740-nand",
3450 +       .num_resources = ARRAY_SIZE(jz4740_nand_resources),
3451 +       .resource = jz4740_nand_resources,
3452 +};
3453 +
3454 +static struct resource jz4740_framebuffer_resources[] = {
3455 +       [0] = {
3456 +               .start  = CPHYSADDR(JZ4740_LCD_BASE_ADDR),
3457 +               .end    = CPHYSADDR(JZ4740_LCD_BASE_ADDR) + 0x10000 - 1,
3458 +               .flags  = IORESOURCE_MEM,
3459 +       },
3460 +};
3461 +
3462 +static u64 jz4740_fb_dmamask = ~(u32)0;
3463 +
3464 +struct platform_device jz4740_framebuffer_device = {
3465 +       .name = "jz4740-fb",
3466 +       .id = -1,
3467 +       .num_resources = ARRAY_SIZE(jz4740_framebuffer_resources),
3468 +       .resource = jz4740_framebuffer_resources,
3469 +       .dev = {
3470 +               .dma_mask = &jz4740_fb_dmamask,
3471 +               .coherent_dma_mask = 0xffffffff,
3472 +       },
3473 +};
3474 +
3475 +static struct resource jz4740_i2s_resources[] = {
3476 +       [0] = {
3477 +               .start  = CPHYSADDR(JZ4740_AIC_BASE_ADDR),
3478 +               .end    = CPHYSADDR(JZ4740_AIC_BASE_ADDR) + 0x38 - 1,
3479 +               .flags  = IORESOURCE_MEM,
3480 +       },
3481 +};
3482 +
3483 +struct platform_device jz4740_i2s_device = {
3484 +       .name = "jz4740-i2s",
3485 +       .id = -1,
3486 +       .num_resources = ARRAY_SIZE(jz4740_i2s_resources),
3487 +       .resource = jz4740_i2s_resources,
3488 +};
3489 +
3490 +static struct resource jz4740_codec_resources[] = {
3491 +       [0] = {
3492 +               .start  = CPHYSADDR(JZ4740_AIC_BASE_ADDR) + 0x80,
3493 +               .end    = CPHYSADDR(JZ4740_AIC_BASE_ADDR) + 0x88 - 1,
3494 +               .flags  = IORESOURCE_MEM,
3495 +       },
3496 +};
3497 +
3498 +struct platform_device jz4740_codec_device = {
3499 +       .name           = "jz4740-codec",
3500 +       .id             = -1,
3501 +       .num_resources  = ARRAY_SIZE(jz4740_codec_resources),
3502 +       .resource       = jz4740_codec_resources,
3503 +};
3504 +
3505 +static struct resource jz4740_adc_resources[] = {
3506 +       [0] = {
3507 +               .start  = CPHYSADDR(JZ4740_SADC_BASE_ADDR),
3508 +               .end    = CPHYSADDR(JZ4740_SADC_BASE_ADDR) + 0x30,
3509 +               .flags  = IORESOURCE_MEM,
3510 +       },
3511 +       [1] = {
3512 +               .start  = JZ4740_IRQ_SADC,
3513 +               .end    = JZ4740_IRQ_SADC,
3514 +               .flags  = IORESOURCE_IRQ,
3515 +       },
3516 +};
3517 +
3518 +struct platform_device jz4740_adc_device = {
3519 +       .name           = "jz4740-adc",
3520 +       .id             = -1,
3521 +       .num_resources  = ARRAY_SIZE(jz4740_adc_resources),
3522 +       .resource       = jz4740_adc_resources,
3523 +};
3524 +
3525 +struct platform_device jz4740_battery_device = {
3526 +       .name = "jz4740-battery",
3527 +       .id = -1,
3528 +       .dev = {
3529 +               .parent = &jz4740_adc_device.dev
3530 +       },
3531 +};
3532 diff --git a/arch/mips/jz4740/pm.c b/arch/mips/jz4740/pm.c
3533 new file mode 100644
3534 index 0000000..4ca3156
3535 --- /dev/null
3536 +++ b/arch/mips/jz4740/pm.c
3537 @@ -0,0 +1,59 @@
3538 +/*
3539 + *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3540 + *     JZ4740 SoC power management support
3541 + *
3542 + *  This program is free software; you can redistribute         it and/or modify it
3543 + *  under  the terms of         the GNU General  Public License as published by the
3544 + *  Free Software Foundation;  either version 2 of the License, or (at your
3545 + *  option) any later version.
3546 + *
3547 + *  You should have received a copy of the  GNU General Public License along
3548 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
3549 + *  675 Mass Ave, Cambridge, MA 02139, USA.
3550 + *
3551 + */
3552 +
3553 +#include <linux/init.h>
3554 +#include <linux/pm.h>
3555 +#include <linux/delay.h>
3556 +#include <linux/suspend.h>
3557 +
3558 +#include <asm/mach-jz4740/clock.h>
3559 +
3560 +#include "clock.h"
3561 +#include "irq.h"
3562 +
3563 +static int jz_pm_enter(suspend_state_t state)
3564 +{
3565 +       jz4740_intc_suspend();
3566 +       jz4740_clock_suspend();
3567 +
3568 +       jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_SLEEP);
3569 +
3570 +       __asm__(".set\tmips3\n\t"
3571 +               "wait\n\t"
3572 +               ".set\tmips0");
3573 +
3574 +       jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_IDLE);
3575 +
3576 +       jz4740_clock_resume();
3577 +       jz4740_intc_resume();
3578 +
3579 +       return 0;
3580 +}
3581 +
3582 +static struct platform_suspend_ops jz_pm_ops = {
3583 +       .valid          = suspend_valid_only_mem,
3584 +       .enter          = jz_pm_enter,
3585 +};
3586 +
3587 +/*
3588 + * Initialize power interface
3589 + */
3590 +int __init jz_pm_init(void)
3591 +{
3592 +       suspend_set_ops(&jz_pm_ops);
3593 +       return 0;
3594 +
3595 +}
3596 +late_initcall(jz_pm_init);
3597 diff --git a/arch/mips/jz4740/prom.c b/arch/mips/jz4740/prom.c
3598 new file mode 100644
3599 index 0000000..4f99ea3
3600 --- /dev/null
3601 +++ b/arch/mips/jz4740/prom.c
3602 @@ -0,0 +1,69 @@
3603 +/*
3604 + *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3605 + *  JZ4740 SoC prom code
3606 + *
3607 + *  This program is free software; you can redistribute         it and/or modify it
3608 + *  under  the terms of         the GNU General  Public License as published by the
3609 + *  Free Software Foundation;  either version 2 of the License, or (at your
3610 + *  option) any later version.
3611 + *
3612 + *  You should have received a copy of the  GNU General Public License along
3613 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
3614 + *  675 Mass Ave, Cambridge, MA 02139, USA.
3615 + *
3616 + */
3617 +
3618 +
3619 +#include <linux/module.h>
3620 +#include <linux/kernel.h>
3621 +#include <linux/init.h>
3622 +#include <linux/string.h>
3623 +
3624 +#include <linux/serial_reg.h>
3625 +
3626 +#include <asm/bootinfo.h>
3627 +#include <asm/mach-jz4740/base.h>
3628 +
3629 +void jz4740_init_cmdline(int argc, char *argv[])
3630 +{
3631 +       unsigned int count = COMMAND_LINE_SIZE - 1;
3632 +       int i;
3633 +       char *dst = &(arcs_cmdline[0]);
3634 +       char *src;
3635 +
3636 +       for (i = 1; i < argc && count; ++i) {
3637 +               src = argv[i];
3638 +               while (*src && count) {
3639 +                       *dst++ = *src++;
3640 +                       --count;
3641 +               }
3642 +               *dst++ = ' ';
3643 +       }
3644 +       if (i > 1)
3645 +               --dst;
3646 +
3647 +       *dst = 0;
3648 +}
3649 +
3650 +void __init prom_init(void)
3651 +{
3652 +       jz4740_init_cmdline((int)fw_arg0, (char **)fw_arg1);
3653 +       mips_machtype = MACH_INGENIC_JZ4740;
3654 +}
3655 +
3656 +void __init prom_free_prom_memory(void)
3657 +{
3658 +}
3659 +
3660 +#define UART_REG(offset) ((void __iomem*)(JZ4740_UART0_BASE_ADDR + (offset << 2)))
3661 +
3662 +void prom_putchar(char c)
3663 +{
3664 +       uint8_t lsr;
3665 +
3666 +       do {
3667 +               lsr = readb(UART_REG(UART_LSR));
3668 +       } while ((lsr & UART_LSR_TEMT) == 0);
3669 +
3670 +       writeb(c, UART_REG(UART_TX));
3671 +}
3672 diff --git a/arch/mips/jz4740/pwm.c b/arch/mips/jz4740/pwm.c
3673 new file mode 100644
3674 index 0000000..0ff8c1d
3675 --- /dev/null
3676 +++ b/arch/mips/jz4740/pwm.c
3677 @@ -0,0 +1,167 @@
3678 +/*
3679 + *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3680 + *  JZ4740 platform PWM support
3681 + *
3682 + *  This program is free software; you can redistribute         it and/or modify it
3683 + *  under  the terms of         the GNU General  Public License as published by the
3684 + *  Free Software Foundation;  either version 2 of the License, or (at your
3685 + *  option) any later version.
3686 + *
3687 + *  You should have received a copy of the  GNU General Public License along
3688 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
3689 + *  675 Mass Ave, Cambridge, MA 02139, USA.
3690 + *
3691 + */
3692 +
3693 +
3694 +#include <linux/kernel.h>
3695 +
3696 +#include <linux/clk.h>
3697 +#include <linux/err.h>
3698 +#include <linux/pwm.h>
3699 +#include <linux/gpio.h>
3700 +
3701 +#include <asm/mach-jz4740/gpio.h>
3702 +#include "timer.h"
3703 +
3704 +static struct clk *jz4740_pwm_clk;
3705 +
3706 +DEFINE_MUTEX(jz4740_pwm_mutex);
3707 +
3708 +struct pwm_device {
3709 +       unsigned int id;
3710 +       unsigned int gpio;
3711 +       bool used;
3712 +};
3713 +
3714 +static struct pwm_device jz4740_pwm_list[] = {
3715 +       { 2, JZ_GPIO_PWM2, false },
3716 +       { 3, JZ_GPIO_PWM3, false },
3717 +       { 4, JZ_GPIO_PWM4, false },
3718 +       { 5, JZ_GPIO_PWM5, false },
3719 +       { 6, JZ_GPIO_PWM6, false },
3720 +       { 7, JZ_GPIO_PWM7, false },
3721 +};
3722 +
3723 +struct pwm_device *pwm_request(int id, const char *label)
3724 +{
3725 +       int ret = 0;
3726 +       struct pwm_device *pwm;
3727 +
3728 +       if (!jz4740_pwm_clk) {
3729 +               jz4740_pwm_clk = clk_get(NULL, "pclk");
3730 +
3731 +               if (IS_ERR(jz4740_pwm_clk))
3732 +                       return ERR_PTR(PTR_ERR(jz4740_pwm_clk));
3733 +       }
3734 +
3735 +       if (id < 2 || id > 7) {
3736 +               return ERR_PTR(-ENOENT);
3737 +       }
3738 +
3739 +       mutex_lock(&jz4740_pwm_mutex);
3740 +
3741 +       pwm = &jz4740_pwm_list[id - 2];
3742 +       if (pwm->used)
3743 +               ret = -EBUSY;
3744 +       else
3745 +               pwm->used = true;
3746 +
3747 +       mutex_unlock(&jz4740_pwm_mutex);
3748 +
3749 +       if (ret) {
3750 +               return ERR_PTR(ret);
3751 +       }
3752 +
3753 +       ret = gpio_request(pwm->gpio, label);
3754 +
3755 +       if (ret) {
3756 +               printk("Failed to request pwm gpio: %d\n", ret);
3757 +               pwm->used = false;
3758 +               return ERR_PTR(ret);
3759 +       }
3760 +
3761 +       jz_gpio_set_function(pwm->gpio, JZ_GPIO_FUNC_PWM);
3762 +
3763 +       jz4740_timer_start(id);
3764 +
3765 +       return pwm;
3766 +}
3767 +
3768 +void pwm_free(struct pwm_device *pwm)
3769 +{
3770 +       pwm_disable(pwm);
3771 +       jz4740_timer_set_ctrl(pwm->id, 0);
3772 +
3773 +       jz_gpio_set_function(pwm->gpio, JZ_GPIO_FUNC_NONE);
3774 +       gpio_free(pwm->gpio);
3775 +
3776 +       jz4740_timer_stop(pwm->id);
3777 +
3778 +       pwm->used = false;
3779 +
3780 +}
3781 +
3782 +int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
3783 +{
3784 +       unsigned long long tmp;
3785 +       unsigned long period, duty;
3786 +       unsigned int prescaler = 0;
3787 +       unsigned int id = pwm->id;
3788 +       uint16_t ctrl;
3789 +       bool is_enabled;
3790 +
3791 +       if (duty_ns < 0 || duty_ns > period_ns)
3792 +               return -EINVAL;
3793 +
3794 +       tmp = (unsigned long long)clk_get_rate(jz4740_pwm_clk) * period_ns;
3795 +
3796 +       do_div(tmp, 1000000000);
3797 +
3798 +       period = tmp;
3799 +
3800 +       while (period > 0xffff && prescaler < 6) {
3801 +               period >>= 2;
3802 +               ++prescaler;
3803 +       }
3804 +
3805 +       if (prescaler == 6)
3806 +               return -EINVAL;
3807 +
3808 +
3809 +       tmp = (unsigned long long)period * duty_ns;
3810 +       do_div(tmp, period_ns);
3811 +       duty = tmp;
3812 +
3813 +       if (duty >= period)
3814 +               duty = period - 1;
3815 +
3816 +       is_enabled = jz4740_timer_is_enabled(id);
3817 +       jz4740_timer_disable(id);
3818 +
3819 +       jz4740_timer_set_count(id, 0);
3820 +       jz4740_timer_set_duty(id, duty);
3821 +       jz4740_timer_set_period(id, period);
3822 +
3823 +       ctrl = JZ_TIMER_CTRL_PRESCALER(prescaler) | JZ_TIMER_CTRL_PWM_ENABLE |
3824 +               JZ_TIMER_CTRL_SRC_PCLK;
3825 +
3826 +       jz4740_timer_set_ctrl(id, ctrl);
3827 +
3828 +       if (is_enabled)
3829 +               jz4740_timer_enable(id);
3830 +
3831 +       return 0;
3832 +}
3833 +
3834 +int pwm_enable(struct pwm_device *pwm)
3835 +{
3836 +       jz4740_timer_enable(pwm->id);
3837 +
3838 +       return 0;
3839 +}
3840 +
3841 +void pwm_disable(struct pwm_device *pwm)
3842 +{
3843 +       jz4740_timer_disable(pwm->id);
3844 +}
3845 diff --git a/arch/mips/jz4740/reset.c b/arch/mips/jz4740/reset.c
3846 new file mode 100644
3847 index 0000000..448a7da
3848 --- /dev/null
3849 +++ b/arch/mips/jz4740/reset.c
3850 @@ -0,0 +1,81 @@
3851 +/*
3852 + *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3853 + *
3854 + *  This program is free software; you can redistribute         it and/or modify it
3855 + *  under  the terms of         the GNU General  Public License as published by the
3856 + *  Free Software Foundation;  either version 2 of the License, or (at your
3857 + *  option) any later version.
3858 + *
3859 + *  You should have received a copy of the  GNU General Public License along
3860 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
3861 + *  675 Mass Ave, Cambridge, MA 02139, USA.
3862 + *
3863 + */
3864 +
3865 +#include <linux/io.h>
3866 +#include <linux/kernel.h>
3867 +#include <linux/pm.h>
3868 +
3869 +#include <linux/delay.h>
3870 +
3871 +#include <asm/reboot.h>
3872 +
3873 +#include <asm/mach-jz4740/base.h>
3874 +#include <asm/mach-jz4740/timer.h>
3875 +
3876 +static void jz4740_halt(void)
3877 +{
3878 +       while (1) {
3879 +               __asm__(".set push;\n"
3880 +                       ".set mips3;\n"
3881 +                       "wait;\n"
3882 +                       ".set pop;\n"
3883 +               );
3884 +       }
3885 +}
3886 +
3887 +#define JZ_REG_WDT_DATA 0x00
3888 +#define JZ_REG_WDT_COUNTER_ENABLE 0x04
3889 +#define JZ_REG_WDT_COUNTER 0x08
3890 +#define JZ_REG_WDT_CTRL 0x0c
3891 +
3892 +static void jz4740_restart(char *command)
3893 +{
3894 +       void __iomem *wdt_base = ioremap(CPHYSADDR(JZ4740_WDT_BASE_ADDR), 0x0f);
3895 +
3896 +       jz4740_timer_enable_watchdog();
3897 +
3898 +       writeb(0, wdt_base + JZ_REG_WDT_COUNTER_ENABLE);
3899 +
3900 +       writew(0, wdt_base + JZ_REG_WDT_COUNTER);
3901 +       writew(0, wdt_base + JZ_REG_WDT_DATA);
3902 +       writew(BIT(2), wdt_base + JZ_REG_WDT_CTRL);
3903 +
3904 +       writeb(1, wdt_base + JZ_REG_WDT_COUNTER_ENABLE);
3905 +       jz4740_halt();
3906 +}
3907 +
3908 +#define JZ_REG_RTC_CTRL                0x00
3909 +#define JZ_REG_RTC_HIBERNATE   0x20
3910 +
3911 +#define JZ_RTC_CTRL_WRDY       BIT(7)
3912 +
3913 +static void jz4740_power_off(void)
3914 +{
3915 +       void __iomem *rtc_base = ioremap(CPHYSADDR(JZ4740_RTC_BASE_ADDR), 0x24);
3916 +       uint32_t ctrl;
3917 +
3918 +       do {
3919 +               ctrl = readl(rtc_base + JZ_REG_RTC_CTRL);
3920 +       } while (!(ctrl & JZ_RTC_CTRL_WRDY));
3921 +
3922 +       writel(1, rtc_base + JZ_REG_RTC_HIBERNATE);
3923 +       jz4740_halt();
3924 +}
3925 +
3926 +void jz4740_reset_init(void)
3927 +{
3928 +       _machine_restart = jz4740_restart;
3929 +       _machine_halt = jz4740_halt;
3930 +       pm_power_off = jz4740_power_off;
3931 +}
3932 diff --git a/arch/mips/jz4740/reset.h b/arch/mips/jz4740/reset.h
3933 new file mode 100644
3934 index 0000000..c57a829
3935 --- /dev/null
3936 +++ b/arch/mips/jz4740/reset.h
3937 @@ -0,0 +1,7 @@
3938 +#ifndef __MIPS_JZ4740_RESET_H__
3939 +#define __MIPS_JZ4740_RESET_H__
3940 +
3941 +extern void jz4740_reset_init(void);
3942 +
3943 +#endif
3944 +
3945 diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c
3946 new file mode 100644
3947 index 0000000..a6628f4
3948 --- /dev/null
3949 +++ b/arch/mips/jz4740/setup.c
3950 @@ -0,0 +1,64 @@
3951 +/*
3952 + *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
3953 + *  JZ4740 setup code
3954 + *
3955 + *  This program is free software; you can redistribute         it and/or modify it
3956 + *  under  the terms of         the GNU General  Public License as published by the
3957 + *  Free Software Foundation;  either version 2 of the License, or (at your
3958 + *  option) any later version.
3959 + *
3960 + *  You should have received a copy of the  GNU General Public License along
3961 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
3962 + *  675 Mass Ave, Cambridge, MA 02139, USA.
3963 + *
3964 + */
3965 +
3966 +
3967 +#include <linux/init.h>
3968 +#include <linux/kernel.h>
3969 +#include <linux/serial.h>
3970 +#include <linux/serial_core.h>
3971 +#include <linux/serial_8250.h>
3972 +
3973 +#include <asm/mach-jz4740/base.h>
3974 +#include <asm/mach-jz4740/clock.h>
3975 +#include <asm/mach-jz4740/serial.h>
3976 +
3977 +#include "reset.h"
3978 +#include "clock.h"
3979 +
3980 +static void __init jz4740_serial_setup(void)
3981 +{
3982 +#ifdef CONFIG_SERIAL_8250
3983 +       struct uart_port s;
3984 +       memset(&s, 0, sizeof(s));
3985 +       s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
3986 +       s.iotype = SERIAL_IO_MEM;
3987 +       s.regshift = 2;
3988 +       s.uartclk = jz4740_clock_bdata.ext_rate;
3989 +
3990 +       s.line = 0;
3991 +       s.membase = (u8 *)JZ4740_UART0_BASE_ADDR;
3992 +       s.irq = JZ4740_IRQ_UART0;
3993 +       if (early_serial_setup(&s) != 0) {
3994 +               printk(KERN_ERR "Serial ttyS0 setup failed!\n");
3995 +       }
3996 +
3997 +       s.line = 1;
3998 +       s.membase = (u8 *)JZ4740_UART1_BASE_ADDR;
3999 +       s.irq = JZ4740_IRQ_UART1;
4000 +       if (early_serial_setup(&s) != 0) {
4001 +               printk(KERN_ERR "Serial ttyS1 setup failed!\n");
4002 +       }
4003 +#endif
4004 +}
4005 +void __init plat_mem_setup(void)
4006 +{
4007 +       jz4740_reset_init();
4008 +       jz4740_serial_setup();
4009 +}
4010 +
4011 +const char *get_system_type(void)
4012 +{
4013 +       return "JZ4740";
4014 +}
4015 diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
4016 new file mode 100644
4017 index 0000000..7721ba7
4018 --- /dev/null
4019 +++ b/arch/mips/jz4740/time.c
4020 @@ -0,0 +1,145 @@
4021 +/*
4022 + *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
4023 + *  JZ4740 platform time support
4024 + *
4025 + *  This program is free software; you can redistribute         it and/or modify it
4026 + *  under  the terms of         the GNU General  Public License as published by the
4027 + *  Free Software Foundation;  either version 2 of the License, or (at your
4028 + *  option) any later version.
4029 + *
4030 + *  You should have received a copy of the  GNU General Public License along
4031 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
4032 + *  675 Mass Ave, Cambridge, MA 02139, USA.
4033 + *
4034 + */
4035 +
4036 +#include <linux/interrupt.h>
4037 +#include <linux/kernel.h>
4038 +#include <linux/time.h>
4039 +
4040 +#include <linux/clockchips.h>
4041 +
4042 +#include <asm/mach-jz4740/irq.h>
4043 +#include <asm/time.h>
4044 +
4045 +#include "clock.h"
4046 +#include "timer.h"
4047 +
4048 +#define TIMER_CLOCKEVENT 0
4049 +#define TIMER_CLOCKSOURCE 1
4050 +
4051 +static uint16_t jz4740_jiffies_per_tick;
4052 +
4053 +static cycle_t jz4740_clocksource_read(struct clocksource *cs)
4054 +{
4055 +       return jz4740_timer_get_count(TIMER_CLOCKSOURCE);
4056 +}
4057 +
4058 +static struct clocksource jz4740_clocksource = {
4059 +       .name = "jz4740-timer",
4060 +       .rating = 200,
4061 +       .read = jz4740_clocksource_read,
4062 +       .mask = CLOCKSOURCE_MASK(16),
4063 +       .flags = CLOCK_SOURCE_IS_CONTINUOUS,
4064 +};
4065 +
4066 +static irqreturn_t jz4740_clockevent_irq(int irq, void *devid)
4067 +{
4068 +       struct clock_event_device *cd = devid;
4069 +
4070 +       jz4740_timer_ack_full(TIMER_CLOCKEVENT);
4071 +
4072 +       if (cd->mode != CLOCK_EVT_MODE_PERIODIC)
4073 +               jz4740_timer_disable(TIMER_CLOCKEVENT);
4074 +
4075 +       cd->event_handler(cd);
4076 +
4077 +    return IRQ_HANDLED;
4078 +}
4079 +
4080 +static void jz4740_clockevent_set_mode(enum clock_event_mode mode,
4081 +       struct clock_event_device *cd)
4082 +{
4083 +       switch (mode) {
4084 +       case CLOCK_EVT_MODE_PERIODIC:
4085 +               jz4740_timer_set_count(TIMER_CLOCKEVENT, 0);
4086 +               jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick);
4087 +       case CLOCK_EVT_MODE_RESUME:
4088 +               jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
4089 +               jz4740_timer_enable(TIMER_CLOCKEVENT);
4090 +               break;
4091 +       case CLOCK_EVT_MODE_ONESHOT:
4092 +       case CLOCK_EVT_MODE_SHUTDOWN:
4093 +               jz4740_timer_disable(TIMER_CLOCKEVENT);
4094 +               break;
4095 +       default:
4096 +               break;
4097 +       }
4098 +}
4099 +
4100 +static int jz4740_clockevent_set_next(unsigned long evt,
4101 +       struct clock_event_device *cd)
4102 +{
4103 +       jz4740_timer_set_count(TIMER_CLOCKEVENT, 0);
4104 +       jz4740_timer_set_period(TIMER_CLOCKEVENT, evt);
4105 +       jz4740_timer_enable(TIMER_CLOCKEVENT);
4106 +
4107 +       return 0;
4108 +}
4109 +
4110 +static struct clock_event_device jz4740_clockevent = {
4111 +       .name = "jz4740-timer",
4112 +       .features = CLOCK_EVT_FEAT_PERIODIC,
4113 +       .set_next_event = jz4740_clockevent_set_next,
4114 +       .set_mode = jz4740_clockevent_set_mode,
4115 +       .rating = 200,
4116 +       .irq = JZ4740_IRQ_TCU0,
4117 +};
4118 +
4119 +static struct irqaction timer_irqaction = {
4120 +       .handler        = jz4740_clockevent_irq,
4121 +       .flags          = IRQF_PERCPU | IRQF_TIMER | IRQF_DISABLED,
4122 +       .name           = "jz4740-timerirq",
4123 +       .dev_id      = &jz4740_clockevent,
4124 +};
4125 +
4126 +void __init plat_time_init(void)
4127 +{
4128 +       int ret;
4129 +       uint32_t clk_rate;
4130 +       uint16_t ctrl;
4131 +
4132 +       jz4740_timer_init();
4133 +
4134 +       clk_rate = jz4740_clock_bdata.ext_rate >> 4;
4135 +    jz4740_jiffies_per_tick = DIV_ROUND_CLOSEST(clk_rate, HZ);
4136 +
4137 +       clockevent_set_clock(&jz4740_clockevent, clk_rate);
4138 +       jz4740_clockevent.min_delta_ns = clockevent_delta2ns(100, &jz4740_clockevent);
4139 +       jz4740_clockevent.max_delta_ns = clockevent_delta2ns(0xffff, &jz4740_clockevent);
4140 +       jz4740_clockevent.cpumask = cpumask_of(0);
4141 +
4142 +       clockevents_register_device(&jz4740_clockevent);
4143 +
4144 +       clocksource_set_clock(&jz4740_clocksource, clk_rate);
4145 +       ret = clocksource_register(&jz4740_clocksource);
4146 +
4147 +       if (ret)
4148 +           printk(KERN_ERR "Failed to register clocksource: %d\n", ret);
4149 +
4150 +       setup_irq(JZ4740_IRQ_TCU0, &timer_irqaction);
4151 +
4152 +       ctrl = JZ_TIMER_CTRL_PRESCALE_16 | JZ_TIMER_CTRL_SRC_EXT;
4153 +
4154 +       jz4740_timer_set_ctrl(TIMER_CLOCKEVENT, ctrl);
4155 +       jz4740_timer_set_ctrl(TIMER_CLOCKSOURCE, ctrl);
4156 +
4157 +       jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick);
4158 +    jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
4159 +
4160 +    jz4740_timer_irq_full_disable(TIMER_CLOCKSOURCE);
4161 +       jz4740_timer_set_period(TIMER_CLOCKSOURCE, 0xffff);
4162 +
4163 +       jz4740_timer_enable(TIMER_CLOCKEVENT);
4164 +       jz4740_timer_enable(TIMER_CLOCKSOURCE);
4165 +}
4166 diff --git a/arch/mips/jz4740/timer.c b/arch/mips/jz4740/timer.c
4167 new file mode 100644
4168 index 0000000..208f14c
4169 --- /dev/null
4170 +++ b/arch/mips/jz4740/timer.c
4171 @@ -0,0 +1,45 @@
4172 +/*
4173 + *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
4174 + *  JZ4740 platform timer support
4175 + *
4176 + *  This program is free software; you can redistribute         it and/or modify it
4177 + *  under  the terms of         the GNU General  Public License as published by the
4178 + *  Free Software Foundation;  either version 2 of the License, or (at your
4179 + *  option) any later version.
4180 + *
4181 + *  You should have received a copy of the  GNU General Public License along
4182 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
4183 + *  675 Mass Ave, Cambridge, MA 02139, USA.
4184 + *
4185 + */
4186 +
4187 +#include <linux/io.h>
4188 +#include <linux/kernel.h>
4189 +#include <linux/module.h>
4190 +
4191 +#include "timer.h"
4192 +
4193 +#include <asm/mach-jz4740/base.h>
4194 +
4195 +void __iomem *jz4740_timer_base;
4196 +
4197 +void jz4740_timer_enable_watchdog(void)
4198 +{
4199 +       writel(BIT(16), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR);
4200 +}
4201 +
4202 +void jz4740_timer_disable_watchdog(void)
4203 +{
4204 +       writel(BIT(16), jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
4205 +}
4206 +
4207 +void __init jz4740_timer_init(void)
4208 +{
4209 +       jz4740_timer_base = ioremap(CPHYSADDR(JZ4740_TCU_BASE_ADDR), 0x100);
4210 +
4211 +       if (!jz4740_timer_base)
4212 +               panic("Failed to ioremap timer registers");
4213 +
4214 +       /* Disable all timers except those used as system timers */
4215 +       writel(0x100fc, jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
4216 +}
4217 diff --git a/arch/mips/jz4740/timer.h b/arch/mips/jz4740/timer.h
4218 new file mode 100644
4219 index 0000000..77d748c
4220 --- /dev/null
4221 +++ b/arch/mips/jz4740/timer.h
4222 @@ -0,0 +1,130 @@
4223 +/*
4224 + *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
4225 + *  JZ4740 platform timer support
4226 + *
4227 + *  This program is free software; you can redistribute         it and/or modify it
4228 + *  under  the terms of         the GNU General  Public License as published by the
4229 + *  Free Software Foundation;  either version 2 of the License, or (at your
4230 + *  option) any later version.
4231 + *
4232 + *  You should have received a copy of the  GNU General Public License along
4233 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
4234 + *  675 Mass Ave, Cambridge, MA 02139, USA.
4235 + *
4236 + */
4237 +
4238 +#ifndef __MIPS_JZ4740_TIMER_H__
4239 +#define __MIPS_JZ4740_TIMER_H__
4240 +
4241 +#include <linux/module.h>
4242 +#include <linux/io.h>
4243 +
4244 +#define JZ_REG_TIMER_STOP              0x1C
4245 +#define JZ_REG_TIMER_STOP_SET          0x2C
4246 +#define JZ_REG_TIMER_STOP_CLEAR                0x3C
4247 +#define JZ_REG_TIMER_ENABLE            0x10
4248 +#define JZ_REG_TIMER_ENABLE_SET                0x14
4249 +#define JZ_REG_TIMER_ENABLE_CLEAR      0x18
4250 +#define JZ_REG_TIMER_FLAG              0x20
4251 +#define JZ_REG_TIMER_FLAG_SET          0x24
4252 +#define JZ_REG_TIMER_FLAG_CLEAR                0x28
4253 +#define JZ_REG_TIMER_MASK              0x30
4254 +#define JZ_REG_TIMER_MASK_SET          0x34
4255 +#define JZ_REG_TIMER_MASK_CLEAR                0x38
4256 +
4257 +#define JZ_REG_TIMER_DFR(x) (((x) * 0x10) + 0x40)
4258 +#define JZ_REG_TIMER_DHR(x) (((x) * 0x10) + 0x44)
4259 +#define JZ_REG_TIMER_CNT(x) (((x) * 0x10) + 0x48)
4260 +#define JZ_REG_TIMER_CTRL(x) (((x) * 0x10) + 0x4C)
4261 +
4262 +#define JZ_TIMER_IRQ_HALF(x) BIT((x) + 0x10)
4263 +#define JZ_TIMER_IRQ_FULL(x) BIT(x)
4264 +
4265 +#define JZ_TIMER_CTRL_PWM_ACTIVE_LOW   BIT(8)
4266 +#define JZ_TIMER_CTRL_PWM_ENABLE       BIT(7)
4267 +#define JZ_TIMER_CTRL_PRESCALE_MASK    0x1c
4268 +#define JZ_TIMER_CTRL_PRESCALE_OFFSET  0x3
4269 +#define JZ_TIMER_CTRL_PRESCALE_1       (0 << 3)
4270 +#define JZ_TIMER_CTRL_PRESCALE_4       (1 << 3)
4271 +#define JZ_TIMER_CTRL_PRESCALE_16      (2 << 3)
4272 +#define JZ_TIMER_CTRL_PRESCALE_64      (3 << 3)
4273 +#define JZ_TIMER_CTRL_PRESCALE_256     (4 << 3)
4274 +#define JZ_TIMER_CTRL_PRESCALE_1024    (5 << 3)
4275 +
4276 +#define JZ_TIMER_CTRL_PRESCALER(x) ((x) << JZ_TIMER_CTRL_PRESCALE_OFFSET)
4277 +
4278 +#define JZ_TIMER_CTRL_SRC_EXT          BIT(2)
4279 +#define JZ_TIMER_CTRL_SRC_RTC          BIT(1)
4280 +#define JZ_TIMER_CTRL_SRC_PCLK         BIT(0)
4281 +
4282 +extern void __iomem *jz4740_timer_base;
4283 +void __init jz4740_timer_init(void);
4284 +
4285 +static inline void jz4740_timer_stop(unsigned int timer)
4286 +{
4287 +       writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
4288 +}
4289 +
4290 +static inline void jz4740_timer_start(unsigned int timer)
4291 +{
4292 +       writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR);
4293 +}
4294 +
4295 +static inline bool jz4740_timer_is_enabled(unsigned int timer)
4296 +{
4297 +       return readb(jz4740_timer_base + JZ_REG_TIMER_ENABLE) & BIT(timer);
4298 +}
4299 +
4300 +static inline void jz4740_timer_enable(unsigned int timer)
4301 +{
4302 +       writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_SET);
4303 +}
4304 +
4305 +static inline void jz4740_timer_disable(unsigned int timer)
4306 +{
4307 +       writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_CLEAR);
4308 +}
4309 +
4310 +
4311 +static inline void jz4740_timer_set_period(unsigned int timer, uint16_t period)
4312 +{
4313 +       writew(period, jz4740_timer_base + JZ_REG_TIMER_DFR(timer));
4314 +}
4315 +
4316 +static inline void jz4740_timer_set_duty(unsigned int timer, uint16_t duty)
4317 +{
4318 +       writew(duty, jz4740_timer_base + JZ_REG_TIMER_DHR(timer));
4319 +}
4320 +
4321 +static inline void jz4740_timer_set_count(unsigned int timer, uint16_t count)
4322 +{
4323 +       writew(count, jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
4324 +}
4325 +
4326 +static inline uint16_t jz4740_timer_get_count(unsigned int timer)
4327 +{
4328 +       return readw(jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
4329 +}
4330 +
4331 +static inline void jz4740_timer_ack_full(unsigned int timer)
4332 +{
4333 +       writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
4334 +}
4335 +
4336 +static inline void jz4740_timer_irq_full_enable(unsigned int timer)
4337 +{
4338 +       writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
4339 +       writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_CLEAR);
4340 +}
4341 +
4342 +static inline void jz4740_timer_irq_full_disable(unsigned int timer)
4343 +{
4344 +       writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_SET);
4345 +}
4346 +
4347 +static inline void jz4740_timer_set_ctrl(unsigned int timer, uint16_t ctrl)
4348 +{
4349 +       writew(ctrl, jz4740_timer_base + JZ_REG_TIMER_CTRL(timer));
4350 +}
4351 +
4352 +#endif
4353 diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
4354 index be5bb16..926c260 100644
4355 --- a/arch/mips/kernel/cpu-probe.c
4356 +++ b/arch/mips/kernel/cpu-probe.c
4357 @@ -163,6 +163,7 @@ void __init check_wait(void)
4358         case CPU_BCM6358:
4359         case CPU_CAVIUM_OCTEON:
4360         case CPU_CAVIUM_OCTEON_PLUS:
4361 +       case CPU_JZRISC:
4362                 cpu_wait = r4k_wait;
4363                 break;
4364  
4365 @@ -932,6 +933,22 @@ platform:
4366         }
4367  }
4368  
4369 +static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
4370 +{
4371 +       decode_configs(c);
4372 +       /* JZRISC does not implement the CP0 counter. */
4373 +       c->options &= ~MIPS_CPU_COUNTER;
4374 +       switch (c->processor_id & 0xff00) {
4375 +       case PRID_IMP_JZRISC:
4376 +               c->cputype = CPU_JZRISC;
4377 +               __cpu_name[cpu] = "Ingenic JZRISC";
4378 +               break;
4379 +       default:
4380 +               panic("Unknown Ingenic Processor ID!");
4381 +               break;
4382 +       }
4383 +}
4384 +
4385  const char *__cpu_name[NR_CPUS];
4386  const char *__elf_platform;
4387  
4388 @@ -970,6 +987,9 @@ __cpuinit void cpu_probe(void)
4389         case PRID_COMP_CAVIUM:
4390                 cpu_probe_cavium(c, cpu);
4391                 break;
4392 +       case PRID_COMP_INGENIC:
4393 +               cpu_probe_ingenic(c, cpu);
4394 +               break;
4395         }
4396  
4397         BUG_ON(!__cpu_name[cpu]);
4398 diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
4399 index 86f004d..4510e61 100644
4400 --- a/arch/mips/mm/tlbex.c
4401 +++ b/arch/mips/mm/tlbex.c
4402 @@ -409,6 +409,11 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
4403                 tlbw(p);
4404                 break;
4405  
4406 +       case CPU_JZRISC:
4407 +               tlbw(p);
4408 +               uasm_i_nop(p);
4409 +               break;
4410 +
4411         default:
4412                 panic("No TLB refill handler yet (CPU type: %d)",
4413                       current_cpu_data.cputype);
4414 -- 
4415 1.5.6.5
4416