1 --- a/drivers/ssb/pci.c
2 +++ b/drivers/ssb/pci.c
3 @@ -514,6 +514,7 @@ unsupported:
4 static int ssb_pci_sprom_get(struct ssb_bus *bus,
5 struct ssb_sprom *sprom)
7 + const struct ssb_sprom *fallback;
11 @@ -533,12 +534,23 @@ static int ssb_pci_sprom_get(struct ssb_
12 bus->sprom_size = SSB_SPROMSIZE_WORDS_R4;
13 sprom_do_read(bus, buf);
14 err = sprom_check_crc(buf, bus->sprom_size);
17 + /* All CRC attempts failed.
18 + * Maybe there is no SPROM on the device?
19 + * If we have a fallback, use that. */
20 + fallback = ssb_get_fallback_sprom();
22 + memcpy(sprom, fallback, sizeof(*sprom));
26 ssb_printk(KERN_WARNING PFX "WARNING: Invalid"
27 " SPROM CRC (corrupt SPROM)\n");
30 err = sprom_extract(bus, sprom, buf, bus->sprom_size);
36 --- a/drivers/ssb/sprom.c
37 +++ b/drivers/ssb/sprom.c
39 #include "ssb_private.h"
42 +static const struct ssb_sprom *fallback_sprom;
45 static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len,
46 size_t sprom_size_words)
48 @@ -131,3 +134,36 @@ out:
50 return err ? err : count;
54 + * ssb_arch_set_fallback_sprom - Set a fallback SPROM for use if no SPROM is found.
56 + * @sprom: The SPROM data structure to register.
58 + * With this function the architecture implementation may register a fallback
59 + * SPROM data structure. The fallback is only used for PCI based SSB devices,
60 + * where no valid SPROM can be found in the shadow registers.
62 + * This function is useful for weird architectures that have a half-assed SSB device
63 + * hardwired to their PCI bus.
65 + * Note that it does only work with PCI attached SSB devices. PCMCIA devices currently
66 + * don't use this fallback.
67 + * Architectures must provide the SPROM for native SSB devices anyway,
68 + * so the fallback also isn't used for native devices.
70 + * This function is available for architecture code, only. So it is not exported.
72 +int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom)
76 + fallback_sprom = sprom;
81 +const struct ssb_sprom *ssb_get_fallback_sprom(void)
83 + return fallback_sprom;
85 --- a/drivers/ssb/ssb_private.h
86 +++ b/drivers/ssb/ssb_private.h
87 @@ -131,6 +131,7 @@ ssize_t ssb_attr_sprom_store(struct ssb_
88 const char *buf, size_t count,
89 int (*sprom_check_crc)(const u16 *sprom, size_t size),
90 int (*sprom_write)(struct ssb_bus *bus, const u16 *sprom));
91 +extern const struct ssb_sprom *ssb_get_fallback_sprom(void);
95 --- a/include/linux/ssb/ssb.h
96 +++ b/include/linux/ssb/ssb.h
97 @@ -339,6 +339,10 @@ extern int ssb_bus_pcmciabus_register(st
99 extern void ssb_bus_unregister(struct ssb_bus *bus);
101 +/* Set a fallback SPROM.
102 + * See kdoc at the function definition for complete documentation. */
103 +extern int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom);
105 /* Suspend a SSB bus.
106 * Call this from the parent bus suspend routine. */
107 extern int ssb_bus_suspend(struct ssb_bus *bus);