diff options
| -rw-r--r-- | drivers/base/Makefile | 1 | ||||
| -rw-r--r-- | drivers/base/base.h | 9 | ||||
| -rw-r--r-- | drivers/base/module.c | 94 | ||||
| -rw-r--r-- | include/linux/module.h | 15 | ||||
| -rw-r--r-- | kernel/module.c | 87 | 
5 files changed, 104 insertions, 102 deletions
diff --git a/drivers/base/Makefile b/drivers/base/Makefile index b39ea3f59c9..ff2696823f8 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 ca6d273064f..05472360f6a 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 00000000000..cad07be5de1 --- /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 fbe930b9b69..c97bdb7eb95 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 d03fcd9d652..dc4d3f5ce82 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; }  |