[MTD] add get and put methods
authorArtem Bityutskiy <dedekind@infradead.org>
Wed, 11 Oct 2006 11:52:45 +0000 (14:52 +0300)
committerArtem Bityutskiy <dedekind@infradead.org>
Wed, 29 Nov 2006 15:04:53 +0000 (17:04 +0200)
This patch adds get_device() and put_device() methods to the MTD description
structure (struct mtd_info). These methods are called by MTD whenever the MTD
device is get or put. They are needed when the underlying driver is something
smarter then just flash chip driver, for example UBI.

Signed-off-by: Artem Bityutskiy <dedekind@infradead.org>
drivers/mtd/mtdcore.c
include/linux/mtd/mtd.h

index 06ec9f836ae5955a4974e1ec01bb485bdfd99c3d..f11f55f02413332dcb8aa31e02a00ab38a1e9603 100644 (file)
@@ -214,12 +214,23 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
                        ret = NULL;
        }
 
-       if (ret && !try_module_get(ret->owner))
+       if (!ret)
+               goto out_unlock;
+
+       if (!try_module_get(ret->owner)) {
+               ret = NULL;
+               goto out_unlock;
+       }
+
+       if (ret->get_device && ret->get_device(ret)) {
+               module_put(ret->owner);
                ret = NULL;
+               goto out_unlock;
+       }
 
-       if (ret)
-               ret->usecount++;
+       ret->usecount++;
 
+out_unlock:
        mutex_unlock(&mtd_table_mutex);
        return ret;
 }
@@ -235,8 +246,8 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
 
 struct mtd_info *get_mtd_device_nm(const char *name)
 {
-       int i;
-       struct mtd_info *mtd = ERR_PTR(-ENODEV);
+       int i, err = -ENODEV;
+       struct mtd_info *mtd = NULL;
 
        mutex_lock(&mtd_table_mutex);
 
@@ -247,17 +258,27 @@ struct mtd_info *get_mtd_device_nm(const char *name)
                }
        }
 
-       if (i == MAX_MTD_DEVICES)
+       if (!mtd)
                goto out_unlock;
 
        if (!try_module_get(mtd->owner))
                goto out_unlock;
 
+       if (mtd->get_device) {
+               err = mtd->get_device(mtd);
+               if (err)
+                       goto out_put;
+       }
+
        mtd->usecount++;
+       mutex_unlock(&mtd_table_mutex);
+       return mtd;
 
+out_put:
+       module_put(mtd->owner);
 out_unlock:
        mutex_unlock(&mtd_table_mutex);
-       return mtd;
+       return ERR_PTR(err);
 }
 
 void put_mtd_device(struct mtd_info *mtd)
@@ -266,6 +287,8 @@ void put_mtd_device(struct mtd_info *mtd)
 
        mutex_lock(&mtd_table_mutex);
        c = --mtd->usecount;
+       if (mtd->put_device)
+               mtd->put_device(mtd);
        mutex_unlock(&mtd_table_mutex);
        BUG_ON(c < 0);
 
index 89e937dfef55d2859448a21b6abae4d3f1820a26..d644e57703ad0ef256b2099af0b883c06959ce35 100644 (file)
@@ -207,6 +207,13 @@ struct mtd_info {
 
        struct module *owner;
        int usecount;
+
+       /* If the driver is something smart, like UBI, it may need to maintain
+        * its own reference counting. The below functions are only for driver.
+        * The driver may register its callbacks. These callbacks are not
+        * supposed to be called by MTD users */
+       int (*get_device) (struct mtd_info *mtd);
+       void (*put_device) (struct mtd_info *mtd);
 };