From 40cf67c5fcc513406558c01b91129280208e57bf Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 Jul 2006 14:31:12 -0700 Subject: [PATCH 1/9] Driver core: remove class_device_rename No one uses it, and it wasn't exported to modules, so remove it. The only other user of it was the network code, which is now converted to use struct device instead. Signed-off-by: Greg Kroah-Hartman --- drivers/base/class.c | 42 ------------------------------------------ include/linux/device.h | 2 -- 2 files changed, 44 deletions(-) diff --git a/drivers/base/class.c b/drivers/base/class.c index 1417e5cd4c6f..d5968128be2b 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -840,48 +840,6 @@ void class_device_destroy(struct class *cls, dev_t devt) class_device_unregister(class_dev); } -int class_device_rename(struct class_device *class_dev, char *new_name) -{ - int error = 0; - char *old_class_name = NULL, *new_class_name = NULL; - - class_dev = class_device_get(class_dev); - if (!class_dev) - return -EINVAL; - - pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id, - new_name); - -#ifdef CONFIG_SYSFS_DEPRECATED - if (class_dev->dev) - old_class_name = make_class_name(class_dev->class->name, - &class_dev->kobj); -#endif - - strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN); - - error = kobject_rename(&class_dev->kobj, new_name); - -#ifdef CONFIG_SYSFS_DEPRECATED - if (class_dev->dev) { - new_class_name = make_class_name(class_dev->class->name, - &class_dev->kobj); - if (new_class_name) - sysfs_create_link(&class_dev->dev->kobj, - &class_dev->kobj, new_class_name); - if (old_class_name) - sysfs_remove_link(&class_dev->dev->kobj, - old_class_name); - } -#endif - class_device_put(class_dev); - - kfree(old_class_name); - kfree(new_class_name); - - return error; -} - struct class_device * class_device_get(struct class_device *class_dev) { if (class_dev) diff --git a/include/linux/device.h b/include/linux/device.h index d1a3a27c3988..39a3199a826d 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -294,8 +294,6 @@ extern void class_device_initialize(struct class_device *); extern int __must_check class_device_add(struct class_device *); extern void class_device_del(struct class_device *); -extern int class_device_rename(struct class_device *, char *); - extern struct class_device * class_device_get(struct class_device *); extern void class_device_put(struct class_device *); From 63ce18cfe685115ff8d341bae4c9204a79043cf0 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Wed, 21 Feb 2007 12:45:35 -0800 Subject: [PATCH 2/9] driver core: refcounting fix Fix a reference counting bug exposed by commit 725522b5453dd680412f2b6463a988e4fd148757. If driver.mod_name exists, we take a reference in module_add_driver(), and never release it. Undo that reference in module_remove_driver(). Signed-off-by: Mike Galbraith Cc: Kay Sievers Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- kernel/module.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kernel/module.c b/kernel/module.c index 8c25b1a04fa6..1ecf08106381 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2425,6 +2425,12 @@ void module_remove_driver(struct device_driver *drv) kfree(driver_name); } } + /* + * Undo the additional reference we added in module_add_driver() + * via kset_find_obj() + */ + if (drv->mod_name) + kobject_put(&drv->kobj); } EXPORT_SYMBOL(module_remove_driver); #endif From d56c3eae6753f53d3313b926dcdda38c6c9bbe9b Mon Sep 17 00:00:00 2001 From: "Adam J. Richter" Date: Fri, 16 Feb 2007 21:35:25 +0800 Subject: [PATCH 3/9] sysfs: move struct sysfs_dirent to private header struct sysfs_dirent is private to the fs/sysfs/ subtree. It is not even referenced as an opaque structure outside of that subtree. The following patch moves the declaration from include/linux/sysfs.h to fs/sysfs/sysfs.h, making it clearer that nothing else in the kernel dereferences it. I have been running this patch for years. Please integrate and forward upstream if there are no objections. From: "Adam J. Richter" Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/sysfs.h | 11 +++++++++++ include/linux/sysfs.h | 13 +------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index d976b0005549..a77c57e5a6d5 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -1,3 +1,14 @@ +struct sysfs_dirent { + atomic_t s_count; + struct list_head s_sibling; + struct list_head s_children; + void * s_element; + int s_type; + umode_t s_mode; + struct dentry * s_dentry; + struct iattr * s_iattr; + atomic_t s_event; +}; extern struct vfsmount * sysfs_mount; extern struct kmem_cache *sysfs_dir_cachep; diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 192de3afa96b..f07065cba7c1 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -17,6 +17,7 @@ struct kobject; struct module; struct nameidata; +struct dentry; struct attribute { const char * name; @@ -68,18 +69,6 @@ struct sysfs_ops { ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t); }; -struct sysfs_dirent { - atomic_t s_count; - struct list_head s_sibling; - struct list_head s_children; - void * s_element; - int s_type; - umode_t s_mode; - struct dentry * s_dentry; - struct iattr * s_iattr; - atomic_t s_event; -}; - #define SYSFS_ROOT 0x0001 #define SYSFS_DIR 0x0002 #define SYSFS_KOBJ_ATTR 0x0004 From dfe461aef0d621d8472d0af343ae8a60866a7a8a Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Wed, 21 Feb 2007 14:47:20 +0100 Subject: [PATCH 4/9] Driver core: more fallout from class_device changes for pcmcia More fallout from the PCMCIA class_device changes. The first hunk is run-tested on SH-4, the others are converted in the spirit of the original conversion. Signed-off-by: Manuel Lauss Signed-off-by: Greg Kroah-Hartman --- drivers/pcmcia/hd64465_ss.c | 2 +- drivers/pcmcia/m32r_cfc.c | 2 +- drivers/pcmcia/m8xx_pcmcia.c | 2 +- drivers/pcmcia/omap_cf.c | 2 +- drivers/pcmcia/rsrc_mgr.c | 2 +- drivers/pcmcia/vrc4171_card.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c index caca0dc9d30f..f2e810f53c81 100644 --- a/drivers/pcmcia/hd64465_ss.c +++ b/drivers/pcmcia/hd64465_ss.c @@ -907,7 +907,7 @@ static int __init init_hs(void) for (i=0; isocket.owner = THIS_MODULE; - cf->socket.dev.dev = dev; + cf->socket.dev.parent = dev; cf->socket.ops = &omap_cf_ops; cf->socket.resource_ops = &pccard_static_ops; cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index 81dfc2cac2b4..ce2226273aaa 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -232,7 +232,7 @@ static struct resource *iodyn_find_io_region(unsigned long base, int num, unsigned long align, struct pcmcia_socket *s) { struct resource *res = make_resource(0, num, IORESOURCE_IO, - s->dev.class_id); + s->dev.bus_id); struct pcmcia_align_data data; unsigned long min = base; int ret; diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index 206e26c91807..eee2f1cb213c 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c @@ -596,7 +596,7 @@ static int __devinit vrc4171_add_sockets(void) } sprintf(socket->name, "NEC VRC4171 Card Slot %1c", 'A' + slot); - socket->pcmcia_socket.dev.dev = &vrc4171_card_device.dev; + socket->pcmcia_socket.dev.parent = &vrc4171_card_device.dev; socket->pcmcia_socket.ops = &vrc4171_pccard_operations; socket->pcmcia_socket.owner = THIS_MODULE; From 9c372d06ce9ddf65e1393f9ea22a6d6bd5f96b42 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 16 Feb 2007 01:38:29 -0800 Subject: [PATCH 5/9] power management: no valid states w/o pm_ops Change /sys/power/state to not advertise any valid states (except for disk if SOFTWARE_SUSPEND is enabled) when no pm_ops have been set so userspace can easily discover what states should be available. Signed-off-by: Johannes Berg Cc: "Randy.Dunlap" Cc: Rafael J. Wysocki Cc: Pavel Macheck Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- kernel/power/main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/power/main.c b/kernel/power/main.c index e1c413120469..a064dfd8877a 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -167,7 +167,10 @@ static inline int valid_state(suspend_state_t state) if (state == PM_SUSPEND_DISK) return 1; - if (pm_ops && pm_ops->valid && !pm_ops->valid(state)) + /* all other states need lowlevel support and need to be + * valid to the lowlevel implementation, no valid callback + * implies that all are valid. */ + if (!pm_ops || (pm_ops->valid && !pm_ops->valid(state))) return 0; return 1; } From 2a9df4945106d62ed9249a44d666fab93c685f7a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 16 Feb 2007 01:38:30 -0800 Subject: [PATCH 6/9] power management: fix struct layout and docs Because the pm ops in powermac are obviously not using them as intended, I added documentation for it in kernel-doc format. Reordering the fields in struct pm_ops not only makes the output of kernel-doc make more sense but also removes a hole from the structure on 64-bit platforms. Signed-off-by: Johannes Berg Cc: "Randy.Dunlap" Cc: Rafael J. Wysocki Cc: Pavel Macheck Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- include/linux/pm.h | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/include/linux/pm.h b/include/linux/pm.h index 070394e846d0..21db05ac7c0b 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -120,15 +120,48 @@ typedef int __bitwise suspend_disk_method_t; #define PM_DISK_TESTPROC ((__force suspend_disk_method_t) 6) #define PM_DISK_MAX ((__force suspend_disk_method_t) 7) +/** + * struct pm_ops - Callbacks for managing platform dependent suspend states. + * @valid: Callback to determine whether the given state can be entered. + * If %CONFIG_SOFTWARE_SUSPEND is set then %PM_SUSPEND_DISK is + * always valid and never passed to this call. + * If not assigned, all suspend states are advertised as valid + * in /sys/power/state (but can still be rejected by prepare or enter.) + * + * @prepare: Prepare the platform for the given suspend state. Can return a + * negative error code if necessary. + * + * @enter: Enter the given suspend state, must be assigned. Can return a + * negative error code if necessary. + * + * @finish: Called when the system has left the given state and all devices + * are resumed. The return value is ignored. + * + * @pm_disk_mode: Set to the disk method that the user should be able to + * configure for suspend-to-disk. Since %PM_DISK_SHUTDOWN, + * %PM_DISK_REBOOT, %PM_DISK_TEST and %PM_DISK_TESTPROC + * are always allowed, currently only %PM_DISK_PLATFORM + * makes sense. If the user then choses %PM_DISK_PLATFORM, + * the @prepare call will be called before suspending to disk + * (if present), the @enter call should be present and will + * be called after all state has been saved and the machine + * is ready to be shut down/suspended/..., and the @finish + * callback is called after state has been restored. All + * these calls are called with %PM_SUSPEND_DISK as the state. + */ struct pm_ops { - suspend_disk_method_t pm_disk_mode; int (*valid)(suspend_state_t state); int (*prepare)(suspend_state_t state); int (*enter)(suspend_state_t state); int (*finish)(suspend_state_t state); + suspend_disk_method_t pm_disk_mode; }; -extern void pm_set_ops(struct pm_ops *); +/** + * pm_set_ops - set platform dependent power management ops + * @pm_ops: The new power management operations to set. + */ +extern void pm_set_ops(struct pm_ops *pm_ops); extern struct pm_ops *pm_ops; extern int pm_suspend(suspend_state_t state); From 4541ac94d0ea0b00776edd5904ac91dd6d6330f7 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 20 Feb 2007 01:07:49 +0100 Subject: [PATCH 7/9] make kernel/kmod.c:kmod_mk static This patch makes the needlessly global struct kmod_mk static. Signed-off-by: Adrian Bunk Signed-off-by: Greg Kroah-Hartman --- kernel/kmod.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/kmod.c b/kernel/kmod.c index 9f923f8ce6a0..f936108f2963 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -48,7 +48,7 @@ static struct workqueue_struct *khelper_wq; modprobe_path is set via /proc/sys. */ char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe"; -struct module_kobject kmod_mk; +static struct module_kobject kmod_mk; /** * request_module - try to load a kernel module From 82f0cf9b7c42684c29189ddb6d0bc86eb1137fc4 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Wed, 21 Feb 2007 17:44:51 +0000 Subject: [PATCH 8/9] Driver core: fix error by cleanup up symlinks properly When a device fails to register the class symlinks where not cleaned up. This left a symlink in the /sys/class/"device"/ directory that pointed to no where. This caused the sysfs_follow_link Oops I reported earlier. This patch cleanups up the symlink. Please apply. Thank you. Signed-Off: James Simmons Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index d04fd33dcd91..cf2a398aaaa1 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -637,12 +637,41 @@ int device_add(struct device *dev) BUS_NOTIFY_DEL_DEVICE, dev); device_remove_groups(dev); GroupError: - device_remove_attrs(dev); + device_remove_attrs(dev); AttrsError: if (dev->devt_attr) { device_remove_file(dev, dev->devt_attr); kfree(dev->devt_attr); } + + if (dev->class) { + sysfs_remove_link(&dev->kobj, "subsystem"); + /* If this is not a "fake" compatible device, remove the + * symlink from the class to the device. */ + if (dev->kobj.parent != &dev->class->subsys.kset.kobj) + sysfs_remove_link(&dev->class->subsys.kset.kobj, + dev->bus_id); +#ifdef CONFIG_SYSFS_DEPRECATED + if (parent) { + char *class_name = make_class_name(dev->class->name, + &dev->kobj); + if (class_name) + sysfs_remove_link(&dev->parent->kobj, + class_name); + kfree(class_name); + sysfs_remove_link(&dev->kobj, "device"); + } +#endif + + down(&dev->class->sem); + /* notify any interfaces that the device is now gone */ + list_for_each_entry(class_intf, &dev->class->interfaces, node) + if (class_intf->remove_dev) + class_intf->remove_dev(dev, class_intf); + /* remove the device from the class list */ + list_del_init(&dev->node); + up(&dev->class->sem); + } ueventattrError: device_remove_file(dev, &dev->uevent_attr); attrError: From dfff0a0671baf4e69fc676bf8150635407548288 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 23 Feb 2007 14:54:57 -0800 Subject: [PATCH 9/9] Revert "Driver core: let request_module() send a /sys/modules/kmod/-uevent" This reverts commit c353c3fb0700a3c17ea2b0237710a184232ccd7f. It turns out that we end up with a loop trying to load the unix module and calling netfilter to do that. Will redo the patch later to not have this loop. Acked-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- include/linux/kmod.h | 2 - kernel/kmod.c | 120 ------------------------------------------- kernel/module.c | 26 ++++------ kernel/params.c | 1 - 4 files changed, 10 insertions(+), 139 deletions(-) diff --git a/include/linux/kmod.h b/include/linux/kmod.h index cc8e674ae27a..10f505c8431d 100644 --- a/include/linux/kmod.h +++ b/include/linux/kmod.h @@ -28,10 +28,8 @@ #ifdef CONFIG_KMOD /* modprobe exit status on success, -ve on error. Return value * usually useless though. */ -extern void kmod_sysfs_init(void); extern int request_module(const char * name, ...) __attribute__ ((format (printf, 1, 2))); #else -static inline void kmod_sysfs_init(void) {}; static inline int request_module(const char * name, ...) { return -ENOSYS; } #endif diff --git a/kernel/kmod.c b/kernel/kmod.c index f936108f2963..796276141e51 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -36,8 +36,6 @@ #include #include -extern int delete_module(const char *name, unsigned int flags); - extern int max_threads; static struct workqueue_struct *khelper_wq; @@ -48,7 +46,6 @@ static struct workqueue_struct *khelper_wq; modprobe_path is set via /proc/sys. */ char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe"; -static struct module_kobject kmod_mk; /** * request_module - try to load a kernel module @@ -78,11 +75,6 @@ int request_module(const char *fmt, ...) static atomic_t kmod_concurrent = ATOMIC_INIT(0); #define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */ static int kmod_loop_msg; - char modalias[16 + MODULE_NAME_LEN] = "MODALIAS="; - char *uevent_envp[2] = { - modalias, - NULL - }; va_start(args, fmt); ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args); @@ -90,12 +82,6 @@ int request_module(const char *fmt, ...) if (ret >= MODULE_NAME_LEN) return -ENAMETOOLONG; - strcpy(&modalias[strlen("MODALIAS=")], module_name); - kobject_uevent_env(&kmod_mk.kobj, KOBJ_CHANGE, uevent_envp); - - if (modprobe_path[0] == '\0') - goto out; - /* If modprobe needs a service that is in a module, we get a recursive * loop. Limit the number of running kmod threads to max_threads/2 or * MAX_KMOD_CONCURRENT, whichever is the smaller. A cleaner method @@ -122,115 +108,9 @@ int request_module(const char *fmt, ...) ret = call_usermodehelper(modprobe_path, argv, envp, 1); atomic_dec(&kmod_concurrent); -out: return ret; } EXPORT_SYMBOL(request_module); - -static ssize_t store_mod_request(struct module_attribute *mattr, - struct module *mod, - const char *buffer, size_t count) -{ - char name[MODULE_NAME_LEN]; - int ret; - - if (count < 1 || count+1 > MODULE_NAME_LEN) - return -EINVAL; - memcpy(name, buffer, count); - name[count] = '\0'; - if (name[count-1] == '\n') - name[count-1] = '\0'; - - ret = request_module(name); - if (ret < 0) - return ret; - return count; -} - -static struct module_attribute mod_request = { - .attr = { .name = "mod_request", .mode = S_IWUSR, .owner = THIS_MODULE }, - .store = store_mod_request, -}; - -#ifdef CONFIG_MODULE_UNLOAD -static ssize_t store_mod_unload(struct module_attribute *mattr, - struct module *mod, - const char *buffer, size_t count) -{ - char name[MODULE_NAME_LEN]; - int ret; - - if (count < 1 || count+1 > MODULE_NAME_LEN) - return -EINVAL; - memcpy(name, buffer, count); - name[count] = '\0'; - if (name[count-1] == '\n') - name[count-1] = '\0'; - - ret = delete_module(name, O_NONBLOCK); - if (ret < 0) - return ret; - return count; -} - -static struct module_attribute mod_unload = { - .attr = { .name = "mod_unload", .mode = S_IWUSR, .owner = THIS_MODULE }, - .store = store_mod_unload, -}; -#endif - -static ssize_t show_mod_request_helper(struct module_attribute *mattr, - struct module *mod, - char *buffer) -{ - return sprintf(buffer, "%s\n", modprobe_path); -} - -static ssize_t store_mod_request_helper(struct module_attribute *mattr, - struct module *mod, - const char *buffer, size_t count) -{ - if (count < 1 || count+1 > KMOD_PATH_LEN) - return -EINVAL; - memcpy(modprobe_path, buffer, count); - modprobe_path[count] = '\0'; - if (modprobe_path[count-1] == '\n') - modprobe_path[count-1] = '\0'; - return count; -} - -static struct module_attribute mod_request_helper = { - .attr = { - .name = "mod_request_helper", - .mode = S_IWUSR | S_IRUGO, - .owner = THIS_MODULE - }, - .show = show_mod_request_helper, - .store = store_mod_request_helper, -}; - -void __init kmod_sysfs_init(void) -{ - int ret; - - kmod_mk.mod = THIS_MODULE; - kobj_set_kset_s(&kmod_mk, module_subsys); - kobject_set_name(&kmod_mk.kobj, "kmod"); - kobject_init(&kmod_mk.kobj); - ret = kobject_add(&kmod_mk.kobj); - if (ret < 0) - goto out; - - ret = sysfs_create_file(&kmod_mk.kobj, &mod_request_helper.attr); - ret = sysfs_create_file(&kmod_mk.kobj, &mod_request.attr); -#ifdef CONFIG_MODULE_UNLOAD - ret = sysfs_create_file(&kmod_mk.kobj, &mod_unload.attr); -#endif - - kobject_uevent(&kmod_mk.kobj, KOBJ_ADD); -out: - return; -} #endif /* CONFIG_KMOD */ struct subprocess_info { diff --git a/kernel/module.c b/kernel/module.c index 1ecf08106381..f77e893e4620 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -653,11 +653,20 @@ static void wait_for_zero_refcount(struct module *mod) mutex_lock(&module_mutex); } -int delete_module(const char *name, unsigned int flags) +asmlinkage long +sys_delete_module(const char __user *name_user, unsigned int flags) { struct module *mod; + char name[MODULE_NAME_LEN]; int ret, forced = 0; + if (!capable(CAP_SYS_MODULE)) + return -EPERM; + + if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0) + return -EFAULT; + name[MODULE_NAME_LEN-1] = '\0'; + if (mutex_lock_interruptible(&module_mutex) != 0) return -EINTR; @@ -718,21 +727,6 @@ int delete_module(const char *name, unsigned int flags) return ret; } -asmlinkage long -sys_delete_module(const char __user *name_user, unsigned int flags) -{ - char name[MODULE_NAME_LEN]; - - if (!capable(CAP_SYS_MODULE)) - return -EPERM; - - if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0) - return -EFAULT; - name[MODULE_NAME_LEN-1] = '\0'; - - return delete_module(name, flags); -} - static void print_unload_info(struct seq_file *m, struct module *mod) { struct module_use *use; diff --git a/kernel/params.c b/kernel/params.c index 7a751570b56d..e265b13195b1 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -707,7 +707,6 @@ static int __init param_sysfs_init(void) } param_sysfs_builtin(); - kmod_sysfs_init(); return 0; }