1 --- a/arch/mips/bcm47xx/nvram.c
2 +++ b/arch/mips/bcm47xx/nvram.c
3 @@ -43,8 +43,8 @@ static void early_nvram_init(void)
4 #ifdef CONFIG_BCM47XX_SSB
5 case BCM47XX_BUS_TYPE_SSB:
6 mcore_ssb = &bcm47xx_bus.ssb.mipscore;
7 - base = mcore_ssb->flash_window;
8 - lim = mcore_ssb->flash_window_size;
9 + base = mcore_ssb->pflash.window;
10 + lim = mcore_ssb->pflash.window_size;
13 #ifdef CONFIG_BCM47XX_BCMA
14 --- a/arch/mips/bcm47xx/wgt634u.c
15 +++ b/arch/mips/bcm47xx/wgt634u.c
16 @@ -156,10 +156,10 @@ static int __init wgt634u_init(void)
20 - wgt634u_flash_data.width = mcore->flash_buswidth;
21 - wgt634u_flash_resource.start = mcore->flash_window;
22 - wgt634u_flash_resource.end = mcore->flash_window
23 - + mcore->flash_window_size
24 + wgt634u_flash_data.width = mcore->pflash.buswidth;
25 + wgt634u_flash_resource.start = mcore->pflash.window;
26 + wgt634u_flash_resource.end = mcore->pflash.window
27 + + mcore->pflash.window_size
29 return platform_add_devices(wgt634u_devices,
30 ARRAY_SIZE(wgt634u_devices));
31 --- a/drivers/ssb/Kconfig
32 +++ b/drivers/ssb/Kconfig
33 @@ -136,6 +136,11 @@ config SSB_DRIVER_MIPS
38 + bool "SSB serial flash support"
39 + depends on SSB_DRIVER_MIPS && BROKEN
42 # Assumption: We are on embedded, if we compile the MIPS core.
45 @@ -160,4 +165,12 @@ config SSB_DRIVER_GIGE
49 +config SSB_DRIVER_GPIO
50 + bool "SSB GPIO driver"
51 + depends on SSB && GPIOLIB
53 + Driver to provide access to the GPIO pins on the bus.
58 --- a/drivers/ssb/Makefile
59 +++ b/drivers/ssb/Makefile
60 @@ -11,10 +11,12 @@ ssb-$(CONFIG_SSB_SDIOHOST) += sdio.o
62 ssb-y += driver_chipcommon.o
63 ssb-y += driver_chipcommon_pmu.o
64 +ssb-$(CONFIG_SSB_SFLASH) += driver_chipcommon_sflash.o
65 ssb-$(CONFIG_SSB_DRIVER_MIPS) += driver_mipscore.o
66 ssb-$(CONFIG_SSB_DRIVER_EXTIF) += driver_extif.o
67 ssb-$(CONFIG_SSB_DRIVER_PCICORE) += driver_pcicore.o
68 ssb-$(CONFIG_SSB_DRIVER_GIGE) += driver_gige.o
69 +ssb-$(CONFIG_SSB_DRIVER_GPIO) += driver_gpio.o
71 # b43 pci-ssb-bridge driver
72 # Not strictly a part of SSB, but kept here for convenience
73 --- a/drivers/ssb/b43_pci_bridge.c
74 +++ b/drivers/ssb/b43_pci_bridge.c
75 @@ -29,11 +29,15 @@ static const struct pci_device_id b43_pc
76 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) },
77 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) },
78 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) },
79 + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4322) },
80 + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43222) },
81 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4324) },
82 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4325) },
83 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4328) },
84 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4329) },
85 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432b) },
86 + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432c) },
87 + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4350) },
90 MODULE_DEVICE_TABLE(pci, b43_pci_bridge_tbl);
91 --- a/drivers/ssb/driver_chipcommon.c
92 +++ b/drivers/ssb/driver_chipcommon.c
95 * Copyright 2005, Broadcom Corporation
96 * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
97 + * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
99 * Licensed under the GNU/GPL. See COPYING for details.
102 #include <linux/ssb/ssb_regs.h>
103 #include <linux/export.h>
104 #include <linux/pci.h>
105 +#include <linux/bcm47xx_wdt.h>
107 #include "ssb_private.h"
109 @@ -280,10 +282,76 @@ static void calc_fast_powerup_delay(stru
110 cc->fast_pwrup_delay = tmp;
113 +static u32 ssb_chipco_alp_clock(struct ssb_chipcommon *cc)
115 + if (cc->capabilities & SSB_CHIPCO_CAP_PMU)
116 + return ssb_pmu_get_alp_clock(cc);
121 +static u32 ssb_chipco_watchdog_get_max_timer(struct ssb_chipcommon *cc)
125 + if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
126 + if (cc->dev->id.revision < 26)
129 + nb = (cc->dev->id.revision >= 37) ? 32 : 24;
136 + return (1 << nb) - 1;
139 +u32 ssb_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks)
141 + struct ssb_chipcommon *cc = bcm47xx_wdt_get_drvdata(wdt);
143 + if (cc->dev->bus->bustype != SSB_BUSTYPE_SSB)
146 + return ssb_chipco_watchdog_timer_set(cc, ticks);
149 +u32 ssb_chipco_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms)
151 + struct ssb_chipcommon *cc = bcm47xx_wdt_get_drvdata(wdt);
154 + if (cc->dev->bus->bustype != SSB_BUSTYPE_SSB)
157 + ticks = ssb_chipco_watchdog_timer_set(cc, cc->ticks_per_ms * ms);
158 + return ticks / cc->ticks_per_ms;
161 +static int ssb_chipco_watchdog_ticks_per_ms(struct ssb_chipcommon *cc)
163 + struct ssb_bus *bus = cc->dev->bus;
165 + if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
166 + /* based on 32KHz ILP clock */
169 + if (cc->dev->id.revision < 18)
170 + return ssb_clockspeed(bus) / 1000;
172 + return ssb_chipco_alp_clock(cc) / 1000;
176 void ssb_chipcommon_init(struct ssb_chipcommon *cc)
179 return; /* We don't have a ChipCommon */
181 + spin_lock_init(&cc->gpio_lock);
183 if (cc->dev->id.revision >= 11)
184 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
185 ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status);
186 @@ -297,6 +365,11 @@ void ssb_chipcommon_init(struct ssb_chip
187 chipco_powercontrol_init(cc);
188 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
189 calc_fast_powerup_delay(cc);
191 + if (cc->dev->bus->bustype == SSB_BUSTYPE_SSB) {
192 + cc->ticks_per_ms = ssb_chipco_watchdog_ticks_per_ms(cc);
193 + cc->max_timer_ms = ssb_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms;
197 void ssb_chipco_suspend(struct ssb_chipcommon *cc)
198 @@ -395,10 +468,27 @@ void ssb_chipco_timing_init(struct ssb_c
201 /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
202 -void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks)
203 +u32 ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks)
206 - chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks);
208 + enum ssb_clkmode clkmode;
210 + maxt = ssb_chipco_watchdog_get_max_timer(cc);
211 + if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
214 + else if (ticks > maxt)
216 + chipco_write32(cc, SSB_CHIPCO_PMU_WATCHDOG, ticks);
218 + clkmode = ticks ? SSB_CLKMODE_FAST : SSB_CLKMODE_DYNAMIC;
219 + ssb_chipco_set_clockmode(cc, clkmode);
223 + chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks);
228 void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value)
229 @@ -418,28 +508,93 @@ u32 ssb_chipco_gpio_in(struct ssb_chipco
231 u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value)
233 - return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value);
234 + unsigned long flags;
237 + spin_lock_irqsave(&cc->gpio_lock, flags);
238 + res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value);
239 + spin_unlock_irqrestore(&cc->gpio_lock, flags);
244 u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value)
246 - return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value);
247 + unsigned long flags;
250 + spin_lock_irqsave(&cc->gpio_lock, flags);
251 + res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value);
252 + spin_unlock_irqrestore(&cc->gpio_lock, flags);
257 u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value)
259 - return chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value);
260 + unsigned long flags;
263 + spin_lock_irqsave(&cc->gpio_lock, flags);
264 + res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value);
265 + spin_unlock_irqrestore(&cc->gpio_lock, flags);
269 EXPORT_SYMBOL(ssb_chipco_gpio_control);
271 u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value)
273 - return chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value);
274 + unsigned long flags;
277 + spin_lock_irqsave(&cc->gpio_lock, flags);
278 + res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value);
279 + spin_unlock_irqrestore(&cc->gpio_lock, flags);
284 u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value)
286 - return chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value);
287 + unsigned long flags;
290 + spin_lock_irqsave(&cc->gpio_lock, flags);
291 + res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value);
292 + spin_unlock_irqrestore(&cc->gpio_lock, flags);
297 +u32 ssb_chipco_gpio_pullup(struct ssb_chipcommon *cc, u32 mask, u32 value)
299 + unsigned long flags;
302 + if (cc->dev->id.revision < 20)
305 + spin_lock_irqsave(&cc->gpio_lock, flags);
306 + res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLUP, mask, value);
307 + spin_unlock_irqrestore(&cc->gpio_lock, flags);
312 +u32 ssb_chipco_gpio_pulldown(struct ssb_chipcommon *cc, u32 mask, u32 value)
314 + unsigned long flags;
317 + if (cc->dev->id.revision < 20)
320 + spin_lock_irqsave(&cc->gpio_lock, flags);
321 + res = chipco_write32_masked(cc, SSB_CHIPCO_GPIOPULLDOWN, mask, value);
322 + spin_unlock_irqrestore(&cc->gpio_lock, flags);
327 #ifdef CONFIG_SSB_SERIAL
328 @@ -473,12 +628,7 @@ int ssb_chipco_serial_init(struct ssb_ch
329 chipco_read32(cc, SSB_CHIPCO_CORECTL)
330 | SSB_CHIPCO_CORECTL_UARTCLK0);
331 } else if ((ccrev >= 11) && (ccrev != 15)) {
332 - /* Fixed ALP clock */
333 - baud_base = 20000000;
334 - if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
335 - /* FIXME: baud_base is different for devices with a PMU */
338 + baud_base = ssb_chipco_alp_clock(cc);
341 /* Turn off UART clock before switching clocksource. */
342 --- a/drivers/ssb/driver_chipcommon_pmu.c
343 +++ b/drivers/ssb/driver_chipcommon_pmu.c
345 #include <linux/ssb/ssb_driver_chipcommon.h>
346 #include <linux/delay.h>
347 #include <linux/export.h>
348 +#ifdef CONFIG_BCM47XX
349 +#include <asm/mach-bcm47xx/nvram.h>
352 #include "ssb_private.h"
354 @@ -92,10 +95,6 @@ static void ssb_pmu0_pllinit_r0(struct s
355 u32 pmuctl, tmp, pllctl;
358 - if ((bus->chip_id == 0x5354) && !crystalfreq) {
359 - /* The 5354 crystal freq is 25MHz */
360 - crystalfreq = 25000;
363 e = pmu0_plltab_find_entry(crystalfreq);
365 @@ -321,7 +320,11 @@ static void ssb_pmu_pll_init(struct ssb_
366 u32 crystalfreq = 0; /* in kHz. 0 = keep default freq. */
368 if (bus->bustype == SSB_BUSTYPE_SSB) {
369 - /* TODO: The user may override the crystal frequency. */
370 +#ifdef CONFIG_BCM47XX
372 + if (nvram_getenv("xtalfreq", buf, sizeof(buf)) >= 0)
373 + crystalfreq = simple_strtoul(buf, NULL, 0);
377 switch (bus->chip_id) {
378 @@ -330,7 +333,11 @@ static void ssb_pmu_pll_init(struct ssb_
379 ssb_pmu1_pllinit_r0(cc, crystalfreq);
382 + ssb_pmu0_pllinit_r0(cc, crystalfreq);
385 + if (crystalfreq == 0)
386 + crystalfreq = 25000;
387 ssb_pmu0_pllinit_r0(cc, crystalfreq);
390 @@ -339,6 +346,8 @@ static void ssb_pmu_pll_init(struct ssb_
391 chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, 0x380005C0);
397 ssb_printk(KERN_ERR PFX
398 "ERROR: PLL init unknown for device %04X\n",
399 @@ -427,6 +436,7 @@ static void ssb_pmu_resources_init(struc
404 /* We keep the default settings:
407 @@ -607,3 +617,61 @@ void ssb_pmu_set_ldo_paref(struct ssb_ch
409 EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage);
410 EXPORT_SYMBOL(ssb_pmu_set_ldo_paref);
412 +static u32 ssb_pmu_get_alp_clock_clk0(struct ssb_chipcommon *cc)
415 + const struct pmu0_plltab_entry *e = NULL;
417 + crystalfreq = chipco_read32(cc, SSB_CHIPCO_PMU_CTL) &
418 + SSB_CHIPCO_PMU_CTL_XTALFREQ >> SSB_CHIPCO_PMU_CTL_XTALFREQ_SHIFT;
419 + e = pmu0_plltab_find_entry(crystalfreq);
421 + return e->freq * 1000;
424 +u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc)
426 + struct ssb_bus *bus = cc->dev->bus;
428 + switch (bus->chip_id) {
430 + ssb_pmu_get_alp_clock_clk0(cc);
432 + ssb_printk(KERN_ERR PFX
433 + "ERROR: PMU alp clock unknown for device %04X\n",
439 +u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc)
441 + struct ssb_bus *bus = cc->dev->bus;
443 + switch (bus->chip_id) {
445 + /* 5354 chip uses a non programmable PLL of frequency 240MHz */
448 + ssb_printk(KERN_ERR PFX
449 + "ERROR: PMU cpu clock unknown for device %04X\n",
455 +u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc)
457 + struct ssb_bus *bus = cc->dev->bus;
459 + switch (bus->chip_id) {
463 + ssb_printk(KERN_ERR PFX
464 + "ERROR: PMU controlclock unknown for device %04X\n",
470 +++ b/drivers/ssb/driver_chipcommon_sflash.c
473 + * Sonics Silicon Backplane
474 + * ChipCommon serial flash interface
476 + * Licensed under the GNU/GPL. See COPYING for details.
479 +#include <linux/ssb/ssb.h>
481 +#include "ssb_private.h"
483 +/* Initialize serial flash access */
484 +int ssb_sflash_init(struct ssb_chipcommon *cc)
486 + pr_err("Serial flash support is not implemented yet!\n");
490 --- a/drivers/ssb/driver_extif.c
491 +++ b/drivers/ssb/driver_extif.c
492 @@ -112,10 +112,37 @@ void ssb_extif_get_clockcontrol(struct s
493 *m = extif_read32(extif, SSB_EXTIF_CLOCK_SB);
496 -void ssb_extif_watchdog_timer_set(struct ssb_extif *extif,
498 +u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks)
500 + struct ssb_extif *extif = bcm47xx_wdt_get_drvdata(wdt);
502 + return ssb_extif_watchdog_timer_set(extif, ticks);
505 +u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms)
507 + struct ssb_extif *extif = bcm47xx_wdt_get_drvdata(wdt);
508 + u32 ticks = (SSB_EXTIF_WATCHDOG_CLK / 1000) * ms;
510 + ticks = ssb_extif_watchdog_timer_set(extif, ticks);
512 + return (ticks * 1000) / SSB_EXTIF_WATCHDOG_CLK;
515 +u32 ssb_extif_watchdog_timer_set(struct ssb_extif *extif, u32 ticks)
517 + if (ticks > SSB_EXTIF_WATCHDOG_MAX_TIMER)
518 + ticks = SSB_EXTIF_WATCHDOG_MAX_TIMER;
519 extif_write32(extif, SSB_EXTIF_WATCHDOG, ticks);
524 +void ssb_extif_init(struct ssb_extif *extif)
527 + return; /* We don't have a Extif core */
528 + spin_lock_init(&extif->gpio_lock);
531 u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)
532 @@ -125,22 +152,50 @@ u32 ssb_extif_gpio_in(struct ssb_extif *
534 u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value)
536 - return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0),
537 + unsigned long flags;
540 + spin_lock_irqsave(&extif->gpio_lock, flags);
541 + res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0),
543 + spin_unlock_irqrestore(&extif->gpio_lock, flags);
548 u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value)
550 - return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0),
551 + unsigned long flags;
554 + spin_lock_irqsave(&extif->gpio_lock, flags);
555 + res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0),
557 + spin_unlock_irqrestore(&extif->gpio_lock, flags);
562 u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value)
564 - return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value);
565 + unsigned long flags;
568 + spin_lock_irqsave(&extif->gpio_lock, flags);
569 + res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value);
570 + spin_unlock_irqrestore(&extif->gpio_lock, flags);
575 u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value)
577 - return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value);
578 + unsigned long flags;
581 + spin_lock_irqsave(&extif->gpio_lock, flags);
582 + res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value);
583 + spin_unlock_irqrestore(&extif->gpio_lock, flags);
588 +++ b/drivers/ssb/driver_gpio.c
591 + * Sonics Silicon Backplane
594 + * Copyright 2011, Broadcom Corporation
595 + * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
597 + * Licensed under the GNU/GPL. See COPYING for details.
600 +#include <linux/gpio.h>
601 +#include <linux/export.h>
602 +#include <linux/ssb/ssb.h>
604 +#include "ssb_private.h"
606 +static struct ssb_bus *ssb_gpio_get_bus(struct gpio_chip *chip)
608 + return container_of(chip, struct ssb_bus, gpio);
611 +static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned gpio)
613 + struct ssb_bus *bus = ssb_gpio_get_bus(chip);
615 + return !!ssb_chipco_gpio_in(&bus->chipco, 1 << gpio);
618 +static void ssb_gpio_chipco_set_value(struct gpio_chip *chip, unsigned gpio,
621 + struct ssb_bus *bus = ssb_gpio_get_bus(chip);
623 + ssb_chipco_gpio_out(&bus->chipco, 1 << gpio, value ? 1 << gpio : 0);
626 +static int ssb_gpio_chipco_direction_input(struct gpio_chip *chip,
629 + struct ssb_bus *bus = ssb_gpio_get_bus(chip);
631 + ssb_chipco_gpio_outen(&bus->chipco, 1 << gpio, 0);
635 +static int ssb_gpio_chipco_direction_output(struct gpio_chip *chip,
636 + unsigned gpio, int value)
638 + struct ssb_bus *bus = ssb_gpio_get_bus(chip);
640 + ssb_chipco_gpio_outen(&bus->chipco, 1 << gpio, 1 << gpio);
641 + ssb_chipco_gpio_out(&bus->chipco, 1 << gpio, value ? 1 << gpio : 0);
645 +static int ssb_gpio_chipco_request(struct gpio_chip *chip, unsigned gpio)
647 + struct ssb_bus *bus = ssb_gpio_get_bus(chip);
649 + ssb_chipco_gpio_control(&bus->chipco, 1 << gpio, 0);
650 + /* clear pulldown */
651 + ssb_chipco_gpio_pulldown(&bus->chipco, 1 << gpio, 0);
653 + ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 1 << gpio);
658 +static void ssb_gpio_chipco_free(struct gpio_chip *chip, unsigned gpio)
660 + struct ssb_bus *bus = ssb_gpio_get_bus(chip);
663 + ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0);
666 +static int ssb_gpio_chipco_init(struct ssb_bus *bus)
668 + struct gpio_chip *chip = &bus->gpio;
670 + chip->label = "ssb_chipco_gpio";
671 + chip->owner = THIS_MODULE;
672 + chip->request = ssb_gpio_chipco_request;
673 + chip->free = ssb_gpio_chipco_free;
674 + chip->get = ssb_gpio_chipco_get_value;
675 + chip->set = ssb_gpio_chipco_set_value;
676 + chip->direction_input = ssb_gpio_chipco_direction_input;
677 + chip->direction_output = ssb_gpio_chipco_direction_output;
679 + /* There is just one SoC in one device and its GPIO addresses should be
680 + * deterministic to address them more easily. The other buses could get
681 + * a random base number. */
682 + if (bus->bustype == SSB_BUSTYPE_SSB)
687 + return gpiochip_add(chip);
690 +#ifdef CONFIG_SSB_DRIVER_EXTIF
692 +static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned gpio)
694 + struct ssb_bus *bus = ssb_gpio_get_bus(chip);
696 + return !!ssb_extif_gpio_in(&bus->extif, 1 << gpio);
699 +static void ssb_gpio_extif_set_value(struct gpio_chip *chip, unsigned gpio,
702 + struct ssb_bus *bus = ssb_gpio_get_bus(chip);
704 + ssb_extif_gpio_out(&bus->extif, 1 << gpio, value ? 1 << gpio : 0);
707 +static int ssb_gpio_extif_direction_input(struct gpio_chip *chip,
710 + struct ssb_bus *bus = ssb_gpio_get_bus(chip);
712 + ssb_extif_gpio_outen(&bus->extif, 1 << gpio, 0);
716 +static int ssb_gpio_extif_direction_output(struct gpio_chip *chip,
717 + unsigned gpio, int value)
719 + struct ssb_bus *bus = ssb_gpio_get_bus(chip);
721 + ssb_extif_gpio_outen(&bus->extif, 1 << gpio, 1 << gpio);
722 + ssb_extif_gpio_out(&bus->extif, 1 << gpio, value ? 1 << gpio : 0);
726 +static int ssb_gpio_extif_init(struct ssb_bus *bus)
728 + struct gpio_chip *chip = &bus->gpio;
730 + chip->label = "ssb_extif_gpio";
731 + chip->owner = THIS_MODULE;
732 + chip->get = ssb_gpio_extif_get_value;
733 + chip->set = ssb_gpio_extif_set_value;
734 + chip->direction_input = ssb_gpio_extif_direction_input;
735 + chip->direction_output = ssb_gpio_extif_direction_output;
737 + /* There is just one SoC in one device and its GPIO addresses should be
738 + * deterministic to address them more easily. The other buses could get
739 + * a random base number. */
740 + if (bus->bustype == SSB_BUSTYPE_SSB)
745 + return gpiochip_add(chip);
749 +static int ssb_gpio_extif_init(struct ssb_bus *bus)
755 +int ssb_gpio_init(struct ssb_bus *bus)
757 + if (ssb_chipco_available(&bus->chipco))
758 + return ssb_gpio_chipco_init(bus);
759 + else if (ssb_extif_available(&bus->extif))
760 + return ssb_gpio_extif_init(bus);
766 --- a/drivers/ssb/driver_mipscore.c
767 +++ b/drivers/ssb/driver_mipscore.c
768 @@ -178,9 +178,9 @@ static void ssb_mips_serial_init(struct
770 struct ssb_bus *bus = mcore->dev->bus;
772 - if (bus->extif.dev)
773 + if (ssb_extif_available(&bus->extif))
774 mcore->nr_serial_ports = ssb_extif_serial_init(&bus->extif, mcore->serial_ports);
775 - else if (bus->chipco.dev)
776 + else if (ssb_chipco_available(&bus->chipco))
777 mcore->nr_serial_ports = ssb_chipco_serial_init(&bus->chipco, mcore->serial_ports);
779 mcore->nr_serial_ports = 0;
780 @@ -190,16 +190,33 @@ static void ssb_mips_flash_detect(struct
782 struct ssb_bus *bus = mcore->dev->bus;
784 - mcore->flash_buswidth = 2;
785 - if (bus->chipco.dev) {
786 - mcore->flash_window = 0x1c000000;
787 - mcore->flash_window_size = 0x02000000;
788 + /* When there is no chipcommon on the bus there is 4MB flash */
789 + if (!ssb_chipco_available(&bus->chipco)) {
790 + mcore->pflash.present = true;
791 + mcore->pflash.buswidth = 2;
792 + mcore->pflash.window = SSB_FLASH1;
793 + mcore->pflash.window_size = SSB_FLASH1_SZ;
797 + /* There is ChipCommon, so use it to read info about flash */
798 + switch (bus->chipco.capabilities & SSB_CHIPCO_CAP_FLASHT) {
799 + case SSB_CHIPCO_FLASHT_STSER:
800 + case SSB_CHIPCO_FLASHT_ATSER:
801 + pr_debug("Found serial flash\n");
802 + ssb_sflash_init(&bus->chipco);
804 + case SSB_CHIPCO_FLASHT_PARA:
805 + pr_debug("Found parallel flash\n");
806 + mcore->pflash.present = true;
807 + mcore->pflash.window = SSB_FLASH2;
808 + mcore->pflash.window_size = SSB_FLASH2_SZ;
809 if ((ssb_read32(bus->chipco.dev, SSB_CHIPCO_FLASH_CFG)
810 & SSB_CHIPCO_CFG_DS16) == 0)
811 - mcore->flash_buswidth = 1;
813 - mcore->flash_window = 0x1fc00000;
814 - mcore->flash_window_size = 0x00400000;
815 + mcore->pflash.buswidth = 1;
817 + mcore->pflash.buswidth = 2;
822 @@ -208,9 +225,12 @@ u32 ssb_cpu_clock(struct ssb_mipscore *m
823 struct ssb_bus *bus = mcore->dev->bus;
824 u32 pll_type, n, m, rate = 0;
826 - if (bus->extif.dev) {
827 + if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
828 + return ssb_pmu_get_cpu_clock(&bus->chipco);
830 + if (ssb_extif_available(&bus->extif)) {
831 ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m);
832 - } else if (bus->chipco.dev) {
833 + } else if (ssb_chipco_available(&bus->chipco)) {
834 ssb_chipco_get_clockcpu(&bus->chipco, &pll_type, &n, &m);
837 @@ -246,9 +266,9 @@ void ssb_mipscore_init(struct ssb_mipsco
839 ns = 1000000000 / hz;
841 - if (bus->extif.dev)
842 + if (ssb_extif_available(&bus->extif))
843 ssb_extif_timing_init(&bus->extif, ns);
844 - else if (bus->chipco.dev)
845 + else if (ssb_chipco_available(&bus->chipco))
846 ssb_chipco_timing_init(&bus->chipco, ns);
848 /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */
849 --- a/drivers/ssb/embedded.c
850 +++ b/drivers/ssb/embedded.c
853 * Copyright 2005-2008, Broadcom Corporation
854 * Copyright 2006-2008, Michael Buesch <m@bues.ch>
855 + * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
857 * Licensed under the GNU/GPL. See COPYING for details.
860 #include <linux/export.h>
861 +#include <linux/platform_device.h>
862 #include <linux/ssb/ssb.h>
863 #include <linux/ssb/ssb_embedded.h>
864 #include <linux/ssb/ssb_driver_pci.h>
865 @@ -32,6 +34,39 @@ int ssb_watchdog_timer_set(struct ssb_bu
867 EXPORT_SYMBOL(ssb_watchdog_timer_set);
869 +int ssb_watchdog_register(struct ssb_bus *bus)
871 + struct bcm47xx_wdt wdt = {};
872 + struct platform_device *pdev;
874 + if (ssb_chipco_available(&bus->chipco)) {
875 + wdt.driver_data = &bus->chipco;
876 + wdt.timer_set = ssb_chipco_watchdog_timer_set_wdt;
877 + wdt.timer_set_ms = ssb_chipco_watchdog_timer_set_ms;
878 + wdt.max_timer_ms = bus->chipco.max_timer_ms;
879 + } else if (ssb_extif_available(&bus->extif)) {
880 + wdt.driver_data = &bus->extif;
881 + wdt.timer_set = ssb_extif_watchdog_timer_set_wdt;
882 + wdt.timer_set_ms = ssb_extif_watchdog_timer_set_ms;
883 + wdt.max_timer_ms = SSB_EXTIF_WATCHDOG_MAX_TIMER_MS;
888 + pdev = platform_device_register_data(NULL, "bcm47xx-wdt",
889 + bus->busnumber, &wdt,
891 + if (IS_ERR(pdev)) {
892 + ssb_dprintk(KERN_INFO PFX
893 + "can not register watchdog device, err: %li\n",
895 + return PTR_ERR(pdev);
898 + bus->watchdog = pdev;
902 u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask)
905 --- a/drivers/ssb/main.c
906 +++ b/drivers/ssb/main.c
908 #include <linux/delay.h>
909 #include <linux/io.h>
910 #include <linux/module.h>
911 +#include <linux/platform_device.h>
912 #include <linux/ssb/ssb.h>
913 #include <linux/ssb/ssb_regs.h>
914 #include <linux/ssb/ssb_driver_gige.h>
915 @@ -140,19 +141,6 @@ static void ssb_device_put(struct ssb_de
916 put_device(dev->dev);
919 -static inline struct ssb_driver *ssb_driver_get(struct ssb_driver *drv)
922 - get_driver(&drv->drv);
926 -static inline void ssb_driver_put(struct ssb_driver *drv)
929 - put_driver(&drv->drv);
932 static int ssb_device_resume(struct device *dev)
934 struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
935 @@ -250,11 +238,9 @@ int ssb_devices_freeze(struct ssb_bus *b
936 ssb_device_put(sdev);
939 - sdrv = ssb_driver_get(drv_to_ssb_drv(sdev->dev->driver));
940 - if (!sdrv || SSB_WARN_ON(!sdrv->remove)) {
941 - ssb_device_put(sdev);
942 + sdrv = drv_to_ssb_drv(sdev->dev->driver);
943 + if (SSB_WARN_ON(!sdrv->remove))
947 ctx->device_frozen[i] = 1;
949 @@ -293,7 +279,6 @@ int ssb_devices_thaw(struct ssb_freeze_c
950 dev_name(sdev->dev));
953 - ssb_driver_put(sdrv);
954 ssb_device_put(sdev);
957 @@ -449,6 +434,11 @@ static void ssb_devices_unregister(struc
959 device_unregister(sdev->dev);
962 +#ifdef CONFIG_SSB_EMBEDDED
963 + if (bus->bustype == SSB_BUSTYPE_SSB)
964 + platform_device_unregister(bus->watchdog);
968 void ssb_bus_unregister(struct ssb_bus *bus)
969 @@ -577,6 +567,8 @@ static int __devinit ssb_attach_queued_b
972 ssb_pcicore_init(&bus->pcicore);
973 + if (bus->bustype == SSB_BUSTYPE_SSB)
974 + ssb_watchdog_register(bus);
975 ssb_bus_may_powerdown(bus);
977 err = ssb_devices_register(bus);
978 @@ -812,7 +804,14 @@ static int __devinit ssb_bus_register(st
980 goto err_pcmcia_exit;
981 ssb_chipcommon_init(&bus->chipco);
982 + ssb_extif_init(&bus->extif);
983 ssb_mipscore_init(&bus->mipscore);
984 + err = ssb_gpio_init(bus);
985 + if (err == -ENOTSUPP)
986 + ssb_dprintk(KERN_DEBUG PFX "GPIO driver not activated\n");
988 + ssb_dprintk(KERN_ERR PFX
989 + "Error registering GPIO driver: %i\n", err);
990 err = ssb_fetch_invariants(bus, get_invariants);
992 ssb_bus_may_powerdown(bus);
993 @@ -1094,6 +1093,9 @@ u32 ssb_clockspeed(struct ssb_bus *bus)
995 u32 clkctl_n, clkctl_m;
997 + if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
998 + return ssb_pmu_get_controlclock(&bus->chipco);
1000 if (ssb_extif_available(&bus->extif))
1001 ssb_extif_get_clockcontrol(&bus->extif, &plltype,
1002 &clkctl_n, &clkctl_m);
1003 @@ -1131,8 +1133,7 @@ static u32 ssb_tmslow_reject_bitmask(str
1004 case SSB_IDLOW_SSBREV_27: /* same here */
1005 return SSB_TMSLOW_REJECT; /* this is a guess */
1007 - printk(KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev);
1009 + WARN(1, KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev);
1011 return (SSB_TMSLOW_REJECT | SSB_TMSLOW_REJECT_23);
1013 --- a/drivers/ssb/pci.c
1014 +++ b/drivers/ssb/pci.c
1015 @@ -178,6 +178,18 @@ err_pci:
1016 #define SPEX(_outvar, _offset, _mask, _shift) \
1017 SPEX16(_outvar, _offset, _mask, _shift)
1019 +#define SPEX_ARRAY8(_field, _offset, _mask, _shift) \
1021 + SPEX(_field[0], _offset + 0, _mask, _shift); \
1022 + SPEX(_field[1], _offset + 2, _mask, _shift); \
1023 + SPEX(_field[2], _offset + 4, _mask, _shift); \
1024 + SPEX(_field[3], _offset + 6, _mask, _shift); \
1025 + SPEX(_field[4], _offset + 8, _mask, _shift); \
1026 + SPEX(_field[5], _offset + 10, _mask, _shift); \
1027 + SPEX(_field[6], _offset + 12, _mask, _shift); \
1028 + SPEX(_field[7], _offset + 14, _mask, _shift); \
1032 static inline u8 ssb_crc8(u8 crc, u8 data)
1034 @@ -331,7 +343,6 @@ static void sprom_extract_r123(struct ss
1041 if (out->revision == 3) /* rev 3 moved MAC */
1042 @@ -361,8 +372,9 @@ static void sprom_extract_r123(struct ss
1043 SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14);
1044 SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15);
1045 SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
1046 - SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
1047 - SSB_SPROM1_BINF_CCODE_SHIFT);
1048 + if (out->revision == 1)
1049 + SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
1050 + SSB_SPROM1_BINF_CCODE_SHIFT);
1051 SPEX(ant_available_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA,
1052 SSB_SPROM1_BINF_ANTA_SHIFT);
1053 SPEX(ant_available_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG,
1054 @@ -388,22 +400,16 @@ static void sprom_extract_r123(struct ss
1055 SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
1056 if (out->revision >= 2)
1057 SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
1058 + SPEX(alpha2[0], SSB_SPROM1_CCODE, 0xff00, 8);
1059 + SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0);
1061 /* Extract the antenna gain values. */
1062 - gain = r123_extract_antgain(out->revision, in,
1063 - SSB_SPROM1_AGAIN_BG,
1064 - SSB_SPROM1_AGAIN_BG_SHIFT);
1065 - out->antenna_gain.ghz24.a0 = gain;
1066 - out->antenna_gain.ghz24.a1 = gain;
1067 - out->antenna_gain.ghz24.a2 = gain;
1068 - out->antenna_gain.ghz24.a3 = gain;
1069 - gain = r123_extract_antgain(out->revision, in,
1070 - SSB_SPROM1_AGAIN_A,
1071 - SSB_SPROM1_AGAIN_A_SHIFT);
1072 - out->antenna_gain.ghz5.a0 = gain;
1073 - out->antenna_gain.ghz5.a1 = gain;
1074 - out->antenna_gain.ghz5.a2 = gain;
1075 - out->antenna_gain.ghz5.a3 = gain;
1076 + out->antenna_gain.a0 = r123_extract_antgain(out->revision, in,
1077 + SSB_SPROM1_AGAIN_BG,
1078 + SSB_SPROM1_AGAIN_BG_SHIFT);
1079 + out->antenna_gain.a1 = r123_extract_antgain(out->revision, in,
1080 + SSB_SPROM1_AGAIN_A,
1081 + SSB_SPROM1_AGAIN_A_SHIFT);
1084 /* Revs 4 5 and 8 have partially shared layout */
1085 @@ -464,14 +470,17 @@ static void sprom_extract_r45(struct ssb
1086 SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0);
1087 SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A,
1088 SSB_SPROM4_ETHPHY_ET1A_SHIFT);
1089 + SPEX(board_rev, SSB_SPROM4_BOARDREV, 0xFFFF, 0);
1090 if (out->revision == 4) {
1091 - SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0);
1092 + SPEX(alpha2[0], SSB_SPROM4_CCODE, 0xff00, 8);
1093 + SPEX(alpha2[1], SSB_SPROM4_CCODE, 0x00ff, 0);
1094 SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
1095 SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0);
1096 SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0);
1097 SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0);
1099 - SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0);
1100 + SPEX(alpha2[0], SSB_SPROM5_CCODE, 0xff00, 8);
1101 + SPEX(alpha2[1], SSB_SPROM5_CCODE, 0x00ff, 0);
1102 SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0);
1103 SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0);
1104 SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0);
1105 @@ -504,16 +513,14 @@ static void sprom_extract_r45(struct ssb
1108 /* Extract the antenna gain values. */
1109 - SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01,
1110 + SPEX(antenna_gain.a0, SSB_SPROM4_AGAIN01,
1111 SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT);
1112 - SPEX(antenna_gain.ghz24.a1, SSB_SPROM4_AGAIN01,
1113 + SPEX(antenna_gain.a1, SSB_SPROM4_AGAIN01,
1114 SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT);
1115 - SPEX(antenna_gain.ghz24.a2, SSB_SPROM4_AGAIN23,
1116 + SPEX(antenna_gain.a2, SSB_SPROM4_AGAIN23,
1117 SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT);
1118 - SPEX(antenna_gain.ghz24.a3, SSB_SPROM4_AGAIN23,
1119 + SPEX(antenna_gain.a3, SSB_SPROM4_AGAIN23,
1120 SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT);
1121 - memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
1122 - sizeof(out->antenna_gain.ghz5));
1124 sprom_extract_r458(out, in);
1126 @@ -523,14 +530,22 @@ static void sprom_extract_r45(struct ssb
1127 static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
1132 + u16 pwr_info_offset[] = {
1133 + SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
1134 + SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
1136 + BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
1137 + ARRAY_SIZE(out->core_pwr_info));
1139 /* extract the MAC address */
1140 for (i = 0; i < 3; i++) {
1141 v = in[SPOFF(SSB_SPROM8_IL0MAC) + i];
1142 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
1144 - SPEX(country_code, SSB_SPROM8_CCODE, 0xFFFF, 0);
1145 + SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0);
1146 + SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
1147 + SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
1148 SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);
1149 SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0);
1150 SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0);
1151 @@ -596,16 +611,46 @@ static void sprom_extract_r8(struct ssb_
1152 SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
1154 /* Extract the antenna gain values. */
1155 - SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01,
1156 + SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
1157 SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
1158 - SPEX(antenna_gain.ghz24.a1, SSB_SPROM8_AGAIN01,
1159 + SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
1160 SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
1161 - SPEX(antenna_gain.ghz24.a2, SSB_SPROM8_AGAIN23,
1162 + SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
1163 SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
1164 - SPEX(antenna_gain.ghz24.a3, SSB_SPROM8_AGAIN23,
1165 + SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
1166 SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
1167 - memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
1168 - sizeof(out->antenna_gain.ghz5));
1170 + /* Extract cores power info info */
1171 + for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
1172 + o = pwr_info_offset[i];
1173 + SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
1174 + SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
1175 + SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
1176 + SSB_SPROM8_2G_MAXP, 0);
1178 + SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
1179 + SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
1180 + SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
1182 + SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
1183 + SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
1184 + SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
1185 + SSB_SPROM8_5G_MAXP, 0);
1186 + SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
1187 + SSB_SPROM8_5GH_MAXP, 0);
1188 + SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
1189 + SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
1191 + SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
1192 + SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
1193 + SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
1194 + SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
1195 + SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
1196 + SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
1197 + SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
1198 + SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
1199 + SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
1202 /* Extract FEM info */
1203 SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G,
1204 @@ -630,6 +675,63 @@ static void sprom_extract_r8(struct ssb_
1205 SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G,
1206 SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT);
1208 + SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
1209 + SSB_SPROM8_LEDDC_ON_SHIFT);
1210 + SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF,
1211 + SSB_SPROM8_LEDDC_OFF_SHIFT);
1213 + SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN,
1214 + SSB_SPROM8_TXRXC_TXCHAIN_SHIFT);
1215 + SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN,
1216 + SSB_SPROM8_TXRXC_RXCHAIN_SHIFT);
1217 + SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH,
1218 + SSB_SPROM8_TXRXC_SWITCH_SHIFT);
1220 + SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0);
1222 + SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0);
1223 + SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0);
1224 + SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0);
1225 + SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0);
1227 + SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP,
1228 + SSB_SPROM8_RAWTS_RAWTEMP_SHIFT);
1229 + SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER,
1230 + SSB_SPROM8_RAWTS_MEASPOWER_SHIFT);
1231 + SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX,
1232 + SSB_SPROM8_OPT_CORRX_TEMP_SLOPE,
1233 + SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT);
1234 + SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX,
1235 + SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT);
1236 + SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX,
1237 + SSB_SPROM8_OPT_CORRX_TEMP_OPTION,
1238 + SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT);
1239 + SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP,
1240 + SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR,
1241 + SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT);
1242 + SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP,
1243 + SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP,
1244 + SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT);
1245 + SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL,
1246 + SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT);
1248 + SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0);
1249 + SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0);
1250 + SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0);
1251 + SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0);
1253 + SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH,
1254 + SSB_SPROM8_THERMAL_TRESH_SHIFT);
1255 + SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET,
1256 + SSB_SPROM8_THERMAL_OFFSET_SHIFT);
1257 + SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA,
1258 + SSB_SPROM8_TEMPDELTA_PHYCAL,
1259 + SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT);
1260 + SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD,
1261 + SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT);
1262 + SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA,
1263 + SSB_SPROM8_TEMPDELTA_HYSTERESIS,
1264 + SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT);
1265 sprom_extract_r458(out, in);
1267 /* TODO - get remaining rev 8 stuff needed */
1268 @@ -759,7 +861,6 @@ static void ssb_pci_get_boardinfo(struct
1270 bi->vendor = bus->host_pci->subsystem_vendor;
1271 bi->type = bus->host_pci->subsystem_device;
1272 - bi->rev = bus->host_pci->revision;
1275 int ssb_pci_get_invariants(struct ssb_bus *bus,
1276 --- a/drivers/ssb/pcmcia.c
1277 +++ b/drivers/ssb/pcmcia.c
1278 @@ -676,14 +676,10 @@ static int ssb_pcmcia_do_get_invariants(
1279 case SSB_PCMCIA_CIS_ANTGAIN:
1280 GOTO_ERROR_ON(tuple->TupleDataLen != 2,
1282 - sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1];
1283 - sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1];
1284 - sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1];
1285 - sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1];
1286 - sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1];
1287 - sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1];
1288 - sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1];
1289 - sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1];
1290 + sprom->antenna_gain.a0 = tuple->TupleData[1];
1291 + sprom->antenna_gain.a1 = tuple->TupleData[1];
1292 + sprom->antenna_gain.a2 = tuple->TupleData[1];
1293 + sprom->antenna_gain.a3 = tuple->TupleData[1];
1295 case SSB_PCMCIA_CIS_BFLAGS:
1296 GOTO_ERROR_ON((tuple->TupleDataLen != 3) &&
1297 --- a/drivers/ssb/scan.c
1298 +++ b/drivers/ssb/scan.c
1299 @@ -90,6 +90,8 @@ const char *ssb_core_name(u16 coreid)
1301 case SSB_DEV_ARM_7TDMI:
1303 + case SSB_DEV_ARM_CM3:
1304 + return "ARM Cortex M3";
1308 @@ -318,6 +320,9 @@ int ssb_bus_scan(struct ssb_bus *bus,
1309 bus->chip_package = 0;
1312 + ssb_printk(KERN_INFO PFX "Found chip with id 0x%04X, rev 0x%02X and "
1313 + "package 0x%02X\n", bus->chip_id, bus->chip_rev,
1314 + bus->chip_package);
1315 if (!bus->nr_devices)
1316 bus->nr_devices = chipid_to_nrcores(bus->chip_id);
1317 if (bus->nr_devices > ARRAY_SIZE(bus->devices)) {
1318 --- a/drivers/ssb/sdio.c
1319 +++ b/drivers/ssb/sdio.c
1320 @@ -551,14 +551,10 @@ int ssb_sdio_get_invariants(struct ssb_b
1321 case SSB_SDIO_CIS_ANTGAIN:
1322 GOTO_ERROR_ON(tuple->size != 2,
1324 - sprom->antenna_gain.ghz24.a0 = tuple->data[1];
1325 - sprom->antenna_gain.ghz24.a1 = tuple->data[1];
1326 - sprom->antenna_gain.ghz24.a2 = tuple->data[1];
1327 - sprom->antenna_gain.ghz24.a3 = tuple->data[1];
1328 - sprom->antenna_gain.ghz5.a0 = tuple->data[1];
1329 - sprom->antenna_gain.ghz5.a1 = tuple->data[1];
1330 - sprom->antenna_gain.ghz5.a2 = tuple->data[1];
1331 - sprom->antenna_gain.ghz5.a3 = tuple->data[1];
1332 + sprom->antenna_gain.a0 = tuple->data[1];
1333 + sprom->antenna_gain.a1 = tuple->data[1];
1334 + sprom->antenna_gain.a2 = tuple->data[1];
1335 + sprom->antenna_gain.a3 = tuple->data[1];
1337 case SSB_SDIO_CIS_BFLAGS:
1338 GOTO_ERROR_ON((tuple->size != 3) &&
1339 --- a/drivers/ssb/ssb_private.h
1340 +++ b/drivers/ssb/ssb_private.h
1343 #include <linux/ssb/ssb.h>
1344 #include <linux/types.h>
1345 +#include <linux/bcm47xx_wdt.h>
1349 @@ -207,4 +208,66 @@ static inline void b43_pci_ssb_bridge_ex
1351 #endif /* CONFIG_SSB_B43_PCI_BRIDGE */
1353 +/* driver_chipcommon_pmu.c */
1354 +extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc);
1355 +extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc);
1356 +extern u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc);
1358 +extern u32 ssb_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt,
1360 +extern u32 ssb_chipco_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms);
1362 +/* driver_chipcommon_sflash.c */
1363 +#ifdef CONFIG_SSB_SFLASH
1364 +int ssb_sflash_init(struct ssb_chipcommon *cc);
1366 +static inline int ssb_sflash_init(struct ssb_chipcommon *cc)
1368 + pr_err("Serial flash not supported\n");
1371 +#endif /* CONFIG_SSB_SFLASH */
1373 +#ifdef CONFIG_SSB_DRIVER_EXTIF
1374 +extern u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks);
1375 +extern u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms);
1377 +static inline u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt,
1382 +static inline u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt,
1389 +#ifdef CONFIG_SSB_EMBEDDED
1390 +extern int ssb_watchdog_register(struct ssb_bus *bus);
1391 +#else /* CONFIG_SSB_EMBEDDED */
1392 +static inline int ssb_watchdog_register(struct ssb_bus *bus)
1396 +#endif /* CONFIG_SSB_EMBEDDED */
1398 +#ifdef CONFIG_SSB_DRIVER_EXTIF
1399 +extern void ssb_extif_init(struct ssb_extif *extif);
1401 +static inline void ssb_extif_init(struct ssb_extif *extif)
1406 +#ifdef CONFIG_SSB_DRIVER_GPIO
1407 +extern int ssb_gpio_init(struct ssb_bus *bus);
1408 +#else /* CONFIG_SSB_DRIVER_GPIO */
1409 +static inline int ssb_gpio_init(struct ssb_bus *bus)
1413 +#endif /* CONFIG_SSB_DRIVER_GPIO */
1415 #endif /* LINUX_SSB_PRIVATE_H_ */
1416 --- a/include/linux/ssb/ssb.h
1417 +++ b/include/linux/ssb/ssb.h
1419 #include <linux/types.h>
1420 #include <linux/spinlock.h>
1421 #include <linux/pci.h>
1422 +#include <linux/gpio.h>
1423 #include <linux/mod_devicetable.h>
1424 #include <linux/dma-mapping.h>
1425 +#include <linux/platform_device.h>
1427 #include <linux/ssb/ssb_regs.h>
1429 @@ -16,6 +18,12 @@ struct pcmcia_device;
1433 +struct ssb_sprom_core_pwr_info {
1434 + u8 itssi_2g, itssi_5g;
1435 + u8 maxpwr_2g, maxpwr_5gl, maxpwr_5g, maxpwr_5gh;
1436 + u16 pa_2g[4], pa_5gl[4], pa_5g[4], pa_5gh[4];
1441 u8 il0mac[6]; /* MAC address for 802.11b/g */
1442 @@ -26,9 +34,12 @@ struct ssb_sprom {
1443 u8 et0mdcport; /* MDIO for enet0 */
1444 u8 et1mdcport; /* MDIO for enet1 */
1445 u16 board_rev; /* Board revision number from SPROM. */
1446 + u16 board_num; /* Board number from SPROM. */
1447 + u16 board_type; /* Board type from SPROM. */
1448 u8 country_code; /* Country Code */
1449 - u16 leddc_on_time; /* LED Powersave Duty Cycle On Count */
1450 - u16 leddc_off_time; /* LED Powersave Duty Cycle Off Count */
1451 + char alpha2[2]; /* Country Code as two chars like EU or US */
1452 + u8 leddc_on_time; /* LED Powersave Duty Cycle On Count */
1453 + u8 leddc_off_time; /* LED Powersave Duty Cycle Off Count */
1454 u8 ant_available_a; /* 2GHz antenna available bits (up to 4) */
1455 u8 ant_available_bg; /* 5GHz antenna available bits (up to 4) */
1457 @@ -47,10 +58,10 @@ struct ssb_sprom {
1458 u8 gpio1; /* GPIO pin 1 */
1459 u8 gpio2; /* GPIO pin 2 */
1460 u8 gpio3; /* GPIO pin 3 */
1461 - u16 maxpwr_bg; /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
1462 - u16 maxpwr_al; /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
1463 - u16 maxpwr_a; /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
1464 - u16 maxpwr_ah; /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
1465 + u8 maxpwr_bg; /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
1466 + u8 maxpwr_al; /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
1467 + u8 maxpwr_a; /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
1468 + u8 maxpwr_ah; /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
1469 u8 itssi_a; /* Idle TSSI Target for A-PHY */
1470 u8 itssi_bg; /* Idle TSSI Target for B/G-PHY */
1471 u8 tri2g; /* 2.4GHz TX isolation */
1472 @@ -61,8 +72,8 @@ struct ssb_sprom {
1473 u8 txpid5gl[4]; /* 4.9 - 5.1GHz TX power index */
1474 u8 txpid5g[4]; /* 5.1 - 5.5GHz TX power index */
1475 u8 txpid5gh[4]; /* 5.5 - ...GHz TX power index */
1476 - u8 rxpo2g; /* 2GHz RX power offset */
1477 - u8 rxpo5g; /* 5GHz RX power offset */
1478 + s8 rxpo2g; /* 2GHz RX power offset */
1479 + s8 rxpo5g; /* 5GHz RX power offset */
1480 u8 rssisav2g; /* 2GHz RSSI params */
1483 @@ -82,16 +93,13 @@ struct ssb_sprom {
1484 u16 boardflags2_hi; /* Board flags (bits 48-63) */
1485 /* TODO store board flags in a single u64 */
1487 + struct ssb_sprom_core_pwr_info core_pwr_info[4];
1489 /* Antenna gain values for up to 4 antennas
1490 * on each band. Values in dBm/4 (Q5.2). Negative gain means the
1491 * loss in the connectors is bigger than the gain. */
1494 - s8 a0, a1, a2, a3;
1495 - } ghz24; /* 2.4GHz band */
1497 - s8 a0, a1, a2, a3;
1498 - } ghz5; /* 5GHz band */
1499 + s8 a0, a1, a2, a3;
1503 @@ -103,14 +111,85 @@ struct ssb_sprom {
1507 - /* TODO - add any parameters needed from rev 2, 3, 4, 5 or 8 SPROMs */
1514 + u8 rxgainerr2ga[3];
1515 + u8 rxgainerr5gla[3];
1516 + u8 rxgainerr5gma[3];
1517 + u8 rxgainerr5gha[3];
1518 + u8 rxgainerr5gua[3];
1520 + u8 noiselvl2ga[3];
1521 + u8 noiselvl5gla[3];
1522 + u8 noiselvl5gma[3];
1523 + u8 noiselvl5gha[3];
1524 + u8 noiselvl5gua[3];
1539 + u8 tempsense_slope;
1541 + u8 tempsense_option;
1542 + u8 freqoffset_corr;
1547 + u8 phycal_tempdelta;
1549 + u8 temps_hysteresis;
1552 + u8 pcieingress_war;
1554 + /* power per rate from sromrev 9 */
1556 + u16 cckbw20ul2gpo;
1557 + u32 legofdmbw202gpo;
1558 + u32 legofdmbw20ul2gpo;
1559 + u32 legofdmbw205glpo;
1560 + u32 legofdmbw20ul5glpo;
1561 + u32 legofdmbw205gmpo;
1562 + u32 legofdmbw20ul5gmpo;
1563 + u32 legofdmbw205ghpo;
1564 + u32 legofdmbw20ul5ghpo;
1566 + u32 mcsbw20ul2gpo;
1569 + u32 mcsbw20ul5glpo;
1572 + u32 mcsbw20ul5gmpo;
1575 + u32 mcsbw20ul5ghpo;
1578 + u16 legofdm40duppo;
1583 /* Information about the PCB the circuitry is soldered on. */
1584 struct ssb_boardinfo {
1591 @@ -166,6 +245,7 @@ struct ssb_bus_ops {
1592 #define SSB_DEV_MINI_MACPHY 0x823
1593 #define SSB_DEV_ARM_1176 0x824
1594 #define SSB_DEV_ARM_7TDMI 0x825
1595 +#define SSB_DEV_ARM_CM3 0x82A
1597 /* Vendor-ID values */
1598 #define SSB_VENDOR_BROADCOM 0x4243
1599 @@ -354,7 +434,11 @@ struct ssb_bus {
1600 #ifdef CONFIG_SSB_EMBEDDED
1601 /* Lock for GPIO register access. */
1602 spinlock_t gpio_lock;
1603 + struct platform_device *watchdog;
1604 #endif /* EMBEDDED */
1605 +#ifdef CONFIG_SSB_DRIVER_GPIO
1606 + struct gpio_chip gpio;
1607 +#endif /* DRIVER_GPIO */
1609 /* Internal-only stuff follows. Do not touch. */
1610 struct list_head list;
1611 --- a/include/linux/ssb/ssb_driver_chipcommon.h
1612 +++ b/include/linux/ssb/ssb_driver_chipcommon.h
1614 #define SSB_CHIPCO_FLASHCTL_ST_SE 0x02D8 /* Sector Erase */
1615 #define SSB_CHIPCO_FLASHCTL_ST_BE 0x00C7 /* Bulk Erase */
1616 #define SSB_CHIPCO_FLASHCTL_ST_DP 0x00B9 /* Deep Power-down */
1617 -#define SSB_CHIPCO_FLASHCTL_ST_RSIG 0x03AB /* Read Electronic Signature */
1618 +#define SSB_CHIPCO_FLASHCTL_ST_RES 0x03AB /* Read Electronic Signature */
1619 +#define SSB_CHIPCO_FLASHCTL_ST_CSA 0x1000 /* Keep chip select asserted */
1620 +#define SSB_CHIPCO_FLASHCTL_ST_SSE 0x0220 /* Sub-sector Erase */
1622 /* Status register bits for ST flashes */
1623 #define SSB_CHIPCO_FLASHSTA_ST_WIP 0x01 /* Write In Progress */
1624 @@ -588,7 +590,10 @@ struct ssb_chipcommon {
1626 /* Fast Powerup Delay constant */
1627 u16 fast_pwrup_delay;
1628 + spinlock_t gpio_lock;
1629 struct ssb_chipcommon_pmu pmu;
1634 static inline bool ssb_chipco_available(struct ssb_chipcommon *cc)
1635 @@ -628,8 +633,7 @@ enum ssb_clkmode {
1636 extern void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc,
1637 enum ssb_clkmode mode);
1639 -extern void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc,
1641 +extern u32 ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks);
1643 void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value);
1645 @@ -642,6 +646,8 @@ u32 ssb_chipco_gpio_outen(struct ssb_chi
1646 u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value);
1647 u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value);
1648 u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value);
1649 +u32 ssb_chipco_gpio_pullup(struct ssb_chipcommon *cc, u32 mask, u32 value);
1650 +u32 ssb_chipco_gpio_pulldown(struct ssb_chipcommon *cc, u32 mask, u32 value);
1652 #ifdef CONFIG_SSB_SERIAL
1653 extern int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
1654 --- a/include/linux/ssb/ssb_driver_extif.h
1655 +++ b/include/linux/ssb/ssb_driver_extif.h
1656 @@ -152,12 +152,16 @@
1658 #define SSB_EXTIF_WATCHDOG_CLK 48000000 /* Hz */
1660 +#define SSB_EXTIF_WATCHDOG_MAX_TIMER ((1 << 28) - 1)
1661 +#define SSB_EXTIF_WATCHDOG_MAX_TIMER_MS (SSB_EXTIF_WATCHDOG_MAX_TIMER \
1662 + / (SSB_EXTIF_WATCHDOG_CLK / 1000))
1665 #ifdef CONFIG_SSB_DRIVER_EXTIF
1668 struct ssb_device *dev;
1669 + spinlock_t gpio_lock;
1672 static inline bool ssb_extif_available(struct ssb_extif *extif)
1673 @@ -171,8 +175,7 @@ extern void ssb_extif_get_clockcontrol(s
1674 extern void ssb_extif_timing_init(struct ssb_extif *extif,
1677 -extern void ssb_extif_watchdog_timer_set(struct ssb_extif *extif,
1679 +extern u32 ssb_extif_watchdog_timer_set(struct ssb_extif *extif, u32 ticks);
1681 /* Extif GPIO pin access */
1682 u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask);
1683 @@ -205,10 +208,52 @@ void ssb_extif_get_clockcontrol(struct s
1687 -void ssb_extif_watchdog_timer_set(struct ssb_extif *extif,
1689 +void ssb_extif_timing_init(struct ssb_extif *extif, unsigned long ns)
1694 +u32 ssb_extif_watchdog_timer_set(struct ssb_extif *extif, u32 ticks)
1699 +static inline u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)
1704 +static inline u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask,
1710 +static inline u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask,
1716 +static inline u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask,
1722 +static inline u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask,
1728 +#ifdef CONFIG_SSB_SERIAL
1729 +static inline int ssb_extif_serial_init(struct ssb_extif *extif,
1730 + struct ssb_serial_port *ports)
1734 +#endif /* CONFIG_SSB_SERIAL */
1736 #endif /* CONFIG_SSB_DRIVER_EXTIF */
1737 #endif /* LINUX_SSB_EXTIFCORE_H_ */
1738 --- a/include/linux/ssb/ssb_driver_gige.h
1739 +++ b/include/linux/ssb/ssb_driver_gige.h
1741 #define LINUX_SSB_DRIVER_GIGE_H_
1743 #include <linux/ssb/ssb.h>
1744 +#include <linux/bug.h>
1745 #include <linux/pci.h>
1746 #include <linux/spinlock.h>
1748 --- a/include/linux/ssb/ssb_driver_mips.h
1749 +++ b/include/linux/ssb/ssb_driver_mips.h
1750 @@ -13,6 +13,12 @@ struct ssb_serial_port {
1751 unsigned int reg_shift;
1754 +struct ssb_pflash {
1761 struct ssb_mipscore {
1762 struct ssb_device *dev;
1763 @@ -20,9 +26,7 @@ struct ssb_mipscore {
1764 int nr_serial_ports;
1765 struct ssb_serial_port serial_ports[4];
1767 - u8 flash_buswidth;
1769 - u32 flash_window_size;
1770 + struct ssb_pflash pflash;
1773 extern void ssb_mipscore_init(struct ssb_mipscore *mcore);
1774 --- a/include/linux/ssb/ssb_regs.h
1775 +++ b/include/linux/ssb/ssb_regs.h
1777 #define SSB_SPROM1_AGAIN_BG_SHIFT 0
1778 #define SSB_SPROM1_AGAIN_A 0xFF00 /* A-PHY */
1779 #define SSB_SPROM1_AGAIN_A_SHIFT 8
1780 +#define SSB_SPROM1_CCODE 0x0076
1782 /* SPROM Revision 2 (inherits from rev 1) */
1783 #define SSB_SPROM2_BFLHI 0x0038 /* Boardflags (high 16 bits) */
1785 #define SSB_SPROM3_OFDMGPO 0x107A /* G-PHY OFDM Power Offset (4 bytes, BigEndian) */
1787 /* SPROM Revision 4 */
1788 +#define SSB_SPROM4_BOARDREV 0x0042 /* Board revision */
1789 #define SSB_SPROM4_BFLLO 0x0044 /* Boardflags (low 16 bits) */
1790 #define SSB_SPROM4_BFLHI 0x0046 /* Board Flags Hi */
1791 #define SSB_SPROM4_BFL2LO 0x0048 /* Board flags 2 (low 16 bits) */
1792 @@ -389,6 +391,11 @@
1793 #define SSB_SPROM8_GPIOB_P2 0x00FF /* Pin 2 */
1794 #define SSB_SPROM8_GPIOB_P3 0xFF00 /* Pin 3 */
1795 #define SSB_SPROM8_GPIOB_P3_SHIFT 8
1796 +#define SSB_SPROM8_LEDDC 0x009A
1797 +#define SSB_SPROM8_LEDDC_ON 0xFF00 /* oncount */
1798 +#define SSB_SPROM8_LEDDC_ON_SHIFT 8
1799 +#define SSB_SPROM8_LEDDC_OFF 0x00FF /* offcount */
1800 +#define SSB_SPROM8_LEDDC_OFF_SHIFT 0
1801 #define SSB_SPROM8_ANTAVAIL 0x009C /* Antenna available bitfields*/
1802 #define SSB_SPROM8_ANTAVAIL_A 0xFF00 /* A-PHY bitfield */
1803 #define SSB_SPROM8_ANTAVAIL_A_SHIFT 8
1804 @@ -404,6 +411,13 @@
1805 #define SSB_SPROM8_AGAIN2_SHIFT 0
1806 #define SSB_SPROM8_AGAIN3 0xFF00 /* Antenna 3 */
1807 #define SSB_SPROM8_AGAIN3_SHIFT 8
1808 +#define SSB_SPROM8_TXRXC 0x00A2
1809 +#define SSB_SPROM8_TXRXC_TXCHAIN 0x000f
1810 +#define SSB_SPROM8_TXRXC_TXCHAIN_SHIFT 0
1811 +#define SSB_SPROM8_TXRXC_RXCHAIN 0x00f0
1812 +#define SSB_SPROM8_TXRXC_RXCHAIN_SHIFT 4
1813 +#define SSB_SPROM8_TXRXC_SWITCH 0xff00
1814 +#define SSB_SPROM8_TXRXC_SWITCH_SHIFT 8
1815 #define SSB_SPROM8_RSSIPARM2G 0x00A4 /* RSSI params for 2GHz */
1816 #define SSB_SPROM8_RSSISMF2G 0x000F
1817 #define SSB_SPROM8_RSSISMC2G 0x00F0
1819 #define SSB_SPROM8_TRI5GH_SHIFT 8
1820 #define SSB_SPROM8_RXPO 0x00AC /* RX power offsets */
1821 #define SSB_SPROM8_RXPO2G 0x00FF /* 2GHz RX power offset */
1822 +#define SSB_SPROM8_RXPO2G_SHIFT 0
1823 #define SSB_SPROM8_RXPO5G 0xFF00 /* 5GHz RX power offset */
1824 #define SSB_SPROM8_RXPO5G_SHIFT 8
1825 #define SSB_SPROM8_FEM2G 0x00AE
1826 @@ -445,10 +460,71 @@
1827 #define SSB_SROM8_FEM_ANTSWLUT 0xF800
1828 #define SSB_SROM8_FEM_ANTSWLUT_SHIFT 11
1829 #define SSB_SPROM8_THERMAL 0x00B2
1830 -#define SSB_SPROM8_MPWR_RAWTS 0x00B4
1831 -#define SSB_SPROM8_TS_SLP_OPT_CORRX 0x00B6
1832 -#define SSB_SPROM8_FOC_HWIQ_IQSWP 0x00B8
1833 -#define SSB_SPROM8_PHYCAL_TEMPDELTA 0x00BA
1834 +#define SSB_SPROM8_THERMAL_OFFSET 0x00ff
1835 +#define SSB_SPROM8_THERMAL_OFFSET_SHIFT 0
1836 +#define SSB_SPROM8_THERMAL_TRESH 0xff00
1837 +#define SSB_SPROM8_THERMAL_TRESH_SHIFT 8
1838 +/* Temp sense related entries */
1839 +#define SSB_SPROM8_RAWTS 0x00B4
1840 +#define SSB_SPROM8_RAWTS_RAWTEMP 0x01ff
1841 +#define SSB_SPROM8_RAWTS_RAWTEMP_SHIFT 0
1842 +#define SSB_SPROM8_RAWTS_MEASPOWER 0xfe00
1843 +#define SSB_SPROM8_RAWTS_MEASPOWER_SHIFT 9
1844 +#define SSB_SPROM8_OPT_CORRX 0x00B6
1845 +#define SSB_SPROM8_OPT_CORRX_TEMP_SLOPE 0x00ff
1846 +#define SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT 0
1847 +#define SSB_SPROM8_OPT_CORRX_TEMPCORRX 0xfc00
1848 +#define SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT 10
1849 +#define SSB_SPROM8_OPT_CORRX_TEMP_OPTION 0x0300
1850 +#define SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT 8
1851 +/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, IQSWP: IQ CAL swap disable */
1852 +#define SSB_SPROM8_HWIQ_IQSWP 0x00B8
1853 +#define SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR 0x000f
1854 +#define SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT 0
1855 +#define SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP 0x0010
1856 +#define SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT 4
1857 +#define SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL 0x0020
1858 +#define SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT 5
1859 +#define SSB_SPROM8_TEMPDELTA 0x00BC
1860 +#define SSB_SPROM8_TEMPDELTA_PHYCAL 0x00ff
1861 +#define SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT 0
1862 +#define SSB_SPROM8_TEMPDELTA_PERIOD 0x0f00
1863 +#define SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT 8
1864 +#define SSB_SPROM8_TEMPDELTA_HYSTERESIS 0xf000
1865 +#define SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT 12
1867 +/* There are 4 blocks with power info sharing the same layout */
1868 +#define SSB_SROM8_PWR_INFO_CORE0 0x00C0
1869 +#define SSB_SROM8_PWR_INFO_CORE1 0x00E0
1870 +#define SSB_SROM8_PWR_INFO_CORE2 0x0100
1871 +#define SSB_SROM8_PWR_INFO_CORE3 0x0120
1873 +#define SSB_SROM8_2G_MAXP_ITSSI 0x00
1874 +#define SSB_SPROM8_2G_MAXP 0x00FF
1875 +#define SSB_SPROM8_2G_ITSSI 0xFF00
1876 +#define SSB_SPROM8_2G_ITSSI_SHIFT 8
1877 +#define SSB_SROM8_2G_PA_0 0x02 /* 2GHz power amp settings */
1878 +#define SSB_SROM8_2G_PA_1 0x04
1879 +#define SSB_SROM8_2G_PA_2 0x06
1880 +#define SSB_SROM8_5G_MAXP_ITSSI 0x08 /* 5GHz ITSSI and 5.3GHz Max Power */
1881 +#define SSB_SPROM8_5G_MAXP 0x00FF
1882 +#define SSB_SPROM8_5G_ITSSI 0xFF00
1883 +#define SSB_SPROM8_5G_ITSSI_SHIFT 8
1884 +#define SSB_SPROM8_5GHL_MAXP 0x0A /* 5.2GHz and 5.8GHz Max Power */
1885 +#define SSB_SPROM8_5GH_MAXP 0x00FF
1886 +#define SSB_SPROM8_5GL_MAXP 0xFF00
1887 +#define SSB_SPROM8_5GL_MAXP_SHIFT 8
1888 +#define SSB_SROM8_5G_PA_0 0x0C /* 5.3GHz power amp settings */
1889 +#define SSB_SROM8_5G_PA_1 0x0E
1890 +#define SSB_SROM8_5G_PA_2 0x10
1891 +#define SSB_SROM8_5GL_PA_0 0x12 /* 5.2GHz power amp settings */
1892 +#define SSB_SROM8_5GL_PA_1 0x14
1893 +#define SSB_SROM8_5GL_PA_2 0x16
1894 +#define SSB_SROM8_5GH_PA_0 0x18 /* 5.8GHz power amp settings */
1895 +#define SSB_SROM8_5GH_PA_1 0x1A
1896 +#define SSB_SROM8_5GH_PA_2 0x1C
1898 +/* TODO: Make it deprecated */
1899 #define SSB_SPROM8_MAXP_BG 0x00C0 /* Max Power 2GHz in path 1 */
1900 #define SSB_SPROM8_MAXP_BG_MASK 0x00FF /* Mask for Max Power 2GHz */
1901 #define SSB_SPROM8_ITSSI_BG 0xFF00 /* Mask for path 1 itssi_bg */
1902 @@ -473,12 +549,23 @@
1903 #define SSB_SPROM8_PA1HIB0 0x00D8 /* 5.8GHz power amp settings */
1904 #define SSB_SPROM8_PA1HIB1 0x00DA
1905 #define SSB_SPROM8_PA1HIB2 0x00DC
1907 #define SSB_SPROM8_CCK2GPO 0x0140 /* CCK power offset */
1908 #define SSB_SPROM8_OFDM2GPO 0x0142 /* 2.4GHz OFDM power offset */
1909 #define SSB_SPROM8_OFDM5GPO 0x0146 /* 5.3GHz OFDM power offset */
1910 #define SSB_SPROM8_OFDM5GLPO 0x014A /* 5.2GHz OFDM power offset */
1911 #define SSB_SPROM8_OFDM5GHPO 0x014E /* 5.8GHz OFDM power offset */
1913 +#define SSB_SPROM8_2G_MCSPO 0x0152
1914 +#define SSB_SPROM8_5G_MCSPO 0x0162
1915 +#define SSB_SPROM8_5GL_MCSPO 0x0172
1916 +#define SSB_SPROM8_5GH_MCSPO 0x0182
1918 +#define SSB_SPROM8_CDDPO 0x0192
1919 +#define SSB_SPROM8_STBCPO 0x0194
1920 +#define SSB_SPROM8_BW40PO 0x0196
1921 +#define SSB_SPROM8_BWDUPPO 0x0198
1923 /* Values for boardflags_lo read from SPROM */
1924 #define SSB_BFL_BTCOEXIST 0x0001 /* implements Bluetooth coexistance */
1925 #define SSB_BFL_PACTRL 0x0002 /* GPIO 9 controlling the PA */
1927 +++ b/include/linux/bcm47xx_wdt.h
1929 +#ifndef LINUX_BCM47XX_WDT_H_
1930 +#define LINUX_BCM47XX_WDT_H_
1932 +#include <linux/types.h>
1935 +struct bcm47xx_wdt {
1936 + u32 (*timer_set)(struct bcm47xx_wdt *, u32);
1937 + u32 (*timer_set_ms)(struct bcm47xx_wdt *, u32);
1940 + void *driver_data;
1943 +static inline void *bcm47xx_wdt_get_drvdata(struct bcm47xx_wdt *wdt)
1945 + return wdt->driver_data;
1947 +#endif /* LINUX_BCM47XX_WDT_H_ */