diff options
author | Kevin Cernekee <kpc.mtd@gmail.com> | 2009-04-03 16:00:45 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2009-04-04 09:32:39 -0400 |
commit | 694bb7fc19c6b87e106f4c85a2707072e2f111a0 (patch) | |
tree | 7c5e2f4cfbe89fee0779b8d7d92b51a84a276747 /drivers/mtd | |
parent | 1f24b5a8ecbb2a3c7080f418974d40e3ffedb221 (diff) |
[MTD] driver model updates (part 2)
1) Add more sysfs attributes: flags, size, erasesize, writesize,
oobsize, numeraseregions, name
2) Move core_initcall() code into init_mtd(). The original approach
does not work if CONFIG_MTD=m .
3) Add device_unregister() in del_mtd_device() so that devices get
removed from sysfs as each driver is unloaded.
Signed-off-by: Kevin Cernekee <kpc.mtd@gmail.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/mtdcore.c | 111 |
1 files changed, 90 insertions, 21 deletions
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index a88f8bc9a534..89c1e5ddc7c2 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c | |||
@@ -89,11 +89,89 @@ static ssize_t mtd_type_show(struct device *dev, | |||
89 | 89 | ||
90 | return snprintf(buf, PAGE_SIZE, "%s\n", type); | 90 | return snprintf(buf, PAGE_SIZE, "%s\n", type); |
91 | } | 91 | } |
92 | static DEVICE_ATTR(mtd_type, S_IRUGO, mtd_type_show, NULL); | 92 | static DEVICE_ATTR(type, S_IRUGO, mtd_type_show, NULL); |
93 | |||
94 | static ssize_t mtd_flags_show(struct device *dev, | ||
95 | struct device_attribute *attr, char *buf) | ||
96 | { | ||
97 | struct mtd_info *mtd = dev_to_mtd(dev); | ||
98 | |||
99 | return snprintf(buf, PAGE_SIZE, "0x%lx\n", (unsigned long)mtd->flags); | ||
100 | |||
101 | } | ||
102 | static DEVICE_ATTR(flags, S_IRUGO, mtd_flags_show, NULL); | ||
103 | |||
104 | static ssize_t mtd_size_show(struct device *dev, | ||
105 | struct device_attribute *attr, char *buf) | ||
106 | { | ||
107 | struct mtd_info *mtd = dev_to_mtd(dev); | ||
108 | |||
109 | return snprintf(buf, PAGE_SIZE, "%llu\n", | ||
110 | (unsigned long long)mtd->size); | ||
111 | |||
112 | } | ||
113 | static DEVICE_ATTR(size, S_IRUGO, mtd_size_show, NULL); | ||
114 | |||
115 | static ssize_t mtd_erasesize_show(struct device *dev, | ||
116 | struct device_attribute *attr, char *buf) | ||
117 | { | ||
118 | struct mtd_info *mtd = dev_to_mtd(dev); | ||
119 | |||
120 | return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->erasesize); | ||
121 | |||
122 | } | ||
123 | static DEVICE_ATTR(erasesize, S_IRUGO, mtd_erasesize_show, NULL); | ||
124 | |||
125 | static ssize_t mtd_writesize_show(struct device *dev, | ||
126 | struct device_attribute *attr, char *buf) | ||
127 | { | ||
128 | struct mtd_info *mtd = dev_to_mtd(dev); | ||
129 | |||
130 | return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->writesize); | ||
131 | |||
132 | } | ||
133 | static DEVICE_ATTR(writesize, S_IRUGO, mtd_writesize_show, NULL); | ||
134 | |||
135 | static ssize_t mtd_oobsize_show(struct device *dev, | ||
136 | struct device_attribute *attr, char *buf) | ||
137 | { | ||
138 | struct mtd_info *mtd = dev_to_mtd(dev); | ||
139 | |||
140 | return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->oobsize); | ||
141 | |||
142 | } | ||
143 | static DEVICE_ATTR(oobsize, S_IRUGO, mtd_oobsize_show, NULL); | ||
144 | |||
145 | static ssize_t mtd_numeraseregions_show(struct device *dev, | ||
146 | struct device_attribute *attr, char *buf) | ||
147 | { | ||
148 | struct mtd_info *mtd = dev_to_mtd(dev); | ||
149 | |||
150 | return snprintf(buf, PAGE_SIZE, "%u\n", mtd->numeraseregions); | ||
151 | |||
152 | } | ||
153 | static DEVICE_ATTR(numeraseregions, S_IRUGO, mtd_numeraseregions_show, | ||
154 | NULL); | ||
155 | |||
156 | static ssize_t mtd_name_show(struct device *dev, | ||
157 | struct device_attribute *attr, char *buf) | ||
158 | { | ||
159 | struct mtd_info *mtd = dev_to_mtd(dev); | ||
160 | |||
161 | return snprintf(buf, PAGE_SIZE, "%s\n", mtd->name); | ||
162 | |||
163 | } | ||
164 | static DEVICE_ATTR(name, S_IRUGO, mtd_name_show, NULL); | ||
93 | 165 | ||
94 | static struct attribute *mtd_attrs[] = { | 166 | static struct attribute *mtd_attrs[] = { |
95 | &dev_attr_mtd_type.attr, | 167 | &dev_attr_type.attr, |
96 | /* FIXME provide a /proc/mtd superset */ | 168 | &dev_attr_flags.attr, |
169 | &dev_attr_size.attr, | ||
170 | &dev_attr_erasesize.attr, | ||
171 | &dev_attr_writesize.attr, | ||
172 | &dev_attr_oobsize.attr, | ||
173 | &dev_attr_numeraseregions.attr, | ||
174 | &dev_attr_name.attr, | ||
97 | NULL, | 175 | NULL, |
98 | }; | 176 | }; |
99 | 177 | ||
@@ -236,6 +314,8 @@ int del_mtd_device (struct mtd_info *mtd) | |||
236 | } else { | 314 | } else { |
237 | struct mtd_notifier *not; | 315 | struct mtd_notifier *not; |
238 | 316 | ||
317 | device_unregister(&mtd->dev); | ||
318 | |||
239 | /* No need to get a refcount on the module containing | 319 | /* No need to get a refcount on the module containing |
240 | the notifier, since we hold the mtd_table_mutex */ | 320 | the notifier, since we hold the mtd_table_mutex */ |
241 | list_for_each_entry(not, &mtd_notifiers, list) | 321 | list_for_each_entry(not, &mtd_notifiers, list) |
@@ -455,24 +535,6 @@ EXPORT_SYMBOL_GPL(register_mtd_user); | |||
455 | EXPORT_SYMBOL_GPL(unregister_mtd_user); | 535 | EXPORT_SYMBOL_GPL(unregister_mtd_user); |
456 | EXPORT_SYMBOL_GPL(default_mtd_writev); | 536 | EXPORT_SYMBOL_GPL(default_mtd_writev); |
457 | 537 | ||
458 | static int __init mtd_setup(void) | ||
459 | { | ||
460 | mtd_class = class_create(THIS_MODULE, "mtd"); | ||
461 | |||
462 | if (IS_ERR(mtd_class)) { | ||
463 | pr_err("Error creating mtd class.\n"); | ||
464 | return PTR_ERR(mtd_class); | ||
465 | } | ||
466 | return 0; | ||
467 | } | ||
468 | core_initcall(mtd_setup); | ||
469 | |||
470 | static void __exit mtd_teardown(void) | ||
471 | { | ||
472 | class_destroy(mtd_class); | ||
473 | } | ||
474 | __exitcall(mtd_teardown); | ||
475 | |||
476 | #ifdef CONFIG_PROC_FS | 538 | #ifdef CONFIG_PROC_FS |
477 | 539 | ||
478 | /*====================================================================*/ | 540 | /*====================================================================*/ |
@@ -528,6 +590,12 @@ done: | |||
528 | 590 | ||
529 | static int __init init_mtd(void) | 591 | static int __init init_mtd(void) |
530 | { | 592 | { |
593 | mtd_class = class_create(THIS_MODULE, "mtd"); | ||
594 | |||
595 | if (IS_ERR(mtd_class)) { | ||
596 | pr_err("Error creating mtd class.\n"); | ||
597 | return PTR_ERR(mtd_class); | ||
598 | } | ||
531 | if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) | 599 | if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) |
532 | proc_mtd->read_proc = mtd_read_proc; | 600 | proc_mtd->read_proc = mtd_read_proc; |
533 | return 0; | 601 | return 0; |
@@ -537,6 +605,7 @@ static void __exit cleanup_mtd(void) | |||
537 | { | 605 | { |
538 | if (proc_mtd) | 606 | if (proc_mtd) |
539 | remove_proc_entry( "mtd", NULL); | 607 | remove_proc_entry( "mtd", NULL); |
608 | class_destroy(mtd_class); | ||
540 | } | 609 | } |
541 | 610 | ||
542 | module_init(init_mtd); | 611 | module_init(init_mtd); |