diff options
-rw-r--r-- | drivers/platform/x86/amd/pmf/acpi.c | 34 | ||||
-rw-r--r-- | drivers/platform/x86/amd/pmf/core.c | 1 | ||||
-rw-r--r-- | drivers/platform/x86/amd/pmf/pmf.h | 5 |
3 files changed, 38 insertions, 2 deletions
diff --git a/drivers/platform/x86/amd/pmf/acpi.c b/drivers/platform/x86/amd/pmf/acpi.c index 5997ab724f3a..6af0e23257ea 100644 --- a/drivers/platform/x86/amd/pmf/acpi.c +++ b/drivers/platform/x86/amd/pmf/acpi.c @@ -103,6 +103,22 @@ int apmf_get_static_slider_granular(struct amd_pmf_dev *pdev, data, sizeof(*data)); } +static void apmf_sbios_heartbeat_notify(struct work_struct *work) +{ + struct amd_pmf_dev *dev = container_of(work, struct amd_pmf_dev, heart_beat.work); + union acpi_object *info; + + dev_dbg(dev->dev, "Sending heartbeat to SBIOS\n"); + info = apmf_if_call(dev, APMF_FUNC_SBIOS_HEARTBEAT, NULL); + if (!info) + goto out; + + schedule_delayed_work(&dev->heart_beat, msecs_to_jiffies(dev->hb_interval * 1000)); + +out: + kfree(info); +} + static int apmf_if_verify_interface(struct amd_pmf_dev *pdev) { struct apmf_verify_interface output; @@ -131,15 +147,23 @@ static int apmf_get_system_params(struct amd_pmf_dev *dev) if (err) return err; - dev_dbg(dev->dev, "system params mask:0x%x flags:0x%x cmd_code:0x%x\n", + dev_dbg(dev->dev, "system params mask:0x%x flags:0x%x cmd_code:0x%x heartbeat:%d\n", params.valid_mask, params.flags, - params.command_code); + params.command_code, + params.heartbeat_int); params.flags = params.flags & params.valid_mask; + dev->hb_interval = params.heartbeat_int; return 0; } +void apmf_acpi_deinit(struct amd_pmf_dev *pmf_dev) +{ + if (pmf_dev->hb_interval) + cancel_delayed_work_sync(&pmf_dev->heart_beat); +} + int apmf_acpi_init(struct amd_pmf_dev *pmf_dev) { int ret; @@ -156,6 +180,12 @@ int apmf_acpi_init(struct amd_pmf_dev *pmf_dev) goto out; } + if (pmf_dev->hb_interval) { + /* 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); + } + out: return ret; } diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c index 032d9dc5e09f..87a1f9b27d2c 100644 --- a/drivers/platform/x86/amd/pmf/core.c +++ b/drivers/platform/x86/amd/pmf/core.c @@ -279,6 +279,7 @@ static int amd_pmf_remove(struct platform_device *pdev) mutex_destroy(&dev->lock); amd_pmf_deinit_features(dev); + apmf_acpi_deinit(dev); amd_pmf_dbgfs_unregister(dev); kfree(dev->buf); return 0; diff --git a/drivers/platform/x86/amd/pmf/pmf.h b/drivers/platform/x86/amd/pmf/pmf.h index 8b25fd19e473..e3a21e4e1c9b 100644 --- a/drivers/platform/x86/amd/pmf/pmf.h +++ b/drivers/platform/x86/amd/pmf/pmf.h @@ -17,6 +17,7 @@ /* APMF Functions */ #define APMF_FUNC_VERIFY_INTERFACE 0 #define APMF_FUNC_GET_SYS_PARAMS 1 +#define APMF_FUNC_SBIOS_HEARTBEAT 4 #define APMF_FUNC_STATIC_SLIDER_GRANULAR 9 /* Message Definitions */ @@ -53,6 +54,7 @@ struct apmf_system_params { u32 valid_mask; u32 flags; u8 command_code; + u32 heartbeat_int; } __packed; enum amd_stt_skin_temp { @@ -91,6 +93,8 @@ struct amd_pmf_dev { enum platform_profile_option current_profile; struct platform_profile_handler pprof; struct dentry *dbgfs_dir; + int hb_interval; /* SBIOS heartbeat interval */ + struct delayed_work heart_beat; }; struct apmf_sps_prop_granular { @@ -116,6 +120,7 @@ struct amd_pmf_static_slider_granular { /* Core Layer */ int apmf_acpi_init(struct amd_pmf_dev *pmf_dev); +void apmf_acpi_deinit(struct amd_pmf_dev *pmf_dev); int is_apmf_func_supported(struct amd_pmf_dev *pdev, unsigned long index); int amd_pmf_send_cmd(struct amd_pmf_dev *dev, u8 message, bool get, u32 arg, u32 *data); int amd_pmf_get_power_source(void); |