aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/lis3lv02d.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/lis3lv02d.c')
-rw-r--r--drivers/hwmon/lis3lv02d.c33
1 files changed, 11 insertions, 22 deletions
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index 159e402ddec3..d9c97e8c53ad 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -343,10 +343,14 @@ static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
343{ 343{
344 if (lis3_dev.pm_dev) 344 if (lis3_dev.pm_dev)
345 pm_runtime_get_sync(lis3_dev.pm_dev); 345 pm_runtime_get_sync(lis3_dev.pm_dev);
346
347 if (lis3_dev.pdata && lis3_dev.whoami == WAI_8B && lis3_dev.idev)
348 atomic_set(&lis3_dev.wake_thread, 1);
346} 349}
347 350
348static void lis3lv02d_joystick_close(struct input_polled_dev *pidev) 351static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
349{ 352{
353 atomic_set(&lis3_dev.wake_thread, 0);
350 if (lis3_dev.pm_dev) 354 if (lis3_dev.pm_dev)
351 pm_runtime_put(lis3_dev.pm_dev); 355 pm_runtime_put(lis3_dev.pm_dev);
352} 356}
@@ -366,8 +370,7 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
366 wake_up_interruptible(&lis3_dev.misc_wait); 370 wake_up_interruptible(&lis3_dev.misc_wait);
367 kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN); 371 kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN);
368out: 372out:
369 if (lis3_dev.pdata && lis3_dev.whoami == WAI_8B && lis3_dev.idev && 373 if (atomic_read(&lis3_dev.wake_thread))
370 lis3_dev.idev->input->users)
371 return IRQ_WAKE_THREAD; 374 return IRQ_WAKE_THREAD;
372 return IRQ_HANDLED; 375 return IRQ_HANDLED;
373} 376}
@@ -398,31 +401,15 @@ static void lis302dl_interrupt_handle_click(struct lis3lv02d *lis3)
398 mutex_unlock(&lis3->mutex); 401 mutex_unlock(&lis3->mutex);
399} 402}
400 403
401static void lis302dl_interrupt_handle_ff_wu(struct lis3lv02d *lis3)
402{
403 u8 wu1_src;
404 u8 wu2_src;
405
406 lis3->read(lis3, FF_WU_SRC_1, &wu1_src);
407 lis3->read(lis3, FF_WU_SRC_2, &wu2_src);
408
409 wu1_src = wu1_src & FF_WU_SRC_IA ? wu1_src : 0;
410 wu2_src = wu2_src & FF_WU_SRC_IA ? wu2_src : 0;
411
412 /* joystick poll is internally protected by the lis3->mutex. */
413 if (wu1_src || wu2_src)
414 lis3lv02d_joystick_poll(lis3_dev.idev);
415}
416
417static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data) 404static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
418{ 405{
419 406
420 struct lis3lv02d *lis3 = data; 407 struct lis3lv02d *lis3 = data;
421 408
422 if ((lis3->pdata->irq_cfg & LIS3_IRQ1_MASK) == LIS3_IRQ1_CLICK) 409 if ((lis3->irq_cfg & LIS3_IRQ1_MASK) == LIS3_IRQ1_CLICK)
423 lis302dl_interrupt_handle_click(lis3); 410 lis302dl_interrupt_handle_click(lis3);
424 else 411 else
425 lis302dl_interrupt_handle_ff_wu(lis3); 412 lis3lv02d_joystick_poll(lis3->idev);
426 413
427 return IRQ_HANDLED; 414 return IRQ_HANDLED;
428} 415}
@@ -432,10 +419,10 @@ static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data)
432 419
433 struct lis3lv02d *lis3 = data; 420 struct lis3lv02d *lis3 = data;
434 421
435 if ((lis3->pdata->irq_cfg & LIS3_IRQ2_MASK) == LIS3_IRQ2_CLICK) 422 if ((lis3->irq_cfg & LIS3_IRQ2_MASK) == LIS3_IRQ2_CLICK)
436 lis302dl_interrupt_handle_click(lis3); 423 lis302dl_interrupt_handle_click(lis3);
437 else 424 else
438 lis302dl_interrupt_handle_ff_wu(lis3); 425 lis3lv02d_joystick_poll(lis3->idev);
439 426
440 return IRQ_HANDLED; 427 return IRQ_HANDLED;
441} 428}
@@ -831,6 +818,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
831 } 818 }
832 819
833 mutex_init(&dev->mutex); 820 mutex_init(&dev->mutex);
821 atomic_set(&dev->wake_thread, 0);
834 822
835 lis3lv02d_add_fs(dev); 823 lis3lv02d_add_fs(dev);
836 lis3lv02d_poweron(dev); 824 lis3lv02d_poweron(dev);
@@ -851,6 +839,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
851 if (dev->whoami == WAI_8B) 839 if (dev->whoami == WAI_8B)
852 lis3lv02d_8b_configure(dev, p); 840 lis3lv02d_8b_configure(dev, p);
853 841
842 dev->irq_cfg = p->irq_cfg;
854 if (p->irq_cfg) 843 if (p->irq_cfg)
855 dev->write(dev, CTRL_REG3, p->irq_cfg); 844 dev->write(dev, CTRL_REG3, p->irq_cfg);
856 } 845 }