diff options
Diffstat (limited to 'target/linux/brcm47xx/patches-3.2/027-mtd-bcm47xx-add-serial-flash-driver.patch')
-rw-r--r-- | target/linux/brcm47xx/patches-3.2/027-mtd-bcm47xx-add-serial-flash-driver.patch | 107 |
1 files changed, 51 insertions, 56 deletions
diff --git a/target/linux/brcm47xx/patches-3.2/027-mtd-bcm47xx-add-serial-flash-driver.patch b/target/linux/brcm47xx/patches-3.2/027-mtd-bcm47xx-add-serial-flash-driver.patch index 1b5dafabd8..45e4a093a0 100644 --- a/target/linux/brcm47xx/patches-3.2/027-mtd-bcm47xx-add-serial-flash-driver.patch +++ b/target/linux/brcm47xx/patches-3.2/027-mtd-bcm47xx-add-serial-flash-driver.patch @@ -1,19 +1,3 @@ -From 2e2951220bf63e05449c03a95453680da1029e44 Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens <hauke@hauke-m.de> -Date: Sun, 17 Jul 2011 14:55:45 +0200 -Subject: [PATCH 08/15] mtd: bcm47xx: add serial flash driver - -sflash get the sflash ops from platform device - -Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> ---- - arch/mips/include/asm/mach-bcm47xx/bus.h | 3 + - drivers/mtd/maps/Kconfig | 9 + - drivers/mtd/maps/Makefile | 1 + - drivers/mtd/maps/bcm47xx-sflash.c | 252 ++++++++++++++++++++++++++++++ - 4 files changed, 265 insertions(+), 0 deletions(-) - create mode 100644 drivers/mtd/maps/bcm47xx-sflash.c - --- a/arch/mips/include/asm/mach-bcm47xx/bus.h +++ b/arch/mips/include/asm/mach-bcm47xx/bus.h @@ -11,6 +11,7 @@ @@ -24,7 +8,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> #include <bcm47xx.h> struct bcm47xx_sflash { -@@ -29,6 +30,8 @@ struct bcm47xx_sflash { +@@ -28,6 +29,8 @@ struct bcm47xx_sflash { u32 blocksize; /* Block size */ u32 numblocks; /* Number of blocks */ u32 size; /* Total size in bytes */ @@ -60,19 +44,15 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +obj-$(CONFIG_MTD_BCM47XX_SFLASH)+= bcm47xx-sflash.o --- /dev/null +++ b/drivers/mtd/maps/bcm47xx-sflash.c -@@ -0,0 +1,252 @@ +@@ -0,0 +1,263 @@ +/* + * Broadcom SiliconBackplane chipcommon serial flash interface + * ++ * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de> + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ ++ * Licensed under the GNU/GPL. See COPYING for details. + */ + +#define pr_fmt(fmt) "bcm47xx_sflash: " fmt @@ -93,28 +73,27 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +sflash_mtd_poll(struct bcm47xx_sflash *sflash, unsigned int offset, int timeout) +{ + unsigned long now = jiffies; -+ int ret = 0; + + for (;;) { + if (!sflash->poll(sflash, offset)) { -+ ret = 0; + break; + } + if (time_after(jiffies, now + timeout)) { + pr_err("timeout while polling\n"); -+ ret = -ETIMEDOUT; -+ break; ++ return -ETIMEDOUT; ++ + } ++ cpu_relax(); + udelay(1); + } + -+ return ret; ++ return 0; +} + +static int +sflash_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) +{ -+ struct bcm47xx_sflash *sflash = (struct bcm47xx_sflash *) mtd->priv; ++ struct bcm47xx_sflash *sflash = (struct bcm47xx_sflash *)mtd->priv; + + /* Check address range */ + if (!len) @@ -124,7 +103,6 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> + return -EINVAL; + + *retlen = 0; -+ + while (len) { + int ret = sflash->read(sflash, from, len, buf); + if (ret < 0) @@ -142,7 +120,9 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +static int +sflash_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) +{ -+ struct bcm47xx_sflash *sflash = (struct bcm47xx_sflash *) mtd->priv; ++ int bytes; ++ int ret; ++ struct bcm47xx_sflash *sflash = (struct bcm47xx_sflash *)mtd->priv; + + /* Check address range */ + if (!len) @@ -153,8 +133,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> + + *retlen = 0; + while (len) { -+ int bytes; -+ int ret = sflash->write(sflash, to, len, buf); ++ ret = sflash->write(sflash, to, len, buf); + if (ret < 0) + return ret; + @@ -228,26 +207,30 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +{ + struct bcm47xx_sflash *sflash = dev_get_platdata(&pdev->dev); + struct mtd_info *mtd; -+ struct mtd_erase_region_info *regions; ++ struct mtd_erase_region_info *eraseregions; + int ret = 0; + + mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL); -+ if (!mtd) -+ return -ENOMEM; ++ if (!mtd){ ++ ret = -ENOMEM; ++ goto err_out; ++ } + -+ regions = kzalloc(sizeof(struct mtd_erase_region_info), GFP_KERNEL); -+ if (!mtd) -+ return -ENOMEM; ++ 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); ++ sflash->blocksize / 1024, sflash->numblocks, sflash->size / 1024); + + /* Setup region info */ -+ regions->offset = 0; -+ regions->erasesize = sflash->blocksize; -+ regions->numblocks = sflash->numblocks; -+ if (regions->erasesize > mtd->erasesize) -+ mtd->erasesize = regions->erasesize; ++ 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; + @@ -255,33 +238,45 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> + mtd->name = "bcm47xx-sflash"; + mtd->type = MTD_NORFLASH; + mtd->flags = MTD_CAP_NORFLASH; -+ mtd->eraseregions = regions; ++ mtd->eraseregions = eraseregions; + mtd->erase = sflash_mtd_erase; + mtd->read = sflash_mtd_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"); -+ return ret; ++ goto err_free_eraseregions; + } -+ sflash->mtd = mtd; + return 0; ++ ++err_free_eraseregions: ++ kfree(eraseregions); ++err_free_mtd: ++ kfree(mtd); ++err_out: ++ return ret; +} + +static int __devexit bcm47xx_sflash_remove(struct platform_device *pdev) +{ -+ struct bcm47xx_sflash *sflash = dev_get_platdata(&pdev->dev); -+ -+ if (sflash) { -+ mtd_device_unregister(sflash->mtd); -+ map_destroy(sflash->mtd); -+ kfree(sflash->mtd->eraseregions); -+ kfree(sflash->mtd); ++ 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; +} |