ubus: update to latest version, includes a small bugfix for object call replies
[openwrt.git] / target / linux / lantiq / patches-3.0 / 110-falcon_board.patch
1 --- /dev/null
2 +++ b/arch/mips/lantiq/falcon/Kconfig
3 @@ -0,0 +1,11 @@
4 +if SOC_FALCON
5 +
6 +menu "Mips Machine"
7 +
8 +config LANTIQ_MACH_EASY98000
9 +       bool "Easy98000"
10 +       default y
11 +
12 +endmenu
13 +
14 +endif
15 --- /dev/null
16 +++ b/arch/mips/lantiq/falcon/Makefile
17 @@ -0,0 +1,4 @@
18 +obj-y := clk-falcon.o devices.o gpio.o prom.o sysctrl.o reset.o
19 +obj-y += softdog_vpe.o
20 +obj-$(CONFIG_LANTIQ_MACH_EASY98000) += addon-easy98000.o
21 +obj-$(CONFIG_LANTIQ_MACH_EASY98000) += mach-easy98000.o
22 --- /dev/null
23 +++ b/arch/mips/lantiq/falcon/clk-falcon.c
24 @@ -0,0 +1,48 @@
25 +/*
26 + * This program is free software; you can redistribute it and/or modify
27 + * it under the terms of the GNU General Public License as published by
28 + * the Free Software Foundation; either version 2 of the License, or
29 + * (at your option) any later version.
30 + *
31 + * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
32 + */
33 +
34 +#include <linux/io.h>
35 +#include <linux/module.h>
36 +#include <linux/init.h>
37 +
38 +#include <asm/time.h>
39 +#include <asm/irq.h>
40 +#include <asm/div64.h>
41 +
42 +#include <lantiq_soc.h>
43 +
44 +#include <falcon.h>
45 +#include <gpon_reg_base.h>
46 +#include <sys1_reg.h>
47 +
48 +static struct gpon_reg_sys1 * const pSYS1 = (struct gpon_reg_sys1 *)GPON_SYS1_BASE;
49 +
50 +unsigned int
51 +ltq_get_io_region_clock(void)
52 +{
53 +       return 200000000; /* 200 MHz */
54 +}
55 +EXPORT_SYMBOL(ltq_get_io_region_clock);
56 +
57 +unsigned int
58 +ltq_get_cpu_hz(void)
59 +{
60 +       if ((ltq_r32(&pSYS1->cpu0cc) & CPU0CC_CPUDIV) == CPU0CC_CPUDIV_SELFHALF)
61 +               return 200000000; /* 200 MHz */
62 +       else
63 +               return 400000000; /* 400 MHz */
64 +}
65 +EXPORT_SYMBOL(ltq_get_cpu_hz);
66 +
67 +unsigned int
68 +ltq_get_fpi_hz(void)
69 +{
70 +       return 100000000;
71 +}
72 +EXPORT_SYMBOL(ltq_get_fpi_hz);
73 --- /dev/null
74 +++ b/arch/mips/lantiq/falcon/devices.c
75 @@ -0,0 +1,258 @@
76 +#include <linux/init.h>
77 +#include <linux/module.h>
78 +#include <linux/types.h>
79 +#include <linux/string.h>
80 +#include <linux/mtd/physmap.h>
81 +#include <linux/kernel.h>
82 +#include <linux/reboot.h>
83 +#include <linux/platform_device.h>
84 +#include <linux/leds.h>
85 +#include <linux/etherdevice.h>
86 +#include <linux/reboot.h>
87 +#include <linux/time.h>
88 +#include <linux/io.h>
89 +#include <linux/gpio.h>
90 +#include <linux/leds.h>
91 +#include <linux/spi/spi.h>
92 +#include <linux/mtd/nand.h>
93 +
94 +#include <asm/bootinfo.h>
95 +#include <asm/irq.h>
96 +
97 +#include <lantiq.h>
98 +
99 +#include <falcon/falcon_irq.h>
100 +#include <falcon/gpon_reg_base.h>
101 +#include <falcon/ebu_reg.h>
102 +#include <falcon/sys1_reg.h>
103 +#include <falcon/sys_eth_reg.h>
104 +
105 +#include <falcon/sysctrl.h>
106 +
107 +#include "devices.h"
108 +
109 +unsigned char ltq_ethaddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
110 +EXPORT_SYMBOL(ltq_ethaddr);
111 +
112 +/* create dummy ebu spinlock for drivers shared with XWAY targets */
113 +DEFINE_SPINLOCK(ebu_lock);
114 +EXPORT_SYMBOL_GPL(ebu_lock);
115 +
116 +static int __init
117 +falcon_set_ethaddr(char *str)
118 +{
119 +       sscanf(str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
120 +               &ltq_ethaddr[0], &ltq_ethaddr[1], &ltq_ethaddr[2],
121 +               &ltq_ethaddr[3], &ltq_ethaddr[4], &ltq_ethaddr[5]);
122 +       return 0;
123 +}
124 +__setup("ethaddr=", falcon_set_ethaddr);
125 +
126 +/* asc ports */
127 +static struct resource falcon_asc0_resources[] =
128 +{
129 +       MEM_RES("asc0",GPON_ASC0_BASE,GPON_ASC0_END),
130 +       IRQ_RES("tx",INT_NUM_IM3_IRL0),
131 +       IRQ_RES("rx",INT_NUM_IM3_IRL0+1),
132 +       IRQ_RES("err",INT_NUM_IM3_IRL0+2),
133 +};
134 +
135 +static struct resource falcon_asc1_resources[] =
136 +{
137 +       MEM_RES("asc1",GPON_ASC1_BASE,GPON_ASC1_END),
138 +       IRQ_RES("tx",INT_NUM_IM3_IRL0+8),
139 +       IRQ_RES("rx",INT_NUM_IM3_IRL0+9),
140 +       IRQ_RES("err",INT_NUM_IM3_IRL0+10),
141 +};
142 +
143 +void __init falcon_register_asc(int port)
144 +{
145 +       switch (port) {
146 +       case 0:
147 +               platform_device_register_simple("ltq_asc", 0,
148 +                       falcon_asc0_resources, ARRAY_SIZE(falcon_asc0_resources));
149 +               break;
150 +       case 1:
151 +               platform_device_register_simple("ltq_asc", 1,
152 +                       falcon_asc1_resources, ARRAY_SIZE(falcon_asc1_resources));
153 +               break;
154 +       default:
155 +               break;
156 +       }
157 +}
158 +
159 +/* nor flash */
160 +static struct resource ltq_nor_resource =
161 +       MEM_RES("nor",LTQ_FLASH_START,LTQ_FLASH_START + LTQ_FLASH_MAX - 1);
162 +
163 +static struct platform_device ltq_nor = {
164 +       .name                   = "ltq_nor",
165 +       .resource               = &ltq_nor_resource,
166 +       .num_resources  = 1,
167 +};
168 +
169 +void __init falcon_register_nor(struct physmap_flash_data *data)
170 +{
171 +       ltq_nor.dev.platform_data = data;
172 +       platform_device_register(&ltq_nor);
173 +}
174 +
175 +/* spi flash */
176 +static struct resource ltq_spi_resources[] = {
177 +       MEM_RES("ebu", GPON_EBU_BASE, GPON_EBU_END),
178 +       MEM_RES("sys1", GPON_SYS1_BASE, GPON_SYS1_END)
179 +};
180 +
181 +static struct platform_device ltq_spi = {
182 +       .name                   = "falcon_spi",
183 +       .resource               = ltq_spi_resources,
184 +       .num_resources          = ARRAY_SIZE(ltq_spi_resources)
185 +};
186 +
187 +void __init falcon_register_spi_flash(struct spi_board_info *data)
188 +{
189 +       spi_register_board_info(data, 1);
190 +       platform_device_register(&ltq_spi);
191 +}
192 +
193 +/* nand flash */
194 +static struct gpon_reg_ebu __iomem *membase_ebu;
195 +static const char *part_probes[] = { "cmdlinepart", NULL };
196 +
197 +static int falcon_nand_ready(struct mtd_info *mtd)
198 +{
199 +       u32 modcon = __raw_readl(&membase_ebu->modcon);
200 +
201 +       return (((modcon & (MODCON_STS|MODCON_STSEDGE)) ==
202 +                                               (MODCON_STS|MODCON_STSEDGE)));
203 +}
204 +
205 +/* address lines used for NAND control signals */
206 +#define NAND_ADDR_ALE          (1<<16)
207 +#define NAND_ADDR_CLE          (1<<17)
208 +
209 +static void falcon_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
210 +{
211 +       struct nand_chip *this = mtd->priv;
212 +       unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
213 +
214 +       if (ctrl & NAND_CTRL_CHANGE) {
215 +               nandaddr &= ~(NAND_ADDR_ALE | NAND_ADDR_CLE);
216 +
217 +               if (ctrl & NAND_CLE)
218 +                       nandaddr |= NAND_ADDR_CLE;
219 +               if (ctrl & NAND_ALE)
220 +                       nandaddr |= NAND_ADDR_ALE;
221 +
222 +               this->IO_ADDR_W = (void __iomem *) nandaddr;
223 +       }
224 +
225 +       if (cmd != NAND_CMD_NONE)
226 +               writeb(cmd, this->IO_ADDR_W);
227 +}
228 +
229 +static struct platform_nand_data falcon_flash_nand_data = {
230 +       .chip = {
231 +               .nr_chips               = 1,
232 +               .chip_delay             = 25,
233 +               .part_probe_types       = part_probes,
234 +       },
235 +       .ctrl = {
236 +               .cmd_ctrl               = falcon_hwcontrol,
237 +               .dev_ready              = falcon_nand_ready,
238 +       }
239 +};
240 +
241 +static struct resource ltq_nand_resources[] = {
242 +       MEM_RES("nand", LTQ_FLASH_START, LTQ_FLASH_START + LTQ_FLASH_MAX - 1),
243 +       MEM_RES("ebu", GPON_EBU_BASE, GPON_EBU_END),
244 +};
245 +
246 +static struct platform_device ltq_flash_nand = {
247 +       .name           = "gen_nand",
248 +       .id             = -1,
249 +       .num_resources  = ARRAY_SIZE(ltq_nand_resources),
250 +       .resource       = ltq_nand_resources,
251 +       .dev            = {
252 +               .platform_data = &falcon_flash_nand_data,
253 +       },
254 +};
255 +
256 +void __init falcon_register_nand(void)
257 +{
258 +       membase_ebu = ioremap_nocache(ltq_nand_resources[1].start,
259 +                       resource_size(&ltq_nand_resources[1]));
260 +
261 +       if (membase_ebu)
262 +               platform_device_register(&ltq_flash_nand);
263 +}
264 +
265 +/* watchdog */
266 +static struct resource falcon_wdt_resource =
267 +       MEM_RES("watchdog",GPON_WDT_BASE,GPON_WDT_END);
268 +
269 +void __init falcon_register_wdt(void)
270 +{
271 +       platform_device_register_simple("ltq_wdt", 0, &falcon_wdt_resource, 1);
272 +}
273 +
274 +/* gpio */
275 +#define DECLARE_GPIO_RES(port) \
276 +static struct resource falcon_gpio ## port ## _resources[] = { \
277 +       MEM_RES("gpio"#port,GPON_GPIO ## port ## _BASE,GPON_GPIO ## port ## _END), \
278 +       MEM_RES("padctrl"#port,GPON_PADCTRL ## port ## _BASE,GPON_PADCTRL ## port ## _END), \
279 +       IRQ_RES("gpio_mux"#port,FALCON_IRQ_GPIO_P ## port ) \
280 +}
281 +DECLARE_GPIO_RES(0);
282 +DECLARE_GPIO_RES(1);
283 +DECLARE_GPIO_RES(2);
284 +#ifdef REGISTER_ALL_GPIO_PORTS
285 +#if NR_IRQS < 328
286 +#error NR_IRQS to low for all gpio irqs
287 +#endif
288 +DECLARE_GPIO_RES(3);
289 +DECLARE_GPIO_RES(4);
290 +#endif
291 +
292 +void __init falcon_register_gpio(void)
293 +{
294 +       platform_device_register_simple("falcon_gpio", 0,
295 +               falcon_gpio0_resources, ARRAY_SIZE(falcon_gpio0_resources));
296 +       platform_device_register_simple("falcon_gpio", 1,
297 +               falcon_gpio1_resources, ARRAY_SIZE(falcon_gpio1_resources));
298 +       platform_device_register_simple("falcon_gpio", 2,
299 +               falcon_gpio2_resources, ARRAY_SIZE(falcon_gpio2_resources));
300 +       sys1_hw_activate(ACTS_PADCTRL1 | ACTS_P1);
301 +       sys_eth_hw_activate(SYS_ETH_ACTS_PADCTRL0 | SYS_ETH_ACTS_PADCTRL2 |
302 +               SYS_ETH_ACTS_P0 | SYS_ETH_ACTS_P2);
303 +
304 +#ifdef REGISTER_ALL_GPIO_PORTS
305 +       /* optional gpio ports: not registered,
306 +          as the pins are EBU specific and always used by linux */
307 +       platform_device_register_simple("falcon_gpio", 3,
308 +               falcon_gpio3_resources, ARRAY_SIZE(falcon_gpio3_resources));
309 +       platform_device_register_simple("falcon_gpio", 4,
310 +               falcon_gpio4_resources, ARRAY_SIZE(falcon_gpio4_resources));
311 +       sys1_hw_activate(ACTS_PADCTRL3 | ACTS_PADCTRL4 | ACTS_P3 | ACTS_P4);
312 +#endif
313 +}
314 +
315 +static struct resource falcon_i2c_resources[] = {
316 +       MEM_RES("i2c", GPON_I2C_BASE,GPON_I2C_END),
317 +       IRQ_RES("i2c_lb", FALCON_IRQ_I2C_LBREQ),
318 +       IRQ_RES("i2c_b", FALCON_IRQ_I2C_BREQ),
319 +       IRQ_RES("i2c_err", FALCON_IRQ_I2C_I2C_ERR),
320 +       IRQ_RES("i2c_p", FALCON_IRQ_I2C_I2C_P),
321 +};
322 +
323 +void __init falcon_register_i2c(void)
324 +{
325 +       platform_device_register_simple("i2c-falcon", 0,
326 +               falcon_i2c_resources, ARRAY_SIZE(falcon_i2c_resources));
327 +       sys1_hw_activate(ACTS_I2C_ACT);
328 +}
329 +
330 +void __init falcon_register_crypto(void)
331 +{
332 +       platform_device_register_simple("ltq_falcon_deu", 0, NULL, 0);
333 +}
334 --- /dev/null
335 +++ b/arch/mips/lantiq/falcon/devices.h
336 @@ -0,0 +1,22 @@
337 +#ifndef _FALCON_DEVICES_H__
338 +#define _FALCON_DEVICES_H__
339 +
340 +#include <linux/mtd/physmap.h>
341 +#include <linux/spi/spi.h>
342 +#include <linux/spi/flash.h>
343 +
344 +extern void __init falcon_register_asc(int port);
345 +extern void __init falcon_register_i2c(void);
346 +extern void __init falcon_register_spi_flash(struct spi_board_info *data);
347 +extern void __init falcon_register_gpio(void);
348 +extern void __init falcon_register_nor(struct physmap_flash_data *data);
349 +extern void __init falcon_register_nand(void);
350 +extern void __init falcon_register_wdt(void);
351 +extern void __init falcon_register_crypto(void);
352 +
353 +#define IRQ_RES(resname,irq) {.name=resname,.start=(irq),.flags=IORESOURCE_IRQ}
354 +#define MEM_RES(resname,adr_start,adr_end) \
355 +       { .name=resname, .flags=IORESOURCE_MEM, \
356 +         .start=((adr_start)&~KSEG1),.end=((adr_end)&~KSEG1) }
357 +
358 +#endif
359 --- /dev/null
360 +++ b/arch/mips/lantiq/falcon/prom.c
361 @@ -0,0 +1,52 @@
362 +/*
363 + * This program is free software; you can redistribute it and/or modify
364 + * it under the terms of the GNU General Public License as published by
365 + * the Free Software Foundation; either version 2 of the License, or
366 + * (at your option) any later version.
367 + *
368 + * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
369 + */
370 +
371 +#include <linux/module.h>
372 +#include <linux/clk.h>
373 +#include <asm/bootinfo.h>
374 +#include <asm/time.h>
375 +
376 +#include <lantiq_soc.h>
377 +
378 +#include <falcon.h>
379 +
380 +#include <falcon/gpon_reg_base.h>
381 +#include <falcon/status_reg.h>
382 +#include <falcon/sys1_reg.h>
383 +
384 +#include "../prom.h"
385 +
386 +static struct gpon_reg_status * const pSTATUS = (struct gpon_reg_status *)GPON_STATUS_BASE;
387 +
388 +#define SOC_FALCON             "Falcon"
389 +
390 +void __init
391 +ltq_soc_setup(void)
392 +{
393 +       /* not used */
394 +}
395 +
396 +void __init
397 +ltq_soc_detect(struct ltq_soc_info *i)
398 +{
399 +       i->partnum = (ltq_r32(&pSTATUS->chipid) & STATUS_CHIPID_PARTNR_MASK) >> STATUS_CHIPID_PARTNR_OFFSET;
400 +       i->rev = (ltq_r32(&pSTATUS->chipid) & STATUS_CHIPID_VERSION_MASK) >> STATUS_CHIPID_VERSION_OFFSET;
401 +       switch (i->partnum)
402 +       {
403 +       case SOC_ID_FALCON:
404 +               i->name = SOC_FALCON;
405 +               i->type = SOC_TYPE_FALCON;
406 +               break;
407 +
408 +       default:
409 +               printk(KERN_ERR "unknown partnum : 0x%08X\n", i->partnum);
410 +               while(1) {      };
411 +               break;
412 +       }
413 +}
414 --- /dev/null
415 +++ b/arch/mips/lantiq/falcon/sysctrl.c
416 @@ -0,0 +1,381 @@
417 +/*
418 + * This program is free software; you can redistribute it and/or
419 + * modify it under the terms of the GNU General Public License as
420 + * published by the Free Software Foundation; either version 2 of
421 + * the License, or (at your option) any later version.
422 + *
423 + * This program is distributed in the hope that it will be useful,
424 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
425 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
426 + * GNU General Public License for more details.
427 + *
428 + * You should have received a copy of the GNU General Public License
429 + * along with this program; if not, write to the Free Software
430 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
431 + * MA 02111-1307 USA
432 + *
433 + * Copyright (C) 2010 Thomas Langer, Lantiq Deutschland
434 + */
435 +
436 +#include <linux/cpu.h>
437 +#include <linux/init.h>
438 +#include <linux/kernel.h>
439 +#include <linux/pm.h>
440 +#include <linux/io.h>
441 +#include <linux/ioport.h>
442 +#include <linux/clk.h>
443 +#include <asm/reboot.h>
444 +
445 +#include <falcon/gpon_reg_base.h>
446 +#include <falcon/status_reg.h>
447 +#include <falcon/sys1_reg.h>
448 +#include <falcon/sys_eth_reg.h>
449 +#include <falcon/sys_gpe_reg.h>
450 +
451 +#include <falcon/sysctrl.h>
452 +
453 +/* mapping to linux hw-accessor routines */
454 +#define reg_r32(reg)                   __raw_readl(reg)
455 +#define reg_w32(val, reg)              __raw_writel(val, reg)
456 +#define reg_w32_mask(clear, set, reg)  reg_w32((reg_r32(reg) & ~(clear)) | (set), reg)
457 +
458 +static struct gpon_reg_sys1 * const sys1 = (struct gpon_reg_sys1 *)GPON_SYS1_BASE;
459 +static struct gpon_reg_sys_eth * const sys_eth = (struct gpon_reg_sys_eth *)GPON_SYS_ETH_BASE;
460 +static struct gpon_reg_sys_gpe * const sys_gpe = (struct gpon_reg_sys_gpe *)GPON_SYS_GPE_BASE;
461 +static struct gpon_reg_status * const status = (struct gpon_reg_status *)GPON_STATUS_BASE;
462 +
463 +/**
464 + * Activate the selected module(s)
465 + * Enables the clock of the module and activates the module itself.
466 + *
467 + * \param[in]   mask    bitmask of module(s), as for registers SYS1.ACT
468 + * \return void
469 + */
470 +void sys1_hw_activate(u32 mask)
471 +{
472 +       sys1_w32(mask, clken);
473 +       sys1_w32(mask, act);
474 +
475 +       while ( (sys1_r32(acts) & mask) != mask) {
476 +               /*NOP;*/
477 +       };
478 +}
479 +EXPORT_SYMBOL(sys1_hw_activate);
480 +
481 +/**
482 + * Deactivate the selected module(s)
483 + * Disables the clock of the module and deactivates the module itself.
484 + *
485 + * \param[in]   mask    bitmask of module(s), as for registers SYS1.DEACT
486 + * \return void
487 + */
488 +void sys1_hw_deactivate(u32 mask)
489 +{
490 +       sys1_w32(mask, clkclr);
491 +       sys1_w32(mask, deact);
492 +
493 +       while ( (sys1_r32(acts) & mask) != 0) {
494 +               /*NOP;*/
495 +       };
496 +}
497 +EXPORT_SYMBOL(sys1_hw_deactivate);
498 +
499 +/**
500 + * Clock enable for the selected module(s)
501 + * Enables the clock of the module.
502 + *
503 + * \param[in]   mask    bitmask of module(s), as for registers SYS1.CLKEN
504 + * \return void
505 + */
506 +void sys1_hw_clk_enable(u32 mask)
507 +{
508 +       sys1_w32(mask, clken);
509 +
510 +       while ( (sys1_r32(clks) & mask) != mask) {
511 +               /*NOP;*/
512 +       };
513 +}
514 +EXPORT_SYMBOL(sys1_hw_clk_enable);
515 +
516 +/**
517 + * Clock disable for the selected module(s)
518 + * disables the clock of the module.
519 + *
520 + * \param[in]   mask    bitmask of module(s), as for registers SYS1.CLKCLR
521 + * \return void
522 + */
523 +void sys1_hw_clk_disable(u32 mask)
524 +{
525 +       sys1_w32(mask, clkclr);
526 +
527 +       while ( (sys1_r32(clks) & mask) != 0) {
528 +               /*NOP;*/
529 +       };
530 +}
531 +EXPORT_SYMBOL(sys1_hw_clk_disable);
532 +
533 +/**
534 + * Reboots the selected module(s)
535 + * Triggers the reboot of the module.
536 + *
537 + * \param[in]   mask    bitmask of module(s), as for registers SYS1.RBT
538 + * \return void
539 + */
540 +void sys1_hw_activate_or_reboot(u32 mask)
541 +{
542 +       u32 acts = sys1_r32(acts);
543 +       /* is not already active? */
544 +       if ((~acts & mask) != 0)
545 +               sys1_hw_activate(~acts & mask);
546 +       sys1_w32(acts & mask, rbt);
547 +       while ( (sys1_r32(acts) & mask) != mask) {
548 +               /*NOP;*/
549 +       };
550 +}
551 +EXPORT_SYMBOL(sys1_hw_activate_or_reboot);
552 +
553 +/**
554 + * Activate the selected module(s)
555 + * Enables the clock of the module and activates the module itself.
556 + *
557 + * \param[in]   mask    bitmask of module(s), as for registers SYS_ETH.ACT
558 + * \return void
559 + */
560 +void sys_eth_hw_activate(u32 mask)
561 +{
562 +       sys_eth_w32(mask, clken);
563 +       sys_eth_w32(mask, act);
564 +
565 +       while ( (sys_eth_r32(acts) & mask) != mask) {
566 +               /*NOP;*/
567 +       };
568 +}
569 +EXPORT_SYMBOL(sys_eth_hw_activate);
570 +
571 +/**
572 + * Deactivate the selected module(s)
573 + * Disables the clock of the module and deactivates the module itself.
574 + *
575 + * \param[in]   mask    bitmask of module(s), as for registers SYS_ETH.DEACT
576 + * \return void
577 + */
578 +void sys_eth_hw_deactivate(u32 mask)
579 +{
580 +       sys_eth_w32(mask, clkclr);
581 +       sys_eth_w32(mask, deact);
582 +
583 +       while ( (sys_eth_r32(acts) & mask) != 0) {
584 +               /*NOP;*/
585 +       };
586 +}
587 +EXPORT_SYMBOL(sys_eth_hw_deactivate);
588 +
589 +/**
590 + * Clock enable for the selected module(s)
591 + * Enables the clock of the module.
592 + *
593 + * \param[in]   mask    bitmask of module(s), as for registers SYS_ETH.CLKEN
594 + * \return void
595 + */
596 +void sys_eth_hw_clk_enable(u32 mask)
597 +{
598 +       sys_eth_w32(mask, clken);
599 +
600 +       while ( (sys_eth_r32(clks) & mask) != mask) {
601 +               /*NOP;*/
602 +       };
603 +}
604 +EXPORT_SYMBOL(sys_eth_hw_clk_enable);
605 +
606 +/**
607 + * Clock disable for the selected module(s)
608 + * disables the clock of the module.
609 + *
610 + * \param[in]   mask    bitmask of module(s), as for registers SYS_ETH.CLKCLR
611 + * \return void
612 + */
613 +void sys_eth_hw_clk_disable(u32 mask)
614 +{
615 +       sys_eth_w32(mask, clkclr);
616 +
617 +       while ( (sys_eth_r32(clks) & mask) != 0) {
618 +               /*NOP;*/
619 +       };
620 +}
621 +EXPORT_SYMBOL(sys_eth_hw_clk_disable);
622 +
623 +/**
624 + * Reboots the selected module(s)
625 + * Triggers the reboot of the module.
626 + *
627 + * \param[in]   mask    bitmask of module(s), as for registers SYS_ETH.RBT
628 + * \return void
629 + */
630 +void sys_eth_hw_activate_or_reboot(u32 mask)
631 +{
632 +       u32 acts = sys_eth_r32(acts);
633 +       /* is not already active? */
634 +       if ((~acts & mask) != 0)
635 +               sys_eth_hw_activate(~acts & mask);
636 +       sys_eth_w32(acts & mask, rbt);
637 +       while ( (sys_eth_r32(acts) & mask) != mask) {
638 +               /*NOP;*/
639 +       };
640 +}
641 +EXPORT_SYMBOL(sys_eth_hw_activate_or_reboot);
642 +
643 +static int gpe_clk_is_enabled(void)
644 +{
645 +       u32 rd_data;
646 +
647 +       rd_data = sys1_r32(infrac);
648 +       if (rd_data & (1<<(INFRAC_GP_OFFSET+1)))
649 +               return 1;
650 +       return 0;
651 +}
652 +
653 +static void enable_gpe_clk(void)
654 +{
655 +       u32 aeFreq;
656 +       u32 rd_data;
657 +       u32 rd_data_to_keep;
658 +       int i;
659 +
660 +       if (gpe_clk_is_enabled())
661 +               /* clock already active, no need to change here */
662 +               return;
663 +
664 +       if (status_r32(config) == 0)
665 +               aeFreq = 1; /* use 625MHz on unfused chip */
666 +       else
667 +               aeFreq = (status_r32(config) & STATUS_CONFIG_GPEFREQ_MASK) >> STATUS_CONFIG_GPEFREQ_OFFSET;
668 +       rd_data = sys1_r32(infrac);
669 +       /* clear gpe-fsel and enable bits */
670 +       rd_data_to_keep = rd_data & ~(7<<(INFRAC_GP_OFFSET+1));
671 +
672 +       /* set new fsel */
673 +       sys1_w32(rd_data_to_keep | (aeFreq<<(INFRAC_GP_OFFSET+2)), infrac);
674 +
675 +       for (i = 0; i <10; i++) /* wait 10 cycles */
676 +               {}
677 +
678 +       /* keep new fsel and enable */
679 +       sys1_w32(rd_data_to_keep | (aeFreq<<(INFRAC_GP_OFFSET+2)) |
680 +               (1<<(INFRAC_GP_OFFSET+1)), infrac);
681 +       for (i = 0; i <100; i++) /* wait 100 cycles */
682 +               {}
683 +}
684 +
685 +/**
686 + * Activate the selected module(s)
687 + * Enables the clock of the module and activates the module itself.
688 + *
689 + * \param[in]   mask    bitmask of module(s), as for registers SYS_GPE.ACT
690 + * \return void
691 + */
692 +void sys_gpe_hw_activate(u32 mask)
693 +{
694 +       enable_gpe_clk();
695 +       sys_gpe_w32(mask, clken);
696 +       sys_gpe_w32(mask, act);
697 +
698 +       while ( (sys_gpe_r32(acts) & mask) != mask) {
699 +               /*NOP;*/
700 +       };
701 +}
702 +EXPORT_SYMBOL(sys_gpe_hw_activate);
703 +
704 +/**
705 + * Deactivate the selected module(s)
706 + * Disables the clock of the module and deactivates the module itself.
707 + *
708 + * \param[in]   mask    bitmask of module(s), as for registers SYS_GPE.DEACT
709 + * \return void
710 + */
711 +void sys_gpe_hw_deactivate(u32 mask)
712 +{
713 +       enable_gpe_clk();
714 +       sys_gpe_w32(mask, clkclr);
715 +       sys_gpe_w32(mask, deact);
716 +
717 +       while ( (sys_gpe_r32(acts) & mask) != 0) {
718 +               /*NOP;*/
719 +       };
720 +}
721 +EXPORT_SYMBOL(sys_gpe_hw_deactivate);
722 +
723 +/**
724 + * Clock enable for the selected module(s)
725 + * Enables the clock of the module.
726 + *
727 + * \param[in]   mask    bitmask of module(s), as for registers SYS_GPE.CLKEN
728 + * \return void
729 + */
730 +void sys_gpe_hw_clk_enable(u32 mask)
731 +{
732 +       enable_gpe_clk();
733 +       sys_gpe_w32(mask, clken);
734 +
735 +       while ( (sys_gpe_r32(clks) & mask) != mask) {
736 +               /*NOP;*/
737 +       };
738 +}
739 +EXPORT_SYMBOL(sys_gpe_hw_clk_enable);
740 +
741 +/**
742 + * Clock disable for the selected module(s)
743 + * disables the clock of the module.
744 + *
745 + * \param[in]   mask    bitmask of module(s), as for registers SYS_GPE.CLKCLR
746 + * \return void
747 + */
748 +void sys_gpe_hw_clk_disable(u32 mask)
749 +{
750 +       enable_gpe_clk();
751 +       sys_gpe_w32(mask, clkclr);
752 +
753 +       while ( (sys_gpe_r32(clks) & mask) != 0) {
754 +               /*NOP;*/
755 +       };
756 +}
757 +EXPORT_SYMBOL(sys_gpe_hw_clk_disable);
758 +
759 +/**
760 + * Reboots the selected module(s)
761 + * Triggers the reboot of the module.
762 + *
763 + * \param[in]   mask    bitmask of module(s), as for registers SYS_GPE.RBT
764 + * \return void
765 + */
766 +void sys_gpe_hw_activate_or_reboot(u32 mask)
767 +{
768 +       u32 acts;
769 +       enable_gpe_clk();
770 +       acts = sys_gpe_r32(acts);
771 +       /* is not already active? */
772 +       if ((~acts & mask) != 0)
773 +               sys_gpe_hw_activate(~acts & mask);
774 +       sys_gpe_w32(acts & mask, rbt);
775 +       while ( (sys_gpe_r32(acts) & mask) != mask) {
776 +               /*NOP;*/
777 +       };
778 +}
779 +EXPORT_SYMBOL(sys_gpe_hw_activate_or_reboot);
780 +
781 +/**
782 + * Retrieve activation status of the selected hardware module(s)
783 + *
784 + * \param[in]   mask    bitmask of module(s), as for registers SYS_GPE.RBT
785 + * \return int 1 - if hardware module(s) is activated (including clock)
786 + */
787 + int sys_gpe_hw_is_activated(u32 mask)
788 +{
789 +       if (gpe_clk_is_enabled() == 0)
790 +               return 0;
791 +
792 +       if ((sys_gpe_r32(clks) & mask) != mask)
793 +               return 0;
794 +
795 +       return ((sys_gpe_r32(acts) & mask) == mask);
796 +}
797 +EXPORT_SYMBOL(sys_gpe_hw_is_activated);
798 --- /dev/null
799 +++ b/arch/mips/lantiq/falcon/gpio.c
800 @@ -0,0 +1,505 @@
801 +/*
802 + *   This program is free software; you can redistribute it and/or modify
803 + *   it under the terms of the GNU General Public License as published by
804 + *   the Free Software Foundation; either version 2 of the License, or
805 + *   (at your option) any later version.
806 + *
807 + *   This program is distributed in the hope that it will be useful,
808 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
809 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
810 + *   GNU General Public License for more details.
811 + *
812 + *   You should have received a copy of the GNU General Public License
813 + *   along with this program; if not, write to the Free Software
814 + *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
815 + *
816 + *   Copyright (C) 2010 Thomas Langer, Lantiq Deutschland
817 + */
818 +
819 +/**
820 +       TODO:
821 +               - add locking?
822 +               - provide mask of available pins per platform_data
823 +*/
824 +
825 +#include <linux/module.h>
826 +#include <linux/types.h>
827 +#include <linux/errno.h>
828 +#include <linux/init.h>
829 +#include <linux/seq_file.h>
830 +#include <linux/platform_device.h>
831 +#include <linux/uaccess.h>
832 +#include <linux/gpio.h>
833 +#include <linux/irq.h>
834 +#include <linux/interrupt.h>
835 +#include <linux/slab.h>
836 +
837 +#include <falcon.h>
838 +#include <falcon/falcon_irq.h>
839 +
840 +#include <linux/version.h>
841 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
842 +#define for_each_set_bit for_each_bit
843 +#endif
844 +
845 +#define gpio_r32(reg)                  __raw_readl(reg)
846 +#define gpio_w32(val, reg)                     __raw_writel(val, reg)
847 +#define gpio_w32_mask(clear, set, reg) gpio_w32((gpio_r32(reg) & ~(clear)) | (set), reg)
848 +
849 +#define MAX_PORTS                      5
850 +#define PINS_PER_PORT                  32
851 +
852 +/** register structure for padctrl
853 +    (mainly needed for mux control) */
854 +typedef struct gpon_padctrl_s
855 +{
856 +       /** Multiplexer Control Register
857 +           The value 0 (the reset-value) is always the default function corresponding to the pad's name. The value 1 selects always the GPIO functionality (if available). */
858 +       unsigned int muxc[32];
859 +       /** Pull Up Enable Register */
860 +       unsigned int puen; /* 0x00000080 */
861 +       /** Pull Down Enable Register */
862 +       unsigned int pden; /* 0x00000084 */
863 +       /** Slew Rate Control Register */
864 +       unsigned int src; /* 0x00000088 */
865 +       /** Drive Current Control Register */
866 +       unsigned int dcc; /* 0x0000008C */
867 +       /** Reserved */
868 +       unsigned int res_0[24]; /* 0x00000090 */
869 +       /** Pad Control Availability Register */
870 +       unsigned int avail; /* 0x000000F0 */
871 +} gpon_padctrl0_t;
872 +
873 +/** register structure for gpio port */
874 +typedef struct gpon_gpio_s
875 +{
876 +       /** Data Output Register
877 +           Via this register the output values of the different bits can be set if they are switched as outputs. */
878 +       unsigned int out; /* 0x00000000 */
879 +       /** Data Input Register
880 +           Via this register the input values of the different bits can be observed. */
881 +       unsigned int in; /* 0x00000004 */
882 +       /** Direction Register
883 +           Via this register the input direction of the different bits can be determined. */
884 +       unsigned int dir; /* 0x00000008 */
885 +       /** Reserved */
886 +       unsigned int res_0[3]; /* 0x0000000C */
887 +       /** External Interrupt Control Register 0 */
888 +       unsigned int exintcr0; /* 0x00000018 */
889 +       /** External Interrupt Control Register 1 */
890 +       unsigned int exintcr1; /* 0x0000001C */
891 +       /** IRN Capture Register
892 +           This register shows the currently active interrupt events masked with the corresponding enable bits of the IRNEN register. The interrupts can be acknowledged by a write operation. */
893 +       unsigned int irncr; /* 0x00000020 */
894 +       /** IRN Interrupt Control Register
895 +           A write operation directly effects the interrupts. This can be used to trigger events under software control for testing purposes. A read operation returns the unmasked interrupt events. */
896 +       unsigned int irnicr; /* 0x00000024 */
897 +       /** IRN Interrupt Enable Register
898 +           This register contains the enable (or mask) bits for the interrupts. Disabled interrupts are not visible in the IRNCR register and are not signalled via the interrupt line towards the controller. */
899 +       unsigned int irnen; /* 0x00000028 */
900 +       /** IRN Interrupt Configuration Register
901 +           Configures the interrupts bitwise to be edge-senstivie or level-sensitive. */
902 +       unsigned int irncfg; /* 0x0000002C */
903 +       /** IRN Interrupt Enable Set Register
904 +           The corresponding bit in the IRNEN register can be set with an atomic access. */
905 +       unsigned int irnenset; /* 0x00000030 */
906 +       /** IRN Interrupt Enable Clear Register
907 +           The corresponding bit in the IRNEN register can be cleared with an atomic access. */
908 +       unsigned int irnenclr; /* 0x00000034 */
909 +       /** Reserved */
910 +       unsigned int res_1[2]; /* 0x00000038 */
911 +       /** Output Set Register
912 +           This register can be used to set certain bits within the OUT register without touching the other bits. */
913 +       unsigned int outset; /* 0x00000040 */
914 +       /** Output Clear Register
915 +           This register can be used to clear certain bits within the OUT register without touching the other bits. */
916 +       unsigned int outclr; /* 0x00000044 */
917 +       /** Direction Set Register
918 +           This register can be used to set certain bits within the DIR register without touching the other bits. */
919 +       unsigned int dirset; /* 0x00000048 */
920 +       /** Direction Clear Register
921 +           This register can be used to clear certain bits within the DIR register without touching the other bits. */
922 +       unsigned int dirclr; /* 0x0000004C */
923 +} gpon_gpio_t;
924 +
925 +struct falcon_gpio_port {
926 +       struct gpio_chip gpio_chip;
927 +       gpon_padctrl0_t __iomem *pad;
928 +       gpon_gpio_t __iomem *port;
929 +       struct resource *pad_req;   /* resources requested */
930 +       struct resource *port_req;
931 +       unsigned int irq_base;
932 +       unsigned int chained_irq;
933 +};
934 +
935 +static struct falcon_gpio_port ltq_gpio_port[MAX_PORTS];
936 +
937 +static int gpio_exported = 0;
938 +static int __init gpio_export_setup(char *str)
939 +{
940 +       get_option(&str, &gpio_exported);
941 +       return 1;
942 +}
943 +__setup("gpio_exported=", gpio_export_setup);
944 +
945 +static inline struct falcon_gpio_port *to_falcon_gpio_port(struct gpio_chip *chip)
946 +{
947 +       return container_of(chip, struct falcon_gpio_port, gpio_chip);
948 +}
949 +
950 +static int falcon_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
951 +{
952 +       struct falcon_gpio_port *gpio_port = to_falcon_gpio_port(chip);
953 +       gpio_w32(1<<offset, &gpio_port->port->dirclr);
954 +       return 0;
955 +}
956 +
957 +static void falcon_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
958 +{
959 +       struct falcon_gpio_port *gpio_port = to_falcon_gpio_port(chip);
960 +       if (value)
961 +               gpio_w32(1<<offset, &gpio_port->port->outset);
962 +       else
963 +               gpio_w32(1<<offset, &gpio_port->port->outclr);
964 +}
965 +
966 +static int falcon_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value)
967 +{
968 +       struct falcon_gpio_port *gpio_port = to_falcon_gpio_port(chip);
969 +       falcon_gpio_set(chip, offset, value);
970 +       gpio_w32(1<<offset, &gpio_port->port->dirset);
971 +       return 0;
972 +}
973 +
974 +static int falcon_gpio_get(struct gpio_chip *chip, unsigned int offset)
975 +{
976 +       struct falcon_gpio_port *gpio_port = to_falcon_gpio_port(chip);
977 +       if ((gpio_r32(&gpio_port->port->dir) >> offset) & 1)
978 +               return (gpio_r32(&gpio_port->port->out) >> offset) & 1;
979 +       else
980 +               return (gpio_r32(&gpio_port->port->in) >> offset) & 1;
981 +}
982 +
983 +static int falcon_gpio_request(struct gpio_chip *chip, unsigned offset)
984 +{
985 +       struct falcon_gpio_port *gpio_port = to_falcon_gpio_port(chip);
986 +       if ( (gpio_r32(&gpio_port->pad->avail) >> offset) & 1) {
987 +               if (gpio_r32(&gpio_port->pad->muxc[offset]) > 1)
988 +                       return -EBUSY;
989 +               /* switch on gpio function */
990 +               gpio_w32(1, &gpio_port->pad->muxc[offset]);
991 +               return 0;
992 +       }
993 +
994 +       return -ENODEV;
995 +}
996 +
997 +static void falcon_gpio_free(struct gpio_chip *chip, unsigned offset)
998 +{
999 +       struct falcon_gpio_port *gpio_port = to_falcon_gpio_port(chip);
1000 +       if ( (gpio_r32(&gpio_port->pad->avail) >> offset) & 1) {
1001 +               if (gpio_r32(&gpio_port->pad->muxc[offset]) > 1)
1002 +                       return;
1003 +               /* switch off gpio function */
1004 +               gpio_w32(0, &gpio_port->pad->muxc[offset]);
1005 +       }
1006 +}
1007 +
1008 +static int falcon_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
1009 +{
1010 +       struct falcon_gpio_port *gpio_port = to_falcon_gpio_port(chip);
1011 +       /* no checks: this functions is only registered with valid irq_base */
1012 +       return gpio_port->irq_base + offset;
1013 +}
1014 +
1015 +static void falcon_gpio_disable_irq(struct irq_data *d)
1016 +{
1017 +       struct falcon_gpio_port *gpio_port = irq_get_chip_data(d->irq);
1018 +       unsigned int offset = d->irq-gpio_port->irq_base;
1019 +       gpio_w32(1<<offset, &gpio_port->port->irnenclr);
1020 +}
1021 +
1022 +static void falcon_gpio_enable_irq(struct irq_data *d)
1023 +{
1024 +       struct falcon_gpio_port *gpio_port = irq_get_chip_data(d->irq);
1025 +       unsigned int offset = d->irq-gpio_port->irq_base;
1026 +
1027 +       if (gpio_r32(&gpio_port->pad->muxc[offset]) < 1) {
1028 +               /* switch on gpio function */
1029 +               gpio_w32(1, &gpio_port->pad->muxc[offset]);
1030 +       }
1031 +
1032 +       gpio_w32(1<<offset, &gpio_port->port->irnenset);
1033 +}
1034 +
1035 +static void falcon_gpio_ack_irq(struct irq_data *d)
1036 +{
1037 +       struct falcon_gpio_port *gpio_port = irq_get_chip_data(d->irq);
1038 +       unsigned int offset = d->irq-gpio_port->irq_base;
1039 +       gpio_w32(1<<offset, &gpio_port->port->irncr);
1040 +}
1041 +
1042 +static void falcon_gpio_mask_and_ack_irq(struct irq_data *d)
1043 +{
1044 +       struct falcon_gpio_port *gpio_port = irq_get_chip_data(d->irq);
1045 +       unsigned int offset = d->irq-gpio_port->irq_base;
1046 +       gpio_w32(1<<offset, &gpio_port->port->irnenclr);
1047 +       gpio_w32(1<<offset, &gpio_port->port->irncr);
1048 +}
1049 +
1050 +int ltq_gpio_mux_set(unsigned int pin, unsigned int mux)
1051 +{
1052 +       int port = pin / 100;
1053 +       int offset = pin % 100;
1054 +       struct falcon_gpio_port *gpio_port;
1055 +
1056 +       if (offset >= PINS_PER_PORT || port >= MAX_PORTS)
1057 +               return -EINVAL;
1058 +
1059 +       gpio_port = &ltq_gpio_port[port];
1060 +       gpio_w32(mux, &gpio_port->pad->muxc[offset]);
1061 +
1062 +       return 0;
1063 +}
1064 +EXPORT_SYMBOL(ltq_gpio_mux_set);
1065 +
1066 +int ltq_gpio_request(unsigned int pin, unsigned int alt0,
1067 +                    unsigned int alt1, unsigned int dir, const char *name)
1068 +{
1069 +       int port = pin / 100;
1070 +       int offset = pin % 100;
1071 +       unsigned int mux = (alt0 & 1) + (alt1 & 1) * 2;
1072 +
1073 +       if (offset >= PINS_PER_PORT || port >= MAX_PORTS)
1074 +               return -EINVAL;
1075 +
1076 +       if (gpio_request(pin, name)) {
1077 +               pr_err("failed to setup lantiq gpio: %s\n", name);
1078 +               return -EBUSY;
1079 +       }
1080 +
1081 +       if (dir)
1082 +               gpio_direction_output(pin, 1);
1083 +       else
1084 +               gpio_direction_input(pin);
1085 +
1086 +       return ltq_gpio_mux_set(pin, mux);
1087 +}
1088 +EXPORT_SYMBOL(ltq_gpio_request);
1089 +
1090 +static struct irq_chip falcon_gpio_irq_chip;
1091 +static int falcon_gpio_irq_type(struct irq_data *d, unsigned int type)
1092 +{
1093 +       struct falcon_gpio_port *gpio_port = irq_get_chip_data(d->irq);
1094 +       unsigned int offset = d->irq-gpio_port->irq_base;
1095 +       unsigned int mask = 1 << offset;
1096 +
1097 +       if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_NONE)
1098 +               return 0;
1099 +
1100 +       if ((type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) != 0) {
1101 +               /* level triggered */
1102 +               gpio_w32_mask(0, mask, &gpio_port->port->irncfg);
1103 +               irq_set_chip_and_handler_name(d->irq,
1104 +                               &falcon_gpio_irq_chip, handle_level_irq, "mux");
1105 +       } else {
1106 +               /* edge triggered */
1107 +               gpio_w32_mask(mask, 0, &gpio_port->port->irncfg);
1108 +               irq_set_chip_and_handler_name(d->irq,
1109 +                               &falcon_gpio_irq_chip, handle_simple_irq, "mux");
1110 +       }
1111 +
1112 +       if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
1113 +               gpio_w32_mask(mask, 0, &gpio_port->port->exintcr0);
1114 +               gpio_w32_mask(0, mask, &gpio_port->port->exintcr1);
1115 +       } else {
1116 +               if ((type & (IRQ_TYPE_EDGE_RISING |IRQ_TYPE_LEVEL_HIGH)) != 0) {
1117 +                       /* positive logic: rising edge, high level */
1118 +                       gpio_w32_mask(mask, 0, &gpio_port->port->exintcr0);
1119 +               } else {
1120 +                       /* negative logic: falling edge, low level */
1121 +                       gpio_w32_mask(0, mask, &gpio_port->port->exintcr0);
1122 +               }
1123 +               gpio_w32_mask(mask, 0, &gpio_port->port->exintcr1);
1124 +       }
1125 +
1126 +       return gpio_direction_input(gpio_port->gpio_chip.base + offset);
1127 +}
1128 +
1129 +static void falcon_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
1130 +{
1131 +       struct falcon_gpio_port *gpio_port = irq_desc_get_handler_data(desc);
1132 +       unsigned long irncr;
1133 +       int offset;
1134 +
1135 +       irncr = gpio_r32(&gpio_port->port->irncr);
1136 +       /* acknowledge interrupt */
1137 +       gpio_w32(irncr, &gpio_port->port->irncr);
1138 +
1139 +       desc->irq_data.chip->irq_ack(&desc->irq_data);
1140 +
1141 +       for_each_set_bit(offset, &irncr, gpio_port->gpio_chip.ngpio)
1142 +               generic_handle_irq(gpio_port->irq_base + offset);
1143 +}
1144 +
1145 +static struct irq_chip falcon_gpio_irq_chip = {
1146 +       .name = "gpio_irq_mux",
1147 +       .irq_mask = falcon_gpio_disable_irq,
1148 +       .irq_unmask = falcon_gpio_enable_irq,
1149 +       .irq_ack = falcon_gpio_ack_irq,
1150 +       .irq_mask_ack = falcon_gpio_mask_and_ack_irq,
1151 +       .irq_set_type = falcon_gpio_irq_type,
1152 +};
1153 +
1154 +static struct irqaction gpio_cascade = {
1155 +       .handler = no_action,
1156 +       .flags = IRQF_DISABLED,
1157 +       .name = "gpio_cascade",
1158 +};
1159 +
1160 +static int falcon_gpio_probe(struct platform_device *pdev)
1161 +{
1162 +       struct falcon_gpio_port *gpio_port;
1163 +       int ret, i;
1164 +       struct resource *gpiores, *padres;
1165 +       int irq;
1166 +
1167 +       if (pdev->id >= MAX_PORTS)
1168 +               return -ENODEV;
1169 +
1170 +       gpiores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1171 +       padres = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1172 +       irq = platform_get_irq(pdev, 0);
1173 +       if (!gpiores || !padres)
1174 +               return -ENODEV;
1175 +
1176 +       gpio_port = &ltq_gpio_port[pdev->id];
1177 +       gpio_port->gpio_chip.label = "falcon-gpio";
1178 +       gpio_port->gpio_chip.direction_input = falcon_gpio_direction_input;
1179 +       gpio_port->gpio_chip.direction_output = falcon_gpio_direction_output;
1180 +       gpio_port->gpio_chip.get = falcon_gpio_get;
1181 +       gpio_port->gpio_chip.set = falcon_gpio_set;
1182 +       gpio_port->gpio_chip.request = falcon_gpio_request;
1183 +       gpio_port->gpio_chip.free = falcon_gpio_free;
1184 +       gpio_port->gpio_chip.base = 100 * pdev->id;
1185 +       gpio_port->gpio_chip.ngpio = 32;
1186 +       gpio_port->gpio_chip.dev = &pdev->dev;
1187 +       gpio_port->gpio_chip.exported = gpio_exported;
1188 +
1189 +       gpio_port->port_req = request_mem_region(gpiores->start,
1190 +               resource_size(gpiores), pdev->name);
1191 +       gpio_port->pad_req = request_mem_region(padres->start,
1192 +               resource_size(padres), pdev->name);
1193 +       if (!gpio_port->port_req || !gpio_port->pad_req) {
1194 +               dev_err(&pdev->dev, "cannot claim register area\n");
1195 +               ret = -EIO;
1196 +               goto err;
1197 +       }
1198 +
1199 +       gpio_port->port = ioremap_nocache(gpiores->start,
1200 +               resource_size(gpiores));
1201 +       gpio_port->pad = ioremap_nocache(padres->start,
1202 +               resource_size(padres));
1203 +       if (!gpio_port->port || !gpio_port->pad) {
1204 +               dev_err(&pdev->dev, "Could not map io ranges\n");
1205 +               ret = -ENOMEM;
1206 +               goto err;
1207 +       }
1208 +
1209 +       if (irq>0) {
1210 +               /*
1211 +                * irq_chip support
1212 +                */
1213 +               gpio_port->gpio_chip.to_irq = falcon_gpio_to_irq;
1214 +               gpio_port->irq_base = INT_NUM_EXTRA_START + 32 * pdev->id;
1215 +
1216 +               for (i = 0; i < 32; i++) {
1217 +                       irq_set_chip_and_handler_name(gpio_port->irq_base + i,
1218 +                               &falcon_gpio_irq_chip, handle_simple_irq, "mux");
1219 +                       irq_set_chip_data(gpio_port->irq_base + i, gpio_port);
1220 +                       /* FIXME: set default cfg to level triggered */
1221 +                       //gpio_w32_mask(0, 1<<i, &gpio_port->port->irncfg);
1222 +                       /* set to negative logic (falling edge, low level) */
1223 +                       gpio_w32_mask(0, 1<<i, &gpio_port->port->exintcr0);
1224 +               }
1225 +
1226 +               gpio_port->chained_irq = irq;
1227 +               setup_irq(irq, &gpio_cascade);
1228 +               irq_set_handler_data(irq, gpio_port);
1229 +               irq_set_chained_handler(irq, falcon_gpio_irq_handler);
1230 +       }
1231 +
1232 +       ret = gpiochip_add(&gpio_port->gpio_chip);
1233 +       if (ret < 0) {
1234 +               dev_err(&pdev->dev, "Could not register gpiochip %d, %d\n",
1235 +                       pdev->id, ret);
1236 +               goto err;
1237 +       }
1238 +       platform_set_drvdata(pdev, gpio_port);
1239 +       return ret;
1240 +
1241 +err:
1242 +       dev_err(&pdev->dev, "Error in gpio_probe %d, %d\n", pdev->id, ret);
1243 +       if (gpio_port->port_req)
1244 +               release_resource(gpio_port->port_req);
1245 +       if (gpio_port->pad_req)
1246 +               release_resource(gpio_port->pad_req);
1247 +
1248 +       if (gpio_port->port)
1249 +               iounmap(gpio_port->port);
1250 +       if (gpio_port->pad)
1251 +               iounmap(gpio_port->pad);
1252 +       return ret;
1253 +}
1254 +
1255 +static int falcon_gpio_remove(struct platform_device *pdev)
1256 +{
1257 +       struct falcon_gpio_port *gpio_port = platform_get_drvdata(pdev);
1258 +       int ret;
1259 +
1260 +       ret = gpiochip_remove(&gpio_port->gpio_chip);
1261 +       if (gpio_port->port_req)
1262 +               release_resource(gpio_port->port_req);
1263 +       if (gpio_port->pad_req)
1264 +               release_resource(gpio_port->pad_req);
1265 +       if (gpio_port->port)
1266 +               iounmap(gpio_port->port);
1267 +       if (gpio_port->pad)
1268 +               iounmap(gpio_port->pad);
1269 +
1270 +       return ret;
1271 +}
1272 +
1273 +static struct platform_driver falcon_gpio_driver = {
1274 +       .probe = falcon_gpio_probe,
1275 +       .remove = __devexit_p(falcon_gpio_remove),
1276 +       .driver = {
1277 +               .name = "falcon_gpio",
1278 +               .owner = THIS_MODULE,
1279 +       },
1280 +};
1281 +
1282 +int __init falcon_gpio_init(void)
1283 +{
1284 +       int ret;
1285 +
1286 +       printk(KERN_INFO "FALC(tm) ON GPIO Driver, (C) 2011 Lantiq Deutschland Gmbh\n");
1287 +       ret = platform_driver_register(&falcon_gpio_driver);
1288 +       if (ret)
1289 +               pr_err( "falcon_gpio: Error registering platform driver!");
1290 +       return ret;
1291 +}
1292 +
1293 +void __exit falcon_gpio_exit(void)
1294 +{
1295 +       platform_driver_unregister(&falcon_gpio_driver);
1296 +}
1297 +
1298 +int gpio_to_irq(unsigned int gpio)
1299 +{
1300 +       return __gpio_to_irq(gpio);
1301 +}
1302 +EXPORT_SYMBOL(gpio_to_irq);
1303 +
1304 +module_init(falcon_gpio_init);
1305 +module_exit(falcon_gpio_exit);
1306 --- /dev/null
1307 +++ b/arch/mips/include/asm/mach-lantiq/falcon/falcon.h
1308 @@ -0,0 +1,16 @@
1309 +/*
1310 + *   This program is free software; you can redistribute it and/or modify
1311 + *   it under the terms of the GNU General Public License as published by
1312 + *   the Free Software Foundation; either version 2 of the License, or
1313 + *   (at your option) any later version.
1314 + *
1315 + *   Copyright (C) 2005 infineon
1316 + *   Copyright (C) 2010 John Crispin <blogic@openwrt.org>
1317 + */
1318 +
1319 +#ifdef CONFIG_SOC_FALCON
1320 +
1321 +#include <lantiq_soc.h>
1322 +#include <falcon/gpon_reg_base.h>
1323 +
1324 +#endif
1325 --- /dev/null
1326 +++ b/arch/mips/lantiq/falcon/reset.c
1327 @@ -0,0 +1,95 @@
1328 +/*
1329 + * This program is free software; you can redistribute it and/or modify
1330 + * it under the terms of the GNU General Public License as published by
1331 + * the Free Software Foundation; either version 2 of the License, or
1332 + * (at your option) any later version.
1333 + *
1334 + * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
1335 + */
1336 +
1337 +#include <linux/init.h>
1338 +#include <linux/io.h>
1339 +#include <linux/pm.h>
1340 +#include <asm/reboot.h>
1341 +#include <linux/module.h>
1342 +
1343 +#include <falcon.h>
1344 +#include <falcon/gpon_reg_base.h>
1345 +#include <falcon/status_reg.h>
1346 +#include <falcon/sys1_reg.h>
1347 +
1348 +static struct gpon_reg_sys1 * const pSYS1 = (struct gpon_reg_sys1 *)GPON_SYS1_BASE;
1349 +
1350 +#define WDT_PW1                        0x00BE0000
1351 +#define WDT_PW2                        0x00DC0000
1352 +#define WDT_REG_BASE           (KSEG1 | 0x1F8803F0)
1353 +
1354 +struct gpon_reg_boot {
1355 +       /* bootrom related virtual registers */
1356 +       unsigned int rvec;
1357 +       unsigned int nvec;
1358 +       unsigned int evec;
1359 +       unsigned int cp0_status;
1360 +       unsigned int cp0_epc;
1361 +       unsigned int cp0_eepc;
1362 +       unsigned int size;
1363 +       unsigned int cfg_stat;
1364 +       /* additional virtual registers */
1365 +       unsigned int magic0; /* magic for valid reboot */
1366 +       unsigned int magic1; /*  -"-  */
1367 +       unsigned int bcount; /* reboot counter, used by u-boot */
1368 +} * const pBOOT = (struct gpon_reg_boot *)GPON_SBS0RAM_BASE;
1369 +
1370 +/* This function is used by the watchdog driver */
1371 +int ltq_reset_cause(void)
1372 +{
1373 +       return 0;
1374 +}
1375 +EXPORT_SYMBOL_GPL(ltq_reset_cause);
1376 +
1377 +static void
1378 +ltq_machine_restart(char *command)
1379 +{
1380 +       printk(KERN_NOTICE "System restart\n");
1381 +       local_irq_disable();
1382 +       /* write magic to signal a valid restart */
1383 +       ltq_w32(0x4C545100, &pBOOT->magic0); /* 'LTQ\0' */
1384 +       ltq_w32(0x0051544C, &pBOOT->magic1); /* '\0QTL' */
1385 +       ltq_w32(0, &pBOOT->rvec); /* reset Bootreg RVEC */
1386 +       /* reset via watchdog timer, to ensure reset of all hardware components */
1387 +       ltq_w32(WDT_PW1, (void*)WDT_REG_BASE);
1388 +       ltq_w32(WDT_PW2 |
1389 +               (0x3 << 26) | /* PWL */
1390 +               (0x2 << 24) | /* CLKDIV */
1391 +               (0x1 << 31) | /* enable */
1392 +               (1), /* reload */
1393 +               (void*)WDT_REG_BASE);
1394 +       for(;;);
1395 +}
1396 +
1397 +static void
1398 +ltq_machine_halt(void)
1399 +{
1400 +       printk(KERN_NOTICE "System halted.\n");
1401 +       local_irq_disable();
1402 +       for(;;);
1403 +}
1404 +
1405 +static void
1406 +ltq_machine_power_off(void)
1407 +{
1408 +       printk(KERN_NOTICE "Please turn off the power now.\n");
1409 +       local_irq_disable();
1410 +       for(;;);
1411 +}
1412 +
1413 +static int __init
1414 +mips_reboot_setup(void)
1415 +{
1416 +       _machine_restart = ltq_machine_restart;
1417 +       _machine_halt = ltq_machine_halt;
1418 +       pm_power_off = ltq_machine_power_off;
1419 +       return 0;
1420 +}
1421 +
1422 +arch_initcall(mips_reboot_setup);
1423 --- /dev/null
1424 +++ b/arch/mips/lantiq/falcon/mach-easy98000.c
1425 @@ -0,0 +1,255 @@
1426 +#include <linux/init.h>
1427 +#include <linux/platform_device.h>
1428 +#include <linux/leds.h>
1429 +#include <linux/gpio.h>
1430 +#include <linux/gpio_buttons.h>
1431 +#include <linux/etherdevice.h>
1432 +#include <linux/mtd/mtd.h>
1433 +#include <linux/mtd/partitions.h>
1434 +#include <linux/mtd/physmap.h>
1435 +#include <linux/input.h>
1436 +#include <linux/interrupt.h>
1437 +#include <linux/dm9000.h>
1438 +#include <linux/i2c.h>
1439 +#include <linux/i2c-gpio.h>
1440 +#include <linux/spi/spi.h>
1441 +#include <linux/spi/spi_gpio.h>
1442 +#include <linux/spi/eeprom.h>
1443 +
1444 +#include "../machtypes.h"
1445 +
1446 +#include "devices.h"
1447 +#include "dev-leds-gpio.h"
1448 +
1449 +#define EASY98000_GPIO_LED_0 9
1450 +#define EASY98000_GPIO_LED_1 10
1451 +#define EASY98000_GPIO_LED_2 11
1452 +#define EASY98000_GPIO_LED_3 12
1453 +#define EASY98000_GPIO_LED_4 13
1454 +#define EASY98000_GPIO_LED_5 14
1455 +
1456 +extern unsigned char ltq_ethaddr[6];
1457 +
1458 +static struct mtd_partition easy98000_nor_partitions[] =
1459 +{
1460 +       {
1461 +               .name   = "uboot",
1462 +               .offset = 0x0,
1463 +               .size   = 0x40000,
1464 +       },
1465 +       {
1466 +               .name   = "uboot_env",
1467 +               .offset = 0x40000,
1468 +               .size   = 0x40000,      /* 2 sectors for redundant env. */
1469 +       },
1470 +       {
1471 +               .name   = "linux",
1472 +               .offset = 0x80000,
1473 +               .size   = 0xF80000,     /* map only 16 MiB */
1474 +       },
1475 +};
1476 +
1477 +static struct physmap_flash_data easy98000_nor_flash_data = {
1478 +       .nr_parts       = ARRAY_SIZE(easy98000_nor_partitions),
1479 +       .parts          = easy98000_nor_partitions,
1480 +};
1481 +
1482 +static struct flash_platform_data easy98000_spi_flash_platform_data = {
1483 +       .name = "sflash",
1484 +       .parts = easy98000_nor_partitions,
1485 +       .nr_parts = ARRAY_SIZE(easy98000_nor_partitions)
1486 +};
1487 +
1488 +static struct spi_board_info easy98000_spi_flash_data __initdata = {
1489 +       .modalias               = "m25p80",
1490 +       .bus_num                = 0,
1491 +       .chip_select            = 0,
1492 +       .max_speed_hz           = 10 * 1000 * 1000,
1493 +       .mode                   = SPI_MODE_3,
1494 +       .platform_data          = &easy98000_spi_flash_platform_data
1495 +};
1496 +
1497 +static struct gpio_led easy98000_leds_gpio[] __initdata = {
1498 +       {
1499 +               .name           = "easy98000:green:0",
1500 +               .gpio           = EASY98000_GPIO_LED_0,
1501 +               .active_low     = 0,
1502 +       }, {
1503 +               .name           = "easy98000:green:1",
1504 +               .gpio           = EASY98000_GPIO_LED_1,
1505 +               .active_low     = 0,
1506 +       }, {
1507 +               .name           = "easy98000:green:2",
1508 +               .gpio           = EASY98000_GPIO_LED_2,
1509 +               .active_low     = 0,
1510 +       }, {
1511 +               .name           = "easy98000:green:3",
1512 +               .gpio           = EASY98000_GPIO_LED_3,
1513 +               .active_low     = 0,
1514 +       }, {
1515 +               .name           = "easy98000:green:4",
1516 +               .gpio           = EASY98000_GPIO_LED_4,
1517 +               .active_low     = 0,
1518 +       }, {
1519 +               .name           = "easy98000:green:5",
1520 +               .gpio           = EASY98000_GPIO_LED_5,
1521 +               .active_low     = 0,
1522 +       }
1523 +};
1524 +
1525 +#define CONFIG_DM9000_BASE             0x14000000
1526 +#define DM9000_IO                      (CONFIG_DM9000_BASE + 3)
1527 +#define DM9000_DATA                    (CONFIG_DM9000_BASE + 1)
1528 +
1529 +static struct dm9000_plat_data dm9000_plat_data = {
1530 +       .flags = DM9000_PLATF_8BITONLY,
1531 +       //.dev_addr = { }, /* possibility to provide an ethernet address for the chip */
1532 +};
1533 +
1534 +static struct resource dm9000_resources[] = {
1535 +       MEM_RES("dm9000_io", DM9000_IO, DM9000_IO),
1536 +       MEM_RES("dm9000_data", DM9000_DATA, DM9000_DATA),
1537 +       [2] = {
1538 +               /* with irq (210 -> gpio 110) the driver is very unreliable */
1539 +               .start  = -1,           /* use polling */
1540 +               .end    = -1,
1541 +               .flags  = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
1542 +       },
1543 +};
1544 +
1545 +static struct platform_device dm9000_platform = {
1546 +       .name = "dm9000",
1547 +       .id = 0,
1548 +       .num_resources  = ARRAY_SIZE(dm9000_resources),
1549 +       .resource       = dm9000_resources,
1550 +       .dev = {
1551 +               .platform_data = (void *) &dm9000_plat_data,
1552 +       }
1553 +};
1554 +
1555 +extern int easy98000_addon_has_dm9000(void);
1556 +static void __init register_davicom(void)
1557 +{
1558 +       if (!easy98000_addon_has_dm9000())
1559 +               return;
1560 +
1561 +       if (!is_valid_ether_addr(ltq_ethaddr))
1562 +               random_ether_addr(dm9000_plat_data.dev_addr);
1563 +       else {
1564 +               memcpy(dm9000_plat_data.dev_addr, ltq_ethaddr, 6);
1565 +               /* change to "Locally Administered Address" */
1566 +               dm9000_plat_data.dev_addr[0] |= 0x2;
1567 +       }
1568 +       platform_device_register(&dm9000_platform);
1569 +}
1570 +
1571 +static struct i2c_gpio_platform_data easy98000_i2c_gpio_data = {
1572 +       .sda_pin        = 107,
1573 +       .scl_pin        = 108,
1574 +};
1575 +
1576 +static struct platform_device easy98000_i2c_gpio_device = {
1577 +       .name           = "i2c-gpio",
1578 +       .id             = 0,
1579 +       .dev = {
1580 +               .platform_data  = &easy98000_i2c_gpio_data,
1581 +       }
1582 +};
1583 +
1584 +void __init register_easy98000_cpld(void)
1585 +{
1586 +       platform_device_register_simple("easy98000_cpld_led", 0, NULL, 0);
1587 +       platform_device_register_simple("easy98000_addon", 0, NULL, 0);
1588 +}
1589 +
1590 +/* setup gpio based spi bus/device for access to the eeprom on the board */
1591 +#define SPI_GPIO_MRST  102
1592 +#define SPI_GPIO_MTSR  103
1593 +#define SPI_GPIO_CLK   104
1594 +#define SPI_GPIO_CS0   105
1595 +#define SPI_GPIO_CS1   106
1596 +#define SPI_GPIO_BUS_NUM       1
1597 +
1598 +static struct spi_gpio_platform_data easy98000_spi_gpio_data = {
1599 +       .sck            = SPI_GPIO_CLK,
1600 +       .mosi           = SPI_GPIO_MTSR,
1601 +       .miso           = SPI_GPIO_MRST,
1602 +       .num_chipselect = 2,
1603 +};
1604 +
1605 +static struct platform_device easy98000_spi_gpio_device = {
1606 +       .name                   = "spi_gpio",
1607 +       .id                     = SPI_GPIO_BUS_NUM,
1608 +       .dev.platform_data      = &easy98000_spi_gpio_data,
1609 +};
1610 +
1611 +static struct spi_eeprom at25160n = {
1612 +       .byte_len       = 16 * 1024 / 8,
1613 +       .name           = "at25160n",
1614 +       .page_size      = 32,
1615 +       .flags          = EE_ADDR2,
1616 +};
1617 +
1618 +static struct spi_board_info easy98000_spi_gpio_devices __initdata = {
1619 +       .modalias               = "at25",
1620 +       .bus_num                = SPI_GPIO_BUS_NUM,
1621 +       .max_speed_hz           = 1000 * 1000,
1622 +       .mode                   = SPI_MODE_3,
1623 +       .chip_select            = 1,
1624 +       .controller_data        = (void *) SPI_GPIO_CS1,
1625 +       .platform_data          = &at25160n,
1626 +};
1627 +
1628 +static void __init easy98000_spi_gpio_init(void)
1629 +{
1630 +       spi_register_board_info(&easy98000_spi_gpio_devices, 1);
1631 +       platform_device_register(&easy98000_spi_gpio_device);
1632 +}
1633 +
1634 +static void __init easy98000_init_common(void)
1635 +{
1636 +       falcon_register_asc(0);
1637 +       falcon_register_gpio();
1638 +       falcon_register_wdt();
1639 +       falcon_register_i2c();
1640 +       platform_device_register(&easy98000_i2c_gpio_device);
1641 +       register_davicom();
1642 +       ltq_add_device_leds_gpio(-1, ARRAY_SIZE(easy98000_leds_gpio),
1643 +                                       easy98000_leds_gpio);
1644 +       register_easy98000_cpld();
1645 +       falcon_register_crypto();
1646 +       easy98000_spi_gpio_init();
1647 +}
1648 +
1649 +static void __init easy98000_init(void)
1650 +{
1651 +       easy98000_init_common();
1652 +       falcon_register_nor(&easy98000_nor_flash_data);
1653 +}
1654 +
1655 +static void __init easy98000sf_init(void)
1656 +{
1657 +       easy98000_init_common();
1658 +       falcon_register_spi_flash(&easy98000_spi_flash_data);
1659 +}
1660 +
1661 +static void __init easy98000nand_init(void)
1662 +{
1663 +       easy98000_init_common();
1664 +       falcon_register_nand();
1665 +}
1666 +
1667 +MIPS_MACHINE(LANTIQ_MACH_EASY98000,
1668 +                       "EASY98000",
1669 +                       "EASY98000 Eval Board",
1670 +                       easy98000_init);
1671 +
1672 +MIPS_MACHINE(LANTIQ_MACH_EASY98000SF,
1673 +                       "EASY98000SF",
1674 +                       "EASY98000 Eval Board (Serial Flash)",
1675 +                       easy98000sf_init);
1676 +
1677 +MIPS_MACHINE(LANTIQ_MACH_EASY98000NAND,
1678 +                       "EASY98000NAND",
1679 +                       "EASY98000 Eval Board (NAND Flash)",
1680 +                       easy98000nand_init);
1681 --- /dev/null
1682 +++ b/arch/mips/lantiq/falcon/softdog_vpe.c
1683 @@ -0,0 +1,109 @@
1684 +/*
1685 +** =============================================================================
1686 +** FILE NAME     : softdog_vpe.c
1687 +** MODULES       : LXDB
1688 +** DATE          : 24-03-2008
1689 +** AUTHOR        : LXDB Team
1690 +** DESCRIPTION   : This header file contains the code for the watchdog
1691 +**                 implentation on vpe1 side.
1692 +** REFERENCES    :
1693 +** COPYRIGHT     : Copyright (c) 2008
1694 +**                 Am Campeon 1-12, 85579 Neubiberg, Germany
1695 +** Any use of this software is subject to the conclusion of a respective
1696 +** License agreement. Without such a License agreement no rights to the
1697 +** software are granted
1698 +**
1699 +** HISTORY       :
1700 +** $Date   $Author    $Comment
1701 +** 24-03-2008   LXDB    Initial version
1702 +** ============================================================================
1703 +*/
1704 +
1705 +#include <linux/module.h>
1706 +#include <linux/moduleparam.h>
1707 +#include <linux/types.h>
1708 +#include <linux/timer.h>
1709 +#include <linux/reboot.h>
1710 +#include <linux/init.h>
1711 +#include <linux/jiffies.h>
1712 +
1713 +#include <falcon/vpe.h>
1714 +
1715 +static unsigned long last_wdog_value;
1716 +static unsigned long vpe1_wdog_cleared;
1717 +
1718 +static unsigned long vpe1_wdog_dead;
1719 +static void watchdog_vpe0_fire(unsigned long); /* Called when vpe0 timer expires */
1720 +static void keep_alive_vpe0(unsigned long);
1721 +VPE_SW_WDOG_RESET reset_local_fn;
1722 +
1723 +
1724 +static struct timer_list watchdog_vpe0_ticktock =
1725 +                TIMER_INITIALIZER(watchdog_vpe0_fire, 0, 0);
1726 +
1727 +static void watchdog_vpe0_fire (unsigned long flags)
1728 +{
1729 +       volatile unsigned long *wdog_ctr_value;
1730 +       wdog_ctr_value = (void*)vpe1_wdog_ctr;
1731 +       if (*wdog_ctr_value == last_wdog_value) { /* VPE1 watchdog expiry handling */
1732 +               vpe1_sw_wdog_stop(flags);
1733 +               vpe1_wdog_dead++;
1734 +               printk(KERN_DEBUG "VPE1 watchdog reset handler called\n");
1735 +       /* Call the reset handler function */
1736 +               reset_local_fn(flags);
1737 +       } else { /* Everything is OK on vpe1 side. Continue. */
1738 +               last_wdog_value = *wdog_ctr_value;
1739 +               vpe1_wdog_cleared++;
1740 +               keep_alive_vpe0(flags);
1741 +       }
1742 +}
1743 +
1744 +int32_t vpe1_sw_wdog_register_reset_handler (VPE_SW_WDOG_RESET reset_fn)
1745 +{
1746 +       reset_local_fn = (VPE_SW_WDOG_RESET)reset_fn;
1747 +       return 0;
1748 +}
1749 +
1750 +static void keep_alive_vpe0(unsigned long flags)
1751 +{
1752 +       mod_timer(&watchdog_vpe0_ticktock, jiffies+ vpe1_wdog_timeout );
1753 +}
1754 +
1755 +unsigned long vpe1_sw_wdog_start(unsigned long flags)
1756 +{
1757 +       volatile unsigned long *wdog_ctr_value;
1758 +       wdog_ctr_value = (void*)vpe1_wdog_ctr;
1759 +       *wdog_ctr_value = 0;
1760 +       last_wdog_value = 0;
1761 +       keep_alive_vpe0(flags);
1762 +       return 0;
1763 +}
1764 +
1765 +unsigned long vpe1_sw_wdog_stop(unsigned long flags)
1766 +{
1767 +       del_timer(&watchdog_vpe0_ticktock);
1768 +       return 0;
1769 +}
1770 +
1771 +static int __init watchdog_vpe1_init(void)
1772 +{
1773 +       /* Nothing to be done here */
1774 +       return 0;
1775 +}
1776 +
1777 +static void __exit watchdog_vpe1_exit(void)
1778 +{
1779 +       unsigned long flags=0;
1780 +       vpe1_sw_wdog_stop(flags);
1781 +}
1782 +
1783 +module_init(watchdog_vpe1_init);
1784 +module_exit(watchdog_vpe1_exit);
1785 +
1786 +EXPORT_SYMBOL(vpe1_sw_wdog_register_reset_handler);
1787 +EXPORT_SYMBOL(vpe1_sw_wdog_start);
1788 +EXPORT_SYMBOL(vpe1_sw_wdog_stop);
1789 +
1790 +MODULE_AUTHOR("LXDB");
1791 +MODULE_DESCRIPTION("Software Watchdog For VPE1");
1792 +MODULE_LICENSE("GPL");
1793 --- /dev/null
1794 +++ b/arch/mips/include/asm/mach-lantiq/falcon/vpe.h
1795 @@ -0,0 +1,44 @@
1796 +/*
1797 + *   This program is free software; you can redistribute it and/or modify
1798 + *   it under the terms of the GNU General Public License as published by
1799 + *   the Free Software Foundation; either version 2 of the License, or
1800 + *   (at your option) any later version.
1801 + *
1802 + *   This program is distributed in the hope that it will be useful,
1803 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
1804 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1805 + *   GNU General Public License for more details.
1806 + *
1807 + *   You should have received a copy of the GNU General Public License
1808 + *   along with this program; if not, write to the Free Software
1809 + *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
1810 + *
1811 + *   Copyright (C) 2005 infineon
1812 + *   Copyright (C) 2007 John Crispin <blogic@openwrt.org>
1813 + *
1814 + */
1815 +#ifndef _IFXMIPS_VPE_H__
1816 +#define _IFXMIPS_VPE_H__
1817 +
1818 +/* For the explanation of the APIs please refer the section "MT APRP Kernel
1819 + * Programming" in AR9 SW Architecture Specification
1820 + */
1821 +int32_t vpe1_sw_start(void* sw_start_addr, uint32_t tcmask, uint32_t flags);
1822 +int32_t vpe1_sw_stop(uint32_t flags);
1823 +uint32_t vpe1_get_load_addr (uint32_t flags);
1824 +uint32_t vpe1_get_max_mem (uint32_t flags);
1825 +
1826 +int32_t vpe1_set_boot_param(char *field, char *value, char flags);
1827 +int32_t vpe1_get_boot_param(char *field, char **value, char flags);
1828 +
1829 +/* Watchdog APIs */
1830 +extern unsigned long vpe1_wdog_ctr;
1831 +extern unsigned long vpe1_wdog_timeout;
1832 +
1833 +unsigned long vpe1_sw_wdog_start(unsigned long);
1834 +unsigned long vpe1_sw_wdog_stop(unsigned long);
1835 +
1836 +typedef int (*VPE_SW_WDOG_RESET)(unsigned long wdog_cleared_ok_count);
1837 +int32_t vpe1_sw_wdog_register_reset_handler(VPE_SW_WDOG_RESET reset_fn);
1838 +
1839 +#endif
1840 --- a/arch/mips/lantiq/Kconfig
1841 +++ b/arch/mips/lantiq/Kconfig
1842 @@ -16,8 +16,12 @@ config SOC_XWAY
1843         bool "XWAY"
1844         select SOC_TYPE_XWAY
1845         select HW_HAS_PCI
1846 +
1847 +config SOC_FALCON
1848 +       bool "FALCON"
1849  endchoice
1850  
1851  source "arch/mips/lantiq/xway/Kconfig"
1852 +source "arch/mips/lantiq/falcon/Kconfig"
1853  
1854  endif
1855 --- a/arch/mips/lantiq/Makefile
1856 +++ b/arch/mips/lantiq/Makefile
1857 @@ -9,3 +9,4 @@ obj-y := irq.o setup.o clk.o prom.o devi
1858  obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
1859  
1860  obj-$(CONFIG_SOC_TYPE_XWAY) += xway/
1861 +obj-$(CONFIG_SOC_FALCON) += falcon/
1862 --- a/arch/mips/lantiq/Platform
1863 +++ b/arch/mips/lantiq/Platform
1864 @@ -6,3 +6,4 @@ platform-$(CONFIG_LANTIQ)       += lantiq/
1865  cflags-$(CONFIG_LANTIQ)                += -I$(srctree)/arch/mips/include/asm/mach-lantiq
1866  load-$(CONFIG_LANTIQ)          = 0xffffffff80002000
1867  cflags-$(CONFIG_SOC_TYPE_XWAY) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway
1868 +cflags-$(CONFIG_SOC_FALCON)    += -I$(srctree)/arch/mips/include/asm/mach-lantiq/falcon
1869 --- a/arch/mips/lantiq/machtypes.h
1870 +++ b/arch/mips/lantiq/machtypes.h
1871 @@ -15,6 +15,12 @@ enum lantiq_mach_type {
1872         LTQ_MACH_GENERIC = 0,
1873         LTQ_MACH_EASY50712,     /* Danube evaluation board */
1874         LTQ_MACH_EASY50601,     /* Amazon SE evaluation board */
1875 +
1876 +       /* FALCON */
1877 +       LANTIQ_MACH_EASY98000,          /* Falcon Eval Board, NOR Flash */
1878 +       LANTIQ_MACH_EASY98000SF,        /* Falcon Eval Board, Serial Flash */
1879 +       LANTIQ_MACH_EASY98000NAND,      /* Falcon Eval Board, NAND Flash */
1880 +       LANTIQ_MACH_EASY98020,          /* Falcon Reference Board */
1881  };
1882  
1883  #endif
1884 --- /dev/null
1885 +++ b/arch/mips/lantiq/falcon/addon-easy98000.c
1886 @@ -0,0 +1,212 @@
1887 +/*
1888 + *  EASY98000 CPLD Addon driver
1889 + *
1890 + *  Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
1891 + *
1892 + *  This program is free software; you can redistribute it and/or modify it
1893 + *  under the terms of the GNU General Public License version 2  as published
1894 + *  by the Free Software Foundation.
1895 + *
1896 + */
1897 +
1898 +#include <linux/kernel.h>
1899 +#include <linux/version.h>
1900 +#include <linux/types.h>
1901 +#include <linux/init.h>
1902 +#include <linux/platform_device.h>
1903 +#include <linux/errno.h>
1904 +#include <linux/slab.h>
1905 +#include <linux/proc_fs.h>
1906 +#include <linux/seq_file.h>
1907 +
1908 +struct easy98000_reg_cpld {
1909 +       u16 cmdreg1;            /* 0x1 */
1910 +       u16 cmdreg0;            /* 0x0 */
1911 +       u16 idreg0;             /* 0x3 */
1912 +       u16 resreg;             /* 0x2 */
1913 +       u16 intreg;             /* 0x5 */
1914 +       u16 idreg1;             /* 0x4 */
1915 +       u16 ledreg;             /* 0x7 */
1916 +       u16 pcmconconfig;       /* 0x6 */
1917 +       u16 res0;               /* 0x9 */
1918 +       u16 ethledreg;          /* 0x8 */
1919 +       u16 res1[4];            /* 0xa-0xd */
1920 +       u16 cpld1v;             /* 0xf */
1921 +       u16 cpld2v;             /* 0xe */
1922 +};
1923 +static struct easy98000_reg_cpld * const cpld =
1924 +       (struct easy98000_reg_cpld *)(KSEG1 | 0x17c00000);
1925 +#define cpld_r8(reg) (__raw_readw(&cpld->reg) & 0xFF)
1926 +#define cpld_w8(val, reg) __raw_writew((val) & 0xFF, &cpld->reg)
1927 +
1928 +int easy98000_addon_has_dm9000(void)
1929 +{
1930 +       if ((cpld_r8(idreg0) & 0xF) == 1)
1931 +               return 1;
1932 +       return 0;
1933 +}
1934 +
1935 +#if defined(CONFIG_PROC_FS)
1936 +typedef void (*cpld_dump) (struct seq_file *s);
1937 +struct proc_entry {
1938 +       char *name;
1939 +       void *callback;
1940 +};
1941 +
1942 +static int cpld_proc_show ( struct seq_file *s, void *p )
1943 +{
1944 +       cpld_dump dump = s->private;
1945 +
1946 +       if ( dump != NULL )
1947 +               dump(s);
1948 +
1949 +       return 0;
1950 +}
1951 +
1952 +static int cpld_proc_open ( struct inode *inode, struct file *file )
1953 +{
1954 +       return single_open ( file, cpld_proc_show, PDE(inode)->data );
1955 +}
1956 +
1957 +static void cpld_versions_get ( struct seq_file *s )
1958 +{
1959 +       seq_printf(s, "CPLD1: V%d\n", cpld_r8(cpld1v));
1960 +       seq_printf(s, "CPLD2: V%d\n", cpld_r8(cpld2v));
1961 +}
1962 +
1963 +static void cpld_ebu_module_get ( struct seq_file *s )
1964 +{
1965 +       u8 addon_id;
1966 +
1967 +       addon_id = cpld_r8(idreg0) & 0xF;
1968 +       switch (addon_id) {
1969 +       case 0xF: /* nothing connected */
1970 +               break;
1971 +       case 1:
1972 +               seq_printf(s, "Ethernet Controller module (dm9000)\n");
1973 +               break;
1974 +       default:
1975 +               seq_printf(s, "Unknown EBU module (EBU_ID=0x%02X)\n", addon_id);
1976 +               break;
1977 +       }
1978 +}
1979 +
1980 +static void cpld_xmii_module_get ( struct seq_file *s )
1981 +{
1982 +       u8 addon_id;
1983 +       char *mod = NULL;
1984 +
1985 +       addon_id = cpld_r8(idreg1) & 0xF;
1986 +       switch (addon_id) {
1987 +       case 0xF:
1988 +               mod = "no module";
1989 +               break;
1990 +       case 0x1:
1991 +               mod = "RGMII module";
1992 +               break;
1993 +       case 0x4:
1994 +               mod = "GMII MAC Mode (XWAY TANTOS-3G)";
1995 +               break;
1996 +       case 0x6:
1997 +               mod = "TMII MAC Mode (XWAY TANTOS-3G)";
1998 +               break;
1999 +       case 0x8:
2000 +               mod = "GMII PHY module";
2001 +               break;
2002 +       case 0x9:
2003 +               mod = "MII PHY module";
2004 +               break;
2005 +       case 0xA:
2006 +               mod = "RMII PHY module";
2007 +               break;
2008 +       default:
2009 +               break;
2010 +       }
2011 +       if (mod)
2012 +               seq_printf(s, "%s\n", mod);
2013 +       else
2014 +               seq_printf(s, "unknown xMII module (xMII_ID=0x%02X)\n", addon_id);
2015 +}
2016 +
2017 +static struct proc_entry proc_entries[] = {
2018 +       {"versions",    cpld_versions_get},
2019 +       {"ebu",         cpld_ebu_module_get},
2020 +       {"xmii",        cpld_xmii_module_get},
2021 +};
2022 +
2023 +static struct file_operations ops = {
2024 +       .owner   = THIS_MODULE,
2025 +       .open    = cpld_proc_open,
2026 +       .read    = seq_read,
2027 +       .llseek  = seq_lseek,
2028 +       .release = single_release,
2029 +};
2030 +
2031 +static void cpld_proc_entry_create(struct proc_dir_entry *parent_node,
2032 +                                  struct proc_entry *proc_entry)
2033 +{
2034 +       proc_create_data ( proc_entry->name, (S_IFREG | S_IRUGO), parent_node,
2035 +                          &ops, proc_entry->callback);
2036 +}
2037 +
2038 +static int cpld_proc_install(void)
2039 +{
2040 +       struct proc_dir_entry *driver_proc_node;
2041 +
2042 +       driver_proc_node = proc_mkdir("cpld", NULL);
2043 +       if (driver_proc_node != NULL) {
2044 +               int i;
2045 +               for (i = 0; i < ARRAY_SIZE(proc_entries); i++)
2046 +                       cpld_proc_entry_create(driver_proc_node,
2047 +                                             &proc_entries[i]);
2048 +       } else {
2049 +               printk("cannot create proc entry");
2050 +               return -1;
2051 +       }
2052 +       return 0;
2053 +}
2054 +#else
2055 +static inline int cpld_proc_install(void) {}
2056 +#endif
2057 +
2058 +static int easy98000_addon_probe(struct platform_device *pdev)
2059 +{
2060 +       return cpld_proc_install();
2061 +}
2062 +
2063 +static int easy98000_addon_remove(struct platform_device *pdev)
2064 +{
2065 +#if defined(CONFIG_PROC_FS)
2066 +       char buf[64];
2067 +       int i;
2068 +
2069 +       for (i = 0; i < sizeof(proc_entries) / sizeof(proc_entries[0]); i++) {
2070 +               sprintf(buf, "cpld/%s", proc_entries[i].name);
2071 +               remove_proc_entry(buf, 0);
2072 +       }
2073 +       remove_proc_entry("cpld", 0);
2074 +#endif
2075 +       return 0;
2076 +}
2077 +
2078 +static struct platform_driver easy98000_addon_driver = {
2079 +       .probe = easy98000_addon_probe,
2080 +       .remove = __devexit_p(easy98000_addon_remove),
2081 +       .driver = {
2082 +               .name = "easy98000_addon",
2083 +               .owner = THIS_MODULE,
2084 +       },
2085 +};
2086 +
2087 +int __init easy98000_addon_init(void)
2088 +{
2089 +       return platform_driver_register(&easy98000_addon_driver);
2090 +}
2091 +
2092 +void __exit easy98000_addon_exit(void)
2093 +{
2094 +       platform_driver_unregister(&easy98000_addon_driver);
2095 +}
2096 +
2097 +module_init(easy98000_addon_init);
2098 +module_exit(easy98000_addon_exit);
2099 --- a/arch/mips/lantiq/prom.c
2100 +++ b/arch/mips/lantiq/prom.c
2101 @@ -45,10 +45,12 @@ static void __init prom_init_cmdline(voi
2102         char **argv = (char **) KSEG1ADDR(fw_arg1);
2103         int i;
2104  
2105 +       arcs_cmdline[0] = '\0';
2106 +
2107         for (i = 0; i < argc; i++) {
2108 -               char *p = (char *)  KSEG1ADDR(argv[i]);
2109 +               char *p = (char *) KSEG1ADDR(argv[i]);
2110  
2111 -               if (p && *p) {
2112 +               if (CPHYSADDR(p) && *p) {
2113                         strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
2114                         strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
2115                 }