diff options
Diffstat (limited to 'drivers/platform/x86/amd/pmf/acpi.c')
-rw-r--r-- | drivers/platform/x86/amd/pmf/acpi.c | 56 |
1 files changed, 43 insertions, 13 deletions
diff --git a/drivers/platform/x86/amd/pmf/acpi.c b/drivers/platform/x86/amd/pmf/acpi.c index 3fc5e4547d9f..f2eb07ef855a 100644 --- a/drivers/platform/x86/amd/pmf/acpi.c +++ b/drivers/platform/x86/amd/pmf/acpi.c @@ -111,7 +111,6 @@ int apmf_os_power_slider_update(struct amd_pmf_dev *pdev, u8 event) struct os_power_slider args; struct acpi_buffer params; union acpi_object *info; - int err = 0; args.size = sizeof(args); args.slider_event = event; @@ -121,10 +120,10 @@ int apmf_os_power_slider_update(struct amd_pmf_dev *pdev, u8 event) info = apmf_if_call(pdev, APMF_FUNC_OS_POWER_SLIDER_UPDATE, ¶ms); if (!info) - err = -EIO; + return -EIO; kfree(info); - return err; + return 0; } static void apmf_sbios_heartbeat_notify(struct work_struct *work) @@ -135,11 +134,9 @@ static void apmf_sbios_heartbeat_notify(struct work_struct *work) dev_dbg(dev->dev, "Sending heartbeat to SBIOS\n"); info = apmf_if_call(dev, APMF_FUNC_SBIOS_HEARTBEAT, NULL); if (!info) - goto out; + return; schedule_delayed_work(&dev->heart_beat, msecs_to_jiffies(dev->hb_interval * 1000)); - -out: kfree(info); } @@ -148,7 +145,6 @@ int apmf_update_fan_idx(struct amd_pmf_dev *pdev, bool manual, u32 idx) union acpi_object *info; struct apmf_fan_idx args; struct acpi_buffer params; - int err = 0; args.size = sizeof(args); args.fan_ctl_mode = manual; @@ -158,14 +154,11 @@ int apmf_update_fan_idx(struct amd_pmf_dev *pdev, bool manual, u32 idx) params.pointer = (void *)&args; info = apmf_if_call(pdev, APMF_FUNC_SET_FAN_IDX, ¶ms); - if (!info) { - err = -EIO; - goto out; - } + if (!info) + return -EIO; -out: kfree(info); - return err; + return 0; } int apmf_get_auto_mode_def(struct amd_pmf_dev *pdev, struct apmf_auto_mode *data) @@ -286,6 +279,43 @@ int apmf_install_handler(struct amd_pmf_dev *pmf_dev) return 0; } +static acpi_status apmf_walk_resources(struct acpi_resource *res, void *data) +{ + struct amd_pmf_dev *dev = data; + + switch (res->type) { + case ACPI_RESOURCE_TYPE_ADDRESS64: + dev->policy_addr = res->data.address64.address.minimum; + dev->policy_sz = res->data.address64.address.address_length; + break; + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: + dev->policy_addr = res->data.fixed_memory32.address; + dev->policy_sz = res->data.fixed_memory32.address_length; + break; + } + + if (!dev->policy_addr || dev->policy_sz > POLICY_BUF_MAX_SZ || dev->policy_sz == 0) { + pr_err("Incorrect Policy params, possibly a SBIOS bug\n"); + return AE_ERROR; + } + + return AE_OK; +} + +int apmf_check_smart_pc(struct amd_pmf_dev *pmf_dev) +{ + acpi_handle ahandle = ACPI_HANDLE(pmf_dev->dev); + acpi_status status; + + status = acpi_walk_resources(ahandle, METHOD_NAME__CRS, apmf_walk_resources, pmf_dev); + if (ACPI_FAILURE(status)) { + dev_err(pmf_dev->dev, "acpi_walk_resources failed :%d\n", status); + return -EINVAL; + } + + return 0; +} + void apmf_acpi_deinit(struct amd_pmf_dev *pmf_dev) { acpi_handle ahandle = ACPI_HANDLE(pmf_dev->dev); |