Commit d731aea0 authored by Jonathan Cameron's avatar Jonathan Cameron Committed by Greg Kroah-Hartman

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: default avatarJonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 02db0bb3
...@@ -162,6 +162,7 @@ struct lis3l02dq_state { ...@@ -162,6 +162,7 @@ struct lis3l02dq_state {
u8 *tx; u8 *tx;
u8 *rx; u8 *rx;
struct mutex buf_lock; struct mutex buf_lock;
bool trigger_on;
}; };
#define lis3l02dq_h_to_s(_h) \ #define lis3l02dq_h_to_s(_h) \
...@@ -202,7 +203,11 @@ void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev); ...@@ -202,7 +203,11 @@ void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev);
#define lis3l02dq_alloc_buf iio_kfifo_allocate #define lis3l02dq_alloc_buf iio_kfifo_allocate
#define lis3l02dq_register_buf_funcs iio_kfifo_register_funcs #define lis3l02dq_register_buf_funcs iio_kfifo_register_funcs
#endif #endif
irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private);
#define lis3l02dq_th lis3l02dq_data_rdy_trig_poll
#else /* CONFIG_IIO_RING_BUFFER */ #else /* CONFIG_IIO_RING_BUFFER */
#define lis3l02dq_th lis3l02dq_noring
static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev) static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
{ {
......
...@@ -35,6 +35,13 @@ ...@@ -35,6 +35,13 @@
* It's in the likely to be added comment at the top of spi.h. * It's in the likely to be added comment at the top of spi.h.
* This means that use cannot be made of spi_write etc. * This means that use cannot be made of spi_write etc.
*/ */
/* direct copy of the irq_default_primary_handler */
#ifndef CONFIG_IIO_RING_BUFFER
static irqreturn_t lis3l02dq_noring(int irq, void *private)
{
return IRQ_WAKE_THREAD;
}
#endif
/** /**
* lis3l02dq_spi_read_reg_8() - read single byte from a single register * 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,19 +564,13 @@ static ssize_t lis3l02dq_read_event_config(struct iio_dev *indio_dev,
int lis3l02dq_disable_all_events(struct iio_dev *indio_dev) int lis3l02dq_disable_all_events(struct iio_dev *indio_dev)
{ {
struct iio_sw_ring_helper_state *h
= iio_dev_get_devdata(indio_dev);
struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
int ret; int ret;
u8 control, val; u8 control, val;
bool irqtofree;
ret = lis3l02dq_spi_read_reg_8(indio_dev, ret = lis3l02dq_spi_read_reg_8(indio_dev,
LIS3L02DQ_REG_CTRL_2_ADDR, LIS3L02DQ_REG_CTRL_2_ADDR,
&control); &control);
irqtofree = !!(control & LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT);
control &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT; control &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT;
ret = lis3l02dq_spi_write_reg_8(indio_dev, ret = lis3l02dq_spi_write_reg_8(indio_dev,
LIS3L02DQ_REG_CTRL_2_ADDR, LIS3L02DQ_REG_CTRL_2_ADDR,
...@@ -590,9 +591,6 @@ int lis3l02dq_disable_all_events(struct iio_dev *indio_dev) ...@@ -590,9 +591,6 @@ int lis3l02dq_disable_all_events(struct iio_dev *indio_dev)
if (ret) if (ret)
goto error_ret; goto error_ret;
if (irqtofree)
free_irq(st->us->irq, indio_dev);
ret = control; ret = control;
error_ret: error_ret:
return ret; return ret;
...@@ -602,9 +600,6 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev, ...@@ -602,9 +600,6 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
int event_code, int event_code,
int state) int state)
{ {
struct iio_sw_ring_helper_state *h
= iio_dev_get_devdata(indio_dev);
struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
int ret = 0; int ret = 0;
u8 val, control; u8 val, control;
u8 currentlyset; u8 currentlyset;
...@@ -636,18 +631,6 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev, ...@@ -636,18 +631,6 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
} }
if (changed) { if (changed) {
if (!(control & LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT)) {
ret = request_threaded_irq(st->us->irq,
NULL,
&lis3l02dq_event_handler,
IRQF_TRIGGER_RISING |
IRQF_ONESHOT,
"lis3l02dq_event",
indio_dev);
if (ret)
goto error_ret;
}
ret = lis3l02dq_spi_write_reg_8(indio_dev, ret = lis3l02dq_spi_write_reg_8(indio_dev,
LIS3L02DQ_REG_WAKE_UP_CFG_ADDR, LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
&val); &val);
...@@ -661,10 +644,6 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev, ...@@ -661,10 +644,6 @@ static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
&control); &control);
if (ret) if (ret)
goto error_ret; goto error_ret;
/* remove interrupt handler if nothing is still on */
if (!(val & 0x3f))
free_irq(st->us->irq, indio_dev);
} }
error_ret: error_ret:
...@@ -748,9 +727,18 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi) ...@@ -748,9 +727,18 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
} }
if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
ret = lis3l02dq_probe_trigger(st->help.indio_dev); ret = request_threaded_irq(st->us->irq,
&lis3l02dq_th,
&lis3l02dq_event_handler,
IRQF_TRIGGER_RISING,
"lis3l02dq",
st->help.indio_dev);
if (ret) if (ret)
goto error_uninitialize_ring; goto error_uninitialize_ring;
ret = lis3l02dq_probe_trigger(st->help.indio_dev);
if (ret)
goto error_free_interrupt;
} }
/* Get the device into a sane initial state */ /* Get the device into a sane initial state */
...@@ -762,6 +750,9 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi) ...@@ -762,6 +750,9 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
error_remove_trigger: error_remove_trigger:
if (st->help.indio_dev->modes & INDIO_RING_TRIGGERED) if (st->help.indio_dev->modes & INDIO_RING_TRIGGERED)
lis3l02dq_remove_trigger(st->help.indio_dev); lis3l02dq_remove_trigger(st->help.indio_dev);
error_free_interrupt:
if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
free_irq(st->us->irq, st->help.indio_dev);
error_uninitialize_ring: error_uninitialize_ring:
iio_ring_buffer_unregister(st->help.indio_dev->ring); iio_ring_buffer_unregister(st->help.indio_dev->ring);
error_unreg_ring_funcs: error_unreg_ring_funcs:
...@@ -823,6 +814,9 @@ static int lis3l02dq_remove(struct spi_device *spi) ...@@ -823,6 +814,9 @@ static int lis3l02dq_remove(struct spi_device *spi)
if (ret) if (ret)
goto err_ret; goto err_ret;
if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
free_irq(st->us->irq, indio_dev);
lis3l02dq_remove_trigger(indio_dev); lis3l02dq_remove_trigger(indio_dev);
iio_ring_buffer_unregister(indio_dev->ring); iio_ring_buffer_unregister(indio_dev->ring);
lis3l02dq_unconfigure_ring(indio_dev); lis3l02dq_unconfigure_ring(indio_dev);
......
...@@ -26,6 +26,22 @@ static inline u16 combine_8_to_16(u8 lower, u8 upper) ...@@ -26,6 +26,22 @@ static inline u16 combine_8_to_16(u8 lower, u8 upper)
return _lower | (_upper << 8); return _lower | (_upper << 8);
} }
/**
* lis3l02dq_data_rdy_trig_poll() the event handler for the data rdy trig
**/
irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private)
{
struct iio_dev *indio_dev = private;
struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
if (st->trigger_on) {
iio_trigger_poll(st->trig, iio_get_time_ns());
return IRQ_HANDLED;
} else
return IRQ_WAKE_THREAD;
}
/** /**
* lis3l02dq_read_accel_from_ring() individual acceleration read from ring * lis3l02dq_read_accel_from_ring() individual acceleration read from ring
**/ **/
...@@ -191,8 +207,7 @@ __lis3l02dq_write_data_ready_config(struct device *dev, bool state) ...@@ -191,8 +207,7 @@ __lis3l02dq_write_data_ready_config(struct device *dev, bool state)
&valold); &valold);
if (ret) if (ret)
goto error_ret; goto error_ret;
st->trigger_on = false;
free_irq(st->us->irq, st->trig);
/* Enable requested */ /* Enable requested */
} else if (state && !currentlyset) { } else if (state && !currentlyset) {
/* if not set, enable requested */ /* if not set, enable requested */
...@@ -203,21 +218,14 @@ __lis3l02dq_write_data_ready_config(struct device *dev, bool state) ...@@ -203,21 +218,14 @@ __lis3l02dq_write_data_ready_config(struct device *dev, bool state)
valold = ret | valold = ret |
LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION; LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
ret = request_irq(st->us->irq,
&iio_trigger_generic_data_rdy_poll,
IRQF_TRIGGER_RISING, "lis3l02dq_datardy",
st->trig);
if (ret)
goto error_ret;
st->trigger_on = true;
ret = lis3l02dq_spi_write_reg_8(indio_dev, ret = lis3l02dq_spi_write_reg_8(indio_dev,
LIS3L02DQ_REG_CTRL_2_ADDR, LIS3L02DQ_REG_CTRL_2_ADDR,
&valold); &valold);
if (ret) { if (ret)
free_irq(st->us->irq, st->trig);
goto error_ret; goto error_ret;
} }
}
return 0; return 0;
error_ret: error_ret:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment