diff options
author | hauke <hauke@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-02-18 23:08:26 +0000 |
---|---|---|
committer | hauke <hauke@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-02-18 23:08:26 +0000 |
commit | 035f06d698fda6b5864d9665c4f657215dbf1e3e (patch) | |
tree | 397b1a30db8f78e15b86821f7268ad2211b00a8a /target/linux/brcm47xx/patches-3.2/195-bcma-add-support-for-sprom-not-found-on-the-device.patch | |
parent | 7005c79799cf4dc2fd5c528dba2ae9940b04bf33 (diff) |
brcm47xx: sprom for nvram parsing
This adds support for parsing sprom form nvram for sprom version form 1 to 9.
It also adds sprom from nvram support for devices on the bcma bus.
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@30638 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/brcm47xx/patches-3.2/195-bcma-add-support-for-sprom-not-found-on-the-device.patch')
-rw-r--r-- | target/linux/brcm47xx/patches-3.2/195-bcma-add-support-for-sprom-not-found-on-the-device.patch | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/target/linux/brcm47xx/patches-3.2/195-bcma-add-support-for-sprom-not-found-on-the-device.patch b/target/linux/brcm47xx/patches-3.2/195-bcma-add-support-for-sprom-not-found-on-the-device.patch new file mode 100644 index 0000000000..6991576d2f --- /dev/null +++ b/target/linux/brcm47xx/patches-3.2/195-bcma-add-support-for-sprom-not-found-on-the-device.patch @@ -0,0 +1,137 @@ +From 332b8f6ca7da3197c631928b6bd1e7fdca87e109 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Sat, 18 Feb 2012 01:16:35 +0100 +Subject: [PATCH 195/202] bcma: add support for sprom not found on the device. + +On SoCs the sprom is stored in the nvram in a special partition on the +flash chip. The nvram contains the sprom for the main bus, but +sometimes also for a pci devices using bcma. This patch makes it +possible for the arch code to register a function to fetch the needed +sprom from the nvram and provide it to the bcma code. + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + drivers/bcma/sprom.c | 80 ++++++++++++++++++++++++++++++++++++++++---- + include/linux/bcma/bcma.h | 6 +++ + 2 files changed, 78 insertions(+), 8 deletions(-) + +--- a/drivers/bcma/sprom.c ++++ b/drivers/bcma/sprom.c +@@ -16,6 +16,49 @@ + + #define SPOFF(offset) ((offset) / sizeof(u16)) + ++static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out); ++ ++/** ++ * ssb_arch_register_fallback_sprom - Registers a method providing a ++ * fallback SPROM if no SPROM is found. ++ * ++ * @sprom_callback: The callback function. ++ * ++ * With this function the architecture implementation may register a ++ * callback handler which fills the 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 bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus, ++ struct ssb_sprom *out)) ++{ ++ if (get_fallback_sprom) ++ return -EEXIST; ++ get_fallback_sprom = sprom_callback; ++ ++ return 0; ++} ++ ++static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus, ++ struct ssb_sprom *out) ++{ ++ if (!get_fallback_sprom) ++ return -ENOENT; ++ ++ return get_fallback_sprom(bus, out); ++} ++ + /************************************************** + * R/W ops. + **************************************************/ +@@ -205,23 +248,44 @@ static void bcma_sprom_extract_r8(struct + SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT; + } + ++static bool bcma_is_sprom_available(struct bcma_bus *bus) ++{ ++ u32 sromctrl; ++ ++ if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM)) ++ return false; ++ ++ if (bus->drv_cc.core->id.rev >= 32) { ++ sromctrl = bcma_read32(bus->drv_cc.core, BCMA_CC_SROM_CONTROL); ++ if (!(sromctrl & BCMA_CC_SROM_CONTROL_PRESENT)) ++ return false; ++ } ++ return true; ++} ++ + int bcma_sprom_get(struct bcma_bus *bus) + { + u16 offset; + u16 *sprom; +- u32 sromctrl; + int err = 0; + + if (!bus->drv_cc.core) + return -EOPNOTSUPP; + +- if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM)) +- return -ENOENT; +- +- if (bus->drv_cc.core->id.rev >= 32) { +- sromctrl = bcma_read32(bus->drv_cc.core, BCMA_CC_SROM_CONTROL); +- if (!(sromctrl & BCMA_CC_SROM_CONTROL_PRESENT)) +- return -ENOENT; ++ if (!bcma_is_sprom_available(bus)) { ++ /* ++ * Maybe there is no SPROM on the device? ++ * Now we ask the arch code if there is some sprom ++ * available for this device in some other storage ++ */ ++ err = bcma_fill_sprom_with_fallback(bus, &bus->sprom); ++ if (err) { ++ pr_warn("Using fallback SPROM failed (err %d)\n", err); ++ } else { ++ pr_debug("Using SPROM revision %d provided by" ++ " platform.\n", bus->sprom.revision); ++ return 0; ++ } + } + + sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), +--- a/include/linux/bcma/bcma.h ++++ b/include/linux/bcma/bcma.h +@@ -177,6 +177,12 @@ int __bcma_driver_register(struct bcma_d + + extern void bcma_driver_unregister(struct bcma_driver *drv); + ++/* Set a fallback SPROM. ++ * See kdoc at the function definition for complete documentation. */ ++extern int bcma_arch_register_fallback_sprom( ++ int (*sprom_callback)(struct bcma_bus *bus, ++ struct ssb_sprom *out)); ++ + struct bcma_bus { + /* The MMIO area. */ + void __iomem *mmio; |