aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2010-05-14 23:08:58 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-04 15:04:50 -0400
commit9d1ac34ec3a67713308ae0883c3359c557f14d17 (patch)
tree05fedcfbe2192b5a2b0671db9f099d55544d03d0
parentce9426d1908001fb2f7b0152fbe4184bbc0c7b68 (diff)
ssb: Handle alternate SSPROM location
In kernel Bugzilla #15825 (2 users), in a wireless mailing list thread (http://lists.infradead.org/pipermail/b43-dev/2010-May/000124.html), and on a netbook owned by John Linville (http://marc.info/?l=linux-wireless&m=127230751408818&w=4), there are reports of ssb failing to detect an SPROM at the normal location. After studying the MMIO trace dump for the Broadcom wl driver, it was determined that the affected boxes had a relocated SPROM. This patch fixes all systems that have reported this problem. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Cc: Stable <stable@kernel.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/ssb/driver_chipcommon.c1
-rw-r--r--drivers/ssb/pci.c15
2 files changed, 14 insertions, 2 deletions
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
index bda851427780..7c031fdc8205 100644
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -259,6 +259,7 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc)
259 return; /* We don't have a ChipCommon */ 259 return; /* We don't have a ChipCommon */
260 if (cc->dev->id.revision >= 11) 260 if (cc->dev->id.revision >= 11)
261 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); 261 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
262 ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status);
262 ssb_pmu_init(cc); 263 ssb_pmu_init(cc);
263 chipco_powercontrol_init(cc); 264 chipco_powercontrol_init(cc);
264 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); 265 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index 6dcda86be6eb..6e88d2b603b4 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -626,11 +626,22 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
626 return -ENODEV; 626 return -ENODEV;
627 } 627 }
628 if (bus->chipco.dev) { /* can be unavailible! */ 628 if (bus->chipco.dev) { /* can be unavailible! */
629 bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ? 629 /*
630 SSB_SPROM_BASE1 : SSB_SPROM_BASE31; 630 * get SPROM offset: SSB_SPROM_BASE1 except for
631 * chipcommon rev >= 31 or chip ID is 0x4312 and
632 * chipcommon status & 3 == 2
633 */
634 if (bus->chipco.dev->id.revision >= 31)
635 bus->sprom_offset = SSB_SPROM_BASE31;
636 else if (bus->chip_id == 0x4312 &&
637 (bus->chipco.status & 0x03) == 2)
638 bus->sprom_offset = SSB_SPROM_BASE31;
639 else
640 bus->sprom_offset = SSB_SPROM_BASE1;
631 } else { 641 } else {
632 bus->sprom_offset = SSB_SPROM_BASE1; 642 bus->sprom_offset = SSB_SPROM_BASE1;
633 } 643 }
644 ssb_dprintk(KERN_INFO PFX "SPROM offset is 0x%x\n", bus->sprom_offset);
634 645
635 buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); 646 buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
636 if (!buf) 647 if (!buf)