aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2007-11-28 15:23:18 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2008-01-24 23:40:35 -0500
commitc63469a3985a9771c18a916b8d42845d044ea0b1 (patch)
tree7d54c8741aec9d71864203ce430d289d40c4c975 /drivers/base
parentcbe9c595f1de2e2a98403be2c14bfbc2486e84c4 (diff)
Driver core: move the driver specific module code into the driver core
The module driver specific code should belong in the driver core, not in the kernel/ directory. So move this code. This is done in preparation for some struct device_driver rework that should be confined to the driver core code only. This also lets us keep from exporting these functions, as no external code should ever be calling it. Thanks to Andrew Morton for the !CONFIG_MODULES fix. Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/Makefile1
-rw-r--r--drivers/base/base.h9
-rw-r--r--drivers/base/module.c94
3 files changed, 104 insertions, 0 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}