bcm47xx: prepare to support different buses
authorHauke Mehrtens <hauke@hauke-m.de>
Fri, 22 Jul 2011 23:20:12 +0000 (01:20 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 8 Aug 2011 18:29:30 +0000 (14:29 -0400)
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>
arch/mips/bcm47xx/gpio.c
arch/mips/bcm47xx/nvram.c
arch/mips/bcm47xx/serial.c
arch/mips/bcm47xx/setup.c
arch/mips/bcm47xx/time.c
arch/mips/bcm47xx/wgt634u.c
arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
arch/mips/include/asm/mach-bcm47xx/gpio.h
drivers/watchdog/bcm47xx_wdt.c

index e4a5ee9c97217381e324774d2c4777f7801d85c5..99e1c50caf6b6ae40bc9c81f226775211c20646f 100644 (file)
@@ -20,42 +20,54 @@ static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES);
 
 int gpio_request(unsigned gpio, const char *tag)
 {
-       if (ssb_chipco_available(&ssb_bcm47xx.chipco) &&
-           ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
-               return -EINVAL;
+       switch (bcm47xx_bus_type) {
+       case BCM47XX_BUS_TYPE_SSB:
+               if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
+                   ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
+                       return -EINVAL;
 
-       if (ssb_extif_available(&ssb_bcm47xx.extif) &&
-           ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
-               return -EINVAL;
+               if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
+                   ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
+                       return -EINVAL;
 
-       if (test_and_set_bit(gpio, gpio_in_use))
-               return -EBUSY;
+               if (test_and_set_bit(gpio, gpio_in_use))
+                       return -EBUSY;
 
-       return 0;
+               return 0;
+       }
+       return -EINVAL;
 }
 EXPORT_SYMBOL(gpio_request);
 
 void gpio_free(unsigned gpio)
 {
-       if (ssb_chipco_available(&ssb_bcm47xx.chipco) &&
-           ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
-               return;
+       switch (bcm47xx_bus_type) {
+       case BCM47XX_BUS_TYPE_SSB:
+               if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
+                   ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
+                       return;
 
-       if (ssb_extif_available(&ssb_bcm47xx.extif) &&
-           ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
-               return;
+               if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
+                   ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
+                       return;
 
-       clear_bit(gpio, gpio_in_use);
+               clear_bit(gpio, gpio_in_use);
+               return;
+       }
 }
 EXPORT_SYMBOL(gpio_free);
 
 int gpio_to_irq(unsigned gpio)
 {
-       if (ssb_chipco_available(&ssb_bcm47xx.chipco))
-               return ssb_mips_irq(ssb_bcm47xx.chipco.dev) + 2;
-       else if (ssb_extif_available(&ssb_bcm47xx.extif))
-               return ssb_mips_irq(ssb_bcm47xx.extif.dev) + 2;
-       else
-               return -EINVAL;
+       switch (bcm47xx_bus_type) {
+       case BCM47XX_BUS_TYPE_SSB:
+               if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco))
+                       return ssb_mips_irq(bcm47xx_bus.ssb.chipco.dev) + 2;
+               else if (ssb_extif_available(&bcm47xx_bus.ssb.extif))
+                       return ssb_mips_irq(bcm47xx_bus.ssb.extif.dev) + 2;
+               else
+                       return -EINVAL;
+       }
+       return -EINVAL;
 }
 EXPORT_SYMBOL_GPL(gpio_to_irq);
index 54db815bc86c46e3586e5b9c7061cb32e96f1e37..bcac2ffd1248950a5dbcd461fe7bfcddb9ad36e8 100644 (file)
@@ -26,14 +26,21 @@ static char nvram_buf[NVRAM_SPACE];
 /* Probe for NVRAM header */
 static void early_nvram_init(void)
 {
-       struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
+       struct ssb_mipscore *mcore_ssb;
        struct nvram_header *header;
        int i;
-       u32 base, lim, off;
+       u32 base = 0;
+       u32 lim = 0;
+       u32 off;
        u32 *src, *dst;
 
-       base = mcore->flash_window;
-       lim = mcore->flash_window_size;
+       switch (bcm47xx_bus_type) {
+       case BCM47XX_BUS_TYPE_SSB:
+               mcore_ssb = &bcm47xx_bus.ssb.mipscore;
+               base = mcore_ssb->flash_window;
+               lim = mcore_ssb->flash_window_size;
+               break;
+       }
 
        off = FLASH_MIN;
        while (off <= lim) {
index 59c11afdb2abe2deaed46f9725ceeac1fa7ef098..17c67e24b5498e0534ff98df70fd6839527806e4 100644 (file)
@@ -23,10 +23,10 @@ static struct platform_device uart8250_device = {
        },
 };
 
-static int __init uart8250_init(void)
+static int __init uart8250_init_ssb(void)
 {
        int i;
-       struct ssb_mipscore *mcore = &(ssb_bcm47xx.mipscore);
+       struct ssb_mipscore *mcore = &(bcm47xx_bus.ssb.mipscore);
 
        memset(&uart8250_data, 0,  sizeof(uart8250_data));
 
@@ -45,6 +45,15 @@ static int __init uart8250_init(void)
        return platform_device_register(&uart8250_device);
 }
 
+static int __init uart8250_init(void)
+{
+       switch (bcm47xx_bus_type) {
+       case BCM47XX_BUS_TYPE_SSB:
+               return uart8250_init_ssb();
+       }
+       return -EINVAL;
+}
+
 module_init(uart8250_init);
 
 MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>");
index cfae81571dedd91d9411d7457fc9322497b93896..271cedb339ae0abb0807d554f66ce6e188a0900d 100644 (file)
 #include <bcm47xx.h>
 #include <asm/mach-bcm47xx/nvram.h>
 
-struct ssb_bus ssb_bcm47xx;
-EXPORT_SYMBOL(ssb_bcm47xx);
+union bcm47xx_bus bcm47xx_bus;
+EXPORT_SYMBOL(bcm47xx_bus);
+
+enum bcm47xx_bus_type bcm47xx_bus_type;
+EXPORT_SYMBOL(bcm47xx_bus_type);
 
 static void bcm47xx_machine_restart(char *command)
 {
        printk(KERN_ALERT "Please stand by while rebooting the system...\n");
        local_irq_disable();
        /* Set the watchdog timer to reset immediately */
-       ssb_watchdog_timer_set(&ssb_bcm47xx, 1);
+       switch (bcm47xx_bus_type) {
+       case BCM47XX_BUS_TYPE_SSB:
+               ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1);
+               break;
+       }
        while (1)
                cpu_relax();
 }
@@ -52,7 +59,11 @@ static void bcm47xx_machine_halt(void)
 {
        /* Disable interrupts and watchdog and spin forever */
        local_irq_disable();
-       ssb_watchdog_timer_set(&ssb_bcm47xx, 0);
+       switch (bcm47xx_bus_type) {
+       case BCM47XX_BUS_TYPE_SSB:
+               ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
+               break;
+       }
        while (1)
                cpu_relax();
 }
@@ -247,7 +258,7 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
        return 0;
 }
 
-void __init plat_mem_setup(void)
+static void __init bcm47xx_register_ssb(void)
 {
        int err;
        char buf[100];
@@ -258,12 +269,12 @@ void __init plat_mem_setup(void)
                printk(KERN_WARNING "bcm47xx: someone else already registered"
                        " a ssb SPROM callback handler (err %d)\n", err);
 
-       err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE,
+       err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE,
                                      bcm47xx_get_invariants);
        if (err)
                panic("Failed to initialize SSB bus (err %d)\n", err);
 
-       mcore = &ssb_bcm47xx.mipscore;
+       mcore = &bcm47xx_bus.ssb.mipscore;
        if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
                if (strstr(buf, "console=ttyS1")) {
                        struct ssb_serial_port port;
@@ -276,6 +287,14 @@ void __init plat_mem_setup(void)
                        memcpy(&mcore->serial_ports[1], &port, sizeof(port));
                }
        }
+}
+
+void __init plat_mem_setup(void)
+{
+       struct cpuinfo_mips *c = &current_cpu_data;
+
+       bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
+       bcm47xx_register_ssb();
 
        _machine_restart = bcm47xx_machine_restart;
        _machine_halt = bcm47xx_machine_halt;
index 0c6f47b3fd9482d838d4ffec4c5e47150523a74b..50aea2e1808c5fb0f06dcbc6ee474f21f5d75c80 100644 (file)
@@ -30,7 +30,7 @@
 
 void __init plat_time_init(void)
 {
-       unsigned long hz;
+       unsigned long hz = 0;
 
        /*
         * Use deterministic values for initial counter interrupt
@@ -39,7 +39,12 @@ void __init plat_time_init(void)
        write_c0_count(0);
        write_c0_compare(0xffff);
 
-       hz = ssb_cpu_clock(&ssb_bcm47xx.mipscore) / 2;
+       switch (bcm47xx_bus_type) {
+       case BCM47XX_BUS_TYPE_SSB:
+               hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2;
+               break;
+       }
+
        if (!hz)
                hz = 100000000;
 
index 74d06965326f7ccd6e140b367b088a04d915d809..e9f9ec8d443b5b959ef4b164b0a46197cad7ebb9 100644 (file)
@@ -108,7 +108,7 @@ static irqreturn_t gpio_interrupt(int irq, void *ignored)
 
        /* Interrupts are shared, check if the current one is
           a GPIO interrupt. */
-       if (!ssb_chipco_irq_status(&ssb_bcm47xx.chipco,
+       if (!ssb_chipco_irq_status(&bcm47xx_bus.ssb.chipco,
                                   SSB_CHIPCO_IRQ_GPIO))
                return IRQ_NONE;
 
@@ -132,22 +132,26 @@ static int __init wgt634u_init(void)
         * machine. Use the MAC address as an heuristic. Netgear Inc. has
         * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
         */
+       u8 *et0mac;
 
-       u8 *et0mac = ssb_bcm47xx.sprom.et0mac;
+       if (bcm47xx_bus_type != BCM47XX_BUS_TYPE_SSB)
+               return -ENODEV;
+
+       et0mac = bcm47xx_bus.ssb.sprom.et0mac;
 
        if (et0mac[0] == 0x00 &&
            ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) ||
             (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) {
-               struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
+               struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore;
 
                printk(KERN_INFO "WGT634U machine detected.\n");
 
                if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET),
                                 gpio_interrupt, IRQF_SHARED,
-                                "WGT634U GPIO", &ssb_bcm47xx.chipco)) {
+                                "WGT634U GPIO", &bcm47xx_bus.ssb.chipco)) {
                        gpio_direction_input(WGT634U_GPIO_RESET);
                        gpio_intmask(WGT634U_GPIO_RESET, 1);
-                       ssb_chipco_irq_mask(&ssb_bcm47xx.chipco,
+                       ssb_chipco_irq_mask(&bcm47xx_bus.ssb.chipco,
                                            SSB_CHIPCO_IRQ_GPIO,
                                            SSB_CHIPCO_IRQ_GPIO);
                }
index d008f47a28bdf8d9a9473c9a4f034dc406e02a1e..7cf481bb1a05ada49b3466cda9cb96f6ea0c7b23 100644 (file)
 #ifndef __ASM_BCM47XX_H
 #define __ASM_BCM47XX_H
 
-/* SSB bus */
-extern struct ssb_bus ssb_bcm47xx;
+#include <linux/ssb/ssb.h>
+
+enum bcm47xx_bus_type {
+       BCM47XX_BUS_TYPE_SSB,
+};
+
+union bcm47xx_bus {
+       struct ssb_bus ssb;
+};
+
+extern union bcm47xx_bus bcm47xx_bus;
+extern enum bcm47xx_bus_type bcm47xx_bus_type;
 
 #endif /* __ASM_BCM47XX_H */
index 98504142124ec97ed571b2c36696c87d3c91e6ac..6b78827dd140e17174041e93e2f6fe540d1e23b2 100644 (file)
@@ -21,41 +21,66 @@ extern int gpio_to_irq(unsigned gpio);
 
 static inline int gpio_get_value(unsigned gpio)
 {
-       return ssb_gpio_in(&ssb_bcm47xx, 1 << gpio);
+       switch (bcm47xx_bus_type) {
+       case BCM47XX_BUS_TYPE_SSB:
+               return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio);
+       }
+       return -EINVAL;
 }
 
 static inline void gpio_set_value(unsigned gpio, int value)
 {
-       ssb_gpio_out(&ssb_bcm47xx, 1 << gpio, value ? 1 << gpio : 0);
+       switch (bcm47xx_bus_type) {
+       case BCM47XX_BUS_TYPE_SSB:
+               ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
+                            value ? 1 << gpio : 0);
+       }
 }
 
 static inline int gpio_direction_input(unsigned gpio)
 {
-       ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0);
-       return 0;
+       switch (bcm47xx_bus_type) {
+       case BCM47XX_BUS_TYPE_SSB:
+               ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0);
+               return 0;
+       }
+       return -EINVAL;
 }
 
 static inline int gpio_direction_output(unsigned gpio, int value)
 {
-       /* first set the gpio out value */
-       ssb_gpio_out(&ssb_bcm47xx, 1 << gpio, value ? 1 << gpio : 0);
-       /* then set the gpio mode */
-       ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio);
-       return 0;
+       switch (bcm47xx_bus_type) {
+       case BCM47XX_BUS_TYPE_SSB:
+               /* first set the gpio out value */
+               ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
+                            value ? 1 << gpio : 0);
+               /* then set the gpio mode */
+               ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio);
+               return 0;
+       }
+       return -EINVAL;
 }
 
 static inline int gpio_intmask(unsigned gpio, int value)
 {
-       ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio,
-                        value ? 1 << gpio : 0);
-       return 0;
+       switch (bcm47xx_bus_type) {
+       case BCM47XX_BUS_TYPE_SSB:
+               ssb_gpio_intmask(&bcm47xx_bus.ssb, 1 << gpio,
+                                value ? 1 << gpio : 0);
+               return 0;
+       }
+       return -EINVAL;
 }
 
 static inline int gpio_polarity(unsigned gpio, int value)
 {
-       ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio,
-                         value ? 1 << gpio : 0);
-       return 0;
+       switch (bcm47xx_bus_type) {
+       case BCM47XX_BUS_TYPE_SSB:
+               ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << gpio,
+                                 value ? 1 << gpio : 0);
+               return 0;
+       }
+       return -EINVAL;
 }
 
 
index bd44417c84d40940302fe484373818b84ac70982..c43406c48613c85865a29681ba03e6bea648667c 100644 (file)
@@ -54,12 +54,20 @@ static atomic_t ticks;
 static inline void bcm47xx_wdt_hw_start(void)
 {
        /* this is 2,5s on 100Mhz clock  and 2s on 133 Mhz */
-       ssb_watchdog_timer_set(&ssb_bcm47xx, 0xfffffff);
+       switch (bcm47xx_bus_type) {
+       case BCM47XX_BUS_TYPE_SSB:
+               ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0xfffffff);
+               break;
+       }
 }
 
 static inline int bcm47xx_wdt_hw_stop(void)
 {
-       return ssb_watchdog_timer_set(&ssb_bcm47xx, 0);
+       switch (bcm47xx_bus_type) {
+       case BCM47XX_BUS_TYPE_SSB:
+               return ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
+       }
+       return -EINVAL;
 }
 
 static void bcm47xx_timer_tick(unsigned long unused)