Re: [PATCH 1/5] iio: imu: st_lsm6dsx: move interrupt thread to core

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 18 Jun 2019, at 17.57, Lorenzo Bianconi <lorenzo@xxxxxxxxxx> wrote:

>> This prepares the interrupt to be used for other stuff than
>> fifo reading -> event readings.
>> 
>> Signed-off-by: Sean Nyekjaer <sean@xxxxxxxxxx>
>> ---
>> drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h       |  1 +
>> .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c    | 80 +----------------
>> drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c  | 87 +++++++++++++++++++
>> 3 files changed, 90 insertions(+), 78 deletions(-)
>> 
> 
> I can't see why we need this patch
> 
> Regards,
> Lorenzo

The interrupt handling isn’t only for fifo reading, so I think it’s correct to move it out of the buffer handling file.

/Sean
> 
>> diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
>> index edcd838037cd..a5e373680e9c 100644
>> --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
>> +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
>> @@ -175,5 +175,6 @@ int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor,
>> int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw);
>> int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw,
>>                 enum st_lsm6dsx_fifo_mode fifo_mode);
>> +int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw);
>> 
>> #endif /* ST_LSM6DSX_H */
>> diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
>> index 631360b14ca7..a1ed61a64a64 100644
>> --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
>> +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
>> @@ -25,8 +25,6 @@
>>  * Licensed under the GPL-2.
>>  */
>> #include <linux/module.h>
>> -#include <linux/interrupt.h>
>> -#include <linux/irq.h>
>> #include <linux/iio/kfifo_buf.h>
>> #include <linux/iio/iio.h>
>> #include <linux/iio/buffer.h>
>> @@ -37,10 +35,6 @@
>> 
>> #include "st_lsm6dsx.h"
>> 
>> -#define ST_LSM6DSX_REG_HLACTIVE_ADDR        0x12
>> -#define ST_LSM6DSX_REG_HLACTIVE_MASK        BIT(5)
>> -#define ST_LSM6DSX_REG_PP_OD_ADDR        0x12
>> -#define ST_LSM6DSX_REG_PP_OD_MASK        BIT(4)
>> #define ST_LSM6DSX_REG_FIFO_MODE_ADDR        0x0a
>> #define ST_LSM6DSX_FIFO_MODE_MASK        GENMASK(2, 0)
>> #define ST_LSM6DSX_FIFO_ODR_MASK        GENMASK(6, 3)
>> @@ -282,7 +276,7 @@ static inline int st_lsm6dsx_read_block(struct st_lsm6dsx_hw *hw, u8 *data,
>>  *
>>  * Return: Number of bytes read from the FIFO
>>  */
>> -static int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
>> +int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
>> {
>>    u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE;
>>    u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask;
>> @@ -465,25 +459,6 @@ static int st_lsm6dsx_update_fifo(struct iio_dev *iio_dev, bool enable)
>>    return err;
>> }
>> 
>> -static irqreturn_t st_lsm6dsx_handler_irq(int irq, void *private)
>> -{
>> -    struct st_lsm6dsx_hw *hw = private;
>> -
>> -    return hw->sip > 0 ? IRQ_WAKE_THREAD : IRQ_NONE;
>> -}
>> -
>> -static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
>> -{
>> -    struct st_lsm6dsx_hw *hw = private;
>> -    int count;
>> -
>> -    mutex_lock(&hw->fifo_lock);
>> -    count = st_lsm6dsx_read_fifo(hw);
>> -    mutex_unlock(&hw->fifo_lock);
>> -
>> -    return !count ? IRQ_NONE : IRQ_HANDLED;
>> -}
>> -
>> static int st_lsm6dsx_buffer_preenable(struct iio_dev *iio_dev)
>> {
>>    return st_lsm6dsx_update_fifo(iio_dev, true);
>> @@ -501,59 +476,8 @@ static const struct iio_buffer_setup_ops st_lsm6dsx_buffer_ops = {
>> 
>> int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw)
>> {
>> -    struct device_node *np = hw->dev->of_node;
>> -    struct st_sensors_platform_data *pdata;
>>    struct iio_buffer *buffer;
>> -    unsigned long irq_type;
>> -    bool irq_active_low;
>> -    int i, err;
>> -
>> -    irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
>> -
>> -    switch (irq_type) {
>> -    case IRQF_TRIGGER_HIGH:
>> -    case IRQF_TRIGGER_RISING:
>> -        irq_active_low = false;
>> -        break;
>> -    case IRQF_TRIGGER_LOW:
>> -    case IRQF_TRIGGER_FALLING:
>> -        irq_active_low = true;
>> -        break;
>> -    default:
>> -        dev_info(hw->dev, "mode %lx unsupported\n", irq_type);
>> -        return -EINVAL;
>> -    }
>> -
>> -    err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_HLACTIVE_ADDR,
>> -                 ST_LSM6DSX_REG_HLACTIVE_MASK,
>> -                 FIELD_PREP(ST_LSM6DSX_REG_HLACTIVE_MASK,
>> -                        irq_active_low));
>> -    if (err < 0)
>> -        return err;
>> -
>> -    pdata = (struct st_sensors_platform_data *)hw->dev->platform_data;
>> -    if ((np && of_property_read_bool(np, "drive-open-drain")) ||
>> -        (pdata && pdata->open_drain)) {
>> -        err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_PP_OD_ADDR,
>> -                     ST_LSM6DSX_REG_PP_OD_MASK,
>> -                     FIELD_PREP(ST_LSM6DSX_REG_PP_OD_MASK,
>> -                            1));
>> -        if (err < 0)
>> -            return err;
>> -
>> -        irq_type |= IRQF_SHARED;
>> -    }
>> -
>> -    err = devm_request_threaded_irq(hw->dev, hw->irq,
>> -                    st_lsm6dsx_handler_irq,
>> -                    st_lsm6dsx_handler_thread,
>> -                    irq_type | IRQF_ONESHOT,
>> -                    "lsm6dsx", hw);
>> -    if (err) {
>> -        dev_err(hw->dev, "failed to request trigger irq %d\n",
>> -            hw->irq);
>> -        return err;
>> -    }
>> +    int i;
>> 
>>    for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
>>        buffer = devm_iio_kfifo_allocate(hw->dev);
>> diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
>> index aebbe0ddd8d8..b5d3fa354de7 100644
>> --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
>> +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
>> @@ -36,6 +36,8 @@
>> #include <linux/delay.h>
>> #include <linux/iio/iio.h>
>> #include <linux/iio/sysfs.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/irq.h>
>> #include <linux/pm.h>
>> #include <linux/regmap.h>
>> #include <linux/bitfield.h>
>> @@ -55,6 +57,11 @@
>> #define ST_LSM6DSX_REG_INT2_ON_INT1_ADDR    0x13
>> #define ST_LSM6DSX_REG_INT2_ON_INT1_MASK    BIT(5)
>> 
>> +#define ST_LSM6DSX_REG_HLACTIVE_ADDR        0x12
>> +#define ST_LSM6DSX_REG_HLACTIVE_MASK        BIT(5)
>> +#define ST_LSM6DSX_REG_PP_OD_ADDR        0x12
>> +#define ST_LSM6DSX_REG_PP_OD_MASK        BIT(4)
>> +
>> #define ST_LSM6DSX_REG_ACC_ODR_ADDR        0x10
>> #define ST_LSM6DSX_REG_ACC_ODR_MASK        GENMASK(7, 4)
>> #define ST_LSM6DSX_REG_ACC_FS_ADDR        0x10
>> @@ -804,6 +811,83 @@ static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
>>    return iio_dev;
>> }
>> 
>> +static irqreturn_t st_lsm6dsx_handler_irq(int irq, void *private)
>> +{
>> +    struct st_lsm6dsx_hw *hw = private;
>> +
>> +    return hw->sip > 0 ? IRQ_WAKE_THREAD : IRQ_NONE;
>> +}
>> +
>> +static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
>> +{
>> +    struct st_lsm6dsx_hw *hw = private;
>> +    int count;
>> +
>> +    mutex_lock(&hw->fifo_lock);
>> +    count = st_lsm6dsx_read_fifo(hw);
>> +    mutex_unlock(&hw->fifo_lock);
>> +
>> +    return !count ? IRQ_NONE : IRQ_HANDLED;
>> +}
>> +
>> +int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw)
>> +{
>> +    struct st_sensors_platform_data *pdata;
>> +    struct device_node *np = hw->dev->of_node;
>> +    unsigned long irq_type;
>> +    bool irq_active_low;
>> +    int err;
>> +
>> +    irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
>> +
>> +    switch (irq_type) {
>> +    case IRQF_TRIGGER_HIGH:
>> +    case IRQF_TRIGGER_RISING:
>> +        irq_active_low = false;
>> +        break;
>> +    case IRQF_TRIGGER_LOW:
>> +    case IRQF_TRIGGER_FALLING:
>> +        irq_active_low = true;
>> +        break;
>> +    default:
>> +        dev_info(hw->dev, "mode %lx unsupported\n", irq_type);
>> +        return -EINVAL;
>> +    }
>> +
>> +    err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_HLACTIVE_ADDR,
>> +                 ST_LSM6DSX_REG_HLACTIVE_MASK,
>> +                 FIELD_PREP(ST_LSM6DSX_REG_HLACTIVE_MASK,
>> +                        irq_active_low));
>> +    if (err < 0)
>> +        return err;
>> +
>> +    pdata = (struct st_sensors_platform_data *)hw->dev->platform_data;
>> +    if ((np && of_property_read_bool(np, "drive-open-drain")) ||
>> +        (pdata && pdata->open_drain)) {
>> +        err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_PP_OD_ADDR,
>> +                     ST_LSM6DSX_REG_PP_OD_MASK,
>> +                     FIELD_PREP(ST_LSM6DSX_REG_PP_OD_MASK,
>> +                            1));
>> +        if (err < 0)
>> +            return err;
>> +
>> +        irq_type |= IRQF_SHARED;
>> +    }
>> +
>> +    err = devm_request_threaded_irq(hw->dev, hw->irq,
>> +                    st_lsm6dsx_handler_irq,
>> +                    st_lsm6dsx_handler_thread,
>> +                    irq_type | IRQF_ONESHOT,
>> +                    "lsm6dsx", hw);
>> +    if (err) {
>> +        dev_err(hw->dev, "failed to request trigger irq %d\n",
>> +            hw->irq);
>> +        return err;
>> +    }
>> +
>> +    return err;
>> +}
>> +
>> int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name,
>>             struct regmap *regmap)
>> {
>> @@ -842,6 +926,9 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name,
>>        return err;
>> 
>>    if (hw->irq > 0) {
>> +        err = st_lsm6dsx_irq_setup(hw);
>> +        if (err < 0)
>> +            return err;
>>        err = st_lsm6dsx_fifo_setup(hw);
>>        if (err < 0)
>>            return err;
>> -- 
>> 2.22.0
>> 




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux