---
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