diff options
Diffstat (limited to 'drivers/platform')
-rw-r--r-- | drivers/platform/x86/amd/pmf/acpi.c | 41 | ||||
-rw-r--r-- | drivers/platform/x86/amd/pmf/core.c | 10 | ||||
-rw-r--r-- | drivers/platform/x86/amd/pmf/pmf.h | 17 |
3 files changed, 66 insertions, 2 deletions
diff --git a/drivers/platform/x86/amd/pmf/acpi.c b/drivers/platform/x86/amd/pmf/acpi.c index 13af83b187ac..f0360eea81e6 100644 --- a/drivers/platform/x86/amd/pmf/acpi.c +++ b/drivers/platform/x86/amd/pmf/acpi.c @@ -140,6 +140,43 @@ static void apmf_sbios_heartbeat_notify(struct work_struct *work) kfree(info); } +int amd_pmf_notify_sbios_heartbeat_event_v2(struct amd_pmf_dev *dev, u8 flag) +{ + struct sbios_hb_event_v2 args = { }; + struct acpi_buffer params; + union acpi_object *info; + + args.size = sizeof(args); + + switch (flag) { + case ON_LOAD: + args.load = 1; + break; + case ON_UNLOAD: + args.unload = 1; + break; + case ON_SUSPEND: + args.suspend = 1; + break; + case ON_RESUME: + args.resume = 1; + break; + default: + dev_dbg(dev->dev, "Failed to send v2 heartbeat event, flag:0x%x\n", flag); + return -EINVAL; + } + + params.length = sizeof(args); + params.pointer = &args; + + info = apmf_if_call(dev, APMF_FUNC_SBIOS_HEARTBEAT_V2, ¶ms); + if (!info) + return -EIO; + + kfree(info); + return 0; +} + int apmf_update_fan_idx(struct amd_pmf_dev *pdev, bool manual, u32 idx) { union acpi_object *info; @@ -327,7 +364,7 @@ void apmf_acpi_deinit(struct amd_pmf_dev *pmf_dev) { acpi_handle ahandle = ACPI_HANDLE(pmf_dev->dev); - if (pmf_dev->hb_interval) + if (pmf_dev->hb_interval && pmf_dev->pmf_if_version == PMF_IF_V1) cancel_delayed_work_sync(&pmf_dev->heart_beat); if (is_apmf_func_supported(pmf_dev, APMF_FUNC_AUTO_MODE) && @@ -351,7 +388,7 @@ int apmf_acpi_init(struct amd_pmf_dev *pmf_dev) goto out; } - if (pmf_dev->hb_interval) { + if (pmf_dev->hb_interval && pmf_dev->pmf_if_version == PMF_IF_V1) { /* send heartbeats only if the interval is not zero */ INIT_DELAYED_WORK(&pmf_dev->heart_beat, apmf_sbios_heartbeat_notify); schedule_delayed_work(&pmf_dev->heart_beat, 0); diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c index a6bdde4f1c68..53c0f61e5c5f 100644 --- a/drivers/platform/x86/amd/pmf/core.c +++ b/drivers/platform/x86/amd/pmf/core.c @@ -299,6 +299,9 @@ static int amd_pmf_suspend_handler(struct device *dev) kfree(pdev->buf); + if (is_apmf_func_supported(pdev, APMF_FUNC_SBIOS_HEARTBEAT_V2)) + amd_pmf_notify_sbios_heartbeat_event_v2(pdev, ON_SUSPEND); + return 0; } @@ -313,6 +316,9 @@ static int amd_pmf_resume_handler(struct device *dev) return ret; } + if (is_apmf_func_supported(pdev, APMF_FUNC_SBIOS_HEARTBEAT_V2)) + amd_pmf_notify_sbios_heartbeat_event_v2(pdev, ON_RESUME); + return 0; } @@ -435,6 +441,8 @@ static int amd_pmf_probe(struct platform_device *pdev) amd_pmf_dbgfs_register(dev); amd_pmf_init_features(dev); apmf_install_handler(dev); + if (is_apmf_func_supported(dev, APMF_FUNC_SBIOS_HEARTBEAT_V2)) + amd_pmf_notify_sbios_heartbeat_event_v2(dev, ON_LOAD); dev_info(dev->dev, "registered PMF device successfully\n"); @@ -446,6 +454,8 @@ static void amd_pmf_remove(struct platform_device *pdev) struct amd_pmf_dev *dev = platform_get_drvdata(pdev); amd_pmf_deinit_features(dev); + if (is_apmf_func_supported(dev, APMF_FUNC_SBIOS_HEARTBEAT_V2)) + amd_pmf_notify_sbios_heartbeat_event_v2(dev, ON_UNLOAD); apmf_acpi_deinit(dev); amd_pmf_dbgfs_unregister(dev); mutex_destroy(&dev->lock); diff --git a/drivers/platform/x86/amd/pmf/pmf.h b/drivers/platform/x86/amd/pmf/pmf.h index aeaaff290bff..bcd1ae71109e 100644 --- a/drivers/platform/x86/amd/pmf/pmf.h +++ b/drivers/platform/x86/amd/pmf/pmf.h @@ -34,6 +34,7 @@ struct cookie_header { #define APMF_FUNC_STATIC_SLIDER_GRANULAR 9 #define APMF_FUNC_DYN_SLIDER_AC 11 #define APMF_FUNC_DYN_SLIDER_DC 12 +#define APMF_FUNC_SBIOS_HEARTBEAT_V2 16 /* Message Definitions */ #define SET_SPL 0x03 /* SPL: Sustained Power Limit */ @@ -89,6 +90,21 @@ struct cookie_header { #define PMF_IF_V1 1 +struct sbios_hb_event_v2 { + u16 size; + u8 load; + u8 unload; + u8 suspend; + u8 resume; +} __packed; + +enum sbios_hb_v2 { + ON_LOAD, + ON_UNLOAD, + ON_SUSPEND, + ON_RESUME, +}; + /* AMD PMF BIOS interfaces */ struct apmf_verify_interface { u16 size; @@ -609,6 +625,7 @@ int amd_pmf_get_power_source(void); int apmf_install_handler(struct amd_pmf_dev *pmf_dev); int apmf_os_power_slider_update(struct amd_pmf_dev *dev, u8 flag); int amd_pmf_set_dram_addr(struct amd_pmf_dev *dev, bool alloc_buffer); +int amd_pmf_notify_sbios_heartbeat_event_v2(struct amd_pmf_dev *dev, u8 flag); /* SPS Layer */ int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf); |