-@@ -254,7 +254,7 @@ static int sprom_do_read(struct ssb_bus
- int i;
-
- for (i = 0; i < bus->sprom_size; i++)
-- sprom[i] = ioread16(bus->mmio + SSB_SPROM_BASE + (i * 2));
-+ sprom[i] = ioread16(bus->mmio + bus->sprom_offset + (i * 2));
-
- return 0;
- }
-@@ -285,7 +285,7 @@ static int sprom_do_write(struct ssb_bus
- ssb_printk("75%%");
- else if (i % 2)
- ssb_printk(".");
-- writew(sprom[i], bus->mmio + SSB_SPROM_BASE + (i * 2));
-+ writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2));
- mmiowb();
- msleep(20);
- }
-@@ -621,6 +621,28 @@ static int ssb_pci_sprom_get(struct ssb_
- int err = -ENOMEM;
- u16 *buf;
-
-+ if (!ssb_is_sprom_available(bus)) {
-+ ssb_printk(KERN_ERR PFX "No SPROM available!\n");
-+ return -ENODEV;
-+ }
-+ if (bus->chipco.dev) { /* can be unavailible! */
-+ /*
-+ * get SPROM offset: SSB_SPROM_BASE1 except for
-+ * chipcommon rev >= 31 or chip ID is 0x4312 and
-+ * chipcommon status & 3 == 2
-+ */
-+ if (bus->chipco.dev->id.revision >= 31)
-+ bus->sprom_offset = SSB_SPROM_BASE31;
-+ else if (bus->chip_id == 0x4312 &&
-+ (bus->chipco.status & 0x03) == 2)
-+ bus->sprom_offset = SSB_SPROM_BASE31;
-+ else
-+ bus->sprom_offset = SSB_SPROM_BASE1;
-+ } else {
-+ bus->sprom_offset = SSB_SPROM_BASE1;
-+ }
-+ ssb_dprintk(KERN_INFO PFX "SPROM offset is 0x%x\n", bus->sprom_offset);
-+
- buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
- if (!buf)
- goto out;
---- a/drivers/ssb/sprom.c
-+++ b/drivers/ssb/sprom.c
-@@ -176,3 +176,18 @@ const struct ssb_sprom *ssb_get_fallback
- {
- return fallback_sprom;
- }
-+
-+/* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */
-+bool ssb_is_sprom_available(struct ssb_bus *bus)
-+{
-+ /* status register only exists on chipcomon rev >= 11 and we need check
-+ for >= 31 only */
-+ /* 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->id.revision >= 31)
-+ return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM;
-+
-+ return true;
-+}