Commit c96711e1 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'iio-fixes-for-5.9a' of...

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
parents 1dffeb8b 3f1093d8
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -320,8 +320,8 @@ static int mchp_tc_probe(struct platform_device *pdev)
	}

	regmap = syscon_node_to_regmap(np->parent);
	if (IS_ERR(priv->regmap))
		return PTR_ERR(priv->regmap);
	if (IS_ERR(regmap))
		return PTR_ERR(regmap);

	/* max. channels number is 2 when in QDEC mode */
	priv->num_channels = of_property_count_u32_elems(np, "reg");
+12 −3
Original line number Diff line number Diff line
@@ -189,6 +189,14 @@ struct bmc150_accel_data {
	struct mutex mutex;
	u8 fifo_mode, watermark;
	s16 buffer[8];
	/*
	 * Ensure there is sufficient space and correct alignment for
	 * the timestamp if enabled
	 */
	struct {
		__le16 channels[3];
		s64 ts __aligned(8);
	} scan;
	u8 bw_bits;
	u32 slope_dur;
	u32 slope_thres;
@@ -922,15 +930,16 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
	 * now.
	 */
	for (i = 0; i < count; i++) {
		u16 sample[8];
		int j, bit;

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

		iio_push_to_buffers_with_timestamp(indio_dev, sample, tstamp);
		iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
						   tstamp);

		tstamp += sample_period;
	}
+11 −5
Original line number Diff line number Diff line
@@ -209,14 +209,20 @@ static irqreturn_t kxsd9_trigger_handler(int irq, void *p)
	const struct iio_poll_func *pf = p;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct kxsd9_state *st = iio_priv(indio_dev);
	/*
	 * Ensure correct positioning and alignment of timestamp.
	 * No need to zero initialize as all elements written.
	 */
	struct {
		__be16 chan[4];
		s64 ts __aligned(8);
	} hw_values;
	int ret;
	/* 4 * 16bit values AND timestamp */
	__be16 hw_values[8];

	ret = regmap_bulk_read(st->map,
			       KXSD9_REG_X,
			       &hw_values,
			       8);
			       hw_values.chan,
			       sizeof(hw_values.chan));
	if (ret) {
		dev_err(st->dev,
			"error reading data\n");
@@ -224,7 +230,7 @@ static irqreturn_t kxsd9_trigger_handler(int irq, void *p)
	}

	iio_push_to_buffers_with_timestamp(indio_dev,
					   hw_values,
					   &hw_values,
					   iio_get_time_ns(indio_dev));
	iio_trigger_notify_done(indio_dev->trig);

+12 −4
Original line number Diff line number Diff line
@@ -52,6 +52,14 @@

struct mma7455_data {
	struct regmap *regmap;
	/*
	 * Used to reorganize data.  Will ensure correct alignment of
	 * the timestamp if present
	 */
	struct {
		__le16 channels[3];
		s64 ts __aligned(8);
	} scan;
};

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

	ret = mma7455_drdy(mma7455);
	if (ret)
		goto done;

	ret = regmap_bulk_read(mma7455->regmap, MMA7455_REG_XOUTL, buf,
			       sizeof(__le16) * 3);
	ret = regmap_bulk_read(mma7455->regmap, MMA7455_REG_XOUTL,
			       mma7455->scan.channels,
			       sizeof(mma7455->scan.channels));
	if (ret)
		goto done;

	iio_push_to_buffers_with_timestamp(indio_dev, buf,
	iio_push_to_buffers_with_timestamp(indio_dev, &mma7455->scan,
					   iio_get_time_ns(indio_dev));

done:
+8 −3
Original line number Diff line number Diff line
@@ -110,6 +110,12 @@ struct mma8452_data {
	int sleep_val;
	struct regulator *vdd_reg;
	struct regulator *vddio_reg;

	/* Ensure correct alignment of time stamp when present */
	struct {
		__be16 channels[3];
		s64 ts __aligned(8);
	} buffer;
};

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

	ret = mma8452_read(data, (__be16 *)buffer);
	ret = mma8452_read(data, data->buffer.channels);
	if (ret < 0)
		goto done;

	iio_push_to_buffers_with_timestamp(indio_dev, buffer,
	iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer,
					   iio_get_time_ns(indio_dev));

done:
Loading