Commit 0b4ae3f6 authored by Gwendal Grignou's avatar Gwendal Grignou Committed by Jonathan Cameron
Browse files

iio: cros: Register FIFO callback after sensor is registered



Instead of registering callback to process sensor events right at
initialization time, wait for the sensor to be register in the iio
subsystem.

Events can come at probe time (in case the kernel rebooted abruptly
without switching the sensor off for  instance), and be sent to IIO core
before the sensor is fully registered.

Fixes: aa984f1b ("iio: cros_ec: Register to cros_ec_sensorhub when EC supports FIFO")
Reported-by: default avatarDouglas Anderson <dianders@chromium.org>
Signed-off-by: default avatarGwendal Grignou <gwendal@chromium.org>
Reviewed-by: default avatarDouglas Anderson <dianders@chromium.org>
Link: https://lore.kernel.org/r/20220711144716.642617-1-gwendal@chromium.org


Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 0565d238
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -215,7 +215,7 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev)
		return -ENOMEM;

	ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
					cros_ec_sensors_capture, NULL);
					cros_ec_sensors_capture);
	if (ret)
		return ret;

@@ -235,7 +235,7 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev)
		state->sign[CROS_EC_SENSOR_Z] = -1;
	}

	return devm_iio_device_register(dev, indio_dev);
	return cros_ec_sensors_core_register(dev, indio_dev, NULL);
}

static struct platform_driver cros_ec_accel_platform_driver = {
+2 −2
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ static int cros_ec_lid_angle_probe(struct platform_device *pdev)
	if (!indio_dev)
		return -ENOMEM;

	ret = cros_ec_sensors_core_init(pdev, indio_dev, false, NULL, NULL);
	ret = cros_ec_sensors_core_init(pdev, indio_dev, false, NULL);
	if (ret)
		return ret;

@@ -114,7 +114,7 @@ static int cros_ec_lid_angle_probe(struct platform_device *pdev)
	if (ret)
		return ret;

	return devm_iio_device_register(dev, indio_dev);
	return cros_ec_sensors_core_register(dev, indio_dev, NULL);
}

static const struct platform_device_id cros_ec_lid_angle_ids[] = {
+3 −3
Original line number Diff line number Diff line
@@ -236,8 +236,7 @@ static int cros_ec_sensors_probe(struct platform_device *pdev)
		return -ENOMEM;

	ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
					cros_ec_sensors_capture,
					cros_ec_sensors_push_data);
					cros_ec_sensors_capture);
	if (ret)
		return ret;

@@ -298,7 +297,8 @@ static int cros_ec_sensors_probe(struct platform_device *pdev)
	else
		state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;

	return devm_iio_device_register(dev, indio_dev);
	return cros_ec_sensors_core_register(dev, indio_dev,
			cros_ec_sensors_push_data);
}

static const struct platform_device_id cros_ec_sensors_ids[] = {
+42 −16
Original line number Diff line number Diff line
@@ -228,21 +228,18 @@ static void cros_ec_sensors_core_clean(void *arg)

/**
 * cros_ec_sensors_core_init() - basic initialization of the core structure
 * @pdev:		platform device created for the sensors
 * @pdev:		platform device created for the sensor
 * @indio_dev:		iio device structure of the device
 * @physical_device:	true if the device refers to a physical device
 * @trigger_capture:    function pointer to call buffer is triggered,
 *    for backward compatibility.
 * @push_data:          function to call when cros_ec_sensorhub receives
 *    a sample for that sensor.
 *
 * Return: 0 on success, -errno on failure.
 */
int cros_ec_sensors_core_init(struct platform_device *pdev,
			      struct iio_dev *indio_dev,
			      bool physical_device,
			      cros_ec_sensors_capture_t trigger_capture,
			      cros_ec_sensorhub_push_data_cb_t push_data)
			      cros_ec_sensors_capture_t trigger_capture)
{
	struct device *dev = &pdev->dev;
	struct cros_ec_sensors_core_state *state = iio_priv(indio_dev);
@@ -340,17 +337,6 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
			if (ret)
				return ret;

			ret = cros_ec_sensorhub_register_push_data(
					sensor_hub, sensor_platform->sensor_num,
					indio_dev, push_data);
			if (ret)
				return ret;

			ret = devm_add_action_or_reset(
					dev, cros_ec_sensors_core_clean, pdev);
			if (ret)
				return ret;

			/* Timestamp coming from FIFO are in ns since boot. */
			ret = iio_device_set_clock(indio_dev, CLOCK_BOOTTIME);
			if (ret)
@@ -372,6 +358,46 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
}
EXPORT_SYMBOL_GPL(cros_ec_sensors_core_init);

/**
 * cros_ec_sensors_core_register() - Register callback to FIFO and IIO when
 * sensor is ready.
 * It must be called at the end of the sensor probe routine.
 * @dev:		device created for the sensor
 * @indio_dev:		iio device structure of the device
 * @push_data:          function to call when cros_ec_sensorhub receives
 *    a sample for that sensor.
 *
 * Return: 0 on success, -errno on failure.
 */
int cros_ec_sensors_core_register(struct device *dev,
				  struct iio_dev *indio_dev,
				  cros_ec_sensorhub_push_data_cb_t push_data)
{
	struct cros_ec_sensor_platform *sensor_platform = dev_get_platdata(dev);
	struct cros_ec_sensorhub *sensor_hub = dev_get_drvdata(dev->parent);
	struct platform_device *pdev = to_platform_device(dev);
	struct cros_ec_dev *ec = sensor_hub->ec;
	int ret;

	ret = devm_iio_device_register(dev, indio_dev);
	if (ret)
		return ret;

	if (!push_data ||
	    !cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO))
		return 0;

	ret = cros_ec_sensorhub_register_push_data(
			sensor_hub, sensor_platform->sensor_num,
			indio_dev, push_data);
	if (ret)
		return ret;

	return devm_add_action_or_reset(
			dev, cros_ec_sensors_core_clean, pdev);
}
EXPORT_SYMBOL_GPL(cros_ec_sensors_core_register);

/**
 * cros_ec_motion_send_host_cmd() - send motion sense host command
 * @state:		pointer to state information for device
+3 −3
Original line number Diff line number Diff line
@@ -182,8 +182,7 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev)
		return -ENOMEM;

	ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
					cros_ec_sensors_capture,
					cros_ec_sensors_push_data);
					cros_ec_sensors_capture);
	if (ret)
		return ret;

@@ -239,7 +238,8 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev)

	state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;

	return devm_iio_device_register(dev, indio_dev);
	return cros_ec_sensors_core_register(dev, indio_dev,
					     cros_ec_sensors_push_data);
}

static const struct platform_device_id cros_ec_light_prox_ids[] = {
Loading