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