Browse Source

MIPS: BCM47xx: Move SPROM driver to drivers/firmware/

Broadcom ARM home routers store SPROM content in NVRAM just like MIPS
ones. To share SPROM code we need to move it out of arch/mips/ to some
common place. We already have bcm47xx_nvram in firmware path and SPROM
should fit there as well.
This driver is responsible for parsing SoC configuration data into a
struct shared between ssb and bcma buses.
This was tested with BCM4706 & BCM5357C0 (BCM47XX) and BCM4708A0
(ARCH_BCM_5301X).

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Cc: Hauke Mehrtens <hauke@hauke-m.de>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/12210/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Rafał Miłecki 9 years ago
parent
commit
2ab71a02c5

+ 1 - 0
arch/mips/Kconfig

@@ -197,6 +197,7 @@ config BCM47XX
 	select GPIOLIB
 	select GPIOLIB
 	select LEDS_GPIO_REGISTER
 	select LEDS_GPIO_REGISTER
 	select BCM47XX_NVRAM
 	select BCM47XX_NVRAM
+	select BCM47XX_SPROM
 	help
 	help
 	 Support for BCM47XX based boards
 	 Support for BCM47XX based boards
 
 

+ 1 - 1
arch/mips/bcm47xx/Makefile

@@ -3,5 +3,5 @@
 # under Linux.
 # under Linux.
 #
 #
 
 
-obj-y				+= irq.o prom.o serial.o setup.o time.o sprom.o
+obj-y				+= irq.o prom.o serial.o setup.o time.o
 obj-y				+= board.o buttons.o leds.o workarounds.o
 obj-y				+= board.o buttons.o leds.o workarounds.o

+ 0 - 3
arch/mips/bcm47xx/bcm47xx_private.h

@@ -10,9 +10,6 @@
 /* prom.c */
 /* prom.c */
 void __init bcm47xx_prom_highmem_init(void);
 void __init bcm47xx_prom_highmem_init(void);
 
 
-/* sprom.c */
-void bcm47xx_sprom_register_fallbacks(void);
-
 /* buttons.c */
 /* buttons.c */
 int __init bcm47xx_buttons_register(void);
 int __init bcm47xx_buttons_register(void);
 
 

+ 1 - 1
arch/mips/bcm47xx/setup.c

@@ -28,6 +28,7 @@
 
 
 #include "bcm47xx_private.h"
 #include "bcm47xx_private.h"
 
 
+#include <linux/bcm47xx_sprom.h>
 #include <linux/export.h>
 #include <linux/export.h>
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/ethtool.h>
 #include <linux/ethtool.h>
@@ -151,7 +152,6 @@ void __init plat_mem_setup(void)
 		pr_info("Using bcma bus\n");
 		pr_info("Using bcma bus\n");
 #ifdef CONFIG_BCM47XX_BCMA
 #ifdef CONFIG_BCM47XX_BCMA
 		bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
 		bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
-		bcm47xx_sprom_register_fallbacks();
 		bcm47xx_register_bcma();
 		bcm47xx_register_bcma();
 		bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id);
 		bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id);
 #ifdef CONFIG_HIGHMEM
 #ifdef CONFIG_HIGHMEM

+ 11 - 0
drivers/firmware/broadcom/Kconfig

@@ -9,3 +9,14 @@ config BCM47XX_NVRAM
 	  This driver provides an easy way to get value of requested parameter.
 	  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
 	  It simply reads content of NVRAM and parses it. It doesn't control any
 	  hardware part itself.
 	  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 - 0
drivers/firmware/broadcom/Makefile

@@ -1 +1,2 @@
 obj-$(CONFIG_BCM47XX_NVRAM)		+= bcm47xx_nvram.o
 obj-$(CONFIG_BCM47XX_NVRAM)		+= bcm47xx_nvram.o
+obj-$(CONFIG_BCM47XX_SPROM)		+= bcm47xx_sprom.o

+ 20 - 7
arch/mips/bcm47xx/sprom.c → drivers/firmware/broadcom/bcm47xx_sprom.c

@@ -26,9 +26,11 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
  */
 
 
-#include <bcm47xx.h>
-#include <linux/if_ether.h>
+#include <linux/bcm47xx_nvram.h>
+#include <linux/bcma/bcma.h>
 #include <linux/etherdevice.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,
 static void create_key(const char *prefix, const char *postfix,
 		       const char *name, char *buf, int len)
 		       const char *name, char *buf, int len)
@@ -599,7 +601,7 @@ void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix,
 	bcm47xx_sprom_fill_auto(sprom, prefix, fallback);
 	bcm47xx_sprom_fill_auto(sprom, prefix, fallback);
 }
 }
 
 
-#if defined(CONFIG_BCM47XX_SSB)
+#if IS_BUILTIN(CONFIG_SSB) && IS_ENABLED(CONFIG_SSB_SPROM)
 static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
 static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
 {
 {
 	char prefix[10];
 	char prefix[10];
@@ -622,7 +624,7 @@ static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
 }
 }
 #endif
 #endif
 
 
-#if defined(CONFIG_BCM47XX_BCMA)
+#if IS_BUILTIN(CONFIG_BCMA)
 /*
 /*
  * Having many NVRAM entries for PCI devices led to repeating prefixes like
  * 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
  * pci/1/1/ all the time and wasting flash space. So at some point Broadcom
@@ -706,19 +708,30 @@ static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
 }
 }
 #endif
 #endif
 
 
+static unsigned int bcm47xx_sprom_registered;
+
 /*
 /*
  * On bcm47xx we need to register SPROM fallback handler very early, so we can't
  * On bcm47xx we need to register SPROM fallback handler very early, so we can't
  * use anything like platform device / driver for this.
  * use anything like platform device / driver for this.
  */
  */
-void bcm47xx_sprom_register_fallbacks(void)
+int bcm47xx_sprom_register_fallbacks(void)
 {
 {
-#if defined(CONFIG_BCM47XX_SSB)
+	if (bcm47xx_sprom_registered)
+		return 0;
+
+#if IS_BUILTIN(CONFIG_SSB) && IS_ENABLED(CONFIG_SSB_SPROM)
 	if (ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb))
 	if (ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb))
 		pr_warn("Failed to register ssb SPROM handler\n");
 		pr_warn("Failed to register ssb SPROM handler\n");
 #endif
 #endif
 
 
-#if defined(CONFIG_BCM47XX_BCMA)
+#if IS_BUILTIN(CONFIG_BCMA)
 	if (bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma))
 	if (bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma))
 		pr_warn("Failed to register bcma SPROM handler\n");
 		pr_warn("Failed to register bcma SPROM handler\n");
 #endif
 #endif
+
+	bcm47xx_sprom_registered = 1;
+
+	return 0;
 }
 }
+
+fs_initcall(bcm47xx_sprom_register_fallbacks);

+ 24 - 0
include/linux/bcm47xx_sprom.h

@@ -0,0 +1,24 @@
+/*
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#ifndef __BCM47XX_SPROM_H
+#define __BCM47XX_SPROM_H
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+
+#ifdef CONFIG_BCM47XX_SPROM
+int bcm47xx_sprom_register_fallbacks(void);
+#else
+static inline int bcm47xx_sprom_register_fallbacks(void)
+{
+	return -ENOTSUPP;
+};
+#endif
+
+#endif /* __BCM47XX_SPROM_H */