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

platform/x86: wmi: Add driver_override support

Add support for forcing the WMI driver core to bind
a certain WMI driver to a WMI device. This will be
necessary to support generic WMI drivers without an
ID table

Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
Link: https://lore.kernel.org/r/20240624173116.31314-2-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
12046f8c 42610314

+37
+33
drivers/platform/x86/wmi.c
··· 772 772 } 773 773 static DEVICE_ATTR_RO(expensive); 774 774 775 + static ssize_t driver_override_show(struct device *dev, struct device_attribute *attr, 776 + char *buf) 777 + { 778 + struct wmi_device *wdev = to_wmi_device(dev); 779 + ssize_t ret; 780 + 781 + device_lock(dev); 782 + ret = sysfs_emit(buf, "%s\n", wdev->driver_override); 783 + device_unlock(dev); 784 + 785 + return ret; 786 + } 787 + 788 + static ssize_t driver_override_store(struct device *dev, struct device_attribute *attr, 789 + const char *buf, size_t count) 790 + { 791 + struct wmi_device *wdev = to_wmi_device(dev); 792 + int ret; 793 + 794 + ret = driver_set_override(dev, &wdev->driver_override, buf, count); 795 + if (ret < 0) 796 + return ret; 797 + 798 + return count; 799 + } 800 + static DEVICE_ATTR_RW(driver_override); 801 + 775 802 static struct attribute *wmi_attrs[] = { 776 803 &dev_attr_modalias.attr, 777 804 &dev_attr_guid.attr, 778 805 &dev_attr_instance_count.attr, 779 806 &dev_attr_expensive.attr, 807 + &dev_attr_driver_override.attr, 780 808 NULL 781 809 }; 782 810 ATTRIBUTE_GROUPS(wmi); ··· 873 845 { 874 846 struct wmi_block *wblock = dev_to_wblock(dev); 875 847 848 + kfree(wblock->dev.driver_override); 876 849 kfree(wblock); 877 850 } 878 851 ··· 882 853 struct wmi_driver *wmi_driver = drv_to_wdrv(driver); 883 854 struct wmi_block *wblock = dev_to_wblock(dev); 884 855 const struct wmi_device_id *id = wmi_driver->id_table; 856 + 857 + /* When driver_override is set, only bind to the matching driver */ 858 + if (wblock->dev.driver_override) 859 + return !strcmp(wblock->dev.driver_override, driver->name); 885 860 886 861 if (id == NULL) 887 862 return 0;
+4
include/linux/wmi.h
··· 16 16 * struct wmi_device - WMI device structure 17 17 * @dev: Device associated with this WMI device 18 18 * @setable: True for devices implementing the Set Control Method 19 + * @driver_override: Driver name to force a match; do not set directly, 20 + * because core frees it; use driver_set_override() to 21 + * set or clear it. 19 22 * 20 23 * This represents WMI devices discovered by the WMI driver core. 21 24 */ 22 25 struct wmi_device { 23 26 struct device dev; 24 27 bool setable; 28 + const char *driver_override; 25 29 }; 26 30 27 31 /**