From 5fe42d5bf2deac62bf2a532b30deacc007805b91 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 17 Sep 2012 11:50:49 +0200 Subject: [PATCH] mtd: basic (read only) driver for BCMA serial flash MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This registers MTD driver for serial flash platform device. Right now it supports reading only, writing still has to be implemented. Artem: minor amendments. Signed-off-by: Rafał Miłecki Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/Kconfig | 8 ++ drivers/mtd/devices/Makefile | 1 + drivers/mtd/devices/bcm47xxsflash.c | 105 ++++++++++++++++++++ include/linux/bcma/bcma_driver_chipcommon.h | 2 + 4 files changed, 116 insertions(+) create mode 100644 drivers/mtd/devices/bcm47xxsflash.c diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index 6cc5a1ac3802..27f80cd8aef3 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig @@ -120,6 +120,14 @@ config MTD_SST25L Set up your spi devices with the right board-specific platform data, if you want to specify device partitioning. +config MTD_BCM47XXSFLASH + tristate "R/O support for serial flash on BCMA bus" + depends on BCMA_SFLASH + help + BCMA bus can have various flash memories attached, they are + registered by bcma as platform devices. This enables driver for + serial flash memories (only read-only mode is implemented). + config MTD_SLRAM tristate "Uncached system RAM" help diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile index a4dd1d822b6c..395733a30ef4 100644 --- a/drivers/mtd/devices/Makefile +++ b/drivers/mtd/devices/Makefile @@ -19,5 +19,6 @@ obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o obj-$(CONFIG_MTD_M25P80) += m25p80.o obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o obj-$(CONFIG_MTD_SST25L) += sst25l.o +obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o CFLAGS_docg3.o += -I$(src) \ No newline at end of file diff --git a/drivers/mtd/devices/bcm47xxsflash.c b/drivers/mtd/devices/bcm47xxsflash.c new file mode 100644 index 000000000000..2dc5a6f3fd57 --- /dev/null +++ b/drivers/mtd/devices/bcm47xxsflash.c @@ -0,0 +1,105 @@ +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Serial flash driver for BCMA bus"); + +static const char *probes[] = { "bcm47xxpart", NULL }; + +static int bcm47xxsflash_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) +{ + struct bcma_sflash *sflash = mtd->priv; + + /* Check address range */ + if ((from + len) > mtd->size) + return -EINVAL; + + memcpy_fromio(buf, (void __iomem *)KSEG0ADDR(sflash->window + from), + len); + + return len; +} + +static void bcm47xxsflash_fill_mtd(struct bcma_sflash *sflash, + struct mtd_info *mtd) +{ + mtd->priv = sflash; + mtd->name = "bcm47xxsflash"; + mtd->owner = THIS_MODULE; + mtd->type = MTD_ROM; + mtd->size = sflash->size; + mtd->_read = bcm47xxsflash_read; + + /* TODO: implement writing support and verify/change following code */ + mtd->flags = MTD_CAP_ROM; + mtd->writebufsize = mtd->writesize = 1; +} + +static int bcm47xxsflash_probe(struct platform_device *pdev) +{ + struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev); + int err; + + sflash->mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL); + if (!sflash->mtd) { + err = -ENOMEM; + goto out; + } + bcm47xxsflash_fill_mtd(sflash, sflash->mtd); + + err = mtd_device_parse_register(sflash->mtd, probes, NULL, NULL, 0); + if (err) { + pr_err("Failed to register MTD device: %d\n", err); + goto err_dev_reg; + } + + return 0; + +err_dev_reg: + kfree(sflash->mtd); +out: + return err; +} + +static int __devexit bcm47xxsflash_remove(struct platform_device *pdev) +{ + struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev); + + mtd_device_unregister(sflash->mtd); + kfree(sflash->mtd); + + return 0; +} + +static struct platform_driver bcma_sflash_driver = { + .remove = __devexit_p(bcm47xxsflash_remove), + .driver = { + .name = "bcma_sflash", + .owner = THIS_MODULE, + }, +}; + +static int __init bcm47xxsflash_init(void) +{ + int err; + + err = platform_driver_probe(&bcma_sflash_driver, bcm47xxsflash_probe); + if (err) + pr_err("Failed to register BCMA serial flash driver: %d\n", + err); + + return err; +} + +static void __exit bcm47xxsflash_exit(void) +{ + platform_driver_unregister(&bcma_sflash_driver); +} + +module_init(bcm47xxsflash_init); +module_exit(bcm47xxsflash_exit); diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index 6ba45d2b99db..1cf1749440ac 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h @@ -522,6 +522,8 @@ struct bcma_sflash { u32 blocksize; u16 numblocks; u32 size; + + struct mtd_info *mtd; }; #endif -- 2.20.1