Skip to content

Commit 4186a47

Browse files
Wer-Wolfij-intel
authored andcommitted
platform/x86: wmi: Decouple probe deferring from wmi_block_list
Many aggregate WMI drivers do not use -EPROBE_DEFER when they cannot find a WMI device during probe, instead they require all WMI devices associated with an platform device to become available at once. This is currently achieved by adding those WMI devices to the wmi_block_list before they are registered, which is then used by the deprecated GUID-based functions to search for WMI devices. Replace this approach with a device link which defers probing of the WMI device until the associated platform device has finished probing (and has registered all WMI devices). New aggregate WMI drivers should not rely on this behaviour. Signed-off-by: Armin Wolf <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Ilpo Järvinen <[email protected]> Signed-off-by: Ilpo Järvinen <[email protected]>
1 parent 02a258a commit 4186a47

File tree

1 file changed

+26
-13
lines changed
  • drivers/platform/x86

1 file changed

+26
-13
lines changed

drivers/platform/x86/wmi.c

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,6 +1221,26 @@ static int wmi_create_device(struct device *wmi_bus_dev,
12211221
return 0;
12221222
}
12231223

1224+
static int wmi_add_device(struct platform_device *pdev, struct wmi_device *wdev)
1225+
{
1226+
struct device_link *link;
1227+
1228+
/*
1229+
* Many aggregate WMI drivers do not use -EPROBE_DEFER when they
1230+
* are unable to find a WMI device during probe, instead they require
1231+
* all WMI devices associated with an platform device to become available
1232+
* at once. This device link thus prevents WMI drivers from probing until
1233+
* the associated platform device has finished probing (and has registered
1234+
* all discovered WMI devices).
1235+
*/
1236+
1237+
link = device_link_add(&wdev->dev, &pdev->dev, DL_FLAG_AUTOREMOVE_SUPPLIER);
1238+
if (!link)
1239+
return -EINVAL;
1240+
1241+
return device_add(&wdev->dev);
1242+
}
1243+
12241244
static void wmi_free_devices(struct acpi_device *device)
12251245
{
12261246
struct wmi_block *wblock, *next;
@@ -1263,11 +1283,12 @@ static bool guid_already_parsed_for_legacy(struct acpi_device *device, const gui
12631283
/*
12641284
* Parse the _WDG method for the GUID data blocks
12651285
*/
1266-
static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
1286+
static int parse_wdg(struct device *wmi_bus_dev, struct platform_device *pdev)
12671287
{
1288+
struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
12681289
struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
12691290
const struct guid_block *gblock;
1270-
struct wmi_block *wblock, *next;
1291+
struct wmi_block *wblock;
12711292
union acpi_object *obj;
12721293
acpi_status status;
12731294
int retval = 0;
@@ -1317,22 +1338,14 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
13171338
wblock->handler = wmi_notify_debug;
13181339
wmi_method_enable(wblock, true);
13191340
}
1320-
}
13211341

1322-
/*
1323-
* Now that all of the devices are created, add them to the
1324-
* device tree and probe subdrivers.
1325-
*/
1326-
list_for_each_entry_safe(wblock, next, &wmi_block_list, list) {
1327-
if (wblock->acpi_device != device)
1328-
continue;
1329-
1330-
retval = device_add(&wblock->dev.dev);
1342+
retval = wmi_add_device(pdev, &wblock->dev);
13311343
if (retval) {
13321344
dev_err(wmi_bus_dev, "failed to register %pUL\n",
13331345
&wblock->gblock.guid);
13341346
if (debug_event)
13351347
wmi_method_enable(wblock, false);
1348+
13361349
list_del(&wblock->list);
13371350
put_device(&wblock->dev.dev);
13381351
}
@@ -1487,7 +1500,7 @@ static int acpi_wmi_probe(struct platform_device *device)
14871500
}
14881501
dev_set_drvdata(&device->dev, wmi_bus_dev);
14891502

1490-
error = parse_wdg(wmi_bus_dev, acpi_device);
1503+
error = parse_wdg(wmi_bus_dev, device);
14911504
if (error) {
14921505
pr_err("Failed to parse WDG method\n");
14931506
goto err_remove_busdev;

0 commit comments

Comments
 (0)