diff options
Diffstat (limited to 'target/linux/generic/patches-3.3/020-ssb_update.patch')
-rw-r--r-- | target/linux/generic/patches-3.3/020-ssb_update.patch | 3206 |
1 files changed, 0 insertions, 3206 deletions
diff --git a/target/linux/generic/patches-3.3/020-ssb_update.patch b/target/linux/generic/patches-3.3/020-ssb_update.patch deleted file mode 100644 index 5354cc7b25..0000000000 --- a/target/linux/generic/patches-3.3/020-ssb_update.patch +++ /dev/null @@ -1,3206 +0,0 @@ ---- a/arch/mips/bcm47xx/nvram.c -+++ b/arch/mips/bcm47xx/nvram.c -@@ -43,8 +43,8 @@ static void early_nvram_init(void) - #ifdef CONFIG_BCM47XX_SSB - case BCM47XX_BUS_TYPE_SSB: - mcore_ssb = &bcm47xx_bus.ssb.mipscore; -- base = mcore_ssb->flash_window; -- lim = mcore_ssb->flash_window_size; -+ base = mcore_ssb->pflash.window; -+ lim = mcore_ssb->pflash.window_size; - break; - #endif - #ifdef CONFIG_BCM47XX_BCMA ---- a/arch/mips/bcm47xx/wgt634u.c -+++ b/arch/mips/bcm47xx/wgt634u.c -@@ -156,10 +156,10 @@ static int __init wgt634u_init(void) - SSB_CHIPCO_IRQ_GPIO); - } - -- wgt634u_flash_data.width = mcore->flash_buswidth; -- wgt634u_flash_resource.start = mcore->flash_window; -- wgt634u_flash_resource.end = mcore->flash_window -- + mcore->flash_window_size -+ wgt634u_flash_data.width = mcore->pflash.buswidth; -+ wgt634u_flash_resource.start = mcore->pflash.window; -+ wgt634u_flash_resource.end = mcore->pflash.window -+ + mcore->pflash.window_size - - 1; - return platform_add_devices(wgt634u_devices, - ARRAY_SIZE(wgt634u_devices)); ---- a/drivers/ssb/Kconfig -+++ b/drivers/ssb/Kconfig -@@ -136,10 +136,15 @@ config SSB_DRIVER_MIPS - - If unsure, say N - -+config SSB_SFLASH -+ bool "SSB serial flash support" -+ depends on SSB_DRIVER_MIPS -+ default y -+ - # Assumption: We are on embedded, if we compile the MIPS core. - config SSB_EMBEDDED - bool -- depends on SSB_DRIVER_MIPS -+ depends on SSB_DRIVER_MIPS && SSB_PCICORE_HOSTMODE - default y - - config SSB_DRIVER_EXTIF -@@ -160,4 +165,12 @@ config SSB_DRIVER_GIGE - - If unsure, say N - -+config SSB_DRIVER_GPIO -+ bool "SSB GPIO driver" -+ depends on SSB && GPIOLIB -+ help -+ Driver to provide access to the GPIO pins on the bus. -+ -+ If unsure, say N -+ - endmenu ---- a/drivers/ssb/Makefile -+++ b/drivers/ssb/Makefile -@@ -11,10 +11,12 @@ ssb-$(CONFIG_SSB_SDIOHOST) += sdio.o - # built-in drivers - ssb-y += driver_chipcommon.o - ssb-y += driver_chipcommon_pmu.o -+ssb-$(CONFIG_SSB_SFLASH) += driver_chipcommon_sflash.o - ssb-$(CONFIG_SSB_DRIVER_MIPS) += driver_mipscore.o - ssb-$(CONFIG_SSB_DRIVER_EXTIF) += driver_extif.o - ssb-$(CONFIG_SSB_DRIVER_PCICORE) += driver_pcicore.o - ssb-$(CONFIG_SSB_DRIVER_GIGE) += driver_gige.o -+ssb-$(CONFIG_SSB_DRIVER_GPIO) += driver_gpio.o - - # b43 pci-ssb-bridge driver - # Not strictly a part of SSB, but kept here for convenience ---- a/drivers/ssb/b43_pci_bridge.c -+++ b/drivers/ssb/b43_pci_bridge.c -@@ -29,11 +29,15 @@ static const struct pci_device_id b43_pc - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4322) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43222) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4324) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4325) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4328) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4329) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432b) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432c) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4350) }, - { 0, }, - }; - MODULE_DEVICE_TABLE(pci, b43_pci_bridge_tbl); ---- a/drivers/ssb/driver_chipcommon.c -+++ b/drivers/ssb/driver_chipcommon.c -@@ -4,6 +4,7 @@ - * - * Copyright 2005, Broadcom Corporation - * Copyright 2006, 2007, Michael Buesch <m@bues.ch> -+ * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de> - * - * Licensed under the GNU/GPL. See COPYING for details. - */ -@@ -12,6 +13,7 @@ - #include <linux/ssb/ssb_regs.h> - #include <linux/export.h> - #include <linux/pci.h> -+#include <linux/bcm47xx_wdt.h> - - #include "ssb_private.h" - -@@ -280,13 +282,79 @@ static void calc_fast_powerup_delay(stru - cc->fast_pwrup_delay = tmp; - } - -+static u32 ssb_chipco_alp_clock(struct ssb_chipcommon *cc) -+{ -+ if (cc->capabilities & SSB_CHIPCO_CAP_PMU) -+ return ssb_pmu_get_alp_clock(cc); -+ -+ return 20000000; -+} -+ -+static u32 ssb_chipco_watchdog_get_max_timer(struct ssb_chipcommon *cc) -+{ -+ u32 nb; -+ -+ if (cc->capabilities & SSB_CHIPCO_CAP_PMU) { -+ if (cc->dev->id.revision < 26) -+ nb = 16; -+ else -+ nb = (cc->dev->id.revision >= 37) ? 32 : 24; -+ } else { -+ nb = 28; -+ } -+ if (nb == 32) -+ return 0xffffffff; -+ else -+ return (1 << nb) - 1; -+} -+ -+u32 ssb_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks) -+{ -+ struct ssb_chipcommon *cc = bcm47xx_wdt_get_drvdata(wdt); -+ -+ if (cc->dev->bus->bustype != SSB_BUSTYPE_SSB) -+ return 0; -+ -+ return ssb_chipco_watchdog_timer_set(cc, ticks); -+} -+ -+u32 ssb_chipco_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms) -+{ -+ struct ssb_chipcommon *cc = bcm47xx_wdt_get_drvdata(wdt); -+ u32 ticks; -+ -+ if (cc->dev->bus->bustype != SSB_BUSTYPE_SSB) -+ return 0; -+ -+ ticks = ssb_chipco_watchdog_timer_set(cc, cc->ticks_per_ms * ms); -+ return ticks / cc->ticks_per_ms; -+} -+ -+static int ssb_chipco_watchdog_ticks_per_ms(struct ssb_chipcommon *cc) -+{ -+ struct ssb_bus *bus = cc->dev->bus; -+ -+ if (cc->capabilities & SSB_CHIPCO_CAP_PMU) { -+ /* based on 32KHz ILP clock */ -+ return 32; -+ } else { -+ if (cc->dev->id.revision < 18) -+ return ssb_clockspeed(bus) / 1000; -+ else -+ return ssb_chipco_alp_clock(cc) / 1000; -+ } -+} -+ - void ssb_chipcommon_init(struct ssb_chipcommon *cc) - { - if (!cc->dev) - return; /* We don't have a ChipCommon */ -+ -+ spin_lock_init(&cc->gpio_lock); -+ - if (cc->dev->id.revision >= 11) - cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); -- ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status); -+ ssb_dbg("chipcommon status is 0x%x\n", cc->status); - - if (cc->dev->id.revision >= 20) { - chipco_write32(cc, SSB_CHIPCO_GPIOPULLUP, 0); -@@ -297,6 +365,11 @@ void ssb_chipcommon_init(struct ssb_chip - chipco_powercontrol_init(cc); - ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); - calc_fast_powerup_delay(cc); -+ -+ if (cc->dev->bus->bustype == SSB_BUSTYPE_SSB) { -+ cc->ticks_per_ms = ssb_chipco_watchdog_ticks_per_ms(cc); -+ cc->max_timer_ms = ssb_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms; -+ } - } - - void ssb_chipco_suspend(struct ssb_chipcommon *cc) -@@ -395,10 +468,27 @@ void ssb_chipco_timing_init(struct ssb_c - } - - /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */ --void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks) -+u32 ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks) - { -- /* instant NMI */ -- chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks); -+ u32 maxt; -+ enum ssb_clkmode clkmode; -+ -+ maxt = ssb_chipco_watchdog_get_max_timer(cc); -+ if (cc->capabilities & SSB_CHIPCO_CAP_PMU) { -+ if (ticks == 1) -+ ticks = 2; -+ else if (ticks > maxt) -+ ticks = maxt; -+ chipco_write32(cc, SSB_CHIPCO_PMU_WATCHDOG, ticks); -+ } else { -+ clkmode = ticks ? SSB_CLKMODE_FAST : SSB_CLKMODE_DYNAMIC; -+ ssb_chipco_set_clockmode(cc, clkmode); -+ if (ticks > maxt) -+ ticks = maxt; -+ /* instant NMI */ -+ chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks); -+ } -+ return ticks; - } - - void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value) -@@ -418,28 +508,93 @@ u32 ssb_chipco_gpio_in(struct ssb_chipco - - u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value) - { -- return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value); -+ unsigned long flags; -+ u32 res = 0; -+ -+ spin_lock_irqsave(&cc->gpio_lock, flags); -+ res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value); -+ spin_unlock_irqrestore(&cc->gpio_lock, flags); -+ -+ return res; - } - - u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value) - { -- return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value); -+ unsigned long flags; -+ u32 res = 0; -+ -+ spin_lock_irqsave(&cc->gpio_lock, flags); -+ res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value); -+ spin_unlock_irqrestore(&cc->gpio_lock, flags); -+ -+ return res; - } - - u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value) - { -- return chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value); -+ unsigned long flags; -+ u32 res = 0; -+ -+ spin_lock_irqsave(&cc->gpio_lock, flags); -+ res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value); -+ spin_unlock_irqrestore(&cc->gpio_lock, flags); -+ -+ return res; - } - EXPORT_SYMBOL(ssb_chipco_gpio_control); - - u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value) - { -- return chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value); -+ unsigned long flags; -+ u32 res = 0; -+ -+ spin_lock_irqsave(&cc->gpio_lock, flags); -+ res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value); -+ spin_unlock_irqrestore(&cc->gpio_lock, flags); -+ -+ return res; - } - - u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value) - { -- return chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value); -+ unsigned long flags; -+ u32 res = 0; -+ -+ spin_lock_irqsave(&cc->gpio_lock, flags); -+ res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value); -+ spin_unlock_irqrestore(&cc->gpio_lock, flags); -+ -+ return res; -+} -+ -+u32 ssb_chipco_gpio_pullup(struct ssb_chipcommon *cc, u32 mask, u32 value) -+{ -+ unsigned long flags; -+ u32 res = 0; -+ -+ if (cc->dev->id.revision < 20) -+ return 0xffffffff; -+ -+ spin_lock_irqsave(&cc->gpio_lock, flags); -+ res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLUP, mask, value); -+ spin_unlock_irqrestore(&cc->gpio_lock, flags); -+ -+ return res; -+} -+ -+u32 ssb_chipco_gpio_pulldown(struct ssb_chipcommon *cc, u32 mask, u32 value) -+{ -+ unsigned long flags; -+ u32 res = 0; -+ -+ if (cc->dev->id.revision < 20) -+ return 0xffffffff; -+ -+ spin_lock_irqsave(&cc->gpio_lock, flags); -+ res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLDOWN, mask, value); -+ spin_unlock_irqrestore(&cc->gpio_lock, flags); -+ -+ return res; - } - - #ifdef CONFIG_SSB_SERIAL -@@ -473,12 +628,7 @@ int ssb_chipco_serial_init(struct ssb_ch - chipco_read32(cc, SSB_CHIPCO_CORECTL) - | SSB_CHIPCO_CORECTL_UARTCLK0); - } else if ((ccrev >= 11) && (ccrev != 15)) { -- /* Fixed ALP clock */ -- baud_base = 20000000; -- if (cc->capabilities & SSB_CHIPCO_CAP_PMU) { -- /* FIXME: baud_base is different for devices with a PMU */ -- SSB_WARN_ON(1); -- } -+ baud_base = ssb_chipco_alp_clock(cc); - div = 1; - if (ccrev >= 21) { - /* Turn off UART clock before switching clocksource. */ ---- a/drivers/ssb/driver_chipcommon_pmu.c -+++ b/drivers/ssb/driver_chipcommon_pmu.c -@@ -13,6 +13,9 @@ - #include <linux/ssb/ssb_driver_chipcommon.h> - #include <linux/delay.h> - #include <linux/export.h> -+#ifdef CONFIG_BCM47XX -+#include <asm/mach-bcm47xx/nvram.h> -+#endif - - #include "ssb_private.h" - -@@ -92,10 +95,6 @@ static void ssb_pmu0_pllinit_r0(struct s - u32 pmuctl, tmp, pllctl; - unsigned int i; - -- if ((bus->chip_id == 0x5354) && !crystalfreq) { -- /* The 5354 crystal freq is 25MHz */ -- crystalfreq = 25000; -- } - if (crystalfreq) - e = pmu0_plltab_find_entry(crystalfreq); - if (!e) -@@ -111,8 +110,8 @@ static void ssb_pmu0_pllinit_r0(struct s - return; - } - -- ssb_printk(KERN_INFO PFX "Programming PLL to %u.%03u MHz\n", -- (crystalfreq / 1000), (crystalfreq % 1000)); -+ ssb_info("Programming PLL to %u.%03u MHz\n", -+ crystalfreq / 1000, crystalfreq % 1000); - - /* First turn the PLL off. */ - switch (bus->chip_id) { -@@ -139,7 +138,7 @@ static void ssb_pmu0_pllinit_r0(struct s - } - tmp = chipco_read32(cc, SSB_CHIPCO_CLKCTLST); - if (tmp & SSB_CHIPCO_CLKCTLST_HAVEHT) -- ssb_printk(KERN_EMERG PFX "Failed to turn the PLL off!\n"); -+ ssb_emerg("Failed to turn the PLL off!\n"); - - /* Set PDIV in PLL control 0. */ - pllctl = ssb_chipco_pll_read(cc, SSB_PMU0_PLLCTL0); -@@ -250,8 +249,8 @@ static void ssb_pmu1_pllinit_r0(struct s - return; - } - -- ssb_printk(KERN_INFO PFX "Programming PLL to %u.%03u MHz\n", -- (crystalfreq / 1000), (crystalfreq % 1000)); -+ ssb_info("Programming PLL to %u.%03u MHz\n", -+ crystalfreq / 1000, crystalfreq % 1000); - - /* First turn the PLL off. */ - switch (bus->chip_id) { -@@ -276,7 +275,7 @@ static void ssb_pmu1_pllinit_r0(struct s - } - tmp = chipco_read32(cc, SSB_CHIPCO_CLKCTLST); - if (tmp & SSB_CHIPCO_CLKCTLST_HAVEHT) -- ssb_printk(KERN_EMERG PFX "Failed to turn the PLL off!\n"); -+ ssb_emerg("Failed to turn the PLL off!\n"); - - /* Set p1div and p2div. */ - pllctl = ssb_chipco_pll_read(cc, SSB_PMU1_PLLCTL0); -@@ -321,7 +320,11 @@ static void ssb_pmu_pll_init(struct ssb_ - u32 crystalfreq = 0; /* in kHz. 0 = keep default freq. */ - - if (bus->bustype == SSB_BUSTYPE_SSB) { -- /* TODO: The user may override the crystal frequency. */ -+#ifdef CONFIG_BCM47XX -+ char buf[20]; -+ if (nvram_getenv("xtalfreq", buf, sizeof(buf)) >= 0) -+ crystalfreq = simple_strtoul(buf, NULL, 0); -+#endif - } - - switch (bus->chip_id) { -@@ -330,7 +333,11 @@ static void ssb_pmu_pll_init(struct ssb_ - ssb_pmu1_pllinit_r0(cc, crystalfreq); - break; - case 0x4328: -+ ssb_pmu0_pllinit_r0(cc, crystalfreq); -+ break; - case 0x5354: -+ if (crystalfreq == 0) -+ crystalfreq = 25000; - ssb_pmu0_pllinit_r0(cc, crystalfreq); - break; - case 0x4322: -@@ -339,10 +346,11 @@ static void ssb_pmu_pll_init(struct ssb_ - chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, 0x380005C0); - } - break; -+ case 43222: -+ break; - default: -- ssb_printk(KERN_ERR PFX -- "ERROR: PLL init unknown for device %04X\n", -- bus->chip_id); -+ ssb_err("ERROR: PLL init unknown for device %04X\n", -+ bus->chip_id); - } - } - -@@ -427,6 +435,7 @@ static void ssb_pmu_resources_init(struc - min_msk = 0xCBB; - break; - case 0x4322: -+ case 43222: - /* We keep the default settings: - * min_msk = 0xCBB - * max_msk = 0x7FFFF -@@ -462,9 +471,8 @@ static void ssb_pmu_resources_init(struc - max_msk = 0xFFFFF; - break; - default: -- ssb_printk(KERN_ERR PFX -- "ERROR: PMU resource config unknown for device %04X\n", -- bus->chip_id); -+ ssb_err("ERROR: PMU resource config unknown for device %04X\n", -+ bus->chip_id); - } - - if (updown_tab) { -@@ -516,8 +524,8 @@ void ssb_pmu_init(struct ssb_chipcommon - pmucap = chipco_read32(cc, SSB_CHIPCO_PMU_CAP); - cc->pmu.rev = (pmucap & SSB_CHIPCO_PMU_CAP_REVISION); - -- ssb_dprintk(KERN_DEBUG PFX "Found rev %u PMU (capabilities 0x%08X)\n", -- cc->pmu.rev, pmucap); -+ ssb_dbg("Found rev %u PMU (capabilities 0x%08X)\n", -+ cc->pmu.rev, pmucap); - - if (cc->pmu.rev == 1) - chipco_mask32(cc, SSB_CHIPCO_PMU_CTL, -@@ -607,3 +615,102 @@ void ssb_pmu_set_ldo_paref(struct ssb_ch - - EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage); - EXPORT_SYMBOL(ssb_pmu_set_ldo_paref); -+ -+static u32 ssb_pmu_get_alp_clock_clk0(struct ssb_chipcommon *cc) -+{ -+ u32 crystalfreq; -+ const struct pmu0_plltab_entry *e = NULL; -+ -+ crystalfreq = chipco_read32(cc, SSB_CHIPCO_PMU_CTL) & -+ SSB_CHIPCO_PMU_CTL_XTALFREQ >> SSB_CHIPCO_PMU_CTL_XTALFREQ_SHIFT; -+ e = pmu0_plltab_find_entry(crystalfreq); -+ BUG_ON(!e); -+ return e->freq * 1000; -+} -+ -+u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc) -+{ -+ struct ssb_bus *bus = cc->dev->bus; -+ -+ switch (bus->chip_id) { -+ case 0x5354: -+ ssb_pmu_get_alp_clock_clk0(cc); -+ default: -+ ssb_err("ERROR: PMU alp clock unknown for device %04X\n", -+ bus->chip_id); -+ return 0; -+ } -+} -+ -+u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc) -+{ -+ struct ssb_bus *bus = cc->dev->bus; -+ -+ switch (bus->chip_id) { -+ case 0x5354: -+ /* 5354 chip uses a non programmable PLL of frequency 240MHz */ -+ return 240000000; -+ default: -+ ssb_err("ERROR: PMU cpu clock unknown for device %04X\n", -+ bus->chip_id); -+ return 0; -+ } -+} -+ -+u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc) -+{ -+ struct ssb_bus *bus = cc->dev->bus; -+ -+ switch (bus->chip_id) { -+ case 0x5354: -+ return 120000000; -+ default: -+ ssb_err("ERROR: PMU controlclock unknown for device %04X\n", -+ bus->chip_id); -+ return 0; -+ } -+} -+ -+void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid) -+{ -+ u32 pmu_ctl = 0; -+ -+ switch (cc->dev->bus->chip_id) { -+ case 0x4322: -+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL0, 0x11100070); -+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL1, 0x1014140a); -+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL5, 0x88888854); -+ if (spuravoid == 1) -+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05201828); -+ else -+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05001828); -+ pmu_ctl = SSB_CHIPCO_PMU_CTL_PLL_UPD; -+ break; -+ case 43222: -+ if (spuravoid == 1) { -+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL0, 0x11500008); -+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL1, 0x0C000C06); -+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x0F600a08); -+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL3, 0x00000000); -+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL4, 0x2001E920); -+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL5, 0x88888815); -+ } else { -+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL0, 0x11100008); -+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL1, 0x0c000c06); -+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x03000a08); -+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL3, 0x00000000); -+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL4, 0x200005c0); -+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL5, 0x88888855); -+ } -+ pmu_ctl = SSB_CHIPCO_PMU_CTL_PLL_UPD; -+ break; -+ default: -+ ssb_printk(KERN_ERR PFX -+ "Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n", -+ cc->dev->bus->chip_id); -+ return; -+ } -+ -+ chipco_set32(cc, SSB_CHIPCO_PMU_CTL, pmu_ctl); -+} -+EXPORT_SYMBOL_GPL(ssb_pmu_spuravoid_pllupdate); ---- /dev/null -+++ b/drivers/ssb/driver_chipcommon_sflash.c -@@ -0,0 +1,164 @@ -+/* -+ * Sonics Silicon Backplane -+ * ChipCommon serial flash interface -+ * -+ * Licensed under the GNU/GPL. See COPYING for details. -+ */ -+ -+#include <linux/ssb/ssb.h> -+ -+#include "ssb_private.h" -+ -+static struct resource ssb_sflash_resource = { -+ .name = "ssb_sflash", -+ .start = SSB_FLASH2, -+ .end = 0, -+ .flags = IORESOURCE_MEM | IORESOURCE_READONLY, -+}; -+ -+struct platform_device ssb_sflash_dev = { -+ .name = "ssb_sflash", -+ .resource = &ssb_sflash_resource, -+ .num_resources = 1, -+}; -+ -+struct ssb_sflash_tbl_e { -+ char *name; -+ u32 id; -+ u32 blocksize; -+ u16 numblocks; -+}; -+ -+static const struct ssb_sflash_tbl_e ssb_sflash_st_tbl[] = { -+ { "M25P20", 0x11, 0x10000, 4, }, -+ { "M25P40", 0x12, 0x10000, 8, }, -+ -+ { "M25P16", 0x14, 0x10000, 32, }, -+ { "M25P32", 0x15, 0x10000, 64, }, -+ { "M25P64", 0x16, 0x10000, 128, }, -+ { "M25FL128", 0x17, 0x10000, 256, }, -+ { 0 }, -+}; -+ -+static const struct ssb_sflash_tbl_e ssb_sflash_sst_tbl[] = { -+ { "SST25WF512", 1, 0x1000, 16, }, -+ { "SST25VF512", 0x48, 0x1000, 16, }, -+ { "SST25WF010", 2, 0x1000, 32, }, -+ { "SST25VF010", 0x49, 0x1000, 32, }, -+ { "SST25WF020", 3, 0x1000, 64, }, -+ { "SST25VF020", 0x43, 0x1000, 64, }, -+ { "SST25WF040", 4, 0x1000, 128, }, -+ { "SST25VF040", 0x44, 0x1000, 128, }, -+ { "SST25VF040B", 0x8d, 0x1000, 128, }, -+ { "SST25WF080", 5, 0x1000, 256, }, -+ { "SST25VF080B", 0x8e, 0x1000, 256, }, -+ { "SST25VF016", 0x41, 0x1000, 512, }, -+ { "SST25VF032", 0x4a, 0x1000, 1024, }, -+ { "SST25VF064", 0x4b, 0x1000, 2048, }, -+ { 0 }, -+}; -+ -+static const struct ssb_sflash_tbl_e ssb_sflash_at_tbl[] = { -+ { "AT45DB011", 0xc, 256, 512, }, -+ { "AT45DB021", 0x14, 256, 1024, }, -+ { "AT45DB041", 0x1c, 256, 2048, }, -+ { "AT45DB081", 0x24, 256, 4096, }, -+ { "AT45DB161", 0x2c, 512, 4096, }, -+ { "AT45DB321", 0x34, 512, 8192, }, -+ { "AT45DB642", 0x3c, 1024, 8192, }, -+ { 0 }, -+}; -+ -+static void ssb_sflash_cmd(struct ssb_chipcommon *cc, u32 opcode) -+{ -+ int i; -+ chipco_write32(cc, SSB_CHIPCO_FLASHCTL, -+ SSB_CHIPCO_FLASHCTL_START | opcode); -+ for (i = 0; i < 1000; i++) { -+ if (!(chipco_read32(cc, SSB_CHIPCO_FLASHCTL) & -+ SSB_CHIPCO_FLASHCTL_BUSY)) -+ return; -+ cpu_relax(); -+ } -+ pr_err("SFLASH control command failed (timeout)!\n"); -+} -+ -+/* Initialize serial flash access */ -+int ssb_sflash_init(struct ssb_chipcommon *cc) -+{ -+ struct ssb_sflash *sflash = &cc->dev->bus->mipscore.sflash; -+ const struct ssb_sflash_tbl_e *e; -+ u32 id, id2; -+ -+ switch (cc->capabilities & SSB_CHIPCO_CAP_FLASHT) { -+ case SSB_CHIPCO_FLASHT_STSER: -+ ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_DP); -+ -+ chipco_write32(cc, SSB_CHIPCO_FLASHADDR, 0); -+ ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_RES); -+ id = chipco_read32(cc, SSB_CHIPCO_FLASHDATA); -+ -+ chipco_write32(cc, SSB_CHIPCO_FLASHADDR, 1); -+ ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_RES); -+ id2 = chipco_read32(cc, SSB_CHIPCO_FLASHDATA); -+ -+ switch (id) { -+ case 0xbf: -+ for (e = ssb_sflash_sst_tbl; e->name; e++) { -+ if (e->id == id2) -+ break; -+ } -+ break; -+ case 0x13: -+ return -ENOTSUPP; -+ default: -+ for (e = ssb_sflash_st_tbl; e->name; e++) { -+ if (e->id == id) -+ break; -+ } -+ break; -+ } -+ if (!e->name) { -+ pr_err("Unsupported ST serial flash (id: 0x%X, id2: 0x%X)\n", -+ id, id2); -+ return -ENOTSUPP; -+ } -+ -+ break; -+ case SSB_CHIPCO_FLASHT_ATSER: -+ ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_AT_STATUS); -+ id = chipco_read32(cc, SSB_CHIPCO_FLASHDATA) & 0x3c; -+ -+ for (e = ssb_sflash_at_tbl; e->name; e++) { -+ if (e->id == id) -+ break; -+ } -+ if (!e->name) { -+ pr_err("Unsupported Atmel serial flash (id: 0x%X)\n", -+ id); -+ return -ENOTSUPP; -+ } -+ -+ break; -+ default: -+ pr_err("Unsupported flash type\n"); -+ return -ENOTSUPP; -+ } -+ -+ sflash->window = SSB_FLASH2; -+ sflash->blocksize = e->blocksize; -+ sflash->numblocks = e->numblocks; -+ sflash->size = sflash->blocksize * sflash->numblocks; -+ sflash->present = true; -+ -+ pr_info("Found %s serial flash (size: %dKiB, blocksize: 0x%X, blocks: %d)\n", -+ e->name, sflash->size / 1024, e->blocksize, e->numblocks); -+ -+ /* Prepare platform device, but don't register it yet. It's too early, -+ * malloc (required by device_private_init) is not available yet. */ -+ ssb_sflash_dev.resource[0].end = ssb_sflash_dev.resource[0].start + -+ sflash->size; -+ ssb_sflash_dev.dev.platform_data = sflash; -+ -+ return 0; -+} ---- a/drivers/ssb/driver_extif.c -+++ b/drivers/ssb/driver_extif.c -@@ -112,10 +112,37 @@ void ssb_extif_get_clockcontrol(struct s - *m = extif_read32(extif, SSB_EXTIF_CLOCK_SB); - } - --void ssb_extif_watchdog_timer_set(struct ssb_extif *extif, -- u32 ticks) -+u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks) - { -+ struct ssb_extif *extif = bcm47xx_wdt_get_drvdata(wdt); -+ -+ return ssb_extif_watchdog_timer_set(extif, ticks); -+} -+ -+u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms) -+{ -+ struct ssb_extif *extif = bcm47xx_wdt_get_drvdata(wdt); -+ u32 ticks = (SSB_EXTIF_WATCHDOG_CLK / 1000) * ms; -+ -+ ticks = ssb_extif_watchdog_timer_set(extif, ticks); -+ -+ return (ticks * 1000) / SSB_EXTIF_WATCHDOG_CLK; -+} -+ -+u32 ssb_extif_watchdog_timer_set(struct ssb_extif *extif, u32 ticks) -+{ -+ if (ticks > SSB_EXTIF_WATCHDOG_MAX_TIMER) -+ ticks = SSB_EXTIF_WATCHDOG_MAX_TIMER; - extif_write32(extif, SSB_EXTIF_WATCHDOG, ticks); -+ -+ return ticks; -+} -+ -+void ssb_extif_init(struct ssb_extif *extif) -+{ -+ if (!extif->dev) -+ return; /* We don't have a Extif core */ -+ spin_lock_init(&extif->gpio_lock); - } - - u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask) -@@ -125,22 +152,50 @@ u32 ssb_extif_gpio_in(struct ssb_extif * - - u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value) - { -- return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0), -+ unsigned long flags; -+ u32 res = 0; -+ -+ spin_lock_irqsave(&extif->gpio_lock, flags); -+ res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0), - mask, value); -+ spin_unlock_irqrestore(&extif->gpio_lock, flags); -+ -+ return res; - } - - u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value) - { -- return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0), -+ unsigned long flags; -+ u32 res = 0; -+ -+ spin_lock_irqsave(&extif->gpio_lock, flags); -+ res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0), - mask, value); -+ spin_unlock_irqrestore(&extif->gpio_lock, flags); -+ -+ return res; - } - - u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value) - { -- return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value); -+ unsigned long flags; -+ u32 res = 0; -+ -+ spin_lock_irqsave(&extif->gpio_lock, flags); -+ res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value); -+ spin_unlock_irqrestore(&extif->gpio_lock, flags); -+ -+ return res; - } - - u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value) - { -- return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value); -+ unsigned long flags; -+ u32 res = 0; -+ -+ spin_lock_irqsave(&extif->gpio_lock, flags); -+ res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value); -+ spin_unlock_irqrestore(&extif->gpio_lock, flags); -+ -+ return res; - } ---- /dev/null -+++ b/drivers/ssb/driver_gpio.c -@@ -0,0 +1,210 @@ -+/* -+ * Sonics Silicon Backplane -+ * GPIO driver -+ * -+ * Copyright 2011, Broadcom Corporation -+ * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de> -+ * -+ * Licensed under the GNU/GPL. See COPYING for details. -+ */ -+ -+#include <linux/gpio.h> -+#include <linux/export.h> -+#include <linux/ssb/ssb.h> -+ -+#include "ssb_private.h" -+ -+static struct ssb_bus *ssb_gpio_get_bus(struct gpio_chip *chip) -+{ -+ return container_of(chip, struct ssb_bus, gpio); -+} -+ -+static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned gpio) -+{ -+ struct ssb_bus *bus = ssb_gpio_get_bus(chip); -+ -+ return !!ssb_chipco_gpio_in(&bus->chipco, 1 << gpio); -+} -+ -+static void ssb_gpio_chipco_set_value(struct gpio_chip *chip, unsigned gpio, -+ int value) -+{ -+ struct ssb_bus *bus = ssb_gpio_get_bus(chip); -+ -+ ssb_chipco_gpio_out(&bus->chipco, 1 << gpio, value ? 1 << gpio : 0); -+} -+ -+static int ssb_gpio_chipco_direction_input(struct gpio_chip *chip, -+ unsigned gpio) -+{ -+ struct ssb_bus *bus = ssb_gpio_get_bus(chip); -+ -+ ssb_chipco_gpio_outen(&bus->chipco, 1 << gpio, 0); -+ return 0; -+} -+ -+static int ssb_gpio_chipco_direction_output(struct gpio_chip *chip, -+ unsigned gpio, int value) -+{ -+ struct ssb_bus *bus = ssb_gpio_get_bus(chip); -+ -+ ssb_chipco_gpio_outen(&bus->chipco, 1 << gpio, 1 << gpio); -+ ssb_chipco_gpio_out(&bus->chipco, 1 << gpio, value ? 1 << gpio : 0); -+ return 0; -+} -+ -+static int ssb_gpio_chipco_request(struct gpio_chip *chip, unsigned gpio) -+{ -+ struct ssb_bus *bus = ssb_gpio_get_bus(chip); -+ -+ ssb_chipco_gpio_control(&bus->chipco, 1 << gpio, 0); -+ /* clear pulldown */ -+ ssb_chipco_gpio_pulldown(&bus->chipco, 1 << gpio, 0); -+ /* Set pullup */ -+ ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 1 << gpio); -+ -+ return 0; -+} -+ -+static void ssb_gpio_chipco_free(struct gpio_chip *chip, unsigned gpio) -+{ -+ struct ssb_bus *bus = ssb_gpio_get_bus(chip); -+ -+ /* clear pullup */ -+ ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0); -+} -+ -+static int ssb_gpio_chipco_to_irq(struct gpio_chip *chip, unsigned gpio) -+{ -+ struct ssb_bus *bus = ssb_gpio_get_bus(chip); -+ -+ if (bus->bustype == SSB_BUSTYPE_SSB) -+ return ssb_mips_irq(bus->chipco.dev) + 2; -+ else -+ return -EINVAL; -+} -+ -+static int ssb_gpio_chipco_init(struct ssb_bus *bus) -+{ -+ struct gpio_chip *chip = &bus->gpio; -+ -+ chip->label = "ssb_chipco_gpio"; -+ chip->owner = THIS_MODULE; -+ chip->request = ssb_gpio_chipco_request; -+ chip->free = ssb_gpio_chipco_free; -+ chip->get = ssb_gpio_chipco_get_value; -+ chip->set = ssb_gpio_chipco_set_value; -+ chip->direction_input = ssb_gpio_chipco_direction_input; -+ chip->direction_output = ssb_gpio_chipco_direction_output; -+ chip->to_irq = ssb_gpio_chipco_to_irq; -+ chip->ngpio = 16; -+ /* There is just one SoC in one device and its GPIO addresses should be -+ * deterministic to address them more easily. The other buses could get -+ * a random base number. */ -+ if (bus->bustype == SSB_BUSTYPE_SSB) -+ chip->base = 0; -+ else -+ chip->base = -1; -+ -+ return gpiochip_add(chip); -+} -+ -+#ifdef CONFIG_SSB_DRIVER_EXTIF -+ -+static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned gpio) -+{ -+ struct ssb_bus *bus = ssb_gpio_get_bus(chip); -+ -+ return !!ssb_extif_gpio_in(&bus->extif, 1 << gpio); -+} -+ -+static void ssb_gpio_extif_set_value(struct gpio_chip *chip, unsigned gpio, -+ int value) -+{ -+ struct ssb_bus *bus = ssb_gpio_get_bus(chip); -+ -+ ssb_extif_gpio_out(&bus->extif, 1 << gpio, value ? 1 << gpio : 0); -+} -+ -+static int ssb_gpio_extif_direction_input(struct gpio_chip *chip, -+ unsigned gpio) -+{ -+ struct ssb_bus *bus = ssb_gpio_get_bus(chip); -+ -+ ssb_extif_gpio_outen(&bus->extif, 1 << gpio, 0); -+ return 0; -+} -+ -+static int ssb_gpio_extif_direction_output(struct gpio_chip *chip, -+ unsigned gpio, int value) -+{ -+ struct ssb_bus *bus = ssb_gpio_get_bus(chip); -+ -+ ssb_extif_gpio_outen(&bus->extif, 1 << gpio, 1 << gpio); -+ ssb_extif_gpio_out(&bus->extif, 1 << gpio, value ? 1 << gpio : 0); -+ return 0; -+} -+ -+static int ssb_gpio_extif_to_irq(struct gpio_chip *chip, unsigned gpio) -+{ -+ struct ssb_bus *bus = ssb_gpio_get_bus(chip); -+ -+ if (bus->bustype == SSB_BUSTYPE_SSB) -+ return ssb_mips_irq(bus->extif.dev) + 2; -+ else -+ return -EINVAL; -+} -+ -+static int ssb_gpio_extif_init(struct ssb_bus *bus) -+{ -+ struct gpio_chip *chip = &bus->gpio; -+ -+ chip->label = "ssb_extif_gpio"; -+ chip->owner = THIS_MODULE; -+ chip->get = ssb_gpio_extif_get_value; -+ chip->set = ssb_gpio_extif_set_value; -+ chip->direction_input = ssb_gpio_extif_direction_input; -+ chip->direction_output = ssb_gpio_extif_direction_output; -+ chip->to_irq = ssb_gpio_extif_to_irq; -+ chip->ngpio = 5; -+ /* There is just one SoC in one device and its GPIO addresses should be -+ * deterministic to address them more easily. The other buses could get -+ * a random base number. */ -+ if (bus->bustype == SSB_BUSTYPE_SSB) -+ chip->base = 0; -+ else -+ chip->base = -1; -+ -+ return gpiochip_add(chip); -+} -+ -+#else -+static int ssb_gpio_extif_init(struct ssb_bus *bus) -+{ -+ return -ENOTSUPP; -+} -+#endif -+ -+int ssb_gpio_init(struct ssb_bus *bus) -+{ -+ if (ssb_chipco_available(&bus->chipco)) -+ return ssb_gpio_chipco_init(bus); -+ else if (ssb_extif_available(&bus->extif)) -+ return ssb_gpio_extif_init(bus); -+ else -+ SSB_WARN_ON(1); -+ -+ return -1; -+} -+ -+int ssb_gpio_unregister(struct ssb_bus *bus) -+{ -+ if (ssb_chipco_available(&bus->chipco) || -+ ssb_extif_available(&bus->extif)) { -+ return gpiochip_remove(&bus->gpio); -+ } else { -+ SSB_WARN_ON(1); -+ } -+ -+ return -1; -+} ---- a/drivers/ssb/driver_mipscore.c -+++ b/drivers/ssb/driver_mipscore.c -@@ -10,6 +10,7 @@ - - #include <linux/ssb/ssb.h> - -+#include <linux/mtd/physmap.h> - #include <linux/serial.h> - #include <linux/serial_core.h> - #include <linux/serial_reg.h> -@@ -17,6 +18,25 @@ - - #include "ssb_private.h" - -+static const char * const part_probes[] = { "bcm47xxpart", NULL }; -+ -+static struct physmap_flash_data ssb_pflash_data = { -+ .part_probe_types = part_probes, -+}; -+ -+static struct resource ssb_pflash_resource = { -+ .name = "ssb_pflash", -+ .flags = IORESOURCE_MEM, -+}; -+ -+struct platform_device ssb_pflash_dev = { -+ .name = "physmap-flash", -+ .dev = { -+ .platform_data = &ssb_pflash_data, -+ }, -+ .resource = &ssb_pflash_resource, -+ .num_resources = 1, -+}; - - static inline u32 mips_read32(struct ssb_mipscore *mcore, - u16 offset) -@@ -147,21 +167,22 @@ static void set_irq(struct ssb_device *d - irqflag |= (ipsflag & ~ipsflag_irq_mask[irq]); - ssb_write32(mdev, SSB_IPSFLAG, irqflag); - } -- ssb_dprintk(KERN_INFO PFX -- "set_irq: core 0x%04x, irq %d => %d\n", -- dev->id.coreid, oldirq+2, irq+2); -+ ssb_dbg("set_irq: core 0x%04x, irq %d => %d\n", -+ dev->id.coreid, oldirq+2, irq+2); - } - - static void print_irq(struct ssb_device *dev, unsigned int irq) - { -- int i; - static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"}; -- ssb_dprintk(KERN_INFO PFX -- "core 0x%04x, irq :", dev->id.coreid); -- for (i = 0; i <= 6; i++) { -- ssb_dprintk(" %s%s", irq_name[i], i==irq?"*":" "); -- } -- ssb_dprintk("\n"); -+ ssb_dbg("core 0x%04x, irq : %s%s %s%s %s%s %s%s %s%s %s%s %s%s\n", -+ dev->id.coreid, -+ irq_name[0], irq == 0 ? "*" : " ", -+ irq_name[1], irq == 1 ? "*" : " ", -+ irq_name[2], irq == 2 ? "*" : " ", -+ irq_name[3], irq == 3 ? "*" : " ", -+ irq_name[4], irq == 4 ? "*" : " ", -+ irq_name[5], irq == 5 ? "*" : " ", -+ irq_name[6], irq == 6 ? "*" : " "); - } - - static void dump_irq(struct ssb_bus *bus) -@@ -178,9 +199,9 @@ static void ssb_mips_serial_init(struct - { - struct ssb_bus *bus = mcore->dev->bus; - -- if (bus->extif.dev) -+ if (ssb_extif_available(&bus->extif)) - mcore->nr_serial_ports = ssb_extif_serial_init(&bus->extif, mcore->serial_ports); -- else if (bus->chipco.dev) -+ else if (ssb_chipco_available(&bus->chipco)) - mcore->nr_serial_ports = ssb_chipco_serial_init(&bus->chipco, mcore->serial_ports); - else - mcore->nr_serial_ports = 0; -@@ -189,17 +210,42 @@ static void ssb_mips_serial_init(struct - static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) - { - struct ssb_bus *bus = mcore->dev->bus; -+ struct ssb_pflash *pflash = &mcore->pflash; - -- mcore->flash_buswidth = 2; -- if (bus->chipco.dev) { -- mcore->flash_window = 0x1c000000; -- mcore->flash_window_size = 0x02000000; -+ /* When there is no chipcommon on the bus there is 4MB flash */ -+ if (!ssb_chipco_available(&bus->chipco)) { -+ pflash->present = true; -+ pflash->buswidth = 2; -+ pflash->window = SSB_FLASH1; -+ pflash->window_size = SSB_FLASH1_SZ; -+ goto ssb_pflash; -+ } -+ -+ /* There is ChipCommon, so use it to read info about flash */ -+ switch (bus->chipco.capabilities & SSB_CHIPCO_CAP_FLASHT) { -+ case SSB_CHIPCO_FLASHT_STSER: -+ case SSB_CHIPCO_FLASHT_ATSER: -+ pr_debug("Found serial flash\n"); -+ ssb_sflash_init(&bus->chipco); -+ break; -+ case SSB_CHIPCO_FLASHT_PARA: -+ pr_debug("Found parallel flash\n"); -+ pflash->present = true; -+ pflash->window = SSB_FLASH2; -+ pflash->window_size = SSB_FLASH2_SZ; - if ((ssb_read32(bus->chipco.dev, SSB_CHIPCO_FLASH_CFG) - & SSB_CHIPCO_CFG_DS16) == 0) -- mcore->flash_buswidth = 1; -- } else { -- mcore->flash_window = 0x1fc00000; -- mcore->flash_window_size = 0x00400000; -+ pflash->buswidth = 1; -+ else -+ pflash->buswidth = 2; -+ break; -+ } -+ -+ssb_pflash: -+ if (pflash->present) { -+ ssb_pflash_data.width = pflash->buswidth; -+ ssb_pflash_resource.start = pflash->window; -+ ssb_pflash_resource.end = pflash->window + pflash->window_size; - } - } - -@@ -208,9 +254,12 @@ u32 ssb_cpu_clock(struct ssb_mipscore *m - struct ssb_bus *bus = mcore->dev->bus; - u32 pll_type, n, m, rate = 0; - -- if (bus->extif.dev) { -+ if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU) -+ return ssb_pmu_get_cpu_clock(&bus->chipco); -+ -+ if (ssb_extif_available(&bus->extif)) { - ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m); -- } else if (bus->chipco.dev) { -+ } else if (ssb_chipco_available(&bus->chipco)) { - ssb_chipco_get_clockcpu(&bus->chipco, &pll_type, &n, &m); - } else - return 0; -@@ -238,7 +287,7 @@ void ssb_mipscore_init(struct ssb_mipsco - if (!mcore->dev) - return; /* We don't have a MIPS core */ - -- ssb_dprintk(KERN_INFO PFX "Initializing MIPS core...\n"); -+ ssb_dbg("Initializing MIPS core...\n"); - - bus = mcore->dev->bus; - hz = ssb_clockspeed(bus); -@@ -246,9 +295,9 @@ void ssb_mipscore_init(struct ssb_mipsco - hz = 100000000; - ns = 1000000000 / hz; - -- if (bus->extif.dev) -+ if (ssb_extif_available(&bus->extif)) - ssb_extif_timing_init(&bus->extif, ns); -- else if (bus->chipco.dev) -+ else if (ssb_chipco_available(&bus->chipco)) - ssb_chipco_timing_init(&bus->chipco, ns); - - /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */ -@@ -286,7 +335,7 @@ void ssb_mipscore_init(struct ssb_mipsco - break; - } - } -- ssb_dprintk(KERN_INFO PFX "after irq reconfiguration\n"); -+ ssb_dbg("after irq reconfiguration\n"); - dump_irq(bus); - - ssb_mips_serial_init(mcore); ---- a/drivers/ssb/driver_pcicore.c -+++ b/drivers/ssb/driver_pcicore.c -@@ -263,8 +263,7 @@ int ssb_pcicore_plat_dev_init(struct pci - return -ENODEV; - } - -- ssb_printk(KERN_INFO "PCI: Fixing up device %s\n", -- pci_name(d)); -+ ssb_info("PCI: Fixing up device %s\n", pci_name(d)); - - /* Fix up interrupt lines */ - d->irq = ssb_mips_irq(extpci_core->dev) + 2; -@@ -285,12 +284,12 @@ static void ssb_pcicore_fixup_pcibridge( - if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) != 0) - return; - -- ssb_printk(KERN_INFO "PCI: Fixing up bridge %s\n", pci_name(dev)); -+ ssb_info("PCI: Fixing up bridge %s\n", pci_name(dev)); - - /* Enable PCI bridge bus mastering and memory space */ - pci_set_master(dev); - if (pcibios_enable_device(dev, ~0) < 0) { -- ssb_printk(KERN_ERR "PCI: SSB bridge enable failed\n"); -+ ssb_err("PCI: SSB bridge enable failed\n"); - return; - } - -@@ -299,8 +298,8 @@ static void ssb_pcicore_fixup_pcibridge( - - /* Make sure our latency is high enough to handle the devices behind us */ - lat = 168; -- ssb_printk(KERN_INFO "PCI: Fixing latency timer of device %s to %u\n", -- pci_name(dev), lat); -+ ssb_info("PCI: Fixing latency timer of device %s to %u\n", -+ pci_name(dev), lat); - pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); - } - DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ssb_pcicore_fixup_pcibridge); -@@ -323,7 +322,7 @@ static void __devinit ssb_pcicore_init_h - return; - extpci_core = pc; - -- ssb_dprintk(KERN_INFO PFX "PCIcore in host mode found\n"); -+ ssb_dbg("PCIcore in host mode found\n"); - /* Reset devices on the external PCI bus */ - val = SSB_PCICORE_CTL_RST_OE; - val |= SSB_PCICORE_CTL_CLK_OE; -@@ -338,7 +337,7 @@ static void __devinit ssb_pcicore_init_h - udelay(1); /* Assertion time demanded by the PCI standard */ - - if (pc->dev->bus->has_cardbus_slot) { -- ssb_dprintk(KERN_INFO PFX "CardBus slot detected\n"); -+ ssb_dbg("CardBus slot detected\n"); - pc->cardbusmode = 1; - /* GPIO 1 resets the bridge */ - ssb_gpio_out(pc->dev->bus, 1, 1); ---- a/drivers/ssb/embedded.c -+++ b/drivers/ssb/embedded.c -@@ -4,11 +4,13 @@ - * - * Copyright 2005-2008, Broadcom Corporation - * Copyright 2006-2008, Michael Buesch <m@bues.ch> -+ * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de> - * - * Licensed under the GNU/GPL. See COPYING for details. - */ - - #include <linux/export.h> -+#include <linux/platform_device.h> - #include <linux/ssb/ssb.h> - #include <linux/ssb/ssb_embedded.h> - #include <linux/ssb/ssb_driver_pci.h> -@@ -32,6 +34,38 @@ int ssb_watchdog_timer_set(struct ssb_bu - } - EXPORT_SYMBOL(ssb_watchdog_timer_set); - -+int ssb_watchdog_register(struct ssb_bus *bus) -+{ -+ struct bcm47xx_wdt wdt = {}; -+ struct platform_device *pdev; -+ -+ if (ssb_chipco_available(&bus->chipco)) { -+ wdt.driver_data = &bus->chipco; -+ wdt.timer_set = ssb_chipco_watchdog_timer_set_wdt; -+ wdt.timer_set_ms = ssb_chipco_watchdog_timer_set_ms; -+ wdt.max_timer_ms = bus->chipco.max_timer_ms; -+ } else if (ssb_extif_available(&bus->extif)) { -+ wdt.driver_data = &bus->extif; -+ wdt.timer_set = ssb_extif_watchdog_timer_set_wdt; -+ wdt.timer_set_ms = ssb_extif_watchdog_timer_set_ms; -+ wdt.max_timer_ms = SSB_EXTIF_WATCHDOG_MAX_TIMER_MS; -+ } else { -+ return -ENODEV; -+ } -+ -+ pdev = platform_device_register_data(NULL, "bcm47xx-wdt", -+ bus->busnumber, &wdt, -+ sizeof(wdt)); -+ if (IS_ERR(pdev)) { -+ ssb_dbg("can not register watchdog device, err: %li\n", -+ PTR_ERR(pdev)); -+ return PTR_ERR(pdev); -+ } -+ -+ bus->watchdog = pdev; -+ return 0; -+} -+ - u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask) - { - unsigned long flags; ---- a/drivers/ssb/main.c -+++ b/drivers/ssb/main.c -@@ -13,6 +13,7 @@ - #include <linux/delay.h> - #include <linux/io.h> - #include <linux/module.h> -+#include <linux/platform_device.h> - #include <linux/ssb/ssb.h> - #include <linux/ssb/ssb_regs.h> - #include <linux/ssb/ssb_driver_gige.h> -@@ -289,8 +290,8 @@ int ssb_devices_thaw(struct ssb_freeze_c - - err = sdrv->probe(sdev, &sdev->id); - if (err) { -- ssb_printk(KERN_ERR PFX "Failed to thaw device %s\n", -- dev_name(sdev->dev)); -+ ssb_err("Failed to thaw device %s\n", -+ dev_name(sdev->dev)); - result = err; - } - ssb_driver_put(sdrv); -@@ -449,10 +450,23 @@ static void ssb_devices_unregister(struc - if (sdev->dev) - device_unregister(sdev->dev); - } -+ -+#ifdef CONFIG_SSB_EMBEDDED -+ if (bus->bustype == SSB_BUSTYPE_SSB) -+ platform_device_unregister(bus->watchdog); -+#endif - } - - void ssb_bus_unregister(struct ssb_bus *bus) - { -+ int err; -+ -+ err = ssb_gpio_unregister(bus); -+ if (err == -EBUSY) -+ ssb_dbg("Some GPIOs are still in use\n"); -+ else if (err) -+ ssb_dbg("Can not unregister GPIO driver: %i\n", err); -+ - ssb_buses_lock(); - ssb_devices_unregister(bus); - list_del(&bus->list); -@@ -498,8 +512,7 @@ static int ssb_devices_register(struct s - - devwrap = kzalloc(sizeof(*devwrap), GFP_KERNEL); - if (!devwrap) { -- ssb_printk(KERN_ERR PFX -- "Could not allocate device\n"); -+ ssb_err("Could not allocate device\n"); - err = -ENOMEM; - goto error; - } -@@ -538,9 +551,7 @@ static int ssb_devices_register(struct s - sdev->dev = dev; - err = device_register(dev); - if (err) { -- ssb_printk(KERN_ERR PFX -- "Could not register %s\n", -- dev_name(dev)); -+ ssb_err("Could not register %s\n", dev_name(dev)); - /* Set dev to NULL to not unregister - * dev on error unwinding. */ - sdev->dev = NULL; -@@ -550,6 +561,22 @@ static int ssb_devices_register(struct s - dev_idx++; - } - -+#ifdef CONFIG_SSB_DRIVER_MIPS -+ if (bus->mipscore.pflash.present) { -+ err = platform_device_register(&ssb_pflash_dev); -+ if (err) -+ pr_err("Error registering parallel flash\n"); -+ } -+#endif -+ -+#ifdef CONFIG_SSB_SFLASH -+ if (bus->mipscore.sflash.present) { -+ err = platform_device_register(&ssb_sflash_dev); -+ if (err) -+ pr_err("Error registering serial flash\n"); -+ } -+#endif -+ - return 0; - error: - /* Unwind the already registered devices. */ -@@ -577,6 +604,8 @@ static int __devinit ssb_attach_queued_b - if (err) - goto error; - ssb_pcicore_init(&bus->pcicore); -+ if (bus->bustype == SSB_BUSTYPE_SSB) -+ ssb_watchdog_register(bus); - ssb_bus_may_powerdown(bus); - - err = ssb_devices_register(bus); -@@ -812,7 +841,13 @@ static int __devinit ssb_bus_register(st - if (err) - goto err_pcmcia_exit; - ssb_chipcommon_init(&bus->chipco); -+ ssb_extif_init(&bus->extif); - ssb_mipscore_init(&bus->mipscore); -+ err = ssb_gpio_init(bus); -+ if (err == -ENOTSUPP) -+ ssb_dbg("GPIO driver not activated\n"); -+ else if (err) -+ ssb_dbg("Error registering GPIO driver: %i\n", err); - err = ssb_fetch_invariants(bus, get_invariants); - if (err) { - ssb_bus_may_powerdown(bus); -@@ -863,11 +898,11 @@ int __devinit ssb_bus_pcibus_register(st - - err = ssb_bus_register(bus, ssb_pci_get_invariants, 0); - if (!err) { -- ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on " -- "PCI device %s\n", dev_name(&host_pci->dev)); -+ ssb_info("Sonics Silicon Backplane found on PCI device %s\n", -+ dev_name(&host_pci->dev)); - } else { -- ssb_printk(KERN_ERR PFX "Failed to register PCI version" -- " of SSB with error %d\n", err); -+ ssb_err("Failed to register PCI version of SSB with error %d\n", -+ err); - } - - return err; -@@ -888,8 +923,8 @@ int __devinit ssb_bus_pcmciabus_register - - err = ssb_bus_register(bus, ssb_pcmcia_get_invariants, baseaddr); - if (!err) { -- ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on " -- "PCMCIA device %s\n", pcmcia_dev->devname); -+ ssb_info("Sonics Silicon Backplane found on PCMCIA device %s\n", -+ pcmcia_dev->devname); - } - - return err; -@@ -911,8 +946,8 @@ int __devinit ssb_bus_sdiobus_register(s - - err = ssb_bus_register(bus, ssb_sdio_get_invariants, ~0); - if (!err) { -- ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on " -- "SDIO device %s\n", sdio_func_id(func)); -+ ssb_info("Sonics Silicon Backplane found on SDIO device %s\n", -+ sdio_func_id(func)); - } - - return err; -@@ -931,8 +966,8 @@ int __devinit ssb_bus_ssbbus_register(st - - err = ssb_bus_register(bus, get_invariants, baseaddr); - if (!err) { -- ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found at " -- "address 0x%08lX\n", baseaddr); -+ ssb_info("Sonics Silicon Backplane found at address 0x%08lX\n", -+ baseaddr); - } - - return err; -@@ -1094,6 +1129,9 @@ u32 ssb_clockspeed(struct ssb_bus *bus) - u32 plltype; - u32 clkctl_n, clkctl_m; - -+ if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU) -+ return ssb_pmu_get_controlclock(&bus->chipco); -+ - if (ssb_extif_available(&bus->extif)) - ssb_extif_get_clockcontrol(&bus->extif, &plltype, - &clkctl_n, &clkctl_m); -@@ -1131,8 +1169,7 @@ static u32 ssb_tmslow_reject_bitmask(str - case SSB_IDLOW_SSBREV_27: /* same here */ - return SSB_TMSLOW_REJECT; /* this is a guess */ - default: -- printk(KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev); -- WARN_ON(1); -+ WARN(1, KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev); - } - return (SSB_TMSLOW_REJECT | SSB_TMSLOW_REJECT_23); - } -@@ -1324,7 +1361,7 @@ out: - #endif - return err; - error: -- ssb_printk(KERN_ERR PFX "Bus powerdown failed\n"); -+ ssb_err("Bus powerdown failed\n"); - goto out; - } - EXPORT_SYMBOL(ssb_bus_may_powerdown); -@@ -1347,7 +1384,7 @@ int ssb_bus_powerup(struct ssb_bus *bus, - - return 0; - error: -- ssb_printk(KERN_ERR PFX "Bus powerup failed\n"); -+ ssb_err("Bus powerup failed\n"); - return err; - } - EXPORT_SYMBOL(ssb_bus_powerup); -@@ -1455,15 +1492,13 @@ static int __init ssb_modinit(void) - - err = b43_pci_ssb_bridge_init(); - if (err) { -- ssb_printk(KERN_ERR "Broadcom 43xx PCI-SSB-bridge " -- "initialization failed\n"); -+ ssb_err("Broadcom 43xx PCI-SSB-bridge initialization failed\n"); - /* don't fail SSB init because of this */ - err = 0; - } - err = ssb_gige_init(); - if (err) { -- ssb_printk(KERN_ERR "SSB Broadcom Gigabit Ethernet " -- "driver initialization failed\n"); -+ ssb_err("SSB Broadcom Gigabit Ethernet driver initialization failed\n"); - /* don't fail SSB init because of this */ - err = 0; - } ---- a/drivers/ssb/pci.c -+++ b/drivers/ssb/pci.c -@@ -56,7 +56,7 @@ int ssb_pci_switch_coreidx(struct ssb_bu - } - return 0; - error: -- ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx); -+ ssb_err("Failed to switch to core %u\n", coreidx); - return -ENODEV; - } - -@@ -67,10 +67,9 @@ int ssb_pci_switch_core(struct ssb_bus * - unsigned long flags; - - #if SSB_VERBOSE_PCICORESWITCH_DEBUG -- ssb_printk(KERN_INFO PFX -- "Switching to %s core, index %d\n", -- ssb_core_name(dev->id.coreid), -- dev->core_index); -+ ssb_info("Switching to %s core, index %d\n", -+ ssb_core_name(dev->id.coreid), -+ dev->core_index); - #endif - - spin_lock_irqsave(&bus->bar_lock, flags); -@@ -178,6 +177,18 @@ err_pci: - #define SPEX(_outvar, _offset, _mask, _shift) \ - SPEX16(_outvar, _offset, _mask, _shift) - -+#define SPEX_ARRAY8(_field, _offset, _mask, _shift) \ -+ do { \ -+ SPEX(_field[0], _offset + 0, _mask, _shift); \ -+ SPEX(_field[1], _offset + 2, _mask, _shift); \ -+ SPEX(_field[2], _offset + 4, _mask, _shift); \ -+ SPEX(_field[3], _offset + 6, _mask, _shift); \ -+ SPEX(_field[4], _offset + 8, _mask, _shift); \ -+ SPEX(_field[5], _offset + 10, _mask, _shift); \ -+ SPEX(_field[6], _offset + 12, _mask, _shift); \ -+ SPEX(_field[7], _offset + 14, _mask, _shift); \ -+ } while (0) -+ - - static inline u8 ssb_crc8(u8 crc, u8 data) - { -@@ -219,6 +230,15 @@ static inline u8 ssb_crc8(u8 crc, u8 dat - return t[crc ^ data]; - } - -+static void sprom_get_mac(char *mac, const u16 *in) -+{ -+ int i; -+ for (i = 0; i < 3; i++) { -+ *mac++ = in[i] >> 8; -+ *mac++ = in[i]; -+ } -+} -+ - static u8 ssb_sprom_crc(const u16 *sprom, u16 size) - { - int word; -@@ -266,7 +286,7 @@ static int sprom_do_write(struct ssb_bus - u32 spromctl; - u16 size = bus->sprom_size; - -- ssb_printk(KERN_NOTICE PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n"); -+ ssb_notice("Writing SPROM. Do NOT turn off the power! Please stand by...\n"); - err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl); - if (err) - goto err_ctlreg; -@@ -274,17 +294,17 @@ static int sprom_do_write(struct ssb_bus - err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl); - if (err) - goto err_ctlreg; -- ssb_printk(KERN_NOTICE PFX "[ 0%%"); -+ ssb_notice("[ 0%%"); - msleep(500); - for (i = 0; i < size; i++) { - if (i == size / 4) -- ssb_printk("25%%"); -+ ssb_cont("25%%"); - else if (i == size / 2) -- ssb_printk("50%%"); -+ ssb_cont("50%%"); - else if (i == (size * 3) / 4) -- ssb_printk("75%%"); -+ ssb_cont("75%%"); - else if (i % 2) -- ssb_printk("."); -+ ssb_cont("."); - writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2)); - mmiowb(); - msleep(20); -@@ -297,12 +317,12 @@ static int sprom_do_write(struct ssb_bus - if (err) - goto err_ctlreg; - msleep(500); -- ssb_printk("100%% ]\n"); -- ssb_printk(KERN_NOTICE PFX "SPROM written.\n"); -+ ssb_cont("100%% ]\n"); -+ ssb_notice("SPROM written\n"); - - return 0; - err_ctlreg: -- ssb_printk(KERN_ERR PFX "Could not access SPROM control register.\n"); -+ ssb_err("Could not access SPROM control register.\n"); - return err; - } - -@@ -327,11 +347,23 @@ static s8 r123_extract_antgain(u8 sprom_ - return (s8)gain; - } - -+static void sprom_extract_r23(struct ssb_sprom *out, const u16 *in) -+{ -+ SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0); -+ SPEX(opo, SSB_SPROM2_OPO, SSB_SPROM2_OPO_VALUE, 0); -+ SPEX(pa1lob0, SSB_SPROM2_PA1LOB0, 0xFFFF, 0); -+ SPEX(pa1lob1, SSB_SPROM2_PA1LOB1, 0xFFFF, 0); -+ SPEX(pa1lob2, SSB_SPROM2_PA1LOB2, 0xFFFF, 0); -+ SPEX(pa1hib0, SSB_SPROM2_PA1HIB0, 0xFFFF, 0); -+ SPEX(pa1hib1, SSB_SPROM2_PA1HIB1, 0xFFFF, 0); -+ SPEX(pa1hib2, SSB_SPROM2_PA1HIB2, 0xFFFF, 0); -+ SPEX(maxpwr_ah, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_HI, 0); -+ SPEX(maxpwr_al, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_LO, -+ SSB_SPROM2_MAXP_A_LO_SHIFT); -+} -+ - static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) - { -- int i; -- u16 v; -- s8 gain; - u16 loc[3]; - - if (out->revision == 3) /* rev 3 moved MAC */ -@@ -341,19 +373,10 @@ static void sprom_extract_r123(struct ss - loc[1] = SSB_SPROM1_ET0MAC; - loc[2] = SSB_SPROM1_ET1MAC; - } -- for (i = 0; i < 3; i++) { -- v = in[SPOFF(loc[0]) + i]; -- *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); -- } -+ sprom_get_mac(out->il0mac, &in[SPOFF(loc[0])]); - if (out->revision < 3) { /* only rev 1-2 have et0, et1 */ -- for (i = 0; i < 3; i++) { -- v = in[SPOFF(loc[1]) + i]; -- *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v); -- } -- for (i = 0; i < 3; i++) { -- v = in[SPOFF(loc[2]) + i]; -- *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v); -- } -+ sprom_get_mac(out->et0mac, &in[SPOFF(loc[1])]); -+ sprom_get_mac(out->et1mac, &in[SPOFF(loc[2])]); - } - SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0); - SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A, -@@ -361,8 +384,10 @@ static void sprom_extract_r123(struct ss - SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14); - SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15); - SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0); -- SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE, -- SSB_SPROM1_BINF_CCODE_SHIFT); -+ SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0); -+ if (out->revision == 1) -+ SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE, -+ SSB_SPROM1_BINF_CCODE_SHIFT); - SPEX(ant_available_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA, - SSB_SPROM1_BINF_ANTA_SHIFT); - SPEX(ant_available_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG, -@@ -386,24 +411,19 @@ static void sprom_extract_r123(struct ss - SSB_SPROM1_ITSSI_A_SHIFT); - SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0); - SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0); -- if (out->revision >= 2) -- SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0); -+ -+ SPEX(alpha2[0], SSB_SPROM1_CCODE, 0xff00, 8); -+ SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0); - - /* Extract the antenna gain values. */ -- gain = r123_extract_antgain(out->revision, in, -- SSB_SPROM1_AGAIN_BG, -- SSB_SPROM1_AGAIN_BG_SHIFT); -- out->antenna_gain.ghz24.a0 = gain; -- out->antenna_gain.ghz24.a1 = gain; -- out->antenna_gain.ghz24.a2 = gain; -- out->antenna_gain.ghz24.a3 = gain; -- gain = r123_extract_antgain(out->revision, in, -- SSB_SPROM1_AGAIN_A, -- SSB_SPROM1_AGAIN_A_SHIFT); -- out->antenna_gain.ghz5.a0 = gain; -- out->antenna_gain.ghz5.a1 = gain; -- out->antenna_gain.ghz5.a2 = gain; -- out->antenna_gain.ghz5.a3 = gain; -+ out->antenna_gain.a0 = r123_extract_antgain(out->revision, in, -+ SSB_SPROM1_AGAIN_BG, -+ SSB_SPROM1_AGAIN_BG_SHIFT); -+ out->antenna_gain.a1 = r123_extract_antgain(out->revision, in, -+ SSB_SPROM1_AGAIN_A, -+ SSB_SPROM1_AGAIN_A_SHIFT); -+ if (out->revision >= 2) -+ sprom_extract_r23(out, in); - } - - /* Revs 4 5 and 8 have partially shared layout */ -@@ -448,30 +468,30 @@ static void sprom_extract_r458(struct ss - - static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) - { -- int i; -- u16 v; - u16 il0mac_offset; - - if (out->revision == 4) - il0mac_offset = SSB_SPROM4_IL0MAC; - else - il0mac_offset = SSB_SPROM5_IL0MAC; -- /* extract the MAC address */ -- for (i = 0; i < 3; i++) { -- v = in[SPOFF(il0mac_offset) + i]; -- *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); -- } -+ -+ sprom_get_mac(out->il0mac, &in[SPOFF(il0mac_offset)]); -+ - SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0); - SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A, - SSB_SPROM4_ETHPHY_ET1A_SHIFT); -+ SPEX(board_rev, SSB_SPROM4_BOARDREV, 0xFFFF, 0); -+ SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0); - if (out->revision == 4) { -- SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0); -+ SPEX(alpha2[0], SSB_SPROM4_CCODE, 0xff00, 8); -+ SPEX(alpha2[1], SSB_SPROM4_CCODE, 0x00ff, 0); - SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0); - SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0); - SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0); - SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0); - } else { -- SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0); -+ SPEX(alpha2[0], SSB_SPROM5_CCODE, 0xff00, 8); -+ SPEX(alpha2[1], SSB_SPROM5_CCODE, 0x00ff, 0); - SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0); - SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0); - SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0); -@@ -504,16 +524,14 @@ static void sprom_extract_r45(struct ssb - } - - /* Extract the antenna gain values. */ -- SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01, -+ SPEX(antenna_gain.a0, SSB_SPROM4_AGAIN01, - SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT); -- SPEX(antenna_gain.ghz24.a1, SSB_SPROM4_AGAIN01, -+ SPEX(antenna_gain.a1, SSB_SPROM4_AGAIN01, - SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT); -- SPEX(antenna_gain.ghz24.a2, SSB_SPROM4_AGAIN23, -+ SPEX(antenna_gain.a2, SSB_SPROM4_AGAIN23, - SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT); -- SPEX(antenna_gain.ghz24.a3, SSB_SPROM4_AGAIN23, -+ SPEX(antenna_gain.a3, SSB_SPROM4_AGAIN23, - SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT); -- memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24, -- sizeof(out->antenna_gain.ghz5)); - - sprom_extract_r458(out, in); - -@@ -523,14 +541,21 @@ static void sprom_extract_r45(struct ssb - static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) - { - int i; -- u16 v; -+ u16 o; -+ u16 pwr_info_offset[] = { -+ SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1, -+ SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3 -+ }; -+ BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) != -+ ARRAY_SIZE(out->core_pwr_info)); - - /* extract the MAC address */ -- for (i = 0; i < 3; i++) { -- v = in[SPOFF(SSB_SPROM8_IL0MAC) + i]; -- *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); -- } -- SPEX(country_code, SSB_SPROM8_CCODE, 0xFFFF, 0); -+ sprom_get_mac(out->il0mac, &in[SPOFF(SSB_SPROM8_IL0MAC)]); -+ -+ SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0); -+ SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0); -+ SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8); -+ SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0); - SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0); - SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0); - SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0); -@@ -596,16 +621,46 @@ static void sprom_extract_r8(struct ssb_ - SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0); - - /* Extract the antenna gain values. */ -- SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01, -+ SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01, - SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT); -- SPEX(antenna_gain.ghz24.a1, SSB_SPROM8_AGAIN01, -+ SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01, - SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT); -- SPEX(antenna_gain.ghz24.a2, SSB_SPROM8_AGAIN23, -+ SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23, - SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT); -- SPEX(antenna_gain.ghz24.a3, SSB_SPROM8_AGAIN23, -+ SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23, - SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT); -- memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24, -- sizeof(out->antenna_gain.ghz5)); -+ -+ /* Extract cores power info info */ -+ for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { -+ o = pwr_info_offset[i]; -+ SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI, -+ SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT); -+ SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI, -+ SSB_SPROM8_2G_MAXP, 0); -+ -+ SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0); -+ SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0); -+ SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0); -+ -+ SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI, -+ SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT); -+ SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI, -+ SSB_SPROM8_5G_MAXP, 0); -+ SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP, -+ SSB_SPROM8_5GH_MAXP, 0); -+ SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP, -+ SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT); -+ -+ SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0); -+ SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0); -+ } - - /* Extract FEM info */ - SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, -@@ -630,6 +685,63 @@ static void sprom_extract_r8(struct ssb_ - SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, - SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT); - -+ SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON, -+ SSB_SPROM8_LEDDC_ON_SHIFT); -+ SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF, -+ SSB_SPROM8_LEDDC_OFF_SHIFT); -+ -+ SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN, -+ SSB_SPROM8_TXRXC_TXCHAIN_SHIFT); -+ SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN, -+ SSB_SPROM8_TXRXC_RXCHAIN_SHIFT); -+ SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH, -+ SSB_SPROM8_TXRXC_SWITCH_SHIFT); -+ -+ SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0); -+ -+ SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0); -+ SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0); -+ SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0); -+ SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0); -+ -+ SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP, -+ SSB_SPROM8_RAWTS_RAWTEMP_SHIFT); -+ SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER, -+ SSB_SPROM8_RAWTS_MEASPOWER_SHIFT); -+ SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX, -+ SSB_SPROM8_OPT_CORRX_TEMP_SLOPE, -+ SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT); -+ SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX, -+ SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT); -+ SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX, -+ SSB_SPROM8_OPT_CORRX_TEMP_OPTION, -+ SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT); -+ SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP, -+ SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR, -+ SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT); -+ SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP, -+ SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP, -+ SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT); -+ SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL, -+ SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT); -+ -+ SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0); -+ SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0); -+ SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0); -+ SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0); -+ -+ SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH, -+ SSB_SPROM8_THERMAL_TRESH_SHIFT); -+ SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET, -+ SSB_SPROM8_THERMAL_OFFSET_SHIFT); -+ SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA, -+ SSB_SPROM8_TEMPDELTA_PHYCAL, -+ SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT); -+ SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD, -+ SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT); -+ SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA, -+ SSB_SPROM8_TEMPDELTA_HYSTERESIS, -+ SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT); - sprom_extract_r458(out, in); - - /* TODO - get remaining rev 8 stuff needed */ -@@ -641,7 +753,7 @@ static int sprom_extract(struct ssb_bus - memset(out, 0, sizeof(*out)); - - out->revision = in[size - 1] & 0x00FF; -- ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision); -+ ssb_dbg("SPROM revision %d detected\n", out->revision); - memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */ - memset(out->et1mac, 0xFF, 6); - -@@ -650,7 +762,7 @@ static int sprom_extract(struct ssb_bus - * number stored in the SPROM. - * Always extract r1. */ - out->revision = 1; -- ssb_dprintk(KERN_DEBUG PFX "SPROM treated as revision %d\n", out->revision); -+ ssb_dbg("SPROM treated as revision %d\n", out->revision); - } - - switch (out->revision) { -@@ -667,9 +779,8 @@ static int sprom_extract(struct ssb_bus - sprom_extract_r8(out, in); - break; - default: -- ssb_printk(KERN_WARNING PFX "Unsupported SPROM" -- " revision %d detected. Will extract" -- " v1\n", out->revision); -+ ssb_warn("Unsupported SPROM revision %d detected. Will extract v1\n", -+ out->revision); - out->revision = 1; - sprom_extract_r123(out, in); - } -@@ -689,7 +800,7 @@ static int ssb_pci_sprom_get(struct ssb_ - u16 *buf; - - if (!ssb_is_sprom_available(bus)) { -- ssb_printk(KERN_ERR PFX "No SPROM available!\n"); -+ ssb_err("No SPROM available!\n"); - return -ENODEV; - } - if (bus->chipco.dev) { /* can be unavailable! */ -@@ -708,7 +819,7 @@ static int ssb_pci_sprom_get(struct ssb_ - } else { - bus->sprom_offset = SSB_SPROM_BASE1; - } -- ssb_dprintk(KERN_INFO PFX "SPROM offset is 0x%x\n", bus->sprom_offset); -+ ssb_dbg("SPROM offset is 0x%x\n", bus->sprom_offset); - - buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); - if (!buf) -@@ -733,18 +844,15 @@ static int ssb_pci_sprom_get(struct ssb_ - * available for this device in some other storage */ - err = ssb_fill_sprom_with_fallback(bus, sprom); - if (err) { -- ssb_printk(KERN_WARNING PFX "WARNING: Using" -- " fallback SPROM failed (err %d)\n", -- err); -+ ssb_warn("WARNING: Using fallback SPROM failed (err %d)\n", -+ err); - } else { -- ssb_dprintk(KERN_DEBUG PFX "Using SPROM" -- " revision %d provided by" -- " platform.\n", sprom->revision); -+ ssb_dbg("Using SPROM revision %d provided by platform\n", -+ sprom->revision); - err = 0; - goto out_free; - } -- ssb_printk(KERN_WARNING PFX "WARNING: Invalid" -- " SPROM CRC (corrupt SPROM)\n"); -+ ssb_warn("WARNING: Invalid SPROM CRC (corrupt SPROM)\n"); - } - } - err = sprom_extract(bus, sprom, buf, bus->sprom_size); -@@ -759,7 +867,6 @@ static void ssb_pci_get_boardinfo(struct - { - bi->vendor = bus->host_pci->subsystem_vendor; - bi->type = bus->host_pci->subsystem_device; -- bi->rev = bus->host_pci->revision; - } - - int ssb_pci_get_invariants(struct ssb_bus *bus, ---- a/drivers/ssb/pcihost_wrapper.c -+++ b/drivers/ssb/pcihost_wrapper.c -@@ -38,7 +38,7 @@ static int ssb_pcihost_resume(struct pci - struct ssb_bus *ssb = pci_get_drvdata(dev); - int err; - -- pci_set_power_state(dev, 0); -+ pci_set_power_state(dev, PCI_D0); - err = pci_enable_device(dev); - if (err) - return err; ---- a/drivers/ssb/pcmcia.c -+++ b/drivers/ssb/pcmcia.c -@@ -143,7 +143,7 @@ int ssb_pcmcia_switch_coreidx(struct ssb - - return 0; - error: -- ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx); -+ ssb_err("Failed to switch to core %u\n", coreidx); - return err; - } - -@@ -153,10 +153,9 @@ int ssb_pcmcia_switch_core(struct ssb_bu - int err; - - #if SSB_VERBOSE_PCMCIACORESWITCH_DEBUG -- ssb_printk(KERN_INFO PFX -- "Switching to %s core, index %d\n", -- ssb_core_name(dev->id.coreid), -- dev->core_index); -+ ssb_info("Switching to %s core, index %d\n", -+ ssb_core_name(dev->id.coreid), -+ dev->core_index); - #endif - - err = ssb_pcmcia_switch_coreidx(bus, dev->core_index); -@@ -192,7 +191,7 @@ int ssb_pcmcia_switch_segment(struct ssb - - return 0; - error: -- ssb_printk(KERN_ERR PFX "Failed to switch pcmcia segment\n"); -+ ssb_err("Failed to switch pcmcia segment\n"); - return err; - } - -@@ -549,44 +548,39 @@ static int ssb_pcmcia_sprom_write_all(st - bool failed = 0; - size_t size = SSB_PCMCIA_SPROM_SIZE; - -- ssb_printk(KERN_NOTICE PFX -- "Writing SPROM. Do NOT turn off the power! " -- "Please stand by...\n"); -+ ssb_notice("Writing SPROM. Do NOT turn off the power! Please stand by...\n"); - err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEEN); - if (err) { -- ssb_printk(KERN_NOTICE PFX -- "Could not enable SPROM write access.\n"); -+ ssb_notice("Could not enable SPROM write access\n"); - return -EBUSY; - } -- ssb_printk(KERN_NOTICE PFX "[ 0%%"); -+ ssb_notice("[ 0%%"); - msleep(500); - for (i = 0; i < size; i++) { - if (i == size / 4) -- ssb_printk("25%%"); -+ ssb_cont("25%%"); - else if (i == size / 2) -- ssb_printk("50%%"); -+ ssb_cont("50%%"); - else if (i == (size * 3) / 4) -- ssb_printk("75%%"); -+ ssb_cont("75%%"); - else if (i % 2) -- ssb_printk("."); -+ ssb_cont("."); - err = ssb_pcmcia_sprom_write(bus, i, sprom[i]); - if (err) { -- ssb_printk(KERN_NOTICE PFX -- "Failed to write to SPROM.\n"); -+ ssb_notice("Failed to write to SPROM\n"); - failed = 1; - break; - } - } - err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEDIS); - if (err) { -- ssb_printk(KERN_NOTICE PFX -- "Could not disable SPROM write access.\n"); -+ ssb_notice("Could not disable SPROM write access\n"); - failed = 1; - } - msleep(500); - if (!failed) { -- ssb_printk("100%% ]\n"); -- ssb_printk(KERN_NOTICE PFX "SPROM written.\n"); -+ ssb_cont("100%% ]\n"); -+ ssb_notice("SPROM written\n"); - } - - return failed ? -EBUSY : 0; -@@ -676,14 +670,10 @@ static int ssb_pcmcia_do_get_invariants( - case SSB_PCMCIA_CIS_ANTGAIN: - GOTO_ERROR_ON(tuple->TupleDataLen != 2, - "antg tpl size"); -- sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1]; -- sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1]; -- sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1]; -- sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1]; -- sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1]; -- sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1]; -- sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1]; -- sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1]; -+ sprom->antenna_gain.a0 = tuple->TupleData[1]; -+ sprom->antenna_gain.a1 = tuple->TupleData[1]; -+ sprom->antenna_gain.a2 = tuple->TupleData[1]; -+ sprom->antenna_gain.a3 = tuple->TupleData[1]; - break; - case SSB_PCMCIA_CIS_BFLAGS: - GOTO_ERROR_ON((tuple->TupleDataLen != 3) && -@@ -704,7 +694,7 @@ static int ssb_pcmcia_do_get_invariants( - return -ENOSPC; /* continue with next entry */ - - error: -- ssb_printk(KERN_ERR PFX -+ ssb_err( - "PCMCIA: Failed to fetch device invariants: %s\n", - error_description); - return -ENODEV; -@@ -726,7 +716,7 @@ int ssb_pcmcia_get_invariants(struct ssb - res = pcmcia_loop_tuple(bus->host_pcmcia, CISTPL_FUNCE, - ssb_pcmcia_get_mac, sprom); - if (res != 0) { -- ssb_printk(KERN_ERR PFX -+ ssb_err( - "PCMCIA: Failed to fetch MAC address\n"); - return -ENODEV; - } -@@ -737,7 +727,7 @@ int ssb_pcmcia_get_invariants(struct ssb - if ((res == 0) || (res == -ENOSPC)) - return 0; - -- ssb_printk(KERN_ERR PFX -+ ssb_err( - "PCMCIA: Failed to fetch device invariants\n"); - return -ENODEV; - } -@@ -847,6 +837,6 @@ int ssb_pcmcia_init(struct ssb_bus *bus) - - return 0; - error: -- ssb_printk(KERN_ERR PFX "Failed to initialize PCMCIA host device\n"); -+ ssb_err("Failed to initialize PCMCIA host device\n"); - return err; - } ---- a/drivers/ssb/scan.c -+++ b/drivers/ssb/scan.c -@@ -90,6 +90,8 @@ const char *ssb_core_name(u16 coreid) - return "ARM 1176"; - case SSB_DEV_ARM_7TDMI: - return "ARM 7TDMI"; -+ case SSB_DEV_ARM_CM3: -+ return "ARM Cortex M3"; - } - return "UNKNOWN"; - } -@@ -123,8 +125,7 @@ static u16 pcidev_to_chipid(struct pci_d - chipid_fallback = 0x4401; - break; - default: -- ssb_printk(KERN_ERR PFX -- "PCI-ID not in fallback list\n"); -+ ssb_err("PCI-ID not in fallback list\n"); - } - - return chipid_fallback; -@@ -150,8 +151,7 @@ static u8 chipid_to_nrcores(u16 chipid) - case 0x4704: - return 9; - default: -- ssb_printk(KERN_ERR PFX -- "CHIPID not in nrcores fallback list\n"); -+ ssb_err("CHIPID not in nrcores fallback list\n"); - } - - return 1; -@@ -318,12 +318,13 @@ int ssb_bus_scan(struct ssb_bus *bus, - bus->chip_package = 0; - } - } -+ ssb_info("Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n", -+ bus->chip_id, bus->chip_rev, bus->chip_package); - if (!bus->nr_devices) - bus->nr_devices = chipid_to_nrcores(bus->chip_id); - if (bus->nr_devices > ARRAY_SIZE(bus->devices)) { -- ssb_printk(KERN_ERR PFX -- "More than %d ssb cores found (%d)\n", -- SSB_MAX_NR_CORES, bus->nr_devices); -+ ssb_err("More than %d ssb cores found (%d)\n", -+ SSB_MAX_NR_CORES, bus->nr_devices); - goto err_unmap; - } - if (bus->bustype == SSB_BUSTYPE_SSB) { -@@ -365,8 +366,7 @@ int ssb_bus_scan(struct ssb_bus *bus, - nr_80211_cores++; - if (nr_80211_cores > 1) { - if (!we_support_multiple_80211_cores(bus)) { -- ssb_dprintk(KERN_INFO PFX "Ignoring additional " -- "802.11 core\n"); -+ ssb_dbg("Ignoring additional 802.11 core\n"); - continue; - } - } -@@ -374,8 +374,7 @@ int ssb_bus_scan(struct ssb_bus *bus, - case SSB_DEV_EXTIF: - #ifdef CONFIG_SSB_DRIVER_EXTIF - if (bus->extif.dev) { -- ssb_printk(KERN_WARNING PFX -- "WARNING: Multiple EXTIFs found\n"); -+ ssb_warn("WARNING: Multiple EXTIFs found\n"); - break; - } - bus->extif.dev = dev; -@@ -383,8 +382,7 @@ int ssb_bus_scan(struct ssb_bus *bus, - break; - case SSB_DEV_CHIPCOMMON: - if (bus->chipco.dev) { -- ssb_printk(KERN_WARNING PFX -- "WARNING: Multiple ChipCommon found\n"); -+ ssb_warn("WARNING: Multiple ChipCommon found\n"); - break; - } - bus->chipco.dev = dev; -@@ -393,8 +391,7 @@ int ssb_bus_scan(struct ssb_bus *bus, - case SSB_DEV_MIPS_3302: - #ifdef CONFIG_SSB_DRIVER_MIPS - if (bus->mipscore.dev) { -- ssb_printk(KERN_WARNING PFX -- "WARNING: Multiple MIPS cores found\n"); -+ ssb_warn("WARNING: Multiple MIPS cores found\n"); - break; - } - bus->mipscore.dev = dev; -@@ -415,8 +412,7 @@ int ssb_bus_scan(struct ssb_bus *bus, - } - } - if (bus->pcicore.dev) { -- ssb_printk(KERN_WARNING PFX -- "WARNING: Multiple PCI(E) cores found\n"); -+ ssb_warn("WARNING: Multiple PCI(E) cores found\n"); - break; - } - bus->pcicore.dev = dev; ---- a/drivers/ssb/sdio.c -+++ b/drivers/ssb/sdio.c -@@ -551,14 +551,10 @@ int ssb_sdio_get_invariants(struct ssb_b - case SSB_SDIO_CIS_ANTGAIN: - GOTO_ERROR_ON(tuple->size != 2, - "antg tpl size"); -- sprom->antenna_gain.ghz24.a0 = tuple->data[1]; -- sprom->antenna_gain.ghz24.a1 = tuple->data[1]; -- sprom->antenna_gain.ghz24.a2 = tuple->data[1]; -- sprom->antenna_gain.ghz24.a3 = tuple->data[1]; -- sprom->antenna_gain.ghz5.a0 = tuple->data[1]; -- sprom->antenna_gain.ghz5.a1 = tuple->data[1]; -- sprom->antenna_gain.ghz5.a2 = tuple->data[1]; -- sprom->antenna_gain.ghz5.a3 = tuple->data[1]; -+ sprom->antenna_gain.a0 = tuple->data[1]; -+ sprom->antenna_gain.a1 = tuple->data[1]; -+ sprom->antenna_gain.a2 = tuple->data[1]; -+ sprom->antenna_gain.a3 = tuple->data[1]; - break; - case SSB_SDIO_CIS_BFLAGS: - GOTO_ERROR_ON((tuple->size != 3) && ---- a/drivers/ssb/sprom.c -+++ b/drivers/ssb/sprom.c -@@ -54,7 +54,7 @@ static int hex2sprom(u16 *sprom, const c - while (cnt < sprom_size_words) { - memcpy(tmp, dump, 4); - dump += 4; -- err = strict_strtoul(tmp, 16, &parsed); -+ err = kstrtoul(tmp, 16, &parsed); - if (err) - return err; - sprom[cnt++] = swab16((u16)parsed); -@@ -127,13 +127,13 @@ ssize_t ssb_attr_sprom_store(struct ssb_ - goto out_kfree; - err = ssb_devices_freeze(bus, &freeze); - if (err) { -- ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze all devices\n"); -+ ssb_err("SPROM write: Could not freeze all devices\n"); - goto out_unlock; - } - res = sprom_write(bus, sprom); - err = ssb_devices_thaw(&freeze); - if (err) -- ssb_printk(KERN_ERR PFX "SPROM write: Could not thaw all devices\n"); -+ ssb_err("SPROM write: Could not thaw all devices\n"); - out_unlock: - mutex_unlock(&bus->sprom_mutex); - out_kfree: ---- a/drivers/ssb/ssb_private.h -+++ b/drivers/ssb/ssb_private.h -@@ -3,21 +3,33 @@ - - #include <linux/ssb/ssb.h> - #include <linux/types.h> -+#include <linux/bcm47xx_wdt.h> - - - #define PFX "ssb: " - - #ifdef CONFIG_SSB_SILENT --# define ssb_printk(fmt, x...) do { /* nothing */ } while (0) -+# define ssb_printk(fmt, ...) \ -+ do { if (0) printk(fmt, ##__VA_ARGS__); } while (0) - #else --# define ssb_printk printk -+# define ssb_printk(fmt, ...) \ -+ printk(fmt, ##__VA_ARGS__) - #endif /* CONFIG_SSB_SILENT */ - -+#define ssb_emerg(fmt, ...) ssb_printk(KERN_EMERG PFX fmt, ##__VA_ARGS__) -+#define ssb_err(fmt, ...) ssb_printk(KERN_ERR PFX fmt, ##__VA_ARGS__) -+#define ssb_warn(fmt, ...) ssb_printk(KERN_WARNING PFX fmt, ##__VA_ARGS__) -+#define ssb_notice(fmt, ...) ssb_printk(KERN_NOTICE PFX fmt, ##__VA_ARGS__) -+#define ssb_info(fmt, ...) ssb_printk(KERN_INFO PFX fmt, ##__VA_ARGS__) -+#define ssb_cont(fmt, ...) ssb_printk(KERN_CONT fmt, ##__VA_ARGS__) -+ - /* dprintk: Debugging printk; vanishes for non-debug compilation */ - #ifdef CONFIG_SSB_DEBUG --# define ssb_dprintk(fmt, x...) ssb_printk(fmt , ##x) -+# define ssb_dbg(fmt, ...) \ -+ ssb_printk(KERN_DEBUG PFX fmt, ##__VA_ARGS__) - #else --# define ssb_dprintk(fmt, x...) do { /* nothing */ } while (0) -+# define ssb_dbg(fmt, ...) \ -+ do { if (0) printk(KERN_DEBUG PFX fmt, ##__VA_ARGS__); } while (0) - #endif - - #ifdef CONFIG_SSB_DEBUG -@@ -207,4 +219,79 @@ static inline void b43_pci_ssb_bridge_ex - } - #endif /* CONFIG_SSB_B43_PCI_BRIDGE */ - -+/* driver_chipcommon_pmu.c */ -+extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc); -+extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc); -+extern u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc); -+ -+extern u32 ssb_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, -+ u32 ticks); -+extern u32 ssb_chipco_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms); -+ -+/* driver_chipcommon_sflash.c */ -+#ifdef CONFIG_SSB_SFLASH -+int ssb_sflash_init(struct ssb_chipcommon *cc); -+#else -+static inline int ssb_sflash_init(struct ssb_chipcommon *cc) -+{ -+ pr_err("Serial flash not supported\n"); -+ return 0; -+} -+#endif /* CONFIG_SSB_SFLASH */ -+ -+#ifdef CONFIG_SSB_DRIVER_MIPS -+extern struct platform_device ssb_pflash_dev; -+#endif -+ -+#ifdef CONFIG_SSB_SFLASH -+extern struct platform_device ssb_sflash_dev; -+#endif -+ -+#ifdef CONFIG_SSB_DRIVER_EXTIF -+extern u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks); -+extern u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms); -+#else -+static inline u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, -+ u32 ticks) -+{ -+ return 0; -+} -+static inline u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, -+ u32 ms) -+{ -+ return 0; -+} -+#endif -+ -+#ifdef CONFIG_SSB_EMBEDDED -+extern int ssb_watchdog_register(struct ssb_bus *bus); -+#else /* CONFIG_SSB_EMBEDDED */ -+static inline int ssb_watchdog_register(struct ssb_bus *bus) -+{ -+ return 0; -+} -+#endif /* CONFIG_SSB_EMBEDDED */ -+ -+#ifdef CONFIG_SSB_DRIVER_EXTIF -+extern void ssb_extif_init(struct ssb_extif *extif); -+#else -+static inline void ssb_extif_init(struct ssb_extif *extif) -+{ -+} -+#endif -+ -+#ifdef CONFIG_SSB_DRIVER_GPIO -+extern int ssb_gpio_init(struct ssb_bus *bus); -+extern int ssb_gpio_unregister(struct ssb_bus *bus); -+#else /* CONFIG_SSB_DRIVER_GPIO */ -+static inline int ssb_gpio_init(struct ssb_bus *bus) -+{ -+ return -ENOTSUPP; -+} -+static inline int ssb_gpio_unregister(struct ssb_bus *bus) -+{ -+ return 0; -+} -+#endif /* CONFIG_SSB_DRIVER_GPIO */ -+ - #endif /* LINUX_SSB_PRIVATE_H_ */ ---- a/include/linux/ssb/ssb.h -+++ b/include/linux/ssb/ssb.h -@@ -6,8 +6,10 @@ - #include <linux/types.h> - #include <linux/spinlock.h> - #include <linux/pci.h> -+#include <linux/gpio.h> - #include <linux/mod_devicetable.h> - #include <linux/dma-mapping.h> -+#include <linux/platform_device.h> - - #include <linux/ssb/ssb_regs.h> - -@@ -16,19 +18,29 @@ struct pcmcia_device; - struct ssb_bus; - struct ssb_driver; - -+struct ssb_sprom_core_pwr_info { -+ u8 itssi_2g, itssi_5g; -+ u8 maxpwr_2g, maxpwr_5gl, maxpwr_5g, maxpwr_5gh; -+ u16 pa_2g[4], pa_5gl[4], pa_5g[4], pa_5gh[4]; -+}; -+ - struct ssb_sprom { - u8 revision; -- u8 il0mac[6]; /* MAC address for 802.11b/g */ -- u8 et0mac[6]; /* MAC address for Ethernet */ -- u8 et1mac[6]; /* MAC address for 802.11a */ -+ u8 il0mac[6] __aligned(sizeof(u16)); /* MAC address for 802.11b/g */ -+ u8 et0mac[6] __aligned(sizeof(u16)); /* MAC address for Ethernet */ -+ u8 et1mac[6] __aligned(sizeof(u16)); /* MAC address for 802.11a */ - u8 et0phyaddr; /* MII address for enet0 */ - u8 et1phyaddr; /* MII address for enet1 */ - u8 et0mdcport; /* MDIO for enet0 */ - u8 et1mdcport; /* MDIO for enet1 */ -+ u16 dev_id; /* Device ID overriding e.g. PCI ID */ - u16 board_rev; /* Board revision number from SPROM. */ -+ u16 board_num; /* Board number from SPROM. */ -+ u16 board_type; /* Board type from SPROM. */ - u8 country_code; /* Country Code */ -- u16 leddc_on_time; /* LED Powersave Duty Cycle On Count */ -- u16 leddc_off_time; /* LED Powersave Duty Cycle Off Count */ -+ char alpha2[2]; /* Country Code as two chars like EU or US */ -+ u8 leddc_on_time; /* LED Powersave Duty Cycle On Count */ -+ u8 leddc_off_time; /* LED Powersave Duty Cycle Off Count */ - u8 ant_available_a; /* 2GHz antenna available bits (up to 4) */ - u8 ant_available_bg; /* 5GHz antenna available bits (up to 4) */ - u16 pa0b0; -@@ -47,10 +59,10 @@ struct ssb_sprom { - u8 gpio1; /* GPIO pin 1 */ - u8 gpio2; /* GPIO pin 2 */ - u8 gpio3; /* GPIO pin 3 */ -- u16 maxpwr_bg; /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */ -- u16 maxpwr_al; /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */ -- u16 maxpwr_a; /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */ -- u16 maxpwr_ah; /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */ -+ u8 maxpwr_bg; /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */ -+ u8 maxpwr_al; /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */ -+ u8 maxpwr_a; /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */ -+ u8 maxpwr_ah; /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */ - u8 itssi_a; /* Idle TSSI Target for A-PHY */ - u8 itssi_bg; /* Idle TSSI Target for B/G-PHY */ - u8 tri2g; /* 2.4GHz TX isolation */ -@@ -61,8 +73,8 @@ struct ssb_sprom { - u8 txpid5gl[4]; /* 4.9 - 5.1GHz TX power index */ - u8 txpid5g[4]; /* 5.1 - 5.5GHz TX power index */ - u8 txpid5gh[4]; /* 5.5 - ...GHz TX power index */ -- u8 rxpo2g; /* 2GHz RX power offset */ -- u8 rxpo5g; /* 5GHz RX power offset */ -+ s8 rxpo2g; /* 2GHz RX power offset */ -+ s8 rxpo5g; /* 5GHz RX power offset */ - u8 rssisav2g; /* 2GHz RSSI params */ - u8 rssismc2g; - u8 rssismf2g; -@@ -82,16 +94,13 @@ struct ssb_sprom { - u16 boardflags2_hi; /* Board flags (bits 48-63) */ - /* TODO store board flags in a single u64 */ - -+ struct ssb_sprom_core_pwr_info core_pwr_info[4]; -+ - /* Antenna gain values for up to 4 antennas - * on each band. Values in dBm/4 (Q5.2). Negative gain means the - * loss in the connectors is bigger than the gain. */ - struct { -- struct { -- s8 a0, a1, a2, a3; -- } ghz24; /* 2.4GHz band */ -- struct { -- s8 a0, a1, a2, a3; -- } ghz5; /* 5GHz band */ -+ s8 a0, a1, a2, a3; - } antenna_gain; - - struct { -@@ -103,14 +112,85 @@ struct ssb_sprom { - } ghz5; - } fem; - -- /* TODO - add any parameters needed from rev 2, 3, 4, 5 or 8 SPROMs */ -+ u16 mcs2gpo[8]; -+ u16 mcs5gpo[8]; -+ u16 mcs5glpo[8]; -+ u16 mcs5ghpo[8]; -+ u8 opo; -+ -+ u8 rxgainerr2ga[3]; -+ u8 rxgainerr5gla[3]; -+ u8 rxgainerr5gma[3]; -+ u8 rxgainerr5gha[3]; -+ u8 rxgainerr5gua[3]; -+ -+ u8 noiselvl2ga[3]; -+ u8 noiselvl5gla[3]; -+ u8 noiselvl5gma[3]; -+ u8 noiselvl5gha[3]; -+ u8 noiselvl5gua[3]; -+ -+ u8 regrev; -+ u8 txchain; -+ u8 rxchain; -+ u8 antswitch; -+ u16 cddpo; -+ u16 stbcpo; -+ u16 bw40po; -+ u16 bwduppo; -+ -+ u8 tempthresh; -+ u8 tempoffset; -+ u16 rawtempsense; -+ u8 measpower; -+ u8 tempsense_slope; -+ u8 tempcorrx; -+ u8 tempsense_option; -+ u8 freqoffset_corr; -+ u8 iqcal_swp_dis; -+ u8 hw_iqcal_en; -+ u8 elna2g; -+ u8 elna5g; -+ u8 phycal_tempdelta; -+ u8 temps_period; -+ u8 temps_hysteresis; -+ u8 measpower1; -+ u8 measpower2; -+ u8 pcieingress_war; -+ -+ /* power per rate from sromrev 9 */ -+ u16 cckbw202gpo; -+ u16 cckbw20ul2gpo; -+ u32 legofdmbw202gpo; -+ u32 legofdmbw20ul2gpo; -+ u32 legofdmbw205glpo; -+ u32 legofdmbw20ul5glpo; -+ u32 legofdmbw205gmpo; -+ u32 legofdmbw20ul5gmpo; -+ u32 legofdmbw205ghpo; -+ u32 legofdmbw20ul5ghpo; -+ u32 mcsbw202gpo; -+ u32 mcsbw20ul2gpo; -+ u32 mcsbw402gpo; -+ u32 mcsbw205glpo; -+ u32 mcsbw20ul5glpo; -+ u32 mcsbw405glpo; -+ u32 mcsbw205gmpo; -+ u32 mcsbw20ul5gmpo; -+ u32 mcsbw405gmpo; -+ u32 mcsbw205ghpo; -+ u32 mcsbw20ul5ghpo; -+ u32 mcsbw405ghpo; -+ u16 mcs32po; -+ u16 legofdm40duppo; -+ u8 sar2g; -+ u8 sar5g; - }; - - /* Information about the PCB the circuitry is soldered on. */ - struct ssb_boardinfo { - u16 vendor; - u16 type; -- u8 rev; - }; - - -@@ -166,6 +246,7 @@ struct ssb_bus_ops { - #define SSB_DEV_MINI_MACPHY 0x823 - #define SSB_DEV_ARM_1176 0x824 - #define SSB_DEV_ARM_7TDMI 0x825 -+#define SSB_DEV_ARM_CM3 0x82A - - /* Vendor-ID values */ - #define SSB_VENDOR_BROADCOM 0x4243 -@@ -260,13 +341,61 @@ enum ssb_bustype { - #define SSB_BOARDVENDOR_DELL 0x1028 /* Dell */ - #define SSB_BOARDVENDOR_HP 0x0E11 /* HP */ - /* board_type */ -+#define SSB_BOARD_BCM94301CB 0x0406 -+#define SSB_BOARD_BCM94301MP 0x0407 -+#define SSB_BOARD_BU4309 0x040A -+#define SSB_BOARD_BCM94309CB 0x040B -+#define SSB_BOARD_BCM4309MP 0x040C -+#define SSB_BOARD_BU4306 0x0416 - #define SSB_BOARD_BCM94306MP 0x0418 - #define SSB_BOARD_BCM4309G 0x0421 - #define SSB_BOARD_BCM4306CB 0x0417 --#define SSB_BOARD_BCM4309MP 0x040C -+#define SSB_BOARD_BCM94306PC 0x0425 /* pcmcia 3.3v 4306 card */ -+#define SSB_BOARD_BCM94306CBSG 0x042B /* with SiGe PA */ -+#define SSB_BOARD_PCSG94306 0x042D /* with SiGe PA */ -+#define SSB_BOARD_BU4704SD 0x042E /* with sdram */ -+#define SSB_BOARD_BCM94704AGR 0x042F /* dual 11a/11g Router */ -+#define SSB_BOARD_BCM94308MP 0x0430 /* 11a-only minipci */ -+#define SSB_BOARD_BU4318 0x0447 -+#define SSB_BOARD_CB4318 0x0448 -+#define SSB_BOARD_MPG4318 0x0449 - #define SSB_BOARD_MP4318 0x044A --#define SSB_BOARD_BU4306 0x0416 --#define SSB_BOARD_BU4309 0x040A -+#define SSB_BOARD_SD4318 0x044B -+#define SSB_BOARD_BCM94306P 0x044C /* with SiGe */ -+#define SSB_BOARD_BCM94303MP 0x044E -+#define SSB_BOARD_BCM94306MPM 0x0450 -+#define SSB_BOARD_BCM94306MPL 0x0453 -+#define SSB_BOARD_PC4303 0x0454 /* pcmcia */ -+#define SSB_BOARD_BCM94306MPLNA 0x0457 -+#define SSB_BOARD_BCM94306MPH 0x045B -+#define SSB_BOARD_BCM94306PCIV 0x045C -+#define SSB_BOARD_BCM94318MPGH 0x0463 -+#define SSB_BOARD_BU4311 0x0464 -+#define SSB_BOARD_BCM94311MC 0x0465 -+#define SSB_BOARD_BCM94311MCAG 0x0466 -+/* 4321 boards */ -+#define SSB_BOARD_BU4321 0x046B -+#define SSB_BOARD_BU4321E 0x047C -+#define SSB_BOARD_MP4321 0x046C -+#define SSB_BOARD_CB2_4321 0x046D -+#define SSB_BOARD_CB2_4321_AG 0x0066 -+#define SSB_BOARD_MC4321 0x046E -+/* 4325 boards */ -+#define SSB_BOARD_BCM94325DEVBU 0x0490 -+#define SSB_BOARD_BCM94325BGABU 0x0491 -+#define SSB_BOARD_BCM94325SDGWB 0x0492 -+#define SSB_BOARD_BCM94325SDGMDL 0x04AA -+#define SSB_BOARD_BCM94325SDGMDL2 0x04C6 -+#define SSB_BOARD_BCM94325SDGMDL3 0x04C9 -+#define SSB_BOARD_BCM94325SDABGWBA 0x04E1 -+/* 4322 boards */ -+#define SSB_BOARD_BCM94322MC 0x04A4 -+#define SSB_BOARD_BCM94322USB 0x04A8 /* dualband */ -+#define SSB_BOARD_BCM94322HM 0x04B0 -+#define SSB_BOARD_BCM94322USB2D 0x04Bf /* single band discrete front end */ -+/* 4312 boards */ -+#define SSB_BOARD_BU4312 0x048A -+#define SSB_BOARD_BCM4312MCGSG 0x04B5 - /* chip_package */ - #define SSB_CHIPPACK_BCM4712S 1 /* Small 200pin 4712 */ - #define SSB_CHIPPACK_BCM4712M 2 /* Medium 225pin 4712 */ -@@ -354,7 +483,11 @@ struct ssb_bus { - #ifdef CONFIG_SSB_EMBEDDED - /* Lock for GPIO register access. */ - spinlock_t gpio_lock; -+ struct platform_device *watchdog; - #endif /* EMBEDDED */ -+#ifdef CONFIG_SSB_DRIVER_GPIO -+ struct gpio_chip gpio; -+#endif /* DRIVER_GPIO */ - - /* Internal-only stuff follows. Do not touch. */ - struct list_head list; ---- a/include/linux/ssb/ssb_driver_chipcommon.h -+++ b/include/linux/ssb/ssb_driver_chipcommon.h -@@ -219,6 +219,7 @@ - #define SSB_CHIPCO_PMU_CTL 0x0600 /* PMU control */ - #define SSB_CHIPCO_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */ - #define SSB_CHIPCO_PMU_CTL_ILP_DIV_SHIFT 16 -+#define SSB_CHIPCO_PMU_CTL_PLL_UPD 0x00000400 - #define SSB_CHIPCO_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */ - #define SSB_CHIPCO_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */ - #define SSB_CHIPCO_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */ -@@ -504,7 +505,9 @@ - #define SSB_CHIPCO_FLASHCTL_ST_SE 0x02D8 /* Sector Erase */ - #define SSB_CHIPCO_FLASHCTL_ST_BE 0x00C7 /* Bulk Erase */ - #define SSB_CHIPCO_FLASHCTL_ST_DP 0x00B9 /* Deep Power-down */ --#define SSB_CHIPCO_FLASHCTL_ST_RSIG 0x03AB /* Read Electronic Signature */ -+#define SSB_CHIPCO_FLASHCTL_ST_RES 0x03AB /* Read Electronic Signature */ -+#define SSB_CHIPCO_FLASHCTL_ST_CSA 0x1000 /* Keep chip select asserted */ -+#define SSB_CHIPCO_FLASHCTL_ST_SSE 0x0220 /* Sub-sector Erase */ - - /* Status register bits for ST flashes */ - #define SSB_CHIPCO_FLASHSTA_ST_WIP 0x01 /* Write In Progress */ -@@ -588,7 +591,10 @@ struct ssb_chipcommon { - u32 status; - /* Fast Powerup Delay constant */ - u16 fast_pwrup_delay; -+ spinlock_t gpio_lock; - struct ssb_chipcommon_pmu pmu; -+ u32 ticks_per_ms; -+ u32 max_timer_ms; - }; - - static inline bool ssb_chipco_available(struct ssb_chipcommon *cc) -@@ -628,8 +634,7 @@ enum ssb_clkmode { - extern void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc, - enum ssb_clkmode mode); - --extern void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, -- u32 ticks); -+extern u32 ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks); - - void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value); - -@@ -642,6 +647,8 @@ u32 ssb_chipco_gpio_outen(struct ssb_chi - u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value); - u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value); - u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value); -+u32 ssb_chipco_gpio_pullup(struct ssb_chipcommon *cc, u32 mask, u32 value); -+u32 ssb_chipco_gpio_pulldown(struct ssb_chipcommon *cc, u32 mask, u32 value); - - #ifdef CONFIG_SSB_SERIAL - extern int ssb_chipco_serial_init(struct ssb_chipcommon *cc, -@@ -661,5 +668,6 @@ enum ssb_pmu_ldo_volt_id { - void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc, - enum ssb_pmu_ldo_volt_id id, u32 voltage); - void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on); -+void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid); - - #endif /* LINUX_SSB_CHIPCO_H_ */ ---- a/include/linux/ssb/ssb_driver_extif.h -+++ b/include/linux/ssb/ssb_driver_extif.h -@@ -152,12 +152,16 @@ - /* watchdog */ - #define SSB_EXTIF_WATCHDOG_CLK 48000000 /* Hz */ - -+#define SSB_EXTIF_WATCHDOG_MAX_TIMER ((1 << 28) - 1) -+#define SSB_EXTIF_WATCHDOG_MAX_TIMER_MS (SSB_EXTIF_WATCHDOG_MAX_TIMER \ -+ / (SSB_EXTIF_WATCHDOG_CLK / 1000)) - - - #ifdef CONFIG_SSB_DRIVER_EXTIF - - struct ssb_extif { - struct ssb_device *dev; -+ spinlock_t gpio_lock; - }; - - static inline bool ssb_extif_available(struct ssb_extif *extif) -@@ -171,8 +175,7 @@ extern void ssb_extif_get_clockcontrol(s - extern void ssb_extif_timing_init(struct ssb_extif *extif, - unsigned long ns); - --extern void ssb_extif_watchdog_timer_set(struct ssb_extif *extif, -- u32 ticks); -+extern u32 ssb_extif_watchdog_timer_set(struct ssb_extif *extif, u32 ticks); - - /* Extif GPIO pin access */ - u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask); -@@ -205,10 +208,52 @@ void ssb_extif_get_clockcontrol(struct s - } - - static inline --void ssb_extif_watchdog_timer_set(struct ssb_extif *extif, -- u32 ticks) -+void ssb_extif_timing_init(struct ssb_extif *extif, unsigned long ns) - { - } - -+static inline -+u32 ssb_extif_watchdog_timer_set(struct ssb_extif *extif, u32 ticks) -+{ -+ return 0; -+} -+ -+static inline u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask) -+{ -+ return 0; -+} -+ -+static inline u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, -+ u32 value) -+{ -+ return 0; -+} -+ -+static inline u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, -+ u32 value) -+{ -+ return 0; -+} -+ -+static inline u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, -+ u32 value) -+{ -+ return 0; -+} -+ -+static inline u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, -+ u32 value) -+{ -+ return 0; -+} -+ -+#ifdef CONFIG_SSB_SERIAL -+static inline int ssb_extif_serial_init(struct ssb_extif *extif, -+ struct ssb_serial_port *ports) -+{ -+ return 0; -+} -+#endif /* CONFIG_SSB_SERIAL */ -+ - #endif /* CONFIG_SSB_DRIVER_EXTIF */ - #endif /* LINUX_SSB_EXTIFCORE_H_ */ ---- a/include/linux/ssb/ssb_driver_gige.h -+++ b/include/linux/ssb/ssb_driver_gige.h -@@ -2,6 +2,7 @@ - #define LINUX_SSB_DRIVER_GIGE_H_ - - #include <linux/ssb/ssb.h> -+#include <linux/bug.h> - #include <linux/pci.h> - #include <linux/spinlock.h> - -@@ -96,21 +97,16 @@ static inline bool ssb_gige_must_flush_p - return 0; - } - --#ifdef CONFIG_BCM47XX --#include <asm/mach-bcm47xx/nvram.h> - /* Get the device MAC address */ --static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr) --{ -- char buf[20]; -- if (nvram_getenv("et0macaddr", buf, sizeof(buf)) < 0) -- return; -- nvram_parse_macaddr(buf, macaddr); --} --#else --static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr) -+static inline int ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr) - { -+ struct ssb_gige *dev = pdev_to_ssb_gige(pdev); -+ if (!dev) -+ return -ENODEV; -+ -+ memcpy(macaddr, dev->dev->bus->sprom.et0mac, 6); -+ return 0; - } --#endif - - extern int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev, - struct pci_dev *pdev); -@@ -174,6 +170,10 @@ static inline bool ssb_gige_must_flush_p - { - return 0; - } -+static inline int ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr) -+{ -+ return -ENODEV; -+} - - #endif /* CONFIG_SSB_DRIVER_GIGE */ - #endif /* LINUX_SSB_DRIVER_GIGE_H_ */ ---- a/include/linux/ssb/ssb_driver_mips.h -+++ b/include/linux/ssb/ssb_driver_mips.h -@@ -13,6 +13,24 @@ struct ssb_serial_port { - unsigned int reg_shift; - }; - -+struct ssb_pflash { -+ bool present; -+ u8 buswidth; -+ u32 window; -+ u32 window_size; -+}; -+ -+#ifdef CONFIG_SSB_SFLASH -+struct ssb_sflash { -+ bool present; -+ u32 window; -+ u32 blocksize; -+ u16 numblocks; -+ u32 size; -+ -+ void *priv; -+}; -+#endif - - struct ssb_mipscore { - struct ssb_device *dev; -@@ -20,9 +38,10 @@ struct ssb_mipscore { - int nr_serial_ports; - struct ssb_serial_port serial_ports[4]; - -- u8 flash_buswidth; -- u32 flash_window; -- u32 flash_window_size; -+ struct ssb_pflash pflash; -+#ifdef CONFIG_SSB_SFLASH -+ struct ssb_sflash sflash; -+#endif - }; - - extern void ssb_mipscore_init(struct ssb_mipscore *mcore); -@@ -41,6 +60,11 @@ void ssb_mipscore_init(struct ssb_mipsco - { - } - -+static inline unsigned int ssb_mips_irq(struct ssb_device *dev) -+{ -+ return 0; -+} -+ - #endif /* CONFIG_SSB_DRIVER_MIPS */ - - #endif /* LINUX_SSB_MIPSCORE_H_ */ ---- a/include/linux/ssb/ssb_regs.h -+++ b/include/linux/ssb/ssb_regs.h -@@ -172,6 +172,7 @@ - #define SSB_SPROMSIZE_WORDS_R4 220 - #define SSB_SPROMSIZE_BYTES_R123 (SSB_SPROMSIZE_WORDS_R123 * sizeof(u16)) - #define SSB_SPROMSIZE_BYTES_R4 (SSB_SPROMSIZE_WORDS_R4 * sizeof(u16)) -+#define SSB_SPROMSIZE_WORDS_R10 230 - #define SSB_SPROM_BASE1 0x1000 - #define SSB_SPROM_BASE31 0x0800 - #define SSB_SPROM_REVISION 0x007E -@@ -228,6 +229,7 @@ - #define SSB_SPROM1_AGAIN_BG_SHIFT 0 - #define SSB_SPROM1_AGAIN_A 0xFF00 /* A-PHY */ - #define SSB_SPROM1_AGAIN_A_SHIFT 8 -+#define SSB_SPROM1_CCODE 0x0076 - - /* SPROM Revision 2 (inherits from rev 1) */ - #define SSB_SPROM2_BFLHI 0x0038 /* Boardflags (high 16 bits) */ -@@ -267,6 +269,7 @@ - #define SSB_SPROM3_OFDMGPO 0x107A /* G-PHY OFDM Power Offset (4 bytes, BigEndian) */ - - /* SPROM Revision 4 */ -+#define SSB_SPROM4_BOARDREV 0x0042 /* Board revision */ - #define SSB_SPROM4_BFLLO 0x0044 /* Boardflags (low 16 bits) */ - #define SSB_SPROM4_BFLHI 0x0046 /* Board Flags Hi */ - #define SSB_SPROM4_BFL2LO 0x0048 /* Board flags 2 (low 16 bits) */ -@@ -287,11 +290,11 @@ - #define SSB_SPROM4_ETHPHY_ET1A_SHIFT 5 - #define SSB_SPROM4_ETHPHY_ET0M (1<<14) /* MDIO for enet0 */ - #define SSB_SPROM4_ETHPHY_ET1M (1<<15) /* MDIO for enet1 */ --#define SSB_SPROM4_ANTAVAIL 0x005D /* Antenna available bitfields */ --#define SSB_SPROM4_ANTAVAIL_A 0x00FF /* A-PHY bitfield */ --#define SSB_SPROM4_ANTAVAIL_A_SHIFT 0 --#define SSB_SPROM4_ANTAVAIL_BG 0xFF00 /* B-PHY and G-PHY bitfield */ --#define SSB_SPROM4_ANTAVAIL_BG_SHIFT 8 -+#define SSB_SPROM4_ANTAVAIL 0x005C /* Antenna available bitfields */ -+#define SSB_SPROM4_ANTAVAIL_BG 0x00FF /* B-PHY and G-PHY bitfield */ -+#define SSB_SPROM4_ANTAVAIL_BG_SHIFT 0 -+#define SSB_SPROM4_ANTAVAIL_A 0xFF00 /* A-PHY bitfield */ -+#define SSB_SPROM4_ANTAVAIL_A_SHIFT 8 - #define SSB_SPROM4_AGAIN01 0x005E /* Antenna Gain (in dBm Q5.2) */ - #define SSB_SPROM4_AGAIN0 0x00FF /* Antenna 0 */ - #define SSB_SPROM4_AGAIN0_SHIFT 0 -@@ -389,6 +392,11 @@ - #define SSB_SPROM8_GPIOB_P2 0x00FF /* Pin 2 */ - #define SSB_SPROM8_GPIOB_P3 0xFF00 /* Pin 3 */ - #define SSB_SPROM8_GPIOB_P3_SHIFT 8 -+#define SSB_SPROM8_LEDDC 0x009A -+#define SSB_SPROM8_LEDDC_ON 0xFF00 /* oncount */ -+#define SSB_SPROM8_LEDDC_ON_SHIFT 8 -+#define SSB_SPROM8_LEDDC_OFF 0x00FF /* offcount */ -+#define SSB_SPROM8_LEDDC_OFF_SHIFT 0 - #define SSB_SPROM8_ANTAVAIL 0x009C /* Antenna available bitfields*/ - #define SSB_SPROM8_ANTAVAIL_A 0xFF00 /* A-PHY bitfield */ - #define SSB_SPROM8_ANTAVAIL_A_SHIFT 8 -@@ -404,6 +412,13 @@ - #define SSB_SPROM8_AGAIN2_SHIFT 0 - #define SSB_SPROM8_AGAIN3 0xFF00 /* Antenna 3 */ - #define SSB_SPROM8_AGAIN3_SHIFT 8 -+#define SSB_SPROM8_TXRXC 0x00A2 -+#define SSB_SPROM8_TXRXC_TXCHAIN 0x000f -+#define SSB_SPROM8_TXRXC_TXCHAIN_SHIFT 0 -+#define SSB_SPROM8_TXRXC_RXCHAIN 0x00f0 -+#define SSB_SPROM8_TXRXC_RXCHAIN_SHIFT 4 -+#define SSB_SPROM8_TXRXC_SWITCH 0xff00 -+#define SSB_SPROM8_TXRXC_SWITCH_SHIFT 8 - #define SSB_SPROM8_RSSIPARM2G 0x00A4 /* RSSI params for 2GHz */ - #define SSB_SPROM8_RSSISMF2G 0x000F - #define SSB_SPROM8_RSSISMC2G 0x00F0 -@@ -430,6 +445,7 @@ - #define SSB_SPROM8_TRI5GH_SHIFT 8 - #define SSB_SPROM8_RXPO 0x00AC /* RX power offsets */ - #define SSB_SPROM8_RXPO2G 0x00FF /* 2GHz RX power offset */ -+#define SSB_SPROM8_RXPO2G_SHIFT 0 - #define SSB_SPROM8_RXPO5G 0xFF00 /* 5GHz RX power offset */ - #define SSB_SPROM8_RXPO5G_SHIFT 8 - #define SSB_SPROM8_FEM2G 0x00AE -@@ -445,10 +461,71 @@ - #define SSB_SROM8_FEM_ANTSWLUT 0xF800 - #define SSB_SROM8_FEM_ANTSWLUT_SHIFT 11 - #define SSB_SPROM8_THERMAL 0x00B2 --#define SSB_SPROM8_MPWR_RAWTS 0x00B4 --#define SSB_SPROM8_TS_SLP_OPT_CORRX 0x00B6 --#define SSB_SPROM8_FOC_HWIQ_IQSWP 0x00B8 --#define SSB_SPROM8_PHYCAL_TEMPDELTA 0x00BA -+#define SSB_SPROM8_THERMAL_OFFSET 0x00ff -+#define SSB_SPROM8_THERMAL_OFFSET_SHIFT 0 -+#define SSB_SPROM8_THERMAL_TRESH 0xff00 -+#define SSB_SPROM8_THERMAL_TRESH_SHIFT 8 -+/* Temp sense related entries */ -+#define SSB_SPROM8_RAWTS 0x00B4 -+#define SSB_SPROM8_RAWTS_RAWTEMP 0x01ff -+#define SSB_SPROM8_RAWTS_RAWTEMP_SHIFT 0 -+#define SSB_SPROM8_RAWTS_MEASPOWER 0xfe00 -+#define SSB_SPROM8_RAWTS_MEASPOWER_SHIFT 9 -+#define SSB_SPROM8_OPT_CORRX 0x00B6 -+#define SSB_SPROM8_OPT_CORRX_TEMP_SLOPE 0x00ff -+#define SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT 0 -+#define SSB_SPROM8_OPT_CORRX_TEMPCORRX 0xfc00 -+#define SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT 10 -+#define SSB_SPROM8_OPT_CORRX_TEMP_OPTION 0x0300 -+#define SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT 8 -+/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, IQSWP: IQ CAL swap disable */ -+#define SSB_SPROM8_HWIQ_IQSWP 0x00B8 -+#define SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR 0x000f -+#define SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT 0 -+#define SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP 0x0010 -+#define SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT 4 -+#define SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL 0x0020 -+#define SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT 5 -+#define SSB_SPROM8_TEMPDELTA 0x00BC -+#define SSB_SPROM8_TEMPDELTA_PHYCAL 0x00ff -+#define SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT 0 -+#define SSB_SPROM8_TEMPDELTA_PERIOD 0x0f00 -+#define SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT 8 -+#define SSB_SPROM8_TEMPDELTA_HYSTERESIS 0xf000 -+#define SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT 12 -+ -+/* There are 4 blocks with power info sharing the same layout */ -+#define SSB_SROM8_PWR_INFO_CORE0 0x00C0 -+#define SSB_SROM8_PWR_INFO_CORE1 0x00E0 -+#define SSB_SROM8_PWR_INFO_CORE2 0x0100 -+#define SSB_SROM8_PWR_INFO_CORE3 0x0120 -+ -+#define SSB_SROM8_2G_MAXP_ITSSI 0x00 -+#define SSB_SPROM8_2G_MAXP 0x00FF -+#define SSB_SPROM8_2G_ITSSI 0xFF00 -+#define SSB_SPROM8_2G_ITSSI_SHIFT 8 -+#define SSB_SROM8_2G_PA_0 0x02 /* 2GHz power amp settings */ -+#define SSB_SROM8_2G_PA_1 0x04 -+#define SSB_SROM8_2G_PA_2 0x06 -+#define SSB_SROM8_5G_MAXP_ITSSI 0x08 /* 5GHz ITSSI and 5.3GHz Max Power */ -+#define SSB_SPROM8_5G_MAXP 0x00FF -+#define SSB_SPROM8_5G_ITSSI 0xFF00 -+#define SSB_SPROM8_5G_ITSSI_SHIFT 8 -+#define SSB_SPROM8_5GHL_MAXP 0x0A /* 5.2GHz and 5.8GHz Max Power */ -+#define SSB_SPROM8_5GH_MAXP 0x00FF -+#define SSB_SPROM8_5GL_MAXP 0xFF00 -+#define SSB_SPROM8_5GL_MAXP_SHIFT 8 -+#define SSB_SROM8_5G_PA_0 0x0C /* 5.3GHz power amp settings */ -+#define SSB_SROM8_5G_PA_1 0x0E -+#define SSB_SROM8_5G_PA_2 0x10 -+#define SSB_SROM8_5GL_PA_0 0x12 /* 5.2GHz power amp settings */ -+#define SSB_SROM8_5GL_PA_1 0x14 -+#define SSB_SROM8_5GL_PA_2 0x16 -+#define SSB_SROM8_5GH_PA_0 0x18 /* 5.8GHz power amp settings */ -+#define SSB_SROM8_5GH_PA_1 0x1A -+#define SSB_SROM8_5GH_PA_2 0x1C -+ -+/* TODO: Make it deprecated */ - #define SSB_SPROM8_MAXP_BG 0x00C0 /* Max Power 2GHz in path 1 */ - #define SSB_SPROM8_MAXP_BG_MASK 0x00FF /* Mask for Max Power 2GHz */ - #define SSB_SPROM8_ITSSI_BG 0xFF00 /* Mask for path 1 itssi_bg */ -@@ -473,12 +550,23 @@ - #define SSB_SPROM8_PA1HIB0 0x00D8 /* 5.8GHz power amp settings */ - #define SSB_SPROM8_PA1HIB1 0x00DA - #define SSB_SPROM8_PA1HIB2 0x00DC -+ - #define SSB_SPROM8_CCK2GPO 0x0140 /* CCK power offset */ - #define SSB_SPROM8_OFDM2GPO 0x0142 /* 2.4GHz OFDM power offset */ - #define SSB_SPROM8_OFDM5GPO 0x0146 /* 5.3GHz OFDM power offset */ - #define SSB_SPROM8_OFDM5GLPO 0x014A /* 5.2GHz OFDM power offset */ - #define SSB_SPROM8_OFDM5GHPO 0x014E /* 5.8GHz OFDM power offset */ - -+#define SSB_SPROM8_2G_MCSPO 0x0152 -+#define SSB_SPROM8_5G_MCSPO 0x0162 -+#define SSB_SPROM8_5GL_MCSPO 0x0172 -+#define SSB_SPROM8_5GH_MCSPO 0x0182 -+ -+#define SSB_SPROM8_CDDPO 0x0192 -+#define SSB_SPROM8_STBCPO 0x0194 -+#define SSB_SPROM8_BW40PO 0x0196 -+#define SSB_SPROM8_BWDUPPO 0x0198 -+ - /* Values for boardflags_lo read from SPROM */ - #define SSB_BFL_BTCOEXIST 0x0001 /* implements Bluetooth coexistance */ - #define SSB_BFL_PACTRL 0x0002 /* GPIO 9 controlling the PA */ ---- /dev/null -+++ b/include/linux/bcm47xx_wdt.h -@@ -0,0 +1,19 @@ -+#ifndef LINUX_BCM47XX_WDT_H_ -+#define LINUX_BCM47XX_WDT_H_ -+ -+#include <linux/types.h> -+ -+ -+struct bcm47xx_wdt { -+ u32 (*timer_set)(struct bcm47xx_wdt *, u32); -+ u32 (*timer_set_ms)(struct bcm47xx_wdt *, u32); -+ u32 max_timer_ms; -+ -+ void *driver_data; -+}; -+ -+static inline void *bcm47xx_wdt_get_drvdata(struct bcm47xx_wdt *wdt) -+{ -+ return wdt->driver_data; -+} -+#endif /* LINUX_BCM47XX_WDT_H_ */ ---- a/drivers/net/wireless/b43/phy_n.c -+++ b/drivers/net/wireless/b43/phy_n.c -@@ -4259,7 +4259,8 @@ static void b43_nphy_pmu_spur_avoid(stru - #endif - #ifdef CONFIG_B43_SSB - case B43_BUS_SSB: -- /* FIXME */ -+ ssb_pmu_spuravoid_pllupdate(&dev->dev->sdev->bus->chipco, -+ avoid); - break; - #endif - } |