[PATCH v3 15/18] iio: accel: bma220: add interrupt trigger

Petre Rodan posted 18 patches 2 weeks, 5 days ago
[PATCH v3 15/18] iio: accel: bma220: add interrupt trigger
Posted by Petre Rodan 2 weeks, 5 days ago
Add interrupt trigger.

Signed-off-by: Petre Rodan <petre.rodan@subdimension.ro>
---
v1->v2 no change, just patch split
v2->v3 replace regmap_bulk_read with regmap_read (Jonathan)
 (I just realized BMA220_REG_IF0 is never used, even by future event
patches)
---
 drivers/iio/accel/bma220_core.c | 61 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/drivers/iio/accel/bma220_core.c b/drivers/iio/accel/bma220_core.c
index 425a8b981e141aa496351f29df0597c989aa4a0a..6297882bcf1b955291a2d8747984648bc6ee8512 100644
--- a/drivers/iio/accel/bma220_core.c
+++ b/drivers/iio/accel/bma220_core.c
@@ -23,6 +23,7 @@
 #include <linux/iio/buffer.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/triggered_buffer.h>
 
@@ -125,6 +126,7 @@ struct bma220_data {
 	struct regmap *regmap;
 	struct mutex lock;
 	u8 range_idx;
+	struct iio_trigger *trig;
 	struct {
 		s8 chans[3];
 		/* Ensure timestamp is naturally aligned. */
@@ -193,6 +195,23 @@ const struct regmap_config bma220_i2c_regmap_config = {
 };
 EXPORT_SYMBOL_NS_GPL(bma220_i2c_regmap_config, "IIO_BOSCH_BMA220");
 
+static int bma220_data_rdy_trigger_set_state(struct iio_trigger *trig,
+					     bool state)
+{
+	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+	struct bma220_data *data = iio_priv(indio_dev);
+
+	guard(mutex)(&data->lock);
+	return regmap_update_bits(data->regmap, BMA220_REG_IE0,
+				  BMA220_INT_EN_DRDY_MSK,
+				  FIELD_PREP(BMA220_INT_EN_DRDY_MSK, state));
+}
+
+static const struct iio_trigger_ops bma220_trigger_ops = {
+	.set_trigger_state = &bma220_data_rdy_trigger_set_state,
+	.validate_device = &iio_trigger_validate_own_device,
+};
+
 static irqreturn_t bma220_trigger_handler(int irq, void *p)
 {
 	int ret;
@@ -417,6 +436,24 @@ static void bma220_deinit(void *data_ptr)
 			 ERR_PTR(ret));
 }
 
+static irqreturn_t bma220_irq_handler(int irq, void *private)
+{
+	struct iio_dev *indio_dev = private;
+	struct bma220_data *data = iio_priv(indio_dev);
+	int rv;
+	unsigned int bma220_reg_if1;
+
+	guard(mutex)(&data->lock);
+	rv = regmap_read(data->regmap, BMA220_REG_IF1, &bma220_reg_if1);
+	if (rv)
+		return IRQ_NONE;
+
+	if (FIELD_GET(BMA220_IF_DRDY, bma220_reg_if1)) {
+		iio_trigger_poll_nested(data->trig);
+
+	return IRQ_HANDLED;
+}
+
 int bma220_common_probe(struct device *dev, struct regmap *regmap, int irq)
 {
 	int ret;
@@ -446,6 +483,30 @@ int bma220_common_probe(struct device *dev, struct regmap *regmap, int irq)
 	indio_dev->num_channels = ARRAY_SIZE(bma220_channels);
 	indio_dev->available_scan_masks = bma220_accel_scan_masks;
 
+	if (irq > 0) {
+		data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d",
+						    indio_dev->name,
+						    iio_device_id(indio_dev));
+		if (!data->trig)
+			return -ENOMEM;
+
+		data->trig->ops = &bma220_trigger_ops;
+		iio_trigger_set_drvdata(data->trig, indio_dev);
+
+		ret = devm_iio_trigger_register(dev, data->trig);
+		if (ret)
+			return dev_err_probe(dev, ret,
+					     "iio trigger register fail\n");
+		indio_dev->trig = iio_trigger_get(data->trig);
+		ret = devm_request_threaded_irq(dev, irq, NULL,
+						&bma220_irq_handler,
+						IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+						indio_dev->name, indio_dev);
+		if (ret)
+			return dev_err_probe(dev, ret,
+					     "request irq %d failed\n", irq);
+	}
+
 	ret = devm_add_action_or_reset(dev, bma220_deinit, data);
 	if (ret)
 		return ret;

-- 
2.49.1
Re: [PATCH v3 15/18] iio: accel: bma220: add interrupt trigger
Posted by Jonathan Cameron 5 days, 2 hours ago
On Sat, 13 Sep 2025 18:39:36 +0300
Petre Rodan <petre.rodan@subdimension.ro> wrote:

> Add interrupt trigger.
> 
> Signed-off-by: Petre Rodan <petre.rodan@subdimension.ro>
Hi Petre

A few lock questions from a fresh look.
Sorry for delay - busy few weeks and a few days lain up in bed with
a cold.

> ---
> v1->v2 no change, just patch split
> v2->v3 replace regmap_bulk_read with regmap_read (Jonathan)
>  (I just realized BMA220_REG_IF0 is never used, even by future event
> patches)
> ---
>  drivers/iio/accel/bma220_core.c | 61 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 61 insertions(+)
> 
> diff --git a/drivers/iio/accel/bma220_core.c b/drivers/iio/accel/bma220_core.c
> index 425a8b981e141aa496351f29df0597c989aa4a0a..6297882bcf1b955291a2d8747984648bc6ee8512 100644
> --- a/drivers/iio/accel/bma220_core.c
> +++ b/drivers/iio/accel/bma220_core.c
> @@ -23,6 +23,7 @@
>  #include <linux/iio/buffer.h>
>  #include <linux/iio/iio.h>
>  #include <linux/iio/sysfs.h>
> +#include <linux/iio/trigger.h>
>  #include <linux/iio/trigger_consumer.h>
>  #include <linux/iio/triggered_buffer.h>
>  
> @@ -125,6 +126,7 @@ struct bma220_data {
>  	struct regmap *regmap;
>  	struct mutex lock;
>  	u8 range_idx;
> +	struct iio_trigger *trig;
>  	struct {
>  		s8 chans[3];
>  		/* Ensure timestamp is naturally aligned. */
> @@ -193,6 +195,23 @@ const struct regmap_config bma220_i2c_regmap_config = {
>  };
>  EXPORT_SYMBOL_NS_GPL(bma220_i2c_regmap_config, "IIO_BOSCH_BMA220");
>  
> +static int bma220_data_rdy_trigger_set_state(struct iio_trigger *trig,
> +					     bool state)
> +{
> +	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
> +	struct bma220_data *data = iio_priv(indio_dev);
> +
> +	guard(mutex)(&data->lock);

What is this lock protecting? 

> +	return regmap_update_bits(data->regmap, BMA220_REG_IE0,
> +				  BMA220_INT_EN_DRDY_MSK,
> +				  FIELD_PREP(BMA220_INT_EN_DRDY_MSK, state));
> +}

> @@ -417,6 +436,24 @@ static void bma220_deinit(void *data_ptr)
>  			 ERR_PTR(ret));
>  }
>  
> +static irqreturn_t bma220_irq_handler(int irq, void *private)
> +{
> +	struct iio_dev *indio_dev = private;
> +	struct bma220_data *data = iio_priv(indio_dev);
> +	int rv;
> +	unsigned int bma220_reg_if1;
> +
> +	guard(mutex)(&data->lock);

What is the lock protecting here?  The internal locks in regmap
superficially look like they'd be enough given we only have a single
read.  I'd expect any necessary locking to be on the otherside
of that use of the iio trigger framework (so the poll function thread).

> +	rv = regmap_read(data->regmap, BMA220_REG_IF1, &bma220_reg_if1);
> +	if (rv)
> +		return IRQ_NONE;
> +
> +	if (FIELD_GET(BMA220_IF_DRDY, bma220_reg_if1)) {
> +		iio_trigger_poll_nested(data->trig);
> +
> +	return IRQ_HANDLED;
> +}
> +
>  int bma220_common_probe(struct device *dev, struct regmap *regmap, int irq)
>  {
>  	int ret;
> @@ -446,6 +483,30 @@ int bma220_common_probe(struct device *dev, struct regmap *regmap, int irq)
>  	indio_dev->num_channels = ARRAY_SIZE(bma220_channels);
>  	indio_dev->available_scan_masks = bma220_accel_scan_masks;
>  
> +	if (irq > 0) {
> +		data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d",
> +						    indio_dev->name,
> +						    iio_device_id(indio_dev));
> +		if (!data->trig)
> +			return -ENOMEM;
> +
> +		data->trig->ops = &bma220_trigger_ops;
> +		iio_trigger_set_drvdata(data->trig, indio_dev);
> +
> +		ret = devm_iio_trigger_register(dev, data->trig);
> +		if (ret)
> +			return dev_err_probe(dev, ret,
> +					     "iio trigger register fail\n");
> +		indio_dev->trig = iio_trigger_get(data->trig);
> +		ret = devm_request_threaded_irq(dev, irq, NULL,
> +						&bma220_irq_handler,
> +						IRQF_TRIGGER_RISING | IRQF_ONESHOT,
Interrupt polarity should be coming from firmware.

It's a historically common mistake to encode it in the driver as it breaks
fairly standard things like using an inverter as a cheap level converter
in front of the interrupt pin.

So IRQF_ONEHSOT only should be all that is needed here.

> +						indio_dev->name, indio_dev);
> +		if (ret)
> +			return dev_err_probe(dev, ret,
> +					     "request irq %d failed\n", irq);
> +	}
> +
>  	ret = devm_add_action_or_reset(dev, bma220_deinit, data);
>  	if (ret)
>  		return ret;
>
Re: [PATCH v3 15/18] iio: accel: bma220: add interrupt trigger
Posted by Andy Shevchenko 2 weeks, 4 days ago
On Sat, Sep 13, 2025 at 6:40 PM Petre Rodan <petre.rodan@subdimension.ro> wrote:
>
> Add interrupt trigger.

...

> +static irqreturn_t bma220_irq_handler(int irq, void *private)
> +{
> +       struct iio_dev *indio_dev = private;
> +       struct bma220_data *data = iio_priv(indio_dev);

> +       int rv;

Be consistent with the variable namings. This sounds like 'ret' to me.

> +       unsigned int bma220_reg_if1;
> +
> +       guard(mutex)(&data->lock);
> +       rv = regmap_read(data->regmap, BMA220_REG_IF1, &bma220_reg_if1);
> +       if (rv)
> +               return IRQ_NONE;
> +
> +       if (FIELD_GET(BMA220_IF_DRDY, bma220_reg_if1)) {
> +               iio_trigger_poll_nested(data->trig);
> +
> +       return IRQ_HANDLED;
> +}

...

> +               ret = devm_request_threaded_irq(dev, irq, NULL,
> +                                               &bma220_irq_handler,
> +                                               IRQF_TRIGGER_RISING | IRQF_ONESHOT,

Why is it okay to override firmware provided IRQ flags, please?

> +                                               indio_dev->name, indio_dev);
> +               if (ret)
> +                       return dev_err_probe(dev, ret,
> +                                            "request irq %d failed\n", irq);


-- 
With Best Regards,
Andy Shevchenko
Re: [PATCH v3 15/18] iio: accel: bma220: add interrupt trigger
Posted by kernel test robot 2 weeks, 4 days ago
Hi Petre,

kernel test robot noticed the following build errors:

[auto build test ERROR on 661facba437e37c1685606825b9fd59be3f78771]

url:    https://github.com/intel-lab-lkp/linux/commits/Petre-Rodan/dt-bindings-iio-accel-bosch-bma220-cleanup-typo/20250913-234451
base:   661facba437e37c1685606825b9fd59be3f78771
patch link:    https://lore.kernel.org/r/20250913-b4-bma220_improvements-v3-15-0b97279b4e45%40subdimension.ro
patch subject: [PATCH v3 15/18] iio: accel: bma220: add interrupt trigger
config: x86_64-buildonly-randconfig-002-20250913 (https://download.01.org/0day-ci/archive/20250914/202509140109.kB7kOKfZ-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250914/202509140109.kB7kOKfZ-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509140109.kB7kOKfZ-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

   In file included from include/linux/linkage.h:7,
                    from arch/x86/include/asm/cache.h:5,
                    from include/vdso/cache.h:5,
                    from include/linux/cache.h:6,
                    from arch/x86/include/asm/current.h:10,
                    from include/linux/sched.h:12,
                    from include/linux/ratelimit.h:6,
                    from include/linux/dev_printk.h:16,
                    from include/linux/device.h:15,
                    from drivers/iio/accel/bma220_core.c:12:
   drivers/iio/accel/bma220_core.c: In function 'bma220_irq_handler':
>> drivers/iio/accel/bma220_core.c:521:22: error: non-static declaration of 'bma220_common_probe' follows static declaration
     521 | EXPORT_SYMBOL_NS_GPL(bma220_common_probe, "IIO_BOSCH_BMA220");
         |                      ^~~~~~~~~~~~~~~~~~~
   include/linux/export.h:76:28: note: in definition of macro '__EXPORT_SYMBOL'
      76 |         extern typeof(sym) sym;                                 \
         |                            ^~~
   drivers/iio/accel/bma220_core.c:521:1: note: in expansion of macro 'EXPORT_SYMBOL_NS_GPL'
     521 | EXPORT_SYMBOL_NS_GPL(bma220_common_probe, "IIO_BOSCH_BMA220");
         | ^~~~~~~~~~~~~~~~~~~~
   drivers/iio/accel/bma220_core.c:457:5: note: previous definition of 'bma220_common_probe' with type 'int(struct device *, struct regmap *, int)'
     457 | int bma220_common_probe(struct device *dev, struct regmap *regmap, int irq)
         |     ^~~~~~~~~~~~~~~~~~~
>> drivers/iio/accel/bma220_core.c:523:12: error: invalid storage class for function 'bma220_suspend'
     523 | static int bma220_suspend(struct device *dev)
         |            ^~~~~~~~~~~~~~
>> drivers/iio/accel/bma220_core.c:531:12: error: invalid storage class for function 'bma220_resume'
     531 | static int bma220_resume(struct device *dev)
         |            ^~~~~~~~~~~~~
>> drivers/iio/accel/bma220_core.c:538:29: error: extern declaration of 'bma220_pm_ops' follows declaration with no linkage
     538 | EXPORT_NS_SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume,
         |                             ^~~~~~~~~~~~~
   include/linux/export.h:76:28: note: in definition of macro '__EXPORT_SYMBOL'
      76 |         extern typeof(sym) sym;                                 \
         |                            ^~~
   include/linux/pm.h:393:57: note: in expansion of macro '_EXPORT_PM_OPS'
     393 | #define _EXPORT_DEV_SLEEP_PM_OPS(name, license, ns)     _EXPORT_PM_OPS(name, license, ns)
         |                                                         ^~~~~~~~~~~~~~
   include/linux/pm.h:405:57: note: in expansion of macro '_EXPORT_DEV_SLEEP_PM_OPS'
     405 | #define EXPORT_NS_DEV_SLEEP_PM_OPS(name, ns)            _EXPORT_DEV_SLEEP_PM_OPS(name, "", #ns)
         |                                                         ^~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/pm.h:427:9: note: in expansion of macro 'EXPORT_NS_DEV_SLEEP_PM_OPS'
     427 |         EXPORT_NS_DEV_SLEEP_PM_OPS(name, ns) = { \
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/iio/accel/bma220_core.c:538:1: note: in expansion of macro 'EXPORT_NS_SIMPLE_DEV_PM_OPS'
     538 | EXPORT_NS_SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume,
         | ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   In file included from include/linux/device.h:25:
   drivers/iio/accel/bma220_core.c:538:29: note: previous declaration of 'bma220_pm_ops' with type 'const struct dev_pm_ops'
     538 | EXPORT_NS_SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume,
         |                             ^~~~~~~~~~~~~
   include/linux/pm.h:379:33: note: in definition of macro '_EXPORT_PM_OPS'
     379 |         const struct dev_pm_ops name;                                   \
         |                                 ^~~~
   include/linux/pm.h:405:57: note: in expansion of macro '_EXPORT_DEV_SLEEP_PM_OPS'
     405 | #define EXPORT_NS_DEV_SLEEP_PM_OPS(name, ns)            _EXPORT_DEV_SLEEP_PM_OPS(name, "", #ns)
         |                                                         ^~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/pm.h:427:9: note: in expansion of macro 'EXPORT_NS_DEV_SLEEP_PM_OPS'
     427 |         EXPORT_NS_DEV_SLEEP_PM_OPS(name, ns) = { \
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/iio/accel/bma220_core.c:538:1: note: in expansion of macro 'EXPORT_NS_SIMPLE_DEV_PM_OPS'
     538 | EXPORT_NS_SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume,
         | ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/iio/accel/bma220_core.c:538:29: error: declaration of 'bma220_pm_ops' with no linkage follows extern declaration
     538 | EXPORT_NS_SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume,
         |                             ^~~~~~~~~~~~~
   include/linux/pm.h:381:33: note: in definition of macro '_EXPORT_PM_OPS'
     381 |         const struct dev_pm_ops name
         |                                 ^~~~
   include/linux/pm.h:405:57: note: in expansion of macro '_EXPORT_DEV_SLEEP_PM_OPS'
     405 | #define EXPORT_NS_DEV_SLEEP_PM_OPS(name, ns)            _EXPORT_DEV_SLEEP_PM_OPS(name, "", #ns)
         |                                                         ^~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/pm.h:427:9: note: in expansion of macro 'EXPORT_NS_DEV_SLEEP_PM_OPS'
     427 |         EXPORT_NS_DEV_SLEEP_PM_OPS(name, ns) = { \
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/iio/accel/bma220_core.c:538:1: note: in expansion of macro 'EXPORT_NS_SIMPLE_DEV_PM_OPS'
     538 | EXPORT_NS_SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume,
         | ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/iio/accel/bma220_core.c:538:29: note: previous declaration of 'bma220_pm_ops' with type 'const struct dev_pm_ops'
     538 | EXPORT_NS_SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume,
         |                             ^~~~~~~~~~~~~
   include/linux/export.h:76:28: note: in definition of macro '__EXPORT_SYMBOL'
      76 |         extern typeof(sym) sym;                                 \
         |                            ^~~
   include/linux/pm.h:393:57: note: in expansion of macro '_EXPORT_PM_OPS'
     393 | #define _EXPORT_DEV_SLEEP_PM_OPS(name, license, ns)     _EXPORT_PM_OPS(name, license, ns)
         |                                                         ^~~~~~~~~~~~~~
   include/linux/pm.h:405:57: note: in expansion of macro '_EXPORT_DEV_SLEEP_PM_OPS'
     405 | #define EXPORT_NS_DEV_SLEEP_PM_OPS(name, ns)            _EXPORT_DEV_SLEEP_PM_OPS(name, "", #ns)
         |                                                         ^~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/pm.h:427:9: note: in expansion of macro 'EXPORT_NS_DEV_SLEEP_PM_OPS'
     427 |         EXPORT_NS_DEV_SLEEP_PM_OPS(name, ns) = { \
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/iio/accel/bma220_core.c:538:1: note: in expansion of macro 'EXPORT_NS_SIMPLE_DEV_PM_OPS'
     538 | EXPORT_NS_SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume,
         | ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/iio/accel/bma220_core.c:543:1: error: expected declaration or statement at end of input
     543 | MODULE_LICENSE("GPL");
         | ^~~~~~~~~~~~~~
>> drivers/iio/accel/bma220_core.c:538:29: warning: unused variable 'bma220_pm_ops' [-Wunused-variable]
     538 | EXPORT_NS_SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume,
         |                             ^~~~~~~~~~~~~
   include/linux/pm.h:381:33: note: in definition of macro '_EXPORT_PM_OPS'
     381 |         const struct dev_pm_ops name
         |                                 ^~~~
   include/linux/pm.h:405:57: note: in expansion of macro '_EXPORT_DEV_SLEEP_PM_OPS'
     405 | #define EXPORT_NS_DEV_SLEEP_PM_OPS(name, ns)            _EXPORT_DEV_SLEEP_PM_OPS(name, "", #ns)
         |                                                         ^~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/pm.h:427:9: note: in expansion of macro 'EXPORT_NS_DEV_SLEEP_PM_OPS'
     427 |         EXPORT_NS_DEV_SLEEP_PM_OPS(name, ns) = { \
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/iio/accel/bma220_core.c:538:1: note: in expansion of macro 'EXPORT_NS_SIMPLE_DEV_PM_OPS'
     538 | EXPORT_NS_SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume,
         | ^~~~~~~~~~~~~~~~~~~~~~~~~~~


vim +/bma220_common_probe +521 drivers/iio/accel/bma220_core.c

b019a92c1241f44 Petre Rodan 2025-09-13  456  
9216bea3069746d Petre Rodan 2025-09-13 @457  int bma220_common_probe(struct device *dev, struct regmap *regmap, int irq)
e51403e66843c16 Petre Rodan 2025-09-13  458  {
e51403e66843c16 Petre Rodan 2025-09-13  459  	int ret;
e51403e66843c16 Petre Rodan 2025-09-13  460  	struct iio_dev *indio_dev;
e51403e66843c16 Petre Rodan 2025-09-13  461  	struct bma220_data *data;
e51403e66843c16 Petre Rodan 2025-09-13  462  
9216bea3069746d Petre Rodan 2025-09-13  463  	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
e51403e66843c16 Petre Rodan 2025-09-13  464  	if (!indio_dev)
e51403e66843c16 Petre Rodan 2025-09-13  465  		return -ENOMEM;
e51403e66843c16 Petre Rodan 2025-09-13  466  
e51403e66843c16 Petre Rodan 2025-09-13  467  	data = iio_priv(indio_dev);
9216bea3069746d Petre Rodan 2025-09-13  468  	data->regmap = regmap;
9216bea3069746d Petre Rodan 2025-09-13  469  	data->dev = dev;
9216bea3069746d Petre Rodan 2025-09-13  470  
9216bea3069746d Petre Rodan 2025-09-13  471  	ret = bma220_init(data);
9216bea3069746d Petre Rodan 2025-09-13  472  	if (ret)
9216bea3069746d Petre Rodan 2025-09-13  473  		return ret;
9216bea3069746d Petre Rodan 2025-09-13  474  
9216bea3069746d Petre Rodan 2025-09-13  475  	ret = devm_mutex_init(dev, &data->lock);
9216bea3069746d Petre Rodan 2025-09-13  476  	if (ret)
9216bea3069746d Petre Rodan 2025-09-13  477  		return ret;
e51403e66843c16 Petre Rodan 2025-09-13  478  
e51403e66843c16 Petre Rodan 2025-09-13  479  	indio_dev->info = &bma220_info;
e51403e66843c16 Petre Rodan 2025-09-13  480  	indio_dev->name = BMA220_DEVICE_NAME;
e51403e66843c16 Petre Rodan 2025-09-13  481  	indio_dev->modes = INDIO_DIRECT_MODE;
e51403e66843c16 Petre Rodan 2025-09-13  482  	indio_dev->channels = bma220_channels;
e51403e66843c16 Petre Rodan 2025-09-13  483  	indio_dev->num_channels = ARRAY_SIZE(bma220_channels);
e51403e66843c16 Petre Rodan 2025-09-13  484  	indio_dev->available_scan_masks = bma220_accel_scan_masks;
e51403e66843c16 Petre Rodan 2025-09-13  485  
b019a92c1241f44 Petre Rodan 2025-09-13  486  	if (irq > 0) {
b019a92c1241f44 Petre Rodan 2025-09-13  487  		data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d",
b019a92c1241f44 Petre Rodan 2025-09-13  488  						    indio_dev->name,
b019a92c1241f44 Petre Rodan 2025-09-13  489  						    iio_device_id(indio_dev));
b019a92c1241f44 Petre Rodan 2025-09-13  490  		if (!data->trig)
b019a92c1241f44 Petre Rodan 2025-09-13  491  			return -ENOMEM;
b019a92c1241f44 Petre Rodan 2025-09-13  492  
b019a92c1241f44 Petre Rodan 2025-09-13  493  		data->trig->ops = &bma220_trigger_ops;
b019a92c1241f44 Petre Rodan 2025-09-13  494  		iio_trigger_set_drvdata(data->trig, indio_dev);
b019a92c1241f44 Petre Rodan 2025-09-13  495  
b019a92c1241f44 Petre Rodan 2025-09-13  496  		ret = devm_iio_trigger_register(dev, data->trig);
b019a92c1241f44 Petre Rodan 2025-09-13  497  		if (ret)
b019a92c1241f44 Petre Rodan 2025-09-13  498  			return dev_err_probe(dev, ret,
b019a92c1241f44 Petre Rodan 2025-09-13  499  					     "iio trigger register fail\n");
b019a92c1241f44 Petre Rodan 2025-09-13  500  		indio_dev->trig = iio_trigger_get(data->trig);
b019a92c1241f44 Petre Rodan 2025-09-13  501  		ret = devm_request_threaded_irq(dev, irq, NULL,
b019a92c1241f44 Petre Rodan 2025-09-13  502  						&bma220_irq_handler,
b019a92c1241f44 Petre Rodan 2025-09-13  503  						IRQF_TRIGGER_RISING | IRQF_ONESHOT,
b019a92c1241f44 Petre Rodan 2025-09-13  504  						indio_dev->name, indio_dev);
b019a92c1241f44 Petre Rodan 2025-09-13  505  		if (ret)
b019a92c1241f44 Petre Rodan 2025-09-13  506  			return dev_err_probe(dev, ret,
b019a92c1241f44 Petre Rodan 2025-09-13  507  					     "request irq %d failed\n", irq);
b019a92c1241f44 Petre Rodan 2025-09-13  508  	}
b019a92c1241f44 Petre Rodan 2025-09-13  509  
9216bea3069746d Petre Rodan 2025-09-13  510  	ret = devm_add_action_or_reset(dev, bma220_deinit, data);
e51403e66843c16 Petre Rodan 2025-09-13  511  	if (ret)
e51403e66843c16 Petre Rodan 2025-09-13  512  		return ret;
e51403e66843c16 Petre Rodan 2025-09-13  513  
d1258c485cdab0a Petre Rodan 2025-09-13  514  	ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
e51403e66843c16 Petre Rodan 2025-09-13  515  					      bma220_trigger_handler, NULL);
9216bea3069746d Petre Rodan 2025-09-13  516  	if (ret < 0)
9216bea3069746d Petre Rodan 2025-09-13  517  		dev_err_probe(dev, ret, "iio triggered buffer setup failed\n");
e51403e66843c16 Petre Rodan 2025-09-13  518  
9216bea3069746d Petre Rodan 2025-09-13  519  	return devm_iio_device_register(dev, indio_dev);
e51403e66843c16 Petre Rodan 2025-09-13  520  }
9216bea3069746d Petre Rodan 2025-09-13 @521  EXPORT_SYMBOL_NS_GPL(bma220_common_probe, "IIO_BOSCH_BMA220");
e51403e66843c16 Petre Rodan 2025-09-13  522  
e51403e66843c16 Petre Rodan 2025-09-13 @523  static int bma220_suspend(struct device *dev)
e51403e66843c16 Petre Rodan 2025-09-13  524  {
9216bea3069746d Petre Rodan 2025-09-13  525  	struct iio_dev *indio_dev = dev_get_drvdata(dev);
9216bea3069746d Petre Rodan 2025-09-13  526  	struct bma220_data *data = iio_priv(indio_dev);
e51403e66843c16 Petre Rodan 2025-09-13  527  
9216bea3069746d Petre Rodan 2025-09-13  528  	return bma220_power(data, false);
e51403e66843c16 Petre Rodan 2025-09-13  529  }
e51403e66843c16 Petre Rodan 2025-09-13  530  
e51403e66843c16 Petre Rodan 2025-09-13 @531  static int bma220_resume(struct device *dev)
e51403e66843c16 Petre Rodan 2025-09-13  532  {
9216bea3069746d Petre Rodan 2025-09-13  533  	struct iio_dev *indio_dev = dev_get_drvdata(dev);
9216bea3069746d Petre Rodan 2025-09-13  534  	struct bma220_data *data = iio_priv(indio_dev);
e51403e66843c16 Petre Rodan 2025-09-13  535  
9216bea3069746d Petre Rodan 2025-09-13  536  	return bma220_power(data, true);
e51403e66843c16 Petre Rodan 2025-09-13  537  }
e51403e66843c16 Petre Rodan 2025-09-13 @538  EXPORT_NS_SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume,
e51403e66843c16 Petre Rodan 2025-09-13  539  			    IIO_BOSCH_BMA220);
e51403e66843c16 Petre Rodan 2025-09-13  540  
e51403e66843c16 Petre Rodan 2025-09-13  541  MODULE_AUTHOR("Tiberiu Breana <tiberiu.a.breana@intel.com>");
e51403e66843c16 Petre Rodan 2025-09-13  542  MODULE_DESCRIPTION("BMA220 acceleration sensor driver");
e51403e66843c16 Petre Rodan 2025-09-13 @543  MODULE_LICENSE("GPL");

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH v3 15/18] iio: accel: bma220: add interrupt trigger
Posted by Petre Rodan 2 weeks, 5 days ago
On Sat, Sep 13, 2025 at 06:39:36PM +0300, Petre Rodan wrote:
> +static irqreturn_t bma220_irq_handler(int irq, void *private)
> +{
> +	struct iio_dev *indio_dev = private;
> +	struct bma220_data *data = iio_priv(indio_dev);
> +	int rv;
> +	unsigned int bma220_reg_if1;
> +
> +	guard(mutex)(&data->lock);
> +	rv = regmap_read(data->regmap, BMA220_REG_IF1, &bma220_reg_if1);
> +	if (rv)
> +		return IRQ_NONE;
> +
> +	if (FIELD_GET(BMA220_IF_DRDY, bma220_reg_if1)) {
> +		iio_trigger_poll_nested(data->trig);
> +
> +	return IRQ_HANDLED;
> +}

sorry, errant '{' in FIELD_GET line throws compilation off, will fix in next rev.

best regards,
peter
Re: [PATCH v3 15/18] iio: accel: bma220: add interrupt trigger
Posted by Andy Shevchenko 2 weeks, 4 days ago
On Sat, Sep 13, 2025 at 7:32 PM Petre Rodan <petre.rodan@subdimension.ro> wrote:
> On Sat, Sep 13, 2025 at 06:39:36PM +0300, Petre Rodan wrote:

> > +     if (FIELD_GET(BMA220_IF_DRDY, bma220_reg_if1)) {
> > +             iio_trigger_poll_nested(data->trig);
> > +
> > +     return IRQ_HANDLED;
> > +}

> sorry, errant '{' in FIELD_GET line throws compilation off, will fix in next rev.

Please, slow down and test your patches carefully. If you haven't even
compiled this, I don't think it's ever possible to be tested on real
HW. So, this is NAK for the series. Also note, due to timing this will
be a material for the next cycle anyway (v6.19), so no rush with a new
version.

-- 
With Best Regards,
Andy Shevchenko