Root/target/linux/brcm47xx/patches-3.0/0008-bcm47xx-prepare-to-support-different-buses.patch

1From 18fe82b600f9563e59e28746211a2ce3176a81de Mon Sep 17 00:00:00 2001
2From: Hauke Mehrtens <hauke@hauke-m.de>
3Date: Mon, 6 Jun 2011 00:07:36 +0200
4Subject: [PATCH 08/26] bcm47xx: prepare to support different buses
5
6Prepare bcm47xx to support different System buses. Before adding
7support for bcma it should be possible to build bcm47xx without the
8need of ssb. With this patch bcm47xx does not directly contain a
9ssb_bus, but a union contain all the supported system buses. As a SoC
10just uses one system bus a union is a good choice.
11
12Signed-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_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_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_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_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_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_bus_type;
178+EXPORT_SYMBOL(bcm47xx_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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)
444

Archive Download this file



interactive