diff options
author | Peter Denison <openwrt@marshadder.org> | 2007-06-25 19:51:09 +0000 |
---|---|---|
committer | Peter Denison <openwrt@marshadder.org> | 2007-06-25 19:51:09 +0000 |
commit | eed7b91c68806d8e6c72aabfadf2322b76997e3a (patch) | |
tree | 15ec468516ccbd0e750abf2a62410f7bdca5be8d /target/linux/brcm47xx-2.6/files/drivers/ssb/pci.c | |
parent | 7e4f2dbf6674f1691acbeceacabd54ae4e09b5d4 (diff) | |
download | upstream-eed7b91c68806d8e6c72aabfadf2322b76997e3a.tar.gz upstream-eed7b91c68806d8e6c72aabfadf2322b76997e3a.tar.bz2 upstream-eed7b91c68806d8e6c72aabfadf2322b76997e3a.zip |
Merge SSB driver from tree at bu3sch.de, pulled 24/6
SVN-Revision: 7732
Diffstat (limited to 'target/linux/brcm47xx-2.6/files/drivers/ssb/pci.c')
-rw-r--r-- | target/linux/brcm47xx-2.6/files/drivers/ssb/pci.c | 76 |
1 files changed, 46 insertions, 30 deletions
diff --git a/target/linux/brcm47xx-2.6/files/drivers/ssb/pci.c b/target/linux/brcm47xx-2.6/files/drivers/ssb/pci.c index fcd8e871cb..f9dc28f51f 100644 --- a/target/linux/brcm47xx-2.6/files/drivers/ssb/pci.c +++ b/target/linux/brcm47xx-2.6/files/drivers/ssb/pci.c @@ -330,12 +330,12 @@ static void sprom_extract_r1(struct ssb_sprom_r1 *out, const u16 *in) SPEX(gpio2, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P2, 0); SPEX(gpio3, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P3, SSB_SPROM1_GPIOB_P3_SHIFT); - SPEX(maxpwr_a, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_A, 0); - SPEX(maxpwr_bg, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_BG, - SSB_SPROM1_MAXPWR_BG_SHIFT); - SPEX(itssi_a, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_A, 0); - SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, - SSB_SPROM1_ITSSI_BG_SHIFT); + SPEX(maxpwr_a, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_A, + SSB_SPROM1_MAXPWR_A_SHIFT); + SPEX(maxpwr_bg, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_BG, 0); + SPEX(itssi_a, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_A, + SSB_SPROM1_ITSSI_A_SHIFT); + SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0); SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0); SPEX(antenna_gain_a, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_A, 0); SPEX(antenna_gain_bg, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_BG, @@ -407,7 +407,8 @@ static void sprom_extract_r3(struct ssb_sprom_r3 *out, const u16 *in) out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 1] & 0x00FF) << 8; } -static int sprom_extract(struct ssb_sprom *out, const u16 *in) +static int sprom_extract(struct ssb_bus *bus, + struct ssb_sprom *out, const u16 *in) { memset(out, 0, sizeof(*out)); @@ -415,16 +416,23 @@ static int sprom_extract(struct ssb_sprom *out, const u16 *in) SPEX(crc, SSB_SPROM_REVISION, SSB_SPROM_REVISION_CRC, SSB_SPROM_REVISION_CRC_SHIFT); - if (out->revision == 0) - goto unsupported; - if (out->revision >= 1 && out->revision <= 3) + if ((bus->chip_id & 0xFF00) == 0x4400) { + /* Workaround: The BCM44XX chip has a stupid revision + * number stored in the SPROM. + * Always extract r1. */ sprom_extract_r1(&out->r1, in); - if (out->revision >= 2 && out->revision <= 3) - sprom_extract_r2(&out->r2, in); - if (out->revision == 3) - sprom_extract_r3(&out->r3, in); - if (out->revision >= 4) - goto unsupported; + } else { + if (out->revision == 0) + goto unsupported; + if (out->revision >= 1 && out->revision <= 3) + sprom_extract_r1(&out->r1, in); + if (out->revision >= 2 && out->revision <= 3) + sprom_extract_r2(&out->r2, in); + if (out->revision == 3) + sprom_extract_r3(&out->r3, in); + if (out->revision >= 4) + goto unsupported; + } return 0; unsupported: @@ -434,13 +442,12 @@ unsupported: return 0; } -int ssb_pci_sprom_get(struct ssb_bus *bus) +static int ssb_pci_sprom_get(struct ssb_bus *bus, + struct ssb_sprom *sprom) { int err = -ENOMEM; u16 *buf; - assert(bus->bustype == SSB_BUSTYPE_PCI); - buf = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL); if (!buf) goto out; @@ -450,21 +457,36 @@ int ssb_pci_sprom_get(struct ssb_bus *bus) ssb_printk(KERN_WARNING PFX "WARNING: Invalid SPROM CRC (corrupt SPROM)\n"); } - err = sprom_extract(&bus->sprom, buf); + err = sprom_extract(bus, sprom, buf); kfree(buf); out: return err; } -void ssb_pci_get_boardtype(struct ssb_bus *bus) +static void ssb_pci_get_boardinfo(struct ssb_bus *bus, + struct ssb_boardinfo *bi) { pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_VENDOR_ID, - &bus->board_vendor); + &bi->vendor); pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_ID, - &bus->board_type); + &bi->type); pci_read_config_word(bus->host_pci, PCI_REVISION_ID, - &bus->board_rev); + &bi->rev); +} + +int ssb_pci_get_invariants(struct ssb_bus *bus, + struct ssb_init_invariants *iv) +{ + int err; + + err = ssb_pci_sprom_get(bus, &iv->sprom); + if (err) + goto out; + ssb_pci_get_boardinfo(bus, &iv->boardinfo); + +out: + return err; } static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset) @@ -660,13 +682,7 @@ int ssb_pci_init(struct ssb_bus *bus) err = device_create_file(&pdev->dev, &dev_attr_ssb_sprom); if (err) goto out; - err = ssb_pci_sprom_get(bus); - if (err) - goto err_remove_sprom_file; out: return err; -err_remove_sprom_file: - device_remove_file(&pdev->dev, &dev_attr_ssb_sprom); - return err; } |