aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJonathan Cameron <jic23@cam.ac.uk>2011-05-18 09:42:20 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-05-19 19:15:02 -0400
commitd731aea081dc96b91be680c23b844f33aa4759e1 (patch)
tree5f058839c1eef9495c09ffdb9590c67158fa0ac0 /drivers
parent02db0bb33acf8afbdb9fb4fbaa99f7185337098f (diff)
staging:iio:lis3l02dq remerge the two interrupt handlers.
Does add a small burden to both handlers, but the gain is somewhat simpler code. Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/iio/accel/lis3l02dq.h5
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_core.c52
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_ring.c30
3 files changed, 47 insertions, 40 deletions
diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h
index a910f2d430ff..3f1d7c678867 100644
--- a/drivers/staging/iio/accel/lis3l02dq.h
+++ b/drivers/staging/iio/accel/lis3l02dq.h
@@ -162,6 +162,7 @@ struct lis3l02dq_state {
162 u8 *tx; 162 u8 *tx;
163 u8 *rx; 163 u8 *rx;
164 struct mutex buf_lock; 164 struct mutex buf_lock;
165 bool trigger_on;
165}; 166};
166 167
167#define lis3l02dq_h_to_s(_h) \ 168#define lis3l02dq_h_to_s(_h) \
@@ -202,7 +203,11 @@ void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev);
202#define lis3l02dq_alloc_buf iio_kfifo_allocate 203#define lis3l02dq_alloc_buf iio_kfifo_allocate
203#define lis3l02dq_register_buf_funcs iio_kfifo_register_funcs 204#define lis3l02dq_register_buf_funcs iio_kfifo_register_funcs
204#endif 205#endif
206irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private);
207#define lis3l02dq_th lis3l02dq_data_rdy_trig_poll
208
205#else /* CONFIG_IIO_RING_BUFFER */ 209#else /* CONFIG_IIO_RING_BUFFER */
210#define lis3l02dq_th lis3l02dq_noring
206 211
207static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev) 212static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
208{ 213{
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 8793ee424993..42261b50b437 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -35,6 +35,13 @@
35 * It's in the likely to be added comment at the top of spi.h. 35 * It's in the likely to be added comment at the top of spi.h.
36 * This means that use cannot be made of spi_write etc. 36 * This means that use cannot be made of spi_write etc.
37 */ 37 */
38/* direct copy of the irq_default_primary_handler */
39#ifndef CONFIG_IIO_RING_BUFFER
40static irqreturn_t lis3l02dq_noring(int irq, void *private)
41{
42 return IRQ_WAKE_THREAD;
43}
44#endif
38 45
39/** 46/**
40 * lis3l02dq_spi_read_reg_8() - read single byte from a single register 47 * lis3l02dq_spi_read_reg_8() - read single byte from a single register
@@ -557,19 +564,13 @@ static ssize_t lis3l02dq_read_event_config(struct iio_dev *indio_dev,
557 564
558int lis3l02dq_disable_all_events(struct iio_dev *indio_dev) 565int lis3l02dq_disable_all_events(struct iio_dev *indio_dev)
559{ 566{
560 struct iio_sw_ring_helper_state *h
561 = iio_dev_get_devdata(indio_dev);
562 struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
563 int ret; 567 int ret;
564 u8 control, val; 568 u8 control, val;
565 bool irqtofree;
566 569
567 ret = lis3l02dq_spi_read_reg_8(indio_dev, 570 ret = lis3l02dq_spi_read_reg_8(indio_dev,
568 LIS3L02DQ_REG_CTRL_2_ADDR, 571 LIS3L02DQ_REG_CTRL_2_ADDR,
569 &control); 572 &control);
570 573
571 irqtofree = !!(control & LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT);
572
573 control &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT; 574 control &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT;
574 ret = lis3l02dq_spi_write_reg_8(indio_dev, 575 ret = lis3l02dq_spi_write_reg_8(indio_dev,
575 LIS3L02DQ_REG_CTRL_2_ADDR, 576 LIS3L02DQ_REG_CTRL_2_ADDR,
@@ -590,9 +591,6 @@ int lis3l02dq_disable_all_events(struct iio_dev *indio_dev)
590 if (ret) 591 if (ret)
591 goto error_ret; 592 goto error_ret;
592 593
593 if (irqtofree)
594 free_irq(st->us->irq, indio_dev);
595
596 ret = control; 594 ret = control;
597error_ret: 595error_ret:
598 return ret; 596 return ret;
@@ -602,9 +600,6 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
602 int event_code, 600 int event_code,
603 int state) 601 int state)
604{ 602{
605 struct iio_sw_ring_helper_state *h
606 = iio_dev_get_devdata(indio_dev);
607 struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
608 int ret = 0; 603 int ret = 0;
609 u8 val, control; 604 u8 val, control;
610 u8 currentlyset; 605 u8 currentlyset;
@@ -636,18 +631,6 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
636 } 631 }
637 632
638 if (changed) { 633 if (changed) {
639 if (!(control & LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT)) {
640 ret = request_threaded_irq(st->us->irq,
641 NULL,
642 &lis3l02dq_event_handler,
643 IRQF_TRIGGER_RISING |
644 IRQF_ONESHOT,
645 "lis3l02dq_event",
646 indio_dev);
647 if (ret)
648 goto error_ret;
649 }
650
651 ret = lis3l02dq_spi_write_reg_8(indio_dev, 634 ret = lis3l02dq_spi_write_reg_8(indio_dev,
652 LIS3L02DQ_REG_WAKE_UP_CFG_ADDR, 635 LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
653 &val); 636 &val);
@@ -661,10 +644,6 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
661 &control); 644 &control);
662 if (ret) 645 if (ret)
663 goto error_ret; 646 goto error_ret;
664
665 /* remove interrupt handler if nothing is still on */
666 if (!(val & 0x3f))
667 free_irq(st->us->irq, indio_dev);
668 } 647 }
669 648
670error_ret: 649error_ret:
@@ -748,9 +727,18 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
748 } 727 }
749 728
750 if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { 729 if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
751 ret = lis3l02dq_probe_trigger(st->help.indio_dev); 730 ret = request_threaded_irq(st->us->irq,
731 &lis3l02dq_th,
732 &lis3l02dq_event_handler,
733 IRQF_TRIGGER_RISING,
734 "lis3l02dq",
735 st->help.indio_dev);
752 if (ret) 736 if (ret)
753 goto error_uninitialize_ring; 737 goto error_uninitialize_ring;
738
739 ret = lis3l02dq_probe_trigger(st->help.indio_dev);
740 if (ret)
741 goto error_free_interrupt;
754 } 742 }
755 743
756 /* Get the device into a sane initial state */ 744 /* Get the device into a sane initial state */
@@ -762,6 +750,9 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
762error_remove_trigger: 750error_remove_trigger:
763 if (st->help.indio_dev->modes & INDIO_RING_TRIGGERED) 751 if (st->help.indio_dev->modes & INDIO_RING_TRIGGERED)
764 lis3l02dq_remove_trigger(st->help.indio_dev); 752 lis3l02dq_remove_trigger(st->help.indio_dev);
753error_free_interrupt:
754 if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
755 free_irq(st->us->irq, st->help.indio_dev);
765error_uninitialize_ring: 756error_uninitialize_ring:
766 iio_ring_buffer_unregister(st->help.indio_dev->ring); 757 iio_ring_buffer_unregister(st->help.indio_dev->ring);
767error_unreg_ring_funcs: 758error_unreg_ring_funcs:
@@ -823,6 +814,9 @@ static int lis3l02dq_remove(struct spi_device *spi)
823 if (ret) 814 if (ret)
824 goto err_ret; 815 goto err_ret;
825 816
817 if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
818 free_irq(st->us->irq, indio_dev);
819
826 lis3l02dq_remove_trigger(indio_dev); 820 lis3l02dq_remove_trigger(indio_dev);
827 iio_ring_buffer_unregister(indio_dev->ring); 821 iio_ring_buffer_unregister(indio_dev->ring);
828 lis3l02dq_unconfigure_ring(indio_dev); 822 lis3l02dq_unconfigure_ring(indio_dev);
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index d261bd612bbd..83f2bbeb2dcf 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -27,6 +27,22 @@ static inline u16 combine_8_to_16(u8 lower, u8 upper)
27} 27}
28 28
29/** 29/**
30 * lis3l02dq_data_rdy_trig_poll() the event handler for the data rdy trig
31 **/
32irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private)
33{
34 struct iio_dev *indio_dev = private;
35 struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
36 struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
37
38 if (st->trigger_on) {
39 iio_trigger_poll(st->trig, iio_get_time_ns());
40 return IRQ_HANDLED;
41 } else
42 return IRQ_WAKE_THREAD;
43}
44
45/**
30 * lis3l02dq_read_accel_from_ring() individual acceleration read from ring 46 * lis3l02dq_read_accel_from_ring() individual acceleration read from ring
31 **/ 47 **/
32ssize_t lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring, 48ssize_t lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring,
@@ -191,8 +207,7 @@ __lis3l02dq_write_data_ready_config(struct device *dev, bool state)
191 &valold); 207 &valold);
192 if (ret) 208 if (ret)
193 goto error_ret; 209 goto error_ret;
194 210 st->trigger_on = false;
195 free_irq(st->us->irq, st->trig);
196/* Enable requested */ 211/* Enable requested */
197 } else if (state && !currentlyset) { 212 } else if (state && !currentlyset) {
198 /* if not set, enable requested */ 213 /* if not set, enable requested */
@@ -203,20 +218,13 @@ __lis3l02dq_write_data_ready_config(struct device *dev, bool state)
203 218
204 valold = ret | 219 valold = ret |
205 LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION; 220 LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
206 ret = request_irq(st->us->irq,
207 &iio_trigger_generic_data_rdy_poll,
208 IRQF_TRIGGER_RISING, "lis3l02dq_datardy",
209 st->trig);
210 if (ret)
211 goto error_ret;
212 221
222 st->trigger_on = true;
213 ret = lis3l02dq_spi_write_reg_8(indio_dev, 223 ret = lis3l02dq_spi_write_reg_8(indio_dev,
214 LIS3L02DQ_REG_CTRL_2_ADDR, 224 LIS3L02DQ_REG_CTRL_2_ADDR,
215 &valold); 225 &valold);
216 if (ret) { 226 if (ret)
217 free_irq(st->us->irq, st->trig);
218 goto error_ret; 227 goto error_ret;
219 }
220 } 228 }
221 229
222 return 0; 230 return 0;