diff options
Diffstat (limited to 'drivers/ssb')
-rw-r--r-- | drivers/ssb/main.c | 44 | ||||
-rw-r--r-- | drivers/ssb/pci.c | 8 | ||||
-rw-r--r-- | drivers/ssb/sprom.c | 2 |
3 files changed, 38 insertions, 16 deletions
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 3918d2cc585..e05ba6eefc7 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -1192,10 +1192,10 @@ void ssb_device_enable(struct ssb_device *dev, u32 core_specific_flags) } EXPORT_SYMBOL(ssb_device_enable); -/* Wait for a bit in a register to get set or unset. +/* Wait for bitmask in a register to get set or cleared. * timeout is in units of ten-microseconds */ -static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask, - int timeout, int set) +static int ssb_wait_bits(struct ssb_device *dev, u16 reg, u32 bitmask, + int timeout, int set) { int i; u32 val; @@ -1203,7 +1203,7 @@ static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask, for (i = 0; i < timeout; i++) { val = ssb_read32(dev, reg); if (set) { - if (val & bitmask) + if ((val & bitmask) == bitmask) return 0; } else { if (!(val & bitmask)) @@ -1220,20 +1220,38 @@ static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask, void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags) { - u32 reject; + u32 reject, val; if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_RESET) return; reject = ssb_tmslow_reject_bitmask(dev); - ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK); - ssb_wait_bit(dev, SSB_TMSLOW, reject, 1000, 1); - ssb_wait_bit(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0); - ssb_write32(dev, SSB_TMSLOW, - SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | - reject | SSB_TMSLOW_RESET | - core_specific_flags); - ssb_flush_tmslow(dev); + + if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_CLOCK) { + ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK); + ssb_wait_bits(dev, SSB_TMSLOW, reject, 1000, 1); + ssb_wait_bits(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0); + + if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) { + val = ssb_read32(dev, SSB_IMSTATE); + val |= SSB_IMSTATE_REJECT; + ssb_write32(dev, SSB_IMSTATE, val); + ssb_wait_bits(dev, SSB_IMSTATE, SSB_IMSTATE_BUSY, 1000, + 0); + } + + ssb_write32(dev, SSB_TMSLOW, + SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | + reject | SSB_TMSLOW_RESET | + core_specific_flags); + ssb_flush_tmslow(dev); + + if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) { + val = ssb_read32(dev, SSB_IMSTATE); + val &= ~SSB_IMSTATE_REJECT; + ssb_write32(dev, SSB_IMSTATE, val); + } + } ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_RESET | diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 158449e5504..6f34963b3c6 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -468,10 +468,14 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 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(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0); SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0); + SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0); + SPEX(boardflags2_hi, SSB_SPROM5_BFL2HI, 0xFFFF, 0); } SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A, SSB_SPROM4_ANTAVAIL_A_SHIFT); @@ -641,7 +645,7 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, break; default: ssb_printk(KERN_WARNING PFX "Unsupported SPROM" - " revision %d detected. Will extract" + " revision %d detected. Will extract" " v1\n", out->revision); out->revision = 1; sprom_extract_r123(out, in); @@ -666,7 +670,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, ssb_printk(KERN_ERR PFX "No SPROM available!\n"); return -ENODEV; } - if (bus->chipco.dev) { /* can be unavailible! */ + if (bus->chipco.dev) { /* can be unavailable! */ /* * get SPROM offset: SSB_SPROM_BASE1 except for * chipcommon rev >= 31 or chip ID is 0x4312 and diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c index 4f7cc8d1327..5f34d7a3e3a 100644 --- a/drivers/ssb/sprom.c +++ b/drivers/ssb/sprom.c @@ -185,7 +185,7 @@ bool ssb_is_sprom_available(struct ssb_bus *bus) /* this routine differs from specs as we do not access SPROM directly on PCMCIA */ if (bus->bustype == SSB_BUSTYPE_PCI && - bus->chipco.dev && /* can be unavailible! */ + bus->chipco.dev && /* can be unavailable! */ bus->chipco.dev->id.revision >= 31) return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM; |