diff options
author | Michael Buesch <mb@bu3sch.de> | 2009-02-27 10:59:05 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-03-05 14:39:32 -0500 |
commit | e79c1ba84c68de9161d541bd2bcc8ea65c89955c (patch) | |
tree | 9399343651e9d92fb92f0c7bd6280353cb296913 /drivers/ssb/pci.c | |
parent | e31ae0508315ebf5d8b1b8a1fca8550737fb3996 (diff) |
ssb: Add SPROM fallback support
This adds SSB functionality to register a fallback SPROM image from the
architecture setup code.
Weird architectures exist that have half-assed SSB devices without SPROM attached to
their PCI busses. The architecture can register a fallback SPROM image that is
used if no SPROM is found on the SSB device.
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Cc: Florian Fainelli <florian@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/ssb/pci.c')
-rw-r--r-- | drivers/ssb/pci.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index c958ac16423..40ea4176224 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c | |||
@@ -564,6 +564,7 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, | |||
564 | static int ssb_pci_sprom_get(struct ssb_bus *bus, | 564 | static int ssb_pci_sprom_get(struct ssb_bus *bus, |
565 | struct ssb_sprom *sprom) | 565 | struct ssb_sprom *sprom) |
566 | { | 566 | { |
567 | const struct ssb_sprom *fallback; | ||
567 | int err = -ENOMEM; | 568 | int err = -ENOMEM; |
568 | u16 *buf; | 569 | u16 *buf; |
569 | 570 | ||
@@ -583,12 +584,23 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, | |||
583 | bus->sprom_size = SSB_SPROMSIZE_WORDS_R4; | 584 | bus->sprom_size = SSB_SPROMSIZE_WORDS_R4; |
584 | sprom_do_read(bus, buf); | 585 | sprom_do_read(bus, buf); |
585 | err = sprom_check_crc(buf, bus->sprom_size); | 586 | err = sprom_check_crc(buf, bus->sprom_size); |
586 | if (err) | 587 | if (err) { |
588 | /* All CRC attempts failed. | ||
589 | * Maybe there is no SPROM on the device? | ||
590 | * If we have a fallback, use that. */ | ||
591 | fallback = ssb_get_fallback_sprom(); | ||
592 | if (fallback) { | ||
593 | memcpy(sprom, fallback, sizeof(*sprom)); | ||
594 | err = 0; | ||
595 | goto out_free; | ||
596 | } | ||
587 | ssb_printk(KERN_WARNING PFX "WARNING: Invalid" | 597 | ssb_printk(KERN_WARNING PFX "WARNING: Invalid" |
588 | " SPROM CRC (corrupt SPROM)\n"); | 598 | " SPROM CRC (corrupt SPROM)\n"); |
599 | } | ||
589 | } | 600 | } |
590 | err = sprom_extract(bus, sprom, buf, bus->sprom_size); | 601 | err = sprom_extract(bus, sprom, buf, bus->sprom_size); |
591 | 602 | ||
603 | out_free: | ||
592 | kfree(buf); | 604 | kfree(buf); |
593 | out: | 605 | out: |
594 | return err; | 606 | return err; |