Merge tag 'mtd/for-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux
[linux-2.6-microblaze.git] / drivers / mtd / rfd_ftl.c
index 6e0d5ce..c546f8c 100644 (file)
@@ -239,7 +239,7 @@ err:
 
 static int rfd_ftl_readsect(struct mtd_blktrans_dev *dev, u_long sector, char *buf)
 {
-       struct partition *part = (struct partition*)dev;
+       struct partition *part = container_of(dev, struct partition, mbd);
        u_long addr;
        size_t retlen;
        int rc;
@@ -600,7 +600,7 @@ static int find_free_sector(const struct partition *part, const struct block *bl
 
 static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf, ulong *old_addr)
 {
-       struct partition *part = (struct partition*)dev;
+       struct partition *part = container_of(dev, struct partition, mbd);
        struct block *block;
        u_long addr;
        int i;
@@ -666,7 +666,7 @@ err:
 
 static int rfd_ftl_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf)
 {
-       struct partition *part = (struct partition*)dev;
+       struct partition *part = container_of(dev, struct partition, mbd);
        u_long old_addr;
        int i;
        int rc = 0;
@@ -705,9 +705,37 @@ err:
        return rc;
 }
 
+static int rfd_ftl_discardsect(struct mtd_blktrans_dev *dev,
+                              unsigned long sector, unsigned int nr_sects)
+{
+       struct partition *part = container_of(dev, struct partition, mbd);
+       u_long addr;
+       int rc;
+
+       while (nr_sects) {
+               if (sector >= part->sector_count)
+                       return -EIO;
+
+               addr = part->sector_map[sector];
+
+               if (addr != -1) {
+                       rc = mark_sector_deleted(part, addr);
+                       if (rc)
+                               return rc;
+
+                       part->sector_map[sector] = -1;
+               }
+
+               sector++;
+               nr_sects--;
+       }
+
+       return 0;
+}
+
 static int rfd_ftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
 {
-       struct partition *part = (struct partition*)dev;
+       struct partition *part = container_of(dev, struct partition, mbd);
 
        geo->heads = 1;
        geo->sectors = SECTORS_PER_TRACK;
@@ -720,7 +748,8 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
 {
        struct partition *part;
 
-       if (mtd->type != MTD_NORFLASH || mtd->size > UINT_MAX)
+       if ((mtd->type != MTD_NORFLASH && mtd->type != MTD_RAM) ||
+           mtd->size > UINT_MAX)
                return;
 
        part = kzalloc(sizeof(struct partition), GFP_KERNEL);
@@ -754,7 +783,7 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
                printk(KERN_INFO PREFIX "name: '%s' type: %d flags %x\n",
                                mtd->name, mtd->type, mtd->flags);
 
-               if (!add_mtd_blktrans_dev((void*)part))
+               if (!add_mtd_blktrans_dev(&part->mbd))
                        return;
        }
 out:
@@ -763,7 +792,7 @@ out:
 
 static void rfd_ftl_remove_dev(struct mtd_blktrans_dev *dev)
 {
-       struct partition *part = (struct partition*)dev;
+       struct partition *part = container_of(dev, struct partition, mbd);
        int i;
 
        for (i=0; i<part->total_blocks; i++) {
@@ -771,10 +800,10 @@ static void rfd_ftl_remove_dev(struct mtd_blktrans_dev *dev)
                        part->mbd.mtd->name, i, part->blocks[i].erases);
        }
 
-       del_mtd_blktrans_dev(dev);
        vfree(part->sector_map);
        kfree(part->header_cache);
        kfree(part->blocks);
+       del_mtd_blktrans_dev(&part->mbd);
 }
 
 static struct mtd_blktrans_ops rfd_ftl_tr = {
@@ -785,6 +814,7 @@ static struct mtd_blktrans_ops rfd_ftl_tr = {
 
        .readsect       = rfd_ftl_readsect,
        .writesect      = rfd_ftl_writesect,
+       .discard        = rfd_ftl_discardsect,
        .getgeo         = rfd_ftl_getgeo,
        .add_mtd        = rfd_ftl_add_mtd,
        .remove_dev     = rfd_ftl_remove_dev,