Merge tag 'char-misc-6.18-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull char / misc / IIO fixes from Greg KH:
 "Here are some much-delayed char/misc/iio driver fixes for 6.18-rc8.

  Fixes in here include:

   - lots of iio driver bugfixes for reported issues.

   - counter driver bugfix

   - slimbus driver bugfix

   - mei tiny bugfix

   - nvmem layout uevent bugfix

  All of these have been in linux-next for a while, but due to travel on
  my side, I haven't had a chance to get them to you"

* tag 'char-misc-6.18-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (23 commits)
  nvmem: layouts: fix nvmem_layout_bus_uevent
  iio: accel: bmc150: Fix irq assumption regression
  most: usb: fix double free on late probe failure
  slimbus: ngd: Fix reference count leak in qcom_slim_ngd_notify_slaves
  firmware: stratix10-svc: fix bug in saving controller data
  mei: fix error flow in probe
  iio: st_lsm6dsx: Fixed calibrated timestamp calculation
  iio: humditiy: hdc3020: fix units for thresholds and hysteresis
  iio: humditiy: hdc3020: fix units for temperature and humidity measurement
  iio: imu: st_lsm6dsx: fix array size for st_lsm6dsx_settings fields
  iio: accel: fix ADXL355 startup race condition
  iio: adc: ad7124: fix temperature channel
  iio:common:ssp_sensors: Fix an error handling path ssp_probe()
  iio: adc: ad7280a: fix ad7280_store_balance_timer()
  iio: buffer-dmaengine: enable .get_dma_dev()
  iio: buffer-dma: support getting the DMA channel
  iio: buffer: support getting dma channel from the buffer
  iio: pressure: bmp280: correct meas_time_us calculation
  iio: adc: stm32-dfsdm: fix st,adc-alt-channel property handling
  iio: adc: ad7380: fix SPI offload trigger rate
  ...
This commit is contained in:
Linus Torvalds
2025-11-28 09:44:48 -08:00
27 changed files with 214 additions and 113 deletions

View File

@@ -451,7 +451,7 @@ static void mchp_tc_irq_remove(void *ptr)
static int mchp_tc_irq_enable(struct counter_device *const counter, int irq)
{
struct mchp_tc_data *const priv = counter_priv(counter);
int ret = devm_request_irq(counter->parent, irq, mchp_tc_isr, 0,
int ret = devm_request_irq(counter->parent, irq, mchp_tc_isr, IRQF_SHARED,
dev_name(counter->parent), counter);
if (ret < 0)

View File

@@ -134,6 +134,7 @@ struct stratix10_svc_data {
* @complete_status: state for completion
* @svc_fifo_lock: protect access to service message data queue
* @invoke_fn: function to issue secure monitor call or hypervisor call
* @svc: manages the list of client svc drivers
*
* This struct is used to create communication channels for service clients, to
* handle secure monitor or hypervisor call.
@@ -150,6 +151,7 @@ struct stratix10_svc_controller {
struct completion complete_status;
spinlock_t svc_fifo_lock;
svc_invoke_fn *invoke_fn;
struct stratix10_svc *svc;
};
/**
@@ -1206,6 +1208,7 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev)
ret = -ENOMEM;
goto err_free_kfifo;
}
controller->svc = svc;
svc->stratix10_svc_rsu = platform_device_alloc(STRATIX10_RSU, 0);
if (!svc->stratix10_svc_rsu) {
@@ -1237,8 +1240,6 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev)
if (ret)
goto err_unregister_fcs_dev;
dev_set_drvdata(dev, svc);
pr_info("Intel Service Layer Driver Initialized\n");
return 0;
@@ -1256,8 +1257,8 @@ err_destroy_pool:
static void stratix10_svc_drv_remove(struct platform_device *pdev)
{
struct stratix10_svc *svc = dev_get_drvdata(&pdev->dev);
struct stratix10_svc_controller *ctrl = platform_get_drvdata(pdev);
struct stratix10_svc *svc = ctrl->svc;
of_platform_depopulate(ctrl->dev);

View File

@@ -56,6 +56,8 @@
#define ADXL355_POWER_CTL_DRDY_MSK BIT(2)
#define ADXL355_SELF_TEST_REG 0x2E
#define ADXL355_RESET_REG 0x2F
#define ADXL355_BASE_ADDR_SHADOW_REG 0x50
#define ADXL355_SHADOW_REG_COUNT 5
#define ADXL355_DEVID_AD_VAL 0xAD
#define ADXL355_DEVID_MST_VAL 0x1D
@@ -294,7 +296,12 @@ static void adxl355_fill_3db_frequency_table(struct adxl355_data *data)
static int adxl355_setup(struct adxl355_data *data)
{
unsigned int regval;
int retries = 5; /* the number is chosen based on empirical reasons */
int ret;
u8 *shadow_regs __free(kfree) = kzalloc(ADXL355_SHADOW_REG_COUNT, GFP_KERNEL);
if (!shadow_regs)
return -ENOMEM;
ret = regmap_read(data->regmap, ADXL355_DEVID_AD_REG, &regval);
if (ret)
@@ -321,14 +328,41 @@ static int adxl355_setup(struct adxl355_data *data)
if (regval != ADXL355_PARTID_VAL)
dev_warn(data->dev, "Invalid DEV ID 0x%02x\n", regval);
/*
* Perform a software reset to make sure the device is in a consistent
* state after start-up.
*/
ret = regmap_write(data->regmap, ADXL355_RESET_REG, ADXL355_RESET_CODE);
/* Read shadow registers to be compared after reset */
ret = regmap_bulk_read(data->regmap,
ADXL355_BASE_ADDR_SHADOW_REG,
shadow_regs, ADXL355_SHADOW_REG_COUNT);
if (ret)
return ret;
do {
if (--retries == 0) {
dev_err(data->dev, "Shadow registers mismatch\n");
return -EIO;
}
/*
* Perform a software reset to make sure the device is in a consistent
* state after start-up.
*/
ret = regmap_write(data->regmap, ADXL355_RESET_REG,
ADXL355_RESET_CODE);
if (ret)
return ret;
/* Wait at least 5ms after software reset */
usleep_range(5000, 10000);
/* Read shadow registers for comparison */
ret = regmap_bulk_read(data->regmap,
ADXL355_BASE_ADDR_SHADOW_REG,
data->buffer.buf,
ADXL355_SHADOW_REG_COUNT);
if (ret)
return ret;
} while (memcmp(shadow_regs, data->buffer.buf,
ADXL355_SHADOW_REG_COUNT));
ret = regmap_update_bits(data->regmap, ADXL355_POWER_CTL_REG,
ADXL355_POWER_CTL_DRDY_MSK,
FIELD_PREP(ADXL355_POWER_CTL_DRDY_MSK, 1));

View File

@@ -523,6 +523,10 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
const struct bmc150_accel_interrupt_info *info = intr->info;
int ret;
/* We do not always have an IRQ */
if (data->irq <= 0)
return 0;
if (state) {
if (atomic_inc_return(&intr->users) > 1)
return 0;
@@ -1696,6 +1700,7 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
}
if (irq > 0) {
data->irq = irq;
ret = devm_request_threaded_irq(dev, irq,
bmc150_accel_irq_handler,
bmc150_accel_irq_thread_handler,

View File

@@ -58,6 +58,7 @@ enum bmc150_accel_trigger_id {
struct bmc150_accel_data {
struct regmap *regmap;
int irq;
struct regulator_bulk_data regulators[2];
struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];

View File

@@ -385,7 +385,7 @@ static int ad4030_get_chan_scale(struct iio_dev *indio_dev,
struct ad4030_state *st = iio_priv(indio_dev);
const struct iio_scan_type *scan_type;
scan_type = iio_get_current_scan_type(indio_dev, st->chip->channels);
scan_type = iio_get_current_scan_type(indio_dev, chan);
if (IS_ERR(scan_type))
return PTR_ERR(scan_type);

View File

@@ -1525,10 +1525,6 @@ static int __ad7124_calibrate_all(struct ad7124_state *st, struct iio_dev *indio
int ret, i;
for (i = 0; i < st->num_channels; i++) {
if (indio_dev->channels[i].type != IIO_VOLTAGE)
continue;
/*
* For calibration the OFFSET register should hold its reset default
* value. For the GAIN register there is no such requirement but
@@ -1538,6 +1534,14 @@ static int __ad7124_calibrate_all(struct ad7124_state *st, struct iio_dev *indio
st->channels[i].cfg.calibration_offset = 0x800000;
st->channels[i].cfg.calibration_gain = st->gain_default;
/*
* Only the main voltage input channels are important enough
* to be automatically calibrated here. For everything else,
* just use the default values set above.
*/
if (indio_dev->channels[i].type != IIO_VOLTAGE)
continue;
/*
* Full-scale calibration isn't supported at gain 1, so skip in
* that case. Note that untypically full-scale calibration has

View File

@@ -541,7 +541,7 @@ static ssize_t ad7280_store_balance_timer(struct iio_dev *indio_dev,
int val, val2;
int ret;
ret = iio_str_to_fixpoint(buf, 1000, &val, &val2);
ret = iio_str_to_fixpoint(buf, 100, &val, &val2);
if (ret)
return ret;

View File

@@ -1227,6 +1227,14 @@ static int ad7380_offload_buffer_postenable(struct iio_dev *indio_dev)
if (ret)
return ret;
/*
* When the sequencer is required to read all channels, we need to
* trigger twice per sample period in order to read one complete set
* of samples.
*/
if (st->seq)
config.periodic.frequency_hz *= 2;
ret = spi_offload_trigger_enable(st->offload, st->offload_trigger, &config);
if (ret)
spi_unoptimize_message(&st->offload_msg);

View File

@@ -300,7 +300,7 @@ static int rtq6056_adc_read_channel(struct rtq6056_priv *priv,
return IIO_VAL_INT;
case RTQ6056_REG_SHUNTVOLT:
case RTQ6056_REG_CURRENT:
*val = sign_extend32(regval, 16);
*val = sign_extend32(regval, 15);
return IIO_VAL_INT;
default:
return -EINVAL;

View File

@@ -725,9 +725,8 @@ static int stm32_dfsdm_generic_channel_parse_of(struct stm32_dfsdm *dfsdm,
}
df_ch->src = val;
ret = fwnode_property_read_u32(node, "st,adc-alt-channel", &df_ch->alt_si);
if (ret != -EINVAL)
df_ch->alt_si = 0;
if (fwnode_property_present(node, "st,adc-alt-channel"))
df_ch->alt_si = 1;
if (adc->dev_data->type == DFSDM_IIO) {
backend = devm_iio_backend_fwnode_get(&indio_dev->dev, NULL, node);

View File

@@ -786,6 +786,12 @@ out_end_signalling:
}
EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_enqueue_dmabuf, "IIO_DMA_BUFFER");
struct device *iio_dma_buffer_get_dma_dev(struct iio_buffer *buffer)
{
return iio_buffer_to_queue(buffer)->dev;
}
EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_get_dma_dev, "IIO_DMA_BUFFER");
void iio_dma_buffer_lock_queue(struct iio_buffer *buffer)
{
struct iio_dma_buffer_queue *queue = iio_buffer_to_queue(buffer);

View File

@@ -177,6 +177,8 @@ static const struct iio_buffer_access_funcs iio_dmaengine_buffer_ops = {
.lock_queue = iio_dma_buffer_lock_queue,
.unlock_queue = iio_dma_buffer_unlock_queue,
.get_dma_dev = iio_dma_buffer_get_dma_dev,
.modes = INDIO_BUFFER_HARDWARE,
.flags = INDIO_BUFFER_FLAG_FIXED_WATERMARK,
};

View File

@@ -503,7 +503,7 @@ static int ssp_probe(struct spi_device *spi)
ret = spi_setup(spi);
if (ret < 0) {
dev_err(&spi->dev, "Failed to setup spi\n");
return ret;
goto err_setup_spi;
}
data->fw_dl_state = SSP_FW_DL_STATE_NONE;
@@ -568,6 +568,8 @@ err_read_reg:
err_setup_irq:
mutex_destroy(&data->pending_lock);
mutex_destroy(&data->comm_lock);
err_setup_spi:
mfd_remove_devices(&spi->dev);
dev_err(&spi->dev, "Probe failed!\n");

View File

@@ -72,6 +72,9 @@
#define HDC3020_MAX_TEMP_HYST_MICRO 164748607
#define HDC3020_MAX_HUM_MICRO 99220264
/* Divide 65535 from the datasheet by 5 to avoid overflows */
#define HDC3020_THRESH_FRACTION (65535 / 5)
struct hdc3020_data {
struct i2c_client *client;
struct gpio_desc *reset_gpio;
@@ -301,9 +304,9 @@ static int hdc3020_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_SCALE:
*val2 = 65536;
if (chan->type == IIO_TEMP)
*val = 175;
*val = 175 * MILLI;
else
*val = 100;
*val = 100 * MILLI;
return IIO_VAL_FRACTIONAL;
case IIO_CHAN_INFO_OFFSET:
@@ -376,15 +379,18 @@ static int hdc3020_thresh_get_temp(u16 thresh)
int temp;
/*
* Get the temperature threshold from 9 LSBs, shift them to get
* the truncated temperature threshold representation and
* calculate the threshold according to the formula in the
* datasheet. Result is degree celsius scaled by 65535.
* Get the temperature threshold from 9 LSBs, shift them to get the
* truncated temperature threshold representation and calculate the
* threshold according to the explicit formula in the datasheet:
* T(C) = -45 + (175 * temp) / 65535.
* Additionally scale by HDC3020_THRESH_FRACTION to avoid precision loss
* when calculating threshold and hysteresis values. Result is degree
* celsius scaled by HDC3020_THRESH_FRACTION.
*/
temp = FIELD_GET(HDC3020_THRESH_TEMP_MASK, thresh) <<
HDC3020_THRESH_TEMP_TRUNC_SHIFT;
return -2949075 + (175 * temp);
return -2949075 / 5 + (175 / 5 * temp);
}
static int hdc3020_thresh_get_hum(u16 thresh)
@@ -394,13 +400,16 @@ static int hdc3020_thresh_get_hum(u16 thresh)
/*
* Get the humidity threshold from 7 MSBs, shift them to get the
* truncated humidity threshold representation and calculate the
* threshold according to the formula in the datasheet. Result is
* percent scaled by 65535.
* threshold according to the explicit formula in the datasheet:
* RH(%) = 100 * hum / 65535.
* Additionally scale by HDC3020_THRESH_FRACTION to avoid precision loss
* when calculating threshold and hysteresis values. Result is percent
* scaled by HDC3020_THRESH_FRACTION.
*/
hum = FIELD_GET(HDC3020_THRESH_HUM_MASK, thresh) <<
HDC3020_THRESH_HUM_TRUNC_SHIFT;
return hum * 100;
return hum * 100 / 5;
}
static u16 hdc3020_thresh_set_temp(int s_temp, u16 curr_thresh)
@@ -455,8 +464,8 @@ int hdc3020_thresh_clr(s64 s_thresh, s64 s_hyst, enum iio_event_direction dir)
else
s_clr = s_thresh + s_hyst;
/* Divide by 65535 to get units of micro */
return div_s64(s_clr, 65535);
/* Divide by HDC3020_THRESH_FRACTION to get units of micro */
return div_s64(s_clr, HDC3020_THRESH_FRACTION);
}
static int _hdc3020_write_thresh(struct hdc3020_data *data, u16 reg, u16 val)
@@ -507,7 +516,7 @@ static int hdc3020_write_thresh(struct iio_dev *indio_dev,
clr = ret;
/* Scale value to include decimal part into calculations */
s_val = (val < 0) ? (val * 1000000 - val2) : (val * 1000000 + val2);
s_val = (val < 0) ? (val * 1000 - val2) : (val * 1000 + val2);
switch (chan->type) {
case IIO_TEMP:
switch (info) {
@@ -523,7 +532,8 @@ static int hdc3020_write_thresh(struct iio_dev *indio_dev,
/* Calculate old hysteresis */
s_thresh = (s64)hdc3020_thresh_get_temp(thresh) * 1000000;
s_clr = (s64)hdc3020_thresh_get_temp(clr) * 1000000;
s_hyst = div_s64(abs(s_thresh - s_clr), 65535);
s_hyst = div_s64(abs(s_thresh - s_clr),
HDC3020_THRESH_FRACTION);
/* Set new threshold */
thresh = reg_val;
/* Set old hysteresis */
@@ -532,16 +542,17 @@ static int hdc3020_write_thresh(struct iio_dev *indio_dev,
case IIO_EV_INFO_HYSTERESIS:
/*
* Function hdc3020_thresh_get_temp returns temperature
* in degree celsius scaled by 65535. Scale by 1000000
* to be able to subtract scaled hysteresis value.
* in degree celsius scaled by HDC3020_THRESH_FRACTION.
* Scale by 1000000 to be able to subtract scaled
* hysteresis value.
*/
s_thresh = (s64)hdc3020_thresh_get_temp(thresh) * 1000000;
/*
* Units of s_val are in micro degree celsius, scale by
* 65535 to get same units as s_thresh.
* HDC3020_THRESH_FRACTION to get same units as s_thresh.
*/
s_val = min(abs(s_val), HDC3020_MAX_TEMP_HYST_MICRO);
s_hyst = (s64)s_val * 65535;
s_hyst = (s64)s_val * HDC3020_THRESH_FRACTION;
s_clr = hdc3020_thresh_clr(s_thresh, s_hyst, dir);
s_clr = max(s_clr, HDC3020_MIN_TEMP_MICRO);
s_clr = min(s_clr, HDC3020_MAX_TEMP_MICRO);
@@ -565,7 +576,8 @@ static int hdc3020_write_thresh(struct iio_dev *indio_dev,
/* Calculate old hysteresis */
s_thresh = (s64)hdc3020_thresh_get_hum(thresh) * 1000000;
s_clr = (s64)hdc3020_thresh_get_hum(clr) * 1000000;
s_hyst = div_s64(abs(s_thresh - s_clr), 65535);
s_hyst = div_s64(abs(s_thresh - s_clr),
HDC3020_THRESH_FRACTION);
/* Set new threshold */
thresh = reg_val;
/* Try to set old hysteresis */
@@ -574,15 +586,16 @@ static int hdc3020_write_thresh(struct iio_dev *indio_dev,
case IIO_EV_INFO_HYSTERESIS:
/*
* Function hdc3020_thresh_get_hum returns relative
* humidity in percent scaled by 65535. Scale by 1000000
* to be able to subtract scaled hysteresis value.
* humidity in percent scaled by HDC3020_THRESH_FRACTION.
* Scale by 1000000 to be able to subtract scaled
* hysteresis value.
*/
s_thresh = (s64)hdc3020_thresh_get_hum(thresh) * 1000000;
/*
* Units of s_val are in micro percent, scale by 65535
* to get same units as s_thresh.
* Units of s_val are in micro percent, scale by
* HDC3020_THRESH_FRACTION to get same units as s_thresh.
*/
s_hyst = (s64)s_val * 65535;
s_hyst = (s64)s_val * HDC3020_THRESH_FRACTION;
s_clr = hdc3020_thresh_clr(s_thresh, s_hyst, dir);
s_clr = max(s_clr, 0);
s_clr = min(s_clr, HDC3020_MAX_HUM_MICRO);
@@ -630,7 +643,7 @@ static int hdc3020_read_thresh(struct iio_dev *indio_dev,
thresh = hdc3020_thresh_get_temp(ret);
switch (info) {
case IIO_EV_INFO_VALUE:
*val = thresh;
*val = thresh * MILLI;
break;
case IIO_EV_INFO_HYSTERESIS:
ret = hdc3020_read_be16(data, reg_clr);
@@ -638,18 +651,18 @@ static int hdc3020_read_thresh(struct iio_dev *indio_dev,
return ret;
clr = hdc3020_thresh_get_temp(ret);
*val = abs(thresh - clr);
*val = abs(thresh - clr) * MILLI;
break;
default:
return -EOPNOTSUPP;
}
*val2 = 65535;
*val2 = HDC3020_THRESH_FRACTION;
return IIO_VAL_FRACTIONAL;
case IIO_HUMIDITYRELATIVE:
thresh = hdc3020_thresh_get_hum(ret);
switch (info) {
case IIO_EV_INFO_VALUE:
*val = thresh;
*val = thresh * MILLI;
break;
case IIO_EV_INFO_HYSTERESIS:
ret = hdc3020_read_be16(data, reg_clr);
@@ -657,12 +670,12 @@ static int hdc3020_read_thresh(struct iio_dev *indio_dev,
return ret;
clr = hdc3020_thresh_get_hum(ret);
*val = abs(thresh - clr);
*val = abs(thresh - clr) * MILLI;
break;
default:
return -EOPNOTSUPP;
}
*val2 = 65535;
*val2 = HDC3020_THRESH_FRACTION;
return IIO_VAL_FRACTIONAL;
default:
return -EOPNOTSUPP;

View File

@@ -192,6 +192,22 @@ struct st_lsm6dsx_fifo_ops {
* @fifo_en: Hw timer FIFO enable register info (addr + mask).
* @decimator: Hw timer FIFO decimator register info (addr + mask).
* @freq_fine: Difference in % of ODR with respect to the typical.
* @ts_sensitivity: Nominal timestamp sensitivity.
* @ts_trim_coeff: Coefficient for calculating the calibrated timestamp gain.
* This coefficient comes into play when linearizing the formula
* used to calculate the calibrated timestamp (please see the
* relevant formula in the AN for the specific IMU).
* For example, in the case of LSM6DSO we have:
*
* 1 / (1 + x) ~= 1 - x (Taylors Series)
* ttrim[s] = 1 / (40000 * (1 + 0.0015 * val)) (from AN5192)
* ttrim[ns] ~= 25000 - 37.5 * val
* ttrim[ns] ~= 25000 - (37500 * val) / 1000
*
* so, replacing ts_sensitivity = 25000 and
* ts_trim_coeff = 37500
*
* ttrim[ns] ~= ts_sensitivity - (ts_trim_coeff * val) / 1000
*/
struct st_lsm6dsx_hw_ts_settings {
struct st_lsm6dsx_reg timer_en;
@@ -199,6 +215,8 @@ struct st_lsm6dsx_hw_ts_settings {
struct st_lsm6dsx_reg fifo_en;
struct st_lsm6dsx_reg decimator;
u8 freq_fine;
u16 ts_sensitivity;
u16 ts_trim_coeff;
};
/**
@@ -252,6 +270,15 @@ struct st_lsm6dsx_event_settings {
u8 wakeup_src_x_mask;
};
enum st_lsm6dsx_sensor_id {
ST_LSM6DSX_ID_GYRO,
ST_LSM6DSX_ID_ACC,
ST_LSM6DSX_ID_EXT0,
ST_LSM6DSX_ID_EXT1,
ST_LSM6DSX_ID_EXT2,
ST_LSM6DSX_ID_MAX
};
enum st_lsm6dsx_ext_sensor_id {
ST_LSM6DSX_ID_MAGN,
};
@@ -337,23 +364,14 @@ struct st_lsm6dsx_settings {
struct st_lsm6dsx_odr_table_entry odr_table[2];
struct st_lsm6dsx_samples_to_discard samples_to_discard[2];
struct st_lsm6dsx_fs_table_entry fs_table[2];
struct st_lsm6dsx_reg decimator[ST_LSM6DSX_MAX_ID];
struct st_lsm6dsx_reg batch[ST_LSM6DSX_MAX_ID];
struct st_lsm6dsx_reg decimator[ST_LSM6DSX_ID_MAX];
struct st_lsm6dsx_reg batch[2];
struct st_lsm6dsx_fifo_ops fifo_ops;
struct st_lsm6dsx_hw_ts_settings ts_settings;
struct st_lsm6dsx_shub_settings shub_settings;
struct st_lsm6dsx_event_settings event_settings;
};
enum st_lsm6dsx_sensor_id {
ST_LSM6DSX_ID_GYRO,
ST_LSM6DSX_ID_ACC,
ST_LSM6DSX_ID_EXT0,
ST_LSM6DSX_ID_EXT1,
ST_LSM6DSX_ID_EXT2,
ST_LSM6DSX_ID_MAX,
};
enum st_lsm6dsx_fifo_mode {
ST_LSM6DSX_FIFO_BYPASS = 0x0,
ST_LSM6DSX_FIFO_CONT = 0x6,

View File

@@ -94,8 +94,6 @@
#define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f
#define ST_LSM6DSX_TS_SENSITIVITY 25000UL /* 25us */
static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
@@ -983,6 +981,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
.mask = GENMASK(7, 6),
},
.freq_fine = 0x63,
.ts_sensitivity = 25000,
.ts_trim_coeff = 37500,
},
.shub_settings = {
.page_mux = {
@@ -1196,6 +1196,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
.mask = GENMASK(7, 6),
},
.freq_fine = 0x63,
.ts_sensitivity = 25000,
.ts_trim_coeff = 37500,
},
.event_settings = {
.enable_reg = {
@@ -1371,6 +1373,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
.mask = GENMASK(7, 6),
},
.freq_fine = 0x4f,
.ts_sensitivity = 21701,
.ts_trim_coeff = 28212,
},
.shub_settings = {
.page_mux = {
@@ -2248,20 +2252,13 @@ static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw)
}
/* calibrate timestamp sensitivity */
hw->ts_gain = ST_LSM6DSX_TS_SENSITIVITY;
hw->ts_gain = ts_settings->ts_sensitivity;
if (ts_settings->freq_fine) {
err = regmap_read(hw->regmap, ts_settings->freq_fine, &val);
if (err < 0)
return err;
/*
* linearize the AN5192 formula:
* 1 / (1 + x) ~= 1 - x (Taylors Series)
* ttrim[s] = 1 / (40000 * (1 + 0.0015 * val))
* ttrim[ns] ~= 25000 - 37.5 * val
* ttrim[ns] ~= 25000 - (37500 * val) / 1000
*/
hw->ts_gain -= ((s8)val * 37500) / 1000;
hw->ts_gain -= ((s8)val * ts_settings->ts_trim_coeff) / 1000;
}
return 0;

View File

@@ -1623,19 +1623,28 @@ static int iio_dma_resv_lock(struct dma_buf *dmabuf, bool nonblock)
return 0;
}
static struct device *iio_buffer_get_dma_dev(const struct iio_dev *indio_dev,
struct iio_buffer *buffer)
{
if (buffer->access->get_dma_dev)
return buffer->access->get_dma_dev(buffer);
return indio_dev->dev.parent;
}
static struct dma_buf_attachment *
iio_buffer_find_attachment(struct iio_dev_buffer_pair *ib,
struct dma_buf *dmabuf, bool nonblock)
{
struct device *dev = ib->indio_dev->dev.parent;
struct iio_buffer *buffer = ib->buffer;
struct device *dma_dev = iio_buffer_get_dma_dev(ib->indio_dev, buffer);
struct dma_buf_attachment *attach = NULL;
struct iio_dmabuf_priv *priv;
guard(mutex)(&buffer->dmabufs_mutex);
list_for_each_entry(priv, &buffer->dmabufs, entry) {
if (priv->attach->dev == dev
if (priv->attach->dev == dma_dev
&& priv->attach->dmabuf == dmabuf) {
attach = priv->attach;
break;
@@ -1653,6 +1662,7 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib,
{
struct iio_dev *indio_dev = ib->indio_dev;
struct iio_buffer *buffer = ib->buffer;
struct device *dma_dev = iio_buffer_get_dma_dev(indio_dev, buffer);
struct dma_buf_attachment *attach;
struct iio_dmabuf_priv *priv, *each;
struct dma_buf *dmabuf;
@@ -1679,7 +1689,7 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib,
goto err_free_priv;
}
attach = dma_buf_attach(dmabuf, indio_dev->dev.parent);
attach = dma_buf_attach(dmabuf, dma_dev);
if (IS_ERR(attach)) {
err = PTR_ERR(attach);
goto err_dmabuf_put;
@@ -1719,7 +1729,7 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib,
* combo. If we do, refuse to attach.
*/
list_for_each_entry(each, &buffer->dmabufs, entry) {
if (each->attach->dev == indio_dev->dev.parent
if (each->attach->dev == dma_dev
&& each->attach->dmabuf == dmabuf) {
/*
* We unlocked the reservation object, so going through
@@ -1758,6 +1768,7 @@ static int iio_buffer_detach_dmabuf(struct iio_dev_buffer_pair *ib,
{
struct iio_buffer *buffer = ib->buffer;
struct iio_dev *indio_dev = ib->indio_dev;
struct device *dma_dev = iio_buffer_get_dma_dev(indio_dev, buffer);
struct iio_dmabuf_priv *priv;
struct dma_buf *dmabuf;
int dmabuf_fd, ret = -EPERM;
@@ -1772,7 +1783,7 @@ static int iio_buffer_detach_dmabuf(struct iio_dev_buffer_pair *ib,
guard(mutex)(&buffer->dmabufs_mutex);
list_for_each_entry(priv, &buffer->dmabufs, entry) {
if (priv->attach->dev == indio_dev->dev.parent
if (priv->attach->dev == dma_dev
&& priv->attach->dmabuf == dmabuf) {
list_del(&priv->entry);

View File

@@ -1040,13 +1040,16 @@ static int bmp280_wait_conv(struct bmp280_data *data)
unsigned int reg, meas_time_us;
int ret;
/* Check if we are using a BME280 device */
if (data->oversampling_humid)
meas_time_us = BMP280_PRESS_HUMID_MEAS_OFFSET +
BIT(data->oversampling_humid) * BMP280_MEAS_DUR;
/* Constant part of the measurement time */
meas_time_us = BMP280_MEAS_OFFSET;
else
meas_time_us = 0;
/*
* Check if we are using a BME280 device,
* Humidity measurement time
*/
if (data->chip_info->oversampling_humid_avail)
meas_time_us += BMP280_PRESS_HUMID_MEAS_OFFSET +
BIT(data->oversampling_humid) * BMP280_MEAS_DUR;
/* Pressure measurement time */
meas_time_us += BMP280_PRESS_HUMID_MEAS_OFFSET +

View File

@@ -223,6 +223,10 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
hw->mem_addr = pcim_iomap_table(pdev)[0];
hw->read_fws = mei_me_read_fws;
err = mei_register(dev, &pdev->dev);
if (err)
goto end;
pci_enable_msi(pdev);
hw->irq = pdev->irq;
@@ -237,13 +241,9 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err) {
dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n",
pdev->irq);
goto end;
goto deregister;
}
err = mei_register(dev, &pdev->dev);
if (err)
goto release_irq;
if (mei_start(dev)) {
dev_err(&pdev->dev, "init hw failure.\n");
err = -ENODEV;
@@ -283,11 +283,10 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0;
deregister:
mei_deregister(dev);
release_irq:
mei_cancel_work(dev);
mei_disable_interrupts(dev);
free_irq(pdev->irq, dev);
mei_deregister(dev);
end:
dev_err(&pdev->dev, "initialization failed.\n");
return err;

View File

@@ -87,6 +87,10 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
hw = to_txe_hw(dev);
hw->mem_addr = pcim_iomap_table(pdev);
err = mei_register(dev, &pdev->dev);
if (err)
goto end;
pci_enable_msi(pdev);
/* clear spurious interrupts */
@@ -106,13 +110,9 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err) {
dev_err(&pdev->dev, "mei: request_threaded_irq failure. irq = %d\n",
pdev->irq);
goto end;
goto deregister;
}
err = mei_register(dev, &pdev->dev);
if (err)
goto release_irq;
if (mei_start(dev)) {
dev_err(&pdev->dev, "init hw failure.\n");
err = -ENODEV;
@@ -145,11 +145,10 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0;
deregister:
mei_deregister(dev);
release_irq:
mei_cancel_work(dev);
mei_disable_interrupts(dev);
free_irq(pdev->irq, dev);
mei_deregister(dev);
end:
dev_err(&pdev->dev, "initialization failed.\n");
return err;

View File

@@ -362,28 +362,27 @@ static int mei_vsc_probe(struct platform_device *pdev)
ret = mei_register(mei_dev, dev);
if (ret)
goto err_dereg;
goto err;
ret = mei_start(mei_dev);
if (ret) {
dev_err_probe(dev, ret, "init hw failed\n");
goto err_cancel;
goto err;
}
pm_runtime_enable(mei_dev->parent);
return 0;
err_dereg:
mei_deregister(mei_dev);
err_cancel:
err:
mei_cancel_work(mei_dev);
vsc_tp_register_event_cb(tp, NULL, NULL);
mei_disable_interrupts(mei_dev);
mei_deregister(mei_dev);
return ret;
}

View File

@@ -1058,7 +1058,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
ret = most_register_interface(&mdev->iface);
if (ret)
goto err_free_busy_urbs;
return ret;
mutex_lock(&mdev->io_mutex);
if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81118 ||
@@ -1068,8 +1068,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
if (!mdev->dci) {
mutex_unlock(&mdev->io_mutex);
most_deregister_interface(&mdev->iface);
ret = -ENOMEM;
goto err_free_busy_urbs;
return -ENOMEM;
}
mdev->dci->dev.init_name = "dci";
@@ -1078,18 +1077,15 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
mdev->dci->dev.release = release_dci;
if (device_register(&mdev->dci->dev)) {
mutex_unlock(&mdev->io_mutex);
put_device(&mdev->dci->dev);
most_deregister_interface(&mdev->iface);
ret = -ENOMEM;
goto err_free_dci;
return -ENOMEM;
}
mdev->dci->usb_device = mdev->usb_device;
}
mutex_unlock(&mdev->io_mutex);
return 0;
err_free_dci:
put_device(&mdev->dci->dev);
err_free_busy_urbs:
kfree(mdev->busy_urbs);
err_free_ep_address:
kfree(mdev->ep_address);
err_free_cap:

View File

@@ -51,7 +51,7 @@ static int nvmem_layout_bus_uevent(const struct device *dev,
int ret;
ret = of_device_uevent_modalias(dev, env);
if (ret != ENODEV)
if (ret != -ENODEV)
return ret;
return 0;

View File

@@ -1241,6 +1241,7 @@ static void qcom_slim_ngd_notify_slaves(struct qcom_slim_ngd_ctrl *ctrl)
if (slim_get_logical_addr(sbdev))
dev_err(ctrl->dev, "Failed to get logical address\n");
put_device(&sbdev->dev);
}
}

View File

@@ -174,5 +174,6 @@ int iio_dma_buffer_enqueue_dmabuf(struct iio_buffer *buffer,
size_t size, bool cyclic);
void iio_dma_buffer_lock_queue(struct iio_buffer *buffer);
void iio_dma_buffer_unlock_queue(struct iio_buffer *buffer);
struct device *iio_dma_buffer_get_dma_dev(struct iio_buffer *buffer);
#endif

View File

@@ -50,6 +50,7 @@ struct sg_table;
* @enqueue_dmabuf: called from userspace via ioctl to queue this DMABUF
* object to this buffer. Requires a valid DMABUF fd, that
* was previouly attached to this buffer.
* @get_dma_dev: called to get the DMA channel associated with this buffer.
* @lock_queue: called when the core needs to lock the buffer queue;
* it is used when enqueueing DMABUF objects.
* @unlock_queue: used to unlock a previously locked buffer queue
@@ -90,6 +91,7 @@ struct iio_buffer_access_funcs {
struct iio_dma_buffer_block *block,
struct dma_fence *fence, struct sg_table *sgt,
size_t size, bool cyclic);
struct device * (*get_dma_dev)(struct iio_buffer *buffer);
void (*lock_queue)(struct iio_buffer *buffer);
void (*unlock_queue)(struct iio_buffer *buffer);