aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/device.h1
-rw-r--r--include/linux/module.h2
-rw-r--r--kernel/module.c33
-rw-r--r--kernel/params.c12
4 files changed, 31 insertions, 17 deletions
diff --git a/include/linux/device.h b/include/linux/device.h
index f44247fe8135..da7221913114 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -126,6 +126,7 @@ struct device_driver {
126 struct klist_node knode_bus; 126 struct klist_node knode_bus;
127 127
128 struct module * owner; 128 struct module * owner;
129 const char * mod_name; /* used for built-in modules */
129 130
130 int (*probe) (struct device * dev); 131 int (*probe) (struct device * dev);
131 int (*remove) (struct device * dev); 132 int (*remove) (struct device * dev);
diff --git a/include/linux/module.h b/include/linux/module.h
index 10f771a49997..90dc2542978c 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -58,6 +58,7 @@ struct module_kobject
58{ 58{
59 struct kobject kobj; 59 struct kobject kobj;
60 struct module *mod; 60 struct module *mod;
61 struct kobject *drivers_dir;
61}; 62};
62 63
63/* These are either module local, or the kernel's dummy ones. */ 64/* These are either module local, or the kernel's dummy ones. */
@@ -263,7 +264,6 @@ struct module
263 struct module_attribute *modinfo_attrs; 264 struct module_attribute *modinfo_attrs;
264 const char *version; 265 const char *version;
265 const char *srcversion; 266 const char *srcversion;
266 struct kobject *drivers_dir;
267 267
268 /* Exported symbols */ 268 /* Exported symbols */
269 const struct kernel_symbol *syms; 269 const struct kernel_symbol *syms;
diff --git a/kernel/module.c b/kernel/module.c
index d0f2260a0210..0f4489af3e29 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1131,8 +1131,8 @@ static int mod_sysfs_setup(struct module *mod,
1131 if (err) 1131 if (err)
1132 goto out; 1132 goto out;
1133 1133
1134 mod->drivers_dir = kobject_add_dir(&mod->mkobj.kobj, "drivers"); 1134 mod->mkobj.drivers_dir = kobject_add_dir(&mod->mkobj.kobj, "drivers");
1135 if (!mod->drivers_dir) { 1135 if (!mod->mkobj.drivers_dir) {
1136 err = -ENOMEM; 1136 err = -ENOMEM;
1137 goto out_unreg; 1137 goto out_unreg;
1138 } 1138 }
@@ -1151,7 +1151,7 @@ static int mod_sysfs_setup(struct module *mod,
1151out_unreg_param: 1151out_unreg_param:
1152 module_param_sysfs_remove(mod); 1152 module_param_sysfs_remove(mod);
1153out_unreg_drivers: 1153out_unreg_drivers:
1154 kobject_unregister(mod->drivers_dir); 1154 kobject_unregister(mod->mkobj.drivers_dir);
1155out_unreg: 1155out_unreg:
1156 kobject_del(&mod->mkobj.kobj); 1156 kobject_del(&mod->mkobj.kobj);
1157 kobject_put(&mod->mkobj.kobj); 1157 kobject_put(&mod->mkobj.kobj);
@@ -1163,7 +1163,7 @@ static void mod_kobject_remove(struct module *mod)
1163{ 1163{
1164 module_remove_modinfo_attrs(mod); 1164 module_remove_modinfo_attrs(mod);
1165 module_param_sysfs_remove(mod); 1165 module_param_sysfs_remove(mod);
1166 kobject_unregister(mod->drivers_dir); 1166 kobject_unregister(mod->mkobj.drivers_dir);
1167 1167
1168 kobject_unregister(&mod->mkobj.kobj); 1168 kobject_unregister(&mod->mkobj.kobj);
1169} 1169}
@@ -2344,15 +2344,30 @@ void module_add_driver(struct module *mod, struct device_driver *drv)
2344{ 2344{
2345 char *driver_name; 2345 char *driver_name;
2346 int no_warn; 2346 int no_warn;
2347 struct module_kobject *mk = NULL;
2347 2348
2348 if (!mod || !drv) 2349 if (!drv)
2350 return;
2351
2352 if (mod)
2353 mk = &mod->mkobj;
2354 else if (drv->mod_name) {
2355 struct kobject *mkobj;
2356
2357 /* Lookup built-in module entry in /sys/modules */
2358 mkobj = kset_find_obj(&module_subsys.kset, drv->mod_name);
2359 if (mkobj)
2360 mk = container_of(mkobj, struct module_kobject, kobj);
2361 }
2362
2363 if (!mk)
2349 return; 2364 return;
2350 2365
2351 /* Don't check return codes; these calls are idempotent */ 2366 /* Don't check return codes; these calls are idempotent */
2352 no_warn = sysfs_create_link(&drv->kobj, &mod->mkobj.kobj, "module"); 2367 no_warn = sysfs_create_link(&drv->kobj, &mk->kobj, "module");
2353 driver_name = make_driver_name(drv); 2368 driver_name = make_driver_name(drv);
2354 if (driver_name) { 2369 if (driver_name) {
2355 no_warn = sysfs_create_link(mod->drivers_dir, &drv->kobj, 2370 no_warn = sysfs_create_link(mk->drivers_dir, &drv->kobj,
2356 driver_name); 2371 driver_name);
2357 kfree(driver_name); 2372 kfree(driver_name);
2358 } 2373 }
@@ -2367,10 +2382,10 @@ void module_remove_driver(struct device_driver *drv)
2367 return; 2382 return;
2368 2383
2369 sysfs_remove_link(&drv->kobj, "module"); 2384 sysfs_remove_link(&drv->kobj, "module");
2370 if (drv->owner && drv->owner->drivers_dir) { 2385 if (drv->owner && drv->owner->mkobj.drivers_dir) {
2371 driver_name = make_driver_name(drv); 2386 driver_name = make_driver_name(drv);
2372 if (driver_name) { 2387 if (driver_name) {
2373 sysfs_remove_link(drv->owner->drivers_dir, 2388 sysfs_remove_link(drv->owner->mkobj.drivers_dir,
2374 driver_name); 2389 driver_name);
2375 kfree(driver_name); 2390 kfree(driver_name);
2376 } 2391 }
diff --git a/kernel/params.c b/kernel/params.c
index 718945da8f58..737b7c5e93aa 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -561,14 +561,12 @@ static void __init kernel_param_sysfs_setup(const char *name,
561 mk->mod = THIS_MODULE; 561 mk->mod = THIS_MODULE;
562 kobj_set_kset_s(mk, module_subsys); 562 kobj_set_kset_s(mk, module_subsys);
563 kobject_set_name(&mk->kobj, name); 563 kobject_set_name(&mk->kobj, name);
564 ret = kobject_register(&mk->kobj); 564 kobject_init(&mk->kobj);
565 ret = kobject_add(&mk->kobj);
565 BUG_ON(ret < 0); 566 BUG_ON(ret < 0);
566 567 param_sysfs_setup(mk, kparam, num_params, name_skip);
567 /* no need to keep the kobject if no parameter is exported */ 568 mk->drivers_dir = kobject_add_dir(&mk->kobj, "drivers");
568 if (!param_sysfs_setup(mk, kparam, num_params, name_skip)) { 569 kobject_uevent(&mk->kobj, KOBJ_ADD);
569 kobject_unregister(&mk->kobj);
570 kfree(mk);
571 }
572} 570}
573 571
574/* 572/*