---
As you could notice OpenWrt recently switched from old MTD drivers to
the mainline ones. Unfortunately it means that serial flash on SSB is no
longer supported.

I mean to fix this (it's a simple patch), but I need some tester to try
it.
Is there anyone with bcm47xx SSB based hardware (like BCM5354, BCM4704,
BCM4705 and others) having serial console who could give it a try?
---
 drivers/mtd/devices/Kconfig         |    2 +-
 drivers/mtd/devices/bcm47xxsflash.c |  126 ++++++++++++++++++++++++++++++++++-
 drivers/mtd/devices/bcm47xxsflash.h |    6 +-
 3 files changed, 130 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 82c5972..f22da05 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -129,7 +129,7 @@ config MTD_SST25L
 
 config MTD_BCM47XXSFLASH
        tristate "R/O support for serial flash on BCMA bus"
-       depends on BCMA_SFLASH
+       depends on SSB_SFLASH || BCMA_SFLASH
        help
          BCMA bus can have various flash memories attached, they are
          registered by bcma as platform devices. This enables driver for
diff --git a/drivers/mtd/devices/bcm47xxsflash.c 
b/drivers/mtd/devices/bcm47xxsflash.c
index 77de29b..0db03f2 100644
--- a/drivers/mtd/devices/bcm47xxsflash.c
+++ b/drivers/mtd/devices/bcm47xxsflash.c
@@ -4,12 +4,13 @@
 #include <linux/delay.h>
 #include <linux/mtd/mtd.h>
 #include <linux/platform_device.h>
+#include <linux/ssb/ssb.h>
 #include <linux/bcma/bcma.h>
 
 #include "bcm47xxsflash.h"
 
 MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Serial flash driver for BCMA bus");
+MODULE_DESCRIPTION("Serial flash driver for SSB and BCMA buses");
 
 static const char * const probes[] = { "bcm47xxpart", NULL };
 
@@ -258,9 +259,87 @@ static void bcm47xxsflash_fill_mtd(struct bcm47xxsflash 
*b47s)
 }
 
 /**************************************************
+ * SSB
+ **************************************************/
+
+#ifdef CONFIG_SSB_SFLASH
+static int bcm47xxsflash_ssb_cc_read(struct bcm47xxsflash *b47s, u16 offset)
+{
+       return chipco_read32(b47s->ssb_cc, offset);
+}
+
+static void bcm47xxsflash_ssb_cc_write(struct bcm47xxsflash *b47s, u16 offset,
+                                      u32 value)
+{
+       chipco_write32(b47s->ssb_cc, offset, value);
+}
+
+static int bcm47xxsflash_ssb_probe(struct platform_device *pdev)
+{
+       struct ssb_sflash *sflash = dev_get_platdata(&pdev->dev);
+       struct ssb_mipscore *mcore = container_of(sflash, struct ssb_mipscore,
+                                                 sflash);
+       struct bcm47xxsflash *b47s;
+       int err;
+
+       b47s = devm_kzalloc(&pdev->dev, sizeof(*b47s), GFP_KERNEL);
+       if (!b47s)
+               return -ENOMEM;
+       sflash->priv = b47s;
+
+       b47s->ssb_cc = &mcore->dev->bus->chipco;
+       b47s->cc_read = bcm47xxsflash_ssb_cc_read;
+       b47s->cc_write = bcm47xxsflash_ssb_cc_write;
+
+       switch (b47s->ssb_cc->capabilities & SSB_CHIPCO_CAP_FLASHT) {
+       case SSB_CHIPCO_FLASHT_STSER:
+               b47s->type = BCM47XXSFLASH_TYPE_ST;
+               break;
+       case SSB_CHIPCO_FLASHT_ATSER:
+               b47s->type = BCM47XXSFLASH_TYPE_ATMEL;
+               break;
+       }
+
+       b47s->window = sflash->window;
+       b47s->blocksize = sflash->blocksize;
+       b47s->numblocks = sflash->numblocks;
+       b47s->size = sflash->size;
+       bcm47xxsflash_fill_mtd(b47s);
+
+       err = mtd_device_parse_register(&b47s->mtd, probes, NULL, NULL, 0);
+       if (err) {
+               pr_err("Failed to register MTD device: %d\n", err);
+               return err;
+       }
+
+       return 0;
+}
+
+static int bcm47xxsflash_ssb_remove(struct platform_device *pdev)
+{
+       struct ssb_sflash *sflash = dev_get_platdata(&pdev->dev);
+       struct bcm47xxsflash *b47s = sflash->priv;
+
+       mtd_device_unregister(&b47s->mtd);
+
+       return 0;
+}
+
+static struct platform_driver ssb_sflash_driver = {
+       .probe  = bcm47xxsflash_ssb_probe,
+       .remove = bcm47xxsflash_ssb_remove,
+       .driver = {
+               .name = "ssb_sflash",
+               .owner = THIS_MODULE,
+       },
+};
+#endif
+
+/**************************************************
  * BCMA
  **************************************************/
 
+#ifdef CONFIG_BCMA_SFLASH
 static int bcm47xxsflash_bcma_cc_read(struct bcm47xxsflash *b47s, u16 offset)
 {
        return bcma_cc_read32(b47s->bcma_cc, offset);
@@ -332,9 +411,52 @@ static struct platform_driver bcma_sflash_driver = {
                .owner = THIS_MODULE,
        },
 };
+#endif
 
 /**************************************************
  * Init
  **************************************************/
 
-module_platform_driver(bcma_sflash_driver);
+static int __init bcm47xxsflash_init(void)
+{
+       int err;
+
+#ifdef CONFIG_SSB_SFLASH
+       err = platform_driver_register(&ssb_sflash_driver);
+       if (err) {
+               pr_err("Failed to register SSB serial flash driver: %d\n", err);
+               goto err_out;
+       }
+#endif
+
+#ifdef CONFIG_BCMA_SFLASH
+       err = platform_driver_register(&bcma_sflash_driver);
+       if (err) {
+               pr_err("Failed to register BCMA serial flash driver: %d\n",
+                      err);
+               goto err_ssb_unregitser;
+       }
+#endif
+
+       return 0;
+
+err_ssb_unregitser:
+#ifdef CONFIG_SSB_SFLASH
+       platform_driver_unregister(&ssb_sflash_driver);
+err_out:
+#endif
+       return err;
+}
+
+static void __exit bcm47xxsflash_exit(void)
+{
+#ifdef CONFIG_SSB_SFLASH
+       platform_driver_unregister(&ssb_sflash_driver);
+#endif
+#ifdef CONFIG_BCMA_SFLASH
+       platform_driver_unregister(&bcma_sflash_driver);
+#endif
+}
+
+module_init(bcm47xxsflash_init);
+module_exit(bcm47xxsflash_exit);
diff --git a/drivers/mtd/devices/bcm47xxsflash.h 
b/drivers/mtd/devices/bcm47xxsflash.h
index fe93daf..4dafa17 100644
--- a/drivers/mtd/devices/bcm47xxsflash.h
+++ b/drivers/mtd/devices/bcm47xxsflash.h
@@ -51,6 +51,7 @@
 #define SR_AT_ID_MASK          0x38
 #define SR_AT_ID_SHIFT         3
 
+struct ssb_chipcommon;
 struct bcma_drv_cc;
 
 enum bcm47xxsflash_type {
@@ -59,7 +60,10 @@ enum bcm47xxsflash_type {
 };
 
 struct bcm47xxsflash {
-       struct bcma_drv_cc *bcma_cc;
+       union {
+               struct ssb_chipcommon *ssb_cc;
+               struct bcma_drv_cc *bcma_cc;
+       };
        int (*cc_read)(struct bcm47xxsflash *b47s, u16 offset);
        void (*cc_write)(struct bcm47xxsflash *b47s, u16 offset, u32 value);
 
-- 
1.7.10.4
_______________________________________________
openwrt-devel mailing list
[email protected]
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to