]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
platform/chrome: Resolve kb_wake_angle visibility race
authorTzung-Bi Shih <tzungbi@kernel.org>
Tue, 7 Apr 2026 10:26:15 +0000 (10:26 +0000)
committerTzung-Bi Shih <tzungbi@kernel.org>
Mon, 11 May 2026 03:09:30 +0000 (03:09 +0000)
A race condition exists between the probe of cros-ec-sysfs and
cros-ec-sensorhub.

The `kb_wake_angle` attribute should only be visible if the sensor hub
detects two or more accelerometers.  If cros_ec_sysfs_probe() runs
before cros_ec_sensorhub_register() completes sensor enumeration, the
sysfs attributes are created while `has_kb_wake_angle` is still false,
hiding `kb_wake_angle` incorrectly.

Store the created attribute group pointer in `ec_dev->group`.  When
the sensor hub completes sensor enumeration, it checks for this group
and calls sysfs_update_group() to notify the sysfs core to re-evaluate
attribute visibility.  This ensures the `kb_wake_angle` attribute
visibility is correctly updated regardless of the driver probe order.

Co-developed-by: Gwendal Grignou <gwendal@chromium.org>
Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
Link: https://lore.kernel.org/r/20260407102615.1605317-1-tzungbi@kernel.org
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
drivers/platform/chrome/cros_ec_sensorhub.c
drivers/platform/chrome/cros_ec_sysfs.c
include/linux/platform_data/cros_ec_proto.h

index 9bad8f72680ea81031838247a2b065fe8e7981d3..f938c3fc84e4f8c1da8c7864ae55bcf2b965fce1 100644 (file)
@@ -122,8 +122,12 @@ static int cros_ec_sensorhub_register(struct device *dev,
                sensor_type[sensorhub->resp->info.type]++;
        }
 
-       if (sensor_type[MOTIONSENSE_TYPE_ACCEL] >= 2)
+       if (sensor_type[MOTIONSENSE_TYPE_ACCEL] >= 2) {
                ec->has_kb_wake_angle = true;
+               if (ec->group && sysfs_update_group(&ec->class_dev.kobj,
+                                                   ec->group))
+                       dev_warn(dev, "Unable to update sysfs");
+       }
 
        if (cros_ec_check_features(ec,
                                   EC_FEATURE_REFINED_TABLET_MODE_HYSTERESIS)) {
index f22e9523da3e8a8d88d755bd520be85eeea554b1..9d3767ab15480be3eb69054eda66a137201f15c5 100644 (file)
@@ -405,7 +405,8 @@ static int cros_ec_sysfs_probe(struct platform_device *pd)
        struct device *dev = &pd->dev;
        int ret;
 
-       ret = sysfs_create_group(&ec_dev->class_dev.kobj, &cros_ec_attr_group);
+       ec_dev->group = &cros_ec_attr_group;
+       ret = sysfs_create_group(&ec_dev->class_dev.kobj, ec_dev->group);
        if (ret < 0)
                dev_err(dev, "failed to create attributes. err=%d\n", ret);
 
@@ -416,7 +417,7 @@ static void cros_ec_sysfs_remove(struct platform_device *pd)
 {
        struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent);
 
-       sysfs_remove_group(&ec_dev->class_dev.kobj, &cros_ec_attr_group);
+       sysfs_remove_group(&ec_dev->class_dev.kobj, ec_dev->group);
 }
 
 static const struct platform_device_id cros_ec_sysfs_id[] = {
index de14923720a53f0164b3e9a3ff9ff7e1f3bf6133..6ed1c4c5ce2ef315df31911226eeb2bc9fc5ef1c 100644 (file)
@@ -228,6 +228,7 @@ struct cros_ec_platform {
 /**
  * struct cros_ec_dev - ChromeOS EC device entry point.
  * @class_dev: Device structure used in sysfs.
+ * @group: sysfs attributes groups for this EC.
  * @ec_dev: cros_ec_device structure to talk to the physical device.
  * @dev: Pointer to the platform device.
  * @debug_info: cros_ec_debugfs structure for debugging information.
@@ -237,6 +238,7 @@ struct cros_ec_platform {
  */
 struct cros_ec_dev {
        struct device class_dev;
+       const struct attribute_group *group;
        struct cros_ec_device *ec_dev;
        struct device *dev;
        struct cros_ec_debugfs *debug_info;