aboutsummaryrefslogtreecommitdiffstats
diff options
-rw-r--r--c2port-convert-class-code-to-use-bin_attrs-in-groups.patch77
-rw-r--r--driver-core-add-binary-attributes-to-struct-device.patch30
-rw-r--r--driver-core-add-default-groups-to-struct-class.patch2
-rw-r--r--driver-core-introduce-device_create_groups.patch179
-rw-r--r--driver-core-remove-bin_attrs-from-struct-device.patch59
-rw-r--r--driver-core-remove-dev_attrs-from-struct-class.patch6
-rw-r--r--driver-core-remove-dev_bin_attrs-from-struct-class.patch112
-rw-r--r--hid-roccat-convert-class-code-to-use-bin_attrs-in-groups.patch1081
-rw-r--r--series15
-rw-r--r--sysfs-add-support-for-binary-attributes-in-groups.patch84
-rw-r--r--sysfs.h-add-bin_attr-macro.patch32
11 files changed, 1647 insertions, 30 deletions
diff --git a/c2port-convert-class-code-to-use-bin_attrs-in-groups.patch b/c2port-convert-class-code-to-use-bin_attrs-in-groups.patch
new file mode 100644
index 00000000000000..7d88166ddee850
--- /dev/null
+++ b/c2port-convert-class-code-to-use-bin_attrs-in-groups.patch
@@ -0,0 +1,77 @@
+From foo@baz Wed Jul 10 12:20:53 PDT 2013
+Date: Wed, 10 Jul 2013 12:20:53 -0700
+To: Greg KH <gregkh@linuxfoundation.org>
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Subject: c2port: convert class code to use bin_attrs in groups
+
+Now that attribute groups support binary attributes, use them instead of
+the dev_bin_attrs field in struct class, as that is going away soon.
+
+Cc: Rodolfo Giometti <giometti@linux.it>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/misc/c2port/core.c | 31 +++++++++++++++++--------------
+ 1 file changed, 17 insertions(+), 14 deletions(-)
+
+--- a/drivers/misc/c2port/core.c
++++ b/drivers/misc/c2port/core.c
+@@ -856,6 +856,9 @@ static ssize_t c2port_write_flash_data(s
+
+ return ret;
+ }
++/* size is computed at run-time */
++static BIN_ATTR(flash_data, 0644, c2port_read_flash_data,
++ c2port_write_flash_data, 0);
+
+ /*
+ * Class attributes
+@@ -873,19 +876,20 @@ static struct attribute *c2port_attrs[]
+ &dev_attr_flash_erase.attr,
+ NULL,
+ };
+-ATTRIBUTE_GROUPS(c2port);
+
+-static struct bin_attribute c2port_bin_attrs[] = {
+- {
+- .attr = {
+- .name = "flash_data",
+- .mode = 0644
+- },
+- .read = c2port_read_flash_data,
+- .write = c2port_write_flash_data,
+- /* .size is computed at run-time */
+- },
+- __ATTR_NULL
++static struct bin_attribute *c2port_bin_attrs[] = {
++ &bin_attr_flash_data,
++ NULL,
++};
++
++static const struct attribute_group c2port_group = {
++ .attrs = c2port_attrs,
++ .bin_attrs = c2port_bin_attrs,
++};
++
++static const struct attribute_group *c2port_groups[] = {
++ &c2port_group,
++ NULL,
+ };
+
+ /*
+@@ -918,7 +922,7 @@ struct c2port_device *c2port_device_regi
+ goto error_idr_alloc;
+ c2dev->id = ret;
+
+- c2port_bin_attrs[0].size = ops->blocks_num * ops->block_size;
++ bin_attr_flash_data.size = ops->blocks_num * ops->block_size;
+
+ c2dev->dev = device_create(c2port_class, NULL, 0, c2dev,
+ "c2port%d", c2dev->id);
+@@ -988,7 +992,6 @@ static int __init c2port_init(void)
+ return PTR_ERR(c2port_class);
+ }
+ c2port_class->dev_groups = c2port_groups;
+- c2port_class->dev_bin_attrs = c2port_bin_attrs;
+
+ return 0;
+ }
diff --git a/driver-core-add-binary-attributes-to-struct-device.patch b/driver-core-add-binary-attributes-to-struct-device.patch
index 658a6ccca87939..caf89bac3621ad 100644
--- a/driver-core-add-binary-attributes-to-struct-device.patch
+++ b/driver-core-add-binary-attributes-to-struct-device.patch
@@ -16,31 +16,13 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
- drivers/base/core.c | 11 +++++++++--
+ drivers/base/core.c | 7 +++++++
include/linux/device.h | 2 ++
- 2 files changed, 11 insertions(+), 2 deletions(-)
+ 2 files changed, 9 insertions(+)
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
-@@ -463,7 +463,7 @@ static void device_remove_attributes(str
- }
-
- static int device_add_bin_attributes(struct device *dev,
-- struct bin_attribute *attrs)
-+ const struct bin_attribute *attrs)
- {
- int error = 0;
- int i;
-@@ -482,7 +482,7 @@ static int device_add_bin_attributes(str
- }
-
- static void device_remove_bin_attributes(struct device *dev,
-- struct bin_attribute *attrs)
-+ const struct bin_attribute *attrs)
- {
- int i;
-
-@@ -552,8 +552,14 @@ static int device_add_attrs(struct devic
+@@ -491,8 +491,14 @@ static int device_add_attrs(struct devic
goto err_remove_type_groups;
}
@@ -55,7 +37,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
err_remove_type_groups:
if (type)
device_remove_groups(dev, type->groups);
-@@ -574,6 +580,7 @@ static void device_remove_attrs(struct d
+@@ -510,6 +516,7 @@ static void device_remove_attrs(struct d
device_remove_file(dev, &online_attr);
device_remove_groups(dev, dev->groups);
@@ -65,7 +47,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
device_remove_groups(dev, type->groups);
--- a/include/linux/device.h
+++ b/include/linux/device.h
-@@ -658,6 +658,7 @@ struct acpi_dev_node {
+@@ -656,6 +656,7 @@ struct acpi_dev_node {
* @knode_class: The node used to add the device to the class list.
* @class: The class of the device.
* @groups: Optional attribute groups.
@@ -73,7 +55,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* @release: Callback to free the device after all references have
* gone away. This should be set by the allocator of the
* device (i.e. the bus driver that discovered the device).
-@@ -734,6 +735,7 @@ struct device {
+@@ -732,6 +733,7 @@ struct device {
struct klist_node knode_class;
struct class *class;
const struct attribute_group **groups; /* optional groups */
diff --git a/driver-core-add-default-groups-to-struct-class.patch b/driver-core-add-default-groups-to-struct-class.patch
index 79787cc18472ed..88d2a54a5b77bb 100644
--- a/driver-core-add-default-groups-to-struct-class.patch
+++ b/driver-core-add-default-groups-to-struct-class.patch
@@ -33,7 +33,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
error = device_add_bin_attributes(dev, class->dev_bin_attrs);
if (error)
goto err_remove_class_attrs;
-@@ -569,6 +572,9 @@ static int device_add_attrs(struct devic
+@@ -563,6 +566,9 @@ static int device_add_attrs(struct devic
err_remove_class_attrs:
if (class)
device_remove_attributes(dev, class->dev_attrs);
diff --git a/driver-core-introduce-device_create_groups.patch b/driver-core-introduce-device_create_groups.patch
new file mode 100644
index 00000000000000..5d4a215c4967c1
--- /dev/null
+++ b/driver-core-introduce-device_create_groups.patch
@@ -0,0 +1,179 @@
+From groeck7@gmail.com Sat Jul 6 10:25:17 2013
+From: Guenter Roeck <linux@roeck-us.net>
+Date: Sat, 6 Jul 2013 10:24:51 -0700
+Subject: driver core: Introduce device_create_groups
+To: Jean Delvare <khali@linux-fr.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: lm-sensors@lm-sensors.org, linux-kernel@vger.kernel.org, Guenter Roeck <linux@roeck-us.net>
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+device_create_groups lets callers create devices as well as associated
+sysfs attributes with a single call. This avoids race conditions seen
+if sysfs attributes on new devices are created later.
+
+[fixed up comment block placement and add checks for printk buffer
+formats - gregkh]
+
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Cc: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/core.c | 111 ++++++++++++++++++++++++++++++++++++-------------
+ include/linux/device.h | 5 ++
+ 2 files changed, 88 insertions(+), 28 deletions(-)
+
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -1667,34 +1667,11 @@ static void device_create_release(struct
+ kfree(dev);
+ }
+
+-/**
+- * device_create_vargs - creates a device and registers it with sysfs
+- * @class: pointer to the struct class that this device should be registered to
+- * @parent: pointer to the parent struct device of this new device, if any
+- * @devt: the dev_t for the char device to be added
+- * @drvdata: the data to be added to the device for callbacks
+- * @fmt: string for the device's name
+- * @args: va_list for the device's name
+- *
+- * This function can be used by char device classes. A struct device
+- * will be created in sysfs, registered to the specified class.
+- *
+- * A "dev" file will be created, showing the dev_t for the device, if
+- * the dev_t is not 0,0.
+- * If a pointer to a parent struct device is passed in, the newly created
+- * struct device will be a child of that device in sysfs.
+- * The pointer to the struct device will be returned from the call.
+- * Any further sysfs files that might be required can be created using this
+- * pointer.
+- *
+- * Returns &struct device pointer on success, or ERR_PTR() on error.
+- *
+- * Note: the struct class passed to this function must have previously
+- * been created with a call to class_create().
+- */
+-struct device *device_create_vargs(struct class *class, struct device *parent,
+- dev_t devt, void *drvdata, const char *fmt,
+- va_list args)
++static struct device *
++device_create_groups_vargs(struct class *class, struct device *parent,
++ dev_t devt, void *drvdata,
++ const struct attribute_group **groups,
++ const char *fmt, va_list args)
+ {
+ struct device *dev = NULL;
+ int retval = -ENODEV;
+@@ -1711,6 +1688,7 @@ struct device *device_create_vargs(struc
+ dev->devt = devt;
+ dev->class = class;
+ dev->parent = parent;
++ dev->groups = groups;
+ dev->release = device_create_release;
+ dev_set_drvdata(dev, drvdata);
+
+@@ -1728,6 +1706,39 @@ error:
+ put_device(dev);
+ return ERR_PTR(retval);
+ }
++
++/**
++ * device_create_vargs - creates a device and registers it with sysfs
++ * @class: pointer to the struct class that this device should be registered to
++ * @parent: pointer to the parent struct device of this new device, if any
++ * @devt: the dev_t for the char device to be added
++ * @drvdata: the data to be added to the device for callbacks
++ * @fmt: string for the device's name
++ * @args: va_list for the device's name
++ *
++ * This function can be used by char device classes. A struct device
++ * will be created in sysfs, registered to the specified class.
++ *
++ * A "dev" file will be created, showing the dev_t for the device, if
++ * the dev_t is not 0,0.
++ * If a pointer to a parent struct device is passed in, the newly created
++ * struct device will be a child of that device in sysfs.
++ * The pointer to the struct device will be returned from the call.
++ * Any further sysfs files that might be required can be created using this
++ * pointer.
++ *
++ * Returns &struct device pointer on success, or ERR_PTR() on error.
++ *
++ * Note: the struct class passed to this function must have previously
++ * been created with a call to class_create().
++ */
++struct device *device_create_vargs(struct class *class, struct device *parent,
++ dev_t devt, void *drvdata, const char *fmt,
++ va_list args)
++{
++ return device_create_groups_vargs(class, parent, devt, drvdata, NULL,
++ fmt, args);
++}
+ EXPORT_SYMBOL_GPL(device_create_vargs);
+
+ /**
+@@ -1767,6 +1778,50 @@ struct device *device_create(struct clas
+ }
+ EXPORT_SYMBOL_GPL(device_create);
+
++/**
++ * device_create_with_groups - creates a device and registers it with sysfs
++ * @class: pointer to the struct class that this device should be registered to
++ * @parent: pointer to the parent struct device of this new device, if any
++ * @devt: the dev_t for the char device to be added
++ * @drvdata: the data to be added to the device for callbacks
++ * @groups: NULL-terminated list of attribute groups to be created
++ * @fmt: string for the device's name
++ *
++ * This function can be used by char device classes. A struct device
++ * will be created in sysfs, registered to the specified class.
++ * Additional attributes specified in the groups parameter will also
++ * be created automatically.
++ *
++ * A "dev" file will be created, showing the dev_t for the device, if
++ * the dev_t is not 0,0.
++ * If a pointer to a parent struct device is passed in, the newly created
++ * struct device will be a child of that device in sysfs.
++ * The pointer to the struct device will be returned from the call.
++ * Any further sysfs files that might be required can be created using this
++ * pointer.
++ *
++ * Returns &struct device pointer on success, or ERR_PTR() on error.
++ *
++ * Note: the struct class passed to this function must have previously
++ * been created with a call to class_create().
++ */
++struct device *device_create_with_groups(struct class *class,
++ struct device *parent, dev_t devt,
++ void *drvdata,
++ const struct attribute_group **groups,
++ const char *fmt, ...)
++{
++ va_list vargs;
++ struct device *dev;
++
++ va_start(vargs, fmt);
++ dev = device_create_groups_vargs(class, parent, devt, drvdata, groups,
++ fmt, vargs);
++ va_end(vargs);
++ return dev;
++}
++EXPORT_SYMBOL_GPL(device_create_with_groups);
++
+ static int __match_devt(struct device *dev, const void *data)
+ {
+ const dev_t *devt = data;
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -928,6 +928,11 @@ extern __printf(5, 6)
+ struct device *device_create(struct class *cls, struct device *parent,
+ dev_t devt, void *drvdata,
+ const char *fmt, ...);
++extern __printf(6, 7)
++struct device *device_create_with_groups(struct class *cls,
++ struct device *parent, dev_t devt, void *drvdata,
++ const struct attribute_group **groups,
++ const char *fmt, ...);
+ extern void device_destroy(struct class *cls, dev_t devt);
+
+ /*
diff --git a/driver-core-remove-bin_attrs-from-struct-device.patch b/driver-core-remove-bin_attrs-from-struct-device.patch
new file mode 100644
index 00000000000000..fb15c4c0a7e05f
--- /dev/null
+++ b/driver-core-remove-bin_attrs-from-struct-device.patch
@@ -0,0 +1,59 @@
+From foo@baz Wed Jul 10 11:59:39 PDT 2013
+Date: Wed, 10 Jul 2013 11:59:39 -0700
+To: Greg KH <gregkh@linuxfoundation.org>
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Subject: driver core: remove bin_attrs from struct device
+
+No one is using the bin_attrs field in struct device, and now that you
+can add them properly through an attribute group, it isn't needed
+either, so remove it.
+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/core.c | 7 -------
+ include/linux/device.h | 2 --
+ 2 files changed, 9 deletions(-)
+
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -491,14 +491,8 @@ static int device_add_attrs(struct devic
+ goto err_remove_type_groups;
+ }
+
+- error = device_add_bin_attributes(dev, dev->bin_attrs);
+- if (error)
+- goto err_remove_groups;
+ return 0;
+
+- err_remove_groups:
+- device_remove_groups(dev, dev->groups);
+-
+ err_remove_type_groups:
+ if (type)
+ device_remove_groups(dev, type->groups);
+@@ -516,7 +510,6 @@ static void device_remove_attrs(struct d
+
+ device_remove_file(dev, &online_attr);
+ device_remove_groups(dev, dev->groups);
+- device_remove_bin_attributes(dev, dev->bin_attrs);
+
+ if (type)
+ device_remove_groups(dev, type->groups);
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -656,7 +656,6 @@ struct acpi_dev_node {
+ * @knode_class: The node used to add the device to the class list.
+ * @class: The class of the device.
+ * @groups: Optional attribute groups.
+- * @bin_attrs: Optional binary attributes for this device.
+ * @release: Callback to free the device after all references have
+ * gone away. This should be set by the allocator of the
+ * device (i.e. the bus driver that discovered the device).
+@@ -733,7 +732,6 @@ struct device {
+ struct klist_node knode_class;
+ struct class *class;
+ const struct attribute_group **groups; /* optional groups */
+- const struct bin_attribute *bin_attrs;
+
+ void (*release)(struct device *dev);
+ struct iommu_group *iommu_group;
diff --git a/driver-core-remove-dev_attrs-from-struct-class.patch b/driver-core-remove-dev_attrs-from-struct-class.patch
index a10c3cc1add959..c7fd11f56c0cca 100644
--- a/driver-core-remove-dev_attrs-from-struct-class.patch
+++ b/driver-core-remove-dev_attrs-from-struct-class.patch
@@ -49,7 +49,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-}
-
static int device_add_bin_attributes(struct device *dev,
- const struct bin_attribute *attrs)
+ struct bin_attribute *attrs)
{
@@ -531,12 +502,9 @@ static int device_add_attrs(struct devic
error = device_add_groups(dev, class->dev_groups);
@@ -65,7 +65,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
}
if (type) {
-@@ -569,9 +537,6 @@ static int device_add_attrs(struct devic
+@@ -563,9 +531,6 @@ static int device_add_attrs(struct devic
err_remove_class_bin_attrs:
if (class)
device_remove_bin_attributes(dev, class->dev_bin_attrs);
@@ -75,7 +75,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
err_remove_class_groups:
if (class)
device_remove_groups(dev, class->dev_groups);
-@@ -592,7 +557,7 @@ static void device_remove_attrs(struct d
+@@ -585,7 +550,7 @@ static void device_remove_attrs(struct d
device_remove_groups(dev, type->groups);
if (class) {
diff --git a/driver-core-remove-dev_bin_attrs-from-struct-class.patch b/driver-core-remove-dev_bin_attrs-from-struct-class.patch
new file mode 100644
index 00000000000000..b6b39b19eac62e
--- /dev/null
+++ b/driver-core-remove-dev_bin_attrs-from-struct-class.patch
@@ -0,0 +1,112 @@
+From foo@baz Wed Jul 10 12:18:18 PDT 2013
+Date: Wed, 10 Jul 2013 12:18:18 -0700
+To: Greg KH <gregkh@linuxfoundation.org>
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Subject: driver core: remove dev_bin_attrs from struct class
+
+No in-kernel code is now using this, they have all be converted over to
+using the bin_attrs support in attribute groups, so this field, and the
+code in the driver core that was creating/remove the binary files can be
+removed.
+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/core.c | 41 ++---------------------------------------
+ include/linux/device.h | 2 --
+ 2 files changed, 2 insertions(+), 41 deletions(-)
+
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -433,35 +433,6 @@ static ssize_t store_online(struct devic
+ static struct device_attribute online_attr =
+ __ATTR(online, S_IRUGO | S_IWUSR, show_online, store_online);
+
+-static int device_add_bin_attributes(struct device *dev,
+- struct bin_attribute *attrs)
+-{
+- int error = 0;
+- int i;
+-
+- if (attrs) {
+- for (i = 0; attr_name(attrs[i]); i++) {
+- error = device_create_bin_file(dev, &attrs[i]);
+- if (error)
+- break;
+- }
+- if (error)
+- while (--i >= 0)
+- device_remove_bin_file(dev, &attrs[i]);
+- }
+- return error;
+-}
+-
+-static void device_remove_bin_attributes(struct device *dev,
+- struct bin_attribute *attrs)
+-{
+- int i;
+-
+- if (attrs)
+- for (i = 0; attr_name(attrs[i]); i++)
+- device_remove_bin_file(dev, &attrs[i]);
+-}
+-
+ static int device_add_groups(struct device *dev,
+ const struct attribute_group **groups)
+ {
+@@ -502,15 +473,12 @@ static int device_add_attrs(struct devic
+ error = device_add_groups(dev, class->dev_groups);
+ if (error)
+ return error;
+- error = device_add_bin_attributes(dev, class->dev_bin_attrs);
+- if (error)
+- goto err_remove_class_groups;
+ }
+
+ if (type) {
+ error = device_add_groups(dev, type->groups);
+ if (error)
+- goto err_remove_class_bin_attrs;
++ goto err_remove_class_groups;
+ }
+
+ error = device_add_groups(dev, dev->groups);
+@@ -528,9 +496,6 @@ static int device_add_attrs(struct devic
+ err_remove_type_groups:
+ if (type)
+ device_remove_groups(dev, type->groups);
+- err_remove_class_bin_attrs:
+- if (class)
+- device_remove_bin_attributes(dev, class->dev_bin_attrs);
+ err_remove_class_groups:
+ if (class)
+ device_remove_groups(dev, class->dev_groups);
+@@ -549,10 +514,8 @@ static void device_remove_attrs(struct d
+ if (type)
+ device_remove_groups(dev, type->groups);
+
+- if (class) {
++ if (class)
+ device_remove_groups(dev, class->dev_groups);
+- device_remove_bin_attributes(dev, class->dev_bin_attrs);
+- }
+ }
+
+
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -314,7 +314,6 @@ int subsys_virtual_register(struct bus_t
+ * @owner: The module owner.
+ * @class_attrs: Default attributes of this class.
+ * @dev_groups: Default attributes of the devices that belong to the class.
+- * @dev_bin_attrs: Default binary attributes of the devices belong to the class.
+ * @dev_kobj: The kobject that represents this class and links it into the hierarchy.
+ * @dev_uevent: Called when a device is added, removed from this class, or a
+ * few other things that generate uevents to add the environment
+@@ -343,7 +342,6 @@ struct class {
+
+ struct class_attribute *class_attrs;
+ const struct attribute_group **dev_groups;
+- struct bin_attribute *dev_bin_attrs;
+ struct kobject *dev_kobj;
+
+ int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
diff --git a/hid-roccat-convert-class-code-to-use-bin_attrs-in-groups.patch b/hid-roccat-convert-class-code-to-use-bin_attrs-in-groups.patch
new file mode 100644
index 00000000000000..b96010eabf3322
--- /dev/null
+++ b/hid-roccat-convert-class-code-to-use-bin_attrs-in-groups.patch
@@ -0,0 +1,1081 @@
+From foo@baz Wed Jul 10 12:22:35 PDT 2013
+Date: Wed, 10 Jul 2013 12:22:35 -0700
+To: Greg KH <gregkh@linuxfoundation.org>
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Subject: hid: roccat: convert class code to use bin_attrs in groups
+
+Now that attribute groups support binary attributes, use them instead of
+the dev_bin_attrs field in struct class, as that is going away soon.
+
+Note, there is now a compiler warning about an unused function in the
+hid-roccat-pyra.c file with this patch:
+drivers/hid/hid-roccat-pyra.c:246:16: warning: ‘pyra_sysfs_write_settings’ defined but not used [-Wunused-function]
+
+That is because the settings binary sysfs file was previously setting
+the write field to be able to call this function on a write, yet the
+sysfs file was always marked read-only, so it was never being called. I
+left the sysfs file the same permissions, but didn't hook up the write
+function as that makes no sense. If wanted, I can just delete the
+function, but I'm not quite sure what is going on here with it.
+
+Cc: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hid/hid-roccat-arvo.c | 32 ++++----
+ drivers/hid/hid-roccat-isku.c | 87 ++++++++++++---------
+ drivers/hid/hid-roccat-kone.c | 78 ++++++++-----------
+ drivers/hid/hid-roccat-koneplus.c | 151 ++++++++++++++++----------------------
+ drivers/hid/hid-roccat-konepure.c | 67 ++++++++++------
+ drivers/hid/hid-roccat-kovaplus.c | 135 +++++++++++++--------------------
+ drivers/hid/hid-roccat-pyra.c | 134 ++++++++++++++-------------------
+ drivers/hid/hid-roccat-savu.c | 58 +++++++-------
+ 8 files changed, 346 insertions(+), 396 deletions(-)
+
+--- a/drivers/hid/hid-roccat-arvo.c
++++ b/drivers/hid/hid-roccat-arvo.c
+@@ -237,6 +237,8 @@ static ssize_t arvo_sysfs_write_button(s
+ return arvo_sysfs_write(fp, kobj, buf, off, count,
+ sizeof(struct arvo_button), ARVO_COMMAND_BUTTON);
+ }
++static BIN_ATTR(button, 0220, NULL, arvo_sysfs_write_button,
++ sizeof(struct arvo_button));
+
+ static ssize_t arvo_sysfs_read_info(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+@@ -245,6 +247,8 @@ static ssize_t arvo_sysfs_read_info(stru
+ return arvo_sysfs_read(fp, kobj, buf, off, count,
+ sizeof(struct arvo_info), ARVO_COMMAND_INFO);
+ }
++static BIN_ATTR(info, 0440, arvo_sysfs_read_info, NULL,
++ sizeof(struct arvo_info));
+
+ static struct attribute *arvo_attrs[] = {
+ &dev_attr_mode_key.attr,
+@@ -252,20 +256,21 @@ static struct attribute *arvo_attrs[] =
+ &dev_attr_actual_profile.attr,
+ NULL,
+ };
+-ATTRIBUTE_GROUPS(arvo);
+
+-static struct bin_attribute arvo_bin_attributes[] = {
+- {
+- .attr = { .name = "button", .mode = 0220 },
+- .size = sizeof(struct arvo_button),
+- .write = arvo_sysfs_write_button
+- },
+- {
+- .attr = { .name = "info", .mode = 0440 },
+- .size = sizeof(struct arvo_info),
+- .read = arvo_sysfs_read_info
+- },
+- __ATTR_NULL
++static struct bin_attribute *arvo_bin_attributes[] = {
++ &bin_attr_button,
++ &bin_attr_info,
++ NULL,
++};
++
++static const struct attribute_group arvo_group = {
++ .attrs = arvo_attrs,
++ .bin_attrs = arvo_bin_attributes,
++};
++
++static const struct attribute_group *arvo_groups[] = {
++ &arvo_group,
++ NULL,
+ };
+
+ static int arvo_init_arvo_device_struct(struct usb_device *usb_dev,
+@@ -434,7 +439,6 @@ static int __init arvo_init(void)
+ if (IS_ERR(arvo_class))
+ return PTR_ERR(arvo_class);
+ arvo_class->dev_groups = arvo_groups;
+- arvo_class->dev_bin_attrs = arvo_bin_attributes;
+
+ retval = hid_register_driver(&arvo_driver);
+ if (retval)
+--- a/drivers/hid/hid-roccat-isku.c
++++ b/drivers/hid/hid-roccat-isku.c
+@@ -116,7 +116,6 @@ static struct attribute *isku_attrs[] =
+ &dev_attr_actual_profile.attr,
+ NULL,
+ };
+-ATTRIBUTE_GROUPS(isku);
+
+ static ssize_t isku_sysfs_read(struct file *fp, struct kobject *kobj,
+ char *buf, loff_t off, size_t count,
+@@ -185,7 +184,8 @@ ISKU_SYSFS_R(thingy, THINGY) \
+ ISKU_SYSFS_W(thingy, THINGY)
+
+ #define ISKU_BIN_ATTR_RW(thingy, THINGY) \
+-{ \
++ISKU_SYSFS_RW(thingy, THINGY); \
++static struct bin_attribute bin_attr_##thingy = { \
+ .attr = { .name = #thingy, .mode = 0660 }, \
+ .size = ISKU_SIZE_ ## THINGY, \
+ .read = isku_sysfs_read_ ## thingy, \
+@@ -193,52 +193,64 @@ ISKU_SYSFS_W(thingy, THINGY)
+ }
+
+ #define ISKU_BIN_ATTR_R(thingy, THINGY) \
+-{ \
++ISKU_SYSFS_R(thingy, THINGY); \
++static struct bin_attribute bin_attr_##thingy = { \
+ .attr = { .name = #thingy, .mode = 0440 }, \
+ .size = ISKU_SIZE_ ## THINGY, \
+ .read = isku_sysfs_read_ ## thingy, \
+ }
+
+ #define ISKU_BIN_ATTR_W(thingy, THINGY) \
+-{ \
++ISKU_SYSFS_W(thingy, THINGY); \
++static struct bin_attribute bin_attr_##thingy = { \
+ .attr = { .name = #thingy, .mode = 0220 }, \
+ .size = ISKU_SIZE_ ## THINGY, \
+ .write = isku_sysfs_write_ ## thingy \
+ }
+
+-ISKU_SYSFS_RW(macro, MACRO)
+-ISKU_SYSFS_RW(keys_function, KEYS_FUNCTION)
+-ISKU_SYSFS_RW(keys_easyzone, KEYS_EASYZONE)
+-ISKU_SYSFS_RW(keys_media, KEYS_MEDIA)
+-ISKU_SYSFS_RW(keys_thumbster, KEYS_THUMBSTER)
+-ISKU_SYSFS_RW(keys_macro, KEYS_MACRO)
+-ISKU_SYSFS_RW(keys_capslock, KEYS_CAPSLOCK)
+-ISKU_SYSFS_RW(light, LIGHT)
+-ISKU_SYSFS_RW(key_mask, KEY_MASK)
+-ISKU_SYSFS_RW(last_set, LAST_SET)
+-ISKU_SYSFS_W(talk, TALK)
+-ISKU_SYSFS_W(talkfx, TALKFX)
+-ISKU_SYSFS_R(info, INFO)
+-ISKU_SYSFS_W(control, CONTROL)
+-ISKU_SYSFS_W(reset, RESET)
+-
+-static struct bin_attribute isku_bin_attributes[] = {
+- ISKU_BIN_ATTR_RW(macro, MACRO),
+- ISKU_BIN_ATTR_RW(keys_function, KEYS_FUNCTION),
+- ISKU_BIN_ATTR_RW(keys_easyzone, KEYS_EASYZONE),
+- ISKU_BIN_ATTR_RW(keys_media, KEYS_MEDIA),
+- ISKU_BIN_ATTR_RW(keys_thumbster, KEYS_THUMBSTER),
+- ISKU_BIN_ATTR_RW(keys_macro, KEYS_MACRO),
+- ISKU_BIN_ATTR_RW(keys_capslock, KEYS_CAPSLOCK),
+- ISKU_BIN_ATTR_RW(light, LIGHT),
+- ISKU_BIN_ATTR_RW(key_mask, KEY_MASK),
+- ISKU_BIN_ATTR_RW(last_set, LAST_SET),
+- ISKU_BIN_ATTR_W(talk, TALK),
+- ISKU_BIN_ATTR_W(talkfx, TALKFX),
+- ISKU_BIN_ATTR_R(info, INFO),
+- ISKU_BIN_ATTR_W(control, CONTROL),
+- ISKU_BIN_ATTR_W(reset, RESET),
+- __ATTR_NULL
++ISKU_BIN_ATTR_RW(macro, MACRO);
++ISKU_BIN_ATTR_RW(keys_function, KEYS_FUNCTION);
++ISKU_BIN_ATTR_RW(keys_easyzone, KEYS_EASYZONE);
++ISKU_BIN_ATTR_RW(keys_media, KEYS_MEDIA);
++ISKU_BIN_ATTR_RW(keys_thumbster, KEYS_THUMBSTER);
++ISKU_BIN_ATTR_RW(keys_macro, KEYS_MACRO);
++ISKU_BIN_ATTR_RW(keys_capslock, KEYS_CAPSLOCK);
++ISKU_BIN_ATTR_RW(light, LIGHT);
++ISKU_BIN_ATTR_RW(key_mask, KEY_MASK);
++ISKU_BIN_ATTR_RW(last_set, LAST_SET);
++ISKU_BIN_ATTR_W(talk, TALK);
++ISKU_BIN_ATTR_W(talkfx, TALKFX);
++ISKU_BIN_ATTR_W(control, CONTROL);
++ISKU_BIN_ATTR_W(reset, RESET);
++ISKU_BIN_ATTR_R(info, INFO);
++
++static struct bin_attribute *isku_bin_attributes[] = {
++ &bin_attr_macro,
++ &bin_attr_keys_function,
++ &bin_attr_keys_easyzone,
++ &bin_attr_keys_media,
++ &bin_attr_keys_thumbster,
++ &bin_attr_keys_macro,
++ &bin_attr_keys_capslock,
++ &bin_attr_light,
++ &bin_attr_key_mask,
++ &bin_attr_last_set,
++ &bin_attr_talk,
++ &bin_attr_talkfx,
++ &bin_attr_control,
++ &bin_attr_reset,
++ &bin_attr_info,
++ NULL,
++};
++
++static const struct attribute_group isku_group = {
++ .attrs = isku_attrs,
++ .bin_attrs = isku_bin_attributes,
++};
++
++static const struct attribute_group *isku_groups[] = {
++ &isku_group,
++ NULL,
+ };
+
+ static int isku_init_isku_device_struct(struct usb_device *usb_dev,
+@@ -429,7 +441,6 @@ static int __init isku_init(void)
+ if (IS_ERR(isku_class))
+ return PTR_ERR(isku_class);
+ isku_class->dev_groups = isku_groups;
+- isku_class->dev_bin_attrs = isku_bin_attributes;
+
+ retval = hid_register_driver(&isku_driver);
+ if (retval)
+--- a/drivers/hid/hid-roccat-kone.c
++++ b/drivers/hid/hid-roccat-kone.c
+@@ -324,6 +324,8 @@ static ssize_t kone_sysfs_write_settings
+
+ return sizeof(struct kone_settings);
+ }
++static BIN_ATTR(settings, 0660, kone_sysfs_read_settings,
++ kone_sysfs_write_settings, sizeof(struct kone_settings));
+
+ static ssize_t kone_sysfs_read_profilex(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr,
+@@ -378,6 +380,19 @@ static ssize_t kone_sysfs_write_profilex
+
+ return sizeof(struct kone_profile);
+ }
++#define PROFILE_ATTR(number) \
++static struct bin_attribute bin_attr_profile##number = { \
++ .attr = { .name = "profile##number", .mode = 0660 }, \
++ .size = sizeof(struct kone_profile), \
++ .read = kone_sysfs_read_profilex, \
++ .write = kone_sysfs_write_profilex, \
++ .private = &profile_numbers[number], \
++};
++PROFILE_ATTR(1);
++PROFILE_ATTR(2);
++PROFILE_ATTR(3);
++PROFILE_ATTR(4);
++PROFILE_ATTR(5);
+
+ static ssize_t kone_sysfs_show_actual_profile(struct device *dev,
+ struct device_attribute *attr, char *buf)
+@@ -616,51 +631,25 @@ static struct attribute *kone_attrs[] =
+ &dev_attr_startup_profile.attr,
+ NULL,
+ };
+-ATTRIBUTE_GROUPS(kone);
+
+-static struct bin_attribute kone_bin_attributes[] = {
+- {
+- .attr = { .name = "settings", .mode = 0660 },
+- .size = sizeof(struct kone_settings),
+- .read = kone_sysfs_read_settings,
+- .write = kone_sysfs_write_settings
+- },
+- {
+- .attr = { .name = "profile1", .mode = 0660 },
+- .size = sizeof(struct kone_profile),
+- .read = kone_sysfs_read_profilex,
+- .write = kone_sysfs_write_profilex,
+- .private = &profile_numbers[0]
+- },
+- {
+- .attr = { .name = "profile2", .mode = 0660 },
+- .size = sizeof(struct kone_profile),
+- .read = kone_sysfs_read_profilex,
+- .write = kone_sysfs_write_profilex,
+- .private = &profile_numbers[1]
+- },
+- {
+- .attr = { .name = "profile3", .mode = 0660 },
+- .size = sizeof(struct kone_profile),
+- .read = kone_sysfs_read_profilex,
+- .write = kone_sysfs_write_profilex,
+- .private = &profile_numbers[2]
+- },
+- {
+- .attr = { .name = "profile4", .mode = 0660 },
+- .size = sizeof(struct kone_profile),
+- .read = kone_sysfs_read_profilex,
+- .write = kone_sysfs_write_profilex,
+- .private = &profile_numbers[3]
+- },
+- {
+- .attr = { .name = "profile5", .mode = 0660 },
+- .size = sizeof(struct kone_profile),
+- .read = kone_sysfs_read_profilex,
+- .write = kone_sysfs_write_profilex,
+- .private = &profile_numbers[4]
+- },
+- __ATTR_NULL
++static struct bin_attribute *kone_bin_attributes[] = {
++ &bin_attr_settings,
++ &bin_attr_profile1,
++ &bin_attr_profile2,
++ &bin_attr_profile3,
++ &bin_attr_profile4,
++ &bin_attr_profile5,
++ NULL,
++};
++
++static const struct attribute_group kone_group = {
++ .attrs = kone_attrs,
++ .bin_attrs = kone_bin_attributes,
++};
++
++static const struct attribute_group *kone_groups[] = {
++ &kone_group,
++ NULL,
+ };
+
+ static int kone_init_kone_device_struct(struct usb_device *usb_dev,
+@@ -898,7 +887,6 @@ static int __init kone_init(void)
+ if (IS_ERR(kone_class))
+ return PTR_ERR(kone_class);
+ kone_class->dev_groups = kone_groups;
+- kone_class->dev_bin_attrs = kone_bin_attributes;
+
+ retval = hid_register_driver(&kone_driver);
+ if (retval)
+--- a/drivers/hid/hid-roccat-koneplus.c
++++ b/drivers/hid/hid-roccat-koneplus.c
+@@ -156,7 +156,8 @@ KONEPLUS_SYSFS_W(thingy, THINGY) \
+ KONEPLUS_SYSFS_R(thingy, THINGY)
+
+ #define KONEPLUS_BIN_ATTRIBUTE_RW(thingy, THINGY) \
+-{ \
++KONEPLUS_SYSFS_RW(thingy, THINGY); \
++static struct bin_attribute bin_attr_##thingy = { \
+ .attr = { .name = #thingy, .mode = 0660 }, \
+ .size = KONEPLUS_SIZE_ ## THINGY, \
+ .read = koneplus_sysfs_read_ ## thingy, \
+@@ -164,28 +165,29 @@ KONEPLUS_SYSFS_R(thingy, THINGY)
+ }
+
+ #define KONEPLUS_BIN_ATTRIBUTE_R(thingy, THINGY) \
+-{ \
++KONEPLUS_SYSFS_R(thingy, THINGY); \
++static struct bin_attribute bin_attr_##thingy = { \
+ .attr = { .name = #thingy, .mode = 0440 }, \
+ .size = KONEPLUS_SIZE_ ## THINGY, \
+ .read = koneplus_sysfs_read_ ## thingy, \
+ }
+
+ #define KONEPLUS_BIN_ATTRIBUTE_W(thingy, THINGY) \
+-{ \
++KONEPLUS_SYSFS_W(thingy, THINGY); \
++static struct bin_attribute bin_attr_##thingy = { \
+ .attr = { .name = #thingy, .mode = 0220 }, \
+ .size = KONEPLUS_SIZE_ ## THINGY, \
+ .write = koneplus_sysfs_write_ ## thingy \
+ }
+-
+-KONEPLUS_SYSFS_W(control, CONTROL)
+-KONEPLUS_SYSFS_RW(info, INFO)
+-KONEPLUS_SYSFS_W(talk, TALK)
+-KONEPLUS_SYSFS_W(macro, MACRO)
+-KONEPLUS_SYSFS_RW(sensor, SENSOR)
+-KONEPLUS_SYSFS_RW(tcu, TCU)
+-KONEPLUS_SYSFS_R(tcu_image, TCU_IMAGE)
+-KONEPLUS_SYSFS_RW(profile_settings, PROFILE_SETTINGS)
+-KONEPLUS_SYSFS_RW(profile_buttons, PROFILE_BUTTONS)
++KONEPLUS_BIN_ATTRIBUTE_W(control, CONTROL);
++KONEPLUS_BIN_ATTRIBUTE_W(talk, TALK);
++KONEPLUS_BIN_ATTRIBUTE_W(macro, MACRO);
++KONEPLUS_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE);
++KONEPLUS_BIN_ATTRIBUTE_RW(info, INFO);
++KONEPLUS_BIN_ATTRIBUTE_RW(sensor, SENSOR);
++KONEPLUS_BIN_ATTRIBUTE_RW(tcu, TCU);
++KONEPLUS_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS);
++KONEPLUS_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS);
+
+ static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+@@ -225,6 +227,25 @@ static ssize_t koneplus_sysfs_read_profi
+ KONEPLUS_COMMAND_PROFILE_BUTTONS);
+ }
+
++#define PROFILE_ATTR(number) \
++static struct bin_attribute bin_attr_profile##number##_settings = { \
++ .attr = { .name = "profile##number##_settings", .mode = 0440 }, \
++ .size = KONEPLUS_SIZE_PROFILE_SETTINGS, \
++ .read = koneplus_sysfs_read_profilex_settings, \
++ .private = &profile_numbers[number-1], \
++}; \
++static struct bin_attribute bin_attr_profile##number##_buttons = { \
++ .attr = { .name = "profile##number##_buttons", .mode = 0440 }, \
++ .size = KONEPLUS_SIZE_PROFILE_BUTTONS, \
++ .read = koneplus_sysfs_read_profilex_buttons, \
++ .private = &profile_numbers[number-1], \
++};
++PROFILE_ATTR(1);
++PROFILE_ATTR(2);
++PROFILE_ATTR(3);
++PROFILE_ATTR(4);
++PROFILE_ATTR(5);
++
+ static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+@@ -308,79 +329,38 @@ static struct attribute *koneplus_attrs[
+ &dev_attr_firmware_version.attr,
+ NULL,
+ };
+-ATTRIBUTE_GROUPS(koneplus);
+
+-static struct bin_attribute koneplus_bin_attributes[] = {
+- KONEPLUS_BIN_ATTRIBUTE_W(control, CONTROL),
+- KONEPLUS_BIN_ATTRIBUTE_RW(info, INFO),
+- KONEPLUS_BIN_ATTRIBUTE_W(talk, TALK),
+- KONEPLUS_BIN_ATTRIBUTE_W(macro, MACRO),
+- KONEPLUS_BIN_ATTRIBUTE_RW(sensor, SENSOR),
+- KONEPLUS_BIN_ATTRIBUTE_RW(tcu, TCU),
+- KONEPLUS_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE),
+- KONEPLUS_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS),
+- KONEPLUS_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS),
+- {
+- .attr = { .name = "profile1_settings", .mode = 0440 },
+- .size = KONEPLUS_SIZE_PROFILE_SETTINGS,
+- .read = koneplus_sysfs_read_profilex_settings,
+- .private = &profile_numbers[0]
+- },
+- {
+- .attr = { .name = "profile2_settings", .mode = 0440 },
+- .size = KONEPLUS_SIZE_PROFILE_SETTINGS,
+- .read = koneplus_sysfs_read_profilex_settings,
+- .private = &profile_numbers[1]
+- },
+- {
+- .attr = { .name = "profile3_settings", .mode = 0440 },
+- .size = KONEPLUS_SIZE_PROFILE_SETTINGS,
+- .read = koneplus_sysfs_read_profilex_settings,
+- .private = &profile_numbers[2]
+- },
+- {
+- .attr = { .name = "profile4_settings", .mode = 0440 },
+- .size = KONEPLUS_SIZE_PROFILE_SETTINGS,
+- .read = koneplus_sysfs_read_profilex_settings,
+- .private = &profile_numbers[3]
+- },
+- {
+- .attr = { .name = "profile5_settings", .mode = 0440 },
+- .size = KONEPLUS_SIZE_PROFILE_SETTINGS,
+- .read = koneplus_sysfs_read_profilex_settings,
+- .private = &profile_numbers[4]
+- },
+- {
+- .attr = { .name = "profile1_buttons", .mode = 0440 },
+- .size = KONEPLUS_SIZE_PROFILE_BUTTONS,
+- .read = koneplus_sysfs_read_profilex_buttons,
+- .private = &profile_numbers[0]
+- },
+- {
+- .attr = { .name = "profile2_buttons", .mode = 0440 },
+- .size = KONEPLUS_SIZE_PROFILE_BUTTONS,
+- .read = koneplus_sysfs_read_profilex_buttons,
+- .private = &profile_numbers[1]
+- },
+- {
+- .attr = { .name = "profile3_buttons", .mode = 0440 },
+- .size = KONEPLUS_SIZE_PROFILE_BUTTONS,
+- .read = koneplus_sysfs_read_profilex_buttons,
+- .private = &profile_numbers[2]
+- },
+- {
+- .attr = { .name = "profile4_buttons", .mode = 0440 },
+- .size = KONEPLUS_SIZE_PROFILE_BUTTONS,
+- .read = koneplus_sysfs_read_profilex_buttons,
+- .private = &profile_numbers[3]
+- },
+- {
+- .attr = { .name = "profile5_buttons", .mode = 0440 },
+- .size = KONEPLUS_SIZE_PROFILE_BUTTONS,
+- .read = koneplus_sysfs_read_profilex_buttons,
+- .private = &profile_numbers[4]
+- },
+- __ATTR_NULL
++static struct bin_attribute *koneplus_bin_attributes[] = {
++ &bin_attr_control,
++ &bin_attr_talk,
++ &bin_attr_macro,
++ &bin_attr_tcu_image,
++ &bin_attr_info,
++ &bin_attr_sensor,
++ &bin_attr_tcu,
++ &bin_attr_profile_settings,
++ &bin_attr_profile_buttons,
++ &bin_attr_profile1_settings,
++ &bin_attr_profile2_settings,
++ &bin_attr_profile3_settings,
++ &bin_attr_profile4_settings,
++ &bin_attr_profile5_settings,
++ &bin_attr_profile1_buttons,
++ &bin_attr_profile2_buttons,
++ &bin_attr_profile3_buttons,
++ &bin_attr_profile4_buttons,
++ &bin_attr_profile5_buttons,
++ NULL,
++};
++
++static const struct attribute_group koneplus_group = {
++ .attrs = koneplus_attrs,
++ .bin_attrs = koneplus_bin_attributes,
++};
++
++static const struct attribute_group *koneplus_groups[] = {
++ &koneplus_group,
++ NULL,
+ };
+
+ static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev,
+@@ -577,7 +557,6 @@ static int __init koneplus_init(void)
+ if (IS_ERR(koneplus_class))
+ return PTR_ERR(koneplus_class);
+ koneplus_class->dev_groups = koneplus_groups;
+- koneplus_class->dev_bin_attrs = koneplus_bin_attributes;
+
+ retval = hid_register_driver(&koneplus_driver);
+ if (retval)
+--- a/drivers/hid/hid-roccat-konepure.c
++++ b/drivers/hid/hid-roccat-konepure.c
+@@ -94,7 +94,8 @@ KONEPURE_SYSFS_W(thingy, THINGY) \
+ KONEPURE_SYSFS_R(thingy, THINGY)
+
+ #define KONEPURE_BIN_ATTRIBUTE_RW(thingy, THINGY) \
+-{ \
++KONEPURE_SYSFS_RW(thingy, THINGY); \
++static struct bin_attribute bin_attr_##thingy = { \
+ .attr = { .name = #thingy, .mode = 0660 }, \
+ .size = KONEPURE_SIZE_ ## THINGY, \
+ .read = konepure_sysfs_read_ ## thingy, \
+@@ -102,44 +103,56 @@ KONEPURE_SYSFS_R(thingy, THINGY)
+ }
+
+ #define KONEPURE_BIN_ATTRIBUTE_R(thingy, THINGY) \
+-{ \
++KONEPURE_SYSFS_R(thingy, THINGY); \
++static struct bin_attribute bin_attr_##thingy = { \
+ .attr = { .name = #thingy, .mode = 0440 }, \
+ .size = KONEPURE_SIZE_ ## THINGY, \
+ .read = konepure_sysfs_read_ ## thingy, \
+ }
+
+ #define KONEPURE_BIN_ATTRIBUTE_W(thingy, THINGY) \
+-{ \
++KONEPURE_SYSFS_W(thingy, THINGY); \
++static struct bin_attribute bin_attr_##thingy = { \
+ .attr = { .name = #thingy, .mode = 0220 }, \
+ .size = KONEPURE_SIZE_ ## THINGY, \
+ .write = konepure_sysfs_write_ ## thingy \
+ }
+
+-KONEPURE_SYSFS_RW(actual_profile, ACTUAL_PROFILE)
+-KONEPURE_SYSFS_W(control, CONTROL)
+-KONEPURE_SYSFS_RW(info, INFO)
+-KONEPURE_SYSFS_W(talk, TALK)
+-KONEPURE_SYSFS_W(macro, MACRO)
+-KONEPURE_SYSFS_RW(sensor, SENSOR)
+-KONEPURE_SYSFS_RW(tcu, TCU)
+-KONEPURE_SYSFS_R(tcu_image, TCU_IMAGE)
+-KONEPURE_SYSFS_RW(profile_settings, PROFILE_SETTINGS)
+-KONEPURE_SYSFS_RW(profile_buttons, PROFILE_BUTTONS)
+-
+-static struct bin_attribute konepure_bin_attributes[] = {
+- KONEPURE_BIN_ATTRIBUTE_RW(actual_profile, ACTUAL_PROFILE),
+- KONEPURE_BIN_ATTRIBUTE_W(control, CONTROL),
+- KONEPURE_BIN_ATTRIBUTE_RW(info, INFO),
+- KONEPURE_BIN_ATTRIBUTE_W(talk, TALK),
+- KONEPURE_BIN_ATTRIBUTE_W(macro, MACRO),
+- KONEPURE_BIN_ATTRIBUTE_RW(sensor, SENSOR),
+- KONEPURE_BIN_ATTRIBUTE_RW(tcu, TCU),
+- KONEPURE_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE),
+- KONEPURE_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS),
+- KONEPURE_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS),
+- __ATTR_NULL
++KONEPURE_BIN_ATTRIBUTE_RW(actual_profile, ACTUAL_PROFILE);
++KONEPURE_BIN_ATTRIBUTE_RW(info, INFO);
++KONEPURE_BIN_ATTRIBUTE_RW(sensor, SENSOR);
++KONEPURE_BIN_ATTRIBUTE_RW(tcu, TCU);
++KONEPURE_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS);
++KONEPURE_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS);
++KONEPURE_BIN_ATTRIBUTE_W(control, CONTROL);
++KONEPURE_BIN_ATTRIBUTE_W(talk, TALK);
++KONEPURE_BIN_ATTRIBUTE_W(macro, MACRO);
++KONEPURE_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE);
++
++static struct bin_attribute *konepure_bin_attributes[] = {
++ &bin_attr_actual_profile,
++ &bin_attr_info,
++ &bin_attr_sensor,
++ &bin_attr_tcu,
++ &bin_attr_profile_settings,
++ &bin_attr_profile_buttons,
++ &bin_attr_control,
++ &bin_attr_talk,
++ &bin_attr_macro,
++ &bin_attr_tcu_image,
++ NULL,
+ };
+
++static const struct attribute_group konepure_group = {
++ .bin_attrs = konepure_bin_attributes,
++};
++
++static const struct attribute_group *konepure_groups[] = {
++ &konepure_group,
++ NULL,
++};
++
++
+ static int konepure_init_konepure_device_struct(struct usb_device *usb_dev,
+ struct konepure_device *konepure)
+ {
+@@ -282,7 +295,7 @@ static int __init konepure_init(void)
+ konepure_class = class_create(THIS_MODULE, "konepure");
+ if (IS_ERR(konepure_class))
+ return PTR_ERR(konepure_class);
+- konepure_class->dev_bin_attrs = konepure_bin_attributes;
++ konepure_class->dev_groups = konepure_groups;
+
+ retval = hid_register_driver(&konepure_driver);
+ if (retval)
+--- a/drivers/hid/hid-roccat-kovaplus.c
++++ b/drivers/hid/hid-roccat-kovaplus.c
+@@ -197,31 +197,25 @@ KOVAPLUS_SYSFS_W(thingy, THINGY) \
+ KOVAPLUS_SYSFS_R(thingy, THINGY)
+
+ #define KOVAPLUS_BIN_ATTRIBUTE_RW(thingy, THINGY) \
+-{ \
++KOVAPLUS_SYSFS_RW(thingy, THINGY); \
++static struct bin_attribute bin_attr_##thingy = { \
+ .attr = { .name = #thingy, .mode = 0660 }, \
+ .size = KOVAPLUS_SIZE_ ## THINGY, \
+ .read = kovaplus_sysfs_read_ ## thingy, \
+ .write = kovaplus_sysfs_write_ ## thingy \
+ }
+
+-#define KOVAPLUS_BIN_ATTRIBUTE_R(thingy, THINGY) \
+-{ \
+- .attr = { .name = #thingy, .mode = 0440 }, \
+- .size = KOVAPLUS_SIZE_ ## THINGY, \
+- .read = kovaplus_sysfs_read_ ## thingy, \
+-}
+-
+ #define KOVAPLUS_BIN_ATTRIBUTE_W(thingy, THINGY) \
+-{ \
++KOVAPLUS_SYSFS_W(thingy, THINGY); \
++static struct bin_attribute bin_attr_##thingy = { \
+ .attr = { .name = #thingy, .mode = 0220 }, \
+ .size = KOVAPLUS_SIZE_ ## THINGY, \
+ .write = kovaplus_sysfs_write_ ## thingy \
+ }
+-
+-KOVAPLUS_SYSFS_W(control, CONTROL)
+-KOVAPLUS_SYSFS_RW(info, INFO)
+-KOVAPLUS_SYSFS_RW(profile_settings, PROFILE_SETTINGS)
+-KOVAPLUS_SYSFS_RW(profile_buttons, PROFILE_BUTTONS)
++KOVAPLUS_BIN_ATTRIBUTE_W(control, CONTROL);
++KOVAPLUS_BIN_ATTRIBUTE_RW(info, INFO);
++KOVAPLUS_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS);
++KOVAPLUS_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS);
+
+ static ssize_t kovaplus_sysfs_read_profilex_settings(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+@@ -261,6 +255,25 @@ static ssize_t kovaplus_sysfs_read_profi
+ KOVAPLUS_COMMAND_PROFILE_BUTTONS);
+ }
+
++#define PROFILE_ATTR(number) \
++static struct bin_attribute bin_attr_profile##number##_settings = { \
++ .attr = { .name = "profile##number##_settings", .mode = 0440 }, \
++ .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, \
++ .read = kovaplus_sysfs_read_profilex_settings, \
++ .private = &profile_numbers[number-1], \
++}; \
++static struct bin_attribute bin_attr_profile##number##_buttons = { \
++ .attr = { .name = "profile##number##_buttons", .mode = 0440 }, \
++ .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, \
++ .read = kovaplus_sysfs_read_profilex_buttons, \
++ .private = &profile_numbers[number-1], \
++};
++PROFILE_ATTR(1);
++PROFILE_ATTR(2);
++PROFILE_ATTR(3);
++PROFILE_ATTR(4);
++PROFILE_ATTR(5);
++
+ static ssize_t kovaplus_sysfs_show_actual_profile(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+@@ -372,74 +385,33 @@ static struct attribute *kovaplus_attrs[
+ &dev_attr_actual_sensitivity_y.attr,
+ NULL,
+ };
+-ATTRIBUTE_GROUPS(kovaplus);
+
+-static struct bin_attribute kovaplus_bin_attributes[] = {
+- KOVAPLUS_BIN_ATTRIBUTE_W(control, CONTROL),
+- KOVAPLUS_BIN_ATTRIBUTE_RW(info, INFO),
+- KOVAPLUS_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS),
+- KOVAPLUS_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS),
+- {
+- .attr = { .name = "profile1_settings", .mode = 0440 },
+- .size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
+- .read = kovaplus_sysfs_read_profilex_settings,
+- .private = &profile_numbers[0]
+- },
+- {
+- .attr = { .name = "profile2_settings", .mode = 0440 },
+- .size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
+- .read = kovaplus_sysfs_read_profilex_settings,
+- .private = &profile_numbers[1]
+- },
+- {
+- .attr = { .name = "profile3_settings", .mode = 0440 },
+- .size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
+- .read = kovaplus_sysfs_read_profilex_settings,
+- .private = &profile_numbers[2]
+- },
+- {
+- .attr = { .name = "profile4_settings", .mode = 0440 },
+- .size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
+- .read = kovaplus_sysfs_read_profilex_settings,
+- .private = &profile_numbers[3]
+- },
+- {
+- .attr = { .name = "profile5_settings", .mode = 0440 },
+- .size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
+- .read = kovaplus_sysfs_read_profilex_settings,
+- .private = &profile_numbers[4]
+- },
+- {
+- .attr = { .name = "profile1_buttons", .mode = 0440 },
+- .size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
+- .read = kovaplus_sysfs_read_profilex_buttons,
+- .private = &profile_numbers[0]
+- },
+- {
+- .attr = { .name = "profile2_buttons", .mode = 0440 },
+- .size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
+- .read = kovaplus_sysfs_read_profilex_buttons,
+- .private = &profile_numbers[1]
+- },
+- {
+- .attr = { .name = "profile3_buttons", .mode = 0440 },
+- .size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
+- .read = kovaplus_sysfs_read_profilex_buttons,
+- .private = &profile_numbers[2]
+- },
+- {
+- .attr = { .name = "profile4_buttons", .mode = 0440 },
+- .size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
+- .read = kovaplus_sysfs_read_profilex_buttons,
+- .private = &profile_numbers[3]
+- },
+- {
+- .attr = { .name = "profile5_buttons", .mode = 0440 },
+- .size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
+- .read = kovaplus_sysfs_read_profilex_buttons,
+- .private = &profile_numbers[4]
+- },
+- __ATTR_NULL
++static struct bin_attribute *kovaplus_bin_attributes[] = {
++ &bin_attr_control,
++ &bin_attr_info,
++ &bin_attr_profile_settings,
++ &bin_attr_profile_buttons,
++ &bin_attr_profile1_settings,
++ &bin_attr_profile2_settings,
++ &bin_attr_profile3_settings,
++ &bin_attr_profile4_settings,
++ &bin_attr_profile5_settings,
++ &bin_attr_profile1_buttons,
++ &bin_attr_profile2_buttons,
++ &bin_attr_profile3_buttons,
++ &bin_attr_profile4_buttons,
++ &bin_attr_profile5_buttons,
++ NULL,
++};
++
++static const struct attribute_group kovaplus_group = {
++ .attrs = kovaplus_attrs,
++ .bin_attrs = kovaplus_bin_attributes,
++};
++
++static const struct attribute_group *kovaplus_groups[] = {
++ &kovaplus_group,
++ NULL,
+ };
+
+ static int kovaplus_init_kovaplus_device_struct(struct usb_device *usb_dev,
+@@ -668,7 +640,6 @@ static int __init kovaplus_init(void)
+ if (IS_ERR(kovaplus_class))
+ return PTR_ERR(kovaplus_class);
+ kovaplus_class->dev_groups = kovaplus_groups;
+- kovaplus_class->dev_bin_attrs = kovaplus_bin_attributes;
+
+ retval = hid_register_driver(&kovaplus_driver);
+ if (retval)
+--- a/drivers/hid/hid-roccat-pyra.c
++++ b/drivers/hid/hid-roccat-pyra.c
+@@ -156,7 +156,8 @@ PYRA_SYSFS_W(thingy, THINGY) \
+ PYRA_SYSFS_R(thingy, THINGY)
+
+ #define PYRA_BIN_ATTRIBUTE_RW(thingy, THINGY) \
+-{ \
++PYRA_SYSFS_RW(thingy, THINGY); \
++static struct bin_attribute bin_attr_##thingy = { \
+ .attr = { .name = #thingy, .mode = 0660 }, \
+ .size = PYRA_SIZE_ ## THINGY, \
+ .read = pyra_sysfs_read_ ## thingy, \
+@@ -164,24 +165,26 @@ PYRA_SYSFS_R(thingy, THINGY)
+ }
+
+ #define PYRA_BIN_ATTRIBUTE_R(thingy, THINGY) \
+-{ \
++PYRA_SYSFS_R(thingy, THINGY); \
++static struct bin_attribute bin_attr_##thingy = { \
+ .attr = { .name = #thingy, .mode = 0440 }, \
+ .size = PYRA_SIZE_ ## THINGY, \
+ .read = pyra_sysfs_read_ ## thingy, \
+ }
+
+ #define PYRA_BIN_ATTRIBUTE_W(thingy, THINGY) \
+-{ \
++PYRA_SYSFS_W(thingy, THINGY); \
++static struct bin_attribute bin_attr_##thingy = { \
+ .attr = { .name = #thingy, .mode = 0220 }, \
+ .size = PYRA_SIZE_ ## THINGY, \
+ .write = pyra_sysfs_write_ ## thingy \
+ }
+
+-PYRA_SYSFS_W(control, CONTROL)
+-PYRA_SYSFS_RW(info, INFO)
+-PYRA_SYSFS_RW(profile_settings, PROFILE_SETTINGS)
+-PYRA_SYSFS_RW(profile_buttons, PROFILE_BUTTONS)
+-PYRA_SYSFS_R(settings, SETTINGS)
++PYRA_BIN_ATTRIBUTE_W(control, CONTROL);
++PYRA_BIN_ATTRIBUTE_RW(info, INFO);
++PYRA_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS);
++PYRA_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS);
++PYRA_BIN_ATTRIBUTE_R(settings, SETTINGS);
+
+ static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+@@ -221,6 +224,25 @@ static ssize_t pyra_sysfs_read_profilex_
+ PYRA_COMMAND_PROFILE_BUTTONS);
+ }
+
++#define PROFILE_ATTR(number) \
++static struct bin_attribute bin_attr_profile##number##_settings = { \
++ .attr = { .name = "profile##number##_settings", .mode = 0440 }, \
++ .size = PYRA_SIZE_PROFILE_SETTINGS, \
++ .read = pyra_sysfs_read_profilex_settings, \
++ .private = &profile_numbers[number-1], \
++}; \
++static struct bin_attribute bin_attr_profile##number##_buttons = { \
++ .attr = { .name = "profile##number##_buttons", .mode = 0440 }, \
++ .size = PYRA_SIZE_PROFILE_BUTTONS, \
++ .read = pyra_sysfs_read_profilex_buttons, \
++ .private = &profile_numbers[number-1], \
++};
++PROFILE_ATTR(1);
++PROFILE_ATTR(2);
++PROFILE_ATTR(3);
++PROFILE_ATTR(4);
++PROFILE_ATTR(5);
++
+ static ssize_t pyra_sysfs_write_settings(struct file *fp,
+ struct kobject *kobj, struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+@@ -314,75 +336,34 @@ static struct attribute *pyra_attrs[] =
+ &dev_attr_startup_profile.attr,
+ NULL,
+ };
+-ATTRIBUTE_GROUPS(pyra);
+
+-static struct bin_attribute pyra_bin_attributes[] = {
+- PYRA_BIN_ATTRIBUTE_W(control, CONTROL),
+- PYRA_BIN_ATTRIBUTE_RW(info, INFO),
+- PYRA_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS),
+- PYRA_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS),
+- PYRA_BIN_ATTRIBUTE_RW(settings, SETTINGS),
+- {
+- .attr = { .name = "profile1_settings", .mode = 0440 },
+- .size = PYRA_SIZE_PROFILE_SETTINGS,
+- .read = pyra_sysfs_read_profilex_settings,
+- .private = &profile_numbers[0]
+- },
+- {
+- .attr = { .name = "profile2_settings", .mode = 0440 },
+- .size = PYRA_SIZE_PROFILE_SETTINGS,
+- .read = pyra_sysfs_read_profilex_settings,
+- .private = &profile_numbers[1]
+- },
+- {
+- .attr = { .name = "profile3_settings", .mode = 0440 },
+- .size = PYRA_SIZE_PROFILE_SETTINGS,
+- .read = pyra_sysfs_read_profilex_settings,
+- .private = &profile_numbers[2]
+- },
+- {
+- .attr = { .name = "profile4_settings", .mode = 0440 },
+- .size = PYRA_SIZE_PROFILE_SETTINGS,
+- .read = pyra_sysfs_read_profilex_settings,
+- .private = &profile_numbers[3]
+- },
+- {
+- .attr = { .name = "profile5_settings", .mode = 0440 },
+- .size = PYRA_SIZE_PROFILE_SETTINGS,
+- .read = pyra_sysfs_read_profilex_settings,
+- .private = &profile_numbers[4]
+- },
+- {
+- .attr = { .name = "profile1_buttons", .mode = 0440 },
+- .size = PYRA_SIZE_PROFILE_BUTTONS,
+- .read = pyra_sysfs_read_profilex_buttons,
+- .private = &profile_numbers[0]
+- },
+- {
+- .attr = { .name = "profile2_buttons", .mode = 0440 },
+- .size = PYRA_SIZE_PROFILE_BUTTONS,
+- .read = pyra_sysfs_read_profilex_buttons,
+- .private = &profile_numbers[1]
+- },
+- {
+- .attr = { .name = "profile3_buttons", .mode = 0440 },
+- .size = PYRA_SIZE_PROFILE_BUTTONS,
+- .read = pyra_sysfs_read_profilex_buttons,
+- .private = &profile_numbers[2]
+- },
+- {
+- .attr = { .name = "profile4_buttons", .mode = 0440 },
+- .size = PYRA_SIZE_PROFILE_BUTTONS,
+- .read = pyra_sysfs_read_profilex_buttons,
+- .private = &profile_numbers[3]
+- },
+- {
+- .attr = { .name = "profile5_buttons", .mode = 0440 },
+- .size = PYRA_SIZE_PROFILE_BUTTONS,
+- .read = pyra_sysfs_read_profilex_buttons,
+- .private = &profile_numbers[4]
+- },
+- __ATTR_NULL
++static struct bin_attribute *pyra_bin_attributes[] = {
++ &bin_attr_control,
++ &bin_attr_info,
++ &bin_attr_profile_settings,
++ &bin_attr_profile_buttons,
++ &bin_attr_settings,
++ &bin_attr_profile1_settings,
++ &bin_attr_profile2_settings,
++ &bin_attr_profile3_settings,
++ &bin_attr_profile4_settings,
++ &bin_attr_profile5_settings,
++ &bin_attr_profile1_buttons,
++ &bin_attr_profile2_buttons,
++ &bin_attr_profile3_buttons,
++ &bin_attr_profile4_buttons,
++ &bin_attr_profile5_buttons,
++ NULL,
++};
++
++static const struct attribute_group pyra_group = {
++ .attrs = pyra_attrs,
++ .bin_attrs = pyra_bin_attributes,
++};
++
++static const struct attribute_group *pyra_groups[] = {
++ &pyra_group,
++ NULL,
+ };
+
+ static int pyra_init_pyra_device_struct(struct usb_device *usb_dev,
+@@ -605,7 +586,6 @@ static int __init pyra_init(void)
+ if (IS_ERR(pyra_class))
+ return PTR_ERR(pyra_class);
+ pyra_class->dev_groups = pyra_groups;
+- pyra_class->dev_bin_attrs = pyra_bin_attributes;
+
+ retval = hid_register_driver(&pyra_driver);
+ if (retval)
+--- a/drivers/hid/hid-roccat-savu.c
++++ b/drivers/hid/hid-roccat-savu.c
+@@ -94,44 +94,48 @@ SAVU_SYSFS_W(thingy, THINGY) \
+ SAVU_SYSFS_R(thingy, THINGY)
+
+ #define SAVU_BIN_ATTRIBUTE_RW(thingy, THINGY) \
+-{ \
++SAVU_SYSFS_RW(thingy, THINGY); \
++static struct bin_attribute bin_attr_##thingy = { \
+ .attr = { .name = #thingy, .mode = 0660 }, \
+ .size = SAVU_SIZE_ ## THINGY, \
+ .read = savu_sysfs_read_ ## thingy, \
+ .write = savu_sysfs_write_ ## thingy \
+ }
+
+-#define SAVU_BIN_ATTRIBUTE_R(thingy, THINGY) \
+-{ \
+- .attr = { .name = #thingy, .mode = 0440 }, \
+- .size = SAVU_SIZE_ ## THINGY, \
+- .read = savu_sysfs_read_ ## thingy, \
+-}
+-
+ #define SAVU_BIN_ATTRIBUTE_W(thingy, THINGY) \
+-{ \
++SAVU_SYSFS_W(thingy, THINGY); \
++static struct bin_attribute bin_attr_##thingy = { \
+ .attr = { .name = #thingy, .mode = 0220 }, \
+ .size = SAVU_SIZE_ ## THINGY, \
+ .write = savu_sysfs_write_ ## thingy \
+ }
+
+-SAVU_SYSFS_W(control, CONTROL)
+-SAVU_SYSFS_RW(profile, PROFILE)
+-SAVU_SYSFS_RW(general, GENERAL)
+-SAVU_SYSFS_RW(buttons, BUTTONS)
+-SAVU_SYSFS_RW(macro, MACRO)
+-SAVU_SYSFS_RW(info, INFO)
+-SAVU_SYSFS_RW(sensor, SENSOR)
+-
+-static struct bin_attribute savu_bin_attributes[] = {
+- SAVU_BIN_ATTRIBUTE_W(control, CONTROL),
+- SAVU_BIN_ATTRIBUTE_RW(profile, PROFILE),
+- SAVU_BIN_ATTRIBUTE_RW(general, GENERAL),
+- SAVU_BIN_ATTRIBUTE_RW(buttons, BUTTONS),
+- SAVU_BIN_ATTRIBUTE_RW(macro, MACRO),
+- SAVU_BIN_ATTRIBUTE_RW(info, INFO),
+- SAVU_BIN_ATTRIBUTE_RW(sensor, SENSOR),
+- __ATTR_NULL
++SAVU_BIN_ATTRIBUTE_W(control, CONTROL);
++SAVU_BIN_ATTRIBUTE_RW(profile, PROFILE);
++SAVU_BIN_ATTRIBUTE_RW(general, GENERAL);
++SAVU_BIN_ATTRIBUTE_RW(buttons, BUTTONS);
++SAVU_BIN_ATTRIBUTE_RW(macro, MACRO);
++SAVU_BIN_ATTRIBUTE_RW(info, INFO);
++SAVU_BIN_ATTRIBUTE_RW(sensor, SENSOR);
++
++static struct bin_attribute *savu_bin_attributes[] = {
++ &bin_attr_control,
++ &bin_attr_profile,
++ &bin_attr_general,
++ &bin_attr_buttons,
++ &bin_attr_macro,
++ &bin_attr_info,
++ &bin_attr_sensor,
++ NULL,
++};
++
++static const struct attribute_group savu_group = {
++ .bin_attrs = savu_bin_attributes,
++};
++
++static const struct attribute_group *savu_groups[] = {
++ &savu_group,
++ NULL,
+ };
+
+ static int savu_init_savu_device_struct(struct usb_device *usb_dev,
+@@ -294,7 +298,7 @@ static int __init savu_init(void)
+ savu_class = class_create(THIS_MODULE, "savu");
+ if (IS_ERR(savu_class))
+ return PTR_ERR(savu_class);
+- savu_class->dev_bin_attrs = savu_bin_attributes;
++ savu_class->dev_groups = savu_groups;
+
+ retval = hid_register_driver(&savu_driver);
+ if (retval)
diff --git a/series b/series
index b71446f8776623..e32ef2004bdcc5 100644
--- a/series
+++ b/series
@@ -3,13 +3,15 @@
# driver core attribute cleanup work
sysfs.h-add-__attr_rw-macro.patch
sysfs.h-add-attribute_groups-macro.patch
+sysfs.h-add-bin_attr-macro.patch
driver-core-add-device_attr_rw-and-device_attr_ro-macros.patch
-driver-core-add-binary-attributes-to-struct-device.patch
+sysfs-add-support-for-binary-attributes-in-groups.patch
+driver-core-introduce-device_create_groups.patch
+
misc-c2port-use-dev_bin_attrs-instead-of-hand-coding-it.patch
# dev_groups to struct class work
driver-core-add-default-groups-to-struct-class.patch
-driver-core-remove-dev_attrs-from-struct-class.patch
mips-convert-vpe_class-to-use-dev_groups.patch
bsr-convert-bsr_class-to-use-dev_groups.patch
tile-srom-convert-srom_class-to-use-dev_groups.patch
@@ -43,6 +45,15 @@ net-ieee802154-convert-class-code-to-use-dev_groups.patch
net-wireless-convert-class-code-to-use-dev_groups.patch
net-rfkill-convert-class-code-to-use-dev_groups.patch
+c2port-convert-class-code-to-use-bin_attrs-in-groups.patch
+hid-roccat-convert-class-code-to-use-bin_attrs-in-groups.patch
+
+driver-core-remove-dev_attrs-from-struct-class.patch
+driver-core-remove-dev_bin_attrs-from-struct-class.patch
+
+#driver-core-add-binary-attributes-to-struct-device.patch
+#driver-core-remove-bin_attrs-from-struct-device.patch
+
# usb DEBUG cleanups
usb-ldusb-remove-custom-dbg_info-macro.patch
diff --git a/sysfs-add-support-for-binary-attributes-in-groups.patch b/sysfs-add-support-for-binary-attributes-in-groups.patch
new file mode 100644
index 00000000000000..800997a0d2e2b0
--- /dev/null
+++ b/sysfs-add-support-for-binary-attributes-in-groups.patch
@@ -0,0 +1,84 @@
+From foo@baz Wed Jul 10 12:02:20 PDT 2013
+Date: Wed, 10 Jul 2013 12:02:20 -0700
+To: Greg KH <gregkh@linuxfoundation.org>
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Subject: sysfs: add support for binary attributes in groups
+
+groups should be able to support binary attributes, just like it
+supports "normal" attributes. This lets us only handle one type of
+structure, groups, throughout the driver core and subsystems, making
+binary attributes a "full fledged" part of the driver model, and not
+something just "tacked on".
+
+Reported-by: Oliver Schinagl <oliver+list@schinagl.nl>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/sysfs/group.c | 18 ++++++++++++++++--
+ include/linux/sysfs.h | 4 ++--
+ 2 files changed, 18 insertions(+), 4 deletions(-)
+
+--- a/fs/sysfs/group.c
++++ b/fs/sysfs/group.c
+@@ -20,16 +20,19 @@ static void remove_files(struct sysfs_di
+ const struct attribute_group *grp)
+ {
+ struct attribute *const* attr;
+- int i;
++ struct bin_attribute *const* bin_attr;
+
+- for (i = 0, attr = grp->attrs; *attr; i++, attr++)
++ for (attr = grp->attrs; *attr; attr++)
+ sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name);
++ for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++)
++ sysfs_remove_bin_file(kobj, *bin_attr);
+ }
+
+ static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
+ const struct attribute_group *grp, int update)
+ {
+ struct attribute *const* attr;
++ struct bin_attribute *const* bin_attr;
+ int error = 0, i;
+
+ for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) {
+@@ -52,6 +55,17 @@ static int create_files(struct sysfs_dir
+ }
+ if (error)
+ remove_files(dir_sd, kobj, grp);
++
++ for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) {
++ if (update)
++ sysfs_remove_bin_file(kobj, *bin_attr);
++ error = sysfs_create_bin_file(kobj, *bin_attr);
++ if (error)
++ break;
++ }
++ if (error)
++ remove_files(dir_sd, kobj, grp);
++
+ return error;
+ }
+
+--- a/include/linux/sysfs.h
++++ b/include/linux/sysfs.h
+@@ -21,6 +21,7 @@
+
+ struct kobject;
+ struct module;
++struct bin_attribute;
+ enum kobj_ns_type;
+
+ struct attribute {
+@@ -59,10 +60,9 @@ struct attribute_group {
+ umode_t (*is_visible)(struct kobject *,
+ struct attribute *, int);
+ struct attribute **attrs;
++ struct bin_attribute **bin_attrs;
+ };
+
+-
+-
+ /**
+ * Use these macros to make defining attributes easier. See include/linux/device.h
+ * for examples..
diff --git a/sysfs.h-add-bin_attr-macro.patch b/sysfs.h-add-bin_attr-macro.patch
new file mode 100644
index 00000000000000..0b024198d00356
--- /dev/null
+++ b/sysfs.h-add-bin_attr-macro.patch
@@ -0,0 +1,32 @@
+From foo@baz Wed Jul 10 12:06:27 PDT 2013
+Date: Wed, 10 Jul 2013 12:06:27 -0700
+To: Greg KH <gregkh@linuxfoundation.org>
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Subject: sysfs.h: add BIN_ATTR macro
+
+This makes it easier to create static binary attributes, which is needed
+in a number of drivers, instead of "open coding" them.
+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/sysfs.h | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/include/linux/sysfs.h
++++ b/include/linux/sysfs.h
+@@ -132,6 +132,15 @@ struct bin_attribute {
+ */
+ #define sysfs_bin_attr_init(bin_attr) sysfs_attr_init(&(bin_attr)->attr)
+
++/* macro to create static binary attributes easier */
++#define BIN_ATTR(_name, _mode, _read, _write, _size) \
++struct bin_attribute bin_attr_##_name = { \
++ .attr = {.name = __stringify(_name), .mode = _mode }, \
++ .read = _read, \
++ .write = _write, \
++ .size = _size, \
++}
++
+ struct sysfs_ops {
+ ssize_t (*show)(struct kobject *, struct attribute *,char *);
+ ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);