diff options
-rw-r--r-- | drivers/mtd/devices/Kconfig | 8 | ||||
-rw-r--r-- | drivers/mtd/devices/Makefile | 1 | ||||
-rw-r--r-- | drivers/mtd/devices/bcm47xxsflash.c | 105 | ||||
-rw-r--r-- | include/linux/bcma/bcma_driver_chipcommon.h | 2 |
4 files changed, 116 insertions, 0 deletions
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 <linux/kernel.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/mtd/mtd.h> +#include <linux/platform_device.h> +#include <linux/bcma/bcma.h> + +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 |