#include "bcm47xx_private.h"
 
+#include <linux/bcm47xx_sprom.h>
 #include <linux/export.h>
 #include <linux/types.h>
 #include <linux/ethtool.h>
                pr_info("Using bcma bus\n");
 #ifdef CONFIG_BCM47XX_BCMA
                bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
-               bcm47xx_sprom_register_fallbacks();
                bcm47xx_register_bcma();
                bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id);
 #ifdef CONFIG_HIGHMEM
 
          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.
 
  *  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/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)
        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)
 {
        char prefix[10];
 }
 #endif
 
-#if defined(CONFIG_BCM47XX_BCMA)
+#if IS_BUILTIN(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
 }
 #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.
  */
-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))
                pr_warn("Failed to register ssb SPROM handler\n");
 #endif
 
-#if defined(CONFIG_BCM47XX_BCMA)
+#if IS_BUILTIN(CONFIG_BCMA)
        if (bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma))
                pr_warn("Failed to register bcma SPROM handler\n");
 #endif
+
+       bcm47xx_sprom_registered = 1;
+
+       return 0;
 }
+
+fs_initcall(bcm47xx_sprom_register_fallbacks);
 
--- /dev/null
+/*
+ *  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 */