aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm47xx/patches-3.9/052-mtd-add-serial-flash-driver.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm47xx/patches-3.9/052-mtd-add-serial-flash-driver.patch')
-rw-r--r--target/linux/brcm47xx/patches-3.9/052-mtd-add-serial-flash-driver.patch345
1 files changed, 0 insertions, 345 deletions
diff --git a/target/linux/brcm47xx/patches-3.9/052-mtd-add-serial-flash-driver.patch b/target/linux/brcm47xx/patches-3.9/052-mtd-add-serial-flash-driver.patch
deleted file mode 100644
index 844f89d4b3..0000000000
--- a/target/linux/brcm47xx/patches-3.9/052-mtd-add-serial-flash-driver.patch
+++ /dev/null
@@ -1,345 +0,0 @@
---- a/drivers/mtd/devices/bcm47xxsflash.c
-+++ b/drivers/mtd/devices/bcm47xxsflash.c
-@@ -1,47 +1,153 @@
--#include <linux/kernel.h>
-+/*
-+ * Broadcom SiliconBackplane chipcommon serial flash interface
-+ *
-+ * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
-+ * Copyright 2006, Broadcom Corporation
-+ * All Rights Reserved.
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+#define pr_fmt(fmt) "bcm47xxsflash: " fmt
- #include <linux/module.h>
- #include <linux/slab.h>
-+#include <linux/ioport.h>
-+#include <linux/sched.h>
- #include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/errno.h>
-+#include <linux/delay.h>
- #include <linux/platform_device.h>
--#include <linux/bcma/bcma.h>
--
--#include "bcm47xxsflash.h"
-+#include <linux/mtd/bcm47xxsflash.h>
-
- MODULE_LICENSE("GPL");
--MODULE_DESCRIPTION("Serial flash driver for BCMA bus");
-+MODULE_DESCRIPTION("BCM47XX serial flash driver");
-
- static const char *probes[] = { "bcm47xxpart", NULL };
-
-+static int
-+sflash_mtd_poll(struct bcm47xxsflash *sflash, unsigned int offset, int timeout)
-+{
-+ unsigned long now = jiffies;
-+
-+ for (;;) {
-+ if (!sflash->poll(sflash, offset)) {
-+ break;
-+ }
-+ if (time_after(jiffies, now + timeout)) {
-+ pr_err("timeout while polling\n");
-+ return -ETIMEDOUT;
-+
-+ }
-+ cpu_relax();
-+ udelay(1);
-+ }
-+
-+ return 0;
-+}
-+
- static int bcm47xxsflash_read(struct mtd_info *mtd, loff_t from, size_t len,
- size_t *retlen, u_char *buf)
- {
-- struct bcm47xxsflash *b47s = mtd->priv;
-+ struct bcm47xxsflash *sflash = (struct bcm47xxsflash *)mtd->priv;
-
- /* Check address range */
-+ if (!len)
-+ return 0;
-+
- if ((from + len) > mtd->size)
- return -EINVAL;
-
-- memcpy_fromio(buf, (void __iomem *)KSEG0ADDR(b47s->window + from),
-+ memcpy_fromio(buf, (void __iomem *)KSEG0ADDR(sflash->window + from),
- len);
- *retlen = len;
-
- return len;
- }
-
--static void bcm47xxsflash_fill_mtd(struct bcm47xxsflash *b47s)
-+static int
-+sflash_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
- {
-- struct mtd_info *mtd = &b47s->mtd;
-+ int bytes;
-+ int ret;
-+ struct bcm47xxsflash *sflash = (struct bcm47xxsflash *)mtd->priv;
-
-- mtd->priv = b47s;
-- mtd->name = "bcm47xxsflash";
-- mtd->owner = THIS_MODULE;
-- mtd->type = MTD_ROM;
-- mtd->size = b47s->size;
-- mtd->_read = bcm47xxsflash_read;
-+ /* Check address range */
-+ if (!len)
-+ return 0;
-+
-+ if ((to + len) > mtd->size)
-+ return -EINVAL;
-+
-+ *retlen = 0;
-+ while (len) {
-+ ret = sflash->write(sflash, to, len, buf);
-+ if (ret < 0)
-+ return ret;
-+
-+ bytes = ret;
-+
-+ ret = sflash_mtd_poll(sflash, (unsigned int) to, HZ / 10);
-+ if (ret)
-+ return ret;
-+
-+ to += (loff_t) bytes;
-+ len -= bytes;
-+ buf += bytes;
-+ *retlen += bytes;
-+ }
-
-- /* TODO: implement writing support and verify/change following code */
-- mtd->flags = MTD_CAP_ROM;
-- mtd->writebufsize = mtd->writesize = 1;
-+ return 0;
-+}
-+
-+static int
-+sflash_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
-+{
-+ struct bcm47xxsflash *sflash = (struct bcm47xxsflash *) mtd->priv;
-+ int i, j, ret = 0;
-+ unsigned int addr, len;
-+
-+ /* Check address range */
-+ if (!erase->len)
-+ return 0;
-+ if ((erase->addr + erase->len) > mtd->size)
-+ return -EINVAL;
-+
-+ addr = erase->addr;
-+ len = erase->len;
-+
-+ /* Ensure that requested regions are aligned */
-+ for (i = 0; i < mtd->numeraseregions; i++) {
-+ for (j = 0; j < mtd->eraseregions[i].numblocks; j++) {
-+ if (addr == mtd->eraseregions[i].offset +
-+ mtd->eraseregions[i].erasesize * j &&
-+ len >= mtd->eraseregions[i].erasesize) {
-+ ret = sflash->erase(sflash, addr);
-+ if (ret < 0)
-+ break;
-+ ret = sflash_mtd_poll(sflash, addr, 10 * HZ);
-+ if (ret)
-+ break;
-+ addr += mtd->eraseregions[i].erasesize;
-+ len -= mtd->eraseregions[i].erasesize;
-+ }
-+ }
-+ if (ret)
-+ break;
-+ }
-+
-+ /* Set erase status */
-+ if (ret)
-+ erase->state = MTD_ERASE_FAILED;
-+ else
-+ erase->state = MTD_ERASE_DONE;
-+
-+ /* Call erase callback */
-+ if (erase->callback)
-+ erase->callback(erase);
-+
-+ return ret;
- }
-
- /**************************************************
-@@ -50,53 +156,94 @@ static void bcm47xxsflash_fill_mtd(struc
-
- static int bcm47xxsflash_bcma_probe(struct platform_device *pdev)
- {
-- struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev);
-- struct bcm47xxsflash *b47s;
-- int err;
-+ struct bcm47xxsflash *sflash = dev_get_platdata(&pdev->dev);
-+ struct mtd_info *mtd;
-+ struct mtd_erase_region_info *eraseregions;
-+ int ret = 0;
-+
-+ mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
-+ if (!mtd){
-+ ret = -ENOMEM;
-+ goto err_out;
-+ }
-
-- b47s = kzalloc(sizeof(*b47s), GFP_KERNEL);
-- if (!b47s) {
-- err = -ENOMEM;
-- goto out;
-- }
-- sflash->priv = b47s;
--
-- 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);
-- goto err_dev_reg;
-+ eraseregions = kzalloc(sizeof(struct mtd_erase_region_info), GFP_KERNEL);
-+ if (!eraseregions) {
-+ ret = -ENOMEM;
-+ goto err_free_mtd;
- }
-
-+ pr_info("found serial flash: blocksize=%dKB, numblocks=%d, size=%dKB\n",
-+ sflash->blocksize / 1024, sflash->numblocks, sflash->size / 1024);
-+
-+ /* Setup region info */
-+ eraseregions->offset = 0;
-+ eraseregions->erasesize = sflash->blocksize;
-+ eraseregions->numblocks = sflash->numblocks;
-+ if (eraseregions->erasesize > mtd->erasesize)
-+ mtd->erasesize = eraseregions->erasesize;
-+ mtd->size = sflash->size;
-+ mtd->numeraseregions = 1;
-+
-+ /* Register with MTD */
-+ mtd->name = "bcm47xx-sflash";
-+ mtd->type = MTD_NORFLASH;
-+ mtd->flags = MTD_CAP_NORFLASH;
-+ mtd->eraseregions = eraseregions;
-+ mtd->_erase = sflash_mtd_erase;
-+ mtd->_read = bcm47xxsflash_read;
-+ mtd->_write = sflash_mtd_write;
-+ mtd->writesize = 1;
-+ mtd->priv = sflash;
-+ ret = dev_set_drvdata(&pdev->dev, mtd);
-+ mtd->owner = THIS_MODULE;
-+ if (ret) {
-+ pr_err("adding private data failed\n");
-+ goto err_free_eraseregions;
-+ }
-+
-+ ret = mtd_device_parse_register(mtd, probes, NULL, NULL, 0);
-+
-+ if (ret) {
-+ pr_err("mtd_device_register failed\n");
-+ goto err_free_eraseregions;
-+ }
- return 0;
-
--err_dev_reg:
-- kfree(&b47s->mtd);
--out:
-- return err;
-+err_free_eraseregions:
-+ kfree(eraseregions);
-+err_free_mtd:
-+ kfree(mtd);
-+err_out:
-+ return ret;
- }
-
- static int bcm47xxsflash_bcma_remove(struct platform_device *pdev)
- {
-- struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev);
-- struct bcm47xxsflash *b47s = sflash->priv;
--
-- mtd_device_unregister(&b47s->mtd);
-- kfree(b47s);
-+ struct mtd_info *mtd = dev_get_drvdata(&pdev->dev);
-
-+ if (mtd) {
-+ mtd_device_unregister(mtd);
-+ map_destroy(mtd);
-+ kfree(mtd->eraseregions);
-+ kfree(mtd);
-+ dev_set_drvdata(&pdev->dev, NULL);
-+ }
- return 0;
- }
-
-+static const struct platform_device_id bcm47xxsflash_table[] = {
-+ { "bcm47xx-sflash", 0 },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(platform, bcm47xxsflash_table);
-+
- static struct platform_driver bcma_sflash_driver = {
-+ .id_table = bcm47xxsflash_table,
- .probe = bcm47xxsflash_bcma_probe,
- .remove = bcm47xxsflash_bcma_remove,
- .driver = {
-- .name = "bcma_sflash",
-+ .name = "bcm47xx-sflash",
- .owner = THIS_MODULE,
- },
- };
-@@ -111,8 +258,7 @@ static int __init bcm47xxsflash_init(voi
-
- err = platform_driver_register(&bcma_sflash_driver);
- if (err)
-- pr_err("Failed to register BCMA serial flash driver: %d\n",
-- err);
-+ pr_err("error registering platform driver: %i\n", err);
-
- return err;
- }
---- /dev/null
-+++ b/include/linux/mtd/bcm47xxsflash.h
-@@ -0,0 +1,33 @@
-+#ifndef LINUX_MTD_BCM47XX_SFLASH_H_
-+#define LINUX_MTD_BCM47XX_SFLASH_H_
-+
-+#include <linux/mtd/mtd.h>
-+
-+enum bcm47xxsflash_type {
-+ BCM47XX_SFLASH_SSB,
-+ BCM47XX_SFLASH_BCMA,
-+};
-+
-+struct ssb_chipcommon;
-+struct bcma_drv_cc;
-+
-+struct bcm47xxsflash {
-+ enum bcm47xxsflash_type type;
-+ union {
-+ struct ssb_chipcommon *scc;
-+ struct bcma_drv_cc *bcc;
-+ };
-+
-+ bool present;
-+ u16 numblocks;
-+ u32 window;
-+ u32 blocksize;
-+ u32 size;
-+
-+ int (*poll)(struct bcm47xxsflash *dev, u32 offset);
-+ int (*write)(struct bcm47xxsflash *dev, u32 offset, u32 len, const u8 *buf);
-+ int (*erase)(struct bcm47xxsflash *dev, u32 offset);
-+
-+ struct mtd_info *mtd;
-+};
-+#endif /* LINUX_MTD_BCM47XX_SFLASH_H_ */