aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/Makefile1
-rw-r--r--drivers/base/base.h9
-rw-r--r--drivers/base/module.c94
-rw-r--r--include/linux/module.h15
-rw-r--r--kernel/module.c87
5 files changed, 104 insertions, 102 deletions
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index b39ea3f59c9b..ff2696823f8d 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_FW_LOADER) += firmware_class.o
11obj-$(CONFIG_NUMA) += node.o 11obj-$(CONFIG_NUMA) += node.o
12obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o 12obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o
13obj-$(CONFIG_SMP) += topology.o 13obj-$(CONFIG_SMP) += topology.o
14obj-$(CONFIG_MODULES) += module.o
14obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o 15obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
15 16
16ifeq ($(CONFIG_DEBUG_DRIVER),y) 17ifeq ($(CONFIG_DEBUG_DRIVER),y)
diff --git a/drivers/base/base.h b/drivers/base/base.h
index ca6d273064f8..05472360f6a2 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -73,3 +73,12 @@ extern char *make_class_name(const char *name, struct kobject *kobj);
73extern int devres_release_all(struct device *dev); 73extern int devres_release_all(struct device *dev);
74 74
75extern struct kset *devices_kset; 75extern struct kset *devices_kset;
76
77#ifdef CONFIG_MODULES
78extern void module_add_driver(struct module *mod, struct device_driver *drv);
79extern void module_remove_driver(struct device_driver *drv);
80#else
81static inline void module_add_driver(struct module *mod,
82 struct device_driver *drv) { }
83static inline void module_remove_driver(struct device_driver *drv) { }
84#endif
diff --git a/drivers/base/module.c b/drivers/base/module.c
new file mode 100644
index 000000000000..cad07be5de1a
--- /dev/null
+++ b/drivers/base/module.c
@@ -0,0 +1,94 @@
1/*
2 * module.c - module sysfs fun for drivers
3 *
4 * This file is released under the GPLv2
5 *
6 */
7#include <linux/device.h>
8#include <linux/module.h>
9#include <linux/errno.h>
10#include <linux/string.h>
11#include "base.h"
12
13static char *make_driver_name(struct device_driver *drv)
14{
15 char *driver_name;
16
17 driver_name = kmalloc(strlen(drv->name) + strlen(drv->bus->name) + 2,
18 GFP_KERNEL);
19 if (!driver_name)
20 return NULL;
21
22 sprintf(driver_name, "%s:%s", drv->bus->name, drv->name);
23 return driver_name;
24}
25
26static void module_create_drivers_dir(struct module_kobject *mk)
27{
28 if (!mk || mk->drivers_dir)
29 return;
30
31 mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
32}
33
34void module_add_driver(struct module *mod, struct device_driver *drv)
35{
36 char *driver_name;
37 int no_warn;
38 struct module_kobject *mk = NULL;
39
40 if (!drv)
41 return;
42
43 if (mod)
44 mk = &mod->mkobj;
45 else if (drv->mod_name) {
46 struct kobject *mkobj;
47
48 /* Lookup built-in module entry in /sys/modules */
49 mkobj = kset_find_obj(module_kset, drv->mod_name);
50 if (mkobj) {
51 mk = container_of(mkobj, struct module_kobject, kobj);
52 /* remember our module structure */
53 drv->mkobj = mk;
54 /* kset_find_obj took a reference */
55 kobject_put(mkobj);
56 }
57 }
58
59 if (!mk)
60 return;
61
62 /* Don't check return codes; these calls are idempotent */
63 no_warn = sysfs_create_link(&drv->kobj, &mk->kobj, "module");
64 driver_name = make_driver_name(drv);
65 if (driver_name) {
66 module_create_drivers_dir(mk);
67 no_warn = sysfs_create_link(mk->drivers_dir, &drv->kobj,
68 driver_name);
69 kfree(driver_name);
70 }
71}
72
73void module_remove_driver(struct device_driver *drv)
74{
75 struct module_kobject *mk = NULL;
76 char *driver_name;
77
78 if (!drv)
79 return;
80
81 sysfs_remove_link(&drv->kobj, "module");
82
83 if (drv->owner)
84 mk = &drv->owner->mkobj;
85 else if (drv->mkobj)
86 mk = drv->mkobj;
87 if (mk && mk->drivers_dir) {
88 driver_name = make_driver_name(drv);
89 if (driver_name) {
90 sysfs_remove_link(mk->drivers_dir, driver_name);
91 kfree(driver_name);
92 }
93 }
94}
diff --git a/include/linux/module.h b/include/linux/module.h
index fbe930b9b69c..c97bdb7eb957 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -609,21 +609,6 @@ static inline void module_remove_modinfo_attrs(struct module *mod)
609 609
610#endif /* CONFIG_SYSFS */ 610#endif /* CONFIG_SYSFS */
611 611
612#if defined(CONFIG_SYSFS) && defined(CONFIG_MODULES)
613
614void module_add_driver(struct module *mod, struct device_driver *drv);
615void module_remove_driver(struct device_driver *drv);
616
617#else /* not both CONFIG_SYSFS && CONFIG_MODULES */
618
619static inline void module_add_driver(struct module *mod, struct device_driver *drv)
620{ }
621
622static inline void module_remove_driver(struct device_driver *drv)
623{ }
624
625#endif
626
627#define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x) 612#define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x)
628 613
629/* BELOW HERE ALL THESE ARE OBSOLETE AND WILL VANISH */ 614/* BELOW HERE ALL THESE ARE OBSOLETE AND WILL VANISH */
diff --git a/kernel/module.c b/kernel/module.c
index d03fcd9d652c..dc4d3f5ce820 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2501,93 +2501,6 @@ void print_modules(void)
2501 printk("\n"); 2501 printk("\n");
2502} 2502}
2503 2503
2504#ifdef CONFIG_SYSFS
2505static char *make_driver_name(struct device_driver *drv)
2506{
2507 char *driver_name;
2508
2509 driver_name = kmalloc(strlen(drv->name) + strlen(drv->bus->name) + 2,
2510 GFP_KERNEL);
2511 if (!driver_name)
2512 return NULL;
2513
2514 sprintf(driver_name, "%s:%s", drv->bus->name, drv->name);
2515 return driver_name;
2516}
2517
2518static void module_create_drivers_dir(struct module_kobject *mk)
2519{
2520 if (!mk || mk->drivers_dir)
2521 return;
2522
2523 mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
2524}
2525
2526void module_add_driver(struct module *mod, struct device_driver *drv)
2527{
2528 char *driver_name;
2529 int no_warn;
2530 struct module_kobject *mk = NULL;
2531
2532 if (!drv)
2533 return;
2534
2535 if (mod)
2536 mk = &mod->mkobj;
2537 else if (drv->mod_name) {
2538 struct kobject *mkobj;
2539
2540 /* Lookup built-in module entry in /sys/modules */
2541 mkobj = kset_find_obj(module_kset, drv->mod_name);
2542 if (mkobj) {
2543 mk = container_of(mkobj, struct module_kobject, kobj);
2544 /* remember our module structure */
2545 drv->mkobj = mk;
2546 /* kset_find_obj took a reference */
2547 kobject_put(mkobj);
2548 }
2549 }
2550
2551 if (!mk)
2552 return;
2553
2554 /* Don't check return codes; these calls are idempotent */
2555 no_warn = sysfs_create_link(&drv->kobj, &mk->kobj, "module");
2556 driver_name = make_driver_name(drv);
2557 if (driver_name) {
2558 module_create_drivers_dir(mk);
2559 no_warn = sysfs_create_link(mk->drivers_dir, &drv->kobj,
2560 driver_name);
2561 kfree(driver_name);
2562 }
2563}
2564EXPORT_SYMBOL(module_add_driver);
2565
2566void module_remove_driver(struct device_driver *drv)
2567{
2568 struct module_kobject *mk = NULL;
2569 char *driver_name;
2570
2571 if (!drv)
2572 return;
2573
2574 sysfs_remove_link(&drv->kobj, "module");
2575
2576 if (drv->owner)
2577 mk = &drv->owner->mkobj;
2578 else if (drv->mkobj)
2579 mk = drv->mkobj;
2580 if (mk && mk->drivers_dir) {
2581 driver_name = make_driver_name(drv);
2582 if (driver_name) {
2583 sysfs_remove_link(mk->drivers_dir, driver_name);
2584 kfree(driver_name);
2585 }
2586 }
2587}
2588EXPORT_SYMBOL(module_remove_driver);
2589#endif
2590
2591#ifdef CONFIG_MODVERSIONS 2504#ifdef CONFIG_MODVERSIONS
2592/* Generate the signature for struct module here, too, for modversions. */ 2505/* Generate the signature for struct module here, too, for modversions. */
2593void struct_module(struct module *mod) { return; } 2506void struct_module(struct module *mod) { return; }