2
0
mirror of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2025-09-04 20:19:47 +08:00

Char/Misc/IIO fixes for 6.16-rc7

Here are some char/misc/iio and other driver fixes for 6.16-rc7.
 Included in here are:
   - IIO driver fixes for reported problems
   - Interconnect driver fixes for reported problems
   - nvmem driver fixes
   - bunch of comedi driver fixes for long-term bugs
   - Kconfig dependancy fixes for mux drivers
   - other small driver fixes for reported problems.
 
 All of these have been in linux-next for a while with no reported
 problems.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCaHzF6Q8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ym+fACfeLnxF0znIjZqK3G56KF11jN89ugAnjUN8Hs2
 yK6Meq35ID98D6nuazES
 =NQ9W
 -----END PGP SIGNATURE-----

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

Pull char / misc / IIO fixes from Greg KH:
 "Here are some char/misc/iio and other driver fixes for 6.16-rc7.
  Included in here are:

   - IIO driver fixes for reported problems

   - Interconnect driver fixes for reported problems

   - nvmem driver fixes

   - bunch of comedi driver fixes for long-term bugs

   - Kconfig dependancy fixes for mux drivers

   - other small driver fixes for reported problems.

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

* tag 'char-misc-6.16-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (35 commits)
  nvmem: layouts: u-boot-env: remove crc32 endianness conversion
  misc: amd-sbi: Explicitly clear in/out arg "mb_in_out"
  misc: amd-sbi: Address copy_to/from_user() warning reported in smatch
  misc: amd-sbi: Address potential integer overflow issue reported in smatch
  comedi: comedi_test: Fix possible deletion of uninitialized timers
  comedi: Fix initialization of data for instructions that write to subdevice
  comedi: Fix use of uninitialized data in insn_rw_emulate_bits()
  comedi: das6402: Fix bit shift out of bounds
  comedi: aio_iiro_16: Fix bit shift out of bounds
  comedi: pcl812: Fix bit shift out of bounds
  comedi: das16m1: Fix bit shift out of bounds
  comedi: Fix some signed shift left operations
  comedi: Fail COMEDI_INSNLIST ioctl if n_insns is too large
  nvmem: imx-ocotp: fix MAC address byte length
  MAINTAINERS: add miscdevice Rust abstractions
  mux: mmio: Fix missing CONFIG_REGMAP_MMIO
  iio: dac: ad3530r: Fix incorrect masking for channels 4-7 in powerdown mode
  iio: adc: ad7380: fix adi,gain-milli property parsing
  iio: adc: ad7949: use spi_is_bpw_supported()
  iio: accel: fxls8962af: Fix use after free in fxls8962af_fifo_flush
  ...
This commit is contained in:
Linus Torvalds 2025-07-20 09:03:41 -07:00
commit ecf11d31bf
35 changed files with 213 additions and 112 deletions

View File

@ -223,12 +223,6 @@ allOf:
- required:
- pwms
- oneOf:
- required:
- interrupts
- required:
- io-backends
- if:
properties:
compatible:

View File

@ -21,7 +21,7 @@ properties:
vlogic-supply: true
interrupts:
minItems: 1
maxItems: 1
description:
Interrupt mapping for the trigger interrupt from the internal oscillator.

View File

@ -5570,6 +5570,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
F: drivers/char/
F: drivers/misc/
F: include/linux/miscdevice.h
F: rust/kernel/miscdevice.rs
F: samples/rust/rust_misc_device.rs
X: drivers/char/agp/
X: drivers/char/hw_random/

View File

@ -1556,21 +1556,27 @@ static int do_insnlist_ioctl(struct comedi_device *dev,
}
for (i = 0; i < n_insns; ++i) {
unsigned int n = insns[i].n;
if (insns[i].insn & INSN_MASK_WRITE) {
if (copy_from_user(data, insns[i].data,
insns[i].n * sizeof(unsigned int))) {
n * sizeof(unsigned int))) {
dev_dbg(dev->class_dev,
"copy_from_user failed\n");
ret = -EFAULT;
goto error;
}
if (n < MIN_SAMPLES) {
memset(&data[n], 0, (MIN_SAMPLES - n) *
sizeof(unsigned int));
}
}
ret = parse_insn(dev, insns + i, data, file);
if (ret < 0)
goto error;
if (insns[i].insn & INSN_MASK_READ) {
if (copy_to_user(insns[i].data, data,
insns[i].n * sizeof(unsigned int))) {
n * sizeof(unsigned int))) {
dev_dbg(dev->class_dev,
"copy_to_user failed\n");
ret = -EFAULT;
@ -1589,6 +1595,16 @@ error:
return i;
}
#define MAX_INSNS MAX_SAMPLES
static int check_insnlist_len(struct comedi_device *dev, unsigned int n_insns)
{
if (n_insns > MAX_INSNS) {
dev_dbg(dev->class_dev, "insnlist length too large\n");
return -EINVAL;
}
return 0;
}
/*
* COMEDI_INSN ioctl
* synchronous instruction
@ -1633,6 +1649,10 @@ static int do_insn_ioctl(struct comedi_device *dev,
ret = -EFAULT;
goto error;
}
if (insn->n < MIN_SAMPLES) {
memset(&data[insn->n], 0,
(MIN_SAMPLES - insn->n) * sizeof(unsigned int));
}
}
ret = parse_insn(dev, insn, data, file);
if (ret < 0)
@ -2239,6 +2259,9 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
rc = -EFAULT;
break;
}
rc = check_insnlist_len(dev, insnlist.n_insns);
if (rc)
break;
insns = kcalloc(insnlist.n_insns, sizeof(*insns), GFP_KERNEL);
if (!insns) {
rc = -ENOMEM;
@ -3142,6 +3165,9 @@ static int compat_insnlist(struct file *file, unsigned long arg)
if (copy_from_user(&insnlist32, compat_ptr(arg), sizeof(insnlist32)))
return -EFAULT;
rc = check_insnlist_len(dev, insnlist32.n_insns);
if (rc)
return rc;
insns = kcalloc(insnlist32.n_insns, sizeof(*insns), GFP_KERNEL);
if (!insns)
return -ENOMEM;

View File

@ -339,10 +339,10 @@ int comedi_dio_insn_config(struct comedi_device *dev,
unsigned int *data,
unsigned int mask)
{
unsigned int chan_mask = 1 << CR_CHAN(insn->chanspec);
unsigned int chan = CR_CHAN(insn->chanspec);
if (!mask)
mask = chan_mask;
if (!mask && chan < 32)
mask = 1U << chan;
switch (data[0]) {
case INSN_CONFIG_DIO_INPUT:
@ -382,7 +382,7 @@ EXPORT_SYMBOL_GPL(comedi_dio_insn_config);
unsigned int comedi_dio_update_state(struct comedi_subdevice *s,
unsigned int *data)
{
unsigned int chanmask = (s->n_chan < 32) ? ((1 << s->n_chan) - 1)
unsigned int chanmask = (s->n_chan < 32) ? ((1U << s->n_chan) - 1)
: 0xffffffff;
unsigned int mask = data[0] & chanmask;
unsigned int bits = data[1];
@ -615,6 +615,9 @@ static int insn_rw_emulate_bits(struct comedi_device *dev,
unsigned int _data[2];
int ret;
if (insn->n == 0)
return 0;
memset(_data, 0, sizeof(_data));
memset(&_insn, 0, sizeof(_insn));
_insn.insn = INSN_BITS;
@ -625,8 +628,8 @@ static int insn_rw_emulate_bits(struct comedi_device *dev,
if (insn->insn == INSN_WRITE) {
if (!(s->subdev_flags & SDF_WRITABLE))
return -EINVAL;
_data[0] = 1 << (chan - base_chan); /* mask */
_data[1] = data[0] ? (1 << (chan - base_chan)) : 0; /* bits */
_data[0] = 1U << (chan - base_chan); /* mask */
_data[1] = data[0] ? (1U << (chan - base_chan)) : 0; /* bits */
}
ret = s->insn_bits(dev, s, &_insn, _data);
@ -709,7 +712,7 @@ static int __comedi_device_postconfig(struct comedi_device *dev)
if (s->type == COMEDI_SUBD_DO) {
if (s->n_chan < 32)
s->io_bits = (1 << s->n_chan) - 1;
s->io_bits = (1U << s->n_chan) - 1;
else
s->io_bits = 0xffffffff;
}

View File

@ -177,7 +177,8 @@ static int aio_iiro_16_attach(struct comedi_device *dev,
* Digital input change of state interrupts are optionally supported
* using IRQ 2-7, 10-12, 14, or 15.
*/
if ((1 << it->options[1]) & 0xdcfc) {
if (it->options[1] > 0 && it->options[1] < 16 &&
(1 << it->options[1]) & 0xdcfc) {
ret = request_irq(it->options[1], aio_iiro_16_cos, 0,
dev->board_name, dev);
if (ret == 0)

View File

@ -792,7 +792,7 @@ static void waveform_detach(struct comedi_device *dev)
{
struct waveform_private *devpriv = dev->private;
if (devpriv) {
if (devpriv && dev->n_subdevices) {
timer_delete_sync(&devpriv->ai_timer);
timer_delete_sync(&devpriv->ao_timer);
}

View File

@ -522,7 +522,8 @@ static int das16m1_attach(struct comedi_device *dev,
devpriv->extra_iobase = dev->iobase + DAS16M1_8255_IOBASE;
/* only irqs 2, 3, 4, 5, 6, 7, 10, 11, 12, 14, and 15 are valid */
if ((1 << it->options[1]) & 0xdcfc) {
if (it->options[1] >= 2 && it->options[1] <= 15 &&
(1 << it->options[1]) & 0xdcfc) {
ret = request_irq(it->options[1], das16m1_interrupt, 0,
dev->board_name, dev);
if (ret == 0)

View File

@ -567,7 +567,8 @@ static int das6402_attach(struct comedi_device *dev,
das6402_reset(dev);
/* IRQs 2,3,5,6,7, 10,11,15 are valid for "enhanced" mode */
if ((1 << it->options[1]) & 0x8cec) {
if (it->options[1] > 0 && it->options[1] < 16 &&
(1 << it->options[1]) & 0x8cec) {
ret = request_irq(it->options[1], das6402_interrupt, 0,
dev->board_name, dev);
if (ret == 0) {

View File

@ -1149,7 +1149,8 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
if ((1 << it->options[1]) & board->irq_bits) {
if (it->options[1] > 0 && it->options[1] < 16 &&
(1 << it->options[1]) & board->irq_bits) {
ret = request_irq(it->options[1], pcl812_interrupt, 0,
dev->board_name, dev);
if (ret == 0)

View File

@ -877,6 +877,8 @@ static int fxls8962af_buffer_predisable(struct iio_dev *indio_dev)
if (ret)
return ret;
synchronize_irq(data->irq);
ret = __fxls8962af_fifo_set_mode(data, false);
if (data->enable_event)

View File

@ -1353,6 +1353,7 @@ static int apply_acpi_orientation(struct iio_dev *indio_dev)
union acpi_object *ont;
union acpi_object *elements;
acpi_status status;
struct device *parent = indio_dev->dev.parent;
int ret = -EINVAL;
unsigned int val;
int i, j;
@ -1371,7 +1372,7 @@ static int apply_acpi_orientation(struct iio_dev *indio_dev)
};
adev = ACPI_COMPANION(indio_dev->dev.parent);
adev = ACPI_COMPANION(parent);
if (!adev)
return -ENXIO;
@ -1380,8 +1381,7 @@ static int apply_acpi_orientation(struct iio_dev *indio_dev)
if (status == AE_NOT_FOUND) {
return -ENXIO;
} else if (ACPI_FAILURE(status)) {
dev_warn(&indio_dev->dev, "failed to execute _ONT: %d\n",
status);
dev_warn(parent, "failed to execute _ONT: %d\n", status);
return status;
}
@ -1457,12 +1457,12 @@ static int apply_acpi_orientation(struct iio_dev *indio_dev)
}
ret = 0;
dev_info(&indio_dev->dev, "computed mount matrix from ACPI\n");
dev_info(parent, "computed mount matrix from ACPI\n");
out:
kfree(buffer.pointer);
if (ret)
dev_dbg(&indio_dev->dev,
dev_dbg(parent,
"failed to apply ACPI orientation data: %d\n", ret);
return ret;

View File

@ -1953,8 +1953,9 @@ static int ad7380_probe(struct spi_device *spi)
if (st->chip_info->has_hardware_gain) {
device_for_each_child_node_scoped(dev, node) {
unsigned int channel, gain;
unsigned int channel;
int gain_idx;
u16 gain;
ret = fwnode_property_read_u32(node, "reg", &channel);
if (ret)
@ -1966,7 +1967,7 @@ static int ad7380_probe(struct spi_device *spi)
"Invalid channel number %i\n",
channel);
ret = fwnode_property_read_u32(node, "adi,gain-milli",
ret = fwnode_property_read_u16(node, "adi,gain-milli",
&gain);
if (ret && ret != -EINVAL)
return dev_err_probe(dev, ret,

View File

@ -308,7 +308,6 @@ static void ad7949_disable_reg(void *reg)
static int ad7949_spi_probe(struct spi_device *spi)
{
u32 spi_ctrl_mask = spi->controller->bits_per_word_mask;
struct device *dev = &spi->dev;
const struct ad7949_adc_spec *spec;
struct ad7949_adc_chip *ad7949_adc;
@ -337,11 +336,11 @@ static int ad7949_spi_probe(struct spi_device *spi)
ad7949_adc->resolution = spec->resolution;
/* Set SPI bits per word */
if (spi_ctrl_mask & SPI_BPW_MASK(ad7949_adc->resolution)) {
if (spi_is_bpw_supported(spi, ad7949_adc->resolution)) {
spi->bits_per_word = ad7949_adc->resolution;
} else if (spi_ctrl_mask == SPI_BPW_MASK(16)) {
} else if (spi_is_bpw_supported(spi, 16)) {
spi->bits_per_word = 16;
} else if (spi_ctrl_mask == SPI_BPW_MASK(8)) {
} else if (spi_is_bpw_supported(spi, 8)) {
spi->bits_per_word = 8;
} else {
dev_err(dev, "unable to find common BPW with spi controller\n");

View File

@ -445,7 +445,7 @@ static int axi_adc_raw_read(struct iio_backend *back, u32 *val)
static int ad7606_bus_reg_read(struct iio_backend *back, u32 reg, u32 *val)
{
struct adi_axi_adc_state *st = iio_backend_get_priv(back);
int addr;
u32 addr, reg_val;
guard(mutex)(&st->lock);
@ -455,7 +455,9 @@ static int ad7606_bus_reg_read(struct iio_backend *back, u32 reg, u32 *val)
*/
addr = FIELD_PREP(ADI_AXI_REG_ADDRESS_MASK, reg) | ADI_AXI_REG_READ_BIT;
axi_adc_raw_write(back, addr);
axi_adc_raw_read(back, val);
axi_adc_raw_read(back, &reg_val);
*val = FIELD_GET(ADI_AXI_REG_VALUE_MASK, reg_val);
/* Write 0x0 on the bus to get back to ADC mode */
axi_adc_raw_write(back, 0);

View File

@ -187,6 +187,7 @@ static struct iio_map axp717_maps[] = {
.consumer_channel = "batt_chrg_i",
.adc_channel_label = "batt_chrg_i",
},
{ }
};
/*

View File

@ -511,10 +511,10 @@ static const struct iio_event_spec max1363_events[] = {
MAX1363_CHAN_U(1, _s1, 1, bits, ev_spec, num_ev_spec), \
MAX1363_CHAN_U(2, _s2, 2, bits, ev_spec, num_ev_spec), \
MAX1363_CHAN_U(3, _s3, 3, bits, ev_spec, num_ev_spec), \
MAX1363_CHAN_B(0, 1, d0m1, 4, bits, ev_spec, num_ev_spec), \
MAX1363_CHAN_B(2, 3, d2m3, 5, bits, ev_spec, num_ev_spec), \
MAX1363_CHAN_B(1, 0, d1m0, 6, bits, ev_spec, num_ev_spec), \
MAX1363_CHAN_B(3, 2, d3m2, 7, bits, ev_spec, num_ev_spec), \
MAX1363_CHAN_B(0, 1, d0m1, 12, bits, ev_spec, num_ev_spec), \
MAX1363_CHAN_B(2, 3, d2m3, 13, bits, ev_spec, num_ev_spec), \
MAX1363_CHAN_B(1, 0, d1m0, 18, bits, ev_spec, num_ev_spec), \
MAX1363_CHAN_B(3, 2, d3m2, 19, bits, ev_spec, num_ev_spec), \
IIO_CHAN_SOFT_TIMESTAMP(8) \
}
@ -532,23 +532,23 @@ static const struct iio_chan_spec max1363_channels[] =
/* Applies to max1236, max1237 */
static const enum max1363_modes max1236_mode_list[] = {
_s0, _s1, _s2, _s3,
s0to1, s0to2, s0to3,
s0to1, s0to2, s2to3, s0to3,
d0m1, d2m3, d1m0, d3m2,
d0m1to2m3, d1m0to3m2,
s2to3,
};
/* Applies to max1238, max1239 */
static const enum max1363_modes max1238_mode_list[] = {
_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11,
s0to1, s0to2, s0to3, s0to4, s0to5, s0to6,
s6to7, s6to8, s6to9, s6to10, s6to11,
s0to7, s0to8, s0to9, s0to10, s0to11,
d0m1, d2m3, d4m5, d6m7, d8m9, d10m11,
d1m0, d3m2, d5m4, d7m6, d9m8, d11m10,
d0m1to2m3, d0m1to4m5, d0m1to6m7, d0m1to8m9, d0m1to10m11,
d1m0to3m2, d1m0to5m4, d1m0to7m6, d1m0to9m8, d1m0to11m10,
s6to7, s6to8, s6to9, s6to10, s6to11,
d6m7to8m9, d6m7to10m11, d7m6to9m8, d7m6to11m10,
d0m1to2m3, d0m1to4m5, d0m1to6m7, d6m7to8m9,
d0m1to8m9, d6m7to10m11, d0m1to10m11, d1m0to3m2,
d1m0to5m4, d1m0to7m6, d7m6to9m8, d1m0to9m8,
d7m6to11m10, d1m0to11m10,
};
#define MAX1363_12X_CHANS(bits) { \
@ -584,16 +584,15 @@ static const struct iio_chan_spec max1238_channels[] = MAX1363_12X_CHANS(12);
static const enum max1363_modes max11607_mode_list[] = {
_s0, _s1, _s2, _s3,
s0to1, s0to2, s0to3,
s2to3,
s0to1, s0to2, s2to3,
s0to3,
d0m1, d2m3, d1m0, d3m2,
d0m1to2m3, d1m0to3m2,
};
static const enum max1363_modes max11608_mode_list[] = {
_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7,
s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, s0to7,
s6to7,
s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, s6to7, s0to7,
d0m1, d2m3, d4m5, d6m7,
d1m0, d3m2, d5m4, d7m6,
d0m1to2m3, d0m1to4m5, d0m1to6m7,
@ -609,14 +608,14 @@ static const enum max1363_modes max11608_mode_list[] = {
MAX1363_CHAN_U(5, _s5, 5, bits, NULL, 0), \
MAX1363_CHAN_U(6, _s6, 6, bits, NULL, 0), \
MAX1363_CHAN_U(7, _s7, 7, bits, NULL, 0), \
MAX1363_CHAN_B(0, 1, d0m1, 8, bits, NULL, 0), \
MAX1363_CHAN_B(2, 3, d2m3, 9, bits, NULL, 0), \
MAX1363_CHAN_B(4, 5, d4m5, 10, bits, NULL, 0), \
MAX1363_CHAN_B(6, 7, d6m7, 11, bits, NULL, 0), \
MAX1363_CHAN_B(1, 0, d1m0, 12, bits, NULL, 0), \
MAX1363_CHAN_B(3, 2, d3m2, 13, bits, NULL, 0), \
MAX1363_CHAN_B(5, 4, d5m4, 14, bits, NULL, 0), \
MAX1363_CHAN_B(7, 6, d7m6, 15, bits, NULL, 0), \
MAX1363_CHAN_B(0, 1, d0m1, 12, bits, NULL, 0), \
MAX1363_CHAN_B(2, 3, d2m3, 13, bits, NULL, 0), \
MAX1363_CHAN_B(4, 5, d4m5, 14, bits, NULL, 0), \
MAX1363_CHAN_B(6, 7, d6m7, 15, bits, NULL, 0), \
MAX1363_CHAN_B(1, 0, d1m0, 18, bits, NULL, 0), \
MAX1363_CHAN_B(3, 2, d3m2, 19, bits, NULL, 0), \
MAX1363_CHAN_B(5, 4, d5m4, 20, bits, NULL, 0), \
MAX1363_CHAN_B(7, 6, d7m6, 21, bits, NULL, 0), \
IIO_CHAN_SOFT_TIMESTAMP(16) \
}
static const struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8);

View File

@ -430,10 +430,9 @@ static int stm32_adc_irq_probe(struct platform_device *pdev,
return -ENOMEM;
}
for (i = 0; i < priv->cfg->num_irqs; i++) {
irq_set_chained_handler(priv->irq[i], stm32_adc_irq_handler);
irq_set_handler_data(priv->irq[i], priv);
}
for (i = 0; i < priv->cfg->num_irqs; i++)
irq_set_chained_handler_and_data(priv->irq[i],
stm32_adc_irq_handler, priv);
return 0;
}

View File

@ -154,7 +154,7 @@ static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs)
return err;
st_accel_set_fullscale_error:
dev_err(&indio_dev->dev, "failed to set new fullscale.\n");
dev_err(indio_dev->dev.parent, "failed to set new fullscale.\n");
return err;
}
@ -231,8 +231,7 @@ int st_sensors_power_enable(struct iio_dev *indio_dev)
ARRAY_SIZE(regulator_names),
regulator_names);
if (err)
return dev_err_probe(&indio_dev->dev, err,
"unable to enable supplies\n");
return dev_err_probe(parent, err, "unable to enable supplies\n");
return 0;
}
@ -241,13 +240,14 @@ EXPORT_SYMBOL_NS(st_sensors_power_enable, "IIO_ST_SENSORS");
static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev,
struct st_sensors_platform_data *pdata)
{
struct device *parent = indio_dev->dev.parent;
struct st_sensor_data *sdata = iio_priv(indio_dev);
/* Sensor does not support interrupts */
if (!sdata->sensor_settings->drdy_irq.int1.addr &&
!sdata->sensor_settings->drdy_irq.int2.addr) {
if (pdata->drdy_int_pin)
dev_info(&indio_dev->dev,
dev_info(parent,
"DRDY on pin INT%d specified, but sensor does not support interrupts\n",
pdata->drdy_int_pin);
return 0;
@ -256,29 +256,27 @@ static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev,
switch (pdata->drdy_int_pin) {
case 1:
if (!sdata->sensor_settings->drdy_irq.int1.mask) {
dev_err(&indio_dev->dev,
"DRDY on INT1 not available.\n");
dev_err(parent, "DRDY on INT1 not available.\n");
return -EINVAL;
}
sdata->drdy_int_pin = 1;
break;
case 2:
if (!sdata->sensor_settings->drdy_irq.int2.mask) {
dev_err(&indio_dev->dev,
"DRDY on INT2 not available.\n");
dev_err(parent, "DRDY on INT2 not available.\n");
return -EINVAL;
}
sdata->drdy_int_pin = 2;
break;
default:
dev_err(&indio_dev->dev, "DRDY on pdata not valid.\n");
dev_err(parent, "DRDY on pdata not valid.\n");
return -EINVAL;
}
if (pdata->open_drain) {
if (!sdata->sensor_settings->drdy_irq.int1.addr_od &&
!sdata->sensor_settings->drdy_irq.int2.addr_od)
dev_err(&indio_dev->dev,
dev_err(parent,
"open drain requested but unsupported.\n");
else
sdata->int_pin_open_drain = true;
@ -336,6 +334,7 @@ EXPORT_SYMBOL_NS(st_sensors_dev_name_probe, "IIO_ST_SENSORS");
int st_sensors_init_sensor(struct iio_dev *indio_dev,
struct st_sensors_platform_data *pdata)
{
struct device *parent = indio_dev->dev.parent;
struct st_sensor_data *sdata = iio_priv(indio_dev);
struct st_sensors_platform_data *of_pdata;
int err = 0;
@ -343,7 +342,7 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev,
mutex_init(&sdata->odr_lock);
/* If OF/DT pdata exists, it will take precedence of anything else */
of_pdata = st_sensors_dev_probe(indio_dev->dev.parent, pdata);
of_pdata = st_sensors_dev_probe(parent, pdata);
if (IS_ERR(of_pdata))
return PTR_ERR(of_pdata);
if (of_pdata)
@ -370,7 +369,7 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev,
if (err < 0)
return err;
} else
dev_info(&indio_dev->dev, "Full-scale not possible\n");
dev_info(parent, "Full-scale not possible\n");
err = st_sensors_set_odr(indio_dev, sdata->odr);
if (err < 0)
@ -405,7 +404,7 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev,
mask = sdata->sensor_settings->drdy_irq.int2.mask_od;
}
dev_info(&indio_dev->dev,
dev_info(parent,
"set interrupt line to open drain mode on pin %d\n",
sdata->drdy_int_pin);
err = st_sensors_write_data_with_mask(indio_dev, addr,
@ -593,21 +592,20 @@ EXPORT_SYMBOL_NS(st_sensors_get_settings_index, "IIO_ST_SENSORS");
int st_sensors_verify_id(struct iio_dev *indio_dev)
{
struct st_sensor_data *sdata = iio_priv(indio_dev);
struct device *parent = indio_dev->dev.parent;
int wai, err;
if (sdata->sensor_settings->wai_addr) {
err = regmap_read(sdata->regmap,
sdata->sensor_settings->wai_addr, &wai);
if (err < 0) {
dev_err(&indio_dev->dev,
"failed to read Who-Am-I register.\n");
return err;
return dev_err_probe(parent, err,
"failed to read Who-Am-I register.\n");
}
if (sdata->sensor_settings->wai != wai) {
dev_warn(&indio_dev->dev,
"%s: WhoAmI mismatch (0x%x).\n",
indio_dev->name, wai);
dev_warn(parent, "%s: WhoAmI mismatch (0x%x).\n",
indio_dev->name, wai);
}
}

View File

@ -127,7 +127,7 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
sdata->trig = devm_iio_trigger_alloc(parent, "%s-trigger",
indio_dev->name);
if (sdata->trig == NULL) {
dev_err(&indio_dev->dev, "failed to allocate iio trigger.\n");
dev_err(parent, "failed to allocate iio trigger.\n");
return -ENOMEM;
}
@ -143,7 +143,7 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
case IRQF_TRIGGER_FALLING:
case IRQF_TRIGGER_LOW:
if (!sdata->sensor_settings->drdy_irq.addr_ihl) {
dev_err(&indio_dev->dev,
dev_err(parent,
"falling/low specified for IRQ but hardware supports only rising/high: will request rising/high\n");
if (irq_trig == IRQF_TRIGGER_FALLING)
irq_trig = IRQF_TRIGGER_RISING;
@ -156,21 +156,19 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
sdata->sensor_settings->drdy_irq.mask_ihl, 1);
if (err < 0)
return err;
dev_info(&indio_dev->dev,
dev_info(parent,
"interrupts on the falling edge or active low level\n");
}
break;
case IRQF_TRIGGER_RISING:
dev_info(&indio_dev->dev,
"interrupts on the rising edge\n");
dev_info(parent, "interrupts on the rising edge\n");
break;
case IRQF_TRIGGER_HIGH:
dev_info(&indio_dev->dev,
"interrupts active high level\n");
dev_info(parent, "interrupts active high level\n");
break;
default:
/* This is the most preferred mode, if possible */
dev_err(&indio_dev->dev,
dev_err(parent,
"unsupported IRQ trigger specified (%lx), enforce rising edge\n", irq_trig);
irq_trig = IRQF_TRIGGER_RISING;
}
@ -179,7 +177,7 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
if (irq_trig == IRQF_TRIGGER_FALLING ||
irq_trig == IRQF_TRIGGER_RISING) {
if (!sdata->sensor_settings->drdy_irq.stat_drdy.addr) {
dev_err(&indio_dev->dev,
dev_err(parent,
"edge IRQ not supported w/o stat register.\n");
return -EOPNOTSUPP;
}
@ -214,13 +212,13 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
sdata->trig->name,
sdata->trig);
if (err) {
dev_err(&indio_dev->dev, "failed to request trigger IRQ.\n");
dev_err(parent, "failed to request trigger IRQ.\n");
return err;
}
err = devm_iio_trigger_register(parent, sdata->trig);
if (err < 0) {
dev_err(&indio_dev->dev, "failed to register iio trigger.\n");
dev_err(parent, "failed to register iio trigger.\n");
return err;
}
indio_dev->trig = iio_trigger_get(sdata->trig);

View File

@ -166,7 +166,9 @@ static ssize_t ad3530r_set_dac_powerdown(struct iio_dev *indio_dev,
AD3530R_OUTPUT_OPERATING_MODE_0 :
AD3530R_OUTPUT_OPERATING_MODE_1;
pdmode = powerdown ? st->chan[chan->channel].powerdown_mode : 0;
mask = AD3530R_OP_MODE_CHAN_MSK(chan->channel);
mask = chan->channel < AD3531R_MAX_CHANNELS ?
AD3530R_OP_MODE_CHAN_MSK(chan->channel) :
AD3530R_OP_MODE_CHAN_MSK(chan->channel - 4);
val = field_prep(mask, pdmode);
ret = regmap_update_bits(st->regmap, reg, mask, val);

View File

@ -155,11 +155,14 @@ static ssize_t iio_backend_debugfs_write_reg(struct file *file,
ssize_t rc;
int ret;
if (count >= sizeof(buf))
return -ENOSPC;
rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, userbuf, count);
if (rc < 0)
return rc;
buf[count] = '\0';
buf[rc] = '\0';
ret = sscanf(buf, "%i %i", &back->cached_reg_addr, &val);

View File

@ -411,12 +411,15 @@ static ssize_t iio_debugfs_write_reg(struct file *file,
char buf[80];
int ret;
if (count >= sizeof(buf))
return -EINVAL;
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, userbuf,
count);
if (ret < 0)
return ret;
buf[count] = '\0';
buf[ret] = '\0';
ret = sscanf(buf, "%i %i", &reg, &val);

View File

@ -20,7 +20,7 @@
#include "internal.h"
#define ICC_DYN_ID_START 10000
#define ICC_DYN_ID_START 100000
#define CREATE_TRACE_POINTS
#include "trace.h"
@ -819,6 +819,9 @@ static struct icc_node *icc_node_create_nolock(int id)
{
struct icc_node *node;
if (id >= ICC_DYN_ID_START)
return ERR_PTR(-EINVAL);
/* check if node already exists */
node = node_find(id);
if (node)
@ -906,10 +909,35 @@ void icc_node_destroy(int id)
return;
kfree(node->links);
if (node->id >= ICC_DYN_ID_START)
kfree(node->name);
kfree(node);
}
EXPORT_SYMBOL_GPL(icc_node_destroy);
/**
* icc_node_set_name() - set node name
* @node: node
* @provider: node provider
* @name: node name
*
* Return: 0 on success, or -ENOMEM on allocation failure
*/
int icc_node_set_name(struct icc_node *node, const struct icc_provider *provider, const char *name)
{
if (node->id >= ICC_DYN_ID_START) {
node->name = kasprintf(GFP_KERNEL, "%s@%s", name,
dev_name(provider->dev));
if (!node->name)
return -ENOMEM;
} else {
node->name = name;
}
return 0;
}
EXPORT_SYMBOL_GPL(icc_node_set_name);
/**
* icc_link_nodes() - create link between two nodes
* @src_node: source node
@ -1038,10 +1066,6 @@ void icc_node_add(struct icc_node *node, struct icc_provider *provider)
node->avg_bw = node->init_avg;
node->peak_bw = node->init_peak;
if (node->id >= ICC_DYN_ID_START)
node->name = devm_kasprintf(provider->dev, GFP_KERNEL, "%s@%s",
node->name, dev_name(provider->dev));
if (node->avg_bw || node->peak_bw) {
if (provider->pre_aggregate)
provider->pre_aggregate(node);

View File

@ -117,6 +117,7 @@ struct icc_provider *icc_clk_register(struct device *dev,
node->name = devm_kasprintf(dev, GFP_KERNEL, "%s_master", data[i].name);
if (!node->name) {
icc_node_destroy(node->id);
ret = -ENOMEM;
goto err;
}
@ -135,6 +136,7 @@ struct icc_provider *icc_clk_register(struct device *dev,
node->name = devm_kasprintf(dev, GFP_KERNEL, "%s_slave", data[i].name);
if (!node->name) {
icc_node_destroy(node->id);
ret = -ENOMEM;
goto err;
}

View File

@ -293,7 +293,12 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev)
goto err_remove_nodes;
}
node->name = qn->name;
ret = icc_node_set_name(node, provider, qn->name);
if (ret) {
icc_node_destroy(node->id);
goto err_remove_nodes;
}
node->data = qn;
icc_node_add(node, provider);

View File

@ -236,7 +236,12 @@ static int qcom_osm_l3_probe(struct platform_device *pdev)
goto err;
}
node->name = qnodes[i]->name;
ret = icc_node_set_name(node, provider, qnodes[i]->name);
if (ret) {
icc_node_destroy(node->id);
goto err;
}
/* Cast away const and add it back in qcom_osm_l3_set() */
node->data = (void *)qnodes[i];
icc_node_add(node, provider);

View File

@ -238,6 +238,7 @@ static struct qcom_icc_node xm_pcie3_1 = {
.id = SC7280_MASTER_PCIE_1,
.channels = 1,
.buswidth = 8,
.num_links = 1,
.links = { SC7280_SLAVE_ANOC_PCIE_GEM_NOC },
};

View File

@ -134,6 +134,11 @@ static int exynos_generic_icc_probe(struct platform_device *pdev)
priv->node = icc_node;
icc_node->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOFn",
bus_dev->of_node);
if (!icc_node->name) {
icc_node_destroy(pdev->id);
return -ENOMEM;
}
if (of_property_read_u32(bus_dev->of_node, "samsung,data-clock-ratio",
&priv->bus_clk_ratio))
priv->bus_clk_ratio = EXYNOS_ICC_DEFAULT_BUS_CLK_RATIO;

View File

@ -42,7 +42,6 @@
#define RD_MCA_CMD 0x86
/* CPUID MCAMSR mask & index */
#define CPUID_MCA_THRD_MASK GENMASK(15, 0)
#define CPUID_MCA_THRD_INDEX 32
#define CPUID_MCA_FUNC_MASK GENMASK(31, 0)
#define CPUID_EXT_FUNC_INDEX 56
@ -129,7 +128,7 @@ static int rmi_cpuid_read(struct sbrmi_data *data,
goto exit_unlock;
}
thread = msg->cpu_in_out << CPUID_MCA_THRD_INDEX & CPUID_MCA_THRD_MASK;
thread = msg->cpu_in_out >> CPUID_MCA_THRD_INDEX;
/* Thread > 127, Thread128 CS register, 1'b1 needs to be set to 1 */
if (thread > 127) {
@ -210,7 +209,7 @@ static int rmi_mca_msr_read(struct sbrmi_data *data,
goto exit_unlock;
}
thread = msg->mcamsr_in_out << CPUID_MCA_THRD_INDEX & CPUID_MCA_THRD_MASK;
thread = msg->mcamsr_in_out >> CPUID_MCA_THRD_INDEX;
/* Thread > 127, Thread128 CS register, 1'b1 needs to be set to 1 */
if (thread > 127) {
@ -321,6 +320,10 @@ int rmi_mailbox_xfer(struct sbrmi_data *data,
ret = regmap_read(data->regmap, SBRMI_OUTBNDMSG7, &ec);
if (ret || ec)
goto exit_clear_alert;
/* Clear the input value before updating the output data */
msg->mb_in_out = 0;
/*
* For a read operation, the initiator (BMC) reads the firmware
* response Command Data Out[31:0] from SBRMI::OutBndMsg_inst[4:1]
@ -373,7 +376,8 @@ static int apml_rmi_reg_xfer(struct sbrmi_data *data,
mutex_unlock(&data->lock);
if (msg.rflag && !ret)
return copy_to_user(arg, &msg, sizeof(struct apml_reg_xfer_msg));
if (copy_to_user(arg, &msg, sizeof(struct apml_reg_xfer_msg)))
return -EFAULT;
return ret;
}
@ -391,7 +395,9 @@ static int apml_mailbox_xfer(struct sbrmi_data *data, struct apml_mbox_msg __use
if (ret && ret != -EPROTOTYPE)
return ret;
return copy_to_user(arg, &msg, sizeof(struct apml_mbox_msg));
if (copy_to_user(arg, &msg, sizeof(struct apml_mbox_msg)))
return -EFAULT;
return ret;
}
static int apml_cpuid_xfer(struct sbrmi_data *data, struct apml_cpuid_msg __user *arg)
@ -408,7 +414,9 @@ static int apml_cpuid_xfer(struct sbrmi_data *data, struct apml_cpuid_msg __user
if (ret && ret != -EPROTOTYPE)
return ret;
return copy_to_user(arg, &msg, sizeof(struct apml_cpuid_msg));
if (copy_to_user(arg, &msg, sizeof(struct apml_cpuid_msg)))
return -EFAULT;
return ret;
}
static int apml_mcamsr_xfer(struct sbrmi_data *data, struct apml_mcamsr_msg __user *arg)
@ -425,7 +433,9 @@ static int apml_mcamsr_xfer(struct sbrmi_data *data, struct apml_mcamsr_msg __us
if (ret && ret != -EPROTOTYPE)
return ret;
return copy_to_user(arg, &msg, sizeof(struct apml_mcamsr_msg));
if (copy_to_user(arg, &msg, sizeof(struct apml_mcamsr_msg)))
return -EFAULT;
return ret;
}
static long sbrmi_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)

View File

@ -48,6 +48,7 @@ config MUX_GPIO
config MUX_MMIO
tristate "MMIO/Regmap register bitfield-controlled Multiplexer"
depends on OF
select REGMAP_MMIO
help
MMIO/Regmap register bitfield-controlled Multiplexer controller.

View File

@ -12,6 +12,7 @@
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/if_ether.h> /* ETH_ALEN */
enum fuse_type {
FUSE_FSB = BIT(0),
@ -118,9 +119,11 @@ static int imx_ocotp_cell_pp(void *context, const char *id, int index,
int i;
/* Deal with some post processing of nvmem cell data */
if (id && !strcmp(id, "mac-address"))
if (id && !strcmp(id, "mac-address")) {
bytes = min(bytes, ETH_ALEN);
for (i = 0; i < bytes / 2; i++)
swap(buf[i], buf[bytes - i - 1]);
}
return 0;
}

View File

@ -23,6 +23,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/if_ether.h> /* ETH_ALEN */
#define IMX_OCOTP_OFFSET_B0W0 0x400 /* Offset from base address of the
* OTP Bank0 Word0
@ -227,9 +228,11 @@ static int imx_ocotp_cell_pp(void *context, const char *id, int index,
int i;
/* Deal with some post processing of nvmem cell data */
if (id && !strcmp(id, "mac-address"))
if (id && !strcmp(id, "mac-address")) {
bytes = min(bytes, ETH_ALEN);
for (i = 0; i < bytes / 2; i++)
swap(buf[i], buf[bytes - i - 1]);
}
return 0;
}

View File

@ -92,7 +92,7 @@ int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem,
size_t crc32_data_offset;
size_t crc32_data_len;
size_t crc32_offset;
__le32 *crc32_addr;
uint32_t *crc32_addr;
size_t data_offset;
size_t data_len;
size_t dev_size;
@ -143,8 +143,8 @@ int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem,
goto err_kfree;
}
crc32_addr = (__le32 *)(buf + crc32_offset);
crc32 = le32_to_cpu(*crc32_addr);
crc32_addr = (uint32_t *)(buf + crc32_offset);
crc32 = *crc32_addr;
crc32_data_len = dev_size - crc32_data_offset;
data_len = dev_size - data_offset;

View File

@ -119,6 +119,7 @@ int icc_std_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
struct icc_node *icc_node_create_dyn(void);
struct icc_node *icc_node_create(int id);
void icc_node_destroy(int id);
int icc_node_set_name(struct icc_node *node, const struct icc_provider *provider, const char *name);
int icc_link_nodes(struct icc_node *src_node, struct icc_node **dst_node);
int icc_link_create(struct icc_node *node, const int dst_id);
void icc_node_add(struct icc_node *node, struct icc_provider *provider);
@ -152,6 +153,12 @@ static inline void icc_node_destroy(int id)
{
}
static inline int icc_node_set_name(struct icc_node *node, const struct icc_provider *provider,
const char *name)
{
return -EOPNOTSUPP;
}
static inline int icc_link_nodes(struct icc_node *src_node, struct icc_node **dst_node)
{
return -EOPNOTSUPP;