aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@googlemail.com>2011-08-17 05:43:20 -0400
committerJiri Kosina <jkosina@suse.cz>2011-08-23 04:54:59 -0400
commit3989ef6cfb80825af2f7933415797f052817ac3e (patch)
treeb195b32922243f9ee4cca6aa5551e5f3a1fc62aa /drivers/hid
parentf5fc87905ea075a0b14878086fd4fe38be128844 (diff)
HID: wiimote: Simplify synchronization
The new locking scheme in HID core allows us to remove a bit of synchronization. Since the HID layer acts synchronously we simply register input core last and there are no synchonization issues anymore. Also register sysfs files after that to simplify the code. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-wiimote.c78
1 files changed, 27 insertions, 51 deletions
diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c
index a594383ce03d..8a68bf515cad 100644
--- a/drivers/hid/hid-wiimote.c
+++ b/drivers/hid/hid-wiimote.c
@@ -10,7 +10,6 @@
10 * any later version. 10 * any later version.
11 */ 11 */
12 12
13#include <linux/atomic.h>
14#include <linux/device.h> 13#include <linux/device.h>
15#include <linux/hid.h> 14#include <linux/hid.h>
16#include <linux/input.h> 15#include <linux/input.h>
@@ -33,7 +32,6 @@ struct wiimote_state {
33}; 32};
34 33
35struct wiimote_data { 34struct wiimote_data {
36 atomic_t ready;
37 struct hid_device *hdev; 35 struct hid_device *hdev;
38 struct input_dev *input; 36 struct input_dev *input;
39 37
@@ -200,9 +198,6 @@ static ssize_t wiifs_led_show_##num(struct device *dev, \
200 unsigned long flags; \ 198 unsigned long flags; \
201 int state; \ 199 int state; \
202 \ 200 \
203 if (!atomic_read(&wdata->ready)) \
204 return -EBUSY; \
205 \
206 spin_lock_irqsave(&wdata->state.lock, flags); \ 201 spin_lock_irqsave(&wdata->state.lock, flags); \
207 state = !!(wdata->state.flags & WIIPROTO_FLAG_LED##num); \ 202 state = !!(wdata->state.flags & WIIPROTO_FLAG_LED##num); \
208 spin_unlock_irqrestore(&wdata->state.lock, flags); \ 203 spin_unlock_irqrestore(&wdata->state.lock, flags); \
@@ -217,9 +212,6 @@ static ssize_t wiifs_led_set_##num(struct device *dev, \
217 unsigned long flags; \ 212 unsigned long flags; \
218 __u8 state; \ 213 __u8 state; \
219 \ 214 \
220 if (!atomic_read(&wdata->ready)) \
221 return -EBUSY; \
222 \
223 spin_lock_irqsave(&wdata->state.lock, flags); \ 215 spin_lock_irqsave(&wdata->state.lock, flags); \
224 \ 216 \
225 state = wdata->state.flags; \ 217 state = wdata->state.flags; \
@@ -244,13 +236,6 @@ wiifs_led_show_set(4);
244static int wiimote_input_event(struct input_dev *dev, unsigned int type, 236static int wiimote_input_event(struct input_dev *dev, unsigned int type,
245 unsigned int code, int value) 237 unsigned int code, int value)
246{ 238{
247 struct wiimote_data *wdata = input_get_drvdata(dev);
248
249 if (!atomic_read(&wdata->ready))
250 return -EBUSY;
251 /* smp_rmb: Make sure wdata->xy is available when wdata->ready is 1 */
252 smp_rmb();
253
254 return 0; 239 return 0;
255} 240}
256 241
@@ -300,11 +285,6 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
300 int i; 285 int i;
301 unsigned long flags; 286 unsigned long flags;
302 287
303 if (!atomic_read(&wdata->ready))
304 return -EBUSY;
305 /* smp_rmb: Make sure wdata->xy is available when wdata->ready is 1 */
306 smp_rmb();
307
308 if (size < 1) 288 if (size < 1)
309 return -EINVAL; 289 return -EINVAL;
310 290
@@ -362,6 +342,15 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev)
362 342
363static void wiimote_destroy(struct wiimote_data *wdata) 343static void wiimote_destroy(struct wiimote_data *wdata)
364{ 344{
345 device_remove_file(&wdata->hdev->dev, &dev_attr_led1);
346 device_remove_file(&wdata->hdev->dev, &dev_attr_led2);
347 device_remove_file(&wdata->hdev->dev, &dev_attr_led3);
348 device_remove_file(&wdata->hdev->dev, &dev_attr_led4);
349
350 input_unregister_device(wdata->input);
351 cancel_work_sync(&wdata->worker);
352 hid_hw_stop(wdata->hdev);
353
365 kfree(wdata); 354 kfree(wdata);
366} 355}
367 356
@@ -377,19 +366,6 @@ static int wiimote_hid_probe(struct hid_device *hdev,
377 return -ENOMEM; 366 return -ENOMEM;
378 } 367 }
379 368
380 ret = device_create_file(&hdev->dev, &dev_attr_led1);
381 if (ret)
382 goto err;
383 ret = device_create_file(&hdev->dev, &dev_attr_led2);
384 if (ret)
385 goto err;
386 ret = device_create_file(&hdev->dev, &dev_attr_led3);
387 if (ret)
388 goto err;
389 ret = device_create_file(&hdev->dev, &dev_attr_led4);
390 if (ret)
391 goto err;
392
393 ret = hid_parse(hdev); 369 ret = hid_parse(hdev);
394 if (ret) { 370 if (ret) {
395 hid_err(hdev, "HID parse failed\n"); 371 hid_err(hdev, "HID parse failed\n");
@@ -408,9 +384,19 @@ static int wiimote_hid_probe(struct hid_device *hdev,
408 goto err_stop; 384 goto err_stop;
409 } 385 }
410 386
411 /* smp_wmb: Write wdata->xy first before wdata->ready is set to 1 */ 387 ret = device_create_file(&hdev->dev, &dev_attr_led1);
412 smp_wmb(); 388 if (ret)
413 atomic_set(&wdata->ready, 1); 389 goto err_free;
390 ret = device_create_file(&hdev->dev, &dev_attr_led2);
391 if (ret)
392 goto err_free;
393 ret = device_create_file(&hdev->dev, &dev_attr_led3);
394 if (ret)
395 goto err_free;
396 ret = device_create_file(&hdev->dev, &dev_attr_led4);
397 if (ret)
398 goto err_free;
399
414 hid_info(hdev, "New device registered\n"); 400 hid_info(hdev, "New device registered\n");
415 401
416 /* by default set led1 after device initialization */ 402 /* by default set led1 after device initialization */
@@ -420,15 +406,15 @@ static int wiimote_hid_probe(struct hid_device *hdev,
420 406
421 return 0; 407 return 0;
422 408
409err_free:
410 wiimote_destroy(wdata);
411 return ret;
412
423err_stop: 413err_stop:
424 hid_hw_stop(hdev); 414 hid_hw_stop(hdev);
425err: 415err:
426 input_free_device(wdata->input); 416 input_free_device(wdata->input);
427 device_remove_file(&hdev->dev, &dev_attr_led1); 417 kfree(wdata);
428 device_remove_file(&hdev->dev, &dev_attr_led2);
429 device_remove_file(&hdev->dev, &dev_attr_led3);
430 device_remove_file(&hdev->dev, &dev_attr_led4);
431 wiimote_destroy(wdata);
432 return ret; 418 return ret;
433} 419}
434 420
@@ -437,16 +423,6 @@ static void wiimote_hid_remove(struct hid_device *hdev)
437 struct wiimote_data *wdata = hid_get_drvdata(hdev); 423 struct wiimote_data *wdata = hid_get_drvdata(hdev);
438 424
439 hid_info(hdev, "Device removed\n"); 425 hid_info(hdev, "Device removed\n");
440
441 device_remove_file(&hdev->dev, &dev_attr_led1);
442 device_remove_file(&hdev->dev, &dev_attr_led2);
443 device_remove_file(&hdev->dev, &dev_attr_led3);
444 device_remove_file(&hdev->dev, &dev_attr_led4);
445
446 hid_hw_stop(hdev);
447 input_unregister_device(wdata->input);
448
449 cancel_work_sync(&wdata->worker);
450 wiimote_destroy(wdata); 426 wiimote_destroy(wdata);
451} 427}
452 428