diff options
author | Luke D. Jones <luke@ljones.dev> | 2023-06-30 17:35:50 +1200 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2023-07-12 17:01:54 +0200 |
commit | 609b3670c29f41a1a9da5e689373fc24d244cd00 (patch) | |
tree | 91c619df2e29bf4bee15cdfcc5a5f3972291f3a0 /drivers/platform/x86/asus-wmi.c | |
parent | d49f4d1a30ac656e65f3fc3609893256da0b9a31 (diff) |
platform/x86: asus-wmi: add safety checks to gpu switching
Add safety checking to dgpu_disable, egpu_enable, gpu_mux_mode.
These checks prevent users from doing such things as:
- disabling the dGPU while is muxed to drive the internal screen
- enabling the eGPU which also disables the dGPU, while muxed to
the internal screen
- switching the MUX to dGPU while the dGPU is disabled
Signed-off-by: Luke D. Jones <luke@ljones.dev>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20230630053552.976579-7-luke@ljones.dev
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'drivers/platform/x86/asus-wmi.c')
-rw-r--r-- | drivers/platform/x86/asus-wmi.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 821addb284d7..9f8f63d68a76 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -645,6 +645,18 @@ static ssize_t dgpu_disable_store(struct device *dev, if (disable > 1) return -EINVAL; + if (asus->gpu_mux_mode_available) { + result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPU_MUX); + if (result < 0) + /* An error here may signal greater failure of GPU handling */ + return result; + if (!result && disable) { + err = -ENODEV; + pr_warn("Can not disable dGPU when the MUX is in dGPU mode: %d\n", err); + return err; + } + } + err = asus_wmi_set_devstate(ASUS_WMI_DEVID_DGPU, disable, &result); if (err) { pr_warn("Failed to set dgpu disable: %d\n", err); @@ -702,6 +714,18 @@ static ssize_t egpu_enable_store(struct device *dev, return err; } + if (asus->gpu_mux_mode_available) { + result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPU_MUX); + if (result < 0) + /* An error here may signal greater failure of GPU handling */ + return result; + if (!result && enable) { + err = -ENODEV; + pr_warn("Can not enable eGPU when the MUX is in dGPU mode: %d\n", err); + return err; + } + } + err = asus_wmi_set_devstate(ASUS_WMI_DEVID_EGPU, enable, &result); if (err) { pr_warn("Failed to set egpu disable: %d\n", err); @@ -764,6 +788,30 @@ static ssize_t gpu_mux_mode_store(struct device *dev, if (optimus > 1) return -EINVAL; + if (asus->dgpu_disable_available) { + result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_DGPU); + if (result < 0) + /* An error here may signal greater failure of GPU handling */ + return result; + if (result && !optimus) { + err = -ENODEV; + pr_warn("Can not switch MUX to dGPU mode when dGPU is disabled: %d\n", err); + return err; + } + } + + if (asus->egpu_enable_available) { + result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_EGPU); + if (result < 0) + /* An error here may signal greater failure of GPU handling */ + return result; + if (result && !optimus) { + err = -ENODEV; + pr_warn("Can not switch MUX to dGPU mode when eGPU is enabled: %d\n", err); + return err; + } + } + err = asus_wmi_set_devstate(ASUS_WMI_DEVID_GPU_MUX, optimus, &result); if (err) { dev_err(dev, "Failed to set GPU MUX mode: %d\n", err); |