Skip to content

Commit f1664ea

Browse files
spandruvadajic23
authored andcommitted
iio: hid-sensor-trigger: Fix the race with user space powering up sensors
It has been reported for a while that with iio-sensor-proxy service the rotation only works after one suspend/resume cycle. This required a wait in the systemd unit file to avoid race. I found a Yoga 900 where I could reproduce this. The problem scenerio is: - During sensor driver init, enable run time PM and also set a auto-suspend for 3 seconds. This result in one runtime resume. But there is a check to avoid a powerup in this sequence, but rpm is active - User space iio-sensor-proxy tries to power up the sensor. Since rpm is active it will simply return. But sensors were not actually powered up in the prior sequence, so actaully the sensors will not work - After 3 seconds the auto suspend kicks If we add a wait in systemd service file to fire iio-sensor-proxy after 3 seconds, then now everything will work as the runtime resume will actually powerup the sensor as this is a user request. To avoid this: - Remove the check to match user requested state, this will cause a brief powerup, but if the iio-sensor-proxy starts immediately it will still work as the sensors are ON. - Also move the autosuspend delay to place when user requested turn off of sensors, like after user finished raw read or buffer disable Signed-off-by: Srinivas Pandruvada <[email protected]> Tested-by: Bastien Nocera <[email protected]> Cc: <[email protected]> Signed-off-by: Jonathan Cameron <[email protected]>
1 parent a359bb2 commit f1664ea

File tree

1 file changed

+4
-4
lines changed

1 file changed

+4
-4
lines changed

drivers/iio/common/hid-sensors/hid-sensor-trigger.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,6 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
111111
s32 poll_value = 0;
112112

113113
if (state) {
114-
if (!atomic_read(&st->user_requested_state))
115-
return 0;
116114
if (sensor_hub_device_open(st->hsdev))
117115
return -EIO;
118116

@@ -161,6 +159,9 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
161159
&report_val);
162160
}
163161

162+
pr_debug("HID_SENSOR %s set power_state %d report_state %d\n",
163+
st->pdev->name, state_val, report_val);
164+
164165
sensor_hub_get_feature(st->hsdev, st->power_state.report_id,
165166
st->power_state.index,
166167
sizeof(state_val), &state_val);
@@ -182,6 +183,7 @@ int hid_sensor_power_state(struct hid_sensor_common *st, bool state)
182183
ret = pm_runtime_get_sync(&st->pdev->dev);
183184
else {
184185
pm_runtime_mark_last_busy(&st->pdev->dev);
186+
pm_runtime_use_autosuspend(&st->pdev->dev);
185187
ret = pm_runtime_put_autosuspend(&st->pdev->dev);
186188
}
187189
if (ret < 0) {
@@ -285,8 +287,6 @@ int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
285287
/* Default to 3 seconds, but can be changed from sysfs */
286288
pm_runtime_set_autosuspend_delay(&attrb->pdev->dev,
287289
3000);
288-
pm_runtime_use_autosuspend(&attrb->pdev->dev);
289-
290290
return ret;
291291
error_unreg_trigger:
292292
iio_trigger_unregister(trig);

0 commit comments

Comments
 (0)