brcm47xx: add initial support for devices with bcma bus.
[openwrt.git] / target / linux / brcm47xx / patches-3.0 / 0010-bcm47xx-prepare-to-support-different-buses.patch
1 From c0886db6357de20fba4f7c0602eceefba3ad343b Mon Sep 17 00:00:00 2001
2 From: Hauke Mehrtens <hauke@hauke-m.de>
3 Date: Mon, 6 Jun 2011 00:07:36 +0200
4 Subject: [PATCH 10/14] bcm47xx: prepare to support different buses
5
6 The ssb bus is not hod directly any more. there is now a union which
7 contains all the supported buses, now just ssb. As just one system bus
8 can be used at a time the union does not cause any problems.
9
10 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
11 ---
12 arch/mips/bcm47xx/gpio.c | 56 ++++++++++++++++----------
13 arch/mips/bcm47xx/nvram.c | 15 +++++--
14 arch/mips/bcm47xx/serial.c | 13 +++++-
15 arch/mips/bcm47xx/setup.c | 32 +++++++++++---
16 arch/mips/bcm47xx/time.c | 9 +++-
17 arch/mips/bcm47xx/wgt634u.c | 13 ++++--
18 arch/mips/include/asm/mach-bcm47xx/bcm47xx.h | 14 ++++++-
19 arch/mips/include/asm/mach-bcm47xx/gpio.h | 55 ++++++++++++++++++-------
20 drivers/watchdog/bcm47xx_wdt.c | 12 +++++-
21 9 files changed, 158 insertions(+), 61 deletions(-)
22
23 --- a/arch/mips/bcm47xx/gpio.c
24 +++ b/arch/mips/bcm47xx/gpio.c
25 @@ -20,42 +20,54 @@ static DECLARE_BITMAP(gpio_in_use, BCM47
26
27 int gpio_request(unsigned gpio, const char *tag)
28 {
29 - if (ssb_chipco_available(&ssb_bcm47xx.chipco) &&
30 - ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
31 - return -EINVAL;
32 -
33 - if (ssb_extif_available(&ssb_bcm47xx.extif) &&
34 - ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
35 - return -EINVAL;
36 -
37 - if (test_and_set_bit(gpio, gpio_in_use))
38 - return -EBUSY;
39 -
40 - return 0;
41 + switch (bcm47xx_active_bus_type) {
42 + case BCM47XX_BUS_TYPE_SSB:
43 + if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
44 + ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
45 + return -EINVAL;
46 +
47 + if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
48 + ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
49 + return -EINVAL;
50 +
51 + if (test_and_set_bit(gpio, gpio_in_use))
52 + return -EBUSY;
53 +
54 + return 0;
55 + }
56 + return -EINVAL;
57 }
58 EXPORT_SYMBOL(gpio_request);
59
60 void gpio_free(unsigned gpio)
61 {
62 - if (ssb_chipco_available(&ssb_bcm47xx.chipco) &&
63 - ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
64 - return;
65 + switch (bcm47xx_active_bus_type) {
66 + case BCM47XX_BUS_TYPE_SSB:
67 + if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
68 + ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
69 + return;
70 +
71 + if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
72 + ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
73 + return;
74
75 - if (ssb_extif_available(&ssb_bcm47xx.extif) &&
76 - ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
77 + clear_bit(gpio, gpio_in_use);
78 return;
79 -
80 - clear_bit(gpio, gpio_in_use);
81 + }
82 }
83 EXPORT_SYMBOL(gpio_free);
84
85 int gpio_to_irq(unsigned gpio)
86 {
87 - if (ssb_chipco_available(&ssb_bcm47xx.chipco))
88 - return ssb_mips_irq(ssb_bcm47xx.chipco.dev) + 2;
89 - else if (ssb_extif_available(&ssb_bcm47xx.extif))
90 - return ssb_mips_irq(ssb_bcm47xx.extif.dev) + 2;
91 - else
92 - return -EINVAL;
93 + switch (bcm47xx_active_bus_type) {
94 + case BCM47XX_BUS_TYPE_SSB:
95 + if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco))
96 + return ssb_mips_irq(bcm47xx_bus.ssb.chipco.dev) + 2;
97 + else if (ssb_extif_available(&bcm47xx_bus.ssb.extif))
98 + return ssb_mips_irq(bcm47xx_bus.ssb.extif.dev) + 2;
99 + else
100 + return -EINVAL;
101 + }
102 + return -EINVAL;
103 }
104 EXPORT_SYMBOL_GPL(gpio_to_irq);
105 --- a/arch/mips/bcm47xx/nvram.c
106 +++ b/arch/mips/bcm47xx/nvram.c
107 @@ -26,14 +26,21 @@ static char nvram_buf[NVRAM_SPACE];
108 /* Probe for NVRAM header */
109 static void early_nvram_init(void)
110 {
111 - struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
112 + struct ssb_mipscore *mcore_ssb;
113 struct nvram_header *header;
114 int i;
115 - u32 base, lim, off;
116 + u32 base = 0;
117 + u32 lim = 0;
118 + u32 off;
119 u32 *src, *dst;
120
121 - base = mcore->flash_window;
122 - lim = mcore->flash_window_size;
123 + switch (bcm47xx_active_bus_type) {
124 + case BCM47XX_BUS_TYPE_SSB:
125 + mcore_ssb = &bcm47xx_bus.ssb.mipscore;
126 + base = mcore_ssb->flash_window;
127 + lim = mcore_ssb->flash_window_size;
128 + break;
129 + }
130
131 off = FLASH_MIN;
132 while (off <= lim) {
133 --- a/arch/mips/bcm47xx/serial.c
134 +++ b/arch/mips/bcm47xx/serial.c
135 @@ -23,10 +23,10 @@ static struct platform_device uart8250_d
136 },
137 };
138
139 -static int __init uart8250_init(void)
140 +static int __init uart8250_init_ssb(void)
141 {
142 int i;
143 - struct ssb_mipscore *mcore = &(ssb_bcm47xx.mipscore);
144 + struct ssb_mipscore *mcore = &(bcm47xx_bus.ssb.mipscore);
145
146 memset(&uart8250_data, 0, sizeof(uart8250_data));
147
148 @@ -45,6 +45,15 @@ static int __init uart8250_init(void)
149 return platform_device_register(&uart8250_device);
150 }
151
152 +static int __init uart8250_init(void)
153 +{
154 + switch (bcm47xx_active_bus_type) {
155 + case BCM47XX_BUS_TYPE_SSB:
156 + return uart8250_init_ssb();
157 + }
158 + return -EINVAL;
159 +}
160 +
161 module_init(uart8250_init);
162
163 MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>");
164 --- a/arch/mips/bcm47xx/setup.c
165 +++ b/arch/mips/bcm47xx/setup.c
166 @@ -35,15 +35,22 @@
167 #include <bcm47xx.h>
168 #include <asm/mach-bcm47xx/nvram.h>
169
170 -struct ssb_bus ssb_bcm47xx;
171 -EXPORT_SYMBOL(ssb_bcm47xx);
172 +union bcm47xx_bus bcm47xx_bus;
173 +EXPORT_SYMBOL(bcm47xx_bus);
174 +
175 +enum bcm47xx_bus_type bcm47xx_active_bus_type;
176 +EXPORT_SYMBOL(bcm47xx_active_bus_type);
177
178 static void bcm47xx_machine_restart(char *command)
179 {
180 printk(KERN_ALERT "Please stand by while rebooting the system...\n");
181 local_irq_disable();
182 /* Set the watchdog timer to reset immediately */
183 - ssb_watchdog_timer_set(&ssb_bcm47xx, 1);
184 + switch (bcm47xx_active_bus_type) {
185 + case BCM47XX_BUS_TYPE_SSB:
186 + ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1);
187 + break;
188 + }
189 while (1)
190 cpu_relax();
191 }
192 @@ -52,7 +59,11 @@ static void bcm47xx_machine_halt(void)
193 {
194 /* Disable interrupts and watchdog and spin forever */
195 local_irq_disable();
196 - ssb_watchdog_timer_set(&ssb_bcm47xx, 0);
197 + switch (bcm47xx_active_bus_type) {
198 + case BCM47XX_BUS_TYPE_SSB:
199 + ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
200 + break;
201 + }
202 while (1)
203 cpu_relax();
204 }
205 @@ -247,7 +258,7 @@ static int bcm47xx_get_invariants(struct
206 return 0;
207 }
208
209 -void __init plat_mem_setup(void)
210 +static void __init bcm47xx_register_ssb(void)
211 {
212 int err;
213 char buf[100];
214 @@ -258,12 +269,12 @@ void __init plat_mem_setup(void)
215 printk(KERN_WARNING "bcm47xx: someone else already registered"
216 " a ssb SPROM callback handler (err %d)\n", err);
217
218 - err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE,
219 + err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE,
220 bcm47xx_get_invariants);
221 if (err)
222 panic("Failed to initialize SSB bus (err %d)\n", err);
223
224 - mcore = &ssb_bcm47xx.mipscore;
225 + mcore = &bcm47xx_bus.ssb.mipscore;
226 if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
227 if (strstr(buf, "console=ttyS1")) {
228 struct ssb_serial_port port;
229 @@ -276,6 +287,14 @@ void __init plat_mem_setup(void)
230 memcpy(&mcore->serial_ports[1], &port, sizeof(port));
231 }
232 }
233 +}
234 +
235 +void __init plat_mem_setup(void)
236 +{
237 + struct cpuinfo_mips *c = &current_cpu_data;
238 +
239 + bcm47xx_active_bus_type = BCM47XX_BUS_TYPE_SSB;
240 + bcm47xx_register_ssb();
241
242 _machine_restart = bcm47xx_machine_restart;
243 _machine_halt = bcm47xx_machine_halt;
244 --- a/arch/mips/bcm47xx/time.c
245 +++ b/arch/mips/bcm47xx/time.c
246 @@ -30,7 +30,7 @@
247
248 void __init plat_time_init(void)
249 {
250 - unsigned long hz;
251 + unsigned long hz = 0;
252
253 /*
254 * Use deterministic values for initial counter interrupt
255 @@ -39,7 +39,12 @@ void __init plat_time_init(void)
256 write_c0_count(0);
257 write_c0_compare(0xffff);
258
259 - hz = ssb_cpu_clock(&ssb_bcm47xx.mipscore) / 2;
260 + switch (bcm47xx_active_bus_type) {
261 + case BCM47XX_BUS_TYPE_SSB:
262 + hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2;
263 + break;
264 + }
265 +
266 if (!hz)
267 hz = 100000000;
268
269 --- a/arch/mips/bcm47xx/wgt634u.c
270 +++ b/arch/mips/bcm47xx/wgt634u.c
271 @@ -108,7 +108,7 @@ static irqreturn_t gpio_interrupt(int ir
272
273 /* Interrupts are shared, check if the current one is
274 a GPIO interrupt. */
275 - if (!ssb_chipco_irq_status(&ssb_bcm47xx.chipco,
276 + if (!ssb_chipco_irq_status(&bcm47xx_bus.ssb.chipco,
277 SSB_CHIPCO_IRQ_GPIO))
278 return IRQ_NONE;
279
280 @@ -133,21 +133,24 @@ static int __init wgt634u_init(void)
281 * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
282 */
283
284 - u8 *et0mac = ssb_bcm47xx.sprom.et0mac;
285 + if (bcm47xx_active_bus_type != BCM47XX_BUS_TYPE_SSB)
286 + return -ENODEV;
287 +
288 + u8 *et0mac = bcm47xx_bus.ssb.sprom.et0mac;
289
290 if (et0mac[0] == 0x00 &&
291 ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) ||
292 (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) {
293 - struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
294 + struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore;
295
296 printk(KERN_INFO "WGT634U machine detected.\n");
297
298 if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET),
299 gpio_interrupt, IRQF_SHARED,
300 - "WGT634U GPIO", &ssb_bcm47xx.chipco)) {
301 + "WGT634U GPIO", &bcm47xx_bus.ssb.chipco)) {
302 gpio_direction_input(WGT634U_GPIO_RESET);
303 gpio_intmask(WGT634U_GPIO_RESET, 1);
304 - ssb_chipco_irq_mask(&ssb_bcm47xx.chipco,
305 + ssb_chipco_irq_mask(&bcm47xx_bus.ssb.chipco,
306 SSB_CHIPCO_IRQ_GPIO,
307 SSB_CHIPCO_IRQ_GPIO);
308 }
309 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
310 +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
311 @@ -19,7 +19,17 @@
312 #ifndef __ASM_BCM47XX_H
313 #define __ASM_BCM47XX_H
314
315 -/* SSB bus */
316 -extern struct ssb_bus ssb_bcm47xx;
317 +#include <linux/ssb/ssb.h>
318 +
319 +enum bcm47xx_bus_type {
320 + BCM47XX_BUS_TYPE_SSB,
321 +};
322 +
323 +union bcm47xx_bus {
324 + struct ssb_bus ssb;
325 +};
326 +
327 +extern union bcm47xx_bus bcm47xx_bus;
328 +extern enum bcm47xx_bus_type bcm47xx_active_bus_type;
329
330 #endif /* __ASM_BCM47XX_H */
331 --- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
332 +++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
333 @@ -21,41 +21,66 @@ extern int gpio_to_irq(unsigned gpio);
334
335 static inline int gpio_get_value(unsigned gpio)
336 {
337 - return ssb_gpio_in(&ssb_bcm47xx, 1 << gpio);
338 + switch (bcm47xx_active_bus_type) {
339 + case BCM47XX_BUS_TYPE_SSB:
340 + return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio);
341 + }
342 + return -EINVAL;
343 }
344
345 static inline void gpio_set_value(unsigned gpio, int value)
346 {
347 - ssb_gpio_out(&ssb_bcm47xx, 1 << gpio, value ? 1 << gpio : 0);
348 + switch (bcm47xx_active_bus_type) {
349 + case BCM47XX_BUS_TYPE_SSB:
350 + ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
351 + value ? 1 << gpio : 0);
352 + }
353 }
354
355 static inline int gpio_direction_input(unsigned gpio)
356 {
357 - ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0);
358 - return 0;
359 + switch (bcm47xx_active_bus_type) {
360 + case BCM47XX_BUS_TYPE_SSB:
361 + ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0);
362 + return 0;
363 + }
364 + return -EINVAL;
365 }
366
367 static inline int gpio_direction_output(unsigned gpio, int value)
368 {
369 - /* first set the gpio out value */
370 - ssb_gpio_out(&ssb_bcm47xx, 1 << gpio, value ? 1 << gpio : 0);
371 - /* then set the gpio mode */
372 - ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio);
373 - return 0;
374 + switch (bcm47xx_active_bus_type) {
375 + case BCM47XX_BUS_TYPE_SSB:
376 + /* first set the gpio out value */
377 + ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
378 + value ? 1 << gpio : 0);
379 + /* then set the gpio mode */
380 + ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio);
381 + return 0;
382 + }
383 + return -EINVAL;
384 }
385
386 static inline int gpio_intmask(unsigned gpio, int value)
387 {
388 - ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio,
389 - value ? 1 << gpio : 0);
390 - return 0;
391 + switch (bcm47xx_active_bus_type) {
392 + case BCM47XX_BUS_TYPE_SSB:
393 + ssb_gpio_intmask(&bcm47xx_bus.ssb, 1 << gpio,
394 + value ? 1 << gpio : 0);
395 + return 0;
396 + }
397 + return -EINVAL;
398 }
399
400 static inline int gpio_polarity(unsigned gpio, int value)
401 {
402 - ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio,
403 - value ? 1 << gpio : 0);
404 - return 0;
405 + switch (bcm47xx_active_bus_type) {
406 + case BCM47XX_BUS_TYPE_SSB:
407 + ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << gpio,
408 + value ? 1 << gpio : 0);
409 + return 0;
410 + }
411 + return -EINVAL;
412 }
413
414
415 --- a/drivers/watchdog/bcm47xx_wdt.c
416 +++ b/drivers/watchdog/bcm47xx_wdt.c
417 @@ -54,12 +54,20 @@ static atomic_t ticks;
418 static inline void bcm47xx_wdt_hw_start(void)
419 {
420 /* this is 2,5s on 100Mhz clock and 2s on 133 Mhz */
421 - ssb_watchdog_timer_set(&ssb_bcm47xx, 0xfffffff);
422 + switch (bcm47xx_active_bus_type) {
423 + case BCM47XX_BUS_TYPE_SSB:
424 + ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0xfffffff);
425 + break;
426 + }
427 }
428
429 static inline int bcm47xx_wdt_hw_stop(void)
430 {
431 - return ssb_watchdog_timer_set(&ssb_bcm47xx, 0);
432 + switch (bcm47xx_active_bus_type) {
433 + case BCM47XX_BUS_TYPE_SSB:
434 + return ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
435 + }
436 + return -EINVAL;
437 }
438
439 static void bcm47xx_timer_tick(unsigned long unused)
This page took 0.06609 seconds and 5 git commands to generate.