brcm47xx: update flash drivers
[openwrt.git] / target / linux / brcm47xx / patches-3.2 / 027-mtd-bcm47xx-add-serial-flash-driver.patch
index 1b5dafa..45e4a09 100644 (file)
@@ -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;
 +}
This page took 0.036858 seconds and 4 git commands to generate.