Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: hid-sensor: Store restore poll and hysteresis on S3

This change undo the change done by 'commit 3bec24747446
("iio: hid-sensor-trigger: Change get poll value function order to avoid
sensor properties losing after resume from S3")' as this breaks some
USB/i2c sensor hubs.

Instead of relying on HW for restoring poll and hysteresis, driver stores
and restores on resume (S3). In this way user space modified settings are
not lost for any kind of sensor hub behavior.

In this change, whenever user space modifies sampling frequency or
hysteresis driver will get the feature value from the hub and store in the
per device hid_sensor_common data structure. On resume callback from S3,
system will set the feature to sensor hub, if user space ever modified the
feature value.

Fixes: 3bec24747446 ("iio: hid-sensor-trigger: Change get poll value function order to avoid sensor properties losing after resume from S3")
Reported-by: Ritesh Raj Sarraf <rrs@researchut.com>
Tested-by: Ritesh Raj Sarraf <rrs@researchut.com>
Tested-by: Song, Hongyan <hongyan.song@intel.com>
Cc: stable@vger.kernel.org
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>

authored by

Srinivas Pandruvada and committed by
Jonathan Cameron
5d9854ea a6d36140

+43 -5
+24 -2
drivers/iio/common/hid-sensors/hid-sensor-attributes.c
··· 221 221 if (ret < 0 || value < 0) 222 222 ret = -EINVAL; 223 223 224 - return ret; 224 + ret = sensor_hub_get_feature(st->hsdev, 225 + st->poll.report_id, 226 + st->poll.index, sizeof(value), &value); 227 + if (ret < 0 || value < 0) 228 + return -EINVAL; 229 + 230 + st->poll_interval = value; 231 + 232 + return 0; 225 233 } 226 234 EXPORT_SYMBOL(hid_sensor_write_samp_freq_value); 227 235 ··· 274 266 if (ret < 0 || value < 0) 275 267 ret = -EINVAL; 276 268 277 - return ret; 269 + ret = sensor_hub_get_feature(st->hsdev, 270 + st->sensitivity.report_id, 271 + st->sensitivity.index, sizeof(value), 272 + &value); 273 + if (ret < 0 || value < 0) 274 + return -EINVAL; 275 + 276 + st->raw_hystersis = value; 277 + 278 + return 0; 278 279 } 279 280 EXPORT_SYMBOL(hid_sensor_write_raw_hyst_value); 280 281 ··· 386 369 /* Default unit of measure is milliseconds */ 387 370 if (st->poll.units == 0) 388 371 st->poll.units = HID_USAGE_SENSOR_UNITS_MILLISECOND; 372 + 373 + st->poll_interval = -1; 374 + 389 375 return 0; 390 376 391 377 } ··· 418 398 HID_FEATURE_REPORT, usage_id, 419 399 HID_USAGE_SENSOR_PROP_SENSITIVITY_ABS, 420 400 &st->sensitivity); 401 + 402 + st->raw_hystersis = -1; 421 403 422 404 sensor_hub_input_get_attribute_info(hsdev, 423 405 HID_INPUT_REPORT, usage_id,
+17 -3
drivers/iio/common/hid-sensors/hid-sensor-trigger.c
··· 51 51 st->report_state.report_id, 52 52 st->report_state.index, 53 53 HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM); 54 + 55 + poll_value = hid_sensor_read_poll_value(st); 54 56 } else { 55 57 int val; 56 58 ··· 89 87 sensor_hub_get_feature(st->hsdev, st->power_state.report_id, 90 88 st->power_state.index, 91 89 sizeof(state_val), &state_val); 92 - if (state) 93 - poll_value = hid_sensor_read_poll_value(st); 94 - if (poll_value > 0) 90 + if (state && poll_value) 95 91 msleep_interruptible(poll_value * 2); 96 92 97 93 return 0; ··· 127 127 struct hid_sensor_common *attrb = container_of(work, 128 128 struct hid_sensor_common, 129 129 work); 130 + 131 + if (attrb->poll_interval >= 0) 132 + sensor_hub_set_feature(attrb->hsdev, attrb->poll.report_id, 133 + attrb->poll.index, 134 + sizeof(attrb->poll_interval), 135 + &attrb->poll_interval); 136 + 137 + if (attrb->raw_hystersis >= 0) 138 + sensor_hub_set_feature(attrb->hsdev, 139 + attrb->sensitivity.report_id, 140 + attrb->sensitivity.index, 141 + sizeof(attrb->raw_hystersis), 142 + &attrb->raw_hystersis); 143 + 130 144 _hid_sensor_power_state(attrb, true); 131 145 } 132 146
+2
include/linux/hid-sensor-hub.h
··· 231 231 unsigned usage_id; 232 232 atomic_t data_ready; 233 233 atomic_t user_requested_state; 234 + int poll_interval; 235 + int raw_hystersis; 234 236 struct iio_trigger *trigger; 235 237 int timestamp_ns_scale; 236 238 struct hid_sensor_hub_attribute_info poll;