summaryrefslogtreecommitdiffstats
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
obj-$(CONFIG_NUMA) += node.o
obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o
obj-$(CONFIG_SMP) += topology.o
+obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
ifeq ($(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);
extern int devres_release_all(struct device *dev);
extern struct kset *devices_kset;
+
+#ifdef CONFIG_MODULES
+extern void module_add_driver(struct module *mod, struct device_driver *drv);
+extern void module_remove_driver(struct device_driver *drv);
+#else
+static inline void module_add_driver(struct module *mod,
+ struct device_driver *drv) { }
+static inline void module_remove_driver(struct device_driver *drv) { }
+#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 @@
+/*
+ * module.c - module sysfs fun for drivers
+ *
+ * This file is released under the GPLv2
+ *
+ */
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include "base.h"
+
+static char *make_driver_name(struct device_driver *drv)
+{
+ char *driver_name;
+
+ driver_name = kmalloc(strlen(drv->name) + strlen(drv->bus->name) + 2,
+ GFP_KERNEL);
+ if (!driver_name)
+ return NULL;
+
+ sprintf(driver_name, "%s:%s", drv->bus->name, drv->name);
+ return driver_name;
+}
+
+static void module_create_drivers_dir(struct module_kobject *mk)
+{
+ if (!mk || mk->drivers_dir)
+ return;
+
+ mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
+}
+
+void module_add_driver(struct module *mod, struct device_driver *drv)
+{
+ char *driver_name;
+ int no_warn;
+ struct module_kobject *mk = NULL;
+
+ if (!drv)
+ return;
+
+ if (mod)
+ mk = &mod->mkobj;
+ else if (drv->mod_name) {
+ struct kobject *mkobj;
+
+ /* Lookup built-in module entry in /sys/modules */
+ mkobj = kset_find_obj(module_kset, drv->mod_name);
+ if (mkobj) {
+ mk = container_of(mkobj, struct module_kobject, kobj);
+ /* remember our module structure */
+ drv->mkobj = mk;
+ /* kset_find_obj took a reference */
+ kobject_put(mkobj);
+ }
+ }
+
+ if (!mk)
+ return;
+
+ /* Don't check return codes; these calls are idempotent */
+ no_warn = sysfs_create_link(&drv->kobj, &mk->kobj, "module");
+ driver_name = make_driver_name(drv);
+ if (driver_name) {
+ module_create_drivers_dir(mk);
+ no_warn = sysfs_create_link(mk->drivers_dir, &drv->kobj,
+ driver_name);
+ kfree(driver_name);
+ }
+}
+
+void module_remove_driver(struct device_driver *drv)
+{
+ struct module_kobject *mk = NULL;
+ char *driver_name;
+
+ if (!drv)
+ return;
+
+ sysfs_remove_link(&drv->kobj, "module");
+
+ if (drv->owner)
+ mk = &drv->owner->mkobj;
+ else if (drv->mkobj)
+ mk = drv->mkobj;
+ if (mk && mk->drivers_dir) {
+ driver_name = make_driver_name(drv);
+ if (driver_name) {
+ sysfs_remove_link(mk->drivers_dir, driver_name);
+ kfree(driver_name);
+ }
+ }
+}
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)
#endif /* CONFIG_SYSFS */
-#if defined(CONFIG_SYSFS) && defined(CONFIG_MODULES)
-
-void module_add_driver(struct module *mod, struct device_driver *drv);
-void module_remove_driver(struct device_driver *drv);
-
-#else /* not both CONFIG_SYSFS && CONFIG_MODULES */
-
-static inline void module_add_driver(struct module *mod, struct device_driver *drv)
-{ }
-
-static inline void module_remove_driver(struct device_driver *drv)
-{ }
-
-#endif
-
#define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x)
/* 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)
printk("\n");
}
-#ifdef CONFIG_SYSFS
-static char *make_driver_name(struct device_driver *drv)
-{
- char *driver_name;
-
- driver_name = kmalloc(strlen(drv->name) + strlen(drv->bus->name) + 2,
- GFP_KERNEL);
- if (!driver_name)
- return NULL;
-
- sprintf(driver_name, "%s:%s", drv->bus->name, drv->name);
- return driver_name;
-}
-
-static void module_create_drivers_dir(struct module_kobject *mk)
-{
- if (!mk || mk->drivers_dir)
- return;
-
- mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
-}
-
-void module_add_driver(struct module *mod, struct device_driver *drv)
-{
- char *driver_name;
- int no_warn;
- struct module_kobject *mk = NULL;
-
- if (!drv)
- return;
-
- if (mod)
- mk = &mod->mkobj;
- else if (drv->mod_name) {
- struct kobject *mkobj;
-
- /* Lookup built-in module entry in /sys/modules */
- mkobj = kset_find_obj(module_kset, drv->mod_name);
- if (mkobj) {
- mk = container_of(mkobj, struct module_kobject, kobj);
- /* remember our module structure */
- drv->mkobj = mk;
- /* kset_find_obj took a reference */
- kobject_put(mkobj);
- }
- }
-
- if (!mk)
- return;
-
- /* Don't check return codes; these calls are idempotent */
- no_warn = sysfs_create_link(&drv->kobj, &mk->kobj, "module");
- driver_name = make_driver_name(drv);
- if (driver_name) {
- module_create_drivers_dir(mk);
- no_warn = sysfs_create_link(mk->drivers_dir, &drv->kobj,
- driver_name);
- kfree(driver_name);
- }
-}
-EXPORT_SYMBOL(module_add_driver);
-
-void module_remove_driver(struct device_driver *drv)
-{
- struct module_kobject *mk = NULL;
- char *driver_name;
-
- if (!drv)
- return;
-
- sysfs_remove_link(&drv->kobj, "module");
-
- if (drv->owner)
- mk = &drv->owner->mkobj;
- else if (drv->mkobj)
- mk = drv->mkobj;
- if (mk && mk->drivers_dir) {
- driver_name = make_driver_name(drv);
- if (driver_name) {
- sysfs_remove_link(mk->drivers_dir, driver_name);
- kfree(driver_name);
- }
- }
-}
-EXPORT_SYMBOL(module_remove_driver);
-#endif
-
#ifdef CONFIG_MODVERSIONS
/* Generate the signature for struct module here, too, for modversions. */
void struct_module(struct module *mod) { return; }