aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/hid-wiimote.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c
index c811a7d14174..0a5e458820b2 100644
--- a/drivers/hid/hid-wiimote.c
+++ b/drivers/hid/hid-wiimote.c
@@ -10,11 +10,13 @@
10 * any later version. 10 * any later version.
11 */ 11 */
12 12
13#include <linux/completion.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>
16#include <linux/leds.h> 17#include <linux/leds.h>
17#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/mutex.h>
18#include <linux/spinlock.h> 20#include <linux/spinlock.h>
19#include "hid-ids.h" 21#include "hid-ids.h"
20 22
@@ -31,6 +33,12 @@ struct wiimote_state {
31 spinlock_t lock; 33 spinlock_t lock;
32 __u8 flags; 34 __u8 flags;
33 __u8 accel_split[2]; 35 __u8 accel_split[2];
36
37 /* synchronous cmd requests */
38 struct mutex sync;
39 struct completion ready;
40 int cmd;
41 __u32 opt;
34}; 42};
35 43
36struct wiimote_data { 44struct wiimote_data {
@@ -118,6 +126,52 @@ static __u16 wiiproto_keymap[] = {
118 BTN_MODE, /* WIIPROTO_KEY_HOME */ 126 BTN_MODE, /* WIIPROTO_KEY_HOME */
119}; 127};
120 128
129/* requires the state.lock spinlock to be held */
130static inline bool wiimote_cmd_pending(struct wiimote_data *wdata, int cmd,
131 __u32 opt)
132{
133 return wdata->state.cmd == cmd && wdata->state.opt == opt;
134}
135
136/* requires the state.lock spinlock to be held */
137static inline void wiimote_cmd_complete(struct wiimote_data *wdata)
138{
139 wdata->state.cmd = WIIPROTO_REQ_NULL;
140 complete(&wdata->state.ready);
141}
142
143static inline int wiimote_cmd_acquire(struct wiimote_data *wdata)
144{
145 return mutex_lock_interruptible(&wdata->state.sync) ? -ERESTARTSYS : 0;
146}
147
148/* requires the state.lock spinlock to be held */
149static inline void wiimote_cmd_set(struct wiimote_data *wdata, int cmd,
150 __u32 opt)
151{
152 INIT_COMPLETION(wdata->state.ready);
153 wdata->state.cmd = cmd;
154 wdata->state.opt = opt;
155}
156
157static inline void wiimote_cmd_release(struct wiimote_data *wdata)
158{
159 mutex_unlock(&wdata->state.sync);
160}
161
162static inline int wiimote_cmd_wait(struct wiimote_data *wdata)
163{
164 int ret;
165
166 ret = wait_for_completion_interruptible_timeout(&wdata->state.ready, HZ);
167 if (ret < 0)
168 return -ERESTARTSYS;
169 else if (ret == 0)
170 return -EIO;
171 else
172 return 0;
173}
174
121static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer, 175static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer,
122 size_t count) 176 size_t count)
123{ 177{
@@ -875,6 +929,8 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev)
875 INIT_WORK(&wdata->worker, wiimote_worker); 929 INIT_WORK(&wdata->worker, wiimote_worker);
876 930
877 spin_lock_init(&wdata->state.lock); 931 spin_lock_init(&wdata->state.lock);
932 init_completion(&wdata->state.ready);
933 mutex_init(&wdata->state.sync);
878 934
879 return wdata; 935 return wdata;
880 936