aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/IR/ir-core-priv.h2
-rw-r--r--drivers/media/IR/ir-raw-event.c34
2 files changed, 27 insertions, 9 deletions
diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h
index 0ad8ea39b39e..90eb3912c455 100644
--- a/drivers/media/IR/ir-core-priv.h
+++ b/drivers/media/IR/ir-core-priv.h
@@ -17,6 +17,7 @@
17#define _IR_RAW_EVENT 17#define _IR_RAW_EVENT
18 18
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/spinlock.h>
20#include <media/ir-core.h> 21#include <media/ir-core.h>
21 22
22struct ir_raw_handler { 23struct ir_raw_handler {
@@ -33,6 +34,7 @@ struct ir_raw_handler {
33struct ir_raw_event_ctrl { 34struct ir_raw_event_ctrl {
34 struct list_head list; /* to keep track of raw clients */ 35 struct list_head list; /* to keep track of raw clients */
35 struct task_struct *thread; 36 struct task_struct *thread;
37 spinlock_t lock;
36 struct kfifo kfifo; /* fifo for the pulse/space durations */ 38 struct kfifo kfifo; /* fifo for the pulse/space durations */
37 ktime_t last_event; /* when last event occurred */ 39 ktime_t last_event; /* when last event occurred */
38 enum raw_event_type last_type; /* last event type */ 40 enum raw_event_type last_type; /* last event type */
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
index 8e0e1b1f8c87..119b567feeab 100644
--- a/drivers/media/IR/ir-raw-event.c
+++ b/drivers/media/IR/ir-raw-event.c
@@ -39,22 +39,34 @@ static int ir_raw_event_thread(void *data)
39 struct ir_raw_event ev; 39 struct ir_raw_event ev;
40 struct ir_raw_handler *handler; 40 struct ir_raw_handler *handler;
41 struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data; 41 struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data;
42 int retval;
42 43
43 while (!kthread_should_stop()) { 44 while (!kthread_should_stop()) {
44 try_to_freeze();
45 45
46 mutex_lock(&ir_raw_handler_lock); 46 spin_lock_irq(&raw->lock);
47 retval = kfifo_out(&raw->kfifo, &ev, sizeof(ev));
48
49 if (!retval) {
50 set_current_state(TASK_INTERRUPTIBLE);
47 51
48 while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev)) { 52 if (kthread_should_stop())
49 list_for_each_entry(handler, &ir_raw_handler_list, list) 53 set_current_state(TASK_RUNNING);
50 handler->decode(raw->input_dev, ev); 54
51 raw->prev_ev = ev; 55 spin_unlock_irq(&raw->lock);
56 schedule();
57 continue;
52 } 58 }
53 59
54 mutex_unlock(&ir_raw_handler_lock); 60 spin_unlock_irq(&raw->lock);
55 61
56 set_current_state(TASK_INTERRUPTIBLE); 62
57 schedule(); 63 BUG_ON(retval != sizeof(ev));
64
65 mutex_lock(&ir_raw_handler_lock);
66 list_for_each_entry(handler, &ir_raw_handler_list, list)
67 handler->decode(raw->input_dev, ev);
68 raw->prev_ev = ev;
69 mutex_unlock(&ir_raw_handler_lock);
58 } 70 }
59 71
60 return 0; 72 return 0;
@@ -232,11 +244,14 @@ EXPORT_SYMBOL_GPL(ir_raw_event_set_idle);
232void ir_raw_event_handle(struct input_dev *input_dev) 244void ir_raw_event_handle(struct input_dev *input_dev)
233{ 245{
234 struct ir_input_dev *ir = input_get_drvdata(input_dev); 246 struct ir_input_dev *ir = input_get_drvdata(input_dev);
247 unsigned long flags;
235 248
236 if (!ir->raw) 249 if (!ir->raw)
237 return; 250 return;
238 251
252 spin_lock_irqsave(&ir->raw->lock, flags);
239 wake_up_process(ir->raw->thread); 253 wake_up_process(ir->raw->thread);
254 spin_unlock_irqrestore(&ir->raw->lock, flags);
240} 255}
241EXPORT_SYMBOL_GPL(ir_raw_event_handle); 256EXPORT_SYMBOL_GPL(ir_raw_event_handle);
242 257
@@ -275,6 +290,7 @@ int ir_raw_event_register(struct input_dev *input_dev)
275 return rc; 290 return rc;
276 } 291 }
277 292
293 spin_lock_init(&ir->raw->lock);
278 ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw, 294 ir->raw->thread = kthread_run(ir_raw_event_thread, ir->raw,
279 "rc%u", (unsigned int)ir->devno); 295 "rc%u", (unsigned int)ir->devno);
280 296