lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <fe32537d44cbb187e1518740f33e3a6716dd363a.camel@gmail.com>
Date: Fri, 19 Sep 2025 13:05:19 +0100
From: Nuno Sá <noname.nuno@...il.com>
To: Akshay Jindal <akshayaj.lkd@...il.com>, dan@...obertson.com, 
	jic23@...nel.org, dlechner@...libre.com, nuno.sa@...log.com, andy@...nel.org
Cc: shuah@...nel.org, linux-iio@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH] iio: accel: bma400: Refactor generic interrupt
 configuration

Hi,

Thanks for your patch.

On Fri, 2025-09-19 at 00:37 +0530, Akshay Jindal wrote:
> Refactor the generic interrupt configuration logic to improve readability
> and reduce repetitive code. Replace hard-coded register values with macros
> and enums, making it clearer what configuration is written to hardware.
> 
> Introduce a const struct to map event direction to the corresponding
> generic interrupt. This removes the need for switch statements in multiple
> callbacks, including activity event setup, read_event_value, and
> write_event_value, while still performing the selection at runtime.
> 
> This change has no functional impact but simplifies the code and makes it
> easier to maintain and extend in future updates.
> 
> Signed-off-by: Akshay Jindal <akshayaj.lkd@...il.com>
> ---

You may be trying to refactor too much in one single patch. I would maybe think
about splitting this into 2/3 logical changes.

>  drivers/iio/accel/bma400.h      |  71 +++++++++++++++---
>  drivers/iio/accel/bma400_core.c | 128 ++++++++++++++++----------------
>  2 files changed, 125 insertions(+), 74 deletions(-)
> 
> diff --git a/drivers/iio/accel/bma400.h b/drivers/iio/accel/bma400.h
> index 932358b45f17..ab7d1d139b66 100644
> --- a/drivers/iio/accel/bma400.h
> +++ b/drivers/iio/accel/bma400.h
> @@ -68,7 +68,19 @@
>  #define BMA400_CMD_REG              0x7e
>  
>  /* Interrupt registers */
> -#define BMA400_INT_CONFIG0_REG	    0x1f
> +#define BMA400_INT_CONFIG0_REG			0x1f
> +#define BMA400_INT_CONFIG0_ORTN_CHG_MASK	BIT(1)
> +#define BMA400_INT_CONFIG0_GEN1_MASK		BIT(2)
> +#define BMA400_INT_CONFIG0_GEN2_MASK		BIT(3)
> +#define BMA400_INT_CONFIG0_FIFO_FULL_MASK	BIT(5)
> +#define BMA400_INT_CONFIG0_FIFO_WTRMRK_MASK	BIT(6)
> +#define BMA400_INT_CONFIG0_DRDY_MASK		BIT(7)
> +
> +enum generic_intr {
> +	GEN1_INTR,
> +	GEN2_INTR
> +};
> +
>  #define BMA400_INT_CONFIG1_REG	    0x20
>  #define BMA400_INT1_MAP_REG	    0x21
>  #define BMA400_INT_IO_CTRL_REG	    0x24
> @@ -96,15 +108,53 @@
>  #define BMA400_ACC_ODR_MIN_HZ       12
>  
>  /* Generic interrupts register */
> -#define BMA400_GEN1INT_CONFIG0      0x3f
> -#define BMA400_GEN2INT_CONFIG0      0x4A
> -#define BMA400_GEN_CONFIG1_OFF      0x01
> -#define BMA400_GEN_CONFIG2_OFF      0x02
> -#define BMA400_GEN_CONFIG3_OFF      0x03
> -#define BMA400_GEN_CONFIG31_OFF     0x04
> -#define BMA400_INT_GEN1_MSK         BIT(2)
> -#define BMA400_INT_GEN2_MSK         BIT(3)
> -#define BMA400_GEN_HYST_MSK         GENMASK(1, 0)
> +#define BMA400_GENINT_CONFIG_REG_BASE	0x3f
> +#define BMA400_NUM_GENINT_CONFIG_REGS	11
> +#define BMA400_GENINT_CONFIG_REG(gen_intr, config_idx)	\
> +	(BMA400_GENINT_CONFIG_REG_BASE +		\
> +	(gen_intr) * BMA400_NUM_GENINT_CONFIG_REGS +	\
> +	(config_idx))

Not sure the above macro helps that much. More on this below...

> +
> +/* Generic Interrupt Config0 register */
> +#define BMA400_GENINT_CONFIG0_HYST_MASK			GENMASK(1, 0)
> +#define BMA400_GENINT_CONFIG0_REF_UPD_MODE_MASK		GENMASK(3, 2)
> +#define BMA400_GENINT_CONFIG0_DATA_SRC_MASK		BIT(4)
> +#define BMA400_GENINT_CONFIG0_X_EN_MASK			BIT(5)
> +#define BMA400_GENINT_CONFIG0_Y_EN_MASK			BIT(6)
> +#define BMA400_GENINT_CONFIG0_Z_EN_MASK			BIT(7)
> +
> +enum bma400_hysteresis_config {
> +	NO_HYSTERESIS,
> +	HYSTERESIS_24MG,
> +	HYSTERESIS_48MG,
> +	HYSTERESIS_96MG
> +};
> +
> +enum bma400_accel_data_src {
> +	ACCEL_FILT1,
> +	ACCEL_FILT2
> +};
> +
> +enum bma400_ref_updt_mode {
> +	BMA400_REF_MANUAL_UPDT_MODE,
> +	BMA400_REF_ONETIME_UPDT_MODE,
> +	BMA400_REF_EVERYTIME_UPDT_MODE,
> +	BMA400_REF_EVERYTIME_LP_UPDT_MODE
> +};
> +
> +/* Generic Interrupt Config1 register */
> +#define BMA400_GENINT_CONFIG1_AXES_COMB_MASK		BIT(0)
> +#define BMA400_GENINT_CONFIG1_DETCT_CRIT_MASK		BIT(1)
> +
> +enum bma400_genintr_acceleval_axescomb {
> +	BMA400_EVAL_X_OR_Y_OR_Z,
> +	BMA400_EVAL_X_AND_Y_AND_Z,
> +};
> +
> +enum bma400_detect_criterion {
> +	BMA400_DETECT_INACTIVITY,
> +	BMA400_DETECT_ACTIVITY,
> +};
>  
>  /* TAP config registers */
>  #define BMA400_TAP_CONFIG           0x57
> @@ -119,6 +169,7 @@
>  #define BMA400_TAP_QUIETDT_MSK      GENMASK(5, 4)
>  #define BMA400_TAP_TIM_LIST_LEN     4
>  
> +
>  /*
>   * BMA400_SCALE_MIN macro value represents m/s^2 for 1 LSB before
>   * converting to micro values for +-2g range.
> diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c
> index 85e23badf733..d59c26b8a57f 100644
> --- a/drivers/iio/accel/bma400_core.c
> +++ b/drivers/iio/accel/bma400_core.c
> @@ -121,6 +121,29 @@ struct bma400_data {
>  	__be16 duration;
>  };
>  
> +struct bma400_genintr_info {
> +	u8 genintr;
> +	unsigned int intrmask;
> +	enum iio_event_direction dir;
> +	enum bma400_detect_criterion detect_mode;
> +};
> +
> +/* Lookup struct for determining GEN1/GEN2 based on dir */
> +static const struct bma400_genintr_info bma400_genintrs[] = {
> +	[IIO_EV_DIR_RISING] = {
> +		.genintr = GEN1_INTR,	/* 0 for GEN1 */
> +		.intrmask = BMA400_INT_CONFIG0_GEN1_MASK,
> +		.dir = IIO_EV_DIR_RISING,
> +		.detect_mode = BMA400_DETECT_ACTIVITY,
> +	},
> +	[IIO_EV_DIR_FALLING] = {
> +		.genintr = GEN2_INTR,	/* 1 for GEN2 */
> +		.intrmask = BMA400_INT_CONFIG0_GEN2_MASK,
> +		.dir = IIO_EV_DIR_FALLING,
> +		.detect_mode = BMA400_DETECT_INACTIVITY,
> +	}
> +};
> +
>  static bool bma400_is_writable_reg(struct device *dev, unsigned int reg)
>  {
>  	switch (reg) {
> @@ -1114,10 +1137,10 @@ static int bma400_read_event_config(struct iio_dev
> *indio_dev,
>  	case IIO_ACCEL:
>  		switch (dir) {
>  		case IIO_EV_DIR_RISING:
> -			return FIELD_GET(BMA400_INT_GEN1_MSK,
> +			return FIELD_GET(BMA400_INT_CONFIG0_GEN1_MASK,
>  					 data->generic_event_en);

Like the above is above renaming defines in a more logical name. Not going to
opinate whether this name is better or not but you could put that (and other
similar changes) in one patch.

>  		case IIO_EV_DIR_FALLING:
> -			return FIELD_GET(BMA400_INT_GEN2_MSK,
> +			return FIELD_GET(BMA400_INT_CONFIG0_GEN2_MASK,
>  					 data->generic_event_en);
>  		case IIO_EV_DIR_SINGLETAP:
>  			return FIELD_GET(BMA400_S_TAP_MSK,
> @@ -1159,59 +1182,50 @@ static int bma400_activity_event_en(struct bma400_data
> *data,
>  				    enum iio_event_direction dir,
>  				    int state)
>  {
> -	int ret, reg, msk, value;
> -	int field_value = 0;
> -
> -	switch (dir) {
> -	case IIO_EV_DIR_RISING:
> -		reg = BMA400_GEN1INT_CONFIG0;
> -		msk = BMA400_INT_GEN1_MSK;
> -		value = 2;
> -		set_mask_bits(&field_value, BMA400_INT_GEN1_MSK,
> -			      FIELD_PREP(BMA400_INT_GEN1_MSK, state));
> -		break;
> -	case IIO_EV_DIR_FALLING:
> -		reg = BMA400_GEN2INT_CONFIG0;
> -		msk = BMA400_INT_GEN2_MSK;
> -		value = 0;
> -		set_mask_bits(&field_value, BMA400_INT_GEN2_MSK,
> -			      FIELD_PREP(BMA400_INT_GEN2_MSK, state));
> -		break;
> -	default:
> -		return -EINVAL;
> -	}
> +	int ret, regval;
> +	u8 genintr = bma400_genintrs[dir].genintr;
> +	u8 detect_criterion = bma400_genintrs[dir].detect_mode;
> +	unsigned int intrmask = bma400_genintrs[dir].intrmask;
>  

Hmm, you should still have the switch case. Again, not sure the const struct
adds that much but I'm also fine with it. But I would do:

switch (dir) {
case IIO_EV_DIR_RISING:
case IIO_EV_DIR_FALLING:
	genintr = bma400_genintrs[dir].genintr;
	detect_criterion = bma400_genintrs[dir].detect_mode;
	intrmask = bma400_genintrs[dir].intrmask;
default:
	return -EINVAL;

>  	/* Enabling all axis for interrupt evaluation */
> -	ret = regmap_write(data->regmap, reg, 0xF8);
> +	ret = regmap_write(data->regmap, BMA400_GENINT_CONFIG_REG(genintr,
> 0),
> +			   BMA400_GENINT_CONFIG0_X_EN_MASK |
> +			   BMA400_GENINT_CONFIG0_Y_EN_MASK |
> +			   BMA400_GENINT_CONFIG0_Z_EN_MASK|
> +			   BMA400_REF_EVERYTIME_UPDT_MODE);
>  	if (ret)
>  		return ret;
>  
>  	/* OR combination of all axis for interrupt evaluation */
> -	ret = regmap_write(data->regmap, reg + BMA400_GEN_CONFIG1_OFF,
> value);
> +	regval = FIELD_PREP(BMA400_GENINT_CONFIG1_AXES_COMB_MASK,
> BMA400_EVAL_X_OR_Y_OR_Z) |
> +		 FIELD_PREP(BMA400_GENINT_CONFIG1_DETCT_CRIT_MASK,
> detect_criterion);
> +	ret = regmap_write(data->regmap, BMA400_GENINT_CONFIG_REG(genintr,
> 1), regval);
>  	if (ret)
>  		return ret;
>  
>  	/* Initial value to avoid interrupts while enabling*/
> -	ret = regmap_write(data->regmap, reg + BMA400_GEN_CONFIG2_OFF, 0x0A);
> +	ret = regmap_write(data->regmap, BMA400_GENINT_CONFIG_REG(genintr,
> 2), 0x0A);

I do not think readability is improved here. The former is way easier to read
IMO. Also, we still have the magic 0x0A.

>  	if (ret)
>  		return ret;
>  
>  	/* Initial duration value to avoid interrupts while enabling*/
> -	ret = regmap_write(data->regmap, reg + BMA400_GEN_CONFIG31_OFF,
> 0x0F);
> +	ret = regmap_write(data->regmap, BMA400_GENINT_CONFIG_REG(genintr,
> 4), 0x0F);
>  	if (ret)
>  		return ret;
>  
> -	ret = regmap_update_bits(data->regmap, BMA400_INT1_MAP_REG, msk,
> -				 field_value);
> +	regval = FIELD_PREP(BMA400_INT_CONFIG0_GEN1_MASK, state);
> +	if (genintr)
> +		regval = FIELD_PREP(BMA400_INT_CONFIG0_GEN2_MASK, state);
> +
> +	ret = regmap_update_bits(data->regmap, BMA400_INT1_MAP_REG, intrmask,
> regval);
>  	if (ret)
>  		return ret;
>  
> -	ret = regmap_update_bits(data->regmap, BMA400_INT_CONFIG0_REG, msk,
> -				 field_value);
> +	ret = regmap_update_bits(data->regmap, BMA400_INT_CONFIG0_REG,
> intrmask, regval);
>  	if (ret)
>  		return ret;
>  
> -	set_mask_bits(&data->generic_event_en, msk, field_value);
> +	set_mask_bits(&data->generic_event_en, intrmask, regval);
>  	return 0;
>  }
>  
> @@ -1336,18 +1350,6 @@ static int bma400_write_event_config(struct iio_dev
> *indio_dev,
>  	}
>  }
>  
> -static int get_gen_config_reg(enum iio_event_direction dir)
> -{
> -	switch (dir) {
> -	case IIO_EV_DIR_FALLING:
> -		return BMA400_GEN2INT_CONFIG0;
> -	case IIO_EV_DIR_RISING:
> -		return BMA400_GEN1INT_CONFIG0;
> -	default:
> -		return -EINVAL;
> -	}
> -}
> -
>  static int bma400_read_event_value(struct iio_dev *indio_dev,
>  				   const struct iio_chan_spec *chan,
>  				   enum iio_event_type type,
> @@ -1356,22 +1358,20 @@ static int bma400_read_event_value(struct iio_dev
> *indio_dev,
>  				   int *val, int *val2)
>  {
>  	struct bma400_data *data = iio_priv(indio_dev);
> -	int ret, reg, reg_val, raw;
> +	int ret, genintr, reg_val, raw;
>  
>  	if (chan->type != IIO_ACCEL)
>  		return -EINVAL;
>  
>  	switch (type) {
>  	case IIO_EV_TYPE_MAG:
> -		reg = get_gen_config_reg(dir);
> -		if (reg < 0)
> -			return -EINVAL;
> +		genintr = bma400_genintrs[dir].genintr;

Again you should make sure dir is valid. You could keep get_gen_config_reg() and
do something similar with what I suggested above.

>  
>  		*val2 = 0;
>  		switch (info) {
>  		case IIO_EV_INFO_VALUE:
>  			ret = regmap_read(data->regmap,
> -					  reg + BMA400_GEN_CONFIG2_OFF,
> +					  BMA400_GENINT_CONFIG_REG(genintr,
> 2),
>  					  val);
>  			if (ret)
>  				return ret;
> @@ -1379,7 +1379,7 @@ static int bma400_read_event_value(struct iio_dev
> *indio_dev,
>  		case IIO_EV_INFO_PERIOD:
>  			mutex_lock(&data->mutex);
>  			ret = regmap_bulk_read(data->regmap,
> -					       reg + BMA400_GEN_CONFIG3_OFF,
> +					      
> BMA400_GENINT_CONFIG_REG(genintr, 3),
>  					       &data->duration,
>  					       sizeof(data->duration));
>  			if (ret) {
> @@ -1390,10 +1390,12 @@ static int bma400_read_event_value(struct iio_dev
> *indio_dev,
>  			mutex_unlock(&data->mutex);
>  			return IIO_VAL_INT;
>  		case IIO_EV_INFO_HYSTERESIS:
> -			ret = regmap_read(data->regmap, reg, val);
> +			ret = regmap_read(data->regmap,
> +					  BMA400_GENINT_CONFIG_REG(genintr,
> 0),
> +					  val);

One more case where I don't really think this macro is doing readability any
better.

- Nuno Sá


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ