]> git.baikalelectronics.ru Git - kernel.git/commitdiff
iio: cros: Register FIFO callback after sensor is registered
authorGwendal Grignou <gwendal@chromium.org>
Mon, 11 Jul 2022 14:47:16 +0000 (07:47 -0700)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Mon, 18 Jul 2022 17:29:13 +0000 (18:29 +0100)
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: c17c81e4fdd4 ("iio: cros_ec: Register to cros_ec_sensorhub when EC supports FIFO")
Reported-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Link: https://lore.kernel.org/r/20220711144716.642617-1-gwendal@chromium.org
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/accel/cros_ec_accel_legacy.c
drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c
drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
drivers/iio/light/cros_ec_light_prox.c
drivers/iio/pressure/cros_ec_baro.c
include/linux/iio/common/cros_ec_sensors_core.h

index 1c0171f26e99e71a5bcf9ec70e1334369d3ef562..0f403342b1fc0d70ca3bb99117d86db7cd03c6ac 100644 (file)
@@ -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 = {
index 9f780fafaed9fcd2e07e574b6b27bc851ccb1061..119acb078af3bfdb33bcca905cc2e4822f92bbd6 100644 (file)
@@ -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[] = {
index 61e07a7bb19959c8764f06caf7b44eb130c5b266..66153b1850f109916d2ccb25f82d9977f2f0f24c 100644 (file)
@@ -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[] = {
index e5ccedef13a808089bcf38f800c9f790e45cf379..05a28d353e343b03d2b9785f2f517bc6a4270f5c 100644 (file)
@@ -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
index e345e0f71b7401f83a95efec6fcfcb46fe27f810..19e529c84e957a13f02b2a15a9fc1333d5308cc7 100644 (file)
@@ -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[] = {
index 25217279f35071eeb3bf198acf23c67a372f1f6d..2649c2f89e8982320dfa7bfb6340b3809fdeec24 100644 (file)
@@ -139,8 +139,7 @@ static int cros_ec_baro_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;
 
@@ -185,7 +184,8 @@ static int cros_ec_baro_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_baro_ids[] = {
index a8259c8822f56374a3dccaaf441f8d1e88db8952..e72167b96d27e77651c59c6d1e8de35ec4d3a3ba 100644 (file)
@@ -93,8 +93,11 @@ int cros_ec_sensors_read_cmd(struct iio_dev *indio_dev, unsigned long scan_mask,
 struct platform_device;
 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);
+
+int cros_ec_sensors_core_register(struct device *dev,
+                                 struct iio_dev *indio_dev,
+                                 cros_ec_sensorhub_push_data_cb_t push_data);
 
 irqreturn_t cros_ec_sensors_capture(int irq, void *p);
 int cros_ec_sensors_push_data(struct iio_dev *indio_dev,