Char/Misc/IIO fixes for 7.1-rc6

Here are some small char/misc/iio driver fixes for 7.1-rc6.  Included in
 here are:
   - lots of small IIO driver fixes for reported problems.
   - Android binder bugfixes for reported issues.
   - small comedi test driver fixes
   - counter driver fix
   - parport driver fix (people still use this?)
   - rpi driver fix
   - uio driver fix
 
 All of these have been in linux-next for over a week with no reported
 problems.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCahrJeQ8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ykKIwCfelyNaZgO2yRfSS1fGmzSv3+W8+sAoK5QHkEY
 TvJIOm1Cwi8/n3vI42Hz
 =EB+S
 -----END PGP SIGNATURE-----

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

Pull char/misc/iio fixes from Greg KH:
 "Here are some small char/misc/iio driver fixes for 7.1-rc6. Included
  in here are:

   - lots of small IIO driver fixes for reported problems.

   - Android binder bugfixes for reported issues.

   - small comedi test driver fixes

   - counter driver fix

   - parport driver fix (people still use this?)

   - rpi driver fix

   - uio driver fix

  All of these have been in linux-next for over a week with no reported
  problems"

* tag 'char-misc-7.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (41 commits)
  Revert "gpib: cb7210: Fix region leak when request_irq fails"
  misc: rp1: Send IACK on IRQ activate to fix kdump/kexec
  gpib: cb7210: Fix region leak when request_irq fails
  parport: Fix race between port and client registration
  uio: uio_pci_generic_sva: fix double free of devm_kzalloc() memory
  rust_binder: Avoid holding lock when dropping delivered_death
  rust_binder: avoid calling pending_oneway_finished() on TF_UPDATE_TXN
  comedi: comedi_test: fix check for valid scan_begin_src in waveform_ai_cmdtest()
  comedi: comedi_test: Fix limiting of convert_arg in waveform_ai_cmdtest()
  iio: adc: viperboard: Fix error handling in vprbrd_iio_read_raw
  iio: gyro: itg3200: fix i2c read into the wrong stack location
  iio: dac: ad5686: fix powerdown control on dual-channel devices
  iio: dac: ad5686: acquire lock when doing powerdown control
  iio: temperature: tsys01: fix broken PROM checksum validation
  iio: dac: ad3530r: Fix AD3531/AD3531R powerdown mode strings
  iio: buffer: hw-consumer: fix use-after-free in error path
  iio: dac: ad5686: fix input raw value check
  iio: dac: ad5686: fix ref bit initialization for single-channel parts
  iio: ssp_sensors: cancel delayed work_refresh on remove
  iio: adc: meson-saradc: fix calibration buffer leak on error
  ...
This commit is contained in:
Linus Torvalds 2026-05-30 08:30:12 -07:00
commit 2544785177
36 changed files with 235 additions and 109 deletions

View File

@ -157,6 +157,14 @@ pub(crate) fn set_info_target_node(&mut self, target_node: NodeRef) {
self.get_or_init_info().target_node = Some(target_node);
}
pub(crate) fn take_oneway_node(&mut self) -> Option<DArc<Node>> {
if let Some(info) = self.allocation_info.as_mut() {
info.oneway_node.take()
} else {
None
}
}
/// Reserve enough space to push at least `num_fds` fds.
pub(crate) fn info_add_fd_reserve(&mut self, num_fds: usize) -> Result {
self.get_or_init_info()

View File

@ -1402,7 +1402,12 @@ fn deferred_release(self: Arc<Self>) {
// Clear delivered_deaths list.
//
// Scope ensures that MutexGuard is dropped while executing the body.
while let Some(delivered_death) = { self.inner.lock().delivered_deaths.pop_front() } {
while let Some(delivered_death) = {
// Explicitly bind to avoid tail expression lifetime extension of the lockguard
// Can be removed when the kernel moves to edition 2024
let maybe_death = self.inner.lock().delivered_deaths.pop_front();
maybe_death
} {
drop(delivered_death);
}

View File

@ -270,7 +270,8 @@ fn drop_outstanding_txn(&self) {
/// Not used for replies.
pub(crate) fn submit(self: DLArc<Self>, info: &mut TransactionInfo) -> BinderResult {
// Defined before `process_inner` so that the destructor runs after releasing the lock.
let mut _t_outdated;
let _t_outdated;
let _oneway_node;
let oneway = self.flags & TF_ONE_WAY != 0;
let process = self.to.clone();
@ -287,6 +288,14 @@ pub(crate) fn submit(self: DLArc<Self>, info: &mut TransactionInfo) -> BinderRes
if let Some(t_outdated) =
target_node.take_outdated_transaction(&self, &mut process_inner)
{
let mut alloc_guard = t_outdated.allocation.lock();
if let Some(alloc) = (*alloc_guard).as_mut() {
// Take the oneway node to prevent `Allocation::drop` from calling
// `pending_oneway_finished()`, which would be incorrect as this
// transaction is not being submitted.
_oneway_node = alloc.take_oneway_node();
}
drop(alloc_guard);
// Save the transaction to be dropped after locks are released.
_t_outdated = t_outdated;
}

View File

@ -274,6 +274,7 @@ static int waveform_ai_cmdtest(struct comedi_device *dev,
/* Step 2a : make sure trigger sources are unique */
err |= comedi_check_trigger_is_unique(cmd->convert_src);
err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
err |= comedi_check_trigger_is_unique(cmd->stop_src);
/* Step 2b : and mutually compatible */
@ -324,10 +325,10 @@ static int waveform_ai_cmdtest(struct comedi_device *dev,
arg = min(arg,
rounddown(UINT_MAX, (unsigned int)NSEC_PER_USEC));
arg = NSEC_PER_USEC * DIV_ROUND_CLOSEST(arg, NSEC_PER_USEC);
if (cmd->scan_begin_arg == TRIG_TIMER) {
if (cmd->scan_begin_src == TRIG_TIMER) {
/* limit convert_arg to keep scan_begin_arg in range */
limit = UINT_MAX / cmd->scan_end_arg;
limit = rounddown(limit, (unsigned int)NSEC_PER_SEC);
limit = rounddown(limit, (unsigned int)NSEC_PER_USEC);
arg = min(arg, limit);
}
err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);

View File

@ -124,7 +124,8 @@ struct counter_device *counter_alloc(size_t sizeof_priv)
err_dev_set_name:
counter_chrdev_remove(counter);
put_device(dev);
return NULL;
err_chrdev_add:
ida_free(&counter_ida, dev->id);

View File

@ -876,14 +876,14 @@ static int ad4695_offload_buffer_postenable(struct iio_dev *indio_dev)
if (ret)
goto err_unoptimize_message;
ret = spi_offload_trigger_enable(st->offload, st->offload_trigger,
&config);
ret = ad4695_enter_advanced_sequencer_mode(st, num_slots);
if (ret)
goto err_disable_busy_output;
ret = ad4695_enter_advanced_sequencer_mode(st, num_slots);
ret = spi_offload_trigger_enable(st->offload, st->offload_trigger,
&config);
if (ret)
goto err_offload_trigger_disable;
goto err_exit_conversion_mode;
mutex_lock(&st->cnv_pwm_lock);
pwm_get_state(st->cnv_pwm, &state);
@ -895,23 +895,16 @@ static int ad4695_offload_buffer_postenable(struct iio_dev *indio_dev)
ret = pwm_apply_might_sleep(st->cnv_pwm, &state);
mutex_unlock(&st->cnv_pwm_lock);
if (ret)
goto err_offload_exit_conversion_mode;
goto err_offload_trigger_disable;
return 0;
err_offload_exit_conversion_mode:
/*
* We have to unwind in a different order to avoid triggering offload.
* ad4695_exit_conversion_mode() triggers a conversion, so it has to be
* done after spi_offload_trigger_disable().
*/
spi_offload_trigger_disable(st->offload, st->offload_trigger);
ad4695_exit_conversion_mode(st);
goto err_disable_busy_output;
err_offload_trigger_disable:
spi_offload_trigger_disable(st->offload, st->offload_trigger);
err_exit_conversion_mode:
ad4695_exit_conversion_mode(st);
err_disable_busy_output:
regmap_clear_bits(st->regmap, AD4695_REG_GP_MODE,
AD4695_REG_GP_MODE_BUSY_GP_EN);

View File

@ -817,9 +817,11 @@ static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev)
}
priv->tsc_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "amlogic,hhi-sysctrl");
if (IS_ERR(priv->tsc_regmap))
if (IS_ERR(priv->tsc_regmap)) {
kfree(buf);
return dev_err_probe(dev, PTR_ERR(priv->tsc_regmap),
"failed to get amlogic,hhi-sysctrl regmap\n");
}
trimming_bits = priv->param->temperature_trimming_bits;
trimming_mask = BIT(trimming_bits) - 1;

View File

@ -497,6 +497,7 @@ static int mt6358_read_imp(struct mt6359_auxadc *adc_dev,
return ret;
/* Read the params before stopping */
val_v = 0;
regmap_read(regmap, reg_adc0 + (cinfo->imp_adc_num << 1), &val_v);
mt6358_stop_imp_conv(adc_dev);

View File

@ -231,7 +231,7 @@ static int npcm_adc_probe(struct platform_device *pdev)
if (IS_ERR(info->reset))
return PTR_ERR(info->reset);
info->adc_clk = devm_clk_get(&pdev->dev, NULL);
info->adc_clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(info->adc_clk)) {
dev_warn(&pdev->dev, "ADC clock failed: can't read clk\n");
return PTR_ERR(info->adc_clk);
@ -244,17 +244,13 @@ static int npcm_adc_probe(struct platform_device *pdev)
info->adc_sample_hz = clk_get_rate(info->adc_clk) / ((div + 1) * 2);
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
ret = irq;
goto err_disable_clk;
}
if (irq < 0)
return irq;
ret = devm_request_irq(&pdev->dev, irq, npcm_adc_isr, 0,
"NPCM_ADC", indio_dev);
if (ret < 0) {
dev_err(dev, "failed requesting interrupt\n");
goto err_disable_clk;
}
if (ret < 0)
return ret;
reg_con = ioread32(info->regs + NPCM_ADCCON);
info->vref = devm_regulator_get_optional(&pdev->dev, "vref");
@ -262,7 +258,7 @@ static int npcm_adc_probe(struct platform_device *pdev)
ret = regulator_enable(info->vref);
if (ret) {
dev_err(&pdev->dev, "Can't enable ADC reference voltage\n");
goto err_disable_clk;
return ret;
}
iowrite32(reg_con & ~NPCM_ADCCON_REFSEL,
@ -272,10 +268,8 @@ static int npcm_adc_probe(struct platform_device *pdev)
* Any error which is not ENODEV indicates the regulator
* has been specified and so is a failure case.
*/
if (PTR_ERR(info->vref) != -ENODEV) {
ret = PTR_ERR(info->vref);
goto err_disable_clk;
}
if (PTR_ERR(info->vref) != -ENODEV)
return PTR_ERR(info->vref);
/* Use internal reference */
iowrite32(reg_con | NPCM_ADCCON_REFSEL,
@ -314,8 +308,6 @@ static int npcm_adc_probe(struct platform_device *pdev)
iowrite32(reg_con & ~NPCM_ADCCON_ADC_EN, info->regs + NPCM_ADCCON);
if (!IS_ERR(info->vref))
regulator_disable(info->vref);
err_disable_clk:
clk_disable_unprepare(info->adc_clk);
return ret;
}
@ -332,7 +324,6 @@ static void npcm_adc_remove(struct platform_device *pdev)
iowrite32(regtemp & ~NPCM_ADCCON_ADC_EN, info->regs + NPCM_ADCCON);
if (!IS_ERR(info->vref))
regulator_disable(info->vref);
clk_disable_unprepare(info->adc_clk);
}
static struct platform_driver npcm_adc_driver = {

View File

@ -198,6 +198,15 @@ static void nxp_sar_adc_irq_cfg(struct nxp_sar_adc *info, bool enable)
writel(0, NXP_SAR_ADC_IMR(info->regs));
}
static void nxp_sar_adc_wait_for(struct nxp_sar_adc *info, unsigned int cycles)
{
u64 rate;
rate = clk_get_rate(info->clk);
if (rate)
ndelay(div64_u64(NSEC_PER_SEC, rate * cycles));
}
static bool nxp_sar_adc_set_enabled(struct nxp_sar_adc *info, bool enable)
{
u32 mcr;
@ -221,7 +230,7 @@ static bool nxp_sar_adc_set_enabled(struct nxp_sar_adc *info, bool enable)
* configuration of NCMR and the setting of NSTART.
*/
if (enable)
ndelay(div64_u64(NSEC_PER_SEC, clk_get_rate(info->clk) * 3));
nxp_sar_adc_wait_for(info, 3);
return pwdn;
}
@ -469,7 +478,7 @@ static void nxp_sar_adc_stop_conversion(struct nxp_sar_adc *info)
* only when the capture finishes. The delay will be very
* short, usec-ish, which is acceptable in the atomic context.
*/
ndelay(div64_u64(NSEC_PER_SEC, clk_get_rate(info->clk)) * 80);
nxp_sar_adc_wait_for(info, 80);
}
static int nxp_sar_adc_start_conversion(struct nxp_sar_adc *info, bool raw)
@ -560,6 +569,9 @@ static int nxp_sar_adc_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec
switch (mask) {
case IIO_CHAN_INFO_SAMP_FREQ:
if (val <= 0)
return -EINVAL;
/*
* Configures the sample period duration in terms of the SAR
* controller clock. The minimum acceptable value is 8.
@ -568,7 +580,11 @@ static int nxp_sar_adc_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec
* sampling timing which gives us the number of cycles expected.
* The value is 8-bit wide, consequently the max value is 0xFF.
*/
inpsamp = clk_get_rate(info->clk) / val - NXP_SAR_ADC_CONV_TIME;
inpsamp = clk_get_rate(info->clk) / val;
if (inpsamp < NXP_SAR_ADC_CONV_TIME)
return -EINVAL;
inpsamp -= NXP_SAR_ADC_CONV_TIME;
nxp_sar_adc_conversion_timing_set(info, inpsamp);
return 0;
@ -660,7 +676,7 @@ static void nxp_sar_adc_dma_cb(void *data)
static int nxp_sar_adc_start_cyclic_dma(struct iio_dev *indio_dev)
{
struct nxp_sar_adc *info = iio_priv(indio_dev);
struct dma_slave_config config;
struct dma_slave_config config = { };
struct dma_async_tx_descriptor *desc;
int ret;

View File

@ -482,7 +482,7 @@ static int adc5_gen3_get_fw_channel_data(struct adc5_chip *adc,
sid = FIELD_GET(ADC5_GEN3_VIRTUAL_SID_MASK, chan);
chan = FIELD_GET(ADC5_GEN3_CHANNEL_MASK, chan);
if (chan > ADC5_MAX_CHANNEL)
if (chan >= ADC5_MAX_CHANNEL)
return dev_err_probe(dev, -EINVAL,
"%s invalid channel number %d\n",
name, chan);

View File

@ -70,8 +70,10 @@ static int vprbrd_iio_read_raw(struct iio_dev *iio_dev,
VPRBRD_USB_TYPE_OUT, 0x0000, 0x0000, admsg,
sizeof(struct vprbrd_adc_msg), VPRBRD_USB_TIMEOUT_MS);
if (ret != sizeof(struct vprbrd_adc_msg)) {
dev_err(&iio_dev->dev, "usb send error on adc read\n");
mutex_unlock(&vb->lock);
error = -EREMOTEIO;
dev_err(&iio_dev->dev, "usb send error on adc read\n");
goto error;
}
ret = usb_control_msg(vb->usb_dev,

View File

@ -817,6 +817,7 @@ static int xadc_postdisable(struct iio_dev *indio_dev)
{
struct xadc *xadc = iio_priv(indio_dev);
unsigned long scan_mask;
int seq_mode;
int ret;
int i;
@ -824,6 +825,12 @@ static int xadc_postdisable(struct iio_dev *indio_dev)
for (i = 0; i < indio_dev->num_channels; i++)
scan_mask |= BIT(indio_dev->channels[i].scan_index);
/*
* Use the correct sequencer mode for the idle state: simultaneous
* mode for dual external mux configurations, continuous otherwise.
*/
seq_mode = xadc_get_seq_mode(xadc, scan_mask);
/* Enable all channels and calibration */
ret = xadc_write_adc_reg(xadc, XADC_REG_SEQ(0), scan_mask & 0xffff);
if (ret)
@ -834,11 +841,11 @@ static int xadc_postdisable(struct iio_dev *indio_dev)
return ret;
ret = xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF1_SEQ_MASK,
XADC_CONF1_SEQ_CONTINUOUS);
seq_mode);
if (ret)
return ret;
return xadc_power_adc_b(xadc, XADC_CONF1_SEQ_CONTINUOUS);
return xadc_power_adc_b(xadc, seq_mode);
}
static int xadc_preenable(struct iio_dev *indio_dev)

View File

@ -85,7 +85,7 @@ static struct hw_consumer_buffer *iio_hw_consumer_get_buffer(
*/
struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev)
{
struct hw_consumer_buffer *buf;
struct hw_consumer_buffer *buf, *tmp;
struct iio_hw_consumer *hwc;
struct iio_channel *chan;
int ret;
@ -116,7 +116,7 @@ struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev)
return hwc;
err_put_buffers:
list_for_each_entry(buf, &hwc->buffers, head)
list_for_each_entry_safe(buf, tmp, &hwc->buffers, head)
iio_buffer_put(&buf->buffer);
iio_channel_release_all(hwc->channels);
err_free_hwc:

View File

@ -52,6 +52,8 @@ struct mhz19b_state {
struct completion buf_ready;
u8 buf_idx;
bool buf_overflow;
/*
* Serdev receive buffer.
* When data is received from the MH-Z19B,
@ -106,6 +108,10 @@ static int mhz19b_serdev_cmd(struct iio_dev *indio_dev, int cmd, u16 arg)
cmd_buf[8] = mhz19b_get_checksum(cmd_buf);
/* Write buf to uart ctrl synchronously */
st->buf_idx = 0;
st->buf_overflow = false;
reinit_completion(&st->buf_ready);
ret = serdev_device_write(serdev, cmd_buf, MHZ19B_CMD_SIZE, 0);
if (ret < 0)
return ret;
@ -121,6 +127,9 @@ static int mhz19b_serdev_cmd(struct iio_dev *indio_dev, int cmd, u16 arg)
if (!ret)
return -ETIMEDOUT;
if (st->buf_overflow)
return -EMSGSIZE;
if (st->buf[8] != mhz19b_get_checksum(st->buf)) {
dev_err(dev, "checksum err");
return -EINVAL;
@ -240,6 +249,14 @@ static size_t mhz19b_receive_buf(struct serdev_device *serdev,
{
struct iio_dev *indio_dev = dev_get_drvdata(&serdev->dev);
struct mhz19b_state *st = iio_priv(indio_dev);
size_t remaining = MHZ19B_CMD_SIZE - st->buf_idx;
if (len > remaining) {
st->buf_idx = 0;
st->buf_overflow = true;
complete(&st->buf_ready);
return len;
}
memcpy(st->buf + st->buf_idx, data, len);
st->buf_idx += len;

View File

@ -256,7 +256,7 @@ static int scd30_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const
guard(mutex)(&state->lock);
switch (mask) {
case IIO_CHAN_INFO_SAMP_FREQ:
if (val)
if (val || !val2)
return -EINVAL;
val = 1000000000 / val2;

View File

@ -590,6 +590,7 @@ static void ssp_remove(struct spi_device *spi)
ssp_clean_pending_list(data);
free_irq(data->spi->irq, data);
cancel_delayed_work_sync(&data->work_refresh);
timer_delete_sync(&data->wdt_timer);
cancel_work_sync(&data->work_wdt);

View File

@ -105,6 +105,12 @@ static const char * const ad3530r_powerdown_modes[] = {
"32kohm_to_gnd",
};
static const char * const ad3531r_powerdown_modes[] = {
"500ohm_to_gnd",
"3.85kohm_to_gnd",
"16kohm_to_gnd",
};
static int ad3530r_get_powerdown_mode(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan)
{
@ -133,6 +139,13 @@ static const struct iio_enum ad3530r_powerdown_mode_enum = {
.set = ad3530r_set_powerdown_mode,
};
static const struct iio_enum ad3531r_powerdown_mode_enum = {
.items = ad3531r_powerdown_modes,
.num_items = ARRAY_SIZE(ad3531r_powerdown_modes),
.get = ad3530r_get_powerdown_mode,
.set = ad3530r_set_powerdown_mode,
};
static ssize_t ad3530r_get_dac_powerdown(struct iio_dev *indio_dev,
uintptr_t private,
const struct iio_chan_spec *chan,
@ -276,7 +289,20 @@ static const struct iio_chan_spec_ext_info ad3530r_ext_info[] = {
{ }
};
#define AD3530R_CHAN(_chan) \
static const struct iio_chan_spec_ext_info ad3531r_ext_info[] = {
{
.name = "powerdown",
.shared = IIO_SEPARATE,
.read = ad3530r_get_dac_powerdown,
.write = ad3530r_set_dac_powerdown,
},
IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad3531r_powerdown_mode_enum),
IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE,
&ad3531r_powerdown_mode_enum),
{ }
};
#define AD3530R_CHAN(_chan, _ext_info) \
{ \
.type = IIO_VOLTAGE, \
.indexed = 1, \
@ -284,25 +310,25 @@ static const struct iio_chan_spec_ext_info ad3530r_ext_info[] = {
.output = 1, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE), \
.ext_info = ad3530r_ext_info, \
.ext_info = _ext_info, \
}
static const struct iio_chan_spec ad3530r_channels[] = {
AD3530R_CHAN(0),
AD3530R_CHAN(1),
AD3530R_CHAN(2),
AD3530R_CHAN(3),
AD3530R_CHAN(4),
AD3530R_CHAN(5),
AD3530R_CHAN(6),
AD3530R_CHAN(7),
AD3530R_CHAN(0, ad3530r_ext_info),
AD3530R_CHAN(1, ad3530r_ext_info),
AD3530R_CHAN(2, ad3530r_ext_info),
AD3530R_CHAN(3, ad3530r_ext_info),
AD3530R_CHAN(4, ad3530r_ext_info),
AD3530R_CHAN(5, ad3530r_ext_info),
AD3530R_CHAN(6, ad3530r_ext_info),
AD3530R_CHAN(7, ad3530r_ext_info),
};
static const struct iio_chan_spec ad3531r_channels[] = {
AD3530R_CHAN(0),
AD3530R_CHAN(1),
AD3530R_CHAN(2),
AD3530R_CHAN(3),
AD3530R_CHAN(0, ad3531r_ext_info),
AD3530R_CHAN(1, ad3531r_ext_info),
AD3530R_CHAN(2, ad3531r_ext_info),
AD3530R_CHAN(3, ad3531r_ext_info),
};
static const struct ad3530r_chip_info ad3530_chip = {

View File

@ -25,22 +25,37 @@ static const char * const ad5686_powerdown_modes[] = {
"three_state"
};
static inline unsigned int ad5686_pd_mask_shift(const struct iio_chan_spec *chan)
{
if (chan->channel == chan->address)
return chan->channel * 2;
/* one-hot encoding is used in dual/quad channel devices */
return __ffs(chan->address) * 2;
}
static int ad5686_get_powerdown_mode(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan)
{
unsigned int shift = ad5686_pd_mask_shift(chan);
struct ad5686_state *st = iio_priv(indio_dev);
return ((st->pwr_down_mode >> (chan->channel * 2)) & 0x3) - 1;
guard(mutex)(&st->lock);
return ((st->pwr_down_mode >> shift) & 0x3U) - 1;
}
static int ad5686_set_powerdown_mode(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
unsigned int mode)
{
unsigned int shift = ad5686_pd_mask_shift(chan);
struct ad5686_state *st = iio_priv(indio_dev);
st->pwr_down_mode &= ~(0x3 << (chan->channel * 2));
st->pwr_down_mode |= ((mode + 1) << (chan->channel * 2));
guard(mutex)(&st->lock);
st->pwr_down_mode &= ~(0x3U << shift);
st->pwr_down_mode |= (mode + 1) << shift;
return 0;
}
@ -55,10 +70,12 @@ static const struct iio_enum ad5686_powerdown_mode_enum = {
static ssize_t ad5686_read_dac_powerdown(struct iio_dev *indio_dev,
uintptr_t private, const struct iio_chan_spec *chan, char *buf)
{
unsigned int shift = ad5686_pd_mask_shift(chan);
struct ad5686_state *st = iio_priv(indio_dev);
return sysfs_emit(buf, "%d\n", !!(st->pwr_down_mask &
(0x3 << (chan->channel * 2))));
guard(mutex)(&st->lock);
return sysfs_emit(buf, "%d\n", !!(st->pwr_down_mask & (0x3U << shift)));
}
static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
@ -77,10 +94,12 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
if (ret)
return ret;
guard(mutex)(&st->lock);
if (readin)
st->pwr_down_mask |= (0x3 << (chan->channel * 2));
st->pwr_down_mask |= 0x3U << ad5686_pd_mask_shift(chan);
else
st->pwr_down_mask &= ~(0x3 << (chan->channel * 2));
st->pwr_down_mask &= ~(0x3U << ad5686_pd_mask_shift(chan));
switch (st->chip_info->regmap_type) {
case AD5310_REGMAP:
@ -154,7 +173,7 @@ static int ad5686_write_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
if (val > (1 << chan->scan_type.realbits) || val < 0)
if (val >= (1 << chan->scan_type.realbits) || val < 0)
return -EINVAL;
mutex_lock(&st->lock);
@ -460,7 +479,7 @@ int ad5686_probe(struct device *dev,
{
struct ad5686_state *st;
struct iio_dev *indio_dev;
unsigned int val, ref_bit_msk;
unsigned int val, ref_bit_msk, shift;
bool has_external_vref;
u8 cmd;
int ret, i;
@ -484,9 +503,18 @@ int ad5686_probe(struct device *dev,
has_external_vref = ret != -ENODEV;
st->vref_mv = has_external_vref ? ret / 1000 : st->chip_info->int_vref_mv;
/* Initialize masks to all ones provided the max shift (last channel) */
shift = ad5686_pd_mask_shift(&st->chip_info->channels[st->chip_info->num_channels - 1]);
st->pwr_down_mask = GENMASK(shift + 1, 0);
st->pwr_down_mode = GENMASK(shift + 1, 0);
/* Set all the power down mode for all channels to 1K pulldown */
for (i = 0; i < st->chip_info->num_channels; i++)
st->pwr_down_mode |= (0x01 << (i * 2));
for (i = 0; i < st->chip_info->num_channels; i++) {
shift = ad5686_pd_mask_shift(&st->chip_info->channels[i]);
st->pwr_down_mask &= ~(0x3U << shift); /* powered up state */
st->pwr_down_mode &= ~(0x3U << shift);
st->pwr_down_mode |= 0x01U << shift;
}
indio_dev->name = name;
indio_dev->info = &ad5686_info;
@ -509,7 +537,7 @@ int ad5686_probe(struct device *dev,
break;
case AD5686_REGMAP:
cmd = AD5686_CMD_INTERNAL_REFER_SETUP;
ref_bit_msk = 0;
ref_bit_msk = AD5686_REF_BIT_MSK;
break;
case AD5693_REGMAP:
cmd = AD5686_CMD_CONTROL_REG;
@ -520,9 +548,9 @@ int ad5686_probe(struct device *dev,
return -EINVAL;
}
val = (has_external_vref | ref_bit_msk);
val = has_external_vref ? ref_bit_msk : 0;
ret = st->write(st, cmd, 0, !!val);
ret = st->write(st, cmd, 0, val);
if (ret)
return ret;

View File

@ -46,6 +46,7 @@
#define AD5310_REF_BIT_MSK BIT(8)
#define AD5683_REF_BIT_MSK BIT(12)
#define AD5686_REF_BIT_MSK BIT(0)
#define AD5693_REF_BIT_MSK BIT(12)
/**

View File

@ -90,6 +90,7 @@ static int max5821_sync_powerdown_mode(struct max5821_data *data,
const struct iio_chan_spec *chan)
{
u8 outbuf[2];
int ret;
outbuf[0] = MAX5821_EXTENDED_COMMAND_MODE;
@ -103,7 +104,13 @@ static int max5821_sync_powerdown_mode(struct max5821_data *data,
else
outbuf[1] |= MAX5821_EXTENDED_POWER_UP;
return i2c_master_send(data->client, outbuf, 2);
ret = i2c_master_send(data->client, outbuf, sizeof(outbuf));
if (ret < 0)
return ret;
if (ret != sizeof(outbuf))
return -EIO;
return 0;
}
static ssize_t max5821_write_dac_powerdown(struct iio_dev *indio_dev,

View File

@ -287,6 +287,9 @@ static int adis16260_write_raw(struct iio_dev *indio_dev,
addr = adis16260_addresses[chan->scan_index][1];
return adis_write_reg_16(adis, addr, val);
case IIO_CHAN_INFO_SAMP_FREQ:
if (val <= 0)
return -EINVAL;
if (spi_get_device_id(adis->spi)->driver_data)
t = 256 / val;
else

View File

@ -34,7 +34,7 @@ static int itg3200_read_all_channels(struct i2c_client *i2c, __be16 *buf)
.addr = i2c->addr,
.flags = i2c->flags | I2C_M_RD,
.len = ITG3200_SCAN_ELEMENTS * sizeof(s16),
.buf = (char *)&buf,
.buf = (char *)buf,
},
};

View File

@ -836,7 +836,7 @@ static irqreturn_t adis16550_trigger_handler(int irq, void *p)
u16 dummy;
bool valid;
struct iio_poll_func *pf = p;
__be32 data[ADIS16550_MAX_SCAN_DATA] __aligned(8);
__be32 data[ADIS16550_MAX_SCAN_DATA] __aligned(8) = { };
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16550 *st = iio_priv(indio_dev);
struct adis *adis = iio_device_get_drvdata(indio_dev);

View File

@ -609,7 +609,7 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)
* must be passed a buffer that is aligned to 8 bytes so
* as to allow insertion of a naturally aligned timestamp.
*/
u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE] __aligned(8);
u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE] __aligned(8) = { };
u8 tag;
bool reset_ts = false;
int i, err, read_len;

View File

@ -1909,6 +1909,7 @@ static int iio_buffer_enqueue_dmabuf(struct iio_dev_buffer_pair *ib,
dma_resv_add_fence(dmabuf->resv, &fence->base,
dma_to_ram ? DMA_RESV_USAGE_WRITE : DMA_RESV_USAGE_READ);
dma_fence_put(&fence->base);
dma_resv_unlock(dmabuf->resv);
cookie = dma_fence_begin_signalling();

View File

@ -738,7 +738,11 @@ int iio_read_channel_processed_scale(struct iio_channel *chan, int *val,
if (ret < 0)
return ret;
return iio_multiply_value(val, scale, ret, pval, pval2);
ret = iio_multiply_value(val, scale, ret, pval, pval2);
if (ret < 0)
return ret;
return 0;
} else {
ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
if (ret < 0)

View File

@ -89,15 +89,14 @@ static int cm3323_init(struct iio_dev *indio_dev)
/* enable sensor and set auto force mode */
ret &= ~(CM3323_CONF_SD_BIT | CM3323_CONF_AF_BIT);
data->reg_conf = ret;
ret = i2c_smbus_write_word_data(data->client, CM3323_CMD_CONF, ret);
ret = i2c_smbus_write_word_data(data->client, CM3323_CMD_CONF, data->reg_conf);
if (ret < 0) {
dev_err(&data->client->dev, "Error writing reg_conf\n");
return ret;
}
data->reg_conf = ret;
return 0;
}

View File

@ -245,13 +245,6 @@ static const struct iio_info veml6070_info = {
.write_raw = veml6070_write_raw,
};
static void veml6070_i2c_unreg(void *p)
{
struct veml6070_data *data = p;
i2c_unregister_device(data->client2);
}
static int veml6070_probe(struct i2c_client *client)
{
struct veml6070_data *data;
@ -281,7 +274,8 @@ static int veml6070_probe(struct i2c_client *client)
if (ret < 0)
return ret;
data->client2 = i2c_new_dummy_device(client->adapter, VEML6070_ADDR_DATA_LSB);
data->client2 = devm_i2c_new_dummy_device(&client->dev, client->adapter,
VEML6070_ADDR_DATA_LSB);
if (IS_ERR(data->client2))
return dev_err_probe(&client->dev, PTR_ERR(data->client2),
"i2c device for second chip address failed\n");
@ -292,10 +286,6 @@ static int veml6070_probe(struct i2c_client *client)
if (ret < 0)
return ret;
ret = devm_add_action_or_reset(&client->dev, veml6070_i2c_unreg, data);
if (ret < 0)
return ret;
return devm_iio_device_register(&client->dev, indio_dev);
}

View File

@ -506,6 +506,11 @@ static const struct st_sensors_platform_data default_magn_pdata = {
.drdy_int_pin = 2,
};
/* LIS2MDL only supports DRDY on INT1 */
static const struct st_sensors_platform_data alt_magn_pdata = {
.drdy_int_pin = 1,
};
static int st_magn_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *ch, int *val,
int *val2, long mask)
@ -628,8 +633,12 @@ int st_magn_common_probe(struct iio_dev *indio_dev)
mdata->current_fullscale = &mdata->sensor_settings->fs.fs_avl[0];
mdata->odr = mdata->sensor_settings->odr.odr_avl[0].hz;
if (!pdata)
pdata = (struct st_sensors_platform_data *)&default_magn_pdata;
if (!pdata) {
if (mdata->sensor_settings->drdy_irq.int2.mask)
pdata = (struct st_sensors_platform_data *)&default_magn_pdata;
else
pdata = (struct st_sensors_platform_data *)&alt_magn_pdata;
}
err = st_sensors_init_sensor(indio_dev, pdata);
if (err < 0)

View File

@ -2616,7 +2616,7 @@ static irqreturn_t bmp580_trigger_handler(int irq, void *p)
__le32 comp_temp;
__le32 comp_press;
aligned_s64 timestamp;
} buffer;
} buffer = { };
int ret;
guard(mutex)(&data->lock);

View File

@ -119,7 +119,7 @@ static bool tsys01_crc_valid(u16 *n_prom)
u8 sum = 0;
for (cnt = 0; cnt < TSYS01_PROM_WORDS_NB; cnt++)
sum += ((n_prom[0] >> 8) + (n_prom[0] & 0xFF));
sum += ((n_prom[cnt] >> 8) + (n_prom[cnt] & 0xFF));
return (sum == 0);
}

View File

@ -143,6 +143,7 @@ static int rp1_irq_activate(struct irq_domain *d, struct irq_data *irqd,
struct rp1_dev *rp1 = d->host_data;
msix_cfg_set(rp1, (unsigned int)irqd->hwirq, MSIX_CFG_ENABLE);
msix_cfg_set(rp1, (unsigned int)irqd->hwirq, MSIX_CFG_IACK);
return 0;
}

View File

@ -214,10 +214,14 @@ static void get_lowlevel_driver(void)
static int port_check(struct device *dev, void *dev_drv)
{
struct parport_driver *drv = dev_drv;
struct parport *port;
/* only send ports, do not send other devices connected to bus */
if (is_parport(dev))
drv->match_port(to_parport_dev(dev));
if (is_parport(dev)) {
port = to_parport_dev(dev);
if (test_bit(PARPORT_ANNOUNCED, &port->devflags))
drv->match_port(port);
}
return 0;
}
@ -532,6 +536,7 @@ void parport_announce_port(struct parport *port)
if (slave)
attach_driver_chain(slave);
}
set_bit(PARPORT_ANNOUNCED, &port->devflags);
mutex_unlock(&registration_lock);
}
EXPORT_SYMBOL(parport_announce_port);
@ -561,6 +566,8 @@ void parport_remove_port(struct parport *port)
mutex_lock(&registration_lock);
clear_bit(PARPORT_ANNOUNCED, &port->devflags);
/* Spread the word. */
detach_driver_chain(port);

View File

@ -129,15 +129,13 @@ static int probe(struct pci_dev *pdev, const struct pci_device_id *id)
ret = devm_uio_register_device(&pdev->dev, &udev->info);
if (ret) {
dev_err(&pdev->dev, "Failed to register uio device\n");
goto out_free;
goto out_disable;
}
pci_set_drvdata(pdev, udev);
return 0;
out_free:
kfree(udev);
out_disable:
pci_disable_device(pdev);
@ -146,11 +144,8 @@ static int probe(struct pci_dev *pdev, const struct pci_device_id *id)
static void remove(struct pci_dev *pdev)
{
struct uio_pci_sva_dev *udev = pci_get_drvdata(pdev);
pci_release_regions(pdev);
pci_disable_device(pdev);
kfree(udev);
}
static ssize_t pasid_show(struct device *dev,

View File

@ -240,6 +240,7 @@ struct parport {
unsigned long devflags;
#define PARPORT_DEVPROC_REGISTERED 0
#define PARPORT_ANNOUNCED 1
struct pardevice *proc_device; /* Currently register proc device */
struct list_head full_list;