iio: imu: st_lsm6dsx: move interrupt thread to core
authorSean Nyekjaer <sean@geanix.com>
Mon, 16 Sep 2019 13:56:26 +0000 (15:56 +0200)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Sat, 5 Oct 2019 11:23:58 +0000 (12:23 +0100)
This prepares the interrupt to be used for other stuff than
fifo reading + event readings.

Signed-off-by: Sean Nyekjaer <sean@geanix.com>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c

index b0f3da1..ef57965 100644 (file)
@@ -30,8 +30,6 @@
  * Denis Ciocca <denis.ciocca@st.com>
  */
 #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>
 
 #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)
@@ -654,25 +648,6 @@ out:
        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 = hw->settings->fifo_ops.read_fifo(hw);
-       mutex_unlock(&hw->fifo_lock);
-
-       return count ? IRQ_HANDLED : IRQ_NONE;
-}
-
 static int st_lsm6dsx_buffer_preenable(struct iio_dev *iio_dev)
 {
        struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
@@ -702,59 +677,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++) {
                if (!hw->iio_devs[i])
index b65a6ca..ef83820 100644 (file)
@@ -50,6 +50,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>
 #define ST_LSM6DSX_REG_BDU_ADDR                        0x12
 #define ST_LSM6DSX_REG_BDU_MASK                        BIT(6)
 
+#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)
+
 static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
        ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
        ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
@@ -1525,6 +1532,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 = hw->settings->fifo_ops.read_fifo(hw);
+       mutex_unlock(&hw->fifo_lock);
+
+       return count ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static 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 0;
+}
+
 int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
                     struct regmap *regmap)
 {
@@ -1573,6 +1657,10 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
        }
 
        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;