HID: lg4ff: Take advantage of private driver data
authorMichal Malý <madcatxster@gmail.com>
Mon, 9 Apr 2012 07:08:49 +0000 (09:08 +0200)
committerJiri Kosina <jkosina@suse.cz>
Fri, 13 Apr 2012 12:55:32 +0000 (14:55 +0200)
lg4ff now calls hid_get/set_drvdata() to read or store device configuration.

Signed-off-by: Michal Malý <madcatxster@gmail.com>
Tested-by: Simon Wood <simon@mungewell.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
drivers/hid/hid-lg4ff.c

index 11452920a6c3577bd509d59085a0afbb5853ffc8..32c173fcb7f8e12b48efd0db4773d12709b9b5a5 100644 (file)
@@ -51,10 +51,7 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at
 
 static DEVICE_ATTR(range, S_IRWXU | S_IRWXG | S_IRWXO, lg4ff_range_show, lg4ff_range_store);
 
-static bool list_inited;
-
 struct lg4ff_device_entry {
-       char  *device_id;       /* Use name in respective kobject structure's address as the ID */
        __u16 range;
        __u16 min_range;
        __u16 max_range;
@@ -63,8 +60,6 @@ struct lg4ff_device_entry {
        void (*set_range)(struct hid_device *hid, u16 range);
 };
 
-static struct lg4ff_device_entry device_list;
-
 static const signed short lg4ff_wheel_effects[] = {
        FF_CONSTANT,
        FF_AUTOCENTER,
@@ -285,18 +280,20 @@ static void hid_lg4ff_switch_native(struct hid_device *hid, const struct lg4ff_n
 /* Read current range and display it in terminal */
 static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
-       struct lg4ff_device_entry *uninitialized_var(entry);
-       struct list_head *h;
        struct hid_device *hid = to_hid_device(dev);
+       struct lg4ff_device_entry *entry;
+       struct lg_drv_data *drv_data;
        size_t count;
 
-       list_for_each(h, &device_list.list) {
-               entry = list_entry(h, struct lg4ff_device_entry, list);
-               if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0)
-                       break;
+       drv_data = hid_get_drvdata(hid);
+       if (!drv_data) {
+               hid_err(hid, "Private driver data not found!\n");
+               return 0;
        }
-       if (h == &device_list.list) {
-               dbg_hid("Device not found!");
+
+       entry = drv_data->device_props;
+       if (!entry) {
+               hid_err(hid, "Device properties not found!\n");
                return 0;
        }
 
@@ -308,19 +305,21 @@ static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *att
  * according to the type of the wheel */
 static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
-       struct lg4ff_device_entry *uninitialized_var(entry);
-       struct list_head *h;
        struct hid_device *hid = to_hid_device(dev);
+       struct lg4ff_device_entry *entry;
+       struct lg_drv_data *drv_data;
        __u16 range = simple_strtoul(buf, NULL, 10);
 
-       list_for_each(h, &device_list.list) {
-               entry = list_entry(h, struct lg4ff_device_entry, list);
-               if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0)
-                       break;
+       drv_data = hid_get_drvdata(hid);
+       if (!drv_data) {
+               hid_err(hid, "Private driver data not found!\n");
+               return 0;
        }
-       if (h == &device_list.list) {
-               dbg_hid("Device not found!");
-               return count;
+
+       entry = drv_data->device_props;
+       if (!entry) {
+               hid_err(hid, "Device properties not found!\n");
+               return 0;
        }
 
        if (range == 0)
@@ -344,6 +343,7 @@ int lg4ff_init(struct hid_device *hid)
        struct hid_report *report;
        struct hid_field *field;
        struct lg4ff_device_entry *entry;
+       struct lg_drv_data *drv_data;
        struct usb_device_descriptor *udesc;
        int error, i, j;
        __u16 bcdDevice, rev_maj, rev_min;
@@ -423,28 +423,24 @@ int lg4ff_init(struct hid_device *hid)
                dev->ff->set_autocenter(dev, 0);
        }
 
-               /* Initialize device_list if this is the first device to handle by lg4ff */
-       if (!list_inited) {
-               INIT_LIST_HEAD(&device_list.list);
-               list_inited = 1;
+       /* Get private driver data */
+       drv_data = hid_get_drvdata(hid);
+       if (!drv_data) {
+               hid_err(hid, "Cannot add device, private driver data not allocated\n");
+               return -1;
        }
 
-       /* Add the device to device_list */
+       /* Initialize device properties */
        entry = kzalloc(sizeof(struct lg4ff_device_entry), GFP_KERNEL);
        if (!entry) {
-               hid_err(hid, "Cannot add device, insufficient memory.\n");
-               return -ENOMEM;
-       }
-       entry->device_id = kstrdup((&hid->dev)->kobj.name, GFP_KERNEL);
-       if (!entry->device_id) {
-               hid_err(hid, "Cannot set device_id, insufficient memory.\n");
-               kfree(entry);
+               hid_err(hid, "Cannot add device, insufficient memory to allocate device properties.\n");
                return -ENOMEM;
        }
+       drv_data->device_props = entry;
+
        entry->min_range = lg4ff_devices[i].min_range;
        entry->max_range = lg4ff_devices[i].max_range;
        entry->set_range = lg4ff_devices[i].set_range;
-       list_add(&entry->list, &device_list.list);
 
        /* Create sysfs interface */
        error = device_create_file(&hid->dev, &dev_attr_range);
@@ -463,27 +459,23 @@ int lg4ff_init(struct hid_device *hid)
 
 int lg4ff_deinit(struct hid_device *hid)
 {
-       bool found = 0;
        struct lg4ff_device_entry *entry;
-       struct list_head *h, *g;
-       
+       struct lg_drv_data *drv_data;
+
        device_remove_file(&hid->dev, &dev_attr_range);
 
-       list_for_each_safe(h, g, &device_list.list) {
-               entry = list_entry(h, struct lg4ff_device_entry, list);
-               if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0) {
-                       list_del(h);
-                       kfree(entry->device_id);
-                       kfree(entry);
-                       found = 1;
-                       break;
-               }
+       drv_data = hid_get_drvdata(hid);
+       if (!drv_data) {
+               hid_err(hid, "Error while deinitializing device, no private driver data.\n");
+               return -1;
        }
-
-       if (!found) {
-               hid_err(hid, "Device entry not found!\n");
+       entry = drv_data->device_props;
+       if (!entry) {
+               hid_err(hid, "Error while deinitializing device, no device properties data.\n");
                return -1;
        }
+       /* Deallocate memory */
+       kfree(entry);
 
        dbg_hid("Device successfully unregistered\n");
        return 0;