bcm53xx: use SPROM driver queued for 4.6
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> SVN-Revision: 48935
This commit is contained in:
parent
4c80909fa1
commit
dab0569b97
7 changed files with 138 additions and 225 deletions
|
@ -9,3 +9,14 @@ config BCM47XX_NVRAM
|
|||
This driver provides an easy way to get value of requested parameter.
|
||||
It simply reads content of NVRAM and parses it. It doesn't control any
|
||||
hardware part itself.
|
||||
|
||||
config BCM47XX_SPROM
|
||||
bool "Broadcom SPROM driver"
|
||||
depends on BCM47XX_NVRAM
|
||||
help
|
||||
Broadcom devices store configuration data in SPROM. Accessing it is
|
||||
specific to the bus host type, e.g. PCI(e) devices have it mapped in
|
||||
a PCI BAR.
|
||||
In case of SoC devices SPROM content is stored on a flash used by
|
||||
bootloader firmware CFE. This driver provides method to ssb and bcma
|
||||
drivers to read SPROM on SoC.
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
obj-$(CONFIG_BCM47XX_NVRAM) += bcm47xx_nvram.o
|
||||
obj-$(CONFIG_BCM47XX_SPROM) += bcm47xx_sprom.o
|
||||
|
|
|
@ -26,20 +26,11 @@
|
|||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/ssb/ssb.h>
|
||||
#include <linux/bcma/bcma.h>
|
||||
#include <linux/bcm47xx_nvram.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/bcma/bcma.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/ssb/ssb.h>
|
||||
|
||||
static void create_key(const char *prefix, const char *postfix,
|
||||
const char *name, char *buf, int len)
|
||||
|
@ -71,9 +62,9 @@ static int get_nvram_var(const char *prefix, const char *postfix,
|
|||
}
|
||||
|
||||
#define NVRAM_READ_VAL(type) \
|
||||
static void nvram_read_ ## type (const char *prefix, \
|
||||
const char *postfix, const char *name, \
|
||||
type *val, type allset, bool fallback) \
|
||||
static void nvram_read_ ## type(const char *prefix, \
|
||||
const char *postfix, const char *name, \
|
||||
type *val, type allset, bool fallback) \
|
||||
{ \
|
||||
char buf[100]; \
|
||||
int err; \
|
||||
|
@ -433,7 +424,10 @@ static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom,
|
|||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) {
|
||||
struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i];
|
||||
struct ssb_sprom_core_pwr_info *pwr_info;
|
||||
|
||||
pwr_info = &sprom->core_pwr_info[i];
|
||||
|
||||
snprintf(postfix, sizeof(postfix), "%i", i);
|
||||
nvram_read_u8(prefix, postfix, "maxp2ga",
|
||||
&pwr_info->maxpwr_2g, 0, fallback);
|
||||
|
@ -481,7 +475,10 @@ static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom,
|
|||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) {
|
||||
struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i];
|
||||
struct ssb_sprom_core_pwr_info *pwr_info;
|
||||
|
||||
pwr_info = &sprom->core_pwr_info[i];
|
||||
|
||||
snprintf(postfix, sizeof(postfix), "%i", i);
|
||||
nvram_read_u16(prefix, postfix, "pa2gw3a",
|
||||
&pwr_info->pa_2g[3], 0, fallback);
|
||||
|
@ -546,10 +543,11 @@ static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
|
|||
nvram_read_macaddr(prefix, "il0macaddr", sprom->il0mac, fallback);
|
||||
|
||||
/* The address prefix 00:90:4C is used by Broadcom in their initial
|
||||
configuration. When a mac address with the prefix 00:90:4C is used
|
||||
all devices from the same series are sharing the same mac address.
|
||||
To prevent mac address collisions we replace them with a mac address
|
||||
based on the base address. */
|
||||
* configuration. When a mac address with the prefix 00:90:4C is used
|
||||
* all devices from the same series are sharing the same mac address.
|
||||
* To prevent mac address collisions we replace them with a mac address
|
||||
* based on the base address.
|
||||
*/
|
||||
if (!bcm47xx_is_valid_mac(sprom->il0mac)) {
|
||||
u8 mac[6];
|
||||
|
||||
|
@ -603,6 +601,30 @@ void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix,
|
|||
bcm47xx_sprom_fill_auto(sprom, prefix, fallback);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SSB_SPROM)
|
||||
static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
|
||||
{
|
||||
char prefix[10];
|
||||
|
||||
switch (bus->bustype) {
|
||||
case SSB_BUSTYPE_SSB:
|
||||
bcm47xx_fill_sprom(out, NULL, false);
|
||||
return 0;
|
||||
case SSB_BUSTYPE_PCI:
|
||||
memset(out, 0, sizeof(struct ssb_sprom));
|
||||
snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
|
||||
bus->host_pci->bus->number + 1,
|
||||
PCI_SLOT(bus->host_pci->devfn));
|
||||
bcm47xx_fill_sprom(out, prefix, false);
|
||||
return 0;
|
||||
default:
|
||||
pr_warn("Unable to fill SPROM for given bustype.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BCMA)
|
||||
/*
|
||||
* Having many NVRAM entries for PCI devices led to repeating prefixes like
|
||||
* pci/1/1/ all the time and wasting flash space. So at some point Broadcom
|
||||
|
@ -618,6 +640,7 @@ static void bcm47xx_sprom_apply_prefix_alias(char *prefix, size_t prefix_size)
|
|||
char buf[20];
|
||||
int i;
|
||||
|
||||
/* Passed prefix has to end with a slash */
|
||||
if (prefix_len <= 0 || prefix[prefix_len - 1] != '/')
|
||||
return;
|
||||
|
||||
|
@ -634,58 +657,81 @@ static void bcm47xx_sprom_apply_prefix_alias(char *prefix, size_t prefix_size)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function has to be called in a very precise moment. It has to be done:
|
||||
* 1) After bcma registers flash cores, so we can read NVRAM.
|
||||
* 2) Before any code needs SPROM content.
|
||||
*
|
||||
* This can be achieved only by using bcma callback.
|
||||
*/
|
||||
static int bcm47xx_sprom_init(struct bcma_bus *bus, struct ssb_sprom *out)
|
||||
static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
|
||||
{
|
||||
char prefix[20];
|
||||
struct bcma_boardinfo *binfo = &bus->boardinfo;
|
||||
struct bcma_device *core;
|
||||
char buf[10];
|
||||
char *prefix;
|
||||
bool fallback = false;
|
||||
|
||||
switch (bus->hosttype) {
|
||||
case BCMA_HOSTTYPE_PCI:
|
||||
snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
|
||||
pci_domain_nr(bus->host_pci->bus) + 1,
|
||||
bus->host_pci->bus->number);
|
||||
bcm47xx_sprom_apply_prefix_alias(prefix, sizeof(prefix));
|
||||
bcm47xx_fill_sprom(out, prefix, false);
|
||||
memset(out, 0, sizeof(struct ssb_sprom));
|
||||
/* On BCM47XX all PCI buses share the same domain */
|
||||
if (config_enabled(CONFIG_BCM47XX))
|
||||
snprintf(buf, sizeof(buf), "pci/%u/%u/",
|
||||
bus->host_pci->bus->number + 1,
|
||||
PCI_SLOT(bus->host_pci->devfn));
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "pci/%u/%u/",
|
||||
pci_domain_nr(bus->host_pci->bus) + 1,
|
||||
bus->host_pci->bus->number);
|
||||
bcm47xx_sprom_apply_prefix_alias(buf, sizeof(buf));
|
||||
prefix = buf;
|
||||
break;
|
||||
case BCMA_HOSTTYPE_SOC:
|
||||
bcm47xx_fill_sprom(out, NULL, false);
|
||||
memset(out, 0, sizeof(struct ssb_sprom));
|
||||
core = bcma_find_core(bus, BCMA_CORE_80211);
|
||||
if (core) {
|
||||
snprintf(buf, sizeof(buf), "sb/%u/",
|
||||
core->core_index);
|
||||
prefix = buf;
|
||||
fallback = true;
|
||||
} else {
|
||||
prefix = NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_err("Unable to fill SPROM for given hosttype.\n");
|
||||
pr_warn("Unable to fill SPROM for given bustype.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
nvram_read_u16(prefix, NULL, "boardvendor", &binfo->vendor, 0, true);
|
||||
if (!binfo->vendor)
|
||||
binfo->vendor = SSB_BOARDVENDOR_BCM;
|
||||
nvram_read_u16(prefix, NULL, "boardtype", &binfo->type, 0, true);
|
||||
|
||||
static int bcm47xx_sprom_probe(struct platform_device *pdev)
|
||||
bcm47xx_fill_sprom(out, prefix, fallback);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned int bcm47xx_sprom_registered;
|
||||
|
||||
/*
|
||||
* On bcm47xx we need to register SPROM fallback handler very early, so we can't
|
||||
* use anything like platform device / driver for this.
|
||||
*/
|
||||
int bcm47xx_sprom_register_fallbacks(void)
|
||||
{
|
||||
return bcma_arch_register_fallback_sprom(&bcm47xx_sprom_init);
|
||||
if (bcm47xx_sprom_registered)
|
||||
return 0;
|
||||
|
||||
#if defined(CONFIG_SSB_SPROM)
|
||||
if (ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb))
|
||||
pr_warn("Failed to registered ssb SPROM handler\n");
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BCMA)
|
||||
if (bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma))
|
||||
pr_warn("Failed to registered bcma SPROM handler\n");
|
||||
#endif
|
||||
|
||||
bcm47xx_sprom_registered = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id bcm47xx_sprom_of_match_table[] = {
|
||||
{ .compatible = "brcm,bcm47xx-sprom", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bcm47xx_sprom_of_match_table);
|
||||
|
||||
static struct platform_driver bcm47xx_sprom_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "bcm47xx-sprom",
|
||||
.of_match_table = bcm47xx_sprom_of_match_table,
|
||||
/* driver unloading/unbinding currently not supported */
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
.probe = bcm47xx_sprom_probe,
|
||||
};
|
||||
module_platform_driver(bcm47xx_sprom_driver);
|
||||
|
||||
MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
fs_initcall(bcm47xx_sprom_register_fallbacks);
|
|
@ -1,69 +0,0 @@
|
|||
From 4e0ab3269a6d260a41a3673157753147f5f71341 Mon Sep 17 00:00:00 2001
|
||||
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||
Date: Sun, 4 May 2014 13:19:20 +0200
|
||||
Subject: [PATCH 03/17] bcm47xx-sprom: add Broadcom sprom parser driver
|
||||
|
||||
This driver needs an nvram driver and fetches the sprom values from the
|
||||
nvram and provides it to any other driver. The calibration data for the
|
||||
wifi chip the mac address and some more board description data is
|
||||
stores in the sprom.
|
||||
|
||||
This is based on a copy of arch/mips/bcm47xx/sprom.c and my plan is to
|
||||
make the bcm47xx MIPS SoCs also use this driver some time later.
|
||||
|
||||
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||
---
|
||||
.../devicetree/bindings/misc/bcm47xx-sprom.txt | 16 +
|
||||
drivers/misc/Kconfig | 11 +
|
||||
drivers/misc/Makefile | 1 +
|
||||
drivers/misc/bcm47xx-sprom.c | 690 +++++++++++++++++++++
|
||||
4 files changed, 718 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/misc/bcm47xx-sprom.txt
|
||||
create mode 100644 drivers/misc/bcm47xx-sprom.c
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/misc/bcm47xx-sprom.txt
|
||||
@@ -0,0 +1,16 @@
|
||||
+Broadcom bcm47xx/bcm53xx sprom converter
|
||||
+
|
||||
+This driver provbides an sprom based on a given nvram.
|
||||
+
|
||||
+Required properties:
|
||||
+
|
||||
+- compatible : brcm,bcm47xx-sprom
|
||||
+
|
||||
+- nvram : reference to a nvram driver, e.g. bcm47xx-nvram
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+sprom0: sprom@0 {
|
||||
+ compatible = "brcm,bcm47xx-sprom";
|
||||
+ nvram = <&nvram0>;
|
||||
+};
|
||||
--- a/drivers/misc/Kconfig
|
||||
+++ b/drivers/misc/Kconfig
|
||||
@@ -515,6 +515,17 @@ config VEXPRESS_SYSCFG
|
||||
bus. System Configuration interface is one of the possible means
|
||||
of generating transactions on this bus.
|
||||
|
||||
+config BCM47XX_SPROM
|
||||
+ tristate "BCM47XX sprom driver"
|
||||
+ help
|
||||
+ This driver parses the sprom from a given nvram which is found on
|
||||
+ Broadcom bcm47xx and bcm53xx SoCs.
|
||||
+
|
||||
+ The sprom contains board configuration data like the
|
||||
+ calibration data fro the wifi chips, the mac addresses used
|
||||
+ by the board and many other board configuration data. This
|
||||
+ driver will provide the sprom to bcma.
|
||||
+
|
||||
source "drivers/misc/c2port/Kconfig"
|
||||
source "drivers/misc/eeprom/Kconfig"
|
||||
source "drivers/misc/cb710/Kconfig"
|
||||
--- a/drivers/misc/Makefile
|
||||
+++ b/drivers/misc/Makefile
|
||||
@@ -56,3 +56,4 @@ obj-$(CONFIG_GENWQE) += genwqe/
|
||||
obj-$(CONFIG_ECHO) += echo/
|
||||
obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o
|
||||
obj-$(CONFIG_CXL_BASE) += cxl/
|
||||
+obj-$(CONFIG_BCM47XX_SPROM) += bcm47xx-sprom.o
|
|
@ -1,26 +0,0 @@
|
|||
From d404e0b22356078a51719fa911f6e09cb1a72d80 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Sun, 7 Jun 2015 16:18:18 +0200
|
||||
Subject: [PATCH] ARM: BCM5301X: Add SPROM
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
|
||||
---
|
||||
arch/arm/boot/dts/bcm5301x.dtsi | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/arch/arm/boot/dts/bcm5301x.dtsi
|
||||
+++ b/arch/arm/boot/dts/bcm5301x.dtsi
|
||||
@@ -105,6 +105,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ sprom0: sprom@0 {
|
||||
+ compatible = "brcm,bcm47xx-sprom";
|
||||
+ };
|
||||
+
|
||||
axi@18000000 {
|
||||
compatible = "brcm,bus-axi";
|
||||
reg = <0x18000000 0x1000>;
|
|
@ -21,49 +21,25 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
|||
create mode 100644 Documentation/devicetree/bindings/misc/bcm47xx-sprom.txt
|
||||
create mode 100644 drivers/misc/bcm47xx-sprom.c
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/misc/bcm47xx-sprom.txt
|
||||
@@ -0,0 +1,16 @@
|
||||
+Broadcom bcm47xx/bcm53xx sprom converter
|
||||
--- a/drivers/firmware/broadcom/Kconfig
|
||||
+++ b/drivers/firmware/broadcom/Kconfig
|
||||
@@ -9,3 +9,14 @@ config BCM47XX_NVRAM
|
||||
This driver provides an easy way to get value of requested parameter.
|
||||
It simply reads content of NVRAM and parses it. It doesn't control any
|
||||
hardware part itself.
|
||||
+
|
||||
+This driver provbides an sprom based on a given nvram.
|
||||
+
|
||||
+Required properties:
|
||||
+
|
||||
+- compatible : brcm,bcm47xx-sprom
|
||||
+
|
||||
+- nvram : reference to a nvram driver, e.g. bcm47xx-nvram
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+sprom0: sprom@0 {
|
||||
+ compatible = "brcm,bcm47xx-sprom";
|
||||
+ nvram = <&nvram0>;
|
||||
+};
|
||||
--- a/drivers/misc/Kconfig
|
||||
+++ b/drivers/misc/Kconfig
|
||||
@@ -525,6 +525,17 @@ config VEXPRESS_SYSCFG
|
||||
bus. System Configuration interface is one of the possible means
|
||||
of generating transactions on this bus.
|
||||
|
||||
+config BCM47XX_SPROM
|
||||
+ tristate "BCM47XX sprom driver"
|
||||
+ bool "Broadcom SPROM driver"
|
||||
+ depends on BCM47XX_NVRAM
|
||||
+ help
|
||||
+ This driver parses the sprom from a given nvram which is found on
|
||||
+ Broadcom bcm47xx and bcm53xx SoCs.
|
||||
+
|
||||
+ The sprom contains board configuration data like the
|
||||
+ calibration data fro the wifi chips, the mac addresses used
|
||||
+ by the board and many other board configuration data. This
|
||||
+ driver will provide the sprom to bcma.
|
||||
+
|
||||
source "drivers/misc/c2port/Kconfig"
|
||||
source "drivers/misc/eeprom/Kconfig"
|
||||
source "drivers/misc/cb710/Kconfig"
|
||||
--- a/drivers/misc/Makefile
|
||||
+++ b/drivers/misc/Makefile
|
||||
@@ -56,3 +56,4 @@ obj-$(CONFIG_GENWQE) += genwqe/
|
||||
obj-$(CONFIG_ECHO) += echo/
|
||||
obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o
|
||||
obj-$(CONFIG_CXL_BASE) += cxl/
|
||||
+obj-$(CONFIG_BCM47XX_SPROM) += bcm47xx-sprom.o
|
||||
+ Broadcom devices store configuration data in SPROM. Accessing it is
|
||||
+ specific to the bus host type, e.g. PCI(e) devices have it mapped in
|
||||
+ a PCI BAR.
|
||||
+ In case of SoC devices SPROM content is stored on a flash used by
|
||||
+ bootloader firmware CFE. This driver provides method to ssb and bcma
|
||||
+ drivers to read SPROM on SoC.
|
||||
--- a/drivers/firmware/broadcom/Makefile
|
||||
+++ b/drivers/firmware/broadcom/Makefile
|
||||
@@ -1 +1,2 @@
|
||||
obj-$(CONFIG_BCM47XX_NVRAM) += bcm47xx_nvram.o
|
||||
+obj-$(CONFIG_BCM47XX_SPROM) += bcm47xx_sprom.o
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
From d404e0b22356078a51719fa911f6e09cb1a72d80 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Sun, 7 Jun 2015 16:18:18 +0200
|
||||
Subject: [PATCH] ARM: BCM5301X: Add SPROM
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
|
||||
---
|
||||
arch/arm/boot/dts/bcm5301x.dtsi | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/arch/arm/boot/dts/bcm5301x.dtsi
|
||||
+++ b/arch/arm/boot/dts/bcm5301x.dtsi
|
||||
@@ -136,6 +136,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ sprom0: sprom@0 {
|
||||
+ compatible = "brcm,bcm47xx-sprom";
|
||||
+ };
|
||||
+
|
||||
axi@18000000 {
|
||||
compatible = "brcm,bus-axi";
|
||||
reg = <0x18000000 0x1000>;
|
Loading…
Reference in a new issue