From ecdf6ceb8cf4756bd4214bf9755755752b6015f5 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 29 Dec 2009 20:11:20 -0800 Subject: Driver core: add platform_create_bundle() helper Many legacy-style module create singleton platform devices themselves, along with corresponding platform driver. Instead of replicating error handling code in all such drivers, provide a helper that allocates and registers a single platform device and a driver and binds them together. Signed-off-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- include/linux/platform_device.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 71ff887ca44e..25e64b43e644 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -77,6 +77,11 @@ extern int platform_driver_probe(struct platform_driver *driver, #define platform_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev) #define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data)) +extern struct platform_device *platform_create_bundle(struct platform_driver *driver, + int (*probe)(struct platform_device *), + struct resource *res, unsigned int n_res, + const void *data, size_t size); + /* early platform driver interface */ struct early_platform_driver { const char *class_str; -- cgit v1.2.3 From 3d03ba4d1dd2246adff5a9ff1194a539b3bc05a7 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Fri, 1 Jan 2010 15:43:28 +0800 Subject: driver core: make platform_device_id table const The platform ID table is normally const, force that by adding the attribute. Signed-off-by: Eric Miao Signed-off-by: Greg Kroah-Hartman --- include/linux/platform_device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 25e64b43e644..2c2d035bfb92 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -21,7 +21,7 @@ struct platform_device { u32 num_resources; struct resource * resource; - struct platform_device_id *id_entry; + const struct platform_device_id *id_entry; /* arch specific additions */ struct pdev_archdata archdata; -- cgit v1.2.3 From c9be0a36f9bf392a7984473124a67a12964df11f Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 5 Jan 2010 12:47:58 +0100 Subject: sysdev: Pass attribute in sysdev_class attributes show/store Passing the attribute to the low level IO functions allows all kinds of cleanups, by sharing low level IO code without requiring an own function for every piece of data. Also drivers can extend the attributes with own data fields and use that in the low level function. Similar to sysdev_attributes and normal attributes. This is a tree-wide sweep, converting everything in one go. No functional changes in this patch other than passing the new argument everywhere. Tested on x86, the non x86 parts are uncompiled. Signed-off-by: Andi Kleen Signed-off-by: Greg Kroah-Hartman --- arch/mips/txx9/generic/7segled.c | 5 +++- arch/s390/kernel/smp.c | 8 +++++-- arch/s390/kernel/time.c | 49 ++++++++++++++++++++++++++++++---------- drivers/base/cpu.c | 9 +++++--- drivers/base/node.c | 17 ++++++++++---- drivers/base/sys.c | 4 ++-- drivers/cpuidle/sysfs.c | 4 ++++ include/linux/sysdev.h | 6 +++-- kernel/perf_event.c | 13 ++++++++--- kernel/sched.c | 4 ++++ 10 files changed, 89 insertions(+), 30 deletions(-) (limited to 'include') diff --git a/arch/mips/txx9/generic/7segled.c b/arch/mips/txx9/generic/7segled.c index 727ab21b6618..7f8416f86222 100644 --- a/arch/mips/txx9/generic/7segled.c +++ b/arch/mips/txx9/generic/7segled.c @@ -58,13 +58,16 @@ static ssize_t raw_store(struct sys_device *dev, static SYSDEV_ATTR(ascii, 0200, NULL, ascii_store); static SYSDEV_ATTR(raw, 0200, NULL, raw_store); -static ssize_t map_seg7_show(struct sysdev_class *class, char *buf) +static ssize_t map_seg7_show(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + char *buf) { memcpy(buf, &txx9_seg7map, sizeof(txx9_seg7map)); return sizeof(txx9_seg7map); } static ssize_t map_seg7_store(struct sysdev_class *class, + struct sysdev_class_attribute *attr, const char *buf, size_t size) { if (size != sizeof(txx9_seg7map)) diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 8b10127c00ad..e2121099f03b 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -1020,7 +1020,9 @@ out: return rc; } -static ssize_t __ref rescan_store(struct sysdev_class *class, const char *buf, +static ssize_t __ref rescan_store(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + const char *buf, size_t count) { int rc; @@ -1041,7 +1043,9 @@ static ssize_t dispatching_show(struct sysdev_class *class, char *buf) return count; } -static ssize_t dispatching_store(struct sysdev_class *dev, const char *buf, +static ssize_t dispatching_store(struct sysdev_class *dev, + struct sysdev_class_attribute *attr, + const char *buf, size_t count) { int val, rc; diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index a8f93f1705ad..75894c281710 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -1116,14 +1116,18 @@ static struct sys_device etr_port1_dev = { /* * ETR class attributes */ -static ssize_t etr_stepping_port_show(struct sysdev_class *class, char *buf) +static ssize_t etr_stepping_port_show(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + char *buf) { return sprintf(buf, "%i\n", etr_port0.esw.p); } static SYSDEV_CLASS_ATTR(stepping_port, 0400, etr_stepping_port_show, NULL); -static ssize_t etr_stepping_mode_show(struct sysdev_class *class, char *buf) +static ssize_t etr_stepping_mode_show(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + char *buf) { char *mode_str; @@ -1584,7 +1588,9 @@ static struct sysdev_class stp_sysclass = { .name = "stp", }; -static ssize_t stp_ctn_id_show(struct sysdev_class *class, char *buf) +static ssize_t stp_ctn_id_show(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + char *buf) { if (!stp_online) return -ENODATA; @@ -1594,7 +1600,9 @@ static ssize_t stp_ctn_id_show(struct sysdev_class *class, char *buf) static SYSDEV_CLASS_ATTR(ctn_id, 0400, stp_ctn_id_show, NULL); -static ssize_t stp_ctn_type_show(struct sysdev_class *class, char *buf) +static ssize_t stp_ctn_type_show(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + char *buf) { if (!stp_online) return -ENODATA; @@ -1603,7 +1611,9 @@ static ssize_t stp_ctn_type_show(struct sysdev_class *class, char *buf) static SYSDEV_CLASS_ATTR(ctn_type, 0400, stp_ctn_type_show, NULL); -static ssize_t stp_dst_offset_show(struct sysdev_class *class, char *buf) +static ssize_t stp_dst_offset_show(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + char *buf) { if (!stp_online || !(stp_info.vbits & 0x2000)) return -ENODATA; @@ -1612,7 +1622,9 @@ static ssize_t stp_dst_offset_show(struct sysdev_class *class, char *buf) static SYSDEV_CLASS_ATTR(dst_offset, 0400, stp_dst_offset_show, NULL); -static ssize_t stp_leap_seconds_show(struct sysdev_class *class, char *buf) +static ssize_t stp_leap_seconds_show(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + char *buf) { if (!stp_online || !(stp_info.vbits & 0x8000)) return -ENODATA; @@ -1621,7 +1633,9 @@ static ssize_t stp_leap_seconds_show(struct sysdev_class *class, char *buf) static SYSDEV_CLASS_ATTR(leap_seconds, 0400, stp_leap_seconds_show, NULL); -static ssize_t stp_stratum_show(struct sysdev_class *class, char *buf) +static ssize_t stp_stratum_show(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + char *buf) { if (!stp_online) return -ENODATA; @@ -1630,7 +1644,9 @@ static ssize_t stp_stratum_show(struct sysdev_class *class, char *buf) static SYSDEV_CLASS_ATTR(stratum, 0400, stp_stratum_show, NULL); -static ssize_t stp_time_offset_show(struct sysdev_class *class, char *buf) +static ssize_t stp_time_offset_show(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + char *buf) { if (!stp_online || !(stp_info.vbits & 0x0800)) return -ENODATA; @@ -1639,7 +1655,9 @@ static ssize_t stp_time_offset_show(struct sysdev_class *class, char *buf) static SYSDEV_CLASS_ATTR(time_offset, 0400, stp_time_offset_show, NULL); -static ssize_t stp_time_zone_offset_show(struct sysdev_class *class, char *buf) +static ssize_t stp_time_zone_offset_show(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + char *buf) { if (!stp_online || !(stp_info.vbits & 0x4000)) return -ENODATA; @@ -1649,7 +1667,9 @@ static ssize_t stp_time_zone_offset_show(struct sysdev_class *class, char *buf) static SYSDEV_CLASS_ATTR(time_zone_offset, 0400, stp_time_zone_offset_show, NULL); -static ssize_t stp_timing_mode_show(struct sysdev_class *class, char *buf) +static ssize_t stp_timing_mode_show(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + char *buf) { if (!stp_online) return -ENODATA; @@ -1658,7 +1678,9 @@ static ssize_t stp_timing_mode_show(struct sysdev_class *class, char *buf) static SYSDEV_CLASS_ATTR(timing_mode, 0400, stp_timing_mode_show, NULL); -static ssize_t stp_timing_state_show(struct sysdev_class *class, char *buf) +static ssize_t stp_timing_state_show(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + char *buf) { if (!stp_online) return -ENODATA; @@ -1667,12 +1689,15 @@ static ssize_t stp_timing_state_show(struct sysdev_class *class, char *buf) static SYSDEV_CLASS_ATTR(timing_state, 0400, stp_timing_state_show, NULL); -static ssize_t stp_online_show(struct sysdev_class *class, char *buf) +static ssize_t stp_online_show(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + char *buf) { return sprintf(buf, "%i\n", stp_online); } static ssize_t stp_online_store(struct sysdev_class *class, + struct sysdev_class_attribute *attr, const char *buf, size_t count) { unsigned int value; diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 958bd1540c30..fd1b2f9b7b8f 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -151,7 +151,8 @@ static ssize_t print_cpus_map(char *buf, const struct cpumask *map) } #define print_cpus_func(type) \ -static ssize_t print_cpus_##type(struct sysdev_class *class, char *buf) \ +static ssize_t print_cpus_##type(struct sysdev_class *class, \ + struct sysdev_class_attribute *attr, char *buf) \ { \ return print_cpus_map(buf, cpu_##type##_mask); \ } \ @@ -165,7 +166,8 @@ print_cpus_func(present); /* * Print values for NR_CPUS and offlined cpus */ -static ssize_t print_cpus_kernel_max(struct sysdev_class *class, char *buf) +static ssize_t print_cpus_kernel_max(struct sysdev_class *class, + struct sysdev_class_attribute *attr, char *buf) { int n = snprintf(buf, PAGE_SIZE-2, "%d\n", NR_CPUS - 1); return n; @@ -175,7 +177,8 @@ static SYSDEV_CLASS_ATTR(kernel_max, 0444, print_cpus_kernel_max, NULL); /* arch-optional setting to enable display of offline cpus >= nr_cpu_ids */ unsigned int total_cpus; -static ssize_t print_cpus_offline(struct sysdev_class *class, char *buf) +static ssize_t print_cpus_offline(struct sysdev_class *class, + struct sysdev_class_attribute *attr, char *buf) { int n = 0, len = PAGE_SIZE-2; cpumask_var_t offline; diff --git a/drivers/base/node.c b/drivers/base/node.c index 70122791683d..85c9d30d7004 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -544,23 +544,29 @@ static ssize_t print_nodes_state(enum node_states state, char *buf) return n; } -static ssize_t print_nodes_possible(struct sysdev_class *class, char *buf) +static ssize_t print_nodes_possible(struct sysdev_class *class, + struct sysdev_class_attribute *attr, char *buf) { return print_nodes_state(N_POSSIBLE, buf); } -static ssize_t print_nodes_online(struct sysdev_class *class, char *buf) +static ssize_t print_nodes_online(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + char *buf) { return print_nodes_state(N_ONLINE, buf); } static ssize_t print_nodes_has_normal_memory(struct sysdev_class *class, - char *buf) + struct sysdev_class_attribute *attr, + char *buf) { return print_nodes_state(N_NORMAL_MEMORY, buf); } -static ssize_t print_nodes_has_cpu(struct sysdev_class *class, char *buf) +static ssize_t print_nodes_has_cpu(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + char *buf) { return print_nodes_state(N_CPU, buf); } @@ -573,7 +579,8 @@ static SYSDEV_CLASS_ATTR(has_cpu, 0444, print_nodes_has_cpu, NULL); #ifdef CONFIG_HIGHMEM static ssize_t print_nodes_has_high_memory(struct sysdev_class *class, - char *buf) + struct sysdev_class_attribute *attr, + char *buf) { return print_nodes_state(N_HIGH_MEMORY, buf); } diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 0d903909af7e..a38445c0f8c5 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -89,7 +89,7 @@ static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr, struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); if (class_attr->show) - return class_attr->show(class, buffer); + return class_attr->show(class, class_attr, buffer); return -EIO; } @@ -100,7 +100,7 @@ static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr, struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); if (class_attr->store) - return class_attr->store(class, buffer, count); + return class_attr->store(class, class_attr, buffer, count); return -EIO; } diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 97b003839fb6..c9cefacabf37 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c @@ -22,6 +22,7 @@ static int __init cpuidle_sysfs_setup(char *unused) __setup("cpuidle_sysfs_switch", cpuidle_sysfs_setup); static ssize_t show_available_governors(struct sysdev_class *class, + struct sysdev_class_attribute *attr, char *buf) { ssize_t i = 0; @@ -41,6 +42,7 @@ out: } static ssize_t show_current_driver(struct sysdev_class *class, + struct sysdev_class_attribute *attr, char *buf) { ssize_t ret; @@ -56,6 +58,7 @@ static ssize_t show_current_driver(struct sysdev_class *class, } static ssize_t show_current_governor(struct sysdev_class *class, + struct sysdev_class_attribute *attr, char *buf) { ssize_t ret; @@ -71,6 +74,7 @@ static ssize_t show_current_governor(struct sysdev_class *class, } static ssize_t store_current_governor(struct sysdev_class *class, + struct sysdev_class_attribute *attr, const char *buf, size_t count) { char gov_name[CPUIDLE_NAME_LEN]; diff --git a/include/linux/sysdev.h b/include/linux/sysdev.h index f395bb3fa2f2..c2458fa8376c 100644 --- a/include/linux/sysdev.h +++ b/include/linux/sysdev.h @@ -41,8 +41,10 @@ struct sysdev_class { struct sysdev_class_attribute { struct attribute attr; - ssize_t (*show)(struct sysdev_class *, char *); - ssize_t (*store)(struct sysdev_class *, const char *, size_t); + ssize_t (*show)(struct sysdev_class *, struct sysdev_class_attribute *, + char *); + ssize_t (*store)(struct sysdev_class *, struct sysdev_class_attribute *, + const char *, size_t); }; #define _SYSDEV_CLASS_ATTR(_name,_mode,_show,_store) \ diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 8e352c756ba7..f40560b86544 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -5481,13 +5481,16 @@ void __init perf_event_init(void) register_cpu_notifier(&perf_cpu_nb); } -static ssize_t perf_show_reserve_percpu(struct sysdev_class *class, char *buf) +static ssize_t perf_show_reserve_percpu(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + char *buf) { return sprintf(buf, "%d\n", perf_reserved_percpu); } static ssize_t perf_set_reserve_percpu(struct sysdev_class *class, + struct sysdev_class_attribute *attr, const char *buf, size_t count) { @@ -5516,13 +5519,17 @@ perf_set_reserve_percpu(struct sysdev_class *class, return count; } -static ssize_t perf_show_overcommit(struct sysdev_class *class, char *buf) +static ssize_t perf_show_overcommit(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + char *buf) { return sprintf(buf, "%d\n", perf_overcommit); } static ssize_t -perf_set_overcommit(struct sysdev_class *class, const char *buf, size_t count) +perf_set_overcommit(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + const char *buf, size_t count) { unsigned long val; int err; diff --git a/kernel/sched.c b/kernel/sched.c index b47ceeec1a91..150b6988de49 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -7406,11 +7406,13 @@ static ssize_t sched_power_savings_store(const char *buf, size_t count, int smt) #ifdef CONFIG_SCHED_MC static ssize_t sched_mc_power_savings_show(struct sysdev_class *class, + struct sysdev_class_attribute *attr, char *page) { return sprintf(page, "%u\n", sched_mc_power_savings); } static ssize_t sched_mc_power_savings_store(struct sysdev_class *class, + struct sysdev_class_attribute *attr, const char *buf, size_t count) { return sched_power_savings_store(buf, count, 0); @@ -7422,11 +7424,13 @@ static SYSDEV_CLASS_ATTR(sched_mc_power_savings, 0644, #ifdef CONFIG_SCHED_SMT static ssize_t sched_smt_power_savings_show(struct sysdev_class *dev, + struct sysdev_class_attribute *attr, char *page) { return sprintf(page, "%u\n", sched_smt_power_savings); } static ssize_t sched_smt_power_savings_store(struct sysdev_class *dev, + struct sysdev_class_attribute *attr, const char *buf, size_t count) { return sched_power_savings_store(buf, count, 1); -- cgit v1.2.3 From 1c205ae18db53ff72985dd79f3baaf2dbaba6db7 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 5 Jan 2010 12:48:01 +0100 Subject: sysfs: Add sysfs_add/remove_files utility functions Adding/Removing a whole array of attributes is very common. Add a standard utility function to do this with a simple function call, instead of requiring drivers to open code this. Signed-off-by: Andi Kleen Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/file.c | 20 ++++++++++++++++++++ include/linux/sysfs.h | 14 ++++++++++++++ 2 files changed, 34 insertions(+) (limited to 'include') diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index dc30d9e31683..50b725bcc3f3 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -542,6 +542,18 @@ int sysfs_create_file(struct kobject * kobj, const struct attribute * attr) } +int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr) +{ + int err = 0; + int i; + + for (i = 0; ptr[i] && !err; i++) + err = sysfs_create_file(kobj, ptr[i]); + if (err) + while (--i >= 0) + sysfs_remove_file(kobj, ptr[i]); + return err; +} /** * sysfs_add_file_to_group - add an attribute file to a pre-existing group. @@ -614,6 +626,12 @@ void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr) sysfs_hash_and_remove(kobj->sd, attr->name); } +void sysfs_remove_files(struct kobject * kobj, const struct attribute **ptr) +{ + int i; + for (i = 0; ptr[i]; i++) + sysfs_remove_file(kobj, ptr[i]); +} /** * sysfs_remove_file_from_group - remove an attribute file from a group. @@ -732,3 +750,5 @@ EXPORT_SYMBOL_GPL(sysfs_schedule_callback); EXPORT_SYMBOL_GPL(sysfs_create_file); EXPORT_SYMBOL_GPL(sysfs_remove_file); +EXPORT_SYMBOL_GPL(sysfs_remove_files); +EXPORT_SYMBOL_GPL(sysfs_create_files); diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index cfa83083a2d4..3e8526582146 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -94,9 +94,12 @@ int __must_check sysfs_move_dir(struct kobject *kobj, int __must_check sysfs_create_file(struct kobject *kobj, const struct attribute *attr); +int __must_check sysfs_create_files(struct kobject *kobj, + const struct attribute **attr); int __must_check sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode); void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr); +void sysfs_remove_files(struct kobject *kobj, const struct attribute **attr); int __must_check sysfs_create_bin_file(struct kobject *kobj, const struct bin_attribute *attr); @@ -164,6 +167,12 @@ static inline int sysfs_create_file(struct kobject *kobj, return 0; } +static inline int sysfs_create_files(struct kobject *kobj, + const struct attribute **attr) +{ + return 0; +} + static inline int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode) { @@ -175,6 +184,11 @@ static inline void sysfs_remove_file(struct kobject *kobj, { } +static inline void sysfs_remove_files(struct kobject *kobj, + const struct attribute **attr) +{ +} + static inline int sysfs_create_bin_file(struct kobject *kobj, const struct bin_attribute *attr) { -- cgit v1.2.3 From 38457ab3a0d36320370c715145ba6da514127194 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 5 Jan 2010 12:48:02 +0100 Subject: sysfs: Add attribute array to sysdev classes Add a attribute array that is automatically registered and unregistered to struct sysdev_class. This is similar to what struct class has. A lot of drivers add list of attributes, so it's better to do this easily in the common sysdev layer. This adds a new field to struct sysdev_class. I audited the whole tree and there are no dynamically allocated sysdev classes, so this is fully compatible. Signed-off-by: Andi Kleen Signed-off-by: Greg Kroah-Hartman --- drivers/base/sys.c | 9 ++++++++- include/linux/sysdev.h | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/drivers/base/sys.c b/drivers/base/sys.c index a38445c0f8c5..747c99e0568b 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -145,13 +145,20 @@ int sysdev_class_register(struct sysdev_class *cls) if (retval) return retval; - return kset_register(&cls->kset); + retval = kset_register(&cls->kset); + if (!retval && cls->attrs) + retval = sysfs_create_files(&cls->kset.kobj, + (const struct attribute **)cls->attrs); + return retval; } void sysdev_class_unregister(struct sysdev_class *cls) { pr_debug("Unregistering sysdev class '%s'\n", kobject_name(&cls->kset.kobj)); + if (cls->attrs) + sysfs_remove_files(&cls->kset.kobj, + (const struct attribute **)cls->attrs); kset_unregister(&cls->kset); } diff --git a/include/linux/sysdev.h b/include/linux/sysdev.h index c2458fa8376c..b6244f9b533f 100644 --- a/include/linux/sysdev.h +++ b/include/linux/sysdev.h @@ -27,10 +27,12 @@ struct sys_device; +struct sysdev_class_attribute; struct sysdev_class { const char *name; struct list_head drivers; + struct sysdev_class_attribute **attrs; /* Default operations for these types of devices */ int (*shutdown)(struct sys_device *); -- cgit v1.2.3 From 1e395ab3d9b6aa09c5f0aa46a1b0a6fc5bd33133 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 5 Jan 2010 12:48:05 +0100 Subject: sysdev: Add sysdev_create/remove_files Allow to create/remove arrays of sysdev attributes Just wrappers around sysfs_create/move_files Will be used later to clean up some drivers. Signed-off-by: Andi Kleen Signed-off-by: Greg Kroah-Hartman --- include/linux/sysdev.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include') diff --git a/include/linux/sysdev.h b/include/linux/sysdev.h index b6244f9b533f..1154c29f4101 100644 --- a/include/linux/sysdev.h +++ b/include/linux/sysdev.h @@ -123,6 +123,19 @@ struct sysdev_attribute { extern int sysdev_create_file(struct sys_device *, struct sysdev_attribute *); extern void sysdev_remove_file(struct sys_device *, struct sysdev_attribute *); +/* Create/remove NULL terminated attribute list */ +static inline int +sysdev_create_files(struct sys_device *d, struct sysdev_attribute **a) +{ + return sysfs_create_files(&d->kobj, (const struct attribute **)a); +} + +static inline void +sysdev_remove_files(struct sys_device *d, struct sysdev_attribute **a) +{ + return sysfs_remove_files(&d->kobj, (const struct attribute **)a); +} + struct sysdev_ext_attribute { struct sysdev_attribute attr; void *var; -- cgit v1.2.3 From 28812fe11a21826ba4c97c6c7971a619987cd912 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 5 Jan 2010 12:48:07 +0100 Subject: driver-core: Add attribute argument to class_attribute show/store Passing the attribute to the low level IO functions allows all kinds of cleanups, by sharing low level IO code without requiring an own function for every piece of data. Also drivers can extend the attributes with own data fields and use that in the low level function. This makes the class attributes the same as sysdev_class attributes and plain attributes. This will allow further cleanups in drivers. Full tree sweep converting all users. Signed-off-by: Andi Kleen Signed-off-by: Greg Kroah-Hartman --- drivers/base/class.c | 4 ++-- drivers/base/cpu.c | 8 ++++++-- drivers/base/firmware_class.c | 8 ++++++-- drivers/base/memory.c | 11 ++++++++--- drivers/block/osdblk.c | 12 +++++++++--- drivers/block/pktcdvd.c | 12 +++++++++--- drivers/gpio/gpiolib.c | 8 ++++++-- drivers/gpu/drm/drm_sysfs.c | 3 ++- drivers/infiniband/core/ucm.c | 4 +++- drivers/infiniband/core/user_mad.c | 4 +++- drivers/infiniband/core/uverbs_main.c | 4 +++- drivers/misc/phantom.c | 2 +- drivers/mtd/ubi/build.c | 3 ++- drivers/net/bonding/bond_sysfs.c | 5 ++++- drivers/staging/asus_oled/asus_oled.c | 4 +++- drivers/uwb/driver.c | 5 ++++- include/linux/device.h | 6 ++++-- net/bluetooth/l2cap.c | 4 +++- net/bluetooth/rfcomm/core.c | 4 +++- net/bluetooth/rfcomm/sock.c | 4 +++- net/bluetooth/sco.c | 4 +++- 21 files changed, 87 insertions(+), 32 deletions(-) (limited to 'include') diff --git a/drivers/base/class.c b/drivers/base/class.c index 6e2c3b064f53..34a2de9c5385 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -31,7 +31,7 @@ static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr, ssize_t ret = -EIO; if (class_attr->show) - ret = class_attr->show(cp->class, buf); + ret = class_attr->show(cp->class, class_attr, buf); return ret; } @@ -43,7 +43,7 @@ static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr, ssize_t ret = -EIO; if (class_attr->store) - ret = class_attr->store(cp->class, buf, count); + ret = class_attr->store(cp->class, class_attr, buf, count); return ret; } diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index fb456b729803..9121c77b77fa 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -79,13 +79,17 @@ void unregister_cpu(struct cpu *cpu) } #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE -static ssize_t cpu_probe_store(struct class *class, const char *buf, +static ssize_t cpu_probe_store(struct class *class, + struct class_attribute *attr, + const char *buf, size_t count) { return arch_cpu_probe(buf, count); } -static ssize_t cpu_release_store(struct class *class, const char *buf, +static ssize_t cpu_release_store(struct class *class, + struct class_attribute *attr, + const char *buf, size_t count) { return arch_cpu_release(buf, count); diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index a95024166b66..6604fb33d072 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -69,7 +69,9 @@ fw_load_abort(struct firmware_priv *fw_priv) } static ssize_t -firmware_timeout_show(struct class *class, char *buf) +firmware_timeout_show(struct class *class, + struct class_attribute *attr, + char *buf) { return sprintf(buf, "%d\n", loading_timeout); } @@ -87,7 +89,9 @@ firmware_timeout_show(struct class *class, char *buf) * Note: zero means 'wait forever'. **/ static ssize_t -firmware_timeout_store(struct class *class, const char *buf, size_t count) +firmware_timeout_store(struct class *class, + struct class_attribute *attr, + const char *buf, size_t count) { loading_timeout = simple_strtol(buf, NULL, 10); if (loading_timeout < 0) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 563656ad75a1..495f15e92d4c 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -331,7 +331,8 @@ static int block_size_init(void) */ #ifdef CONFIG_ARCH_MEMORY_PROBE static ssize_t -memory_probe_store(struct class *class, const char *buf, size_t count) +memory_probe_store(struct class *class, struct class_attribute *attr, + const char *buf, size_t count) { u64 phys_addr; int nid; @@ -368,7 +369,9 @@ static inline int memory_probe_init(void) /* Soft offline a page */ static ssize_t -store_soft_offline_page(struct class *class, const char *buf, size_t count) +store_soft_offline_page(struct class *class, + struct class_attribute *attr, + const char *buf, size_t count) { int ret; u64 pfn; @@ -385,7 +388,9 @@ store_soft_offline_page(struct class *class, const char *buf, size_t count) /* Forcibly offline a page, including killing processes. */ static ssize_t -store_hard_offline_page(struct class *class, const char *buf, size_t count) +store_hard_offline_page(struct class *class, + struct class_attribute *attr, + const char *buf, size_t count) { int ret; u64 pfn; diff --git a/drivers/block/osdblk.c b/drivers/block/osdblk.c index a808b1530b3b..eb2091aa1c19 100644 --- a/drivers/block/osdblk.c +++ b/drivers/block/osdblk.c @@ -476,7 +476,9 @@ static void class_osdblk_release(struct class *cls) kfree(cls); } -static ssize_t class_osdblk_list(struct class *c, char *data) +static ssize_t class_osdblk_list(struct class *c, + struct class_attribute *attr, + char *data) { int n = 0; struct list_head *tmp; @@ -500,7 +502,9 @@ static ssize_t class_osdblk_list(struct class *c, char *data) return n; } -static ssize_t class_osdblk_add(struct class *c, const char *buf, size_t count) +static ssize_t class_osdblk_add(struct class *c, + struct class_attribute *attr, + const char *buf, size_t count) { struct osdblk_device *osdev; ssize_t rc; @@ -592,7 +596,9 @@ err_out_mod: return rc; } -static ssize_t class_osdblk_remove(struct class *c, const char *buf, +static ssize_t class_osdblk_remove(struct class *c, + struct class_attribute *attr, + const char *buf, size_t count) { struct osdblk_device *osdev = NULL; diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index b72935b8f203..73d815d3f1b2 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -337,7 +337,9 @@ static void class_pktcdvd_release(struct class *cls) { kfree(cls); } -static ssize_t class_pktcdvd_show_map(struct class *c, char *data) +static ssize_t class_pktcdvd_show_map(struct class *c, + struct class_attribute *attr, + char *data) { int n = 0; int idx; @@ -356,7 +358,9 @@ static ssize_t class_pktcdvd_show_map(struct class *c, char *data) return n; } -static ssize_t class_pktcdvd_store_add(struct class *c, const char *buf, +static ssize_t class_pktcdvd_store_add(struct class *c, + struct class_attribute *attr, + const char *buf, size_t count) { unsigned int major, minor; @@ -376,7 +380,9 @@ static ssize_t class_pktcdvd_store_add(struct class *c, const char *buf, return -EINVAL; } -static ssize_t class_pktcdvd_store_remove(struct class *c, const char *buf, +static ssize_t class_pktcdvd_store_remove(struct class *c, + struct class_attribute *attr, + const char *buf, size_t count) { unsigned int major, minor; diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 9006fdb26fea..6d1b86661e63 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -623,7 +623,9 @@ static const struct attribute_group gpiochip_attr_group = { * /sys/class/gpio/unexport ... write-only * integer N ... number of GPIO to unexport */ -static ssize_t export_store(struct class *class, const char *buf, size_t len) +static ssize_t export_store(struct class *class, + struct class_attribute *attr, + const char *buf, size_t len) { long gpio; int status; @@ -653,7 +655,9 @@ done: return status ? : len; } -static ssize_t unexport_store(struct class *class, const char *buf, size_t len) +static ssize_t unexport_store(struct class *class, + struct class_attribute *attr, + const char *buf, size_t len) { long gpio; int status; diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 7e42b7e9d43a..b95aaf23596e 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -71,7 +71,8 @@ static int drm_class_resume(struct device *dev) } /* Display the version of drm_core. This doesn't work right in current design */ -static ssize_t version_show(struct class *dev, char *buf) +static ssize_t version_show(struct class *dev, struct class_attribute *attr, + char *buf) { return sprintf(buf, "%s %d.%d.%d %s\n", CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE); diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index 1b09b735c5a8..02e209ff33fd 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c @@ -1336,7 +1336,9 @@ static void ib_ucm_remove_one(struct ib_device *device) device_unregister(&ucm_dev->dev); } -static ssize_t show_abi_version(struct class *class, char *buf) +static ssize_t show_abi_version(struct class *class, + struct class_attribute *attr, + char *buf) { return sprintf(buf, "%d\n", IB_USER_CM_ABI_VERSION); } diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 02d360cfc2f7..d0de8f265f45 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -965,7 +965,9 @@ static ssize_t show_port(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR(port, S_IRUGO, show_port, NULL); -static ssize_t show_abi_version(struct class *class, char *buf) +static ssize_t show_abi_version(struct class *class, + struct class_attribute *attr, + char *buf) { return sprintf(buf, "%d\n", IB_USER_MAD_ABI_VERSION); } diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 4fa2e6516441..60879399207a 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -691,7 +691,9 @@ static ssize_t show_dev_abi_version(struct device *device, } static DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL); -static ssize_t show_abi_version(struct class *class, char *buf) +static ssize_t show_abi_version(struct class *class, + struct class_attribute *attr, + char *buf) { return sprintf(buf, "%d\n", IB_USER_VERBS_ABI_VERSION); } diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c index 04c27266f567..d30ae9560309 100644 --- a/drivers/misc/phantom.c +++ b/drivers/misc/phantom.c @@ -497,7 +497,7 @@ static struct pci_driver phantom_pci_driver = { .resume = phantom_resume }; -static ssize_t phantom_show_version(struct class *cls, char *buf) +static ssize_t phantom_show_version(struct class *cls, struct class_attribute *attr, char *buf) { return sprintf(buf, PHANTOM_VERSION "\n"); } diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index bc45ef9af17d..fad40aa6f099 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -89,7 +89,8 @@ DEFINE_MUTEX(ubi_devices_mutex); static DEFINE_SPINLOCK(ubi_devices_lock); /* "Show" method for files in '//class/ubi/' */ -static ssize_t ubi_version_show(struct class *class, char *buf) +static ssize_t ubi_version_show(struct class *class, struct class_attribute *attr, + char *buf) { return sprintf(buf, "%d\n", UBI_VERSION); } diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 5acd557cea9b..b8bec086daa1 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -51,7 +51,9 @@ * "show" function for the bond_masters attribute. * The class parameter is ignored. */ -static ssize_t bonding_show_bonds(struct class *cls, char *buf) +static ssize_t bonding_show_bonds(struct class *cls, + struct class_attribute *attr, + char *buf) { struct net *net = current->nsproxy->net_ns; struct bond_net *bn = net_generic(net, bond_net_id); @@ -98,6 +100,7 @@ static struct net_device *bond_get_by_name(struct net *net, const char *ifname) */ static ssize_t bonding_store_bonds(struct class *cls, + struct class_attribute *attr, const char *buffer, size_t count) { struct net *net = current->nsproxy->net_ns; diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c index cadb6f7321ad..7d93f50a0a64 100644 --- a/drivers/staging/asus_oled/asus_oled.c +++ b/drivers/staging/asus_oled/asus_oled.c @@ -770,7 +770,9 @@ static struct usb_driver oled_driver = { .id_table = id_table, }; -static ssize_t version_show(struct class *dev, char *buf) +static ssize_t version_show(struct class *dev, + struct class_attribute *attr, + char *buf) { return sprintf(buf, ASUS_OLED_UNDERSCORE_NAME " %s\n", ASUS_OLED_VERSION); diff --git a/drivers/uwb/driver.c b/drivers/uwb/driver.c index da77e41de990..08bd6dbfd4a6 100644 --- a/drivers/uwb/driver.c +++ b/drivers/uwb/driver.c @@ -74,13 +74,16 @@ unsigned long beacon_timeout_ms = 500; static -ssize_t beacon_timeout_ms_show(struct class *class, char *buf) +ssize_t beacon_timeout_ms_show(struct class *class, + struct class_attribute *attr, + char *buf) { return scnprintf(buf, PAGE_SIZE, "%lu\n", beacon_timeout_ms); } static ssize_t beacon_timeout_ms_store(struct class *class, + struct class_attribute *attr, const char *buf, size_t size) { unsigned long bt; diff --git a/include/linux/device.h b/include/linux/device.h index b30527db3ac0..190f8d30d1d3 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -251,8 +251,10 @@ extern struct device *class_find_device(struct class *class, struct class_attribute { struct attribute attr; - ssize_t (*show)(struct class *class, char *buf); - ssize_t (*store)(struct class *class, const char *buf, size_t count); + ssize_t (*show)(struct class *class, struct class_attribute *attr, + char *buf); + ssize_t (*store)(struct class *class, struct class_attribute *attr, + const char *buf, size_t count); }; #define CLASS_ATTR(_name, _mode, _show, _store) \ diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 400efa26ddba..4db7ae2fe07d 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -3937,7 +3937,9 @@ drop: return 0; } -static ssize_t l2cap_sysfs_show(struct class *dev, char *buf) +static ssize_t l2cap_sysfs_show(struct class *dev, + struct class_attribute *attr, + char *buf) { struct sock *sk; struct hlist_node *node; diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 89f4a59eb82b..db8a68e1a5ba 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -2098,7 +2098,9 @@ static struct hci_cb rfcomm_cb = { .security_cfm = rfcomm_security_cfm }; -static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, char *buf) +static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, + struct class_attribute *attr, + char *buf) { struct rfcomm_session *s; struct list_head *pp, *p; diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 4b5968dda673..ca87d6ac6a20 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -1061,7 +1061,9 @@ done: return result; } -static ssize_t rfcomm_sock_sysfs_show(struct class *dev, char *buf) +static ssize_t rfcomm_sock_sysfs_show(struct class *dev, + struct class_attribute *attr, + char *buf) { struct sock *sk; struct hlist_node *node; diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index dd8f6ec57dce..f93b939539bc 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -953,7 +953,9 @@ drop: return 0; } -static ssize_t sco_sysfs_show(struct class *dev, char *buf) +static ssize_t sco_sysfs_show(struct class *dev, + struct class_attribute *attr, + char *buf) { struct sock *sk; struct hlist_node *node; -- cgit v1.2.3 From 869dfc875e32fd832385fd52ce54525a10401ed6 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 5 Jan 2010 12:48:08 +0100 Subject: driver core: Add class_attr_string for simple read-only string Several drivers just export a static string as class attributes. Use the new extensible attribute support to define a simple CLASS_ATTR_STRING() macro for this. This will allow to remove code from drivers in followon patches. Signed-off-by: Andi Kleen Signed-off-by: Greg Kroah-Hartman --- drivers/base/class.c | 10 ++++++++++ include/linux/device.h | 17 +++++++++++++++++ 2 files changed, 27 insertions(+) (limited to 'include') diff --git a/drivers/base/class.c b/drivers/base/class.c index 34a2de9c5385..2e297cc4cd3d 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -490,6 +490,16 @@ void class_interface_unregister(struct class_interface *class_intf) class_put(parent); } +ssize_t show_class_attr_string(struct class *class, struct class_attribute *attr, + char *buf) +{ + struct class_attribute_string *cs; + cs = container_of(attr, struct class_attribute_string, attr); + return snprintf(buf, PAGE_SIZE, "%s\n", cs->str); +} + +EXPORT_SYMBOL_GPL(show_class_attr_string); + struct class_compat { struct kobject *kobj; }; diff --git a/include/linux/device.h b/include/linux/device.h index 190f8d30d1d3..f95d5bfe8248 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -265,6 +265,23 @@ extern int __must_check class_create_file(struct class *class, extern void class_remove_file(struct class *class, const struct class_attribute *attr); +/* Simple class attribute that is just a static string */ + +struct class_attribute_string { + struct class_attribute attr; + char *str; +}; + +/* Currently read-only only */ +#define _CLASS_ATTR_STRING(_name, _mode, _str) \ + { __ATTR(_name, _mode, show_class_attr_string, NULL), _str } +#define CLASS_ATTR_STRING(_name, _mode, _str) \ + struct class_attribute_string class_attr_##_name = \ + _CLASS_ATTR_STRING(_name, _mode, _str) + +extern ssize_t show_class_attr_string(struct class *class, struct class_attribute *attr, + char *buf); + struct class_interface { struct list_head node; struct class *class; -- cgit v1.2.3 From 9cd43611ccfb46632bfa7d19f688924ea93f1613 Mon Sep 17 00:00:00 2001 From: Emese Revfy Date: Thu, 31 Dec 2009 14:52:51 +0100 Subject: kobject: Constify struct kset_uevent_ops Constify struct kset_uevent_ops. This is part of the ops structure constification effort started by Arjan van de Ven et al. Benefits of this constification: * prevents modification of data that is shared (referenced) by many other structure instances at runtime * detects/prevents accidental (but not intentional) modification attempts on archs that enforce read-only kernel data at runtime * potentially better optimized code as the compiler can assume that the const data cannot be changed * the compiler/linker move const data into .rodata and therefore exclude them from false sharing Signed-off-by: Emese Revfy Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 2 +- drivers/base/core.c | 2 +- drivers/base/memory.c | 2 +- fs/gfs2/sys.c | 2 +- include/linux/kobject.h | 10 +++++----- kernel/params.c | 2 +- lib/kobject.c | 4 ++-- lib/kobject_uevent.c | 2 +- mm/slub.c | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) (limited to 'include') diff --git a/drivers/base/bus.c b/drivers/base/bus.c index c0c5a43d9fb3..2afe599eb35d 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -154,7 +154,7 @@ static int bus_uevent_filter(struct kset *kset, struct kobject *kobj) return 0; } -static struct kset_uevent_ops bus_uevent_ops = { +static const struct kset_uevent_ops bus_uevent_ops = { .filter = bus_uevent_filter, }; diff --git a/drivers/base/core.c b/drivers/base/core.c index f6c73a9e3d95..58ec1069f4b0 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -252,7 +252,7 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, return retval; } -static struct kset_uevent_ops device_uevent_ops = { +static const struct kset_uevent_ops device_uevent_ops = { .filter = dev_uevent_filter, .name = dev_uevent_name, .uevent = dev_uevent, diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 495f15e92d4c..2f8691511190 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -44,7 +44,7 @@ static int memory_uevent(struct kset *kset, struct kobject *obj, struct kobj_uev return retval; } -static struct kset_uevent_ops memory_uevent_ops = { +static const struct kset_uevent_ops memory_uevent_ops = { .name = memory_uevent_name, .uevent = memory_uevent, }; diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index b5f1a46133c8..543503010ed0 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c @@ -574,7 +574,7 @@ static int gfs2_uevent(struct kset *kset, struct kobject *kobj, return 0; } -static struct kset_uevent_ops gfs2_uevent_ops = { +static const struct kset_uevent_ops gfs2_uevent_ops = { .uevent = gfs2_uevent, }; diff --git a/include/linux/kobject.h b/include/linux/kobject.h index 58ae8e00fcdd..57a1eaae9096 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -118,9 +118,9 @@ struct kobj_uevent_env { }; struct kset_uevent_ops { - int (*filter)(struct kset *kset, struct kobject *kobj); - const char *(*name)(struct kset *kset, struct kobject *kobj); - int (*uevent)(struct kset *kset, struct kobject *kobj, + int (* const filter)(struct kset *kset, struct kobject *kobj); + const char *(* const name)(struct kset *kset, struct kobject *kobj); + int (* const uevent)(struct kset *kset, struct kobject *kobj, struct kobj_uevent_env *env); }; @@ -155,14 +155,14 @@ struct kset { struct list_head list; spinlock_t list_lock; struct kobject kobj; - struct kset_uevent_ops *uevent_ops; + const struct kset_uevent_ops *uevent_ops; }; extern void kset_init(struct kset *kset); extern int __must_check kset_register(struct kset *kset); extern void kset_unregister(struct kset *kset); extern struct kset * __must_check kset_create_and_add(const char *name, - struct kset_uevent_ops *u, + const struct kset_uevent_ops *u, struct kobject *parent_kobj); static inline struct kset *to_kset(struct kobject *kobj) diff --git a/kernel/params.c b/kernel/params.c index 8d95f5451b22..48370be3c0a1 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -736,7 +736,7 @@ static int uevent_filter(struct kset *kset, struct kobject *kobj) return 0; } -static struct kset_uevent_ops module_uevent_ops = { +static const struct kset_uevent_ops module_uevent_ops = { .filter = uevent_filter, }; diff --git a/lib/kobject.c b/lib/kobject.c index b512b746d2af..cecf5a0ef6e1 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -789,7 +789,7 @@ static struct kobj_type kset_ktype = { * If the kset was not able to be created, NULL will be returned. */ static struct kset *kset_create(const char *name, - struct kset_uevent_ops *uevent_ops, + const struct kset_uevent_ops *uevent_ops, struct kobject *parent_kobj) { struct kset *kset; @@ -832,7 +832,7 @@ static struct kset *kset_create(const char *name, * If the kset was not able to be created, NULL will be returned. */ struct kset *kset_create_and_add(const char *name, - struct kset_uevent_ops *uevent_ops, + const struct kset_uevent_ops *uevent_ops, struct kobject *parent_kobj) { struct kset *kset; diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 920a3ca6e259..c9d3a3e8405d 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c @@ -95,7 +95,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, const char *subsystem; struct kobject *top_kobj; struct kset *kset; - struct kset_uevent_ops *uevent_ops; + const struct kset_uevent_ops *uevent_ops; u64 seq; int i = 0; int retval = 0; diff --git a/mm/slub.c b/mm/slub.c index 0bfd3863d521..a26753c12dcd 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -4409,7 +4409,7 @@ static int uevent_filter(struct kset *kset, struct kobject *kobj) return 0; } -static struct kset_uevent_ops slab_uevent_ops = { +static const struct kset_uevent_ops slab_uevent_ops = { .filter = uevent_filter, }; -- cgit v1.2.3 From 52cf25d0ab7f78eeecc59ac652ed5090f69b619e Mon Sep 17 00:00:00 2001 From: Emese Revfy Date: Tue, 19 Jan 2010 02:58:23 +0100 Subject: Driver core: Constify struct sysfs_ops in struct kobj_type Constify struct sysfs_ops. This is part of the ops structure constification effort started by Arjan van de Ven et al. Benefits of this constification: * prevents modification of data that is shared (referenced) by many other structure instances at runtime * detects/prevents accidental (but not intentional) modification attempts on archs that enforce read-only kernel data at runtime * potentially better optimized code as the compiler can assume that the const data cannot be changed * the compiler/linker move const data into .rodata and therefore exclude them from false sharing Signed-off-by: Emese Revfy Acked-by: David Teigland Acked-by: Matt Domsch Acked-by: Maciej Sosnowski Acked-by: Hans J. Koch Acked-by: Pekka Enberg Acked-by: Jens Axboe Acked-by: Stephen Hemminger Signed-off-by: Greg Kroah-Hartman --- Documentation/kobject.txt | 2 +- arch/ia64/kernel/topology.c | 2 +- arch/powerpc/kernel/cacheinfo.c | 2 +- arch/sh/kernel/cpu/sh4/sq.c | 2 +- arch/x86/kernel/cpu/intel_cacheinfo.c | 2 +- arch/x86/kernel/cpu/mcheck/mce_amd.c | 2 +- block/blk-integrity.c | 2 +- block/blk-sysfs.c | 2 +- block/elevator.c | 2 +- drivers/base/bus.c | 4 ++-- drivers/base/class.c | 2 +- drivers/base/core.c | 2 +- drivers/base/sys.c | 4 ++-- drivers/block/pktcdvd.c | 2 +- drivers/cpufreq/cpufreq.c | 2 +- drivers/cpuidle/sysfs.c | 4 ++-- drivers/dma/ioat/dma.c | 2 +- drivers/dma/ioat/dma.h | 2 +- drivers/edac/edac_device_sysfs.c | 6 +++--- drivers/edac/edac_mc_sysfs.c | 4 ++-- drivers/edac/edac_pci_sysfs.c | 4 ++-- drivers/firmware/edd.c | 2 +- drivers/firmware/efivars.c | 2 +- drivers/firmware/iscsi_ibft.c | 2 +- drivers/firmware/memmap.c | 2 +- drivers/gpu/drm/ttm/ttm_bo.c | 2 +- drivers/gpu/drm/ttm/ttm_memory.c | 2 +- drivers/infiniband/core/cm.c | 2 +- drivers/infiniband/core/sysfs.c | 2 +- drivers/md/dm-sysfs.c | 2 +- drivers/md/md.c | 4 ++-- drivers/net/ibmveth.c | 2 +- drivers/net/iseries_veth.c | 4 ++-- drivers/parisc/pdc_stable.c | 2 +- drivers/pci/hotplug/fakephp.c | 2 +- drivers/pci/slot.c | 2 +- drivers/uio/uio.c | 4 ++-- drivers/uwb/wlp/sysfs.c | 3 +-- drivers/video/omap2/dss/manager.c | 2 +- drivers/video/omap2/dss/overlay.c | 2 +- drivers/xen/sys-hypervisor.c | 2 +- fs/btrfs/sysfs.c | 4 ++-- fs/dlm/lockspace.c | 2 +- fs/ext4/super.c | 2 +- fs/gfs2/sys.c | 2 +- fs/ocfs2/cluster/masklog.c | 2 +- fs/sysfs/file.c | 8 ++++---- include/linux/kobject.h | 4 ++-- kernel/params.c | 2 +- lib/kobject.c | 2 +- mm/slub.c | 2 +- net/bridge/br_private.h | 2 +- net/bridge/br_sysfs_if.c | 2 +- samples/kobject/kset-example.c | 2 +- 54 files changed, 69 insertions(+), 70 deletions(-) (limited to 'include') diff --git a/Documentation/kobject.txt b/Documentation/kobject.txt index c79ab996dada..bdb13817e1e9 100644 --- a/Documentation/kobject.txt +++ b/Documentation/kobject.txt @@ -266,7 +266,7 @@ kobj_type: struct kobj_type { void (*release)(struct kobject *); - struct sysfs_ops *sysfs_ops; + const struct sysfs_ops *sysfs_ops; struct attribute **default_attrs; }; diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index 8f060352e129..b3a5818088d9 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c @@ -282,7 +282,7 @@ static ssize_t cache_show(struct kobject * kobj, struct attribute * attr, char * return ret; } -static struct sysfs_ops cache_sysfs_ops = { +static const struct sysfs_ops cache_sysfs_ops = { .show = cache_show }; diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c index bb37b1d19a58..01fe9ce28379 100644 --- a/arch/powerpc/kernel/cacheinfo.c +++ b/arch/powerpc/kernel/cacheinfo.c @@ -642,7 +642,7 @@ static struct kobj_attribute *cache_index_opt_attrs[] = { &cache_assoc_attr, }; -static struct sysfs_ops cache_index_ops = { +static const struct sysfs_ops cache_index_ops = { .show = cache_index_show, }; diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c index fc065f9da6e5..14726eef1ce0 100644 --- a/arch/sh/kernel/cpu/sh4/sq.c +++ b/arch/sh/kernel/cpu/sh4/sq.c @@ -326,7 +326,7 @@ static struct attribute *sq_sysfs_attrs[] = { NULL, }; -static struct sysfs_ops sq_sysfs_ops = { +static const struct sysfs_ops sq_sysfs_ops = { .show = sq_sysfs_show, .store = sq_sysfs_store, }; diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index eddb1bdd1b8f..b3eeb66c0a51 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -903,7 +903,7 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, return ret; } -static struct sysfs_ops sysfs_ops = { +static const struct sysfs_ops sysfs_ops = { .show = show, .store = store, }; diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 83a3d1f4efca..cda932ca3ade 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -388,7 +388,7 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, return ret; } -static struct sysfs_ops threshold_ops = { +static const struct sysfs_ops threshold_ops = { .show = show, .store = store, }; diff --git a/block/blk-integrity.c b/block/blk-integrity.c index 15c630813b1c..96e83c2bdb94 100644 --- a/block/blk-integrity.c +++ b/block/blk-integrity.c @@ -278,7 +278,7 @@ static struct attribute *integrity_attrs[] = { NULL, }; -static struct sysfs_ops integrity_ops = { +static const struct sysfs_ops integrity_ops = { .show = &integrity_attr_show, .store = &integrity_attr_store, }; diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index e85442415db3..2ae2cb3f362f 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -450,7 +450,7 @@ static void blk_release_queue(struct kobject *kobj) kmem_cache_free(blk_requestq_cachep, q); } -static struct sysfs_ops queue_sysfs_ops = { +static const struct sysfs_ops queue_sysfs_ops = { .show = queue_attr_show, .store = queue_attr_store, }; diff --git a/block/elevator.c b/block/elevator.c index ee3a883840f2..df75676f6671 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -892,7 +892,7 @@ elv_attr_store(struct kobject *kobj, struct attribute *attr, return error; } -static struct sysfs_ops elv_sysfs_ops = { +static const struct sysfs_ops elv_sysfs_ops = { .show = elv_attr_show, .store = elv_attr_store, }; diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 2afe599eb35d..cca1aa10054c 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -70,7 +70,7 @@ static ssize_t drv_attr_store(struct kobject *kobj, struct attribute *attr, return ret; } -static struct sysfs_ops driver_sysfs_ops = { +static const struct sysfs_ops driver_sysfs_ops = { .show = drv_attr_show, .store = drv_attr_store, }; @@ -115,7 +115,7 @@ static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr, return ret; } -static struct sysfs_ops bus_sysfs_ops = { +static const struct sysfs_ops bus_sysfs_ops = { .show = bus_attr_show, .store = bus_attr_store, }; diff --git a/drivers/base/class.c b/drivers/base/class.c index 2e297cc4cd3d..0147f476b8a9 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -63,7 +63,7 @@ static void class_release(struct kobject *kobj) kfree(cp); } -static struct sysfs_ops class_sysfs_ops = { +static const struct sysfs_ops class_sysfs_ops = { .show = class_attr_show, .store = class_attr_store, }; diff --git a/drivers/base/core.c b/drivers/base/core.c index 58ec1069f4b0..b0d6646a2814 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -100,7 +100,7 @@ static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr, return ret; } -static struct sysfs_ops dev_sysfs_ops = { +static const struct sysfs_ops dev_sysfs_ops = { .show = dev_attr_show, .store = dev_attr_store, }; diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 747c99e0568b..8980feec5d14 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -54,7 +54,7 @@ sysdev_store(struct kobject *kobj, struct attribute *attr, return -EIO; } -static struct sysfs_ops sysfs_ops = { +static const struct sysfs_ops sysfs_ops = { .show = sysdev_show, .store = sysdev_store, }; @@ -104,7 +104,7 @@ static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr, return -EIO; } -static struct sysfs_ops sysfs_class_ops = { +static const struct sysfs_ops sysfs_class_ops = { .show = sysdev_class_show, .store = sysdev_class_store, }; diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 73d815d3f1b2..39c8514442eb 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -284,7 +284,7 @@ static ssize_t kobj_pkt_store(struct kobject *kobj, return len; } -static struct sysfs_ops kobj_pkt_ops = { +static const struct sysfs_ops kobj_pkt_ops = { .show = kobj_pkt_show, .store = kobj_pkt_store }; diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 67bc2ece7b4b..2d5d575e889d 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -766,7 +766,7 @@ static void cpufreq_sysfs_release(struct kobject *kobj) complete(&policy->kobj_unregister); } -static struct sysfs_ops sysfs_ops = { +static const struct sysfs_ops sysfs_ops = { .show = show, .store = store, }; diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index c9cefacabf37..8719b36e1a4d 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c @@ -195,7 +195,7 @@ static ssize_t cpuidle_store(struct kobject * kobj, struct attribute * attr, return ret; } -static struct sysfs_ops cpuidle_sysfs_ops = { +static const struct sysfs_ops cpuidle_sysfs_ops = { .show = cpuidle_show, .store = cpuidle_store, }; @@ -281,7 +281,7 @@ static ssize_t cpuidle_state_show(struct kobject * kobj, return ret; } -static struct sysfs_ops cpuidle_state_sysfs_ops = { +static const struct sysfs_ops cpuidle_state_sysfs_ops = { .show = cpuidle_state_show, }; diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index af14c9a5b8d4..0099340b9616 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c @@ -1138,7 +1138,7 @@ ioat_attr_show(struct kobject *kobj, struct attribute *attr, char *page) return entry->show(&chan->common, page); } -struct sysfs_ops ioat_sysfs_ops = { +const struct sysfs_ops ioat_sysfs_ops = { .show = ioat_attr_show, }; diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 4f747a254074..86b97ac8774e 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h @@ -346,7 +346,7 @@ bool ioat_cleanup_preamble(struct ioat_chan_common *chan, unsigned long *phys_complete); void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type); void ioat_kobject_del(struct ioatdma_device *device); -extern struct sysfs_ops ioat_sysfs_ops; +extern const struct sysfs_ops ioat_sysfs_ops; extern struct ioat_sysfs_entry ioat_version_attr; extern struct ioat_sysfs_entry ioat_cap_attr; #endif /* IOATDMA_H */ diff --git a/drivers/edac/edac_device_sysfs.c b/drivers/edac/edac_device_sysfs.c index 53764577035f..5fdedbc0f545 100644 --- a/drivers/edac/edac_device_sysfs.c +++ b/drivers/edac/edac_device_sysfs.c @@ -137,7 +137,7 @@ static ssize_t edac_dev_ctl_info_store(struct kobject *kobj, } /* edac_dev file operations for an 'ctl_info' */ -static struct sysfs_ops device_ctl_info_ops = { +static const struct sysfs_ops device_ctl_info_ops = { .show = edac_dev_ctl_info_show, .store = edac_dev_ctl_info_store }; @@ -373,7 +373,7 @@ static ssize_t edac_dev_instance_store(struct kobject *kobj, } /* edac_dev file operations for an 'instance' */ -static struct sysfs_ops device_instance_ops = { +static const struct sysfs_ops device_instance_ops = { .show = edac_dev_instance_show, .store = edac_dev_instance_store }; @@ -476,7 +476,7 @@ static ssize_t edac_dev_block_store(struct kobject *kobj, } /* edac_dev file operations for a 'block' */ -static struct sysfs_ops device_block_ops = { +static const struct sysfs_ops device_block_ops = { .show = edac_dev_block_show, .store = edac_dev_block_store }; diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index e1d4ce083481..88840e9fa3e0 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c @@ -245,7 +245,7 @@ static ssize_t csrowdev_store(struct kobject *kobj, struct attribute *attr, return -EIO; } -static struct sysfs_ops csrowfs_ops = { +static const struct sysfs_ops csrowfs_ops = { .show = csrowdev_show, .store = csrowdev_store }; @@ -575,7 +575,7 @@ static ssize_t mcidev_store(struct kobject *kobj, struct attribute *attr, } /* Intermediate show/store table */ -static struct sysfs_ops mci_ops = { +static const struct sysfs_ops mci_ops = { .show = mcidev_show, .store = mcidev_store }; diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c index fb60a877d768..bef94e3d9944 100644 --- a/drivers/edac/edac_pci_sysfs.c +++ b/drivers/edac/edac_pci_sysfs.c @@ -121,7 +121,7 @@ static ssize_t edac_pci_instance_store(struct kobject *kobj, } /* fs_ops table */ -static struct sysfs_ops pci_instance_ops = { +static const struct sysfs_ops pci_instance_ops = { .show = edac_pci_instance_show, .store = edac_pci_instance_store }; @@ -261,7 +261,7 @@ static ssize_t edac_pci_dev_store(struct kobject *kobj, return -EIO; } -static struct sysfs_ops edac_pci_sysfs_ops = { +static const struct sysfs_ops edac_pci_sysfs_ops = { .show = edac_pci_dev_show, .store = edac_pci_dev_store }; diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c index 9e4f59dc7f1e..110e24e50883 100644 --- a/drivers/firmware/edd.c +++ b/drivers/firmware/edd.c @@ -122,7 +122,7 @@ edd_attr_show(struct kobject * kobj, struct attribute *attr, char *buf) return ret; } -static struct sysfs_ops edd_attr_ops = { +static const struct sysfs_ops edd_attr_ops = { .show = edd_attr_show, }; diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index f4f709d1370b..082f06ecd327 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -362,7 +362,7 @@ static ssize_t efivar_attr_store(struct kobject *kobj, struct attribute *attr, return ret; } -static struct sysfs_ops efivar_attr_ops = { +static const struct sysfs_ops efivar_attr_ops = { .show = efivar_attr_show, .store = efivar_attr_store, }; diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c index a3600e3ed0fa..ed2801c378de 100644 --- a/drivers/firmware/iscsi_ibft.c +++ b/drivers/firmware/iscsi_ibft.c @@ -519,7 +519,7 @@ static ssize_t ibft_show_attribute(struct kobject *kobj, return ret; } -static struct sysfs_ops ibft_attr_ops = { +static const struct sysfs_ops ibft_attr_ops = { .show = ibft_show_attribute, }; diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c index 20f645743ead..d59f7cad2269 100644 --- a/drivers/firmware/memmap.c +++ b/drivers/firmware/memmap.c @@ -74,7 +74,7 @@ static struct attribute *def_attrs[] = { NULL }; -static struct sysfs_ops memmap_attr_ops = { +static const struct sysfs_ops memmap_attr_ops = { .show = memmap_attr_show, }; diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index c7320ce4567d..89c38c49066f 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -128,7 +128,7 @@ static struct attribute *ttm_bo_global_attrs[] = { NULL }; -static struct sysfs_ops ttm_bo_global_ops = { +static const struct sysfs_ops ttm_bo_global_ops = { .show = &ttm_bo_global_show }; diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c index f5245c02b8fd..eb143e04d402 100644 --- a/drivers/gpu/drm/ttm/ttm_memory.c +++ b/drivers/gpu/drm/ttm/ttm_memory.c @@ -152,7 +152,7 @@ static struct attribute *ttm_mem_zone_attrs[] = { NULL }; -static struct sysfs_ops ttm_mem_zone_ops = { +static const struct sysfs_ops ttm_mem_zone_ops = { .show = &ttm_mem_zone_show, .store = &ttm_mem_zone_store }; diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 5130fc55b8e2..764787ebe8d8 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -3597,7 +3597,7 @@ static ssize_t cm_show_counter(struct kobject *obj, struct attribute *attr, atomic_long_read(&group->counter[cm_attr->index])); } -static struct sysfs_ops cm_counter_ops = { +static const struct sysfs_ops cm_counter_ops = { .show = cm_show_counter }; diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 158a214da2f7..1558bb7fc74d 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c @@ -79,7 +79,7 @@ static ssize_t port_attr_show(struct kobject *kobj, return port_attr->show(p, port_attr, buf); } -static struct sysfs_ops port_sysfs_ops = { +static const struct sysfs_ops port_sysfs_ops = { .show = port_attr_show }; diff --git a/drivers/md/dm-sysfs.c b/drivers/md/dm-sysfs.c index f91b40942e07..84d2b91e4efb 100644 --- a/drivers/md/dm-sysfs.c +++ b/drivers/md/dm-sysfs.c @@ -75,7 +75,7 @@ static struct attribute *dm_attrs[] = { NULL, }; -static struct sysfs_ops dm_sysfs_ops = { +static const struct sysfs_ops dm_sysfs_ops = { .show = dm_attr_show, }; diff --git a/drivers/md/md.c b/drivers/md/md.c index a20a71e5efd3..fdc1890b6ac5 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2642,7 +2642,7 @@ static void rdev_free(struct kobject *ko) mdk_rdev_t *rdev = container_of(ko, mdk_rdev_t, kobj); kfree(rdev); } -static struct sysfs_ops rdev_sysfs_ops = { +static const struct sysfs_ops rdev_sysfs_ops = { .show = rdev_attr_show, .store = rdev_attr_store, }; @@ -4059,7 +4059,7 @@ static void md_free(struct kobject *ko) kfree(mddev); } -static struct sysfs_ops md_sysfs_ops = { +static const struct sysfs_ops md_sysfs_ops = { .show = md_attr_show, .store = md_attr_store, }; diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index f2b937966950..0bc777bac9b4 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -1577,7 +1577,7 @@ static struct attribute * veth_pool_attrs[] = { NULL, }; -static struct sysfs_ops veth_pool_ops = { +static const struct sysfs_ops veth_pool_ops = { .show = veth_pool_show, .store = veth_pool_store, }; diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 966de5d69521..e6e972d9b7ca 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -384,7 +384,7 @@ static struct attribute *veth_cnx_default_attrs[] = { NULL }; -static struct sysfs_ops veth_cnx_sysfs_ops = { +static const struct sysfs_ops veth_cnx_sysfs_ops = { .show = veth_cnx_attribute_show }; @@ -441,7 +441,7 @@ static struct attribute *veth_port_default_attrs[] = { NULL }; -static struct sysfs_ops veth_port_sysfs_ops = { +static const struct sysfs_ops veth_port_sysfs_ops = { .show = veth_port_attribute_show }; diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index 0bc5d474b168..1062b8ffe244 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c @@ -481,7 +481,7 @@ pdcspath_attr_store(struct kobject *kobj, struct attribute *attr, return ret; } -static struct sysfs_ops pdcspath_attr_ops = { +static const struct sysfs_ops pdcspath_attr_ops = { .show = pdcspath_attr_show, .store = pdcspath_attr_store, }; diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index 6151389fd903..0a894efd4b9b 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c @@ -73,7 +73,7 @@ static void legacy_release(struct kobject *kobj) } static struct kobj_type legacy_ktype = { - .sysfs_ops = &(struct sysfs_ops){ + .sysfs_ops = &(const struct sysfs_ops){ .store = legacy_store, .show = legacy_show }, .release = &legacy_release, diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 49c9e6c9779a..f75a44d37fbe 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c @@ -29,7 +29,7 @@ static ssize_t pci_slot_attr_store(struct kobject *kobj, return attribute->store ? attribute->store(slot, buf, len) : -EIO; } -static struct sysfs_ops pci_slot_sysfs_ops = { +static const struct sysfs_ops pci_slot_sysfs_ops = { .show = pci_slot_attr_show, .store = pci_slot_attr_store, }; diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index e941367dd28f..4de382acd8f2 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -129,7 +129,7 @@ static ssize_t map_type_show(struct kobject *kobj, struct attribute *attr, return entry->show(mem, buf); } -static struct sysfs_ops map_sysfs_ops = { +static const struct sysfs_ops map_sysfs_ops = { .show = map_type_show, }; @@ -217,7 +217,7 @@ static ssize_t portio_type_show(struct kobject *kobj, struct attribute *attr, return entry->show(port, buf); } -static struct sysfs_ops portio_sysfs_ops = { +static const struct sysfs_ops portio_sysfs_ops = { .show = portio_type_show, }; diff --git a/drivers/uwb/wlp/sysfs.c b/drivers/uwb/wlp/sysfs.c index 0370399ff4bb..6627c94cc854 100644 --- a/drivers/uwb/wlp/sysfs.c +++ b/drivers/uwb/wlp/sysfs.c @@ -615,8 +615,7 @@ ssize_t wlp_wss_attr_store(struct kobject *kobj, struct attribute *attr, return ret; } -static -struct sysfs_ops wss_sysfs_ops = { +static const struct sysfs_ops wss_sysfs_ops = { .show = wlp_wss_attr_show, .store = wlp_wss_attr_store, }; diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 913142d4cab1..9acef00c47ea 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -341,7 +341,7 @@ static ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr, return manager_attr->store(manager, buf, size); } -static struct sysfs_ops manager_sysfs_ops = { +static const struct sysfs_ops manager_sysfs_ops = { .show = manager_attr_show, .store = manager_attr_store, }; diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index 0c5bea263ac6..aed3f3194347 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c @@ -320,7 +320,7 @@ static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr, return overlay_attr->store(overlay, buf, size); } -static struct sysfs_ops overlay_sysfs_ops = { +static const struct sysfs_ops overlay_sysfs_ops = { .show = overlay_attr_show, .store = overlay_attr_store, }; diff --git a/drivers/xen/sys-hypervisor.c b/drivers/xen/sys-hypervisor.c index ae5cb05a1a1c..bb71ab2336c8 100644 --- a/drivers/xen/sys-hypervisor.c +++ b/drivers/xen/sys-hypervisor.c @@ -426,7 +426,7 @@ static ssize_t hyp_sysfs_store(struct kobject *kobj, return 0; } -static struct sysfs_ops hyp_sysfs_ops = { +static const struct sysfs_ops hyp_sysfs_ops = { .show = hyp_sysfs_show, .store = hyp_sysfs_store, }; diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index a240b6fa81df..4ce16ef702a3 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -164,12 +164,12 @@ static void btrfs_root_release(struct kobject *kobj) complete(&root->kobj_unregister); } -static struct sysfs_ops btrfs_super_attr_ops = { +static const struct sysfs_ops btrfs_super_attr_ops = { .show = btrfs_super_attr_show, .store = btrfs_super_attr_store, }; -static struct sysfs_ops btrfs_root_attr_ops = { +static const struct sysfs_ops btrfs_root_attr_ops = { .show = btrfs_root_attr_show, .store = btrfs_root_attr_store, }; diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index 26a8bd40400a..f994a7dfda85 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -148,7 +148,7 @@ static void lockspace_kobj_release(struct kobject *k) kfree(ls); } -static struct sysfs_ops dlm_attr_ops = { +static const struct sysfs_ops dlm_attr_ops = { .show = dlm_attr_show, .store = dlm_attr_store, }; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 2b83b96cb2eb..ce84a6ed4a48 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -2358,7 +2358,7 @@ static void ext4_sb_release(struct kobject *kobj) } -static struct sysfs_ops ext4_attr_ops = { +static const struct sysfs_ops ext4_attr_ops = { .show = ext4_attr_show, .store = ext4_attr_store, }; diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 543503010ed0..419042f7f0b6 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c @@ -49,7 +49,7 @@ static ssize_t gfs2_attr_store(struct kobject *kobj, struct attribute *attr, return a->store ? a->store(sdp, buf, len) : len; } -static struct sysfs_ops gfs2_attr_ops = { +static const struct sysfs_ops gfs2_attr_ops = { .show = gfs2_attr_show, .store = gfs2_attr_store, }; diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c index b39da877b12f..3bb928a2bf7d 100644 --- a/fs/ocfs2/cluster/masklog.c +++ b/fs/ocfs2/cluster/masklog.c @@ -136,7 +136,7 @@ static ssize_t mlog_store(struct kobject *obj, struct attribute *attr, return mlog_mask_store(mlog_attr->mask, buf, count); } -static struct sysfs_ops mlog_attr_ops = { +static const struct sysfs_ops mlog_attr_ops = { .show = mlog_show, .store = mlog_store, }; diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 50b725bcc3f3..ced2299f1c9a 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -53,7 +53,7 @@ struct sysfs_buffer { size_t count; loff_t pos; char * page; - struct sysfs_ops * ops; + const struct sysfs_ops * ops; struct mutex mutex; int needs_read_fill; int event; @@ -75,7 +75,7 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer { struct sysfs_dirent *attr_sd = dentry->d_fsdata; struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; - struct sysfs_ops * ops = buffer->ops; + const struct sysfs_ops * ops = buffer->ops; int ret = 0; ssize_t count; @@ -199,7 +199,7 @@ flush_write_buffer(struct dentry * dentry, struct sysfs_buffer * buffer, size_t { struct sysfs_dirent *attr_sd = dentry->d_fsdata; struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; - struct sysfs_ops * ops = buffer->ops; + const struct sysfs_ops * ops = buffer->ops; int rc; /* need attr_sd for attr and ops, its parent for kobj */ @@ -335,7 +335,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file) struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; struct sysfs_buffer *buffer; - struct sysfs_ops *ops; + const struct sysfs_ops *ops; int error = -EACCES; char *p; diff --git a/include/linux/kobject.h b/include/linux/kobject.h index 57a1eaae9096..3950d3c2850d 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -106,7 +106,7 @@ extern char *kobject_get_path(struct kobject *kobj, gfp_t flag); struct kobj_type { void (*release)(struct kobject *kobj); - struct sysfs_ops *sysfs_ops; + const struct sysfs_ops *sysfs_ops; struct attribute **default_attrs; }; @@ -132,7 +132,7 @@ struct kobj_attribute { const char *buf, size_t count); }; -extern struct sysfs_ops kobj_sysfs_ops; +extern const struct sysfs_ops kobj_sysfs_ops; /** * struct kset - a set of kobjects of a specific type, belonging to a specific subsystem. diff --git a/kernel/params.c b/kernel/params.c index 48370be3c0a1..68396d73c838 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -722,7 +722,7 @@ static ssize_t module_attr_store(struct kobject *kobj, return ret; } -static struct sysfs_ops module_sysfs_ops = { +static const struct sysfs_ops module_sysfs_ops = { .show = module_attr_show, .store = module_attr_store, }; diff --git a/lib/kobject.c b/lib/kobject.c index cecf5a0ef6e1..8115eb1bbf4d 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -700,7 +700,7 @@ static ssize_t kobj_attr_store(struct kobject *kobj, struct attribute *attr, return ret; } -struct sysfs_ops kobj_sysfs_ops = { +const struct sysfs_ops kobj_sysfs_ops = { .show = kobj_attr_show, .store = kobj_attr_store, }; diff --git a/mm/slub.c b/mm/slub.c index a26753c12dcd..a2b8969ba6d0 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -4390,7 +4390,7 @@ static void kmem_cache_release(struct kobject *kobj) kfree(s); } -static struct sysfs_ops slab_sysfs_ops = { +static const struct sysfs_ops slab_sysfs_ops = { .show = slab_attr_show, .store = slab_attr_store, }; diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 1cf2cef78584..fef0384e3c0b 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -423,7 +423,7 @@ extern void br_ifinfo_notify(int event, struct net_bridge_port *port); #ifdef CONFIG_SYSFS /* br_sysfs_if.c */ -extern struct sysfs_ops brport_sysfs_ops; +extern const struct sysfs_ops brport_sysfs_ops; extern int br_sysfs_addif(struct net_bridge_port *p); /* br_sysfs_br.c */ diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c index 696596cd3384..0b9916489d6b 100644 --- a/net/bridge/br_sysfs_if.c +++ b/net/bridge/br_sysfs_if.c @@ -238,7 +238,7 @@ static ssize_t brport_store(struct kobject * kobj, return ret; } -struct sysfs_ops brport_sysfs_ops = { +const struct sysfs_ops brport_sysfs_ops = { .show = brport_show, .store = brport_store, }; diff --git a/samples/kobject/kset-example.c b/samples/kobject/kset-example.c index 7c6088140528..3b126d1f8599 100644 --- a/samples/kobject/kset-example.c +++ b/samples/kobject/kset-example.c @@ -87,7 +87,7 @@ static ssize_t foo_attr_store(struct kobject *kobj, } /* Our custom sysfs_ops that we will associate with our ktype later on */ -static struct sysfs_ops foo_sysfs_ops = { +static const struct sysfs_ops foo_sysfs_ops = { .show = foo_attr_show, .store = foo_attr_store, }; -- cgit v1.2.3 From 831fad2f75f0d7bfc339de81173e7068a3c72276 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 26 Jan 2010 09:35:00 +0100 Subject: Driver core: make struct platform_driver.id_table const MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a warning on several pxa based machines: arch/arm/mach-pxa/ssp.c:475: warning: initialization discards qualifiers from pointer target type Signed-off-by: Uwe Kleine-König Acked-by: Vikram Dhillon Acked-by: Eric Miao Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 2 +- include/linux/platform_device.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 937d58021d1b..575e08bc6630 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -636,7 +636,7 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) } static const struct platform_device_id *platform_match_id( - struct platform_device_id *id, + const struct platform_device_id *id, struct platform_device *pdev) { while (id->name[0]) { diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 2c2d035bfb92..212da17d06af 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -62,7 +62,7 @@ struct platform_driver { int (*suspend)(struct platform_device *, pm_message_t state); int (*resume)(struct platform_device *); struct device_driver driver; - struct platform_device_id *id_table; + const struct platform_device_id *id_table; }; extern int platform_driver_register(struct platform_driver *); -- cgit v1.2.3 From 6992f5334995af474c2b58d010d08bc597f0f2fe Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Thu, 11 Feb 2010 15:21:53 -0800 Subject: sysfs: Use one lockdep class per sysfs attribute. Acknowledge that the logical sysfs rwsem has one instance per sysfs attribute with different locking depencencies for different attributes. There is a sysfs idiom where writing to one sysfs file causes the addition or removal of other sysfs files. Lumping all of the sysfs attributes together in one lock class causes lockdep to generate lots of false positives. This introduces the requirement that non-static sysfs attributes need to be initialized with sysfs_attr_init or sysfs_bin_attr_init. Strictly speaking this requirement only exists when lockdep is enabled, and when lockdep is enabled we get a bit fat warning if this requirement is not met. Signed-off-by: Eric W. Biederman Acked-by: WANG Cong Cc: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/sysfs.h | 7 +++++-- include/linux/sysfs.h | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 7db6884f4206..37e0e086233c 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h @@ -92,9 +92,12 @@ static inline unsigned int sysfs_type(struct sysfs_dirent *sd) #ifdef CONFIG_DEBUG_LOCK_ALLOC #define sysfs_dirent_init_lockdep(sd) \ do { \ - static struct lock_class_key __key; \ + struct attribute *attr = sd->s_attr.attr; \ + struct lock_class_key *key = attr->key; \ + if (!key) \ + key = &attr->skey; \ \ - lockdep_init_map(&sd->dep_map, "s_active", &__key, 0); \ + lockdep_init_map(&sd->dep_map, "s_active", key, 0); \ } while(0) #else #define sysfs_dirent_init_lockdep(sd) do {} while(0) diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 3e8526582146..006c359e63c0 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -15,6 +15,7 @@ #include #include #include +#include #include struct kobject; @@ -29,8 +30,23 @@ struct attribute { const char *name; struct module *owner; mode_t mode; +#ifdef CONFIG_DEBUG_LOCK_ALLOC + struct lock_class_key *key; + struct lock_class_key skey; +#endif }; +#ifdef CONFIG_DEBUG_LOCK_ALLOC +#define sysfs_attr_init(attr) \ +do { \ + static struct lock_class_key __key; \ + \ + (attr)->key = &__key; \ +} while(0) +#else +#define sysfs_attr_init(attr) do {} while(0) +#endif + struct attribute_group { const char *name; mode_t (*is_visible)(struct kobject *, @@ -74,6 +90,8 @@ struct bin_attribute { struct vm_area_struct *vma); }; +#define sysfs_bin_attr_init(bin_attr) sysfs_attr_init(&bin_attr->attr) + struct sysfs_ops { ssize_t (*show)(struct kobject *, struct attribute *,char *); ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t); -- cgit v1.2.3 From 35960258ed388cdcebdb71df35fd5126978ca325 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 12 Feb 2010 04:35:32 -0800 Subject: sysfs: Document sysfs_attr_init and sysfs_bin_attr_init I have added a new requirement to the external sysfs interface that dynamically allocated sysfs attributes must call sysfs_attr_init if lockdep is enabled. For the time being callying sysfs_attr_init is only mandatory if lockdep is enabled, so we can live with a few unconverted instances until we find them all. As this is part of the public interface of sysfs it is a good idea to document these pseudo functions so someone inspeciting the code can find out what has happened. Signed-off-by: Eric W. Biederman Signed-off-by: Greg Kroah-Hartman --- include/linux/sysfs.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'include') diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 006c359e63c0..5b8f80f5aca6 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -36,6 +36,16 @@ struct attribute { #endif }; +/** + * sysfs_attr_init - initialize a dynamically allocated sysfs attribute + * @attr: struct attribute to initialize + * + * Initialize a dynamically allocated struct attribute so we can + * make lockdep happy. This is a new requirement for attributes + * and initially this is only needed when lockdep is enabled. + * Lockdep gives a nice error when your attribute is added to + * sysfs if you don't have this. + */ #ifdef CONFIG_DEBUG_LOCK_ALLOC #define sysfs_attr_init(attr) \ do { \ @@ -90,6 +100,16 @@ struct bin_attribute { struct vm_area_struct *vma); }; +/** + * sysfs_bin_attr_init - initialize a dynamically allocated bin_attribute + * @attr: struct bin_attribute to initialize + * + * Initialize a dynamically allocated struct bin_attribute so we + * can make lockdep happy. This is a new requirement for + * attributes and initially this is only needed when lockdep is + * enabled. Lockdep gives a nice error when your attribute is + * added to sysfs if you don't have this. + */ #define sysfs_bin_attr_init(bin_attr) sysfs_attr_init(&bin_attr->attr) struct sysfs_ops { -- cgit v1.2.3 From 7cb32942d91a501b2df944928ccc9e6590ab237b Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 12 Feb 2010 19:22:25 -0800 Subject: sysfs: Implement sysfs_rename_link Because of rename ordering problems we occassionally give false warnings about invalid sysfs operations. So using sysfs_rename create a sysfs_rename_link function that doesn't need strange workarounds. Cc: Benjamin Thery Cc: Daniel Lezcano Acked-by: Serge Hallyn Acked-by: Tejun Heo Signed-off-by: Eric W. Biederman Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/symlink.c | 38 ++++++++++++++++++++++++++++++++++++++ include/linux/sysfs.h | 9 +++++++++ 2 files changed, 47 insertions(+) (limited to 'include') diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index c5eff49fa41b..1b9a3a1e8a17 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -123,6 +123,44 @@ void sysfs_remove_link(struct kobject * kobj, const char * name) sysfs_hash_and_remove(parent_sd, name); } +/** + * sysfs_rename_link - rename symlink in object's directory. + * @kobj: object we're acting for. + * @targ: object we're pointing to. + * @old: previous name of the symlink. + * @new: new name of the symlink. + * + * A helper function for the common rename symlink idiom. + */ +int sysfs_rename_link(struct kobject *kobj, struct kobject *targ, + const char *old, const char *new) +{ + struct sysfs_dirent *parent_sd, *sd = NULL; + int result; + + if (!kobj) + parent_sd = &sysfs_root; + else + parent_sd = kobj->sd; + + result = -ENOENT; + sd = sysfs_get_dirent(parent_sd, old); + if (!sd) + goto out; + + result = -EINVAL; + if (sysfs_type(sd) != SYSFS_KOBJ_LINK) + goto out; + if (sd->s_symlink.target_sd->s_dir.kobj != targ) + goto out; + + result = sysfs_rename(sd, parent_sd, new); + +out: + sysfs_put(sd); + return result; +} + static int sysfs_get_target_path(struct sysfs_dirent *parent_sd, struct sysfs_dirent *target_sd, char *path) { diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 5b8f80f5aca6..d77cde6d0498 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -151,6 +151,9 @@ int __must_check sysfs_create_link_nowarn(struct kobject *kobj, const char *name); void sysfs_remove_link(struct kobject *kobj, const char *name); +int sysfs_rename_link(struct kobject *kobj, struct kobject *target, + const char *old_name, const char *new_name); + int __must_check sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp); int sysfs_update_group(struct kobject *kobj, @@ -255,6 +258,12 @@ static inline void sysfs_remove_link(struct kobject *kobj, const char *name) { } +static inline int sysfs_rename_link(struct kobject *k, struct kobject *t, + const char *old_name, const char *new_name) +{ + return 0; +} + static inline int sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp) { -- cgit v1.2.3 From 62e877b893e6350c900d381f353aa62ed48dcc97 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 1 Mar 2010 20:38:36 +1100 Subject: sysfs: fix for thinko with sysfs_bin_attr_init() After merging the final tree, today's linux-next build (powerpc allyesconfig) failed like this: drivers/pci/pci-sysfs.c: In function 'pci_create_legacy_files': drivers/pci/pci-sysfs.c:645: error: lvalue required as unary '&' operand drivers/pci/pci-sysfs.c:658: error: lvalue required as unary '&' operand Caused by commit "sysfs: Use sysfs_attr_init and sysfs_bin_attr_init on dynamic attributes" interacting with commit "sysfs: Use one lockdep class per sysfs attribute") both from the driver-core tree. Signed-off-by: Stephen Rothwell Cc: "Eric W. Biederman" Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci-sysfs.c | 4 ++-- include/linux/sysfs.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 9fa183cfb0e9..de296452c957 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -642,7 +642,7 @@ void pci_create_legacy_files(struct pci_bus *b) if (!b->legacy_io) goto kzalloc_err; - sysfs_bin_attr_init(&b->legacy_io); + sysfs_bin_attr_init(b->legacy_io); b->legacy_io->attr.name = "legacy_io"; b->legacy_io->size = 0xffff; b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; @@ -655,7 +655,7 @@ void pci_create_legacy_files(struct pci_bus *b) goto legacy_io_err; /* Allocated above after the legacy_io struct */ - sysfs_bin_attr_init(&b->legacy_mem); + sysfs_bin_attr_init(b->legacy_mem); b->legacy_mem = b->legacy_io + 1; b->legacy_mem->attr.name = "legacy_mem"; b->legacy_mem->size = 1024*1024; diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index d77cde6d0498..f0496b3d1811 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -110,7 +110,7 @@ struct bin_attribute { * enabled. Lockdep gives a nice error when your attribute is * added to sysfs if you don't have this. */ -#define sysfs_bin_attr_init(bin_attr) sysfs_attr_init(&bin_attr->attr) +#define sysfs_bin_attr_init(bin_attr) sysfs_attr_init(&(bin_attr)->attr) struct sysfs_ops { ssize_t (*show)(struct kobject *, struct attribute *,char *); -- cgit v1.2.3 From 8e9394ce2412254ec69fd2a4f3e44a66eade2297 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 17 Feb 2010 10:57:05 -0800 Subject: Driver core: create lock/unlock functions for struct device In the future, we are going to be changing the lock type for struct device (once we get the lockdep infrastructure properly worked out) To make that changeover easier, and to possibly burry the lock in a different part of struct device, let's create some functions to lock and unlock a device so that no out-of-core code needs to be changed in the future. This patch creates the device_lock/unlock/trylock() functions, and converts all in-tree users to them. Cc: Thomas Gleixner Cc: Jean Delvare Cc: Dave Young Cc: Ming Lei Cc: Jiri Kosina Cc: Phil Carmody Cc: Arjan van de Ven Cc: Cornelia Huck Cc: Rafael J. Wysocki Cc: Pavel Machek Cc: Len Brown Cc: Magnus Damm Cc: Alan Stern Cc: Randy Dunlap Cc: Stefan Richter Cc: David Brownell Cc: Vegard Nossum Cc: Jesse Barnes Cc: Alex Chiang Cc: Kenji Kaneshige Cc: Andrew Morton Cc: Andrew Patterson Cc: Yu Zhao Cc: Dominik Brodowski Cc: Samuel Ortiz Cc: Wolfram Sang Cc: CHENG Renquan Cc: Oliver Neukum Cc: Frans Pop Cc: David Vrabel Cc: Kay Sievers Cc: Sarah Sharp Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 20 ++++++++++---------- drivers/base/dd.c | 38 +++++++++++++++++++------------------- drivers/base/power/main.c | 20 ++++++++++---------- drivers/firewire/core-device.c | 5 ++--- drivers/ieee1394/nodemgr.c | 5 ++--- drivers/pci/bus.c | 4 ++-- drivers/pci/pci.c | 4 ++-- drivers/pcmcia/ds.c | 8 ++++---- drivers/usb/core/driver.c | 4 ++-- drivers/uwb/umc-bus.c | 4 ++-- drivers/uwb/uwb-internal.h | 4 ++-- include/linux/device.h | 17 ++++++++++++++++- include/linux/usb.h | 6 +++--- 13 files changed, 76 insertions(+), 63 deletions(-) (limited to 'include') diff --git a/drivers/base/bus.c b/drivers/base/bus.c index cca1aa10054c..71f6af5c8b0b 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -173,10 +173,10 @@ static ssize_t driver_unbind(struct device_driver *drv, dev = bus_find_device_by_name(bus, NULL, buf); if (dev && dev->driver == drv) { if (dev->parent) /* Needed for USB */ - down(&dev->parent->sem); + device_lock(dev->parent); device_release_driver(dev); if (dev->parent) - up(&dev->parent->sem); + device_unlock(dev->parent); err = count; } put_device(dev); @@ -200,12 +200,12 @@ static ssize_t driver_bind(struct device_driver *drv, dev = bus_find_device_by_name(bus, NULL, buf); if (dev && dev->driver == NULL && driver_match_device(drv, dev)) { if (dev->parent) /* Needed for USB */ - down(&dev->parent->sem); - down(&dev->sem); + device_lock(dev->parent); + device_lock(dev); err = driver_probe_device(drv, dev); - up(&dev->sem); + device_unlock(dev); if (dev->parent) - up(&dev->parent->sem); + device_unlock(dev->parent); if (err > 0) { /* success */ @@ -744,10 +744,10 @@ static int __must_check bus_rescan_devices_helper(struct device *dev, if (!dev->driver) { if (dev->parent) /* Needed for USB */ - down(&dev->parent->sem); + device_lock(dev->parent); ret = device_attach(dev); if (dev->parent) - up(&dev->parent->sem); + device_unlock(dev->parent); } return ret < 0 ? ret : 0; } @@ -779,10 +779,10 @@ int device_reprobe(struct device *dev) { if (dev->driver) { if (dev->parent) /* Needed for USB */ - down(&dev->parent->sem); + device_lock(dev->parent); device_release_driver(dev); if (dev->parent) - up(&dev->parent->sem); + device_unlock(dev->parent); } return bus_rescan_devices_helper(dev, NULL); } diff --git a/drivers/base/dd.c b/drivers/base/dd.c index ee95c76bfd3d..c89291f8a16b 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -85,7 +85,7 @@ static void driver_sysfs_remove(struct device *dev) * for before calling this. (It is ok to call with no other effort * from a driver's probe() method.) * - * This function must be called with @dev->sem held. + * This function must be called with the device lock held. */ int device_bind_driver(struct device *dev) { @@ -190,8 +190,8 @@ EXPORT_SYMBOL_GPL(wait_for_device_probe); * This function returns -ENODEV if the device is not registered, * 1 if the device is bound successfully and 0 otherwise. * - * This function must be called with @dev->sem held. When called for a - * USB interface, @dev->parent->sem must be held as well. + * This function must be called with @dev lock held. When called for a + * USB interface, @dev->parent lock must be held as well. */ int driver_probe_device(struct device_driver *drv, struct device *dev) { @@ -233,13 +233,13 @@ static int __device_attach(struct device_driver *drv, void *data) * 0 if no matching driver was found; * -ENODEV if the device is not registered. * - * When called for a USB interface, @dev->parent->sem must be held. + * When called for a USB interface, @dev->parent lock must be held. */ int device_attach(struct device *dev) { int ret = 0; - down(&dev->sem); + device_lock(dev); if (dev->driver) { ret = device_bind_driver(dev); if (ret == 0) @@ -253,7 +253,7 @@ int device_attach(struct device *dev) ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); pm_runtime_put_sync(dev); } - up(&dev->sem); + device_unlock(dev); return ret; } EXPORT_SYMBOL_GPL(device_attach); @@ -276,13 +276,13 @@ static int __driver_attach(struct device *dev, void *data) return 0; if (dev->parent) /* Needed for USB */ - down(&dev->parent->sem); - down(&dev->sem); + device_lock(dev->parent); + device_lock(dev); if (!dev->driver) driver_probe_device(drv, dev); - up(&dev->sem); + device_unlock(dev); if (dev->parent) - up(&dev->parent->sem); + device_unlock(dev->parent); return 0; } @@ -303,8 +303,8 @@ int driver_attach(struct device_driver *drv) EXPORT_SYMBOL_GPL(driver_attach); /* - * __device_release_driver() must be called with @dev->sem held. - * When called for a USB interface, @dev->parent->sem must be held as well. + * __device_release_driver() must be called with @dev lock held. + * When called for a USB interface, @dev->parent lock must be held as well. */ static void __device_release_driver(struct device *dev) { @@ -343,7 +343,7 @@ static void __device_release_driver(struct device *dev) * @dev: device. * * Manually detach device from driver. - * When called for a USB interface, @dev->parent->sem must be held. + * When called for a USB interface, @dev->parent lock must be held. */ void device_release_driver(struct device *dev) { @@ -352,9 +352,9 @@ void device_release_driver(struct device *dev) * within their ->remove callback for the same device, they * will deadlock right here. */ - down(&dev->sem); + device_lock(dev); __device_release_driver(dev); - up(&dev->sem); + device_unlock(dev); } EXPORT_SYMBOL_GPL(device_release_driver); @@ -381,13 +381,13 @@ void driver_detach(struct device_driver *drv) spin_unlock(&drv->p->klist_devices.k_lock); if (dev->parent) /* Needed for USB */ - down(&dev->parent->sem); - down(&dev->sem); + device_lock(dev->parent); + device_lock(dev); if (dev->driver == drv) __device_release_driver(dev); - up(&dev->sem); + device_unlock(dev); if (dev->parent) - up(&dev->parent->sem); + device_unlock(dev->parent); put_device(dev); } } diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 0e26a6f6fd48..d477f4dc5e51 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -35,8 +35,8 @@ * because children are guaranteed to be discovered after parents, and * are inserted at the back of the list on discovery. * - * Since device_pm_add() may be called with a device semaphore held, - * we must never try to acquire a device semaphore while holding + * Since device_pm_add() may be called with a device lock held, + * we must never try to acquire a device lock while holding * dpm_list_mutex. */ @@ -508,7 +508,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) TRACE_RESUME(0); dpm_wait(dev->parent, async); - down(&dev->sem); + device_lock(dev); dev->power.status = DPM_RESUMING; @@ -543,7 +543,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) } } End: - up(&dev->sem); + device_unlock(dev); complete_all(&dev->power.completion); TRACE_RESUME(error); @@ -629,7 +629,7 @@ static void dpm_resume(pm_message_t state) */ static void device_complete(struct device *dev, pm_message_t state) { - down(&dev->sem); + device_lock(dev); if (dev->class && dev->class->pm && dev->class->pm->complete) { pm_dev_dbg(dev, state, "completing class "); @@ -646,7 +646,7 @@ static void device_complete(struct device *dev, pm_message_t state) dev->bus->pm->complete(dev); } - up(&dev->sem); + device_unlock(dev); } /** @@ -809,7 +809,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) int error = 0; dpm_wait_for_children(dev, async); - down(&dev->sem); + device_lock(dev); if (async_error) goto End; @@ -849,7 +849,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) dev->power.status = DPM_OFF; End: - up(&dev->sem); + device_unlock(dev); complete_all(&dev->power.completion); return error; @@ -938,7 +938,7 @@ static int device_prepare(struct device *dev, pm_message_t state) { int error = 0; - down(&dev->sem); + device_lock(dev); if (dev->bus && dev->bus->pm && dev->bus->pm->prepare) { pm_dev_dbg(dev, state, "preparing "); @@ -962,7 +962,7 @@ static int device_prepare(struct device *dev, pm_message_t state) suspend_report_result(dev->class->pm->prepare, error); } End: - up(&dev->sem); + device_unlock(dev); return error; } diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 014cabd3afda..5db0518c66da 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -828,9 +827,9 @@ static int update_unit(struct device *dev, void *data) struct fw_driver *driver = (struct fw_driver *)dev->driver; if (is_fw_unit(dev) && driver != NULL && driver->update != NULL) { - down(&dev->sem); + device_lock(dev); driver->update(unit); - up(&dev->sem); + device_unlock(dev); } return 0; diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 5122b5a8aa2d..18350213479e 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include "csr.h" @@ -1397,9 +1396,9 @@ static int update_pdrv(struct device *dev, void *data) pdrv = container_of(drv, struct hpsb_protocol_driver, driver); if (pdrv->update) { - down(&ud->device.sem); + device_lock(&ud->device); error = pdrv->update(ud); - up(&ud->device.sem); + device_unlock(&ud->device); } if (error) device_release_driver(&ud->device); diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 712250f5874a..26301cb25e7f 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -288,9 +288,9 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), next = dev->bus_list.next; /* Run device routines with the device locked */ - down(&dev->dev.sem); + device_lock(&dev->dev); retval = cb(dev, userdata); - up(&dev->dev.sem); + device_unlock(&dev->dev); if (retval) break; } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 77b493b3d97b..897fa5ccdb78 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2486,7 +2486,7 @@ static int pci_dev_reset(struct pci_dev *dev, int probe) if (!probe) { pci_block_user_cfg_access(dev); /* block PM suspend, driver probe, etc. */ - down(&dev->dev.sem); + device_lock(&dev->dev); } rc = pci_dev_specific_reset(dev, probe); @@ -2508,7 +2508,7 @@ static int pci_dev_reset(struct pci_dev *dev, int probe) rc = pci_parent_bus_reset(dev, probe); done: if (!probe) { - up(&dev->dev.sem); + device_unlock(&dev->dev); pci_unblock_user_cfg_access(dev); } diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 0f98be4450b7..ad93ebd7b2a2 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -971,9 +971,9 @@ static int runtime_suspend(struct device *dev) { int rc; - down(&dev->sem); + device_lock(dev); rc = pcmcia_dev_suspend(dev, PMSG_SUSPEND); - up(&dev->sem); + device_unlock(dev); return rc; } @@ -981,9 +981,9 @@ static int runtime_resume(struct device *dev) { int rc; - down(&dev->sem); + device_lock(dev); rc = pcmcia_dev_resume(dev); - up(&dev->sem); + device_unlock(dev); return rc; } diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index a7037bf81688..f3c233806fa3 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -489,10 +489,10 @@ void usb_driver_release_interface(struct usb_driver *driver, if (device_is_registered(dev)) { device_release_driver(dev); } else { - down(&dev->sem); + device_lock(dev); usb_unbind_interface(dev); dev->driver = NULL; - up(&dev->sem); + device_unlock(dev); } } EXPORT_SYMBOL_GPL(usb_driver_release_interface); diff --git a/drivers/uwb/umc-bus.c b/drivers/uwb/umc-bus.c index cdd6c8efc9f8..5fad4e791b3e 100644 --- a/drivers/uwb/umc-bus.c +++ b/drivers/uwb/umc-bus.c @@ -62,12 +62,12 @@ int umc_controller_reset(struct umc_dev *umc) struct device *parent = umc->dev.parent; int ret = 0; - if(down_trylock(&parent->sem)) + if (device_trylock(parent)) return -EAGAIN; ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper); if (ret >= 0) ret = device_for_each_child(parent, parent, umc_bus_post_reset_helper); - up(&parent->sem); + device_unlock(parent); return ret; } diff --git a/drivers/uwb/uwb-internal.h b/drivers/uwb/uwb-internal.h index d5bcfc1c227a..157485c862c0 100644 --- a/drivers/uwb/uwb-internal.h +++ b/drivers/uwb/uwb-internal.h @@ -366,12 +366,12 @@ struct dentry *uwb_dbg_create_pal_dir(struct uwb_pal *pal); static inline void uwb_dev_lock(struct uwb_dev *uwb_dev) { - down(&uwb_dev->dev.sem); + device_lock(&uwb_dev->dev); } static inline void uwb_dev_unlock(struct uwb_dev *uwb_dev) { - up(&uwb_dev->dev.sem); + device_unlock(&uwb_dev->dev); } #endif /* #ifndef __UWB_INTERNAL_H__ */ diff --git a/include/linux/device.h b/include/linux/device.h index f95d5bfe8248..182192892d45 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -106,7 +106,7 @@ extern int bus_unregister_notifier(struct bus_type *bus, /* All 4 notifers below get called with the target struct device * * as an argument. Note that those functions are likely to be called - * with the device semaphore held in the core, so be careful. + * with the device lock held in the core, so be careful. */ #define BUS_NOTIFY_ADD_DEVICE 0x00000001 /* device added */ #define BUS_NOTIFY_DEL_DEVICE 0x00000002 /* device removed */ @@ -508,6 +508,21 @@ static inline bool device_async_suspend_enabled(struct device *dev) return !!dev->power.async_suspend; } +static inline void device_lock(struct device *dev) +{ + down(&dev->sem); +} + +static inline int device_trylock(struct device *dev) +{ + return down_trylock(&dev->sem); +} + +static inline void device_unlock(struct device *dev) +{ + up(&dev->sem); +} + void driver_init(void); /* diff --git a/include/linux/usb.h b/include/linux/usb.h index 3492abf82e75..8c9f053111bb 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -512,9 +512,9 @@ extern struct usb_device *usb_get_dev(struct usb_device *dev); extern void usb_put_dev(struct usb_device *dev); /* USB device locking */ -#define usb_lock_device(udev) down(&(udev)->dev.sem) -#define usb_unlock_device(udev) up(&(udev)->dev.sem) -#define usb_trylock_device(udev) down_trylock(&(udev)->dev.sem) +#define usb_lock_device(udev) device_lock(&(udev)->dev) +#define usb_unlock_device(udev) device_unlock(&(udev)->dev) +#define usb_trylock_device(udev) device_trylock(&(udev)->dev) extern int usb_lock_device_for_reset(struct usb_device *udev, const struct usb_interface *iface); -- cgit v1.2.3