aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Bityutskiy <dedekind@infradead.org>2006-10-11 07:52:45 -0400
committerArtem Bityutskiy <dedekind@infradead.org>2006-11-29 10:04:53 -0500
commit9fe912cea32aec18f860c95e8574410b5892481b (patch)
tree3efcd1c31f2af29b4357164d5891cfdbe6f3e052
parent7799308f34d3c3371a319559687c78c0f2506fcf (diff)
[MTD] add get and put methods
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>
-rw-r--r--drivers/mtd/mtdcore.c37
-rw-r--r--include/linux/mtd/mtd.h7
2 files changed, 37 insertions, 7 deletions
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 06ec9f836ae5..f11f55f02413 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -214,12 +214,23 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
214 ret = NULL; 214 ret = NULL;
215 } 215 }
216 216
217 if (ret && !try_module_get(ret->owner)) 217 if (!ret)
218 goto out_unlock;
219
220 if (!try_module_get(ret->owner)) {
221 ret = NULL;
222 goto out_unlock;
223 }
224
225 if (ret->get_device && ret->get_device(ret)) {
226 module_put(ret->owner);
218 ret = NULL; 227 ret = NULL;
228 goto out_unlock;
229 }
219 230
220 if (ret) 231 ret->usecount++;
221 ret->usecount++;
222 232
233out_unlock:
223 mutex_unlock(&mtd_table_mutex); 234 mutex_unlock(&mtd_table_mutex);
224 return ret; 235 return ret;
225} 236}
@@ -235,8 +246,8 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
235 246
236struct mtd_info *get_mtd_device_nm(const char *name) 247struct mtd_info *get_mtd_device_nm(const char *name)
237{ 248{
238 int i; 249 int i, err = -ENODEV;
239 struct mtd_info *mtd = ERR_PTR(-ENODEV); 250 struct mtd_info *mtd = NULL;
240 251
241 mutex_lock(&mtd_table_mutex); 252 mutex_lock(&mtd_table_mutex);
242 253
@@ -247,17 +258,27 @@ struct mtd_info *get_mtd_device_nm(const char *name)
247 } 258 }
248 } 259 }
249 260
250 if (i == MAX_MTD_DEVICES) 261 if (!mtd)
251 goto out_unlock; 262 goto out_unlock;
252 263
253 if (!try_module_get(mtd->owner)) 264 if (!try_module_get(mtd->owner))
254 goto out_unlock; 265 goto out_unlock;
255 266
267 if (mtd->get_device) {
268 err = mtd->get_device(mtd);
269 if (err)
270 goto out_put;
271 }
272
256 mtd->usecount++; 273 mtd->usecount++;
274 mutex_unlock(&mtd_table_mutex);
275 return mtd;
257 276
277out_put:
278 module_put(mtd->owner);
258out_unlock: 279out_unlock:
259 mutex_unlock(&mtd_table_mutex); 280 mutex_unlock(&mtd_table_mutex);
260 return mtd; 281 return ERR_PTR(err);
261} 282}
262 283
263void put_mtd_device(struct mtd_info *mtd) 284void put_mtd_device(struct mtd_info *mtd)
@@ -266,6 +287,8 @@ void put_mtd_device(struct mtd_info *mtd)
266 287
267 mutex_lock(&mtd_table_mutex); 288 mutex_lock(&mtd_table_mutex);
268 c = --mtd->usecount; 289 c = --mtd->usecount;
290 if (mtd->put_device)
291 mtd->put_device(mtd);
269 mutex_unlock(&mtd_table_mutex); 292 mutex_unlock(&mtd_table_mutex);
270 BUG_ON(c < 0); 293 BUG_ON(c < 0);
271 294
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 89e937dfef55..d644e57703ad 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -207,6 +207,13 @@ struct mtd_info {
207 207
208 struct module *owner; 208 struct module *owner;
209 int usecount; 209 int usecount;
210
211 /* If the driver is something smart, like UBI, it may need to maintain
212 * its own reference counting. The below functions are only for driver.
213 * The driver may register its callbacks. These callbacks are not
214 * supposed to be called by MTD users */
215 int (*get_device) (struct mtd_info *mtd);
216 void (*put_device) (struct mtd_info *mtd);
210}; 217};
211 218
212 219