diff options
author | Michal Malý <madcatxster@gmail.com> | 2012-04-09 03:08:49 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2012-04-13 08:55:32 -0400 |
commit | 3b6b17b7330c0fab7d8442b6d225bee905df3745 (patch) | |
tree | 86eb75d40f6122e8c98efc50b8f333c9bef00a2c /drivers/hid | |
parent | 6a2e176b2d6ae6bb528c0c1a50a6332e176cda12 (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.c | 92 |
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 | ||
52 | static DEVICE_ATTR(range, S_IRWXU | S_IRWXG | S_IRWXO, lg4ff_range_show, lg4ff_range_store); | 52 | static DEVICE_ATTR(range, S_IRWXU | S_IRWXG | S_IRWXO, lg4ff_range_show, lg4ff_range_store); |
53 | 53 | ||
54 | static bool list_inited; | ||
55 | |||
56 | struct lg4ff_device_entry { | 54 | struct 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 | ||
66 | static struct lg4ff_device_entry device_list; | ||
67 | |||
68 | static const signed short lg4ff_wheel_effects[] = { | 63 | static 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 */ |
286 | static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *attr, char *buf) | 281 | static 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 */ |
309 | static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 306 | static 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 | ||
464 | int lg4ff_deinit(struct hid_device *hid) | 460 | int 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; |