[PATCH 2/7][SRU][OEM-5.14] HID: amd_sfh: Add support for PM suspend and resume
Alex Hung
alex.hung at canonical.com
Mon Feb 21 05:52:52 UTC 2022
From: Basavaraj Natikar <Basavaraj.Natikar at amd.com>
BugLink: https://bugs.launchpad.net/bugs/1961121
Add support for power management routines.
Reviewed-by: Shyam Sundar S K <Shyam-sundar.S-k at amd.com>
Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar at amd.com>
Signed-off-by: Jiri Kosina <jkosina at suse.cz>
(cherry picked from commit 0873d1afacd2167e717ea751fe7274011cb4c26a)
Signed-off-by: Alex Hung <alex.hung at canonical.com>
---
drivers/hid/amd-sfh-hid/amd_sfh_client.c | 1 -
drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 49 ++++++++++++++++++++++++++++++++
drivers/hid/amd-sfh-hid/amd_sfh_pcie.h | 5 ++++
3 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
index b7b66a1..e8aabde 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
@@ -17,7 +17,6 @@
#include "amd_sfh_pcie.h"
#include "amd_sfh_hid.h"
-#define AMD_SFH_IDLE_LOOP 200
struct request_list {
struct hid_device *hid;
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
index ef2df3b..2a40f32a 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
@@ -264,6 +264,54 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
return devm_add_action_or_reset(&pdev->dev, amd_mp2_pci_remove, privdata);
}
+static int __maybe_unused amd_mp2_pci_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct amd_mp2_dev *mp2 = pci_get_drvdata(pdev);
+ struct amdtp_cl_data *cl_data = mp2->cl_data;
+ struct amd_mp2_sensor_info info;
+ int i, status;
+
+ for (i = 0; i < cl_data->num_hid_devices; i++) {
+ if (cl_data->sensor_sts[i] == SENSOR_DISABLED) {
+ info.period = AMD_SFH_IDLE_LOOP;
+ info.sensor_idx = cl_data->sensor_idx[i];
+ info.dma_address = cl_data->sensor_dma_addr[i];
+ mp2->mp2_ops->start(mp2, info);
+ status = amd_sfh_wait_for_response
+ (mp2, cl_data->sensor_idx[i], SENSOR_ENABLED);
+ if (status == SENSOR_ENABLED)
+ cl_data->sensor_sts[i] = SENSOR_ENABLED;
+ }
+ }
+
+ return 0;
+}
+
+static int __maybe_unused amd_mp2_pci_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct amd_mp2_dev *mp2 = pci_get_drvdata(pdev);
+ struct amdtp_cl_data *cl_data = mp2->cl_data;
+ int i, status;
+
+ for (i = 0; i < cl_data->num_hid_devices; i++) {
+ if (cl_data->sensor_idx[i] != HPD_IDX &&
+ cl_data->sensor_sts[i] == SENSOR_ENABLED) {
+ mp2->mp2_ops->stop(mp2, cl_data->sensor_idx[i]);
+ status = amd_sfh_wait_for_response
+ (mp2, cl_data->sensor_idx[i], SENSOR_DISABLED);
+ if (status != SENSOR_ENABLED)
+ cl_data->sensor_sts[i] = SENSOR_DISABLED;
+ }
+ }
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(amd_mp2_pm_ops, amd_mp2_pci_suspend,
+ amd_mp2_pci_resume);
+
static const struct pci_device_id amd_mp2_pci_tbl[] = {
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_MP2) },
{ }
@@ -274,6 +322,7 @@ static struct pci_driver amd_mp2_pci_driver = {
.name = DRIVER_NAME,
.id_table = amd_mp2_pci_tbl,
.probe = amd_mp2_pci_probe,
+ .driver.pm = &amd_mp2_pm_ops,
};
module_pci_driver(amd_mp2_pci_driver);
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
index 21ef55d..1ff6f83 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
@@ -36,6 +36,8 @@
#define HPD_IDX 16
+#define AMD_SFH_IDLE_LOOP 200
+
/* SFH Command register */
union sfh_cmd_base {
u32 ul;
@@ -129,6 +131,9 @@ void amd_stop_all_sensors(struct amd_mp2_dev *privdata);
int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id);
int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata);
int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata);
+u32 amd_sfh_wait_for_response(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts);
+void amd_mp2_suspend(struct amd_mp2_dev *mp2);
+void amd_mp2_resume(struct amd_mp2_dev *mp2);
struct amd_mp2_ops {
void (*start)(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info);
--
2.7.4
More information about the kernel-team
mailing list