Skip to content

Commit c96711e

Browse files
committed
Merge tag 'iio-fixes-for-5.9a' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-linus
Jonathan writes: First set of IIO fixes for the 5.9 cycle Most of the fixes this time are for a long term issue that Lars-Peter Clausen identified recently. IIO assumes that any data pushed to the buffer interface (either kfifo or another in kernel consumer) are naturally aligned. Unfortunately this isn't true in a number of drivers, mostly by failing to ensure the buffer used is aligned suitably for an s64 timestamp. For the ones covered this time we use a structure to enforce this alignment, with the added need for __aligned(8) to ensure 8 byte alignment of the timestamp on x86_32 and similar platforms where it would be 4 byte aligned giving different padded from some other architectures. Patches to make this requirement clearer and potentially cause an error print will follow once we've cleaned up existing cases. Note that it is a very hard to hit problem and as a result of this as we only have one bug report despite the problem being present for many years. Other fixes: * cros_ec: - set gyroscope default frequency. For some older boards not having this set can lead to a choice that doesn't work. * counter,microchip-tcb-capture: - Fix a wrong value check in error check. * mcp3422 - Fix locking to protect against race condition. * meson-adc - Use right device when looking up fuse values for calibration. * rockchip-adc - Fix missing Kconfig dependency. * ti-ads1015: - Fix reading when CONFIG_PM not set. * tag 'iio-fixes-for-5.9a' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: iio: adc: mcp3422: fix locking scope iio: adc: meson-saradc: Use the parent device to look up the calib data iio:adc:max1118 Fix alignment of timestamp and data leak issues iio:adc:ina2xx Fix timestamp alignment issue. iio:adc:ti-adc084s021 Fix alignment and data leak issues. iio:adc:ti-adc081c Fix alignment and data leak issues iio:magnetometer:ak8975 Fix alignment and data leak issues. iio:light:ltr501 Fix timestamp alignment issue. iio:light:max44000 Fix timestamp alignment and prevent data leak. iio:chemical:ccs811: Fix timestamp alignment and prevent data leak. iio:proximity:mb1232: Fix timestamp alignment and prevent data leak. iio:accel:mma7455: Fix timestamp alignment and prevent data leak. iio:accel:bmc150-accel: Fix timestamp alignment and prevent data leak. iio:accel:mma8452: Fix timestamp alignment and prevent data leak. iio: accel: kxsd9: Fix alignment of local buffer. iio: adc: rockchip_saradc: select IIO_TRIGGERED_BUFFER iio: adc: ti-ads1015: fix conversion when CONFIG_PM is not set counter: microchip-tcb-capture: check the correct variable iio: cros_ec: Set Gyroscope default frequency to 25Hz
2 parents 1dffeb8 + 3f1093d commit c96711e

File tree

19 files changed

+144
-64
lines changed

19 files changed

+144
-64
lines changed

drivers/counter/microchip-tcb-capture.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,8 @@ static int mchp_tc_probe(struct platform_device *pdev)
320320
}
321321

322322
regmap = syscon_node_to_regmap(np->parent);
323-
if (IS_ERR(priv->regmap))
324-
return PTR_ERR(priv->regmap);
323+
if (IS_ERR(regmap))
324+
return PTR_ERR(regmap);
325325

326326
/* max. channels number is 2 when in QDEC mode */
327327
priv->num_channels = of_property_count_u32_elems(np, "reg");

drivers/iio/accel/bmc150-accel-core.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,14 @@ struct bmc150_accel_data {
189189
struct mutex mutex;
190190
u8 fifo_mode, watermark;
191191
s16 buffer[8];
192+
/*
193+
* Ensure there is sufficient space and correct alignment for
194+
* the timestamp if enabled
195+
*/
196+
struct {
197+
__le16 channels[3];
198+
s64 ts __aligned(8);
199+
} scan;
192200
u8 bw_bits;
193201
u32 slope_dur;
194202
u32 slope_thres;
@@ -922,15 +930,16 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
922930
* now.
923931
*/
924932
for (i = 0; i < count; i++) {
925-
u16 sample[8];
926933
int j, bit;
927934

928935
j = 0;
929936
for_each_set_bit(bit, indio_dev->active_scan_mask,
930937
indio_dev->masklength)
931-
memcpy(&sample[j++], &buffer[i * 3 + bit], 2);
938+
memcpy(&data->scan.channels[j++], &buffer[i * 3 + bit],
939+
sizeof(data->scan.channels[0]));
932940

933-
iio_push_to_buffers_with_timestamp(indio_dev, sample, tstamp);
941+
iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
942+
tstamp);
934943

935944
tstamp += sample_period;
936945
}

drivers/iio/accel/kxsd9.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -209,22 +209,28 @@ static irqreturn_t kxsd9_trigger_handler(int irq, void *p)
209209
const struct iio_poll_func *pf = p;
210210
struct iio_dev *indio_dev = pf->indio_dev;
211211
struct kxsd9_state *st = iio_priv(indio_dev);
212+
/*
213+
* Ensure correct positioning and alignment of timestamp.
214+
* No need to zero initialize as all elements written.
215+
*/
216+
struct {
217+
__be16 chan[4];
218+
s64 ts __aligned(8);
219+
} hw_values;
212220
int ret;
213-
/* 4 * 16bit values AND timestamp */
214-
__be16 hw_values[8];
215221

216222
ret = regmap_bulk_read(st->map,
217223
KXSD9_REG_X,
218-
&hw_values,
219-
8);
224+
hw_values.chan,
225+
sizeof(hw_values.chan));
220226
if (ret) {
221227
dev_err(st->dev,
222228
"error reading data\n");
223229
return ret;
224230
}
225231

226232
iio_push_to_buffers_with_timestamp(indio_dev,
227-
hw_values,
233+
&hw_values,
228234
iio_get_time_ns(indio_dev));
229235
iio_trigger_notify_done(indio_dev->trig);
230236

drivers/iio/accel/mma7455_core.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@
5252

5353
struct mma7455_data {
5454
struct regmap *regmap;
55+
/*
56+
* Used to reorganize data. Will ensure correct alignment of
57+
* the timestamp if present
58+
*/
59+
struct {
60+
__le16 channels[3];
61+
s64 ts __aligned(8);
62+
} scan;
5563
};
5664

5765
static int mma7455_drdy(struct mma7455_data *mma7455)
@@ -82,19 +90,19 @@ static irqreturn_t mma7455_trigger_handler(int irq, void *p)
8290
struct iio_poll_func *pf = p;
8391
struct iio_dev *indio_dev = pf->indio_dev;
8492
struct mma7455_data *mma7455 = iio_priv(indio_dev);
85-
u8 buf[16]; /* 3 x 16-bit channels + padding + ts */
8693
int ret;
8794

8895
ret = mma7455_drdy(mma7455);
8996
if (ret)
9097
goto done;
9198

92-
ret = regmap_bulk_read(mma7455->regmap, MMA7455_REG_XOUTL, buf,
93-
sizeof(__le16) * 3);
99+
ret = regmap_bulk_read(mma7455->regmap, MMA7455_REG_XOUTL,
100+
mma7455->scan.channels,
101+
sizeof(mma7455->scan.channels));
94102
if (ret)
95103
goto done;
96104

97-
iio_push_to_buffers_with_timestamp(indio_dev, buf,
105+
iio_push_to_buffers_with_timestamp(indio_dev, &mma7455->scan,
98106
iio_get_time_ns(indio_dev));
99107

100108
done:

drivers/iio/accel/mma8452.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,12 @@ struct mma8452_data {
110110
int sleep_val;
111111
struct regulator *vdd_reg;
112112
struct regulator *vddio_reg;
113+
114+
/* Ensure correct alignment of time stamp when present */
115+
struct {
116+
__be16 channels[3];
117+
s64 ts __aligned(8);
118+
} buffer;
113119
};
114120

115121
/**
@@ -1091,14 +1097,13 @@ static irqreturn_t mma8452_trigger_handler(int irq, void *p)
10911097
struct iio_poll_func *pf = p;
10921098
struct iio_dev *indio_dev = pf->indio_dev;
10931099
struct mma8452_data *data = iio_priv(indio_dev);
1094-
u8 buffer[16]; /* 3 16-bit channels + padding + ts */
10951100
int ret;
10961101

1097-
ret = mma8452_read(data, (__be16 *)buffer);
1102+
ret = mma8452_read(data, data->buffer.channels);
10981103
if (ret < 0)
10991104
goto done;
11001105

1101-
iio_push_to_buffers_with_timestamp(indio_dev, buffer,
1106+
iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer,
11021107
iio_get_time_ns(indio_dev));
11031108

11041109
done:

drivers/iio/adc/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,8 @@ config ROCKCHIP_SARADC
865865
tristate "Rockchip SARADC driver"
866866
depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST)
867867
depends on RESET_CONTROLLER
868+
select IIO_BUFFER
869+
select IIO_TRIGGERED_BUFFER
868870
help
869871
Say yes here to build support for the SARADC found in SoCs from
870872
Rockchip.

drivers/iio/adc/ina2xx-adc.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,11 @@ struct ina2xx_chip_info {
146146
int range_vbus; /* Bus voltage maximum in V */
147147
int pga_gain_vshunt; /* Shunt voltage PGA gain */
148148
bool allow_async_readout;
149+
/* data buffer needs space for channel data and timestamp */
150+
struct {
151+
u16 chan[4];
152+
u64 ts __aligned(8);
153+
} scan;
149154
};
150155

151156
static const struct ina2xx_config ina2xx_config[] = {
@@ -738,8 +743,6 @@ static int ina2xx_conversion_ready(struct iio_dev *indio_dev)
738743
static int ina2xx_work_buffer(struct iio_dev *indio_dev)
739744
{
740745
struct ina2xx_chip_info *chip = iio_priv(indio_dev);
741-
/* data buffer needs space for channel data and timestap */
742-
unsigned short data[4 + sizeof(s64)/sizeof(short)];
743746
int bit, ret, i = 0;
744747
s64 time;
745748

@@ -758,10 +761,10 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev)
758761
if (ret < 0)
759762
return ret;
760763

761-
data[i++] = val;
764+
chip->scan.chan[i++] = val;
762765
}
763766

764-
iio_push_to_buffers_with_timestamp(indio_dev, data, time);
767+
iio_push_to_buffers_with_timestamp(indio_dev, &chip->scan, time);
765768

766769
return 0;
767770
};

drivers/iio/adc/max1118.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ struct max1118 {
3636
struct spi_device *spi;
3737
struct mutex lock;
3838
struct regulator *reg;
39+
/* Ensure natural alignment of buffer elements */
40+
struct {
41+
u8 channels[2];
42+
s64 ts __aligned(8);
43+
} scan;
3944

4045
u8 data ____cacheline_aligned;
4146
};
@@ -166,7 +171,6 @@ static irqreturn_t max1118_trigger_handler(int irq, void *p)
166171
struct iio_poll_func *pf = p;
167172
struct iio_dev *indio_dev = pf->indio_dev;
168173
struct max1118 *adc = iio_priv(indio_dev);
169-
u8 data[16] = { }; /* 2x 8-bit ADC data + padding + 8 bytes timestamp */
170174
int scan_index;
171175
int i = 0;
172176

@@ -184,10 +188,10 @@ static irqreturn_t max1118_trigger_handler(int irq, void *p)
184188
goto out;
185189
}
186190

187-
data[i] = ret;
191+
adc->scan.channels[i] = ret;
188192
i++;
189193
}
190-
iio_push_to_buffers_with_timestamp(indio_dev, data,
194+
iio_push_to_buffers_with_timestamp(indio_dev, &adc->scan,
191195
iio_get_time_ns(indio_dev));
192196
out:
193197
mutex_unlock(&adc->lock);

drivers/iio/adc/mcp3422.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,16 +96,12 @@ static int mcp3422_update_config(struct mcp3422 *adc, u8 newconfig)
9696
{
9797
int ret;
9898

99-
mutex_lock(&adc->lock);
100-
10199
ret = i2c_master_send(adc->i2c, &newconfig, 1);
102100
if (ret > 0) {
103101
adc->config = newconfig;
104102
ret = 0;
105103
}
106104

107-
mutex_unlock(&adc->lock);
108-
109105
return ret;
110106
}
111107

@@ -138,6 +134,8 @@ static int mcp3422_read_channel(struct mcp3422 *adc,
138134
u8 config;
139135
u8 req_channel = channel->channel;
140136

137+
mutex_lock(&adc->lock);
138+
141139
if (req_channel != MCP3422_CHANNEL(adc->config)) {
142140
config = adc->config;
143141
config &= ~MCP3422_CHANNEL_MASK;
@@ -150,7 +148,11 @@ static int mcp3422_read_channel(struct mcp3422 *adc,
150148
msleep(mcp3422_read_times[MCP3422_SAMPLE_RATE(adc->config)]);
151149
}
152150

153-
return mcp3422_read(adc, value, &config);
151+
ret = mcp3422_read(adc, value, &config);
152+
153+
mutex_unlock(&adc->lock);
154+
155+
return ret;
154156
}
155157

156158
static int mcp3422_read_raw(struct iio_dev *iio,

drivers/iio/adc/meson_saradc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,7 @@ static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev)
707707
size_t read_len;
708708
int ret;
709709

710-
temperature_calib = devm_nvmem_cell_get(&indio_dev->dev,
710+
temperature_calib = devm_nvmem_cell_get(indio_dev->dev.parent,
711711
"temperature_calib");
712712
if (IS_ERR(temperature_calib)) {
713713
ret = PTR_ERR(temperature_calib);

0 commit comments

Comments
 (0)