aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/IR/ir-raw-event.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/IR/ir-raw-event.c')
-rw-r--r--drivers/media/IR/ir-raw-event.c34
1 files changed, 25 insertions, 9 deletions
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