diff options
Diffstat (limited to 'drivers/mtd/devices')
| -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 |
3 files changed, 114 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 | |||
| 120 | Set up your spi devices with the right board-specific platform data, | 120 | Set up your spi devices with the right board-specific platform data, |
| 121 | if you want to specify device partitioning. | 121 | if you want to specify device partitioning. |
| 122 | 122 | ||
| 123 | config MTD_BCM47XXSFLASH | ||
| 124 | tristate "R/O support for serial flash on BCMA bus" | ||
| 125 | depends on BCMA_SFLASH | ||
| 126 | help | ||
| 127 | BCMA bus can have various flash memories attached, they are | ||
| 128 | registered by bcma as platform devices. This enables driver for | ||
| 129 | serial flash memories (only read-only mode is implemented). | ||
| 130 | |||
| 123 | config MTD_SLRAM | 131 | config MTD_SLRAM |
| 124 | tristate "Uncached system RAM" | 132 | tristate "Uncached system RAM" |
| 125 | help | 133 | 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 | |||
| 19 | obj-$(CONFIG_MTD_M25P80) += m25p80.o | 19 | obj-$(CONFIG_MTD_M25P80) += m25p80.o |
| 20 | obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o | 20 | obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o |
| 21 | obj-$(CONFIG_MTD_SST25L) += sst25l.o | 21 | obj-$(CONFIG_MTD_SST25L) += sst25l.o |
| 22 | obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o | ||
| 22 | 23 | ||
| 23 | CFLAGS_docg3.o += -I$(src) \ No newline at end of file | 24 | 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 @@ | |||
| 1 | #include <linux/kernel.h> | ||
| 2 | #include <linux/module.h> | ||
| 3 | #include <linux/slab.h> | ||
| 4 | #include <linux/mtd/mtd.h> | ||
| 5 | #include <linux/platform_device.h> | ||
| 6 | #include <linux/bcma/bcma.h> | ||
| 7 | |||
| 8 | MODULE_LICENSE("GPL"); | ||
| 9 | MODULE_DESCRIPTION("Serial flash driver for BCMA bus"); | ||
| 10 | |||
| 11 | static const char *probes[] = { "bcm47xxpart", NULL }; | ||
| 12 | |||
| 13 | static int bcm47xxsflash_read(struct mtd_info *mtd, loff_t from, size_t len, | ||
| 14 | size_t *retlen, u_char *buf) | ||
| 15 | { | ||
| 16 | struct bcma_sflash *sflash = mtd->priv; | ||
| 17 | |||
| 18 | /* Check address range */ | ||
| 19 | if ((from + len) > mtd->size) | ||
| 20 | return -EINVAL; | ||
| 21 | |||
| 22 | memcpy_fromio(buf, (void __iomem *)KSEG0ADDR(sflash->window + from), | ||
| 23 | len); | ||
| 24 | |||
| 25 | return len; | ||
| 26 | } | ||
| 27 | |||
| 28 | static void bcm47xxsflash_fill_mtd(struct bcma_sflash *sflash, | ||
| 29 | struct mtd_info *mtd) | ||
| 30 | { | ||
| 31 | mtd->priv = sflash; | ||
| 32 | mtd->name = "bcm47xxsflash"; | ||
| 33 | mtd->owner = THIS_MODULE; | ||
| 34 | mtd->type = MTD_ROM; | ||
| 35 | mtd->size = sflash->size; | ||
| 36 | mtd->_read = bcm47xxsflash_read; | ||
| 37 | |||
| 38 | /* TODO: implement writing support and verify/change following code */ | ||
| 39 | mtd->flags = MTD_CAP_ROM; | ||
| 40 | mtd->writebufsize = mtd->writesize = 1; | ||
| 41 | } | ||
| 42 | |||
| 43 | static int bcm47xxsflash_probe(struct platform_device *pdev) | ||
| 44 | { | ||
| 45 | struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev); | ||
| 46 | int err; | ||
| 47 | |||
| 48 | sflash->mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL); | ||
| 49 | if (!sflash->mtd) { | ||
| 50 | err = -ENOMEM; | ||
| 51 | goto out; | ||
| 52 | } | ||
| 53 | bcm47xxsflash_fill_mtd(sflash, sflash->mtd); | ||
| 54 | |||
| 55 | err = mtd_device_parse_register(sflash->mtd, probes, NULL, NULL, 0); | ||
| 56 | if (err) { | ||
| 57 | pr_err("Failed to register MTD device: %d\n", err); | ||
| 58 | goto err_dev_reg; | ||
| 59 | } | ||
| 60 | |||
| 61 | return 0; | ||
| 62 | |||
| 63 | err_dev_reg: | ||
| 64 | kfree(sflash->mtd); | ||
| 65 | out: | ||
| 66 | return err; | ||
| 67 | } | ||
| 68 | |||
| 69 | static int __devexit bcm47xxsflash_remove(struct platform_device *pdev) | ||
| 70 | { | ||
| 71 | struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev); | ||
| 72 | |||
| 73 | mtd_device_unregister(sflash->mtd); | ||
| 74 | kfree(sflash->mtd); | ||
| 75 | |||
| 76 | return 0; | ||
| 77 | } | ||
| 78 | |||
| 79 | static struct platform_driver bcma_sflash_driver = { | ||
| 80 | .remove = __devexit_p(bcm47xxsflash_remove), | ||
| 81 | .driver = { | ||
| 82 | .name = "bcma_sflash", | ||
| 83 | .owner = THIS_MODULE, | ||
| 84 | }, | ||
| 85 | }; | ||
| 86 | |||
| 87 | static int __init bcm47xxsflash_init(void) | ||
| 88 | { | ||
| 89 | int err; | ||
| 90 | |||
| 91 | err = platform_driver_probe(&bcma_sflash_driver, bcm47xxsflash_probe); | ||
| 92 | if (err) | ||
| 93 | pr_err("Failed to register BCMA serial flash driver: %d\n", | ||
| 94 | err); | ||
| 95 | |||
| 96 | return err; | ||
| 97 | } | ||
| 98 | |||
| 99 | static void __exit bcm47xxsflash_exit(void) | ||
| 100 | { | ||
| 101 | platform_driver_unregister(&bcma_sflash_driver); | ||
| 102 | } | ||
| 103 | |||
| 104 | module_init(bcm47xxsflash_init); | ||
| 105 | module_exit(bcm47xxsflash_exit); | ||
