aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--drivers/watchdog/bcm47xx_wdt.c12
9 files changed, 160 insertions, 61 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
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index bd44417c84d4..c43406c48613 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -54,12 +54,20 @@ static atomic_t ticks;
54static inline void bcm47xx_wdt_hw_start(void) 54static inline void bcm47xx_wdt_hw_start(void)
55{ 55{
56 /* this is 2,5s on 100Mhz clock and 2s on 133 Mhz */ 56 /* this is 2,5s on 100Mhz clock and 2s on 133 Mhz */
57 ssb_watchdog_timer_set(&ssb_bcm47xx, 0xfffffff); 57 switch (bcm47xx_bus_type) {
58 case BCM47XX_BUS_TYPE_SSB:
59 ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0xfffffff);
60 break;
61 }
58} 62}
59 63
60static inline int bcm47xx_wdt_hw_stop(void) 64static inline int bcm47xx_wdt_hw_stop(void)
61{ 65{
62 return ssb_watchdog_timer_set(&ssb_bcm47xx, 0); 66 switch (bcm47xx_bus_type) {
67 case BCM47XX_BUS_TYPE_SSB:
68 return ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
69 }
70 return -EINVAL;
63} 71}
64 72
65static void bcm47xx_timer_tick(unsigned long unused) 73static void bcm47xx_timer_tick(unsigned long unused)