linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] [0/12] SYSFS: Sysfs attribute improvements
@ 2010-01-05 11:47 Andi Kleen
  2010-01-05 11:47 ` [PATCH] [1/12] SYSFS: Pass attribute in sysdev_class attributes show/store Andi Kleen
                   ` (12 more replies)
  0 siblings, 13 replies; 21+ messages in thread
From: Andi Kleen @ 2010-01-05 11:47 UTC (permalink / raw)
  To: linux-kernel, greg


sysdev_class attributes and class attributes do not pass
their own attribute to the low level store/show functions. This means
that itiss not possible to use shared functions for common data,
but each data item had to have its own function. Typically this
lead to ugly and big custom macro cascades in drivers, generating
the store/show functions for each attribute. This leads to 
large code and is ugly.

When the attributes are passed to the callbacks -- like they are for plain
attributes and sysdev attributes -- it's possible to "derive"
own attribute objects that carry some data, use that data and then call into 
shared store/show code.

This patchkit fixes up these callback interfaces to allow to do this. This
involves two tree sweeps for sysdev_class_attributes and class_attributes,
changing them all to accept the new attribute argument.

I tried to convert all users, but was only able to compile test on x86.

All users were converted in a single patch to avoid unbisectable
sections. I didn't put all the individual driver maintainers in cc,
they probably wouldn't need to care.

Also I added some utility functions to easier deal with arrays
of attributes. A lot of users define multiple attributes and had
to open code array handling for this. Add new sysfs interfaces
to handle the arrays directly. sysdev classes now can just
directly carry their own attributes, similar to normal classes.

Then the CPU and the NODE driver in drivers/base serve as a poster
child for the new facilities and shrink their code dramatically
by using the new facilities.

In addition I added a new string attribute type derived 
from class attributes. This allows various drivers who use
class attributes to export static version strings to just
use a single macro, no custom callbacks.

I didn't convert all drivers over to the new facilities, this
can be done gradually.

-Andi

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH] [1/12] SYSFS: Pass attribute in sysdev_class attributes show/store
  2010-01-05 11:47 [PATCH] [0/12] SYSFS: Sysfs attribute improvements Andi Kleen
@ 2010-01-05 11:47 ` Andi Kleen
  2010-01-05 14:53   ` Greg KH
  2010-01-05 11:47 ` [PATCH] [2/12] SYSFS: Convert node driver class attributes to be data driven Andi Kleen
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 21+ messages in thread
From: Andi Kleen @ 2010-01-05 11:47 UTC (permalink / raw)
  To: linux-kernel, greg


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 <ak@linux.intel.com>

---
 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(-)

Index: linux-2.6.33-rc2-ak/arch/mips/txx9/generic/7segled.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/arch/mips/txx9/generic/7segled.c
+++ linux-2.6.33-rc2-ak/arch/mips/txx9/generic/7segled.c
@@ -58,13 +58,16 @@ static ssize_t raw_store(struct sys_devi
 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))
Index: linux-2.6.33-rc2-ak/arch/s390/kernel/smp.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/arch/s390/kernel/smp.c
+++ linux-2.6.33-rc2-ak/arch/s390/kernel/smp.c
@@ -995,7 +995,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;
@@ -1016,7 +1018,9 @@ static ssize_t dispatching_show(struct s
 	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;
Index: linux-2.6.33-rc2-ak/arch/s390/kernel/time.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/arch/s390/kernel/time.c
+++ linux-2.6.33-rc2-ak/arch/s390/kernel/time.c
@@ -1124,14 +1124,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;
 
@@ -1592,7 +1596,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;
@@ -1602,7 +1608,9 @@ static ssize_t stp_ctn_id_show(struct sy
 
 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;
@@ -1611,7 +1619,9 @@ static ssize_t stp_ctn_type_show(struct
 
 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;
@@ -1620,7 +1630,9 @@ static ssize_t stp_dst_offset_show(struc
 
 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;
@@ -1629,7 +1641,9 @@ static ssize_t stp_leap_seconds_show(str
 
 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;
@@ -1638,7 +1652,9 @@ static ssize_t stp_stratum_show(struct s
 
 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;
@@ -1647,7 +1663,9 @@ static ssize_t stp_time_offset_show(stru
 
 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;
@@ -1657,7 +1675,9 @@ static ssize_t stp_time_zone_offset_show
 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;
@@ -1666,7 +1686,9 @@ static ssize_t stp_timing_mode_show(stru
 
 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;
@@ -1675,12 +1697,15 @@ static ssize_t stp_timing_state_show(str
 
 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;
Index: linux-2.6.33-rc2-ak/drivers/base/cpu.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/base/cpu.c
+++ linux-2.6.33-rc2-ak/drivers/base/cpu.c
@@ -151,7 +151,8 @@ static ssize_t print_cpus_map(char *buf,
 }
 
 #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, 044
 /* 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;
Index: linux-2.6.33-rc2-ak/drivers/base/node.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/base/node.c
+++ linux-2.6.33-rc2-ak/drivers/base/node.c
@@ -544,23 +544,29 @@ static ssize_t print_nodes_state(enum no
 	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,
 
 #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);
 }
Index: linux-2.6.33-rc2-ak/drivers/base/sys.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/base/sys.c
+++ linux-2.6.33-rc2-ak/drivers/base/sys.c
@@ -89,7 +89,7 @@ static ssize_t sysdev_class_show(struct
 	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
 	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;
 }
 
Index: linux-2.6.33-rc2-ak/drivers/cpuidle/sysfs.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/cpuidle/sysfs.c
+++ linux-2.6.33-rc2-ak/drivers/cpuidle/sysfs.c
@@ -22,6 +22,7 @@ static int __init cpuidle_sysfs_setup(ch
 __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(struc
 }
 
 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(str
 }
 
 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];
Index: linux-2.6.33-rc2-ak/include/linux/sysdev.h
===================================================================
--- linux-2.6.33-rc2-ak.orig/include/linux/sysdev.h
+++ linux-2.6.33-rc2-ak/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) 		\
Index: linux-2.6.33-rc2-ak/kernel/perf_event.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/kernel/perf_event.c
+++ linux-2.6.33-rc2-ak/kernel/perf_event.c
@@ -5275,13 +5275,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)
 {
@@ -5310,13 +5313,17 @@ perf_set_reserve_percpu(struct sysdev_cl
 	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;
Index: linux-2.6.33-rc2-ak/kernel/sched.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/kernel/sched.c
+++ linux-2.6.33-rc2-ak/kernel/sched.c
@@ -9199,11 +9199,13 @@ static ssize_t sched_power_savings_store
 
 #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);
@@ -9215,11 +9217,13 @@ static SYSDEV_CLASS_ATTR(sched_mc_power_
 
 #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);

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH] [2/12] SYSFS: Convert node driver class attributes to be data driven
  2010-01-05 11:47 [PATCH] [0/12] SYSFS: Sysfs attribute improvements Andi Kleen
  2010-01-05 11:47 ` [PATCH] [1/12] SYSFS: Pass attribute in sysdev_class attributes show/store Andi Kleen
@ 2010-01-05 11:47 ` Andi Kleen
  2010-01-05 11:48 ` [PATCH] [3/12] SYSDEV: Convert cpu driver sysdev class attributes Andi Kleen
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Andi Kleen @ 2010-01-05 11:47 UTC (permalink / raw)
  To: linux-kernel, greg


Using the new attribute argument convert the node driver class attributes
to carry the node state. Then use a shared function to do what 
a lot of individual functions did before.

Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/base/node.c |   65 ++++++++++++++--------------------------------------
 1 file changed, 18 insertions(+), 47 deletions(-)

Index: linux-2.6.33-rc2-ak/drivers/base/node.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/base/node.c
+++ linux-2.6.33-rc2-ak/drivers/base/node.c
@@ -544,59 +544,29 @@ static ssize_t print_nodes_state(enum no
 	return n;
 }
 
-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,
-				  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,
-					     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,
-				   struct sysdev_class_attribute *attr,
-				   char *buf)
-{
-	return print_nodes_state(N_CPU, buf);
-}
-
-static SYSDEV_CLASS_ATTR(possible, 0444, print_nodes_possible, NULL);
-static SYSDEV_CLASS_ATTR(online, 0444, print_nodes_online, NULL);
-static SYSDEV_CLASS_ATTR(has_normal_memory, 0444, print_nodes_has_normal_memory,
-									NULL);
-static SYSDEV_CLASS_ATTR(has_cpu, 0444, print_nodes_has_cpu, NULL);
+struct node_attr {
+	struct sysdev_class_attribute attr;
+	enum node_states state;
+};
 
-#ifdef CONFIG_HIGHMEM
-static ssize_t print_nodes_has_high_memory(struct sysdev_class *class,
-					   struct sysdev_class_attribute *attr,
-					   char *buf)
+static ssize_t show_node_state(struct sysdev_class *class,
+			       struct sysdev_class_attribute *attr, char *buf)
 {
-	return print_nodes_state(N_HIGH_MEMORY, buf);
+	struct node_attr *na = container_of(attr, struct node_attr, attr);
+	return print_nodes_state(na->state, buf);
 }
 
-static SYSDEV_CLASS_ATTR(has_high_memory, 0444, print_nodes_has_high_memory,
-									 NULL);
-#endif
+#define _NODE_ATTR(name, state) \
+	{ _SYSDEV_CLASS_ATTR(name, 0444, show_node_state, NULL), state }
 
-struct sysdev_class_attribute *node_state_attr[] = {
-	&attr_possible,
-	&attr_online,
-	&attr_has_normal_memory,
+static struct node_attr node_state_attr[] = {
+	_NODE_ATTR(possible, N_POSSIBLE),
+	_NODE_ATTR(online, N_ONLINE),
+	_NODE_ATTR(has_normal_memory, N_NORMAL_MEMORY),
+	_NODE_ATTR(has_cpu, N_CPU),
 #ifdef CONFIG_HIGHMEM
-	&attr_has_high_memory,
+	_NODE_ATTR(has_high_memory, N_HIGH_MEMORY),
 #endif
-	&attr_has_cpu,
 };
 
 static int node_states_init(void)
@@ -604,9 +574,10 @@ static int node_states_init(void)
 	int i;
 	int err = 0;
 
+	BUILD_BUG_ON(ARRAY_SIZE(node_state_attr) != NR_NODE_STATES);
 	for (i = 0;  i < NR_NODE_STATES; i++) {
 		int ret;
-		ret = sysdev_class_create_file(&node_class, node_state_attr[i]);
+		ret = sysdev_class_create_file(&node_class, &node_state_attr[i].attr);
 		if (!err)
 			err = ret;
 	}

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH] [3/12] SYSDEV: Convert cpu driver sysdev class attributes
  2010-01-05 11:47 [PATCH] [0/12] SYSFS: Sysfs attribute improvements Andi Kleen
  2010-01-05 11:47 ` [PATCH] [1/12] SYSFS: Pass attribute in sysdev_class attributes show/store Andi Kleen
  2010-01-05 11:47 ` [PATCH] [2/12] SYSFS: Convert node driver class attributes to be data driven Andi Kleen
@ 2010-01-05 11:48 ` Andi Kleen
  2010-01-05 11:48 ` [PATCH] [4/12] SYSFS: Add sysfs_add/remove_files utility functions Andi Kleen
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Andi Kleen @ 2010-01-05 11:48 UTC (permalink / raw)
  To: linux-kernel, greg


Using the new attribute argument convert the cpu driver class attributes
to carry the node state. Then use a shared function to do what 
a lot of individual functions did before.

This eliminates an ugly macro.

Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/base/cpu.c |   39 ++++++++++++++++++++++-----------------
 1 file changed, 22 insertions(+), 17 deletions(-)

Index: linux-2.6.33-rc2-ak/drivers/base/cpu.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/base/cpu.c
+++ linux-2.6.33-rc2-ak/drivers/base/cpu.c
@@ -141,27 +141,32 @@ static SYSDEV_ATTR(crash_notes, 0400, sh
 /*
  * Print cpu online, possible, present, and system maps
  */
-static ssize_t print_cpus_map(char *buf, const struct cpumask *map)
+
+struct cpu_attr {
+	struct sysdev_class_attribute attr;
+	const struct cpumask *const * const map;
+};
+
+static ssize_t show_cpus_attr(struct sysdev_class *class,
+			      struct sysdev_class_attribute *attr,
+			      char *buf)
 {
-	int n = cpulist_scnprintf(buf, PAGE_SIZE-2, map);
+	struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr);
+	int n = cpulist_scnprintf(buf, PAGE_SIZE-2, *(ca->map));
 
 	buf[n++] = '\n';
 	buf[n] = '\0';
 	return n;
 }
 
-#define	print_cpus_func(type) \
-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);			\
-}									\
-static struct sysdev_class_attribute attr_##type##_map = 		\
-	_SYSDEV_CLASS_ATTR(type, 0444, print_cpus_##type, NULL)
-
-print_cpus_func(online);
-print_cpus_func(possible);
-print_cpus_func(present);
+#define _CPU_ATTR(name, map)						\
+	{ _SYSDEV_CLASS_ATTR(name, 0444, show_cpus_attr, NULL), map }
+
+static struct cpu_attr cpu_attrs[] = {
+	_CPU_ATTR(online, &cpu_online_mask),
+	_CPU_ATTR(possible, &cpu_possible_mask),
+	_CPU_ATTR(present, &cpu_present_mask),
+};
 
 /*
  * Print values for NR_CPUS and offlined cpus
@@ -208,9 +213,9 @@ static ssize_t print_cpus_offline(struct
 static SYSDEV_CLASS_ATTR(offline, 0444, print_cpus_offline, NULL);
 
 static struct sysdev_class_attribute *cpu_state_attr[] = {
-	&attr_online_map,
-	&attr_possible_map,
-	&attr_present_map,
+	&cpu_attrs[0].attr,
+	&cpu_attrs[1].attr,
+	&cpu_attrs[2].attr,
 	&attr_kernel_max,
 	&attr_offline,
 };

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH] [4/12] SYSFS: Add sysfs_add/remove_files utility functions
  2010-01-05 11:47 [PATCH] [0/12] SYSFS: Sysfs attribute improvements Andi Kleen
                   ` (2 preceding siblings ...)
  2010-01-05 11:48 ` [PATCH] [3/12] SYSDEV: Convert cpu driver sysdev class attributes Andi Kleen
@ 2010-01-05 11:48 ` Andi Kleen
  2010-01-05 14:53   ` Greg KH
  2010-01-05 11:48 ` [PATCH] [5/12] SYSFS: Add attribute array to sysdev classes Andi Kleen
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 21+ messages in thread
From: Andi Kleen @ 2010-01-05 11:48 UTC (permalink / raw)
  To: linux-kernel, greg


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 <ak@linux.intel.com>

---
 fs/sysfs/file.c       |   20 ++++++++++++++++++++
 include/linux/sysfs.h |   14 ++++++++++++++
 2 files changed, 34 insertions(+)

Index: linux-2.6.33-rc2-ak/fs/sysfs/file.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/fs/sysfs/file.c
+++ linux-2.6.33-rc2-ak/fs/sysfs/file.c
@@ -542,6 +542,18 @@ int sysfs_create_file(struct kobject * k
 
 }
 
+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 *
 	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_callbac
 
 EXPORT_SYMBOL_GPL(sysfs_create_file);
 EXPORT_SYMBOL_GPL(sysfs_remove_file);
+EXPORT_SYMBOL_GPL(sysfs_remove_files);
+EXPORT_SYMBOL_GPL(sysfs_create_files);
Index: linux-2.6.33-rc2-ak/include/linux/sysfs.h
===================================================================
--- linux-2.6.33-rc2-ak.orig/include/linux/sysfs.h
+++ linux-2.6.33-rc2-ak/include/linux/sysfs.h
@@ -94,9 +94,12 @@ int __must_check sysfs_move_dir(struct k
 
 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(stru
 	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(str
 {
 }
 
+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)
 {

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH] [5/12] SYSFS: Add attribute array to sysdev classes
  2010-01-05 11:47 [PATCH] [0/12] SYSFS: Sysfs attribute improvements Andi Kleen
                   ` (3 preceding siblings ...)
  2010-01-05 11:48 ` [PATCH] [4/12] SYSFS: Add sysfs_add/remove_files utility functions Andi Kleen
@ 2010-01-05 11:48 ` Andi Kleen
  2010-01-05 14:54   ` Greg KH
  2010-01-05 11:48 ` [PATCH] [6/12] SYSDEV: Convert node driver Andi Kleen
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 21+ messages in thread
From: Andi Kleen @ 2010-01-05 11:48 UTC (permalink / raw)
  To: linux-kernel, greg


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 <ak@linux.intel.com>

---
 drivers/base/sys.c     |    9 ++++++++-
 include/linux/sysdev.h |    2 ++
 2 files changed, 10 insertions(+), 1 deletion(-)

Index: linux-2.6.33-rc2-ak/drivers/base/sys.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/base/sys.c
+++ linux-2.6.33-rc2-ak/drivers/base/sys.c
@@ -145,13 +145,20 @@ int sysdev_class_register(struct sysdev_
 	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);
 }
 
Index: linux-2.6.33-rc2-ak/include/linux/sysdev.h
===================================================================
--- linux-2.6.33-rc2-ak.orig/include/linux/sysdev.h
+++ linux-2.6.33-rc2-ak/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 *);

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH] [6/12] SYSDEV: Convert node driver
  2010-01-05 11:47 [PATCH] [0/12] SYSFS: Sysfs attribute improvements Andi Kleen
                   ` (4 preceding siblings ...)
  2010-01-05 11:48 ` [PATCH] [5/12] SYSFS: Add attribute array to sysdev classes Andi Kleen
@ 2010-01-05 11:48 ` Andi Kleen
  2010-01-05 11:48 ` [PATCH] [7/12] SYSDEV: Use sysdev_class attribute arrays in " Andi Kleen
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Andi Kleen @ 2010-01-05 11:48 UTC (permalink / raw)
  To: linux-kernel, greg


Use sysdev_class attribute arrays in node driver

Convert the node driver to sysdev_class attribute arrays. This
greatly cleans up the code and remove a lot of code.

Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/base/cpu.c |   65 ++++++++++++++++-------------------------------------
 1 file changed, 20 insertions(+), 45 deletions(-)

Index: linux-2.6.33-rc2-ak/drivers/base/cpu.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/base/cpu.c
+++ linux-2.6.33-rc2-ak/drivers/base/cpu.c
@@ -13,8 +13,11 @@
 
 #include "base.h"
 
+static struct sysdev_class_attribute *cpu_sysdev_class_attrs[];
+
 struct sysdev_class cpu_sysdev_class = {
 	.name = "cpu",
+	.attrs = cpu_sysdev_class_attrs,
 };
 EXPORT_SYMBOL(cpu_sysdev_class);
 
@@ -90,20 +93,6 @@ static ssize_t cpu_release_store(struct
 
 static CLASS_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
 static CLASS_ATTR(release, S_IWUSR, NULL, cpu_release_store);
-
-int __init cpu_probe_release_init(void)
-{
-	int rc;
-
-	rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
-			       &class_attr_probe.attr);
-	if (!rc)
-		rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
-				       &class_attr_release.attr);
-
-	return rc;
-}
-device_initcall(cpu_probe_release_init);
 #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
 
 #else /* ... !CONFIG_HOTPLUG_CPU */
@@ -162,6 +151,7 @@ static ssize_t show_cpus_attr(struct sys
 #define _CPU_ATTR(name, map)						\
 	{ _SYSDEV_CLASS_ATTR(name, 0444, show_cpus_attr, NULL), map }
 
+/* Keep in sync with cpu_sysdev_class_attrs */
 static struct cpu_attr cpu_attrs[] = {
 	_CPU_ATTR(online, &cpu_online_mask),
 	_CPU_ATTR(possible, &cpu_possible_mask),
@@ -212,29 +202,6 @@ static ssize_t print_cpus_offline(struct
 }
 static SYSDEV_CLASS_ATTR(offline, 0444, print_cpus_offline, NULL);
 
-static struct sysdev_class_attribute *cpu_state_attr[] = {
-	&cpu_attrs[0].attr,
-	&cpu_attrs[1].attr,
-	&cpu_attrs[2].attr,
-	&attr_kernel_max,
-	&attr_offline,
-};
-
-static int cpu_states_init(void)
-{
-	int i;
-	int err = 0;
-
-	for (i = 0;  i < ARRAY_SIZE(cpu_state_attr); i++) {
-		int ret;
-		ret = sysdev_class_create_file(&cpu_sysdev_class,
-						cpu_state_attr[i]);
-		if (!err)
-			err = ret;
-	}
-	return err;
-}
-
 /*
  * register_cpu - Setup a sysfs device for a CPU.
  * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
@@ -280,9 +247,6 @@ int __init cpu_dev_init(void)
 	int err;
 
 	err = sysdev_class_register(&cpu_sysdev_class);
-	if (!err)
-		err = cpu_states_init();
-
 #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
 	if (!err)
 		err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class);
@@ -290,3 +254,16 @@ int __init cpu_dev_init(void)
 
 	return err;
 }
+
+static struct sysdev_class_attribute *cpu_sysdev_class_attrs[] = {
+#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
+	&class_attr_probe.attr,
+	&class_attr_release.attr,
+#endif
+	&cpu_attrs[0].attr,
+	&cpu_attrs[1].attr,
+	&cpu_attrs[2].attr,
+	&attr_kernel_max,
+	&attr_offline,
+	NULL
+};

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH] [7/12] SYSDEV: Use sysdev_class attribute arrays in node driver
  2010-01-05 11:47 [PATCH] [0/12] SYSFS: Sysfs attribute improvements Andi Kleen
                   ` (5 preceding siblings ...)
  2010-01-05 11:48 ` [PATCH] [6/12] SYSDEV: Convert node driver Andi Kleen
@ 2010-01-05 11:48 ` Andi Kleen
  2010-01-05 11:48 ` [PATCH] [8/12] SYSFS: Add sysdev_create/remove_files Andi Kleen
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Andi Kleen @ 2010-01-05 11:48 UTC (permalink / raw)
  To: linux-kernel, greg


Convert the node driver to sysdev_class attribute arrays. This
greatly cleans up the code and remove a lot of code.

Saves ~150 bytes of code on x86-64.

Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/base/node.c |   31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

Index: linux-2.6.33-rc2-ak/drivers/base/node.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/base/node.c
+++ linux-2.6.33-rc2-ak/drivers/base/node.c
@@ -16,8 +16,11 @@
 #include <linux/device.h>
 #include <linux/swap.h>
 
+static struct sysdev_class_attribute *node_state_attrs[];
+
 static struct sysdev_class node_class = {
 	.name = "node",
+	.attrs = node_state_attrs,
 };
 
 
@@ -569,29 +572,27 @@ static struct node_attr node_state_attr[
 #endif
 };
 
-static int node_states_init(void)
-{
-	int i;
-	int err = 0;
-
-	BUILD_BUG_ON(ARRAY_SIZE(node_state_attr) != NR_NODE_STATES);
-	for (i = 0;  i < NR_NODE_STATES; i++) {
-		int ret;
-		ret = sysdev_class_create_file(&node_class, &node_state_attr[i].attr);
-		if (!err)
-			err = ret;
-	}
-	return err;
-}
+static struct sysdev_class_attribute *node_state_attrs[] = {
+	&node_state_attr[0].attr,
+	&node_state_attr[1].attr,
+	&node_state_attr[2].attr,
+	&node_state_attr[3].attr,
+#ifdef CONFIG_HIGHMEM
+	&node_state_attr[4].attr,
+#endif
+	NULL
+};
 
 #define NODE_CALLBACK_PRI	2	/* lower than SLAB */
 static int __init register_node_type(void)
 {
 	int ret;
 
+ 	BUILD_BUG_ON(ARRAY_SIZE(node_state_attr) != NR_NODE_STATES);
+ 	BUILD_BUG_ON(ARRAY_SIZE(node_state_attrs)-1 != NR_NODE_STATES);
+
 	ret = sysdev_class_register(&node_class);
 	if (!ret) {
-		ret = node_states_init();
 		hotplug_memory_notifier(node_memory_callback,
 					NODE_CALLBACK_PRI);
 	}

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH] [8/12] SYSFS: Add sysdev_create/remove_files
  2010-01-05 11:47 [PATCH] [0/12] SYSFS: Sysfs attribute improvements Andi Kleen
                   ` (6 preceding siblings ...)
  2010-01-05 11:48 ` [PATCH] [7/12] SYSDEV: Use sysdev_class attribute arrays in " Andi Kleen
@ 2010-01-05 11:48 ` Andi Kleen
  2010-01-05 11:48 ` [PATCH] [9/12] SYSFS: Fix type of sysdev class attribute in memory driver Andi Kleen
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Andi Kleen @ 2010-01-05 11:48 UTC (permalink / raw)
  To: linux-kernel, greg


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 <ak@linux.intel.com>

---
 include/linux/sysdev.h |   13 +++++++++++++
 1 file changed, 13 insertions(+)

Index: linux-2.6.33-rc2-ak/include/linux/sysdev.h
===================================================================
--- linux-2.6.33-rc2-ak.orig/include/linux/sysdev.h
+++ linux-2.6.33-rc2-ak/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;

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH] [9/12] SYSFS: Fix type of sysdev class attribute in memory driver
  2010-01-05 11:47 [PATCH] [0/12] SYSFS: Sysfs attribute improvements Andi Kleen
                   ` (7 preceding siblings ...)
  2010-01-05 11:48 ` [PATCH] [8/12] SYSFS: Add sysdev_create/remove_files Andi Kleen
@ 2010-01-05 11:48 ` Andi Kleen
  2010-01-05 11:48 ` [PATCH] [10/12] SYSDEV: Add attribute argument to class_attribute show/store Andi Kleen
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Andi Kleen @ 2010-01-05 11:48 UTC (permalink / raw)
  To: linux-kernel, greg


This attribute is really a sysdev_class attribute, not a plain class attribute.

They are identical in layout currently, but this might not always be 
the case.

Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/base/memory.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

Index: linux-2.6.33-rc2-ak/drivers/base/memory.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/base/memory.c
+++ linux-2.6.33-rc2-ak/drivers/base/memory.c
@@ -309,17 +309,18 @@ static SYSDEV_ATTR(removable, 0444, show
  * Block size attribute stuff
  */
 static ssize_t
-print_block_size(struct class *class, char *buf)
+print_block_size(struct sysdev_class *class, struct sysdev_class_attribute *attr,
+		 char *buf)
 {
 	return sprintf(buf, "%lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE);
 }
 
-static CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
+static SYSDEV_CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
 
 static int block_size_init(void)
 {
 	return sysfs_create_file(&memory_sysdev_class.kset.kobj,
-				&class_attr_block_size_bytes.attr);
+				&attr_block_size_bytes.attr);
 }
 
 /*

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH] [10/12] SYSDEV: Add attribute argument to class_attribute show/store
  2010-01-05 11:47 [PATCH] [0/12] SYSFS: Sysfs attribute improvements Andi Kleen
                   ` (8 preceding siblings ...)
  2010-01-05 11:48 ` [PATCH] [9/12] SYSFS: Fix type of sysdev class attribute in memory driver Andi Kleen
@ 2010-01-05 11:48 ` Andi Kleen
  2010-01-05 11:48 ` [PATCH] [11/12] SYSFS: Add class_attr_string for simple read-only string Andi Kleen
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 21+ messages in thread
From: Andi Kleen @ 2010-01-05 11:48 UTC (permalink / raw)
  To: linux-kernel, greg


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 <ak@linux.intel.com>

---
 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(-)

Index: linux-2.6.33-rc2-ak/drivers/base/cpu.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/base/cpu.c
+++ linux-2.6.33-rc2-ak/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);
Index: linux-2.6.33-rc2-ak/drivers/base/firmware_class.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/base/firmware_class.c
+++ linux-2.6.33-rc2-ak/drivers/base/firmware_class.c
@@ -69,7 +69,9 @@ fw_load_abort(struct firmware_priv *fw_p
 }
 
 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 *clas
  *	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)
Index: linux-2.6.33-rc2-ak/drivers/base/memory.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/base/memory.c
+++ linux-2.6.33-rc2-ak/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 *cl
 
 /* 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;
Index: linux-2.6.33-rc2-ak/include/linux/device.h
===================================================================
--- linux-2.6.33-rc2-ak.orig/include/linux/device.h
+++ linux-2.6.33-rc2-ak/include/linux/device.h
@@ -251,8 +251,10 @@ extern struct device *class_find_device(
 
 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)			\
Index: linux-2.6.33-rc2-ak/drivers/gpu/drm/drm_sysfs.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/gpu/drm/drm_sysfs.c
+++ linux-2.6.33-rc2-ak/drivers/gpu/drm/drm_sysfs.c
@@ -71,7 +71,8 @@ static int drm_class_resume(struct devic
 }
 
 /* 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);
Index: linux-2.6.33-rc2-ak/drivers/infiniband/core/ucm.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/infiniband/core/ucm.c
+++ linux-2.6.33-rc2-ak/drivers/infiniband/core/ucm.c
@@ -1297,7 +1297,9 @@ static void ib_ucm_remove_one(struct ib_
 	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);
 }
Index: linux-2.6.33-rc2-ak/drivers/infiniband/core/user_mad.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/infiniband/core/user_mad.c
+++ linux-2.6.33-rc2-ak/drivers/infiniband/core/user_mad.c
@@ -984,7 +984,9 @@ static ssize_t show_port(struct device *
 }
 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);
 }
Index: linux-2.6.33-rc2-ak/drivers/infiniband/core/uverbs_main.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/infiniband/core/uverbs_main.c
+++ linux-2.6.33-rc2-ak/drivers/infiniband/core/uverbs_main.c
@@ -729,7 +729,9 @@ static ssize_t show_dev_abi_version(stru
 }
 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);
 }
Index: linux-2.6.33-rc2-ak/drivers/misc/phantom.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/misc/phantom.c
+++ linux-2.6.33-rc2-ak/drivers/misc/phantom.c
@@ -497,7 +497,7 @@ static struct pci_driver phantom_pci_dri
 	.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");
 }
Index: linux-2.6.33-rc2-ak/drivers/net/bonding/bond_sysfs.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/net/bonding/bond_sysfs.c
+++ linux-2.6.33-rc2-ak/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_na
  */
 
 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;
Index: linux-2.6.33-rc2-ak/drivers/staging/asus_oled/asus_oled.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/staging/asus_oled/asus_oled.c
+++ linux-2.6.33-rc2-ak/drivers/staging/asus_oled/asus_oled.c
@@ -755,7 +755,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);
Index: linux-2.6.33-rc2-ak/net/bluetooth/l2cap.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/net/bluetooth/l2cap.c
+++ linux-2.6.33-rc2-ak/net/bluetooth/l2cap.c
@@ -3939,7 +3939,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;
Index: linux-2.6.33-rc2-ak/net/bluetooth/sco.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/net/bluetooth/sco.c
+++ linux-2.6.33-rc2-ak/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;
Index: linux-2.6.33-rc2-ak/drivers/base/class.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/base/class.c
+++ linux-2.6.33-rc2-ak/drivers/base/class.c
@@ -31,7 +31,7 @@ static ssize_t class_attr_show(struct ko
 	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 k
 	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;
 }
 
Index: linux-2.6.33-rc2-ak/drivers/block/osdblk.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/block/osdblk.c
+++ linux-2.6.33-rc2-ak/drivers/block/osdblk.c
@@ -476,7 +476,9 @@ static void class_osdblk_release(struct
 	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
 	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;
Index: linux-2.6.33-rc2-ak/drivers/block/pktcdvd.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/block/pktcdvd.c
+++ linux-2.6.33-rc2-ak/drivers/block/pktcdvd.c
@@ -337,7 +337,9 @@ static void class_pktcdvd_release(struct
 {
 	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(st
 	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(s
 	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;
Index: linux-2.6.33-rc2-ak/drivers/gpio/gpiolib.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/gpio/gpiolib.c
+++ linux-2.6.33-rc2-ak/drivers/gpio/gpiolib.c
@@ -623,7 +623,9 @@ static const struct attribute_group gpio
  * /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;
Index: linux-2.6.33-rc2-ak/drivers/mtd/ubi/build.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/mtd/ubi/build.c
+++ linux-2.6.33-rc2-ak/drivers/mtd/ubi/build.c
@@ -87,7 +87,8 @@ DEFINE_MUTEX(ubi_devices_mutex);
 static DEFINE_SPINLOCK(ubi_devices_lock);
 
 /* "Show" method for files in '/<sysfs>/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);
 }
Index: linux-2.6.33-rc2-ak/drivers/uwb/driver.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/uwb/driver.c
+++ linux-2.6.33-rc2-ak/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;
Index: linux-2.6.33-rc2-ak/net/bluetooth/rfcomm/core.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/net/bluetooth/rfcomm/core.c
+++ linux-2.6.33-rc2-ak/net/bluetooth/rfcomm/core.c
@@ -2094,7 +2094,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;
Index: linux-2.6.33-rc2-ak/net/bluetooth/rfcomm/sock.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/net/bluetooth/rfcomm/sock.c
+++ linux-2.6.33-rc2-ak/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;

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH] [11/12] SYSFS: Add class_attr_string for simple read-only string
  2010-01-05 11:47 [PATCH] [0/12] SYSFS: Sysfs attribute improvements Andi Kleen
                   ` (9 preceding siblings ...)
  2010-01-05 11:48 ` [PATCH] [10/12] SYSDEV: Add attribute argument to class_attribute show/store Andi Kleen
@ 2010-01-05 11:48 ` Andi Kleen
  2010-01-05 11:48 ` [PATCH] [12/12] SYSFS: Convert some drivers to CLASS_ATTR_STRING Andi Kleen
  2010-01-05 14:55 ` [PATCH] [0/12] SYSFS: Sysfs attribute improvements Greg KH
  12 siblings, 0 replies; 21+ messages in thread
From: Andi Kleen @ 2010-01-05 11:48 UTC (permalink / raw)
  To: linux-kernel, greg


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 <ak@linux.intel.com>

---
 drivers/base/class.c   |   10 ++++++++++
 include/linux/device.h |   17 +++++++++++++++++
 2 files changed, 27 insertions(+)

Index: linux-2.6.33-rc2-ak/drivers/base/class.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/base/class.c
+++ linux-2.6.33-rc2-ak/drivers/base/class.c
@@ -488,6 +488,16 @@ void class_interface_unregister(struct c
 	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;
 };
Index: linux-2.6.33-rc2-ak/include/linux/device.h
===================================================================
--- linux-2.6.33-rc2-ak.orig/include/linux/device.h
+++ linux-2.6.33-rc2-ak/include/linux/device.h
@@ -265,6 +265,23 @@ extern int __must_check class_create_fil
 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;

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH] [12/12] SYSFS: Convert some drivers to CLASS_ATTR_STRING
  2010-01-05 11:47 [PATCH] [0/12] SYSFS: Sysfs attribute improvements Andi Kleen
                   ` (10 preceding siblings ...)
  2010-01-05 11:48 ` [PATCH] [11/12] SYSFS: Add class_attr_string for simple read-only string Andi Kleen
@ 2010-01-05 11:48 ` Andi Kleen
  2010-01-05 14:55 ` [PATCH] [0/12] SYSFS: Sysfs attribute improvements Greg KH
  12 siblings, 0 replies; 21+ messages in thread
From: Andi Kleen @ 2010-01-05 11:48 UTC (permalink / raw)
  To: linux-kernel, greg


Convert some drivers who export a single string as class attribute
to the new class_attr_string functions. This removes redundant
code all over.

Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 drivers/gpu/drm/drm_sysfs.c           |   19 ++++++++-----------
 drivers/infiniband/core/ucm.c         |   15 +++++----------
 drivers/infiniband/core/user_mad.c    |   11 +++--------
 drivers/infiniband/core/uverbs_main.c |   11 +++--------
 drivers/misc/phantom.c                |   13 ++++---------
 drivers/staging/asus_oled/asus_oled.c |   13 +++----------
 6 files changed, 26 insertions(+), 56 deletions(-)

Index: linux-2.6.33-rc2-ak/drivers/infiniband/core/ucm.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/infiniband/core/ucm.c
+++ linux-2.6.33-rc2-ak/drivers/infiniband/core/ucm.c
@@ -1297,13 +1297,8 @@ static void ib_ucm_remove_one(struct ib_
 	device_unregister(&ucm_dev->dev);
 }
 
-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);
-}
-static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
+static CLASS_ATTR_STRING(abi_version, S_IRUGO,
+			 __stringify(IB_USER_CM_ABI_VERSION));
 
 static int __init ib_ucm_init(void)
 {
@@ -1316,7 +1311,7 @@ static int __init ib_ucm_init(void)
 		goto error1;
 	}
 
-	ret = class_create_file(&cm_class, &class_attr_abi_version);
+	ret = class_create_file(&cm_class, &class_attr_abi_version.attr);
 	if (ret) {
 		printk(KERN_ERR "ucm: couldn't create abi_version attribute\n");
 		goto error2;
@@ -1330,7 +1325,7 @@ static int __init ib_ucm_init(void)
 	return 0;
 
 error3:
-	class_remove_file(&cm_class, &class_attr_abi_version);
+	class_remove_file(&cm_class, &class_attr_abi_version.attr);
 error2:
 	unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES);
 error1:
@@ -1340,7 +1335,7 @@ error1:
 static void __exit ib_ucm_cleanup(void)
 {
 	ib_unregister_client(&ucm_client);
-	class_remove_file(&cm_class, &class_attr_abi_version);
+	class_remove_file(&cm_class, &class_attr_abi_version.attr);
 	unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES);
 	idr_destroy(&ctx_id_table);
 }
Index: linux-2.6.33-rc2-ak/drivers/infiniband/core/user_mad.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/infiniband/core/user_mad.c
+++ linux-2.6.33-rc2-ak/drivers/infiniband/core/user_mad.c
@@ -984,13 +984,8 @@ static ssize_t show_port(struct device *
 }
 static DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
 
-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);
-}
-static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
+static CLASS_ATTR_STRING(abi_version, S_IRUGO,
+			 __stringify(IB_USER_MAD_ABI_VERSION));
 
 static int ib_umad_init_port(struct ib_device *device, int port_num,
 			     struct ib_umad_port *port)
@@ -1187,7 +1182,7 @@ static int __init ib_umad_init(void)
 		goto out_chrdev;
 	}
 
-	ret = class_create_file(umad_class, &class_attr_abi_version);
+	ret = class_create_file(umad_class, &class_attr_abi_version.attr);
 	if (ret) {
 		printk(KERN_ERR "user_mad: couldn't create abi_version attribute\n");
 		goto out_class;
Index: linux-2.6.33-rc2-ak/drivers/infiniband/core/uverbs_main.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/infiniband/core/uverbs_main.c
+++ linux-2.6.33-rc2-ak/drivers/infiniband/core/uverbs_main.c
@@ -729,13 +729,8 @@ static ssize_t show_dev_abi_version(stru
 }
 static DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL);
 
-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);
-}
-static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
+static CLASS_ATTR_STRING(abi_version, S_IRUGO,
+			 __stringify(IB_USER_VERBS_ABI_VERSION));
 
 static void ib_uverbs_add_one(struct ib_device *device)
 {
@@ -860,7 +855,7 @@ static int __init ib_uverbs_init(void)
 		goto out_chrdev;
 	}
 
-	ret = class_create_file(uverbs_class, &class_attr_abi_version);
+	ret = class_create_file(uverbs_class, &class_attr_abi_version.attr);
 	if (ret) {
 		printk(KERN_ERR "user_verbs: couldn't create abi_version attribute\n");
 		goto out_class;
Index: linux-2.6.33-rc2-ak/drivers/misc/phantom.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/misc/phantom.c
+++ linux-2.6.33-rc2-ak/drivers/misc/phantom.c
@@ -497,12 +497,7 @@ static struct pci_driver phantom_pci_dri
 	.resume = phantom_resume
 };
 
-static ssize_t phantom_show_version(struct class *cls, struct class_attribute *attr, char *buf)
-{
-	return sprintf(buf, PHANTOM_VERSION "\n");
-}
-
-static CLASS_ATTR(version, 0444, phantom_show_version, NULL);
+static CLASS_ATTR_STRING(version, 0444, PHANTOM_VERSION);
 
 static int __init phantom_init(void)
 {
@@ -515,7 +510,7 @@ static int __init phantom_init(void)
 		printk(KERN_ERR "phantom: can't register phantom class\n");
 		goto err;
 	}
-	retval = class_create_file(phantom_class, &class_attr_version);
+	retval = class_create_file(phantom_class, &class_attr_version.attr);
 	if (retval) {
 		printk(KERN_ERR "phantom: can't create sysfs version file\n");
 		goto err_class;
@@ -541,7 +536,7 @@ static int __init phantom_init(void)
 err_unchr:
 	unregister_chrdev_region(dev, PHANTOM_MAX_MINORS);
 err_attr:
-	class_remove_file(phantom_class, &class_attr_version);
+	class_remove_file(phantom_class, &class_attr_version.attr);
 err_class:
 	class_destroy(phantom_class);
 err:
@@ -554,7 +549,7 @@ static void __exit phantom_exit(void)
 
 	unregister_chrdev_region(MKDEV(phantom_major, 0), PHANTOM_MAX_MINORS);
 
-	class_remove_file(phantom_class, &class_attr_version);
+	class_remove_file(phantom_class, &class_attr_version.attr);
 	class_destroy(phantom_class);
 
 	pr_debug("phantom: module successfully removed\n");
Index: linux-2.6.33-rc2-ak/drivers/gpu/drm/drm_sysfs.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/gpu/drm/drm_sysfs.c
+++ linux-2.6.33-rc2-ak/drivers/gpu/drm/drm_sysfs.c
@@ -70,20 +70,17 @@ static int drm_class_resume(struct devic
 	return 0;
 }
 
-/* Display the version of drm_core. This doesn't work right in current design */
-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);
-}
-
 static char *drm_devnode(struct device *dev, mode_t *mode)
 {
 	return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev));
 }
 
-static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
+static CLASS_ATTR_STRING(version, S_IRUGO,
+		CORE_NAME " "
+		__stringify(CORE_MAJOR) "."
+		__stringify(CORE_MINOR) "."
+		__stringify(CORE_PATCHLEVEL) " "
+		CORE_DATE);
 
 /**
  * drm_sysfs_create - create a struct drm_sysfs_class structure
@@ -110,7 +107,7 @@ struct class *drm_sysfs_create(struct mo
 	class->suspend = drm_class_suspend;
 	class->resume = drm_class_resume;
 
-	err = class_create_file(class, &class_attr_version);
+	err = class_create_file(class, &class_attr_version.attr);
 	if (err)
 		goto err_out_class;
 
@@ -133,7 +130,7 @@ void drm_sysfs_destroy(void)
 {
 	if ((drm_class == NULL) || (IS_ERR(drm_class)))
 		return;
-	class_remove_file(drm_class, &class_attr_version);
+	class_remove_file(drm_class, &class_attr_version.attr);
 	class_destroy(drm_class);
 }
 
Index: linux-2.6.33-rc2-ak/drivers/staging/asus_oled/asus_oled.c
===================================================================
--- linux-2.6.33-rc2-ak.orig/drivers/staging/asus_oled/asus_oled.c
+++ linux-2.6.33-rc2-ak/drivers/staging/asus_oled/asus_oled.c
@@ -755,15 +755,8 @@ static struct usb_driver oled_driver = {
 	.id_table =	id_table,
 };
 
-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);
-}
-
-static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
+static CLASS_ATTR_STRING(version, S_IRUGO,
+		 	ASUS_OLED_UNDERSCORE_NAME " " ASUS_OLD_VERSION);
 
 static int __init asus_oled_init(void)
 {
@@ -775,7 +768,7 @@ static int __init asus_oled_init(void)
 		return PTR_ERR(oled_class);
 	}
 
-	retval = class_create_file(oled_class, &class_attr_version);
+	retval = class_create_file(oled_class, &class_attr_version.attr);
 	if (retval) {
 		err("Error creating class version file");
 		goto error;

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] [4/12] SYSFS: Add sysfs_add/remove_files utility functions
  2010-01-05 11:48 ` [PATCH] [4/12] SYSFS: Add sysfs_add/remove_files utility functions Andi Kleen
@ 2010-01-05 14:53   ` Greg KH
  2010-01-05 16:21     ` Andi Kleen
  0 siblings, 1 reply; 21+ messages in thread
From: Greg KH @ 2010-01-05 14:53 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel

On Tue, Jan 05, 2010 at 12:48:01PM +0100, Andi Kleen wrote:
> 
> 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.

Hm, that is what the sysfs_create_group(), sysfs_update_group(), and
sysfs_remove_group() functions are for.  We don't need to add any new
functions that do the same thing, right?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] [1/12] SYSFS: Pass attribute in sysdev_class attributes show/store
  2010-01-05 11:47 ` [PATCH] [1/12] SYSFS: Pass attribute in sysdev_class attributes show/store Andi Kleen
@ 2010-01-05 14:53   ` Greg KH
  0 siblings, 0 replies; 21+ messages in thread
From: Greg KH @ 2010-01-05 14:53 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel

On Tue, Jan 05, 2010 at 12:47:58PM +0100, Andi Kleen wrote:
> 
> 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 <ak@linux.intel.com>

Looks good, I'll queue this up.

greg k-h

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] [5/12] SYSFS: Add attribute array to sysdev classes
  2010-01-05 11:48 ` [PATCH] [5/12] SYSFS: Add attribute array to sysdev classes Andi Kleen
@ 2010-01-05 14:54   ` Greg KH
  2010-01-05 16:24     ` Andi Kleen
  0 siblings, 1 reply; 21+ messages in thread
From: Greg KH @ 2010-01-05 14:54 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel

On Tue, Jan 05, 2010 at 12:48:02PM +0100, Andi Kleen wrote:
> 
> 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. 

I agree, this should be done, but can you use an attribute group
instead, like the driver core does?  That way you don't need the new
function that you created that duplicates that logic :)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] [0/12] SYSFS: Sysfs attribute improvements
  2010-01-05 11:47 [PATCH] [0/12] SYSFS: Sysfs attribute improvements Andi Kleen
                   ` (11 preceding siblings ...)
  2010-01-05 11:48 ` [PATCH] [12/12] SYSFS: Convert some drivers to CLASS_ATTR_STRING Andi Kleen
@ 2010-01-05 14:55 ` Greg KH
  12 siblings, 0 replies; 21+ messages in thread
From: Greg KH @ 2010-01-05 14:55 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel

On Tue, Jan 05, 2010 at 12:47:57PM +0100, Andi Kleen wrote:
> 
> sysdev_class attributes and class attributes do not pass
> their own attribute to the low level store/show functions. This means
> that itiss not possible to use shared functions for common data,
> but each data item had to have its own function. Typically this
> lead to ugly and big custom macro cascades in drivers, generating
> the store/show functions for each attribute. This leads to 
> large code and is ugly.
> 
> When the attributes are passed to the callbacks -- like they are for plain
> attributes and sysdev attributes -- it's possible to "derive"
> own attribute objects that carry some data, use that data and then call into 
> shared store/show code.
> 
> This patchkit fixes up these callback interfaces to allow to do this. This
> involves two tree sweeps for sysdev_class_attributes and class_attributes,
> changing them all to accept the new attribute argument.
> 
> I tried to convert all users, but was only able to compile test on x86.
> 
> All users were converted in a single patch to avoid unbisectable
> sections. I didn't put all the individual driver maintainers in cc,
> they probably wouldn't need to care.
> 
> Also I added some utility functions to easier deal with arrays
> of attributes. A lot of users define multiple attributes and had
> to open code array handling for this. Add new sysfs interfaces
> to handle the arrays directly. sysdev classes now can just
> directly carry their own attributes, similar to normal classes.
> 
> Then the CPU and the NODE driver in drivers/base serve as a poster
> child for the new facilities and shrink their code dramatically
> by using the new facilities.
> 
> In addition I added a new string attribute type derived 
> from class attributes. This allows various drivers who use
> class attributes to export static version strings to just
> use a single macro, no custom callbacks.
> 
> I didn't convert all drivers over to the new facilities, this
> can be done gradually.

I like these changes, thanks for doing the work.  I do have some
comments on some of the patches, they will follow.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] [4/12] SYSFS: Add sysfs_add/remove_files utility functions
  2010-01-05 14:53   ` Greg KH
@ 2010-01-05 16:21     ` Andi Kleen
  2010-01-05 23:20       ` Greg KH
  0 siblings, 1 reply; 21+ messages in thread
From: Andi Kleen @ 2010-01-05 16:21 UTC (permalink / raw)
  To: Greg KH; +Cc: Andi Kleen, linux-kernel

On Tue, Jan 05, 2010 at 06:53:09AM -0800, Greg KH wrote:
> On Tue, Jan 05, 2010 at 12:48:01PM +0100, Andi Kleen wrote:
> > 
> > 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.
> 
> Hm, that is what the sysfs_create_group(), sysfs_update_group(), and
> sysfs_remove_group() functions are for.  We don't need to add any new
> functions that do the same thing, right?

Hmm, originally I didn't use them because they created a sub-directory,
but I see now that's optional.

Still the input format is completely different and doesn't fit into
the ->attrs list that are used elsewhere (e.g. for the sysdev_classes)
So using groups would need a lot of restructuring.

Also similar code as I have is already in a lot of places, which
over time will be converted. So it's definitely less code than
before.

-Andi

-- 
ak@linux.intel.com -- Speaking for myself only.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] [5/12] SYSFS: Add attribute array to sysdev classes
  2010-01-05 14:54   ` Greg KH
@ 2010-01-05 16:24     ` Andi Kleen
  2010-01-05 23:20       ` Greg KH
  0 siblings, 1 reply; 21+ messages in thread
From: Andi Kleen @ 2010-01-05 16:24 UTC (permalink / raw)
  To: Greg KH; +Cc: Andi Kleen, linux-kernel

On Tue, Jan 05, 2010 at 06:54:33AM -0800, Greg KH wrote:
> On Tue, Jan 05, 2010 at 12:48:02PM +0100, Andi Kleen wrote:
> > 
> > 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. 
> 
> I agree, this should be done, but can you use an attribute group
> instead, like the driver core does?  That way you don't need the new
> function that you created that duplicates that logic :)

Actually the attributes use own loops for this too.

In theory could add a group in the middle, but it would greatly complicate
the driver interface for little gain.

In theory the low loops could be shared between the group code
and sysfs_create_files(), but I'm not sure it's really worth
it because it's just a few lines of code (which are currently
duplicated in multiple places anyways, so it's a net-win)

You still want me to attempt that?

-Andi

-- 
ak@linux.intel.com -- Speaking for myself only.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] [4/12] SYSFS: Add sysfs_add/remove_files utility functions
  2010-01-05 16:21     ` Andi Kleen
@ 2010-01-05 23:20       ` Greg KH
  0 siblings, 0 replies; 21+ messages in thread
From: Greg KH @ 2010-01-05 23:20 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel

On Tue, Jan 05, 2010 at 05:21:06PM +0100, Andi Kleen wrote:
> On Tue, Jan 05, 2010 at 06:53:09AM -0800, Greg KH wrote:
> > On Tue, Jan 05, 2010 at 12:48:01PM +0100, Andi Kleen wrote:
> > > 
> > > 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.
> > 
> > Hm, that is what the sysfs_create_group(), sysfs_update_group(), and
> > sysfs_remove_group() functions are for.  We don't need to add any new
> > functions that do the same thing, right?
> 
> Hmm, originally I didn't use them because they created a sub-directory,
> but I see now that's optional.
> 
> Still the input format is completely different and doesn't fit into
> the ->attrs list that are used elsewhere (e.g. for the sysdev_classes)
> So using groups would need a lot of restructuring.

Argh, you are right.

Damm I hate the sysdev code, I need to dig up my "make drivers bind to
multiple devices" tree and get it up to date so we can just delete the
things completly and move to a "real" struct device instead.

> Also similar code as I have is already in a lot of places, which
> over time will be converted. So it's definitely less code than
> before.

Ok, good point, I'll queue this up, and hopefully be able to delete it
all in 6-8 months again :)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] [5/12] SYSFS: Add attribute array to sysdev classes
  2010-01-05 16:24     ` Andi Kleen
@ 2010-01-05 23:20       ` Greg KH
  0 siblings, 0 replies; 21+ messages in thread
From: Greg KH @ 2010-01-05 23:20 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel

On Tue, Jan 05, 2010 at 05:24:51PM +0100, Andi Kleen wrote:
> On Tue, Jan 05, 2010 at 06:54:33AM -0800, Greg KH wrote:
> > On Tue, Jan 05, 2010 at 12:48:02PM +0100, Andi Kleen wrote:
> > > 
> > > 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. 
> > 
> > I agree, this should be done, but can you use an attribute group
> > instead, like the driver core does?  That way you don't need the new
> > function that you created that duplicates that logic :)
> 
> Actually the attributes use own loops for this too.
> 
> In theory could add a group in the middle, but it would greatly complicate
> the driver interface for little gain.
> 
> In theory the low loops could be shared between the group code
> and sysfs_create_files(), but I'm not sure it's really worth
> it because it's just a few lines of code (which are currently
> duplicated in multiple places anyways, so it's a net-win)
> 
> You still want me to attempt that?

For now, nah, that's ok, I'll take this as-is.  But if you want to make
this change in the future, feel free to.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2010-01-05 23:22 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-01-05 11:47 [PATCH] [0/12] SYSFS: Sysfs attribute improvements Andi Kleen
2010-01-05 11:47 ` [PATCH] [1/12] SYSFS: Pass attribute in sysdev_class attributes show/store Andi Kleen
2010-01-05 14:53   ` Greg KH
2010-01-05 11:47 ` [PATCH] [2/12] SYSFS: Convert node driver class attributes to be data driven Andi Kleen
2010-01-05 11:48 ` [PATCH] [3/12] SYSDEV: Convert cpu driver sysdev class attributes Andi Kleen
2010-01-05 11:48 ` [PATCH] [4/12] SYSFS: Add sysfs_add/remove_files utility functions Andi Kleen
2010-01-05 14:53   ` Greg KH
2010-01-05 16:21     ` Andi Kleen
2010-01-05 23:20       ` Greg KH
2010-01-05 11:48 ` [PATCH] [5/12] SYSFS: Add attribute array to sysdev classes Andi Kleen
2010-01-05 14:54   ` Greg KH
2010-01-05 16:24     ` Andi Kleen
2010-01-05 23:20       ` Greg KH
2010-01-05 11:48 ` [PATCH] [6/12] SYSDEV: Convert node driver Andi Kleen
2010-01-05 11:48 ` [PATCH] [7/12] SYSDEV: Use sysdev_class attribute arrays in " Andi Kleen
2010-01-05 11:48 ` [PATCH] [8/12] SYSFS: Add sysdev_create/remove_files Andi Kleen
2010-01-05 11:48 ` [PATCH] [9/12] SYSFS: Fix type of sysdev class attribute in memory driver Andi Kleen
2010-01-05 11:48 ` [PATCH] [10/12] SYSDEV: Add attribute argument to class_attribute show/store Andi Kleen
2010-01-05 11:48 ` [PATCH] [11/12] SYSFS: Add class_attr_string for simple read-only string Andi Kleen
2010-01-05 11:48 ` [PATCH] [12/12] SYSFS: Convert some drivers to CLASS_ATTR_STRING Andi Kleen
2010-01-05 14:55 ` [PATCH] [0/12] SYSFS: Sysfs attribute improvements Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).