aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@googlemail.com>2011-07-05 07:45:12 -0400
committerJiri Kosina <jkosina@suse.cz>2011-07-11 08:30:22 -0400
commit4d36e9754f6b71870a476e84f418a864c2ddf77c (patch)
tree0fa70d8c1f443d6077cc1bcd0996bc6b39a48dd3 /drivers/hid
parent672bc4e090c9a2c655c28f8295e981609a1b84ba (diff)
HID: wiimote: Synchronize wiimote input and hid event handling
The wiimote first starts HID hardware and then registers the input device. We need to synchronize the startup so no event handler will start parsing events when the wiimote device is not ready, yet. 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.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c
index deaf23207812..3416f69302cd 100644
--- a/drivers/hid/hid-wiimote.c
+++ b/drivers/hid/hid-wiimote.c
@@ -10,6 +10,7 @@
10 * any later version. 10 * any later version.
11 */ 11 */
12 12
13#include <linux/atomic.h>
13#include <linux/device.h> 14#include <linux/device.h>
14#include <linux/hid.h> 15#include <linux/hid.h>
15#include <linux/input.h> 16#include <linux/input.h>
@@ -20,6 +21,7 @@
20#define WIIMOTE_NAME "Nintendo Wii Remote" 21#define WIIMOTE_NAME "Nintendo Wii Remote"
21 22
22struct wiimote_data { 23struct wiimote_data {
24 atomic_t ready;
23 struct hid_device *hdev; 25 struct hid_device *hdev;
24 struct input_dev *input; 26 struct input_dev *input;
25}; 27};
@@ -27,12 +29,26 @@ struct wiimote_data {
27static int wiimote_input_event(struct input_dev *dev, unsigned int type, 29static int wiimote_input_event(struct input_dev *dev, unsigned int type,
28 unsigned int code, int value) 30 unsigned int code, int value)
29{ 31{
32 struct wiimote_data *wdata = input_get_drvdata(dev);
33
34 if (!atomic_read(&wdata->ready))
35 return -EBUSY;
36 /* smp_rmb: Make sure wdata->xy is available when wdata->ready is 1 */
37 smp_rmb();
38
30 return 0; 39 return 0;
31} 40}
32 41
33static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report, 42static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
34 u8 *raw_data, int size) 43 u8 *raw_data, int size)
35{ 44{
45 struct wiimote_data *wdata = hid_get_drvdata(hdev);
46
47 if (!atomic_read(&wdata->ready))
48 return -EBUSY;
49 /* smp_rmb: Make sure wdata->xy is available when wdata->ready is 1 */
50 smp_rmb();
51
36 if (size < 1) 52 if (size < 1)
37 return -EINVAL; 53 return -EINVAL;
38 54
@@ -103,6 +119,9 @@ static int wiimote_hid_probe(struct hid_device *hdev,
103 goto err_stop; 119 goto err_stop;
104 } 120 }
105 121
122 /* smp_wmb: Write wdata->xy first before wdata->ready is set to 1 */
123 smp_wmb();
124 atomic_set(&wdata->ready, 1);
106 hid_info(hdev, "New device registered\n"); 125 hid_info(hdev, "New device registered\n");
107 return 0; 126 return 0;
108 127