diff options
author | Hauke Mehrtens <hauke@hauke-m.de> | 2011-06-28 22:21:57 +0000 |
---|---|---|
committer | Hauke Mehrtens <hauke@hauke-m.de> | 2011-06-28 22:21:57 +0000 |
commit | 4c18da3df65146d5148dc241c7b6cd1ccc2bcee8 (patch) | |
tree | 03eb26311c9d4c410cb9180ccc08a4e00a22433b /target/linux/brcm47xx/patches-3.0/0010-bcm47xx-prepare-to-support-different-buses.patch | |
parent | 3f0eed15a2c8140943f66e31806054c7550377ae (diff) | |
download | upstream-4c18da3df65146d5148dc241c7b6cd1ccc2bcee8.tar.gz upstream-4c18da3df65146d5148dc241c7b6cd1ccc2bcee8.tar.bz2 upstream-4c18da3df65146d5148dc241c7b6cd1ccc2bcee8.zip |
brcm47xx: add initial support for devices with bcma bus.
Ethernet and wifi are not working and this is highly experimental.
SVN-Revision: 27301
Diffstat (limited to 'target/linux/brcm47xx/patches-3.0/0010-bcm47xx-prepare-to-support-different-buses.patch')
-rw-r--r-- | target/linux/brcm47xx/patches-3.0/0010-bcm47xx-prepare-to-support-different-buses.patch | 439 |
1 files changed, 439 insertions, 0 deletions
diff --git a/target/linux/brcm47xx/patches-3.0/0010-bcm47xx-prepare-to-support-different-buses.patch b/target/linux/brcm47xx/patches-3.0/0010-bcm47xx-prepare-to-support-different-buses.patch new file mode 100644 index 0000000000..4363a5bd99 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.0/0010-bcm47xx-prepare-to-support-different-buses.patch @@ -0,0 +1,439 @@ +From c0886db6357de20fba4f7c0602eceefba3ad343b Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Mon, 6 Jun 2011 00:07:36 +0200 +Subject: [PATCH 10/14] bcm47xx: prepare to support different buses + +The ssb bus is not hod directly any more. there is now a union which +contains all the supported buses, now just ssb. As just one system bus +can be used at a time the union does not cause any problems. + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + arch/mips/bcm47xx/gpio.c | 56 ++++++++++++++++---------- + arch/mips/bcm47xx/nvram.c | 15 +++++-- + arch/mips/bcm47xx/serial.c | 13 +++++- + arch/mips/bcm47xx/setup.c | 32 +++++++++++--- + arch/mips/bcm47xx/time.c | 9 +++- + arch/mips/bcm47xx/wgt634u.c | 13 ++++-- + arch/mips/include/asm/mach-bcm47xx/bcm47xx.h | 14 ++++++- + arch/mips/include/asm/mach-bcm47xx/gpio.h | 55 ++++++++++++++++++------- + drivers/watchdog/bcm47xx_wdt.c | 12 +++++- + 9 files changed, 158 insertions(+), 61 deletions(-) + +--- a/arch/mips/bcm47xx/gpio.c ++++ b/arch/mips/bcm47xx/gpio.c +@@ -20,42 +20,54 @@ static DECLARE_BITMAP(gpio_in_use, BCM47 + + int gpio_request(unsigned gpio, const char *tag) + { +- if (ssb_chipco_available(&ssb_bcm47xx.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 (test_and_set_bit(gpio, gpio_in_use)) +- return -EBUSY; +- +- return 0; ++ switch (bcm47xx_active_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(&bcm47xx_bus.ssb.extif) && ++ ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES)) ++ return -EINVAL; ++ ++ if (test_and_set_bit(gpio, gpio_in_use)) ++ return -EBUSY; ++ ++ 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_active_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(&bcm47xx_bus.ssb.extif) && ++ ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES)) ++ return; + +- if (ssb_extif_available(&ssb_bcm47xx.extif) && +- ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES)) ++ clear_bit(gpio, gpio_in_use); + return; +- +- clear_bit(gpio, gpio_in_use); ++ } + } + 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_active_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); +--- a/arch/mips/bcm47xx/nvram.c ++++ b/arch/mips/bcm47xx/nvram.c +@@ -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_active_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) { +--- a/arch/mips/bcm47xx/serial.c ++++ b/arch/mips/bcm47xx/serial.c +@@ -23,10 +23,10 @@ static struct platform_device uart8250_d + }, + }; + +-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_active_bus_type) { ++ case BCM47XX_BUS_TYPE_SSB: ++ return uart8250_init_ssb(); ++ } ++ return -EINVAL; ++} ++ + module_init(uart8250_init); + + MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>"); +--- a/arch/mips/bcm47xx/setup.c ++++ b/arch/mips/bcm47xx/setup.c +@@ -35,15 +35,22 @@ + #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_active_bus_type; ++EXPORT_SYMBOL(bcm47xx_active_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_active_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_active_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 + 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 = ¤t_cpu_data; ++ ++ bcm47xx_active_bus_type = BCM47XX_BUS_TYPE_SSB; ++ bcm47xx_register_ssb(); + + _machine_restart = bcm47xx_machine_restart; + _machine_halt = bcm47xx_machine_halt; +--- a/arch/mips/bcm47xx/time.c ++++ b/arch/mips/bcm47xx/time.c +@@ -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_active_bus_type) { ++ case BCM47XX_BUS_TYPE_SSB: ++ hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2; ++ break; ++ } ++ + if (!hz) + hz = 100000000; + +--- a/arch/mips/bcm47xx/wgt634u.c ++++ b/arch/mips/bcm47xx/wgt634u.c +@@ -108,7 +108,7 @@ static irqreturn_t gpio_interrupt(int ir + + /* 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; + +@@ -133,21 +133,24 @@ static int __init wgt634u_init(void) + * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx. + */ + +- u8 *et0mac = ssb_bcm47xx.sprom.et0mac; ++ if (bcm47xx_active_bus_type != BCM47XX_BUS_TYPE_SSB) ++ return -ENODEV; ++ ++ u8 *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); + } +--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h ++++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h +@@ -19,7 +19,17 @@ + #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_active_bus_type; + + #endif /* __ASM_BCM47XX_H */ +--- 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); + + static inline int gpio_get_value(unsigned gpio) + { +- return ssb_gpio_in(&ssb_bcm47xx, 1 << gpio); ++ switch (bcm47xx_active_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_active_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_active_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_active_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_active_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_active_bus_type) { ++ case BCM47XX_BUS_TYPE_SSB: ++ ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << gpio, ++ value ? 1 << gpio : 0); ++ return 0; ++ } ++ return -EINVAL; + } + + +--- a/drivers/watchdog/bcm47xx_wdt.c ++++ b/drivers/watchdog/bcm47xx_wdt.c +@@ -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_active_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_active_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) |