rk2928:modify gpio numbers
[firefly-linux-kernel-4.4.55.git] / drivers / mtd / mtdconcat.c
index db6de74082ad647d0540b0904e35dacec9c707c9..e601672a53050900d3d0b8cf084829db6d10d9bd 100644 (file)
@@ -1,11 +1,25 @@
 /*
  * MTD device concatenation layer
  *
- * (C) 2002 Robert Kaiser <rkaiser@sysgo.de>
+ * Copyright © 2002 Robert Kaiser <rkaiser@sysgo.de>
+ * Copyright © 2002-2010 David Woodhouse <dwmw2@infradead.org>
  *
  * NAND support by Christian Gan <cgan@iders.ca>
  *
- * This code is GPL
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
  */
 
 #include <linux/kernel.h>
@@ -183,10 +197,9 @@ concat_writev(struct mtd_info *mtd, const struct kvec *vecs,
        }
 
        /* make a copy of vecs */
-       vecs_copy = kmalloc(sizeof(struct kvec) * count, GFP_KERNEL);
+       vecs_copy = kmemdup(vecs, sizeof(struct kvec) * count, GFP_KERNEL);
        if (!vecs_copy)
                return -ENOMEM;
-       memcpy(vecs_copy, vecs, sizeof(struct kvec) * count);
 
        entry_low = 0;
        for (i = 0; i < concat->num_subdev; i++) {
@@ -306,7 +319,7 @@ concat_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops)
        if (!(mtd->flags & MTD_WRITEABLE))
                return -EROFS;
 
-       ops->retlen = 0;
+       ops->retlen = ops->oobretlen = 0;
 
        for (i = 0; i < concat->num_subdev; i++) {
                struct mtd_info *subdev = concat->subdev[i];
@@ -321,7 +334,7 @@ concat_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops)
                        devops.len = subdev->size - to;
 
                err = subdev->write_oob(subdev, to, &devops);
-               ops->retlen += devops.retlen;
+               ops->retlen += devops.oobretlen;
                if (err)
                        return err;
 
@@ -541,10 +554,12 @@ static int concat_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
                else
                        size = len;
 
-               err = subdev->lock(subdev, ofs, size);
-
-               if (err)
-                       break;
+               if (subdev->lock) {
+                       err = subdev->lock(subdev, ofs, size);
+                       if (err)
+                               break;
+               } else
+                       err = -EOPNOTSUPP;
 
                len -= size;
                if (len == 0)
@@ -579,10 +594,12 @@ static int concat_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
                else
                        size = len;
 
-               err = subdev->unlock(subdev, ofs, size);
-
-               if (err)
-                       break;
+               if (subdev->unlock) {
+                       err = subdev->unlock(subdev, ofs, size);
+                       if (err)
+                               break;
+               } else
+                       err = -EOPNOTSUPP;
 
                len -= size;
                if (len == 0)
@@ -733,6 +750,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[],       /* subdevices to c
        struct mtd_concat *concat;
        uint32_t max_erasesize, curr_erasesize;
        int num_erase_region;
+       int max_writebufsize = 0;
 
        printk(KERN_NOTICE "Concatenating MTD devices:\n");
        for (i = 0; i < num_devs; i++)
@@ -759,6 +777,12 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[],      /* subdevices to c
        concat->mtd.size = subdev[0]->size;
        concat->mtd.erasesize = subdev[0]->erasesize;
        concat->mtd.writesize = subdev[0]->writesize;
+
+       for (i = 0; i < num_devs; i++)
+               if (max_writebufsize < subdev[i]->writebufsize)
+                       max_writebufsize = subdev[i]->writebufsize;
+       concat->mtd.writebufsize = max_writebufsize;
+
        concat->mtd.subpage_sft = subdev[0]->subpage_sft;
        concat->mtd.oobsize = subdev[0]->oobsize;
        concat->mtd.oobavail = subdev[0]->oobavail;