mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
platform/chrome: Resolve kb_wake_angle visibility race
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>
This commit is contained in:
parent
5d6919055d
commit
c40f5f9927
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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[] = {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user