summaryrefslogtreecommitdiff
path: root/drivers/platform
diff options
context:
space:
mode:
authorArmin Wolf <W_Armin@gmx.de>2024-06-24 19:31:15 +0200
committerIlpo Järvinen <ilpo.jarvinen@linux.intel.com>2024-06-24 20:36:08 +0300
commit12046f8c77e0ed6d41beabde0edbb729499c970b (patch)
tree44a0963ce0848a34db25e4473a252d519189f529 /drivers/platform
parent4261031484d8f8fcbd2bd6517416b88545447597 (diff)
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>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/wmi.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index d21f3fa25823..6bfae28b962a 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -772,11 +772,39 @@ static ssize_t expensive_show(struct device *dev,
}
static DEVICE_ATTR_RO(expensive);
+static ssize_t driver_override_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct wmi_device *wdev = to_wmi_device(dev);
+ ssize_t ret;
+
+ device_lock(dev);
+ ret = sysfs_emit(buf, "%s\n", wdev->driver_override);
+ device_unlock(dev);
+
+ return ret;
+}
+
+static ssize_t driver_override_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct wmi_device *wdev = to_wmi_device(dev);
+ int ret;
+
+ ret = driver_set_override(dev, &wdev->driver_override, buf, count);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+static DEVICE_ATTR_RW(driver_override);
+
static struct attribute *wmi_attrs[] = {
&dev_attr_modalias.attr,
&dev_attr_guid.attr,
&dev_attr_instance_count.attr,
&dev_attr_expensive.attr,
+ &dev_attr_driver_override.attr,
NULL
};
ATTRIBUTE_GROUPS(wmi);
@@ -845,6 +873,7 @@ static void wmi_dev_release(struct device *dev)
{
struct wmi_block *wblock = dev_to_wblock(dev);
+ kfree(wblock->dev.driver_override);
kfree(wblock);
}
@@ -854,6 +883,10 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver)
struct wmi_block *wblock = dev_to_wblock(dev);
const struct wmi_device_id *id = wmi_driver->id_table;
+ /* When driver_override is set, only bind to the matching driver */
+ if (wblock->dev.driver_override)
+ return !strcmp(wblock->dev.driver_override, driver->name);
+
if (id == NULL)
return 0;