Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

platform/x86: wmi: Use devres to disable the WMI device

Use devm_add_action_or_reset() to disable the WMI device instead of
manually calling wmi_method_enable() to prepare for future changes
inside the WMI data block handlign code.

The reason for this is that we have to make sure that all
devres-managed resources are released first because some might still
want to access the underlying WMI device.

Because devres-managed resources are not released during shutdown
we still have to manually disable the WMI device in this case.

Signed-off-by: Armin Wolf <W_Armin@gmx.de>
Link: https://lore.kernel.org/r/20250216193251.866125-6-W_Armin@gmx.de
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

authored by

Armin Wolf and committed by
Ilpo Järvinen
b6b56690 0fcc3162

+22 -9
+22 -9
drivers/platform/x86/wmi.c
··· 821 821 return 0; 822 822 } 823 823 824 + static void wmi_dev_disable(void *data) 825 + { 826 + struct wmi_block *wblock = data; 827 + 828 + if (ACPI_FAILURE(wmi_method_enable(wblock, false))) 829 + dev_warn(&wblock->dev.dev, "Failed to disable device\n"); 830 + } 831 + 824 832 static int wmi_dev_probe(struct device *dev) 825 833 { 826 834 struct wmi_block *wblock = dev_to_wblock(dev); 827 835 struct wmi_driver *wdriver = to_wmi_driver(dev->driver); 828 - int ret = 0; 836 + int ret; 829 837 830 838 /* Some older WMI drivers will break if instantiated multiple times, 831 839 * so they are blocked from probing WMI devices with a duplicated GUID. ··· 855 847 if (ACPI_FAILURE(wmi_method_enable(wblock, true))) 856 848 dev_warn(dev, "failed to enable device -- probing anyway\n"); 857 849 850 + /* 851 + * We have to make sure that all devres-managed resources are released first because 852 + * some might still want to access the underlying WMI device. 853 + */ 854 + ret = devm_add_action_or_reset(dev, wmi_dev_disable, wblock); 855 + if (ret < 0) 856 + return ret; 857 + 858 858 if (wdriver->probe) { 859 859 ret = wdriver->probe(to_wmi_device(dev), 860 860 find_guid_context(wblock, wdriver)); 861 - if (ret) { 862 - if (ACPI_FAILURE(wmi_method_enable(wblock, false))) 863 - dev_warn(dev, "Failed to disable device\n"); 864 - 861 + if (ret) 865 862 return ret; 866 - } 867 863 } 868 864 869 865 down_write(&wblock->notify_lock); ··· 888 876 889 877 if (wdriver->remove) 890 878 wdriver->remove(to_wmi_device(dev)); 891 - 892 - if (ACPI_FAILURE(wmi_method_enable(wblock, false))) 893 - dev_warn(dev, "failed to disable device\n"); 894 879 } 895 880 896 881 static void wmi_dev_shutdown(struct device *dev) ··· 911 902 if (wdriver->shutdown) 912 903 wdriver->shutdown(to_wmi_device(dev)); 913 904 905 + /* 906 + * We still need to disable the WMI device here since devres-managed resources 907 + * like wmi_dev_disable() will not be release during shutdown. 908 + */ 914 909 if (ACPI_FAILURE(wmi_method_enable(wblock, false))) 915 910 dev_warn(dev, "Failed to disable device\n"); 916 911 }