diff options
-rw-r--r-- | drivers/hwmon/dell-smm-hwmon.c | 1 | ||||
-rw-r--r-- | drivers/platform/x86/dell/dell-wmi-ddv.c | 1 | ||||
-rw-r--r-- | drivers/platform/x86/intel/wmi/sbl-fw-update.c | 1 | ||||
-rw-r--r-- | drivers/platform/x86/intel/wmi/thunderbolt.c | 1 | ||||
-rw-r--r-- | drivers/platform/x86/wmi-bmof.c | 1 | ||||
-rw-r--r-- | drivers/platform/x86/wmi.c | 12 | ||||
-rw-r--r-- | include/linux/wmi.h | 2 |
7 files changed, 19 insertions, 0 deletions
diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c index 6d8c0f328b7b..168d669c4eca 100644 --- a/drivers/hwmon/dell-smm-hwmon.c +++ b/drivers/hwmon/dell-smm-hwmon.c @@ -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, }; /* diff --git a/drivers/platform/x86/dell/dell-wmi-ddv.c b/drivers/platform/x86/dell/dell-wmi-ddv.c index db1e9240dd02..0b2299f7a2de 100644 --- a/drivers/platform/x86/dell/dell-wmi-ddv.c +++ b/drivers/platform/x86/dell/dell-wmi-ddv.c @@ -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); diff --git a/drivers/platform/x86/intel/wmi/sbl-fw-update.c b/drivers/platform/x86/intel/wmi/sbl-fw-update.c index 040153ad67c1..75c82c08117f 100644 --- a/drivers/platform/x86/intel/wmi/sbl-fw-update.c +++ b/drivers/platform/x86/intel/wmi/sbl-fw-update.c @@ -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); diff --git a/drivers/platform/x86/intel/wmi/thunderbolt.c b/drivers/platform/x86/intel/wmi/thunderbolt.c index e2ad3f46f356..08df560a2c7a 100644 --- a/drivers/platform/x86/intel/wmi/thunderbolt.c +++ b/drivers/platform/x86/intel/wmi/thunderbolt.c @@ -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); diff --git a/drivers/platform/x86/wmi-bmof.c b/drivers/platform/x86/wmi-bmof.c index 644d2fd889c0..df6f0ae6e6c7 100644 --- a/drivers/platform/x86/wmi-bmof.c +++ b/drivers/platform/x86/wmi-bmof.c @@ -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); diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 29dfe52eb802..349deced87e8 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -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; diff --git a/include/linux/wmi.h b/include/linux/wmi.h index 781958310bfb..63cca3b58d6d 100644 --- a/include/linux/wmi.h +++ b/include/linux/wmi.h @@ -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); |