diff options
Diffstat (limited to 'drivers/ssb')
-rw-r--r-- | drivers/ssb/driver_chipcommon.c | 2 | ||||
-rw-r--r-- | drivers/ssb/driver_pcicore.c | 29 | ||||
-rw-r--r-- | drivers/ssb/main.c | 3 | ||||
-rw-r--r-- | drivers/ssb/pci.c | 14 | ||||
-rw-r--r-- | drivers/ssb/sprom.c | 14 |
5 files changed, 30 insertions, 32 deletions
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index 59c3c0fdbecd..59ae76bace14 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c @@ -233,6 +233,8 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc) { if (!cc->dev) return; /* We don't have a ChipCommon */ + if (cc->dev->id.revision >= 11) + cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); ssb_pmu_init(cc); chipco_powercontrol_init(cc); ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index f1dcd7969a5c..0e8d35224614 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c @@ -246,20 +246,12 @@ static struct pci_controller ssb_pcicore_controller = { .pci_ops = &ssb_pcicore_pciops, .io_resource = &ssb_pcicore_io_resource, .mem_resource = &ssb_pcicore_mem_resource, - .mem_offset = 0x24000000, }; -static u32 ssb_pcicore_pcibus_iobase = 0x100; -static u32 ssb_pcicore_pcibus_membase = SSB_PCI_DMA; - /* This function is called when doing a pci_enable_device(). * We must first check if the device is a device on the PCI-core bridge. */ int ssb_pcicore_plat_dev_init(struct pci_dev *d) { - struct resource *res; - int pos, size; - u32 *base; - if (d->bus->ops != &ssb_pcicore_pciops) { /* This is not a device on the PCI-core bridge. */ return -ENODEV; @@ -268,27 +260,6 @@ int ssb_pcicore_plat_dev_init(struct pci_dev *d) ssb_printk(KERN_INFO "PCI: Fixing up device %s\n", pci_name(d)); - /* Fix up resource bases */ - for (pos = 0; pos < 6; pos++) { - res = &d->resource[pos]; - if (res->flags & IORESOURCE_IO) - base = &ssb_pcicore_pcibus_iobase; - else - base = &ssb_pcicore_pcibus_membase; - res->flags |= IORESOURCE_PCI_FIXED; - if (res->end) { - size = res->end - res->start + 1; - if (*base & (size - 1)) - *base = (*base + size) & ~(size - 1); - res->start = *base; - res->end = res->start + size - 1; - *base += size; - pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start); - } - /* Fix up PCI bridge BAR0 only */ - if (d->bus->number == 0 && PCI_SLOT(d->devfn) == 0) - break; - } /* Fix up interrupt lines */ d->irq = ssb_mips_irq(extpci_core->dev) + 2; pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq); diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 80ff7d9e60de..7e5b8a8a64cc 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -834,6 +834,9 @@ int ssb_bus_pcibus_register(struct ssb_bus *bus, if (!err) { ssb_printk(KERN_INFO PFX "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); } return err; diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index a8dbb06623c9..989e2752cc36 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -168,7 +168,7 @@ err_pci: } /* Get the word-offset for a SSB_SPROM_XXX define. */ -#define SPOFF(offset) (((offset) - SSB_SPROM_BASE) / sizeof(u16)) +#define SPOFF(offset) ((offset) / sizeof(u16)) /* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */ #define SPEX16(_outvar, _offset, _mask, _shift) \ out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift)) @@ -254,7 +254,7 @@ static int sprom_do_read(struct ssb_bus *bus, u16 *sprom) 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 *bus, const u16 *sprom) 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,14 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, int err = -ENOMEM; u16 *buf; + if (!ssb_is_sprom_available(bus)) { + ssb_printk(KERN_ERR PFX "No SPROM available!\n"); + return -ENODEV; + } + + bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ? + SSB_SPROM_BASE1 : SSB_SPROM_BASE31; + buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); if (!buf) goto out; diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c index f2f920fef10d..007bc3a03486 100644 --- a/drivers/ssb/sprom.c +++ b/drivers/ssb/sprom.c @@ -176,3 +176,17 @@ const struct ssb_sprom *ssb_get_fallback_sprom(void) { 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->id.revision >= 31) + return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM; + + return true; +} |