On Sat, 2020-01-11 at 11:34 +0000, Jonathan Cameron wrote: > [External] > > On Tue, 7 Jan 2020 13:17:04 +0200 > Alexandru Ardelean <alexandru.ardelean@xxxxxxxxxx> wrote: > > > From: Nuno Sá <nuno.sa@xxxxxxxxxx> > > > > The adis library only allows to define a `startup_delay` which for some > > devices is enough. However, other devices define different timeouts > > with > > significantly different timings which could lead to devices to not wait > > enough time or to wait a lot more than necessary (which is not > > efficient). This patch introduces a new timeout struct that must be > > passed into `adis_init()`. There are mainly, for now, three timeouts > > used. This is also an introductory patch with the goal of refactoring > > `adis_initial_startup()`. New driver's (eg: adis16480, adis16460) are > > replicating code for the device initial setup. With some changes (being > > this the first one) we can pass this to `adis_initial_startup()`. > > > > Signed-off-by: Nuno Sá <nuno.sa@xxxxxxxxxx> > > Signed-off-by: Alexandru Ardelean <alexandru.ardelean@xxxxxxxxxx> > > I'm a little unsure if this is the right option long term. > You may be better off putting the _data structure as a member of > the chip info structures (using macros to handle the parts that > are reused). That would avoid either the need for memcpy or > to pass a 'per driver' part and a 'per chip_info' part into the init > function. > Hmm, I'll admit that this idea slipped me [adis_data + macros]. > However, for now this is fairly clean. The best option will depend > in the long run on what else we find needs similar handling to these > timeouts. > One thing that would probably make this worth-it, is the ADIS burst for the adis16480 driver. In any case, let's leave it like this for now and see how we progress. We also have a few more ADIS drivers to send. Thanks Alex > As such.. Applied to the togreg branch of iio.git and pushed out as > testing for the autobuilders to poke at it. > > --- > > > > Changelog v1 - v2: > > * rework patch to remove manual assignments for adis16136, adis16400, > > adis16480 and do memcpy() from the static adis_data > > > > > > drivers/iio/accel/adis16201.c | 7 +++ > > drivers/iio/accel/adis16209.c | 7 +++ > > drivers/iio/gyro/adis16136.c | 40 ++++++++++++++++- > > drivers/iio/gyro/adis16260.c | 7 +++ > > drivers/iio/imu/adis.c | 18 ++++++-- > > drivers/iio/imu/adis16400.c | 63 ++++++++++++++++++++++++++- > > drivers/iio/imu/adis16460.c | 7 +++ > > drivers/iio/imu/adis16480.c | 58 +++++++++++++++++++++++- > > drivers/staging/iio/accel/adis16203.c | 7 +++ > > drivers/staging/iio/accel/adis16240.c | 7 +++ > > include/linux/iio/imu/adis.h | 13 ++++++ > > 11 files changed, 227 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/iio/accel/adis16201.c > > b/drivers/iio/accel/adis16201.c > > index c4810c73b2a2..c92d22387b01 100644 > > --- a/drivers/iio/accel/adis16201.c > > +++ b/drivers/iio/accel/adis16201.c > > @@ -233,6 +233,12 @@ static const char * const > > adis16201_status_error_msgs[] = { > > [ADIS16201_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.975V", > > }; > > > > +static const struct adis_timeout adis16201_timeouts = { > > + .reset_ms = ADIS16201_STARTUP_DELAY_MS, > > + .sw_reset_ms = ADIS16201_STARTUP_DELAY_MS, > > + .self_test_ms = ADIS16201_STARTUP_DELAY_MS, > > +}; > > + > > static const struct adis_data adis16201_data = { > > .read_delay = 20, > > .msc_ctrl_reg = ADIS16201_MSC_CTRL_REG, > > @@ -242,6 +248,7 @@ static const struct adis_data adis16201_data = { > > .self_test_mask = ADIS16201_MSC_CTRL_SELF_TEST_EN, > > .self_test_no_autoclear = true, > > .startup_delay = ADIS16201_STARTUP_DELAY_MS, > > + .timeouts = &adis16201_timeouts, > > > > .status_error_msgs = adis16201_status_error_msgs, > > .status_error_mask = BIT(ADIS16201_DIAG_STAT_SPI_FAIL_BIT) | > > diff --git a/drivers/iio/accel/adis16209.c > > b/drivers/iio/accel/adis16209.c > > index 98d77af8a2b0..f5a78fc11919 100644 > > --- a/drivers/iio/accel/adis16209.c > > +++ b/drivers/iio/accel/adis16209.c > > @@ -243,6 +243,12 @@ static const char * const > > adis16209_status_error_msgs[] = { > > [ADIS16209_STAT_POWER_LOW_BIT] = "Power supply below 2.975V", > > }; > > > > +static const struct adis_timeout adis16209_timeouts = { > > + .reset_ms = ADIS16209_STARTUP_DELAY_MS, > > + .self_test_ms = ADIS16209_STARTUP_DELAY_MS, > > + .sw_reset_ms = ADIS16209_STARTUP_DELAY_MS, > > +}; > > + > > static const struct adis_data adis16209_data = { > > .read_delay = 30, > > .msc_ctrl_reg = ADIS16209_MSC_CTRL_REG, > > @@ -252,6 +258,7 @@ static const struct adis_data adis16209_data = { > > .self_test_mask = ADIS16209_MSC_CTRL_SELF_TEST_EN, > > .self_test_no_autoclear = true, > > .startup_delay = ADIS16209_STARTUP_DELAY_MS, > > + .timeouts = &adis16209_timeouts, > > > > .status_error_msgs = adis16209_status_error_msgs, > > .status_error_mask = BIT(ADIS16209_STAT_SELFTEST_FAIL_BIT) | > > diff --git a/drivers/iio/gyro/adis16136.c > > b/drivers/iio/gyro/adis16136.c > > index f10c4f173898..dc91d8df7697 100644 > > --- a/drivers/iio/gyro/adis16136.c > > +++ b/drivers/iio/gyro/adis16136.c > > @@ -59,6 +59,7 @@ > > struct adis16136_chip_info { > > unsigned int precision; > > unsigned int fullscale; > > + const struct adis_timeout *timeouts; > > }; > > > > struct adis16136 { > > @@ -490,30 +491,63 @@ enum adis16136_id { > > ID_ADIS16137, > > }; > > > > +static const struct adis_timeout adis16133_timeouts = { > > + .reset_ms = 75, > > + .sw_reset_ms = 75, > > + .self_test_ms = 50, > > +}; > > + > > +static const struct adis_timeout adis16136_timeouts = { > > + .reset_ms = 128, > > + .sw_reset_ms = 75, > > + .self_test_ms = 245, > > +}; > > + > > static const struct adis16136_chip_info adis16136_chip_info[] = { > > [ID_ADIS16133] = { > > .precision = IIO_DEGREE_TO_RAD(1200), > > .fullscale = 24000, > > + .timeouts = &adis16133_timeouts, > > }, > > [ID_ADIS16135] = { > > .precision = IIO_DEGREE_TO_RAD(300), > > .fullscale = 24000, > > + .timeouts = &adis16133_timeouts, > > }, > > [ID_ADIS16136] = { > > .precision = IIO_DEGREE_TO_RAD(450), > > .fullscale = 24623, > > + .timeouts = &adis16136_timeouts, > > }, > > [ID_ADIS16137] = { > > .precision = IIO_DEGREE_TO_RAD(1000), > > .fullscale = 24609, > > + .timeouts = &adis16136_timeouts, > > }, > > }; > > > > +static struct adis_data *adis16136_adis_data_alloc(struct adis16136 > > *st, > > + struct device *dev) > > +{ > > + struct adis_data *data; > > + > > + data = devm_kmalloc(dev, sizeof(struct adis_data), GFP_KERNEL); > > + if (!data) > > + return ERR_PTR(-ENOMEM); > > + > > + memcpy(data, &adis16136_data, sizeof(*data)); > > + > > + data->timeouts = st->chip_info->timeouts; > > + > > + return data; > > +} > > + > > static int adis16136_probe(struct spi_device *spi) > > { > > const struct spi_device_id *id = spi_get_device_id(spi); > > struct adis16136 *adis16136; > > struct iio_dev *indio_dev; > > + const struct adis_data *adis16136_data; > > int ret; > > > > indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adis16136)); > > @@ -532,7 +566,11 @@ static int adis16136_probe(struct spi_device *spi) > > indio_dev->info = &adis16136_info; > > indio_dev->modes = INDIO_DIRECT_MODE; > > > > - ret = adis_init(&adis16136->adis, indio_dev, spi, &adis16136_data); > > + adis16136_data = adis16136_adis_data_alloc(adis16136, &spi->dev); > > + if (IS_ERR(adis16136_data)) > > + return PTR_ERR(adis16136_data); > > + > > + ret = adis_init(&adis16136->adis, indio_dev, spi, adis16136_data); > > if (ret) > > return ret; > > > > diff --git a/drivers/iio/gyro/adis16260.c > > b/drivers/iio/gyro/adis16260.c > > index 726a0aa321a8..0e3a66a7726d 100644 > > --- a/drivers/iio/gyro/adis16260.c > > +++ b/drivers/iio/gyro/adis16260.c > > @@ -332,6 +332,12 @@ static const char * const > > adis1620_status_error_msgs[] = { > > [ADIS16260_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 4.75", > > }; > > > > +static const struct adis_timeout adis16260_timeouts = { > > + .reset_ms = ADIS16260_STARTUP_DELAY, > > + .sw_reset_ms = ADIS16260_STARTUP_DELAY, > > + .self_test_ms = ADIS16260_STARTUP_DELAY, > > +}; > > + > > static const struct adis_data adis16260_data = { > > .write_delay = 30, > > .read_delay = 30, > > @@ -341,6 +347,7 @@ static const struct adis_data adis16260_data = { > > > > .self_test_mask = ADIS16260_MSC_CTRL_MEM_TEST, > > .startup_delay = ADIS16260_STARTUP_DELAY, > > + .timeouts = &adis16260_timeouts, > > > > .status_error_msgs = adis1620_status_error_msgs, > > .status_error_mask = BIT(ADIS16260_DIAG_STAT_FLASH_CHK_BIT) | > > diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c > > index c53f3ed3cb97..3e12ad4b71ba 100644 > > --- a/drivers/iio/imu/adis.c > > +++ b/drivers/iio/imu/adis.c > > @@ -317,19 +317,25 @@ EXPORT_SYMBOL_GPL(__adis_check_status); > > int __adis_reset(struct adis *adis) > > { > > int ret; > > + const struct adis_timeout *timeouts = adis->data->timeouts; > > > > ret = __adis_write_reg_8(adis, adis->data->glob_cmd_reg, > > ADIS_GLOB_CMD_SW_RESET); > > - if (ret) > > + if (ret) { > > dev_err(&adis->spi->dev, "Failed to reset device: %d\n", > > ret); > > + return ret; > > + } > > > > - return ret; > > + msleep(timeouts->sw_reset_ms); > > + > > + return 0; > > } > > EXPORT_SYMBOL_GPL(__adis_reset); > > > > static int adis_self_test(struct adis *adis) > > { > > int ret; > > + const struct adis_timeout *timeouts = adis->data->timeouts; > > > > ret = __adis_write_reg_16(adis, adis->data->msc_ctrl_reg, > > adis->data->self_test_mask); > > @@ -339,7 +345,7 @@ static int adis_self_test(struct adis *adis) > > return ret; > > } > > > > - msleep(adis->data->startup_delay); > > + msleep(timeouts->self_test_ms); > > > > ret = __adis_check_status(adis); > > > > @@ -368,7 +374,6 @@ int adis_initial_startup(struct adis *adis) > > if (ret) { > > dev_err(&adis->spi->dev, "Self-test failed, trying > > reset.\n"); > > __adis_reset(adis); > > - msleep(adis->data->startup_delay); > > ret = adis_self_test(adis); > > if (ret) { > > dev_err(&adis->spi->dev, "Second self-test failed, > > giving up.\n"); > > @@ -444,6 +449,11 @@ EXPORT_SYMBOL_GPL(adis_single_conversion); > > int adis_init(struct adis *adis, struct iio_dev *indio_dev, > > struct spi_device *spi, const struct adis_data *data) > > { > > + if (!data || !data->timeouts) { > > + dev_err(&spi->dev, "No config data or timeouts not > > defined!\n"); > > + return -EINVAL; > > + } > > + > > mutex_init(&adis->state_lock); > > adis->spi = spi; > > adis->data = data; > > diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c > > index 662cb5367c11..51b1ec23b8ef 100644 > > --- a/drivers/iio/imu/adis16400.c > > +++ b/drivers/iio/imu/adis16400.c > > @@ -156,6 +156,7 @@ struct adis16400_state; > > > > struct adis16400_chip_info { > > const struct iio_chan_spec *channels; > > + const struct adis_timeout *timeouts; > > const int num_channels; > > const long flags; > > unsigned int gyro_scale_micro; > > @@ -929,6 +930,36 @@ static const struct iio_chan_spec > > adis16334_channels[] = { > > IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP), > > }; > > > > +static const struct adis_timeout adis16300_timeouts = { > > + .reset_ms = ADIS16400_STARTUP_DELAY, > > + .sw_reset_ms = ADIS16400_STARTUP_DELAY, > > + .self_test_ms = ADIS16400_STARTUP_DELAY, > > +}; > > + > > +static const struct adis_timeout adis16362_timeouts = { > > + .reset_ms = 130, > > + .sw_reset_ms = 130, > > + .self_test_ms = 12, > > +}; > > + > > +static const struct adis_timeout adis16400_timeouts = { > > + .reset_ms = 170, > > + .sw_reset_ms = 170, > > + .self_test_ms = 12, > > +}; > > + > > +static const struct adis_timeout adis16445_timeouts = { > > + .reset_ms = 55, > > + .sw_reset_ms = 55, > > + .self_test_ms = 16, > > +}; > > + > > +static const struct adis_timeout adis16448_timeouts = { > > + .reset_ms = 90, > > + .sw_reset_ms = 90, > > + .self_test_ms = 45, > > +}; > > + > > static struct adis16400_chip_info adis16400_chips[] = { > > [ADIS16300] = { > > .channels = adis16300_channels, > > @@ -941,6 +972,7 @@ static struct adis16400_chip_info adis16400_chips[] > > = { > > .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */ > > .set_freq = adis16400_set_freq, > > .get_freq = adis16400_get_freq, > > + .timeouts = &adis16300_timeouts, > > }, > > [ADIS16334] = { > > .channels = adis16334_channels, > > @@ -964,6 +996,7 @@ static struct adis16400_chip_info adis16400_chips[] > > = { > > .flags = ADIS16400_NO_BURST | ADIS16400_HAS_SLOW_MODE, > > .set_freq = adis16400_set_freq, > > .get_freq = adis16400_get_freq, > > + .timeouts = &adis16300_timeouts, > > }, > > [ADIS16360] = { > > .channels = adis16350_channels, > > @@ -976,6 +1009,7 @@ static struct adis16400_chip_info > > adis16400_chips[] = { > > .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ > > .set_freq = adis16400_set_freq, > > .get_freq = adis16400_get_freq, > > + .timeouts = &adis16300_timeouts, > > }, > > [ADIS16362] = { > > .channels = adis16350_channels, > > @@ -988,6 +1022,7 @@ static struct adis16400_chip_info > > adis16400_chips[] = { > > .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ > > .set_freq = adis16400_set_freq, > > .get_freq = adis16400_get_freq, > > + .timeouts = &adis16362_timeouts, > > }, > > [ADIS16364] = { > > .channels = adis16350_channels, > > @@ -1000,6 +1035,7 @@ static struct adis16400_chip_info > > adis16400_chips[] = { > > .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ > > .set_freq = adis16400_set_freq, > > .get_freq = adis16400_get_freq, > > + .timeouts = &adis16362_timeouts, > > }, > > [ADIS16367] = { > > .channels = adis16350_channels, > > @@ -1012,6 +1048,7 @@ static struct adis16400_chip_info > > adis16400_chips[] = { > > .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ > > .set_freq = adis16400_set_freq, > > .get_freq = adis16400_get_freq, > > + .timeouts = &adis16300_timeouts, > > }, > > [ADIS16400] = { > > .channels = adis16400_channels, > > @@ -1023,6 +1060,7 @@ static struct adis16400_chip_info > > adis16400_chips[] = { > > .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */ > > .set_freq = adis16400_set_freq, > > .get_freq = adis16400_get_freq, > > + .timeouts = &adis16400_timeouts, > > }, > > [ADIS16445] = { > > .channels = adis16445_channels, > > @@ -1036,6 +1074,7 @@ static struct adis16400_chip_info > > adis16400_chips[] = { > > .temp_offset = 31000000 / 73860, /* 31 C = 0x00 */ > > .set_freq = adis16334_set_freq, > > .get_freq = adis16334_get_freq, > > + .timeouts = &adis16445_timeouts, > > }, > > [ADIS16448] = { > > .channels = adis16448_channels, > > @@ -1049,6 +1088,7 @@ static struct adis16400_chip_info > > adis16400_chips[] = { > > .temp_offset = 31000000 / 73860, /* 31 C = 0x00 */ > > .set_freq = adis16334_set_freq, > > .get_freq = adis16334_get_freq, > > + .timeouts = &adis16448_timeouts, > > } > > }; > > > > @@ -1120,11 +1160,28 @@ static void adis16400_setup_chan_mask(struct > > adis16400_state *st) > > } > > } > > > > +static struct adis_data *adis16400_adis_data_alloc(struct > > adis16400_state *st, > > + struct device *dev) > > +{ > > + struct adis_data *data; > > + > > + data = devm_kmalloc(dev, sizeof(struct adis_data), GFP_KERNEL); > > + if (!data) > > + return ERR_PTR(-ENOMEM); > > + > > + memcpy(data, &adis16400_data, sizeof(*data)); > > + > > + data->timeouts = st->variant->timeouts; > > + > > + return data; > > +} > > + > > static int adis16400_probe(struct spi_device *spi) > > { > > struct adis16400_state *st; > > struct iio_dev *indio_dev; > > int ret; > > + const struct adis_data *adis16400_data; > > > > indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); > > if (indio_dev == NULL) > > @@ -1151,7 +1208,11 @@ static int adis16400_probe(struct spi_device > > *spi) > > st->adis.burst->extra_len = sizeof(u16); > > } > > > > - ret = adis_init(&st->adis, indio_dev, spi, &adis16400_data); > > + adis16400_data = adis16400_adis_data_alloc(st, &spi->dev); > > + if (IS_ERR(adis16400_data)) > > + return PTR_ERR(adis16400_data); > > + > > + ret = adis_init(&st->adis, indio_dev, spi, adis16400_data); > > if (ret) > > return ret; > > > > diff --git a/drivers/iio/imu/adis16460.c b/drivers/iio/imu/adis16460.c > > index b55812521537..9539cfe4a259 100644 > > --- a/drivers/iio/imu/adis16460.c > > +++ b/drivers/iio/imu/adis16460.c > > @@ -383,6 +383,12 @@ static const char * const > > adis16460_status_error_msgs[] = { > > [ADIS16460_DIAG_STAT_FLASH_UPT] = "Flash update failure", > > }; > > > > +static const struct adis_timeout adis16460_timeouts = { > > + .reset_ms = 225, > > + .sw_reset_ms = 225, > > + .self_test_ms = 10, > > +}; > > + > > static const struct adis_data adis16460_data = { > > .diag_stat_reg = ADIS16460_REG_DIAG_STAT, > > .glob_cmd_reg = ADIS16460_REG_GLOB_CMD, > > @@ -398,6 +404,7 @@ static const struct adis_data adis16460_data = { > > BIT(ADIS16460_DIAG_STAT_SPI_COMM) | > > BIT(ADIS16460_DIAG_STAT_FLASH_UPT), > > .enable_irq = adis16460_enable_irq, > > + .timeouts = &adis16460_timeouts, > > }; > > > > static int adis16460_probe(struct spi_device *spi) > > diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c > > index f73094e8d35d..f0ad7ce64861 100644 > > --- a/drivers/iio/imu/adis16480.c > > +++ b/drivers/iio/imu/adis16480.c > > @@ -138,6 +138,7 @@ struct adis16480_chip_info { > > unsigned int max_dec_rate; > > const unsigned int *filter_freqs; > > bool has_pps_clk_mode; > > + const struct adis_timeout *timeouts; > > }; > > > > enum adis16480_int_pin { > > @@ -794,6 +795,30 @@ enum adis16480_variant { > > ADIS16497_3, > > }; > > > > +static const struct adis_timeout adis16485_timeouts = { > > + .reset_ms = 560, > > + .sw_reset_ms = 120, > > + .self_test_ms = 12, > > +}; > > + > > +static const struct adis_timeout adis16480_timeouts = { > > + .reset_ms = 560, > > + .sw_reset_ms = 560, > > + .self_test_ms = 12, > > +}; > > + > > +static const struct adis_timeout adis16495_timeouts = { > > + .reset_ms = 170, > > + .sw_reset_ms = 130, > > + .self_test_ms = 40, > > +}; > > + > > +static const struct adis_timeout adis16495_1_timeouts = { > > + .reset_ms = 250, > > + .sw_reset_ms = 210, > > + .self_test_ms = 20, > > +}; > > + > > static const struct adis16480_chip_info adis16480_chip_info[] = { > > [ADIS16375] = { > > .channels = adis16485_channels, > > @@ -812,6 +837,7 @@ static const struct adis16480_chip_info > > adis16480_chip_info[] = { > > .int_clk = 2460000, > > .max_dec_rate = 2048, > > .filter_freqs = adis16480_def_filter_freqs, > > + .timeouts = &adis16485_timeouts, > > }, > > [ADIS16480] = { > > .channels = adis16480_channels, > > @@ -824,6 +850,7 @@ static const struct adis16480_chip_info > > adis16480_chip_info[] = { > > .int_clk = 2460000, > > .max_dec_rate = 2048, > > .filter_freqs = adis16480_def_filter_freqs, > > + .timeouts = &adis16480_timeouts, > > }, > > [ADIS16485] = { > > .channels = adis16485_channels, > > @@ -836,6 +863,7 @@ static const struct adis16480_chip_info > > adis16480_chip_info[] = { > > .int_clk = 2460000, > > .max_dec_rate = 2048, > > .filter_freqs = adis16480_def_filter_freqs, > > + .timeouts = &adis16485_timeouts, > > }, > > [ADIS16488] = { > > .channels = adis16480_channels, > > @@ -848,6 +876,7 @@ static const struct adis16480_chip_info > > adis16480_chip_info[] = { > > .int_clk = 2460000, > > .max_dec_rate = 2048, > > .filter_freqs = adis16480_def_filter_freqs, > > + .timeouts = &adis16485_timeouts, > > }, > > [ADIS16495_1] = { > > .channels = adis16485_channels, > > @@ -861,6 +890,7 @@ static const struct adis16480_chip_info > > adis16480_chip_info[] = { > > .max_dec_rate = 4250, > > .filter_freqs = adis16495_def_filter_freqs, > > .has_pps_clk_mode = true, > > + .timeouts = &adis16495_1_timeouts, > > }, > > [ADIS16495_2] = { > > .channels = adis16485_channels, > > @@ -874,6 +904,7 @@ static const struct adis16480_chip_info > > adis16480_chip_info[] = { > > .max_dec_rate = 4250, > > .filter_freqs = adis16495_def_filter_freqs, > > .has_pps_clk_mode = true, > > + .timeouts = &adis16495_1_timeouts, > > }, > > [ADIS16495_3] = { > > .channels = adis16485_channels, > > @@ -887,6 +918,7 @@ static const struct adis16480_chip_info > > adis16480_chip_info[] = { > > .max_dec_rate = 4250, > > .filter_freqs = adis16495_def_filter_freqs, > > .has_pps_clk_mode = true, > > + .timeouts = &adis16495_1_timeouts, > > }, > > [ADIS16497_1] = { > > .channels = adis16485_channels, > > @@ -900,6 +932,7 @@ static const struct adis16480_chip_info > > adis16480_chip_info[] = { > > .max_dec_rate = 4250, > > .filter_freqs = adis16495_def_filter_freqs, > > .has_pps_clk_mode = true, > > + .timeouts = &adis16495_1_timeouts, > > }, > > [ADIS16497_2] = { > > .channels = adis16485_channels, > > @@ -913,6 +946,7 @@ static const struct adis16480_chip_info > > adis16480_chip_info[] = { > > .max_dec_rate = 4250, > > .filter_freqs = adis16495_def_filter_freqs, > > .has_pps_clk_mode = true, > > + .timeouts = &adis16495_1_timeouts, > > }, > > [ADIS16497_3] = { > > .channels = adis16485_channels, > > @@ -926,6 +960,7 @@ static const struct adis16480_chip_info > > adis16480_chip_info[] = { > > .max_dec_rate = 4250, > > .filter_freqs = adis16495_def_filter_freqs, > > .has_pps_clk_mode = true, > > + .timeouts = &adis16495_1_timeouts, > > }, > > }; > > > > @@ -1195,9 +1230,26 @@ static int adis16480_get_ext_clocks(struct > > adis16480 *st) > > return 0; > > } > > > > +static struct adis_data *adis16480_adis_data_alloc(struct adis16480 > > *st, > > + struct device *dev) > > +{ > > + struct adis_data *data; > > + > > + data = devm_kmalloc(dev, sizeof(struct adis_data), GFP_KERNEL); > > + if (!data) > > + return ERR_PTR(-ENOMEM); > > + > > + memcpy(data, &adis16480_data, sizeof(*data)); > > + > > + data->timeouts = st->chip_info->timeouts; > > + > > + return data; > > +} > > + > > static int adis16480_probe(struct spi_device *spi) > > { > > const struct spi_device_id *id = spi_get_device_id(spi); > > + const struct adis_data *adis16480_data; > > struct iio_dev *indio_dev; > > struct adis16480 *st; > > int ret; > > @@ -1218,7 +1270,11 @@ static int adis16480_probe(struct spi_device > > *spi) > > indio_dev->info = &adis16480_info; > > indio_dev->modes = INDIO_DIRECT_MODE; > > > > - ret = adis_init(&st->adis, indio_dev, spi, &adis16480_data); > > + adis16480_data = adis16480_adis_data_alloc(st, &spi->dev); > > + if (IS_ERR(adis16480_data)) > > + return PTR_ERR(adis16480_data); > > + > > + ret = adis_init(&st->adis, indio_dev, spi, adis16480_data); > > if (ret) > > return ret; > > > > diff --git a/drivers/staging/iio/accel/adis16203.c > > b/drivers/staging/iio/accel/adis16203.c > > index 39687139a7d3..3d706ee02df0 100644 > > --- a/drivers/staging/iio/accel/adis16203.c > > +++ b/drivers/staging/iio/accel/adis16203.c > > @@ -237,6 +237,12 @@ static const char * const > > adis16203_status_error_msgs[] = { > > [ADIS16203_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.975V", > > }; > > > > +static const struct adis_timeout adis16203_timeouts = { > > + .reset_ms = ADIS16203_STARTUP_DELAY, > > + .sw_reset_ms = ADIS16203_STARTUP_DELAY, > > + .self_test_ms = ADIS16203_STARTUP_DELAY > > +}; > > + > > static const struct adis_data adis16203_data = { > > .read_delay = 20, > > .msc_ctrl_reg = ADIS16203_MSC_CTRL, > > @@ -246,6 +252,7 @@ static const struct adis_data adis16203_data = { > > .self_test_mask = ADIS16203_MSC_CTRL_SELF_TEST_EN, > > .self_test_no_autoclear = true, > > .startup_delay = ADIS16203_STARTUP_DELAY, > > + .timeouts = &adis16203_timeouts, > > > > .status_error_msgs = adis16203_status_error_msgs, > > .status_error_mask = BIT(ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT) | > > diff --git a/drivers/staging/iio/accel/adis16240.c > > b/drivers/staging/iio/accel/adis16240.c > > index 794f063e6c86..d4848ef78c75 100644 > > --- a/drivers/staging/iio/accel/adis16240.c > > +++ b/drivers/staging/iio/accel/adis16240.c > > @@ -359,6 +359,12 @@ static const char * const > > adis16240_status_error_msgs[] = { > > [ADIS16240_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.225V", > > }; > > > > +static const struct adis_timeout adis16240_timeouts = { > > + .reset_ms = ADIS16240_STARTUP_DELAY, > > + .sw_reset_ms = ADIS16240_STARTUP_DELAY, > > + .self_test_ms = ADIS16240_STARTUP_DELAY, > > +}; > > + > > static const struct adis_data adis16240_data = { > > .write_delay = 35, > > .read_delay = 35, > > @@ -369,6 +375,7 @@ static const struct adis_data adis16240_data = { > > .self_test_mask = ADIS16240_MSC_CTRL_SELF_TEST_EN, > > .self_test_no_autoclear = true, > > .startup_delay = ADIS16240_STARTUP_DELAY, > > + .timeouts = &adis16240_timeouts, > > > > .status_error_msgs = adis16240_status_error_msgs, > > .status_error_mask = BIT(ADIS16240_DIAG_STAT_PWRON_FAIL_BIT) | > > diff --git a/include/linux/iio/imu/adis.h > > b/include/linux/iio/imu/adis.h > > index 4b5bc0e06e69..853dc8c8365c 100644 > > --- a/include/linux/iio/imu/adis.h > > +++ b/include/linux/iio/imu/adis.h > > @@ -22,6 +22,17 @@ > > struct adis; > > struct adis_burst; > > > > +/** > > + * struct adis_timeouts - ADIS chip variant timeouts > > + * @reset_ms - Wait time after rst pin goes inactive > > + * @sw_reset_ms - Wait time after sw reset command > > + * @self_test_ms - Wait time after self test command > > + */ > > +struct adis_timeout { > > + u16 reset_ms; > > + u16 sw_reset_ms; > > + u16 self_test_ms; > > +}; > > /** > > * struct adis_data - ADIS chip variant specific data > > * @read_delay: SPI delay for read operations in us > > @@ -32,6 +43,7 @@ struct adis_burst; > > * @diag_stat_reg: Register address of the DIAG_STAT register > > * @status_error_msgs: Array of error messgaes > > * @status_error_mask: > > + * @timeouts: Chip specific delays > > */ > > struct adis_data { > > unsigned int read_delay; > > @@ -45,6 +57,7 @@ struct adis_data { > > unsigned int self_test_mask; > > bool self_test_no_autoclear; > > unsigned int startup_delay; > > + const struct adis_timeout *timeouts; > > > > const char * const *status_error_msgs; > > unsigned int status_error_mask;