aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
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