Skip to content

Commit 8d245ac

Browse files
committed
Merge tag 'char-misc-6.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc/iio fixes from Greg KH: "Here are a small number of char/misc/iio and other driver fixes for 6.17-rc3. Included in here are: - IIO driver bugfixes for reported issues - bunch of comedi driver fixes - most core bugfix - fpga driver bugfix - cdx driver bugfix All of these have been in linux-next this week with no reported issues" * tag 'char-misc-6.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: most: core: Drop device reference after usage in get_channel() comedi: Make insn_rw_emulate_bits() do insn->n samples comedi: Fix use of uninitialized memory in do_insn_ioctl() and do_insnlist_ioctl() comedi: pcl726: Prevent invalid irq number cdx: Fix off-by-one error in cdx_rpmsg_probe() fpga: zynq_fpga: Fix the wrong usage of dma_map_sgtable() iio: pressure: bmp280: Use IS_ERR() in bmp280_common_probe() iio: light: as73211: Ensure buffer holes are zeroed iio: adc: rzg2l_adc: Set driver data before enabling runtime PM iio: adc: rzg2l: Cleanup suspend/resume path iio: adc: ad7380: fix missing max_conversion_rate_hz on adaq4381-4 iio: adc: bd79124: Add GPIOLIB dependency iio: imu: inv_icm42600: change invalid data error to -EBUSY iio: adc: ad7124: fix channel lookup in syscalib functions iio: temperature: maxim_thermocouple: use DMA-safe buffer for spi_read() iio: adc: ad7173: prevent scan if too many setups requested iio: proximity: isl29501: fix buffered read on big-endian systems iio: accel: sca3300: fix uninitialized iio scan data
2 parents 8004d08 + fe85261 commit 8d245ac

File tree

17 files changed

+158
-84
lines changed

17 files changed

+158
-84
lines changed

drivers/cdx/controller/cdx_rpmsg.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,7 @@ static int cdx_rpmsg_probe(struct rpmsg_device *rpdev)
129129

130130
chinfo.src = RPMSG_ADDR_ANY;
131131
chinfo.dst = rpdev->dst;
132-
strscpy(chinfo.name, cdx_rpmsg_id_table[0].name,
133-
strlen(cdx_rpmsg_id_table[0].name));
132+
strscpy(chinfo.name, cdx_rpmsg_id_table[0].name, sizeof(chinfo.name));
134133

135134
cdx_mcdi->ept = rpmsg_create_ept(rpdev, cdx_rpmsg_cb, NULL, chinfo);
136135
if (!cdx_mcdi->ept) {

drivers/comedi/comedi_fops.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1587,6 +1587,9 @@ static int do_insnlist_ioctl(struct comedi_device *dev,
15871587
memset(&data[n], 0, (MIN_SAMPLES - n) *
15881588
sizeof(unsigned int));
15891589
}
1590+
} else {
1591+
memset(data, 0, max_t(unsigned int, n, MIN_SAMPLES) *
1592+
sizeof(unsigned int));
15901593
}
15911594
ret = parse_insn(dev, insns + i, data, file);
15921595
if (ret < 0)
@@ -1670,6 +1673,8 @@ static int do_insn_ioctl(struct comedi_device *dev,
16701673
memset(&data[insn->n], 0,
16711674
(MIN_SAMPLES - insn->n) * sizeof(unsigned int));
16721675
}
1676+
} else {
1677+
memset(data, 0, n_data * sizeof(unsigned int));
16731678
}
16741679
ret = parse_insn(dev, insn, data, file);
16751680
if (ret < 0)

drivers/comedi/drivers.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -620,11 +620,9 @@ static int insn_rw_emulate_bits(struct comedi_device *dev,
620620
unsigned int chan = CR_CHAN(insn->chanspec);
621621
unsigned int base_chan = (chan < 32) ? 0 : chan;
622622
unsigned int _data[2];
623+
unsigned int i;
623624
int ret;
624625

625-
if (insn->n == 0)
626-
return 0;
627-
628626
memset(_data, 0, sizeof(_data));
629627
memset(&_insn, 0, sizeof(_insn));
630628
_insn.insn = INSN_BITS;
@@ -635,18 +633,21 @@ static int insn_rw_emulate_bits(struct comedi_device *dev,
635633
if (insn->insn == INSN_WRITE) {
636634
if (!(s->subdev_flags & SDF_WRITABLE))
637635
return -EINVAL;
638-
_data[0] = 1U << (chan - base_chan); /* mask */
639-
_data[1] = data[0] ? (1U << (chan - base_chan)) : 0; /* bits */
636+
_data[0] = 1U << (chan - base_chan); /* mask */
640637
}
638+
for (i = 0; i < insn->n; i++) {
639+
if (insn->insn == INSN_WRITE)
640+
_data[1] = data[i] ? _data[0] : 0; /* bits */
641641

642-
ret = s->insn_bits(dev, s, &_insn, _data);
643-
if (ret < 0)
644-
return ret;
642+
ret = s->insn_bits(dev, s, &_insn, _data);
643+
if (ret < 0)
644+
return ret;
645645

646-
if (insn->insn == INSN_READ)
647-
data[0] = (_data[1] >> (chan - base_chan)) & 1;
646+
if (insn->insn == INSN_READ)
647+
data[i] = (_data[1] >> (chan - base_chan)) & 1;
648+
}
648649

649-
return 1;
650+
return insn->n;
650651
}
651652

652653
static int __comedi_device_postconfig_async(struct comedi_device *dev,

drivers/comedi/drivers/pcl726.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,8 @@ static int pcl726_attach(struct comedi_device *dev,
328328
* Hook up the external trigger source interrupt only if the
329329
* user config option is valid and the board supports interrupts.
330330
*/
331-
if (it->options[1] && (board->irq_mask & (1 << it->options[1]))) {
331+
if (it->options[1] > 0 && it->options[1] < 16 &&
332+
(board->irq_mask & (1U << it->options[1]))) {
332333
ret = request_irq(it->options[1], pcl726_interrupt, 0,
333334
dev->board_name, dev);
334335
if (ret == 0) {

drivers/fpga/zynq-fpga.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -405,12 +405,12 @@ static int zynq_fpga_ops_write(struct fpga_manager *mgr, struct sg_table *sgt)
405405
}
406406
}
407407

408-
priv->dma_nelms =
409-
dma_map_sgtable(mgr->dev.parent, sgt, DMA_TO_DEVICE, 0);
410-
if (priv->dma_nelms == 0) {
408+
err = dma_map_sgtable(mgr->dev.parent, sgt, DMA_TO_DEVICE, 0);
409+
if (err) {
411410
dev_err(&mgr->dev, "Unable to DMA map (TO_DEVICE)\n");
412-
return -ENOMEM;
411+
return err;
413412
}
413+
priv->dma_nelms = sgt->nents;
414414

415415
/* enable clock */
416416
err = clk_enable(priv->clk);

drivers/iio/accel/sca3300.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ static irqreturn_t sca3300_trigger_handler(int irq, void *p)
477477
struct iio_dev *indio_dev = pf->indio_dev;
478478
struct sca3300_data *data = iio_priv(indio_dev);
479479
int bit, ret, val, i = 0;
480-
IIO_DECLARE_BUFFER_WITH_TS(s16, channels, SCA3300_SCAN_MAX);
480+
IIO_DECLARE_BUFFER_WITH_TS(s16, channels, SCA3300_SCAN_MAX) = { };
481481

482482
iio_for_each_active_channel(indio_dev, bit) {
483483
ret = sca3300_read_reg(data, indio_dev->channels[bit].address, &val);

drivers/iio/adc/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1300,7 +1300,7 @@ config RN5T618_ADC
13001300

13011301
config ROHM_BD79124
13021302
tristate "Rohm BD79124 ADC driver"
1303-
depends on I2C
1303+
depends on I2C && GPIOLIB
13041304
select REGMAP_I2C
13051305
select IIO_ADC_HELPER
13061306
help

drivers/iio/adc/ad7124.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,7 @@ enum {
849849
static int ad7124_syscalib_locked(struct ad7124_state *st, const struct iio_chan_spec *chan)
850850
{
851851
struct device *dev = &st->sd.spi->dev;
852-
struct ad7124_channel *ch = &st->channels[chan->channel];
852+
struct ad7124_channel *ch = &st->channels[chan->address];
853853
int ret;
854854

855855
if (ch->syscalib_mode == AD7124_SYSCALIB_ZERO_SCALE) {
@@ -865,8 +865,8 @@ static int ad7124_syscalib_locked(struct ad7124_state *st, const struct iio_chan
865865
if (ret < 0)
866866
return ret;
867867

868-
dev_dbg(dev, "offset for channel %d after zero-scale calibration: 0x%x\n",
869-
chan->channel, ch->cfg.calibration_offset);
868+
dev_dbg(dev, "offset for channel %lu after zero-scale calibration: 0x%x\n",
869+
chan->address, ch->cfg.calibration_offset);
870870
} else {
871871
ch->cfg.calibration_gain = st->gain_default;
872872

@@ -880,8 +880,8 @@ static int ad7124_syscalib_locked(struct ad7124_state *st, const struct iio_chan
880880
if (ret < 0)
881881
return ret;
882882

883-
dev_dbg(dev, "gain for channel %d after full-scale calibration: 0x%x\n",
884-
chan->channel, ch->cfg.calibration_gain);
883+
dev_dbg(dev, "gain for channel %lu after full-scale calibration: 0x%x\n",
884+
chan->address, ch->cfg.calibration_gain);
885885
}
886886

887887
return 0;
@@ -924,7 +924,7 @@ static int ad7124_set_syscalib_mode(struct iio_dev *indio_dev,
924924
{
925925
struct ad7124_state *st = iio_priv(indio_dev);
926926

927-
st->channels[chan->channel].syscalib_mode = mode;
927+
st->channels[chan->address].syscalib_mode = mode;
928928

929929
return 0;
930930
}
@@ -934,7 +934,7 @@ static int ad7124_get_syscalib_mode(struct iio_dev *indio_dev,
934934
{
935935
struct ad7124_state *st = iio_priv(indio_dev);
936936

937-
return st->channels[chan->channel].syscalib_mode;
937+
return st->channels[chan->address].syscalib_mode;
938938
}
939939

940940
static const struct iio_enum ad7124_syscalib_mode_enum = {

drivers/iio/adc/ad7173.c

Lines changed: 75 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ struct ad7173_channel_config {
200200
/*
201201
* Following fields are used to compare equality. If you
202202
* make adaptations in it, you most likely also have to adapt
203-
* ad7173_find_live_config(), too.
203+
* ad7173_is_setup_equal(), too.
204204
*/
205205
struct_group(config_props,
206206
bool bipolar;
@@ -561,12 +561,19 @@ static void ad7173_reset_usage_cnts(struct ad7173_state *st)
561561
st->config_usage_counter = 0;
562562
}
563563

564-
static struct ad7173_channel_config *
565-
ad7173_find_live_config(struct ad7173_state *st, struct ad7173_channel_config *cfg)
564+
/**
565+
* ad7173_is_setup_equal - Compare two channel setups
566+
* @cfg1: First channel configuration
567+
* @cfg2: Second channel configuration
568+
*
569+
* Compares all configuration options that affect the registers connected to
570+
* SETUP_SEL, namely CONFIGx, FILTERx, GAINx and OFFSETx.
571+
*
572+
* Returns: true if the setups are identical, false otherwise
573+
*/
574+
static bool ad7173_is_setup_equal(const struct ad7173_channel_config *cfg1,
575+
const struct ad7173_channel_config *cfg2)
566576
{
567-
struct ad7173_channel_config *cfg_aux;
568-
int i;
569-
570577
/*
571578
* This is just to make sure that the comparison is adapted after
572579
* struct ad7173_channel_config was changed.
@@ -579,14 +586,22 @@ ad7173_find_live_config(struct ad7173_state *st, struct ad7173_channel_config *c
579586
u8 ref_sel;
580587
}));
581588

589+
return cfg1->bipolar == cfg2->bipolar &&
590+
cfg1->input_buf == cfg2->input_buf &&
591+
cfg1->odr == cfg2->odr &&
592+
cfg1->ref_sel == cfg2->ref_sel;
593+
}
594+
595+
static struct ad7173_channel_config *
596+
ad7173_find_live_config(struct ad7173_state *st, struct ad7173_channel_config *cfg)
597+
{
598+
struct ad7173_channel_config *cfg_aux;
599+
int i;
600+
582601
for (i = 0; i < st->num_channels; i++) {
583602
cfg_aux = &st->channels[i].cfg;
584603

585-
if (cfg_aux->live &&
586-
cfg->bipolar == cfg_aux->bipolar &&
587-
cfg->input_buf == cfg_aux->input_buf &&
588-
cfg->odr == cfg_aux->odr &&
589-
cfg->ref_sel == cfg_aux->ref_sel)
604+
if (cfg_aux->live && ad7173_is_setup_equal(cfg, cfg_aux))
590605
return cfg_aux;
591606
}
592607
return NULL;
@@ -1228,7 +1243,7 @@ static int ad7173_update_scan_mode(struct iio_dev *indio_dev,
12281243
const unsigned long *scan_mask)
12291244
{
12301245
struct ad7173_state *st = iio_priv(indio_dev);
1231-
int i, ret;
1246+
int i, j, k, ret;
12321247

12331248
for (i = 0; i < indio_dev->num_channels; i++) {
12341249
if (test_bit(i, scan_mask))
@@ -1239,6 +1254,54 @@ static int ad7173_update_scan_mode(struct iio_dev *indio_dev,
12391254
return ret;
12401255
}
12411256

1257+
/*
1258+
* On some chips, there are more channels that setups, so if there were
1259+
* more unique setups requested than the number of available slots,
1260+
* ad7173_set_channel() will have written over some of the slots. We
1261+
* can detect this by making sure each assigned cfg_slot matches the
1262+
* requested configuration. If it doesn't, we know that the slot was
1263+
* overwritten by a different channel.
1264+
*/
1265+
for_each_set_bit(i, scan_mask, indio_dev->num_channels) {
1266+
const struct ad7173_channel_config *cfg1, *cfg2;
1267+
1268+
cfg1 = &st->channels[i].cfg;
1269+
1270+
for_each_set_bit(j, scan_mask, indio_dev->num_channels) {
1271+
cfg2 = &st->channels[j].cfg;
1272+
1273+
/*
1274+
* Only compare configs that are assigned to the same
1275+
* SETUP_SEL slot and don't compare channel to itself.
1276+
*/
1277+
if (i == j || cfg1->cfg_slot != cfg2->cfg_slot)
1278+
continue;
1279+
1280+
/*
1281+
* If we find two different configs trying to use the
1282+
* same SETUP_SEL slot, then we know that the that we
1283+
* have too many unique configurations requested for
1284+
* the available slots and at least one was overwritten.
1285+
*/
1286+
if (!ad7173_is_setup_equal(cfg1, cfg2)) {
1287+
/*
1288+
* At this point, there isn't a way to tell
1289+
* which setups are actually programmed in the
1290+
* ADC anymore, so we could read them back to
1291+
* see, but it is simpler to just turn off all
1292+
* of the live flags so that everything gets
1293+
* reprogramed on the next attempt read a sample.
1294+
*/
1295+
for (k = 0; k < st->num_channels; k++)
1296+
st->channels[k].cfg.live = false;
1297+
1298+
dev_err(&st->sd.spi->dev,
1299+
"Too many unique channel configurations requested for scan\n");
1300+
return -EINVAL;
1301+
}
1302+
}
1303+
}
1304+
12421305
return 0;
12431306
}
12441307

drivers/iio/adc/ad7380.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,7 @@ static const struct ad7380_chip_info adaq4381_4_chip_info = {
873873
.has_hardware_gain = true,
874874
.available_scan_masks = ad7380_4_channel_scan_masks,
875875
.timing_specs = &ad7380_4_timing,
876+
.max_conversion_rate_hz = 4 * MEGA,
876877
};
877878

878879
static const struct spi_offload_config ad7380_offload_config = {

0 commit comments

Comments
 (0)