diff options
author | Jonathan Cameron <jic23@cam.ac.uk> | 2011-05-18 09:42:20 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-05-19 19:15:02 -0400 |
commit | d731aea081dc96b91be680c23b844f33aa4759e1 (patch) | |
tree | 5f058839c1eef9495c09ffdb9590c67158fa0ac0 /drivers | |
parent | 02db0bb33acf8afbdb9fb4fbaa99f7185337098f (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.h | 5 | ||||
-rw-r--r-- | drivers/staging/iio/accel/lis3l02dq_core.c | 52 | ||||
-rw-r--r-- | drivers/staging/iio/accel/lis3l02dq_ring.c | 30 |
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 |
206 | irqreturn_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 | ||
207 | static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev) | 212 | static 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 | ||
40 | static 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 | ||
558 | int lis3l02dq_disable_all_events(struct iio_dev *indio_dev) | 565 | int 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; |
597 | error_ret: | 595 | error_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 | ||
670 | error_ret: | 649 | error_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) | |||
762 | error_remove_trigger: | 750 | error_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); |
753 | error_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); | ||
765 | error_uninitialize_ring: | 756 | error_uninitialize_ring: |
766 | iio_ring_buffer_unregister(st->help.indio_dev->ring); | 757 | iio_ring_buffer_unregister(st->help.indio_dev->ring); |
767 | error_unreg_ring_funcs: | 758 | error_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 | **/ | ||
32 | irqreturn_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 | **/ |
32 | ssize_t lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring, | 48 | ssize_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; |