Commit a66ccfc2 authored by Armin Wolf's avatar Armin Wolf Committed by Ilpo Järvinen

platform/x86: wmi: Do not instantiate older WMI drivers multiple times

Many older WMI drivers cannot be instantiated multiple times for
two reasons:

- they are using the legacy GUID-based WMI API
- they are singletons (with global state)

Prevent such WMI drivers from binding to WMI devices with a duplicated
GUID, as this would mean that the WMI driver will be instantiated at
least two times (one for the original GUID and one for the duplicated
GUID).
WMI drivers which can be instantiated multiple times can signal this
by setting a flag inside struct wmi_driver.

Tested on a ASUS Prime B650-Plus.
Signed-off-by: default avatarArmin Wolf <W_Armin@gmx.de>
Link: https://lore.kernel.org/r/20240226193557.2888-2-W_Armin@gmx.deReviewed-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
parent 92843958
......@@ -1587,6 +1587,7 @@ static struct wmi_driver dell_smm_wmi_driver = {
},
.id_table = dell_smm_wmi_id_table,
.probe = dell_smm_wmi_probe,
.no_singleton = true,
};
/*
......
......@@ -882,6 +882,7 @@ static struct wmi_driver dell_wmi_ddv_driver = {
},
.id_table = dell_wmi_ddv_id_table,
.probe = dell_wmi_ddv_probe,
.no_singleton = true,
};
module_wmi_driver(dell_wmi_ddv_driver);
......
......@@ -131,6 +131,7 @@ static struct wmi_driver intel_wmi_sbl_fw_update_driver = {
.probe = intel_wmi_sbl_fw_update_probe,
.remove = intel_wmi_sbl_fw_update_remove,
.id_table = intel_wmi_sbl_id_table,
.no_singleton = true,
};
module_wmi_driver(intel_wmi_sbl_fw_update_driver);
......
......@@ -63,6 +63,7 @@ static struct wmi_driver intel_wmi_thunderbolt_driver = {
.dev_groups = tbt_groups,
},
.id_table = intel_wmi_thunderbolt_id_table,
.no_singleton = true,
};
module_wmi_driver(intel_wmi_thunderbolt_driver);
......
......@@ -94,6 +94,7 @@ static struct wmi_driver wmi_bmof_driver = {
.probe = wmi_bmof_probe,
.remove = wmi_bmof_remove,
.id_table = wmi_bmof_id_table,
.no_singleton = true,
};
module_wmi_driver(wmi_bmof_driver);
......
......@@ -883,6 +883,18 @@ static int wmi_dev_probe(struct device *dev)
struct wmi_driver *wdriver = drv_to_wdrv(dev->driver);
int ret = 0;
/* Some older WMI drivers will break if instantiated multiple times,
* so they are blocked from probing WMI devices with a duplicated GUID.
*
* New WMI drivers should support being instantiated multiple times.
*/
if (test_bit(WMI_GUID_DUPLICATED, &wblock->flags) && !wdriver->no_singleton) {
dev_warn(dev, "Legacy driver %s cannot be instantiated multiple times\n",
dev->driver->name);
return -ENODEV;
}
if (wdriver->notify) {
if (test_bit(WMI_NO_EVENT_DATA, &wblock->flags) && !wdriver->no_notify_data)
return -ENODEV;
......
......@@ -49,6 +49,7 @@ u8 wmidev_instance_count(struct wmi_device *wdev);
* @driver: Driver model structure
* @id_table: List of WMI GUIDs supported by this driver
* @no_notify_data: Driver supports WMI events which provide no event data
* @no_singleton: Driver can be instantiated multiple times
* @probe: Callback for device binding
* @remove: Callback for device unbinding
* @notify: Callback for receiving WMI events
......@@ -59,6 +60,7 @@ struct wmi_driver {
struct device_driver driver;
const struct wmi_device_id *id_table;
bool no_notify_data;
bool no_singleton;
int (*probe)(struct wmi_device *wdev, const void *context);
void (*remove)(struct wmi_device *wdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment