Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 97865fe4 authored by Linus Walleij's avatar Linus Walleij Committed by Jonathan Cameron
Browse files

iio: st_sensors: verify interrupt event to status



This makes all ST sensor drivers check that they actually have
new data available for the requested channel(s) before claiming
an IRQ, by reading the status register (which is conveniently
the same for all ST sensors) and check that the channel has new
data before proceeding to read it and fill the buffer.

This way sensors can share an interrupt line: it can be flaged
as shared and then the sensor that did not fire will return
NO_IRQ, and the sensor that fired will handle the IRQ and
return IRQ_HANDLED.

Cc: Giuseppe Barba <giuseppe.barba@st.com>
Cc: Denis Ciocca <denis.ciocca@st.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent 6436db37
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -332,6 +332,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
			.mask_int2 = ST_ACCEL_1_DRDY_IRQ_INT2_MASK,
			.addr_ihl = ST_ACCEL_1_IHL_IRQ_ADDR,
			.mask_ihl = ST_ACCEL_1_IHL_IRQ_MASK,
			.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
		},
		.multi_read_bit = ST_ACCEL_1_MULTIREAD_BIT,
		.bootime = 2,
@@ -397,6 +398,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
			.mask_int2 = ST_ACCEL_2_DRDY_IRQ_INT2_MASK,
			.addr_ihl = ST_ACCEL_2_IHL_IRQ_ADDR,
			.mask_ihl = ST_ACCEL_2_IHL_IRQ_MASK,
			.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
		},
		.multi_read_bit = ST_ACCEL_2_MULTIREAD_BIT,
		.bootime = 2,
@@ -474,6 +476,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
			.mask_int2 = ST_ACCEL_3_DRDY_IRQ_INT2_MASK,
			.addr_ihl = ST_ACCEL_3_IHL_IRQ_ADDR,
			.mask_ihl = ST_ACCEL_3_IHL_IRQ_MASK,
			.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
			.ig1 = {
				.en_addr = ST_ACCEL_3_IG1_EN_ADDR,
				.en_mask = ST_ACCEL_3_IG1_EN_MASK,
@@ -532,6 +535,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
		.drdy_irq = {
			.addr = ST_ACCEL_4_DRDY_IRQ_ADDR,
			.mask_int1 = ST_ACCEL_4_DRDY_IRQ_INT1_MASK,
			.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
		},
		.multi_read_bit = ST_ACCEL_4_MULTIREAD_BIT,
		.bootime = 2, /* guess */
@@ -583,6 +587,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
			.mask_int2 = ST_ACCEL_5_DRDY_IRQ_INT2_MASK,
			.addr_ihl = ST_ACCEL_5_IHL_IRQ_ADDR,
			.mask_ihl = ST_ACCEL_5_IHL_IRQ_MASK,
			.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
		},
		.multi_read_bit = ST_ACCEL_5_MULTIREAD_BIT,
		.bootime = 2, /* guess */
+18 −0
Original line number Diff line number Diff line
@@ -58,6 +58,24 @@ irqreturn_t st_sensors_trigger_handler(int irq, void *p)
	struct iio_dev *indio_dev = pf->indio_dev;
	struct st_sensor_data *sdata = iio_priv(indio_dev);

	/* If we have a status register, check if this IRQ came from us */
	if (sdata->sensor_settings->drdy_irq.addr_stat_drdy) {
		u8 status;

		len = sdata->tf->read_byte(&sdata->tb, sdata->dev,
			   sdata->sensor_settings->drdy_irq.addr_stat_drdy,
			   &status);
		if (len < 0)
			dev_err(sdata->dev, "could not read channel status\n");

		/*
		 * If this was not caused by any channels on this sensor,
		 * return IRQ_NONE
		 */
		if (!(status & (u8)indio_dev->active_scan_mask[0]))
			return IRQ_NONE;
	}

	len = st_sensors_get_buffer_element(indio_dev, sdata->buffer_data);
	if (len < 0)
		goto st_sensors_get_buffer_element_error;
+3 −0
Original line number Diff line number Diff line
@@ -190,6 +190,7 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = {
			 * drain settings, but only for INT1 and not
			 * for the DRDY line on INT2.
			 */
			.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
		},
		.multi_read_bit = ST_GYRO_1_MULTIREAD_BIT,
		.bootime = 2,
@@ -258,6 +259,7 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = {
			 * drain settings, but only for INT1 and not
			 * for the DRDY line on INT2.
			 */
			.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
		},
		.multi_read_bit = ST_GYRO_2_MULTIREAD_BIT,
		.bootime = 2,
@@ -322,6 +324,7 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = {
			 * drain settings, but only for INT1 and not
			 * for the DRDY line on INT2.
			 */
			.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
		},
		.multi_read_bit = ST_GYRO_3_MULTIREAD_BIT,
		.bootime = 2,
+1 −0
Original line number Diff line number Diff line
@@ -484,6 +484,7 @@ static const struct st_sensor_settings st_magn_sensors_settings[] = {
			.mask_int1 = ST_MAGN_3_DRDY_INT_MASK,
			.addr_ihl = ST_MAGN_3_IHL_IRQ_ADDR,
			.mask_ihl = ST_MAGN_3_IHL_IRQ_MASK,
			.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
		},
		.multi_read_bit = ST_MAGN_3_MULTIREAD_BIT,
		.bootime = 2,
+2 −0
Original line number Diff line number Diff line
@@ -226,6 +226,7 @@ static const struct st_sensor_settings st_press_sensors_settings[] = {
			.mask_int2 = ST_PRESS_LPS331AP_DRDY_IRQ_INT2_MASK,
			.addr_ihl = ST_PRESS_LPS331AP_IHL_IRQ_ADDR,
			.mask_ihl = ST_PRESS_LPS331AP_IHL_IRQ_MASK,
			.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
		},
		.multi_read_bit = ST_PRESS_LPS331AP_MULTIREAD_BIT,
		.bootime = 2,
@@ -312,6 +313,7 @@ static const struct st_sensor_settings st_press_sensors_settings[] = {
			.mask_int2 = ST_PRESS_LPS25H_DRDY_IRQ_INT2_MASK,
			.addr_ihl = ST_PRESS_LPS25H_IHL_IRQ_ADDR,
			.mask_ihl = ST_PRESS_LPS25H_IHL_IRQ_MASK,
			.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
		},
		.multi_read_bit = ST_PRESS_LPS25H_MULTIREAD_BIT,
		.bootime = 2,
Loading