ixp4xx: add support for linux 3.3.1
[openwrt.git] / target / linux / brcm47xx / patches-3.0 / 0010-bcm47xx-add-support-for-bcma-bus.patch
1 From d3fb63a710e1f04fed2c2703c6dce3531490c451 Mon Sep 17 00:00:00 2001
2 From: Hauke Mehrtens <hauke@hauke-m.de>
3 Date: Mon, 6 Jun 2011 00:07:37 +0200
4 Subject: [PATCH 10/26] bcm47xx: add support for bcma bus
5
6 This patch add support for the bcma bus. Broadcom uses only Mips 74K
7 CPUs on the new SoC and on the old ons using ssb bus there are no Mips
8 74K CPUs.
9
10 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
11 ---
12  arch/mips/bcm47xx/Kconfig                    |   13 ++++++
13  arch/mips/bcm47xx/gpio.c                     |   22 +++++++++++
14  arch/mips/bcm47xx/nvram.c                    |   10 +++++
15  arch/mips/bcm47xx/serial.c                   |   29 ++++++++++++++
16  arch/mips/bcm47xx/setup.c                    |   53 +++++++++++++++++++++++++-
17  arch/mips/bcm47xx/time.c                     |    5 ++
18  arch/mips/include/asm/mach-bcm47xx/bcm47xx.h |    8 ++++
19  arch/mips/include/asm/mach-bcm47xx/gpio.h    |   41 ++++++++++++++++++++
20  drivers/watchdog/bcm47xx_wdt.c               |   11 +++++
21  9 files changed, 190 insertions(+), 2 deletions(-)
22
23 --- a/arch/mips/bcm47xx/Kconfig
24 +++ b/arch/mips/bcm47xx/Kconfig
25 @@ -15,4 +15,17 @@ config BCM47XX_SSB
26  
27          This will generate an image with support for SSB and MIPS32 R1 instruction set.
28  
29 +config BCM47XX_BCMA
30 +       bool "BCMA Support for Broadcom BCM47XX"
31 +       select SYS_HAS_CPU_MIPS32_R2
32 +       select BCMA
33 +       select BCMA_HOST_SOC
34 +       select BCMA_DRIVER_MIPS
35 +       select BCMA_DRIVER_PCI_HOSTMODE if PCI
36 +       default y
37 +       help
38 +        Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
39 +
40 +        This will generate an image with support for BCMA and MIPS32 R2 instruction set.
41 +
42  endif
43 --- a/arch/mips/bcm47xx/gpio.c
44 +++ b/arch/mips/bcm47xx/gpio.c
45 @@ -36,6 +36,16 @@ int gpio_request(unsigned gpio, const ch
46  
47                 return 0;
48  #endif
49 +#ifdef CONFIG_BCM47XX_BCMA
50 +       case BCM47XX_BUS_TYPE_BCMA:
51 +               if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
52 +                       return -EINVAL;
53 +
54 +               if (test_and_set_bit(gpio, gpio_in_use))
55 +                       return -EBUSY;
56 +
57 +               return 0;
58 +#endif
59         }
60         return -EINVAL;
61  }
62 @@ -57,6 +67,14 @@ void gpio_free(unsigned gpio)
63                 clear_bit(gpio, gpio_in_use);
64                 return;
65  #endif
66 +#ifdef CONFIG_BCM47XX_BCMA
67 +       case BCM47XX_BUS_TYPE_BCMA:
68 +               if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
69 +                       return;
70 +
71 +               clear_bit(gpio, gpio_in_use);
72 +               return;
73 +#endif
74         }
75  }
76  EXPORT_SYMBOL(gpio_free);
77 @@ -73,6 +91,10 @@ int gpio_to_irq(unsigned gpio)
78                 else
79                         return -EINVAL;
80  #endif
81 +#ifdef CONFIG_BCM47XX_BCMA
82 +       case BCM47XX_BUS_TYPE_BCMA:
83 +               return bcma_core_mips_irq(bcm47xx_bus.bcma.bus.drv_cc.core) + 2;
84 +#endif
85         }
86         return -EINVAL;
87  }
88 --- a/arch/mips/bcm47xx/nvram.c
89 +++ b/arch/mips/bcm47xx/nvram.c
90 @@ -29,6 +29,9 @@ static void early_nvram_init(void)
91  #ifdef CONFIG_BCM47XX_SSB
92         struct ssb_mipscore *mcore_ssb;
93  #endif
94 +#ifdef CONFIG_BCM47XX_BCMA
95 +       struct bcma_drv_cc *bcma_cc;
96 +#endif
97         struct nvram_header *header;
98         int i;
99         u32 base = 0;
100 @@ -44,6 +47,13 @@ static void early_nvram_init(void)
101                 lim = mcore_ssb->flash_window_size;
102                 break;
103  #endif
104 +#ifdef CONFIG_BCM47XX_BCMA
105 +       case BCM47XX_BUS_TYPE_BCMA:
106 +               bcma_cc = &bcm47xx_bus.bcma.bus.drv_cc;
107 +               base = bcma_cc->pflash.window;
108 +               lim = bcma_cc->pflash.window_size;
109 +               break;
110 +#endif
111         }
112  
113         off = FLASH_MIN;
114 --- a/arch/mips/bcm47xx/serial.c
115 +++ b/arch/mips/bcm47xx/serial.c
116 @@ -47,6 +47,31 @@ static int __init uart8250_init_ssb(void
117  }
118  #endif
119  
120 +#ifdef CONFIG_BCM47XX_BCMA
121 +static int __init uart8250_init_bcma(void)
122 +{
123 +       int i;
124 +       struct bcma_drv_cc *cc = &(bcm47xx_bus.bcma.bus.drv_cc);
125 +
126 +       memset(&uart8250_data, 0,  sizeof(uart8250_data));
127 +
128 +       for (i = 0; i < cc->nr_serial_ports; i++) {
129 +               struct plat_serial8250_port *p = &(uart8250_data[i]);
130 +               struct bcma_serial_port *bcma_port;
131 +               bcma_port = &(cc->serial_ports[i]);
132 +
133 +               p->mapbase = (unsigned int) bcma_port->regs;
134 +               p->membase = (void *) bcma_port->regs;
135 +               p->irq = bcma_port->irq + 2;
136 +               p->uartclk = bcma_port->baud_base;
137 +               p->regshift = bcma_port->reg_shift;
138 +               p->iotype = UPIO_MEM;
139 +               p->flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
140 +       }
141 +       return platform_device_register(&uart8250_device);
142 +}
143 +#endif
144 +
145  static int __init uart8250_init(void)
146  {
147         switch (bcm47xx_bus_type) {
148 @@ -54,6 +79,10 @@ static int __init uart8250_init(void)
149         case BCM47XX_BUS_TYPE_SSB:
150                 return uart8250_init_ssb();
151  #endif
152 +#ifdef CONFIG_BCM47XX_BCMA
153 +       case BCM47XX_BUS_TYPE_BCMA:
154 +               return uart8250_init_bcma();
155 +#endif
156         }
157         return -EINVAL;
158  }
159 --- a/arch/mips/bcm47xx/setup.c
160 +++ b/arch/mips/bcm47xx/setup.c
161 @@ -29,6 +29,7 @@
162  #include <linux/types.h>
163  #include <linux/ssb/ssb.h>
164  #include <linux/ssb/ssb_embedded.h>
165 +#include <linux/bcma/bcma_soc.h>
166  #include <asm/bootinfo.h>
167  #include <asm/reboot.h>
168  #include <asm/time.h>
169 @@ -52,6 +53,11 @@ static void bcm47xx_machine_restart(char
170                 ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1);
171                 break;
172  #endif
173 +#ifdef CONFIG_BCM47XX_BCMA
174 +       case BCM47XX_BUS_TYPE_BCMA:
175 +               bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 1);
176 +               break;
177 +#endif
178         }
179         while (1)
180                 cpu_relax();
181 @@ -67,6 +73,11 @@ static void bcm47xx_machine_halt(void)
182                 ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
183                 break;
184  #endif
185 +#ifdef CONFIG_BCM47XX_BCMA
186 +       case BCM47XX_BUS_TYPE_BCMA:
187 +               bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0);
188 +               break;
189 +#endif
190         }
191         while (1)
192                 cpu_relax();
193 @@ -295,16 +306,54 @@ static void __init bcm47xx_register_ssb(
194  }
195  #endif
196  
197 +#ifdef CONFIG_BCM47XX_BCMA
198 +static void __init bcm47xx_register_bcma(void)
199 +{
200 +       int err;
201 +
202 +       err = bcma_host_soc_register(&bcm47xx_bus.bcma);
203 +       if (err)
204 +               panic("Failed to initialize BCMA bus (err %d)\n", err);
205 +}
206 +#endif
207 +
208  void __init plat_mem_setup(void)
209  {
210         struct cpuinfo_mips *c = &current_cpu_data;
211  
212 +       if (c->cputype == CPU_74K) {
213 +               printk(KERN_INFO "bcm47xx: using bcma bus\n");
214 +#ifdef CONFIG_BCM47XX_BCMA
215 +               bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
216 +               bcm47xx_register_bcma();
217 +#endif
218 +       } else {
219 +               printk(KERN_INFO "bcm47xx: using ssb bus\n");
220  #ifdef CONFIG_BCM47XX_SSB
221 -       bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
222 -       bcm47xx_register_ssb();
223 +               bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
224 +               bcm47xx_register_ssb();
225  #endif
226 +       }
227  
228         _machine_restart = bcm47xx_machine_restart;
229         _machine_halt = bcm47xx_machine_halt;
230         pm_power_off = bcm47xx_machine_halt;
231  }
232 +
233 +static int __init bcm47xx_register_bus_complete(void)
234 +{
235 +       switch (bcm47xx_bus_type) {
236 +#ifdef CONFIG_BCM47XX_SSB
237 +       case BCM47XX_BUS_TYPE_SSB:
238 +               /* Nothing to do */
239 +               break;
240 +#endif
241 +#ifdef CONFIG_BCM47XX_BCMA
242 +       case BCM47XX_BUS_TYPE_BCMA:
243 +               bcma_bus_register(&bcm47xx_bus.bcma.bus);
244 +               break;
245 +#endif
246 +       }
247 +       return 0;
248 +}
249 +device_initcall(bcm47xx_register_bus_complete);
250 --- a/arch/mips/bcm47xx/time.c
251 +++ b/arch/mips/bcm47xx/time.c
252 @@ -45,6 +45,11 @@ void __init plat_time_init(void)
253                 hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2;
254                 break;
255  #endif
256 +#ifdef CONFIG_BCM47XX_BCMA
257 +       case BCM47XX_BUS_TYPE_BCMA:
258 +               hz = bcma_cpu_clock(&bcm47xx_bus.bcma.bus.drv_mips) / 2;
259 +               break;
260 +#endif
261         }
262  
263         if (!hz)
264 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
265 +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
266 @@ -20,17 +20,25 @@
267  #define __ASM_BCM47XX_H
268  
269  #include <linux/ssb/ssb.h>
270 +#include <linux/bcma/bcma.h>
271 +#include <linux/bcma/bcma_soc.h>
272  
273  enum bcm47xx_bus_type {
274  #ifdef CONFIG_BCM47XX_SSB
275         BCM47XX_BUS_TYPE_SSB,
276  #endif
277 +#ifdef CONFIG_BCM47XX_BCMA
278 +       BCM47XX_BUS_TYPE_BCMA,
279 +#endif
280  };
281  
282  union bcm47xx_bus {
283  #ifdef CONFIG_BCM47XX_SSB
284         struct ssb_bus ssb;
285  #endif
286 +#ifdef CONFIG_BCM47XX_BCMA
287 +       struct bcma_soc bcma;
288 +#endif
289  };
290  
291  extern union bcm47xx_bus bcm47xx_bus;
292 --- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
293 +++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
294 @@ -10,6 +10,7 @@
295  #define __BCM47XX_GPIO_H
296  
297  #include <linux/ssb/ssb_embedded.h>
298 +#include <linux/bcma/bcma.h>
299  #include <asm/mach-bcm47xx/bcm47xx.h>
300  
301  #define BCM47XX_EXTIF_GPIO_LINES       5
302 @@ -26,6 +27,11 @@ static inline int gpio_get_value(unsigne
303         case BCM47XX_BUS_TYPE_SSB:
304                 return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio);
305  #endif
306 +#ifdef CONFIG_BCM47XX_BCMA
307 +       case BCM47XX_BUS_TYPE_BCMA:
308 +               return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc,
309 +                                          1 << gpio);
310 +#endif
311         }
312         return -EINVAL;
313  }
314 @@ -37,6 +43,13 @@ static inline void gpio_set_value(unsign
315         case BCM47XX_BUS_TYPE_SSB:
316                 ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
317                              value ? 1 << gpio : 0);
318 +               return;
319 +#endif
320 +#ifdef CONFIG_BCM47XX_BCMA
321 +       case BCM47XX_BUS_TYPE_BCMA:
322 +               bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
323 +                                    value ? 1 << gpio : 0);
324 +               return;
325  #endif
326         }
327  }
328 @@ -49,6 +62,12 @@ static inline int gpio_direction_input(u
329                 ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0);
330                 return 0;
331  #endif
332 +#ifdef CONFIG_BCM47XX_BCMA
333 +       case BCM47XX_BUS_TYPE_BCMA:
334 +               bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
335 +                                      0);
336 +               return 0;
337 +#endif
338         }
339         return -EINVAL;
340  }
341 @@ -65,6 +84,16 @@ static inline int gpio_direction_output(
342                 ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio);
343                 return 0;
344  #endif
345 +#ifdef CONFIG_BCM47XX_BCMA
346 +       case BCM47XX_BUS_TYPE_BCMA:
347 +               /* first set the gpio out value */
348 +               bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
349 +                                    value ? 1 << gpio : 0);
350 +               /* then set the gpio mode */
351 +               bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
352 +                                      1 << gpio);
353 +               return 0;
354 +#endif
355         }
356         return -EINVAL;
357  }
358 @@ -78,6 +107,12 @@ static inline int gpio_intmask(unsigned
359                                  value ? 1 << gpio : 0);
360                 return 0;
361  #endif
362 +#ifdef CONFIG_BCM47XX_BCMA
363 +       case BCM47XX_BUS_TYPE_BCMA:
364 +               bcma_chipco_gpio_intmask(&bcm47xx_bus.bcma.bus.drv_cc,
365 +                                        1 << gpio, value ? 1 << gpio : 0);
366 +               return 0;
367 +#endif
368         }
369         return -EINVAL;
370  }
371 @@ -91,6 +126,12 @@ static inline int gpio_polarity(unsigned
372                                   value ? 1 << gpio : 0);
373                 return 0;
374  #endif
375 +#ifdef CONFIG_BCM47XX_BCMA
376 +       case BCM47XX_BUS_TYPE_BCMA:
377 +               bcma_chipco_gpio_polarity(&bcm47xx_bus.bcma.bus.drv_cc,
378 +                                         1 << gpio, value ? 1 << gpio : 0);
379 +               return 0;
380 +#endif
381         }
382         return -EINVAL;
383  }
384 --- a/drivers/watchdog/bcm47xx_wdt.c
385 +++ b/drivers/watchdog/bcm47xx_wdt.c
386 @@ -60,6 +60,12 @@ static inline void bcm47xx_wdt_hw_start(
387                 ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0xfffffff);
388                 break;
389  #endif
390 +#ifdef CONFIG_BCM47XX_BCMA
391 +       case BCM47XX_BUS_TYPE_BCMA:
392 +               bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc,
393 +                                              0xfffffff);
394 +               break;
395 +#endif
396         }
397  }
398  
399 @@ -70,6 +76,11 @@ static inline int bcm47xx_wdt_hw_stop(vo
400         case BCM47XX_BUS_TYPE_SSB:
401                 return ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
402  #endif
403 +#ifdef CONFIG_BCM47XX_BCMA
404 +       case BCM47XX_BUS_TYPE_BCMA:
405 +               bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0);
406 +               return 0;
407 +#endif
408         }
409         return -EINVAL;
410  }