diff options
-rw-r--r-- | target/linux/generic-2.6/patches-2.6.28/975-ssb-fallback-sprom.patch | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/target/linux/generic-2.6/patches-2.6.28/975-ssb-fallback-sprom.patch b/target/linux/generic-2.6/patches-2.6.28/975-ssb-fallback-sprom.patch new file mode 100644 index 0000000..815c37d --- /dev/null +++ b/target/linux/generic-2.6/patches-2.6.28/975-ssb-fallback-sprom.patch @@ -0,0 +1,115 @@ +Index: linux-2.6.28.7/drivers/ssb/pci.c +=================================================================== +--- linux-2.6.28.7.orig/drivers/ssb/pci.c 2009-02-26 20:37:02.000000000 +0100 ++++ linux-2.6.28.7/drivers/ssb/pci.c 2009-02-26 20:41:44.000000000 +0100 +@@ -514,6 +514,7 @@ unsupported: + static int ssb_pci_sprom_get(struct ssb_bus *bus, + struct ssb_sprom *sprom) + { ++ const struct ssb_sprom *fallback; + int err = -ENOMEM; + u16 *buf; + +@@ -533,12 +534,23 @@ static int ssb_pci_sprom_get(struct ssb_ + bus->sprom_size = SSB_SPROMSIZE_WORDS_R4; + sprom_do_read(bus, buf); + err = sprom_check_crc(buf, bus->sprom_size); +- if (err) ++ if (err) { ++ /* All CRC attempts failed. ++ * Maybe there is no SPROM on the device? ++ * If we have a fallback, use that. */ ++ fallback = ssb_get_fallback_sprom(); ++ if (fallback) { ++ memcpy(sprom, fallback, sizeof(*sprom)); ++ err = 0; ++ goto out_free; ++ } + ssb_printk(KERN_WARNING PFX "WARNING: Invalid" + " SPROM CRC (corrupt SPROM)\n"); ++ } + } + err = sprom_extract(bus, sprom, buf, bus->sprom_size); + ++out_free: + kfree(buf); + out: + return err; +Index: linux-2.6.28.7/drivers/ssb/sprom.c +=================================================================== +--- linux-2.6.28.7.orig/drivers/ssb/sprom.c 2009-02-26 20:33:21.000000000 +0100 ++++ linux-2.6.28.7/drivers/ssb/sprom.c 2009-02-26 20:52:35.000000000 +0100 +@@ -14,6 +14,9 @@ + #include "ssb_private.h" + + ++static const struct ssb_sprom *fallback_sprom; ++ ++ + static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len, + size_t sprom_size_words) + { +@@ -131,3 +134,36 @@ out: + return res; + return err ? err : count; + } ++ ++/** ++ * ssb_arch_set_fallback_sprom - Set a fallback SPROM for use if no SPROM is found. ++ * ++ * @sprom: The SPROM data structure to register. ++ * ++ * With this function the architecture implementation may register a fallback ++ * SPROM data structure. The fallback is only used for PCI based SSB devices, ++ * where no valid SPROM can be found in the shadow registers. ++ * ++ * This function is useful for weird architectures that have a half-assed SSB device ++ * hardwired to their PCI bus. ++ * ++ * Note that it does only work with PCI attached SSB devices. PCMCIA devices currently ++ * don't use this fallback. ++ * Architectures must provide the SPROM for native SSB devices anyway, ++ * so the fallback also isn't used for native devices. ++ * ++ * This function is available for architecture code, only. So it is not exported. ++ */ ++int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom) ++{ ++ if (fallback_sprom) ++ return -EEXIST; ++ fallback_sprom = sprom; ++ ++ return 0; ++} ++ ++const struct ssb_sprom *ssb_get_fallback_sprom(void) ++{ ++ return fallback_sprom; ++} +Index: linux-2.6.28.7/drivers/ssb/ssb_private.h +=================================================================== +--- linux-2.6.28.7.orig/drivers/ssb/ssb_private.h 2009-02-26 20:36:33.000000000 +0100 ++++ linux-2.6.28.7/drivers/ssb/ssb_private.h 2009-02-26 20:36:56.000000000 +0100 +@@ -131,6 +131,7 @@ ssize_t ssb_attr_sprom_store(struct ssb_ + const char *buf, size_t count, + int (*sprom_check_crc)(const u16 *sprom, size_t size), + int (*sprom_write)(struct ssb_bus *bus, const u16 *sprom)); ++extern const struct ssb_sprom *ssb_get_fallback_sprom(void); + + + /* core.c */ +Index: linux-2.6.28.7/include/linux/ssb/ssb.h +=================================================================== +--- linux-2.6.28.7.orig/include/linux/ssb/ssb.h 2009-02-26 20:26:34.000000000 +0100 ++++ linux-2.6.28.7/include/linux/ssb/ssb.h 2009-02-26 20:32:30.000000000 +0100 +@@ -339,6 +339,10 @@ extern int ssb_bus_pcmciabus_register(st + + extern void ssb_bus_unregister(struct ssb_bus *bus); + ++/* Set a fallback SPROM. ++ * See kdoc at the function definition for complete documentation. */ ++extern int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom); ++ + /* Suspend a SSB bus. + * Call this from the parent bus suspend routine. */ + extern int ssb_bus_suspend(struct ssb_bus *bus); |