0001
0002
0003
0004
0005
0006
0007 #include <linux/kernel.h>
0008 #include <linux/module.h>
0009 #include <linux/kmod.h>
0010 #include <linux/spinlock.h>
0011 #include <linux/slab.h>
0012 #include <linux/mtd/map.h>
0013 #include <linux/mtd/mtd.h>
0014
0015 static DEFINE_SPINLOCK(chip_drvs_lock);
0016 static LIST_HEAD(chip_drvs_list);
0017
0018 void register_mtd_chip_driver(struct mtd_chip_driver *drv)
0019 {
0020 spin_lock(&chip_drvs_lock);
0021 list_add(&drv->list, &chip_drvs_list);
0022 spin_unlock(&chip_drvs_lock);
0023 }
0024
0025 void unregister_mtd_chip_driver(struct mtd_chip_driver *drv)
0026 {
0027 spin_lock(&chip_drvs_lock);
0028 list_del(&drv->list);
0029 spin_unlock(&chip_drvs_lock);
0030 }
0031
0032 static struct mtd_chip_driver *get_mtd_chip_driver (const char *name)
0033 {
0034 struct mtd_chip_driver *ret = NULL, *this;
0035
0036 spin_lock(&chip_drvs_lock);
0037
0038 list_for_each_entry(this, &chip_drvs_list, list) {
0039 if (!strcmp(this->name, name)) {
0040 ret = this;
0041 break;
0042 }
0043 }
0044 if (ret && !try_module_get(ret->module))
0045 ret = NULL;
0046
0047 spin_unlock(&chip_drvs_lock);
0048
0049 return ret;
0050 }
0051
0052
0053
0054
0055 struct mtd_info *do_map_probe(const char *name, struct map_info *map)
0056 {
0057 struct mtd_chip_driver *drv;
0058 struct mtd_info *ret;
0059
0060 drv = get_mtd_chip_driver(name);
0061
0062 if (!drv && !request_module("%s", name))
0063 drv = get_mtd_chip_driver(name);
0064
0065 if (!drv)
0066 return NULL;
0067
0068 ret = drv->probe(map);
0069
0070
0071
0072
0073
0074
0075 module_put(drv->module);
0076
0077 return ret;
0078 }
0079
0080
0081
0082
0083 void map_destroy(struct mtd_info *mtd)
0084 {
0085 struct map_info *map = mtd->priv;
0086
0087 if (map->fldrv->destroy)
0088 map->fldrv->destroy(mtd);
0089
0090 module_put(map->fldrv->module);
0091
0092 kfree(mtd);
0093 }
0094
0095 EXPORT_SYMBOL(register_mtd_chip_driver);
0096 EXPORT_SYMBOL(unregister_mtd_chip_driver);
0097 EXPORT_SYMBOL(do_map_probe);
0098 EXPORT_SYMBOL(map_destroy);
0099
0100 MODULE_LICENSE("GPL");
0101 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
0102 MODULE_DESCRIPTION("Core routines for registering and invoking MTD chip drivers");