mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 03:24:45 +01:00
Char/Misc/IIO driver fixes for 6.19-rc7
Here are some small char/misc/iio and some other minor driver subsystem fixes for 6.19-rc7. Nothing huge here, just some fixes for reported issues including: - lots of little iio driver fixes - comedi driver fixes - mux driver fix - w1 driver fixes - uio driver fix - slimbus driver fixes - hwtracing bugfix - other tiny bugfixes All of these have been in linux-next for a while with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCaXY0dA8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ylkhgCgvwYNIuJosuQRKK0sFTOR1Utig3sAn2g6E2H9 AOZZ43qoosl++HsuXDLP =XzfC -----END PGP SIGNATURE----- Merge tag 'char-misc-6.19-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc Pull char/misc/iio driver fixes from Greg KH: "Here are some small char/misc/iio and some other minor driver subsystem fixes for 6.19-rc7. Nothing huge here, just some fixes for reported issues including: - lots of little iio driver fixes - comedi driver fixes - mux driver fix - w1 driver fixes - uio driver fix - slimbus driver fixes - hwtracing bugfix - other tiny bugfixes All of these have been in linux-next for a while with no reported issues" * tag 'char-misc-6.19-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (36 commits) comedi: dmm32at: serialize use of paged registers mei: trace: treat reg parameter as string uio: pci_sva: correct '-ENODEV' check logic uacce: ensure safe queue release with state management uacce: implement mremap in uacce_vm_ops to return -EPERM uacce: fix isolate sysfs check condition uacce: fix cdev handling in the cleanup path slimbus: core: clean up of_slim_get_device() slimbus: core: fix of_slim_get_device() kernel doc slimbus: core: amend slim_get_device() kernel doc slimbus: core: fix device reference leak on report present slimbus: core: fix runtime PM imbalance on report present slimbus: core: fix OF node leak on registration failure intel_th: rename error label intel_th: fix device leak on output open() comedi: Fix getting range information for subdevices 16 to 255 mux: mmio: Fix IS_ERR() vs NULL check in probe() interconnect: debugfs: initialize src_node and dst_node to empty strings iio: dac: ad3552r-hs: fix out-of-bound write in ad3552r_hs_write_data_source iio: accel: iis328dq: fix gain values ...
This commit is contained in:
commit
0a6dce0a5c
30 changed files with 312 additions and 138 deletions
|
|
@ -74,6 +74,37 @@ allOf:
|
|||
- description: aggre UFS CARD AXI clock
|
||||
- description: RPMH CC IPA clock
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sa8775p-config-noc
|
||||
- qcom,sa8775p-dc-noc
|
||||
- qcom,sa8775p-gem-noc
|
||||
- qcom,sa8775p-gpdsp-anoc
|
||||
- qcom,sa8775p-lpass-ag-noc
|
||||
- qcom,sa8775p-mmss-noc
|
||||
- qcom,sa8775p-nspa-noc
|
||||
- qcom,sa8775p-nspb-noc
|
||||
- qcom,sa8775p-pcie-anoc
|
||||
- qcom,sa8775p-system-noc
|
||||
then:
|
||||
properties:
|
||||
clocks: false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sa8775p-clk-virt
|
||||
- qcom,sa8775p-mc-virt
|
||||
then:
|
||||
properties:
|
||||
reg: false
|
||||
clocks: false
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
|
|
|||
|
|
@ -13172,6 +13172,7 @@ F: Documentation/devicetree/bindings/interconnect/
|
|||
F: Documentation/driver-api/interconnect.rst
|
||||
F: drivers/interconnect/
|
||||
F: include/dt-bindings/interconnect/
|
||||
F: include/linux/interconnect-clk.h
|
||||
F: include/linux/interconnect-provider.h
|
||||
F: include/linux/interconnect.h
|
||||
|
||||
|
|
|
|||
|
|
@ -1155,7 +1155,7 @@ static int do_chaninfo_ioctl(struct comedi_device *dev,
|
|||
for (i = 0; i < s->n_chan; i++) {
|
||||
int x;
|
||||
|
||||
x = (dev->minor << 28) | (it->subdev << 24) | (i << 16) |
|
||||
x = (it->subdev << 24) | (i << 16) |
|
||||
(s->range_table_list[i]->length);
|
||||
if (put_user(x, it->rangelist + i))
|
||||
return -EFAULT;
|
||||
|
|
|
|||
|
|
@ -330,6 +330,7 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev,
|
|||
|
||||
static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec)
|
||||
{
|
||||
unsigned long irq_flags;
|
||||
unsigned char lo1, lo2, hi2;
|
||||
unsigned short both2;
|
||||
|
||||
|
|
@ -342,6 +343,9 @@ static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec)
|
|||
/* set counter clocks to 10MHz, disable all aux dio */
|
||||
outb(0, dev->iobase + DMM32AT_CTRDIO_CFG_REG);
|
||||
|
||||
/* serialize access to control register and paged registers */
|
||||
spin_lock_irqsave(&dev->spinlock, irq_flags);
|
||||
|
||||
/* get access to the clock regs */
|
||||
outb(DMM32AT_CTRL_PAGE_8254, dev->iobase + DMM32AT_CTRL_REG);
|
||||
|
||||
|
|
@ -354,6 +358,8 @@ static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec)
|
|||
outb(lo2, dev->iobase + DMM32AT_CLK2);
|
||||
outb(hi2, dev->iobase + DMM32AT_CLK2);
|
||||
|
||||
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
|
||||
|
||||
/* enable the ai conversion interrupt and the clock to start scans */
|
||||
outb(DMM32AT_INTCLK_ADINT |
|
||||
DMM32AT_INTCLK_CLKEN | DMM32AT_INTCLK_CLKSEL,
|
||||
|
|
@ -363,13 +369,19 @@ static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec)
|
|||
static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
{
|
||||
struct comedi_cmd *cmd = &s->async->cmd;
|
||||
unsigned long irq_flags;
|
||||
int ret;
|
||||
|
||||
dmm32at_ai_set_chanspec(dev, s, cmd->chanlist[0], cmd->chanlist_len);
|
||||
|
||||
/* serialize access to control register and paged registers */
|
||||
spin_lock_irqsave(&dev->spinlock, irq_flags);
|
||||
|
||||
/* reset the interrupt just in case */
|
||||
outb(DMM32AT_CTRL_INTRST, dev->iobase + DMM32AT_CTRL_REG);
|
||||
|
||||
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
|
||||
|
||||
/*
|
||||
* wait for circuit to settle
|
||||
* we don't have the 'insn' here but it's not needed
|
||||
|
|
@ -429,8 +441,13 @@ static irqreturn_t dmm32at_isr(int irq, void *d)
|
|||
comedi_handle_events(dev, s);
|
||||
}
|
||||
|
||||
/* serialize access to control register and paged registers */
|
||||
spin_lock(&dev->spinlock);
|
||||
|
||||
/* reset the interrupt */
|
||||
outb(DMM32AT_CTRL_INTRST, dev->iobase + DMM32AT_CTRL_REG);
|
||||
|
||||
spin_unlock(&dev->spinlock);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
|
@ -481,14 +498,25 @@ static int dmm32at_ao_insn_write(struct comedi_device *dev,
|
|||
static int dmm32at_8255_io(struct comedi_device *dev,
|
||||
int dir, int port, int data, unsigned long regbase)
|
||||
{
|
||||
unsigned long irq_flags;
|
||||
int ret;
|
||||
|
||||
/* serialize access to control register and paged registers */
|
||||
spin_lock_irqsave(&dev->spinlock, irq_flags);
|
||||
|
||||
/* get access to the DIO regs */
|
||||
outb(DMM32AT_CTRL_PAGE_8255, dev->iobase + DMM32AT_CTRL_REG);
|
||||
|
||||
if (dir) {
|
||||
outb(data, dev->iobase + regbase + port);
|
||||
return 0;
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = inb(dev->iobase + regbase + port);
|
||||
}
|
||||
return inb(dev->iobase + regbase + port);
|
||||
|
||||
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Make sure the board is there and put it to a known state */
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ int do_rangeinfo_ioctl(struct comedi_device *dev,
|
|||
const struct comedi_lrange *lr;
|
||||
struct comedi_subdevice *s;
|
||||
|
||||
subd = (it->range_type >> 24) & 0xf;
|
||||
subd = (it->range_type >> 24) & 0xff;
|
||||
chan = (it->range_type >> 16) & 0xff;
|
||||
|
||||
if (!dev->attached)
|
||||
|
|
|
|||
|
|
@ -810,16 +810,19 @@ static int intel_th_output_open(struct inode *inode, struct file *file)
|
|||
int err;
|
||||
|
||||
dev = bus_find_device_by_devt(&intel_th_bus, inode->i_rdev);
|
||||
if (!dev || !dev->driver) {
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
||||
if (!dev->driver) {
|
||||
err = -ENODEV;
|
||||
goto out_no_device;
|
||||
goto err_put_dev;
|
||||
}
|
||||
|
||||
thdrv = to_intel_th_driver(dev->driver);
|
||||
fops = fops_get(thdrv->fops);
|
||||
if (!fops) {
|
||||
err = -ENODEV;
|
||||
goto out_put_device;
|
||||
goto err_put_dev;
|
||||
}
|
||||
|
||||
replace_fops(file, fops);
|
||||
|
|
@ -829,19 +832,29 @@ static int intel_th_output_open(struct inode *inode, struct file *file)
|
|||
if (file->f_op->open) {
|
||||
err = file->f_op->open(inode, file);
|
||||
if (err)
|
||||
goto out_put_device;
|
||||
goto err_put_dev;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_put_device:
|
||||
err_put_dev:
|
||||
put_device(dev);
|
||||
out_no_device:
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int intel_th_output_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct intel_th_device *thdev = file->private_data;
|
||||
|
||||
put_device(&thdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct file_operations intel_th_output_fops = {
|
||||
.open = intel_th_output_open,
|
||||
.release = intel_th_output_release,
|
||||
.llseek = noop_llseek,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1784,9 +1784,9 @@ static int adxl380_config_irq(struct iio_dev *indio_dev)
|
|||
st->int_map[1] = ADXL380_INT0_MAP1_REG;
|
||||
} else {
|
||||
st->irq = fwnode_irq_get_byname(dev_fwnode(st->dev), "INT1");
|
||||
if (st->irq > 0)
|
||||
return dev_err_probe(st->dev, -ENODEV,
|
||||
"no interrupt name specified");
|
||||
if (st->irq < 0)
|
||||
return dev_err_probe(st->dev, st->irq,
|
||||
"no interrupt name specified\n");
|
||||
st->int_map[0] = ADXL380_INT1_MAP0_REG;
|
||||
st->int_map[1] = ADXL380_INT1_MAP1_REG;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -517,7 +517,6 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
|
|||
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
|
||||
.sensors_supported = {
|
||||
[0] = H3LIS331DL_ACCEL_DEV_NAME,
|
||||
[1] = IIS328DQ_ACCEL_DEV_NAME,
|
||||
},
|
||||
.ch = (struct iio_chan_spec *)st_accel_12bit_channels,
|
||||
.odr = {
|
||||
|
|
@ -584,6 +583,77 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
|
|||
.multi_read_bit = true,
|
||||
.bootime = 2,
|
||||
},
|
||||
{
|
||||
.wai = 0x32,
|
||||
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
|
||||
.sensors_supported = {
|
||||
[0] = IIS328DQ_ACCEL_DEV_NAME,
|
||||
},
|
||||
.ch = (struct iio_chan_spec *)st_accel_12bit_channels,
|
||||
.odr = {
|
||||
.addr = 0x20,
|
||||
.mask = 0x18,
|
||||
.odr_avl = {
|
||||
{ .hz = 50, .value = 0x00, },
|
||||
{ .hz = 100, .value = 0x01, },
|
||||
{ .hz = 400, .value = 0x02, },
|
||||
{ .hz = 1000, .value = 0x03, },
|
||||
},
|
||||
},
|
||||
.pw = {
|
||||
.addr = 0x20,
|
||||
.mask = 0x20,
|
||||
.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
|
||||
.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
|
||||
},
|
||||
.enable_axis = {
|
||||
.addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
|
||||
.mask = ST_SENSORS_DEFAULT_AXIS_MASK,
|
||||
},
|
||||
.fs = {
|
||||
.addr = 0x23,
|
||||
.mask = 0x30,
|
||||
.fs_avl = {
|
||||
[0] = {
|
||||
.num = ST_ACCEL_FS_AVL_100G,
|
||||
.value = 0x00,
|
||||
.gain = IIO_G_TO_M_S_2(980),
|
||||
},
|
||||
[1] = {
|
||||
.num = ST_ACCEL_FS_AVL_200G,
|
||||
.value = 0x01,
|
||||
.gain = IIO_G_TO_M_S_2(1950),
|
||||
},
|
||||
[2] = {
|
||||
.num = ST_ACCEL_FS_AVL_400G,
|
||||
.value = 0x03,
|
||||
.gain = IIO_G_TO_M_S_2(3910),
|
||||
},
|
||||
},
|
||||
},
|
||||
.bdu = {
|
||||
.addr = 0x23,
|
||||
.mask = 0x80,
|
||||
},
|
||||
.drdy_irq = {
|
||||
.int1 = {
|
||||
.addr = 0x22,
|
||||
.mask = 0x02,
|
||||
},
|
||||
.int2 = {
|
||||
.addr = 0x22,
|
||||
.mask = 0x10,
|
||||
},
|
||||
.addr_ihl = 0x22,
|
||||
.mask_ihl = 0x80,
|
||||
},
|
||||
.sim = {
|
||||
.addr = 0x23,
|
||||
.value = BIT(0),
|
||||
},
|
||||
.multi_read_bit = true,
|
||||
.bootime = 2,
|
||||
},
|
||||
{
|
||||
/* No WAI register present */
|
||||
.sensors_supported = {
|
||||
|
|
|
|||
|
|
@ -1024,7 +1024,9 @@ static int ad7280_probe(struct spi_device *spi)
|
|||
|
||||
st->spi->max_speed_hz = AD7280A_MAX_SPI_CLK_HZ;
|
||||
st->spi->mode = SPI_MODE_1;
|
||||
spi_setup(st->spi);
|
||||
ret = spi_setup(st->spi);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
st->ctrl_lb = FIELD_PREP(AD7280A_CTRL_LB_ACQ_TIME_MSK, st->acquisition_time) |
|
||||
FIELD_PREP(AD7280A_CTRL_LB_THERMISTOR_MSK, st->thermistor_term_en);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@ static int ad7606_par_bus_setup_iio_backend(struct device *dev,
|
|||
struct iio_dev *indio_dev)
|
||||
{
|
||||
struct ad7606_state *st = iio_priv(indio_dev);
|
||||
unsigned int ret, c;
|
||||
unsigned int c;
|
||||
int ret;
|
||||
struct iio_backend_data_fmt data = {
|
||||
.sign_extend = true,
|
||||
.enable = true,
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@
|
|||
|
||||
#define CHIPID_AD9434 0x6A
|
||||
#define AD9434_DEF_OUTPUT_MODE 0x00
|
||||
#define AD9434_REG_VREF_MASK 0xC0
|
||||
#define AD9434_REG_VREF_MASK GENMASK(4, 0)
|
||||
|
||||
/*
|
||||
* Analog Devices AD9467 16-Bit, 200/250 MSPS ADC
|
||||
|
|
|
|||
|
|
@ -2481,6 +2481,7 @@ static void at91_adc_remove(struct platform_device *pdev)
|
|||
struct at91_adc_state *st = iio_priv(indio_dev);
|
||||
|
||||
iio_device_unregister(indio_dev);
|
||||
cancel_work_sync(&st->touch_st.workq);
|
||||
|
||||
at91_adc_dma_disable(st);
|
||||
|
||||
|
|
|
|||
|
|
@ -540,15 +540,6 @@ static const struct iio_chan_spec exynos_adc_iio_channels[] = {
|
|||
ADC_CHANNEL(9, "adc9"),
|
||||
};
|
||||
|
||||
static int exynos_adc_remove_devices(struct device *dev, void *c)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
|
||||
platform_device_unregister(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int exynos_adc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct exynos_adc *info = NULL;
|
||||
|
|
@ -660,8 +651,7 @@ static int exynos_adc_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
|
||||
err_of_populate:
|
||||
device_for_each_child(&indio_dev->dev, NULL,
|
||||
exynos_adc_remove_devices);
|
||||
of_platform_depopulate(&indio_dev->dev);
|
||||
iio_device_unregister(indio_dev);
|
||||
err_irq:
|
||||
free_irq(info->irq, info);
|
||||
|
|
@ -681,8 +671,7 @@ static void exynos_adc_remove(struct platform_device *pdev)
|
|||
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
|
||||
struct exynos_adc *info = iio_priv(indio_dev);
|
||||
|
||||
device_for_each_child(&indio_dev->dev, NULL,
|
||||
exynos_adc_remove_devices);
|
||||
of_platform_depopulate(&indio_dev->dev);
|
||||
iio_device_unregister(indio_dev);
|
||||
free_irq(info->irq, info);
|
||||
if (info->data->exit_hw)
|
||||
|
|
|
|||
|
|
@ -665,9 +665,9 @@ static int pac1934_reg_snapshot(struct pac1934_chip_info *info,
|
|||
/* add the power_acc field */
|
||||
curr_energy += inc;
|
||||
|
||||
clamp(curr_energy, PAC_193X_MIN_POWER_ACC, PAC_193X_MAX_POWER_ACC);
|
||||
|
||||
reg_data->energy_sec_acc[cnt] = curr_energy;
|
||||
reg_data->energy_sec_acc[cnt] = clamp(curr_energy,
|
||||
PAC_193X_MIN_POWER_ACC,
|
||||
PAC_193X_MAX_POWER_ACC);
|
||||
}
|
||||
|
||||
offset_reg_data_p += PAC1934_VPOWER_ACC_REG_LEN;
|
||||
|
|
|
|||
|
|
@ -584,7 +584,7 @@ static const struct iio_chan_spec scd4x_channels[] = {
|
|||
.sign = 'u',
|
||||
.realbits = 16,
|
||||
.storagebits = 16,
|
||||
.endianness = IIO_BE,
|
||||
.endianness = IIO_CPU,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -599,7 +599,7 @@ static const struct iio_chan_spec scd4x_channels[] = {
|
|||
.sign = 'u',
|
||||
.realbits = 16,
|
||||
.storagebits = 16,
|
||||
.endianness = IIO_BE,
|
||||
.endianness = IIO_CPU,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -612,7 +612,7 @@ static const struct iio_chan_spec scd4x_channels[] = {
|
|||
.sign = 'u',
|
||||
.realbits = 16,
|
||||
.storagebits = 16,
|
||||
.endianness = IIO_BE,
|
||||
.endianness = IIO_CPU,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -549,12 +549,15 @@ static ssize_t ad3552r_hs_write_data_source(struct file *f,
|
|||
|
||||
guard(mutex)(&st->lock);
|
||||
|
||||
if (count >= sizeof(buf))
|
||||
return -ENOSPC;
|
||||
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, userbuf,
|
||||
count);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
buf[count] = '\0';
|
||||
buf[ret] = '\0';
|
||||
|
||||
ret = match_string(dbgfs_attr_source, ARRAY_SIZE(dbgfs_attr_source),
|
||||
buf);
|
||||
|
|
|
|||
|
|
@ -434,6 +434,12 @@ static const struct ad5686_chip_info ad5686_chip_info_tbl[] = {
|
|||
.num_channels = 4,
|
||||
.regmap_type = AD5686_REGMAP,
|
||||
},
|
||||
[ID_AD5695R] = {
|
||||
.channels = ad5685r_channels,
|
||||
.int_vref_mv = 2500,
|
||||
.num_channels = 4,
|
||||
.regmap_type = AD5686_REGMAP,
|
||||
},
|
||||
[ID_AD5696] = {
|
||||
.channels = ad5686_channels,
|
||||
.num_channels = 4,
|
||||
|
|
|
|||
|
|
@ -960,16 +960,17 @@ int inv_icm45600_temp_read_raw(struct iio_dev *indio_dev,
|
|||
return IIO_VAL_INT;
|
||||
/*
|
||||
* T°C = (temp / 128) + 25
|
||||
* Tm°C = 1000 * ((temp * 100 / 12800) + 25)
|
||||
* scale: 100000 / 13248 = 7.8125
|
||||
* offset: 25000
|
||||
* Tm°C = ((temp + 25 * 128) / 128)) * 1000
|
||||
* Tm°C = (temp + 3200) * (1000 / 128)
|
||||
* scale: 1000 / 128 = 7.8125
|
||||
* offset: 3200
|
||||
*/
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
*val = 7;
|
||||
*val2 = 812500;
|
||||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
case IIO_CHAN_INFO_OFFSET:
|
||||
*val = 25000;
|
||||
*val = 3200;
|
||||
return IIO_VAL_INT;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -101,6 +101,13 @@ static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
|
|||
IIO_CHAN_SOFT_TIMESTAMP(3),
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec st_lsm6ds0_acc_channels[] = {
|
||||
ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
|
||||
ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
|
||||
ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2),
|
||||
IIO_CHAN_SOFT_TIMESTAMP(3),
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
|
||||
ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0),
|
||||
ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1),
|
||||
|
|
@ -142,8 +149,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
|||
},
|
||||
.channels = {
|
||||
[ST_LSM6DSX_ID_ACC] = {
|
||||
.chan = st_lsm6dsx_acc_channels,
|
||||
.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
|
||||
.chan = st_lsm6ds0_acc_channels,
|
||||
.len = ARRAY_SIZE(st_lsm6ds0_acc_channels),
|
||||
},
|
||||
[ST_LSM6DSX_ID_GYRO] = {
|
||||
.chan = st_lsm6ds0_gyro_channels,
|
||||
|
|
@ -1449,8 +1456,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
|||
},
|
||||
.channels = {
|
||||
[ST_LSM6DSX_ID_ACC] = {
|
||||
.chan = st_lsm6dsx_acc_channels,
|
||||
.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
|
||||
.chan = st_lsm6ds0_acc_channels,
|
||||
.len = ARRAY_SIZE(st_lsm6ds0_acc_channels),
|
||||
},
|
||||
[ST_LSM6DSX_ID_GYRO] = {
|
||||
.chan = st_lsm6dsx_gyro_channels,
|
||||
|
|
|
|||
|
|
@ -1657,6 +1657,7 @@ static void iio_dev_release(struct device *device)
|
|||
mutex_destroy(&iio_dev_opaque->info_exist_lock);
|
||||
mutex_destroy(&iio_dev_opaque->mlock);
|
||||
|
||||
lockdep_unregister_key(&iio_dev_opaque->info_exist_key);
|
||||
lockdep_unregister_key(&iio_dev_opaque->mlock_key);
|
||||
|
||||
ida_free(&iio_ida, iio_dev_opaque->id);
|
||||
|
|
@ -1717,9 +1718,10 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv)
|
|||
INIT_LIST_HEAD(&iio_dev_opaque->ioctl_handlers);
|
||||
|
||||
lockdep_register_key(&iio_dev_opaque->mlock_key);
|
||||
lockdep_register_key(&iio_dev_opaque->info_exist_key);
|
||||
|
||||
mutex_init_with_key(&iio_dev_opaque->mlock, &iio_dev_opaque->mlock_key);
|
||||
mutex_init(&iio_dev_opaque->info_exist_lock);
|
||||
mutex_init_with_key(&iio_dev_opaque->info_exist_lock, &iio_dev_opaque->info_exist_key);
|
||||
|
||||
indio_dev->dev.parent = parent;
|
||||
indio_dev->dev.type = &iio_device_type;
|
||||
|
|
|
|||
|
|
@ -150,6 +150,11 @@ int icc_debugfs_client_init(struct dentry *icc_dir)
|
|||
return ret;
|
||||
}
|
||||
|
||||
src_node = devm_kstrdup(&pdev->dev, "", GFP_KERNEL);
|
||||
dst_node = devm_kstrdup(&pdev->dev, "", GFP_KERNEL);
|
||||
if (!src_node || !dst_node)
|
||||
return -ENOMEM;
|
||||
|
||||
client_dir = debugfs_create_dir("test_client", icc_dir);
|
||||
|
||||
debugfs_create_str("src_node", 0600, client_dir, &src_node);
|
||||
|
|
|
|||
|
|
@ -21,18 +21,18 @@ TRACE_EVENT(mei_reg_read,
|
|||
TP_ARGS(dev, reg, offs, val),
|
||||
TP_STRUCT__entry(
|
||||
__string(dev, dev_name(dev))
|
||||
__field(const char *, reg)
|
||||
__string(reg, reg)
|
||||
__field(u32, offs)
|
||||
__field(u32, val)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__assign_str(dev);
|
||||
__entry->reg = reg;
|
||||
__assign_str(reg);
|
||||
__entry->offs = offs;
|
||||
__entry->val = val;
|
||||
),
|
||||
TP_printk("[%s] read %s:[%#x] = %#x",
|
||||
__get_str(dev), __entry->reg, __entry->offs, __entry->val)
|
||||
__get_str(dev), __get_str(reg), __entry->offs, __entry->val)
|
||||
);
|
||||
|
||||
TRACE_EVENT(mei_reg_write,
|
||||
|
|
@ -40,18 +40,18 @@ TRACE_EVENT(mei_reg_write,
|
|||
TP_ARGS(dev, reg, offs, val),
|
||||
TP_STRUCT__entry(
|
||||
__string(dev, dev_name(dev))
|
||||
__field(const char *, reg)
|
||||
__string(reg, reg)
|
||||
__field(u32, offs)
|
||||
__field(u32, val)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__assign_str(dev);
|
||||
__entry->reg = reg;
|
||||
__assign_str(reg);
|
||||
__entry->offs = offs;
|
||||
__entry->val = val;
|
||||
),
|
||||
TP_printk("[%s] write %s[%#x] = %#x",
|
||||
__get_str(dev), __entry->reg, __entry->offs, __entry->val)
|
||||
__get_str(dev), __get_str(reg), __entry->offs, __entry->val)
|
||||
);
|
||||
|
||||
TRACE_EVENT(mei_pci_cfg_read,
|
||||
|
|
@ -59,18 +59,18 @@ TRACE_EVENT(mei_pci_cfg_read,
|
|||
TP_ARGS(dev, reg, offs, val),
|
||||
TP_STRUCT__entry(
|
||||
__string(dev, dev_name(dev))
|
||||
__field(const char *, reg)
|
||||
__string(reg, reg)
|
||||
__field(u32, offs)
|
||||
__field(u32, val)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__assign_str(dev);
|
||||
__entry->reg = reg;
|
||||
__assign_str(reg);
|
||||
__entry->offs = offs;
|
||||
__entry->val = val;
|
||||
),
|
||||
TP_printk("[%s] pci cfg read %s:[%#x] = %#x",
|
||||
__get_str(dev), __entry->reg, __entry->offs, __entry->val)
|
||||
__get_str(dev), __get_str(reg), __entry->offs, __entry->val)
|
||||
);
|
||||
|
||||
#endif /* _MEI_TRACE_H_ */
|
||||
|
|
|
|||
|
|
@ -40,20 +40,34 @@ static int uacce_start_queue(struct uacce_queue *q)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int uacce_put_queue(struct uacce_queue *q)
|
||||
static int uacce_stop_queue(struct uacce_queue *q)
|
||||
{
|
||||
struct uacce_device *uacce = q->uacce;
|
||||
|
||||
if ((q->state == UACCE_Q_STARTED) && uacce->ops->stop_queue)
|
||||
if (q->state != UACCE_Q_STARTED)
|
||||
return 0;
|
||||
|
||||
if (uacce->ops->stop_queue)
|
||||
uacce->ops->stop_queue(q);
|
||||
|
||||
if ((q->state == UACCE_Q_INIT || q->state == UACCE_Q_STARTED) &&
|
||||
uacce->ops->put_queue)
|
||||
q->state = UACCE_Q_INIT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void uacce_put_queue(struct uacce_queue *q)
|
||||
{
|
||||
struct uacce_device *uacce = q->uacce;
|
||||
|
||||
uacce_stop_queue(q);
|
||||
|
||||
if (q->state != UACCE_Q_INIT)
|
||||
return;
|
||||
|
||||
if (uacce->ops->put_queue)
|
||||
uacce->ops->put_queue(q);
|
||||
|
||||
q->state = UACCE_Q_ZOMBIE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long uacce_fops_unl_ioctl(struct file *filep,
|
||||
|
|
@ -80,7 +94,7 @@ static long uacce_fops_unl_ioctl(struct file *filep,
|
|||
ret = uacce_start_queue(q);
|
||||
break;
|
||||
case UACCE_CMD_PUT_Q:
|
||||
ret = uacce_put_queue(q);
|
||||
ret = uacce_stop_queue(q);
|
||||
break;
|
||||
default:
|
||||
if (uacce->ops->ioctl)
|
||||
|
|
@ -214,8 +228,14 @@ static void uacce_vma_close(struct vm_area_struct *vma)
|
|||
}
|
||||
}
|
||||
|
||||
static int uacce_vma_mremap(struct vm_area_struct *area)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static const struct vm_operations_struct uacce_vm_ops = {
|
||||
.close = uacce_vma_close,
|
||||
.mremap = uacce_vma_mremap,
|
||||
};
|
||||
|
||||
static int uacce_fops_mmap(struct file *filep, struct vm_area_struct *vma)
|
||||
|
|
@ -382,6 +402,9 @@ static ssize_t isolate_strategy_show(struct device *dev, struct device_attribute
|
|||
struct uacce_device *uacce = to_uacce_device(dev);
|
||||
u32 val;
|
||||
|
||||
if (!uacce->ops->isolate_err_threshold_read)
|
||||
return -ENOENT;
|
||||
|
||||
val = uacce->ops->isolate_err_threshold_read(uacce);
|
||||
|
||||
return sysfs_emit(buf, "%u\n", val);
|
||||
|
|
@ -394,6 +417,9 @@ static ssize_t isolate_strategy_store(struct device *dev, struct device_attribut
|
|||
unsigned long val;
|
||||
int ret;
|
||||
|
||||
if (!uacce->ops->isolate_err_threshold_write)
|
||||
return -ENOENT;
|
||||
|
||||
if (kstrtoul(buf, 0, &val) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -519,6 +545,8 @@ EXPORT_SYMBOL_GPL(uacce_alloc);
|
|||
*/
|
||||
int uacce_register(struct uacce_device *uacce)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!uacce)
|
||||
return -ENODEV;
|
||||
|
||||
|
|
@ -529,7 +557,11 @@ int uacce_register(struct uacce_device *uacce)
|
|||
uacce->cdev->ops = &uacce_fops;
|
||||
uacce->cdev->owner = THIS_MODULE;
|
||||
|
||||
return cdev_device_add(uacce->cdev, &uacce->dev);
|
||||
ret = cdev_device_add(uacce->cdev, &uacce->dev);
|
||||
if (ret)
|
||||
uacce->cdev = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(uacce_register);
|
||||
|
||||
|
|
|
|||
|
|
@ -101,13 +101,13 @@ static int mux_mmio_probe(struct platform_device *pdev)
|
|||
mux_mmio = mux_chip_priv(mux_chip);
|
||||
|
||||
mux_mmio->fields = devm_kmalloc(dev, num_fields * sizeof(*mux_mmio->fields), GFP_KERNEL);
|
||||
if (IS_ERR(mux_mmio->fields))
|
||||
return PTR_ERR(mux_mmio->fields);
|
||||
if (!mux_mmio->fields)
|
||||
return -ENOMEM;
|
||||
|
||||
mux_mmio->hardware_states = devm_kmalloc(dev, num_fields *
|
||||
sizeof(*mux_mmio->hardware_states), GFP_KERNEL);
|
||||
if (IS_ERR(mux_mmio->hardware_states))
|
||||
return PTR_ERR(mux_mmio->hardware_states);
|
||||
if (!mux_mmio->hardware_states)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < num_fields; i++) {
|
||||
struct mux_control *mux = &mux_chip->mux[i];
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ static void slim_dev_release(struct device *dev)
|
|||
{
|
||||
struct slim_device *sbdev = to_slim_device(dev);
|
||||
|
||||
of_node_put(sbdev->dev.of_node);
|
||||
kfree(sbdev);
|
||||
}
|
||||
|
||||
|
|
@ -280,7 +281,6 @@ EXPORT_SYMBOL_GPL(slim_register_controller);
|
|||
/* slim_remove_device: Remove the effect of slim_add_device() */
|
||||
static void slim_remove_device(struct slim_device *sbdev)
|
||||
{
|
||||
of_node_put(sbdev->dev.of_node);
|
||||
device_unregister(&sbdev->dev);
|
||||
}
|
||||
|
||||
|
|
@ -366,6 +366,9 @@ static struct slim_device *find_slim_device(struct slim_controller *ctrl,
|
|||
* @ctrl: Controller on which this device will be added/queried
|
||||
* @e_addr: Enumeration address of the device to be queried
|
||||
*
|
||||
* Takes a reference to the embedded struct device which needs to be dropped
|
||||
* after use.
|
||||
*
|
||||
* Return: pointer to a device if it has already reported. Creates a new
|
||||
* device and returns pointer to it if the device has not yet enumerated.
|
||||
*/
|
||||
|
|
@ -379,14 +382,27 @@ struct slim_device *slim_get_device(struct slim_controller *ctrl,
|
|||
sbdev = slim_alloc_device(ctrl, e_addr, NULL);
|
||||
if (!sbdev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
get_device(&sbdev->dev);
|
||||
}
|
||||
|
||||
return sbdev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(slim_get_device);
|
||||
|
||||
static struct slim_device *of_find_slim_device(struct slim_controller *ctrl,
|
||||
struct device_node *np)
|
||||
/**
|
||||
* of_slim_get_device() - get handle to a device using dt node.
|
||||
*
|
||||
* @ctrl: Controller on which this device will be queried
|
||||
* @np: node pointer to device
|
||||
*
|
||||
* Takes a reference to the embedded struct device which needs to be dropped
|
||||
* after use.
|
||||
*
|
||||
* Return: pointer to a device if it has been registered, otherwise NULL.
|
||||
*/
|
||||
struct slim_device *of_slim_get_device(struct slim_controller *ctrl,
|
||||
struct device_node *np)
|
||||
{
|
||||
struct slim_device *sbdev;
|
||||
struct device *dev;
|
||||
|
|
@ -399,21 +415,6 @@ static struct slim_device *of_find_slim_device(struct slim_controller *ctrl,
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* of_slim_get_device() - get handle to a device using dt node.
|
||||
*
|
||||
* @ctrl: Controller on which this device will be added/queried
|
||||
* @np: node pointer to device
|
||||
*
|
||||
* Return: pointer to a device if it has already reported. Creates a new
|
||||
* device and returns pointer to it if the device has not yet enumerated.
|
||||
*/
|
||||
struct slim_device *of_slim_get_device(struct slim_controller *ctrl,
|
||||
struct device_node *np)
|
||||
{
|
||||
return of_find_slim_device(ctrl, np);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_slim_get_device);
|
||||
|
||||
static int slim_device_alloc_laddr(struct slim_device *sbdev,
|
||||
|
|
@ -489,21 +490,24 @@ int slim_device_report_present(struct slim_controller *ctrl,
|
|||
if (ctrl->sched.clk_state != SLIM_CLK_ACTIVE) {
|
||||
dev_err(ctrl->dev, "slim ctrl not active,state:%d, ret:%d\n",
|
||||
ctrl->sched.clk_state, ret);
|
||||
goto slimbus_not_active;
|
||||
goto out_put_rpm;
|
||||
}
|
||||
|
||||
sbdev = slim_get_device(ctrl, e_addr);
|
||||
if (IS_ERR(sbdev))
|
||||
return -ENODEV;
|
||||
if (IS_ERR(sbdev)) {
|
||||
ret = -ENODEV;
|
||||
goto out_put_rpm;
|
||||
}
|
||||
|
||||
if (sbdev->is_laddr_valid) {
|
||||
*laddr = sbdev->laddr;
|
||||
return 0;
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = slim_device_alloc_laddr(sbdev, true);
|
||||
}
|
||||
|
||||
ret = slim_device_alloc_laddr(sbdev, true);
|
||||
|
||||
slimbus_not_active:
|
||||
put_device(&sbdev->dev);
|
||||
out_put_rpm:
|
||||
pm_runtime_mark_last_busy(ctrl->dev);
|
||||
pm_runtime_put_autosuspend(ctrl->dev);
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ static int uio_pci_sva_open(struct uio_info *info, struct inode *inode)
|
|||
struct uio_pci_sva_dev *udev = info->priv;
|
||||
struct iommu_domain *domain;
|
||||
|
||||
if (!udev && !udev->pdev)
|
||||
if (!udev || !udev->pdev)
|
||||
return -ENODEV;
|
||||
|
||||
domain = iommu_get_domain_for_dev(&udev->pdev->dev);
|
||||
|
|
@ -51,7 +51,7 @@ static int uio_pci_sva_release(struct uio_info *info, struct inode *inode)
|
|||
{
|
||||
struct uio_pci_sva_dev *udev = info->priv;
|
||||
|
||||
if (!udev && !udev->pdev)
|
||||
if (!udev || !udev->pdev)
|
||||
return -ENODEV;
|
||||
|
||||
iommu_sva_unbind_device(udev->sva_handle);
|
||||
|
|
|
|||
|
|
@ -1836,53 +1836,35 @@ static ssize_t alarms_store(struct device *device,
|
|||
struct w1_slave *sl = dev_to_w1_slave(device);
|
||||
struct therm_info info;
|
||||
u8 new_config_register[3]; /* array of data to be written */
|
||||
int temp, ret;
|
||||
char *token = NULL;
|
||||
long long temp;
|
||||
int ret = 0;
|
||||
s8 tl, th; /* 1 byte per value + temp ring order */
|
||||
char *p_args, *orig;
|
||||
const char *p = buf;
|
||||
char *endp;
|
||||
|
||||
p_args = orig = kmalloc(size, GFP_KERNEL);
|
||||
/* Safe string copys as buf is const */
|
||||
if (!p_args) {
|
||||
dev_warn(device,
|
||||
"%s: error unable to allocate memory %d\n",
|
||||
__func__, -ENOMEM);
|
||||
return size;
|
||||
}
|
||||
strcpy(p_args, buf);
|
||||
|
||||
/* Split string using space char */
|
||||
token = strsep(&p_args, " ");
|
||||
|
||||
if (!token) {
|
||||
dev_info(device,
|
||||
"%s: error parsing args %d\n", __func__, -EINVAL);
|
||||
goto free_m;
|
||||
}
|
||||
|
||||
/* Convert 1st entry to int */
|
||||
ret = kstrtoint (token, 10, &temp);
|
||||
temp = simple_strtoll(p, &endp, 10);
|
||||
if (p == endp || *endp != ' ')
|
||||
ret = -EINVAL;
|
||||
else if (temp < INT_MIN || temp > INT_MAX)
|
||||
ret = -ERANGE;
|
||||
if (ret) {
|
||||
dev_info(device,
|
||||
"%s: error parsing args %d\n", __func__, ret);
|
||||
goto free_m;
|
||||
return size;
|
||||
}
|
||||
|
||||
tl = int_to_short(temp);
|
||||
|
||||
/* Split string using space char */
|
||||
token = strsep(&p_args, " ");
|
||||
if (!token) {
|
||||
dev_info(device,
|
||||
"%s: error parsing args %d\n", __func__, -EINVAL);
|
||||
goto free_m;
|
||||
}
|
||||
/* Convert 2nd entry to int */
|
||||
ret = kstrtoint (token, 10, &temp);
|
||||
p = endp + 1;
|
||||
temp = simple_strtoll(p, &endp, 10);
|
||||
if (p == endp)
|
||||
ret = -EINVAL;
|
||||
else if (temp < INT_MIN || temp > INT_MAX)
|
||||
ret = -ERANGE;
|
||||
if (ret) {
|
||||
dev_info(device,
|
||||
"%s: error parsing args %d\n", __func__, ret);
|
||||
goto free_m;
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Prepare to cast to short by eliminating out of range values */
|
||||
|
|
@ -1905,7 +1887,7 @@ static ssize_t alarms_store(struct device *device,
|
|||
dev_info(device,
|
||||
"%s: error reading from the slave device %d\n",
|
||||
__func__, ret);
|
||||
goto free_m;
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Write data in the device RAM */
|
||||
|
|
@ -1913,7 +1895,7 @@ static ssize_t alarms_store(struct device *device,
|
|||
dev_info(device,
|
||||
"%s: Device not supported by the driver %d\n",
|
||||
__func__, -ENODEV);
|
||||
goto free_m;
|
||||
return size;
|
||||
}
|
||||
|
||||
ret = SLAVE_SPECIFIC_FUNC(sl)->write_data(sl, new_config_register);
|
||||
|
|
@ -1922,10 +1904,6 @@ static ssize_t alarms_store(struct device *device,
|
|||
"%s: error writing to the slave device %d\n",
|
||||
__func__, ret);
|
||||
|
||||
free_m:
|
||||
/* free allocated memory */
|
||||
kfree(orig);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -758,8 +758,6 @@ int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
|
|||
if (err < 0) {
|
||||
dev_err(&dev->dev, "%s: Attaching %s failed.\n", __func__,
|
||||
sl->name);
|
||||
dev->slave_count--;
|
||||
w1_family_put(sl->family);
|
||||
atomic_dec(&sl->master->refcnt);
|
||||
kfree(sl);
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
* @mlock: lock used to prevent simultaneous device state changes
|
||||
* @mlock_key: lockdep class for iio_dev lock
|
||||
* @info_exist_lock: lock to prevent use during removal
|
||||
* @info_exist_key: lockdep class for info_exist lock
|
||||
* @trig_readonly: mark the current trigger immutable
|
||||
* @event_interface: event chrdevs associated with interrupt lines
|
||||
* @attached_buffers: array of buffers statically attached by the driver
|
||||
|
|
@ -47,6 +48,7 @@ struct iio_dev_opaque {
|
|||
struct mutex mlock;
|
||||
struct lock_class_key mlock_key;
|
||||
struct mutex info_exist_lock;
|
||||
struct lock_class_key info_exist_key;
|
||||
bool trig_readonly;
|
||||
struct iio_event_interface *event_interface;
|
||||
struct iio_buffer **attached_buffers;
|
||||
|
|
|
|||
|
|
@ -640,7 +640,7 @@ struct comedi_chaninfo {
|
|||
|
||||
/**
|
||||
* struct comedi_rangeinfo - used to retrieve the range table for a channel
|
||||
* @range_type: Encodes subdevice index (bits 27:24), channel index
|
||||
* @range_type: Encodes subdevice index (bits 31:24), channel index
|
||||
* (bits 23:16) and range table length (bits 15:0).
|
||||
* @range_ptr: Pointer to array of @struct comedi_krange to be filled
|
||||
* in with the range table for the channel or subdevice.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue