[PATCH] HID: hid-sensor-hub: Optimize suspend/resume time

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When system suspend is issued, the pm core issues resume call for all
run time suspended devices. This is required for some devices to
continue suspend.
For sensor hub we don't need to runtime resume devices and then suspend.
So when the system suspend is in progress, ignore call to power up
the sensors. This has a significant impact on suspend/resume performance.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@xxxxxxxxxxxxxxx>
---
 .../iio/common/hid-sensors/hid-sensor-trigger.c    | 31 ++++++++++++++++++++++
 include/linux/hid-sensor-hub.h                     |  2 ++
 2 files changed, 33 insertions(+)

diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
index 610fc98..d9170d2 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
@@ -23,6 +23,7 @@
 #include <linux/irq.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/suspend.h>
 #include <linux/hid-sensor-hub.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/trigger.h>
@@ -36,6 +37,9 @@ static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
 	s32 poll_value = 0;
 
 	if (state) {
+		if (atomic_read(&st->suspend_in_progress))
+			return 0;
+
 		if (sensor_hub_device_open(st->hsdev))
 			return -EIO;
 
@@ -113,6 +117,28 @@ int hid_sensor_power_state(struct hid_sensor_common *st, bool state)
 #endif
 }
 
+static int hid_sensor_pm_notifier(struct notifier_block *nb, unsigned long val,
+				  void *ptr)
+{
+	struct hid_sensor_common *common =
+			container_of(nb, struct hid_sensor_common, pm_nb);
+
+	switch (val) {
+	case PM_HIBERNATION_PREPARE:
+	case PM_SUSPEND_PREPARE:
+		atomic_set(&common->suspend_in_progress, 1);
+		break;
+	case PM_POST_HIBERNATION:
+	case PM_POST_SUSPEND:
+	case PM_POST_RESTORE:
+		atomic_set(&common->suspend_in_progress, 0);
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
 static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
 						bool state)
 {
@@ -121,6 +147,7 @@ static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
 
 void hid_sensor_remove_trigger(struct hid_sensor_common *attrb)
 {
+	unregister_pm_notifier(&attrb->pm_nb);
 	iio_trigger_unregister(attrb->trigger);
 	iio_trigger_free(attrb->trigger);
 }
@@ -168,6 +195,10 @@ int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
 					 3000);
 	pm_runtime_use_autosuspend(&attrb->pdev->dev);
 
+	atomic_set(&attrb->suspend_in_progress, 0);
+	attrb->pm_nb.notifier_call = hid_sensor_pm_notifier;
+	register_pm_notifier(&attrb->pm_nb);
+
 	return ret;
 error_unreg_trigger:
 	iio_trigger_unregister(trig);
diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h
index 0042bf3..e38c72a 100644
--- a/include/linux/hid-sensor-hub.h
+++ b/include/linux/hid-sensor-hub.h
@@ -230,6 +230,8 @@ struct hid_sensor_common {
 	struct platform_device *pdev;
 	unsigned usage_id;
 	atomic_t data_ready;
+	atomic_t suspend_in_progress;
+	struct notifier_block pm_nb;
 	struct iio_trigger *trigger;
 	struct hid_sensor_hub_attribute_info poll;
 	struct hid_sensor_hub_attribute_info report_state;
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux