aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorHauke Mehrtens <hauke@hauke-m.de>2011-07-22 19:20:12 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-08-08 14:29:30 -0400
commit08ccf57283f89adbc2ff897ad82d6ad4560db7cd (patch)
tree11d715ac33eab75e57a8e62b0b7d822e316a9145 /arch
parent908debc8da0d5a91418f71c6a462f62bd2ac69ef (diff)
bcm47xx: prepare to support different buses
Prepare bcm47xx to support different System buses. Before adding support for bcma it should be possible to build bcm47xx without the need of ssb. With this patch bcm47xx does not directly contain a ssb_bus, but a union contain all the supported system buses. As a SoC just uses one system bus a union is a good choice. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> Acked-by: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/bcm47xx/gpio.c56
-rw-r--r--arch/mips/bcm47xx/nvram.c15
-rw-r--r--arch/mips/bcm47xx/serial.c13
-rw-r--r--arch/mips/bcm47xx/setup.c33
-rw-r--r--arch/mips/bcm47xx/time.c9
-rw-r--r--arch/mips/bcm47xx/wgt634u.c14
-rw-r--r--arch/mips/include/asm/mach-bcm47xx/bcm47xx.h14
-rw-r--r--arch/mips/include/asm/mach-bcm47xx/gpio.h55
8 files changed, 150 insertions, 59 deletions
diff --git a/arch/mips/bcm47xx/gpio.c b/arch/mips/bcm47xx/gpio.c
index e4a5ee9c9721..99e1c50caf6b 100644
--- a/arch/mips/bcm47xx/gpio.c
+++ b/arch/mips/bcm47xx/gpio.c
@@ -20,42 +20,54 @@ static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES);
20 20
21int gpio_request(unsigned gpio, const char *tag) 21int gpio_request(unsigned gpio, const char *tag)
22{ 22{
23 if (ssb_chipco_available(&ssb_bcm47xx.chipco) && 23 switch (bcm47xx_bus_type) {
24 ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES)) 24 case BCM47XX_BUS_TYPE_SSB:
25 return -EINVAL; 25 if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
26 ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
27 return -EINVAL;
26 28
27 if (ssb_extif_available(&ssb_bcm47xx.extif) && 29 if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
28 ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES)) 30 ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
29 return -EINVAL; 31 return -EINVAL;
30 32
31 if (test_and_set_bit(gpio, gpio_in_use)) 33 if (test_and_set_bit(gpio, gpio_in_use))
32 return -EBUSY; 34 return -EBUSY;
33 35
34 return 0; 36 return 0;
37 }
38 return -EINVAL;
35} 39}
36EXPORT_SYMBOL(gpio_request); 40EXPORT_SYMBOL(gpio_request);
37 41
38void gpio_free(unsigned gpio) 42void gpio_free(unsigned gpio)
39{ 43{
40 if (ssb_chipco_available(&ssb_bcm47xx.chipco) && 44 switch (bcm47xx_bus_type) {
41 ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES)) 45 case BCM47XX_BUS_TYPE_SSB:
42 return; 46 if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
47 ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
48 return;
43 49
44 if (ssb_extif_available(&ssb_bcm47xx.extif) && 50 if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
45 ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES)) 51 ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
46 return; 52 return;
47 53
48 clear_bit(gpio, gpio_in_use); 54 clear_bit(gpio, gpio_in_use);
55 return;
56 }
49} 57}
50EXPORT_SYMBOL(gpio_free); 58EXPORT_SYMBOL(gpio_free);
51 59
52int gpio_to_irq(unsigned gpio) 60int gpio_to_irq(unsigned gpio)
53{ 61{
54 if (ssb_chipco_available(&ssb_bcm47xx.chipco)) 62 switch (bcm47xx_bus_type) {
55 return ssb_mips_irq(ssb_bcm47xx.chipco.dev) + 2; 63 case BCM47XX_BUS_TYPE_SSB:
56 else if (ssb_extif_available(&ssb_bcm47xx.extif)) 64 if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco))
57 return ssb_mips_irq(ssb_bcm47xx.extif.dev) + 2; 65 return ssb_mips_irq(bcm47xx_bus.ssb.chipco.dev) + 2;
58 else 66 else if (ssb_extif_available(&bcm47xx_bus.ssb.extif))
59 return -EINVAL; 67 return ssb_mips_irq(bcm47xx_bus.ssb.extif.dev) + 2;
68 else
69 return -EINVAL;
70 }
71 return -EINVAL;
60} 72}
61EXPORT_SYMBOL_GPL(gpio_to_irq); 73EXPORT_SYMBOL_GPL(gpio_to_irq);
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c
index 54db815bc86c..bcac2ffd1248 100644
--- a/arch/mips/bcm47xx/nvram.c
+++ b/arch/mips/bcm47xx/nvram.c
@@ -26,14 +26,21 @@ static char nvram_buf[NVRAM_SPACE];
26/* Probe for NVRAM header */ 26/* Probe for NVRAM header */
27static void early_nvram_init(void) 27static void early_nvram_init(void)
28{ 28{
29 struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore; 29 struct ssb_mipscore *mcore_ssb;
30 struct nvram_header *header; 30 struct nvram_header *header;
31 int i; 31 int i;
32 u32 base, lim, off; 32 u32 base = 0;
33 u32 lim = 0;
34 u32 off;
33 u32 *src, *dst; 35 u32 *src, *dst;
34 36
35 base = mcore->flash_window; 37 switch (bcm47xx_bus_type) {
36 lim = mcore->flash_window_size; 38 case BCM47XX_BUS_TYPE_SSB:
39 mcore_ssb = &bcm47xx_bus.ssb.mipscore;
40 base = mcore_ssb->flash_window;
41 lim = mcore_ssb->flash_window_size;
42 break;
43 }
37 44
38 off = FLASH_MIN; 45 off = FLASH_MIN;
39 while (off <= lim) { 46 while (off <= lim) {
diff --git a/arch/mips/bcm47xx/serial.c b/arch/mips/bcm47xx/serial.c
index 59c11afdb2ab..17c67e24b549 100644
--- a/arch/mips/bcm47xx/serial.c
+++ b/arch/mips/bcm47xx/serial.c
@@ -23,10 +23,10 @@ static struct platform_device uart8250_device = {
23 }, 23 },
24}; 24};
25 25
26static int __init uart8250_init(void) 26static int __init uart8250_init_ssb(void)
27{ 27{
28 int i; 28 int i;
29 struct ssb_mipscore *mcore = &(ssb_bcm47xx.mipscore); 29 struct ssb_mipscore *mcore = &(bcm47xx_bus.ssb.mipscore);
30 30
31 memset(&uart8250_data, 0, sizeof(uart8250_data)); 31 memset(&uart8250_data, 0, sizeof(uart8250_data));
32 32
@@ -45,6 +45,15 @@ static int __init uart8250_init(void)
45 return platform_device_register(&uart8250_device); 45 return platform_device_register(&uart8250_device);
46} 46}
47 47
48static int __init uart8250_init(void)
49{
50 switch (bcm47xx_bus_type) {
51 case BCM47XX_BUS_TYPE_SSB:
52 return uart8250_init_ssb();
53 }
54 return -EINVAL;
55}
56
48module_init(uart8250_init); 57module_init(uart8250_init);
49 58
50MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>"); 59MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>");
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index cfae81571ded..271cedb339ae 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -35,15 +35,22 @@
35#include <bcm47xx.h> 35#include <bcm47xx.h>
36#include <asm/mach-bcm47xx/nvram.h> 36#include <asm/mach-bcm47xx/nvram.h>
37 37
38struct ssb_bus ssb_bcm47xx; 38union bcm47xx_bus bcm47xx_bus;
39EXPORT_SYMBOL(ssb_bcm47xx); 39EXPORT_SYMBOL(bcm47xx_bus);
40
41enum bcm47xx_bus_type bcm47xx_bus_type;
42EXPORT_SYMBOL(bcm47xx_bus_type);
40 43
41static void bcm47xx_machine_restart(char *command) 44static void bcm47xx_machine_restart(char *command)
42{ 45{
43 printk(KERN_ALERT "Please stand by while rebooting the system...\n"); 46 printk(KERN_ALERT "Please stand by while rebooting the system...\n");
44 local_irq_disable(); 47 local_irq_disable();
45 /* Set the watchdog timer to reset immediately */ 48 /* Set the watchdog timer to reset immediately */
46 ssb_watchdog_timer_set(&ssb_bcm47xx, 1); 49 switch (bcm47xx_bus_type) {
50 case BCM47XX_BUS_TYPE_SSB:
51 ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1);
52 break;
53 }
47 while (1) 54 while (1)
48 cpu_relax(); 55 cpu_relax();
49} 56}
@@ -52,7 +59,11 @@ static void bcm47xx_machine_halt(void)
52{ 59{
53 /* Disable interrupts and watchdog and spin forever */ 60 /* Disable interrupts and watchdog and spin forever */
54 local_irq_disable(); 61 local_irq_disable();
55 ssb_watchdog_timer_set(&ssb_bcm47xx, 0); 62 switch (bcm47xx_bus_type) {
63 case BCM47XX_BUS_TYPE_SSB:
64 ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
65 break;
66 }
56 while (1) 67 while (1)
57 cpu_relax(); 68 cpu_relax();
58} 69}
@@ -247,7 +258,7 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
247 return 0; 258 return 0;
248} 259}
249 260
250void __init plat_mem_setup(void) 261static void __init bcm47xx_register_ssb(void)
251{ 262{
252 int err; 263 int err;
253 char buf[100]; 264 char buf[100];
@@ -258,12 +269,12 @@ void __init plat_mem_setup(void)
258 printk(KERN_WARNING "bcm47xx: someone else already registered" 269 printk(KERN_WARNING "bcm47xx: someone else already registered"
259 " a ssb SPROM callback handler (err %d)\n", err); 270 " a ssb SPROM callback handler (err %d)\n", err);
260 271
261 err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE, 272 err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE,
262 bcm47xx_get_invariants); 273 bcm47xx_get_invariants);
263 if (err) 274 if (err)
264 panic("Failed to initialize SSB bus (err %d)\n", err); 275 panic("Failed to initialize SSB bus (err %d)\n", err);
265 276
266 mcore = &ssb_bcm47xx.mipscore; 277 mcore = &bcm47xx_bus.ssb.mipscore;
267 if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) { 278 if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
268 if (strstr(buf, "console=ttyS1")) { 279 if (strstr(buf, "console=ttyS1")) {
269 struct ssb_serial_port port; 280 struct ssb_serial_port port;
@@ -276,6 +287,14 @@ void __init plat_mem_setup(void)
276 memcpy(&mcore->serial_ports[1], &port, sizeof(port)); 287 memcpy(&mcore->serial_ports[1], &port, sizeof(port));
277 } 288 }
278 } 289 }
290}
291
292void __init plat_mem_setup(void)
293{
294 struct cpuinfo_mips *c = &current_cpu_data;
295
296 bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
297 bcm47xx_register_ssb();
279 298
280 _machine_restart = bcm47xx_machine_restart; 299 _machine_restart = bcm47xx_machine_restart;
281 _machine_halt = bcm47xx_machine_halt; 300 _machine_halt = bcm47xx_machine_halt;
diff --git a/arch/mips/bcm47xx/time.c b/arch/mips/bcm47xx/time.c
index 0c6f47b3fd94..50aea2e1808c 100644
--- a/arch/mips/bcm47xx/time.c
+++ b/arch/mips/bcm47xx/time.c
@@ -30,7 +30,7 @@
30 30
31void __init plat_time_init(void) 31void __init plat_time_init(void)
32{ 32{
33 unsigned long hz; 33 unsigned long hz = 0;
34 34
35 /* 35 /*
36 * Use deterministic values for initial counter interrupt 36 * Use deterministic values for initial counter interrupt
@@ -39,7 +39,12 @@ void __init plat_time_init(void)
39 write_c0_count(0); 39 write_c0_count(0);
40 write_c0_compare(0xffff); 40 write_c0_compare(0xffff);
41 41
42 hz = ssb_cpu_clock(&ssb_bcm47xx.mipscore) / 2; 42 switch (bcm47xx_bus_type) {
43 case BCM47XX_BUS_TYPE_SSB:
44 hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2;
45 break;
46 }
47
43 if (!hz) 48 if (!hz)
44 hz = 100000000; 49 hz = 100000000;
45 50
diff --git a/arch/mips/bcm47xx/wgt634u.c b/arch/mips/bcm47xx/wgt634u.c
index 74d06965326f..e9f9ec8d443b 100644
--- a/arch/mips/bcm47xx/wgt634u.c
+++ b/arch/mips/bcm47xx/wgt634u.c
@@ -108,7 +108,7 @@ static irqreturn_t gpio_interrupt(int irq, void *ignored)
108 108
109 /* Interrupts are shared, check if the current one is 109 /* Interrupts are shared, check if the current one is
110 a GPIO interrupt. */ 110 a GPIO interrupt. */
111 if (!ssb_chipco_irq_status(&ssb_bcm47xx.chipco, 111 if (!ssb_chipco_irq_status(&bcm47xx_bus.ssb.chipco,
112 SSB_CHIPCO_IRQ_GPIO)) 112 SSB_CHIPCO_IRQ_GPIO))
113 return IRQ_NONE; 113 return IRQ_NONE;
114 114
@@ -132,22 +132,26 @@ static int __init wgt634u_init(void)
132 * machine. Use the MAC address as an heuristic. Netgear Inc. has 132 * machine. Use the MAC address as an heuristic. Netgear Inc. has
133 * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx. 133 * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
134 */ 134 */
135 u8 *et0mac;
135 136
136 u8 *et0mac = ssb_bcm47xx.sprom.et0mac; 137 if (bcm47xx_bus_type != BCM47XX_BUS_TYPE_SSB)
138 return -ENODEV;
139
140 et0mac = bcm47xx_bus.ssb.sprom.et0mac;
137 141
138 if (et0mac[0] == 0x00 && 142 if (et0mac[0] == 0x00 &&
139 ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) || 143 ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) ||
140 (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) { 144 (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) {
141 struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore; 145 struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore;
142 146
143 printk(KERN_INFO "WGT634U machine detected.\n"); 147 printk(KERN_INFO "WGT634U machine detected.\n");
144 148
145 if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET), 149 if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET),
146 gpio_interrupt, IRQF_SHARED, 150 gpio_interrupt, IRQF_SHARED,
147 "WGT634U GPIO", &ssb_bcm47xx.chipco)) { 151 "WGT634U GPIO", &bcm47xx_bus.ssb.chipco)) {
148 gpio_direction_input(WGT634U_GPIO_RESET); 152 gpio_direction_input(WGT634U_GPIO_RESET);
149 gpio_intmask(WGT634U_GPIO_RESET, 1); 153 gpio_intmask(WGT634U_GPIO_RESET, 1);
150 ssb_chipco_irq_mask(&ssb_bcm47xx.chipco, 154 ssb_chipco_irq_mask(&bcm47xx_bus.ssb.chipco,
151 SSB_CHIPCO_IRQ_GPIO, 155 SSB_CHIPCO_IRQ_GPIO,
152 SSB_CHIPCO_IRQ_GPIO); 156 SSB_CHIPCO_IRQ_GPIO);
153 } 157 }
diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
index d008f47a28bd..7cf481bb1a05 100644
--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
+++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
@@ -19,7 +19,17 @@
19#ifndef __ASM_BCM47XX_H 19#ifndef __ASM_BCM47XX_H
20#define __ASM_BCM47XX_H 20#define __ASM_BCM47XX_H
21 21
22/* SSB bus */ 22#include <linux/ssb/ssb.h>
23extern struct ssb_bus ssb_bcm47xx; 23
24enum bcm47xx_bus_type {
25 BCM47XX_BUS_TYPE_SSB,
26};
27
28union bcm47xx_bus {
29 struct ssb_bus ssb;
30};
31
32extern union bcm47xx_bus bcm47xx_bus;
33extern enum bcm47xx_bus_type bcm47xx_bus_type;
24 34
25#endif /* __ASM_BCM47XX_H */ 35#endif /* __ASM_BCM47XX_H */
diff --git a/arch/mips/include/asm/mach-bcm47xx/gpio.h b/arch/mips/include/asm/mach-bcm47xx/gpio.h
index 98504142124e..6b78827dd140 100644
--- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
+++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
@@ -21,41 +21,66 @@ extern int gpio_to_irq(unsigned gpio);
21 21
22static inline int gpio_get_value(unsigned gpio) 22static inline int gpio_get_value(unsigned gpio)
23{ 23{
24 return ssb_gpio_in(&ssb_bcm47xx, 1 << gpio); 24 switch (bcm47xx_bus_type) {
25 case BCM47XX_BUS_TYPE_SSB:
26 return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio);
27 }
28 return -EINVAL;
25} 29}
26 30
27static inline void gpio_set_value(unsigned gpio, int value) 31static inline void gpio_set_value(unsigned gpio, int value)
28{ 32{
29 ssb_gpio_out(&ssb_bcm47xx, 1 << gpio, value ? 1 << gpio : 0); 33 switch (bcm47xx_bus_type) {
34 case BCM47XX_BUS_TYPE_SSB:
35 ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
36 value ? 1 << gpio : 0);
37 }
30} 38}
31 39
32static inline int gpio_direction_input(unsigned gpio) 40static inline int gpio_direction_input(unsigned gpio)
33{ 41{
34 ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0); 42 switch (bcm47xx_bus_type) {
35 return 0; 43 case BCM47XX_BUS_TYPE_SSB:
44 ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0);
45 return 0;
46 }
47 return -EINVAL;
36} 48}
37 49
38static inline int gpio_direction_output(unsigned gpio, int value) 50static inline int gpio_direction_output(unsigned gpio, int value)
39{ 51{
40 /* first set the gpio out value */ 52 switch (bcm47xx_bus_type) {
41 ssb_gpio_out(&ssb_bcm47xx, 1 << gpio, value ? 1 << gpio : 0); 53 case BCM47XX_BUS_TYPE_SSB:
42 /* then set the gpio mode */ 54 /* first set the gpio out value */
43 ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio); 55 ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
44 return 0; 56 value ? 1 << gpio : 0);
57 /* then set the gpio mode */
58 ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio);
59 return 0;
60 }
61 return -EINVAL;
45} 62}
46 63
47static inline int gpio_intmask(unsigned gpio, int value) 64static inline int gpio_intmask(unsigned gpio, int value)
48{ 65{
49 ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio, 66 switch (bcm47xx_bus_type) {
50 value ? 1 << gpio : 0); 67 case BCM47XX_BUS_TYPE_SSB:
51 return 0; 68 ssb_gpio_intmask(&bcm47xx_bus.ssb, 1 << gpio,
69 value ? 1 << gpio : 0);
70 return 0;
71 }
72 return -EINVAL;
52} 73}
53 74
54static inline int gpio_polarity(unsigned gpio, int value) 75static inline int gpio_polarity(unsigned gpio, int value)
55{ 76{
56 ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio, 77 switch (bcm47xx_bus_type) {
57 value ? 1 << gpio : 0); 78 case BCM47XX_BUS_TYPE_SSB:
58 return 0; 79 ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << gpio,
80 value ? 1 << gpio : 0);
81 return 0;
82 }
83 return -EINVAL;
59} 84}
60 85
61 86