aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorMichal Malý <madcatxster@gmail.com>2012-04-09 03:08:49 -0400
committerJiri Kosina <jkosina@suse.cz>2012-04-13 08:55:32 -0400
commit3b6b17b7330c0fab7d8442b6d225bee905df3745 (patch)
tree86eb75d40f6122e8c98efc50b8f333c9bef00a2c /drivers/hid
parent6a2e176b2d6ae6bb528c0c1a50a6332e176cda12 (diff)
HID: lg4ff: Take advantage of private driver data
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>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-lg4ff.c92
1 files changed, 42 insertions, 50 deletions
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
index 11452920a6c3..32c173fcb7f8 100644
--- a/drivers/hid/hid-lg4ff.c
+++ b/drivers/hid/hid-lg4ff.c
@@ -51,10 +51,7 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at
51 51
52static DEVICE_ATTR(range, S_IRWXU | S_IRWXG | S_IRWXO, lg4ff_range_show, lg4ff_range_store); 52static DEVICE_ATTR(range, S_IRWXU | S_IRWXG | S_IRWXO, lg4ff_range_show, lg4ff_range_store);
53 53
54static bool list_inited;
55
56struct lg4ff_device_entry { 54struct lg4ff_device_entry {
57 char *device_id; /* Use name in respective kobject structure's address as the ID */
58 __u16 range; 55 __u16 range;
59 __u16 min_range; 56 __u16 min_range;
60 __u16 max_range; 57 __u16 max_range;
@@ -63,8 +60,6 @@ struct lg4ff_device_entry {
63 void (*set_range)(struct hid_device *hid, u16 range); 60 void (*set_range)(struct hid_device *hid, u16 range);
64}; 61};
65 62
66static struct lg4ff_device_entry device_list;
67
68static const signed short lg4ff_wheel_effects[] = { 63static const signed short lg4ff_wheel_effects[] = {
69 FF_CONSTANT, 64 FF_CONSTANT,
70 FF_AUTOCENTER, 65 FF_AUTOCENTER,
@@ -285,18 +280,20 @@ static void hid_lg4ff_switch_native(struct hid_device *hid, const struct lg4ff_n
285/* Read current range and display it in terminal */ 280/* Read current range and display it in terminal */
286static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *attr, char *buf) 281static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *attr, char *buf)
287{ 282{
288 struct lg4ff_device_entry *uninitialized_var(entry);
289 struct list_head *h;
290 struct hid_device *hid = to_hid_device(dev); 283 struct hid_device *hid = to_hid_device(dev);
284 struct lg4ff_device_entry *entry;
285 struct lg_drv_data *drv_data;
291 size_t count; 286 size_t count;
292 287
293 list_for_each(h, &device_list.list) { 288 drv_data = hid_get_drvdata(hid);
294 entry = list_entry(h, struct lg4ff_device_entry, list); 289 if (!drv_data) {
295 if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0) 290 hid_err(hid, "Private driver data not found!\n");
296 break; 291 return 0;
297 } 292 }
298 if (h == &device_list.list) { 293
299 dbg_hid("Device not found!"); 294 entry = drv_data->device_props;
295 if (!entry) {
296 hid_err(hid, "Device properties not found!\n");
300 return 0; 297 return 0;
301 } 298 }
302 299
@@ -308,19 +305,21 @@ static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *att
308 * according to the type of the wheel */ 305 * according to the type of the wheel */
309static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 306static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
310{ 307{
311 struct lg4ff_device_entry *uninitialized_var(entry);
312 struct list_head *h;
313 struct hid_device *hid = to_hid_device(dev); 308 struct hid_device *hid = to_hid_device(dev);
309 struct lg4ff_device_entry *entry;
310 struct lg_drv_data *drv_data;
314 __u16 range = simple_strtoul(buf, NULL, 10); 311 __u16 range = simple_strtoul(buf, NULL, 10);
315 312
316 list_for_each(h, &device_list.list) { 313 drv_data = hid_get_drvdata(hid);
317 entry = list_entry(h, struct lg4ff_device_entry, list); 314 if (!drv_data) {
318 if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0) 315 hid_err(hid, "Private driver data not found!\n");
319 break; 316 return 0;
320 } 317 }
321 if (h == &device_list.list) { 318
322 dbg_hid("Device not found!"); 319 entry = drv_data->device_props;
323 return count; 320 if (!entry) {
321 hid_err(hid, "Device properties not found!\n");
322 return 0;
324 } 323 }
325 324
326 if (range == 0) 325 if (range == 0)
@@ -344,6 +343,7 @@ int lg4ff_init(struct hid_device *hid)
344 struct hid_report *report; 343 struct hid_report *report;
345 struct hid_field *field; 344 struct hid_field *field;
346 struct lg4ff_device_entry *entry; 345 struct lg4ff_device_entry *entry;
346 struct lg_drv_data *drv_data;
347 struct usb_device_descriptor *udesc; 347 struct usb_device_descriptor *udesc;
348 int error, i, j; 348 int error, i, j;
349 __u16 bcdDevice, rev_maj, rev_min; 349 __u16 bcdDevice, rev_maj, rev_min;
@@ -423,28 +423,24 @@ int lg4ff_init(struct hid_device *hid)
423 dev->ff->set_autocenter(dev, 0); 423 dev->ff->set_autocenter(dev, 0);
424 } 424 }
425 425
426 /* Initialize device_list if this is the first device to handle by lg4ff */ 426 /* Get private driver data */
427 if (!list_inited) { 427 drv_data = hid_get_drvdata(hid);
428 INIT_LIST_HEAD(&device_list.list); 428 if (!drv_data) {
429 list_inited = 1; 429 hid_err(hid, "Cannot add device, private driver data not allocated\n");
430 return -1;
430 } 431 }
431 432
432 /* Add the device to device_list */ 433 /* Initialize device properties */
433 entry = kzalloc(sizeof(struct lg4ff_device_entry), GFP_KERNEL); 434 entry = kzalloc(sizeof(struct lg4ff_device_entry), GFP_KERNEL);
434 if (!entry) { 435 if (!entry) {
435 hid_err(hid, "Cannot add device, insufficient memory.\n"); 436 hid_err(hid, "Cannot add device, insufficient memory to allocate device properties.\n");
436 return -ENOMEM;
437 }
438 entry->device_id = kstrdup((&hid->dev)->kobj.name, GFP_KERNEL);
439 if (!entry->device_id) {
440 hid_err(hid, "Cannot set device_id, insufficient memory.\n");
441 kfree(entry);
442 return -ENOMEM; 437 return -ENOMEM;
443 } 438 }
439 drv_data->device_props = entry;
440
444 entry->min_range = lg4ff_devices[i].min_range; 441 entry->min_range = lg4ff_devices[i].min_range;
445 entry->max_range = lg4ff_devices[i].max_range; 442 entry->max_range = lg4ff_devices[i].max_range;
446 entry->set_range = lg4ff_devices[i].set_range; 443 entry->set_range = lg4ff_devices[i].set_range;
447 list_add(&entry->list, &device_list.list);
448 444
449 /* Create sysfs interface */ 445 /* Create sysfs interface */
450 error = device_create_file(&hid->dev, &dev_attr_range); 446 error = device_create_file(&hid->dev, &dev_attr_range);
@@ -463,27 +459,23 @@ int lg4ff_init(struct hid_device *hid)
463 459
464int lg4ff_deinit(struct hid_device *hid) 460int lg4ff_deinit(struct hid_device *hid)
465{ 461{
466 bool found = 0;
467 struct lg4ff_device_entry *entry; 462 struct lg4ff_device_entry *entry;
468 struct list_head *h, *g; 463 struct lg_drv_data *drv_data;
469 464
470 device_remove_file(&hid->dev, &dev_attr_range); 465 device_remove_file(&hid->dev, &dev_attr_range);
471 466
472 list_for_each_safe(h, g, &device_list.list) { 467 drv_data = hid_get_drvdata(hid);
473 entry = list_entry(h, struct lg4ff_device_entry, list); 468 if (!drv_data) {
474 if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0) { 469 hid_err(hid, "Error while deinitializing device, no private driver data.\n");
475 list_del(h); 470 return -1;
476 kfree(entry->device_id);
477 kfree(entry);
478 found = 1;
479 break;
480 }
481 } 471 }
482 472 entry = drv_data->device_props;
483 if (!found) { 473 if (!entry) {
484 hid_err(hid, "Device entry not found!\n"); 474 hid_err(hid, "Error while deinitializing device, no device properties data.\n");
485 return -1; 475 return -1;
486 } 476 }
477 /* Deallocate memory */
478 kfree(entry);
487 479
488 dbg_hid("Device successfully unregistered\n"); 480 dbg_hid("Device successfully unregistered\n");
489 return 0; 481 return 0;