platform/x86: wmi: Fix probe failure when failing to register WMI devices

[ Upstream commit ed85891a27 ]

When a WMI device besides the first one somehow fails to register,
retval is returned while still containing a negative error code. This
causes the ACPI device fail to probe, leaving behind zombie WMI devices
leading to various errors later.

Handle the single error path separately and return 0 unconditionally
after trying to register all WMI devices to solve the issue. Also
continue to register WMI devices even if some fail to allocate memory.

Fixes: 6ee50aaa9a ("platform/x86: wmi: Instantiate all devices before adding them")
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
Link: https://lore.kernel.org/r/20231020211005.38216-4-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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Armin Wolf 2023-10-20 23:10:03 +02:00 committed by Greg Kroah-Hartman
parent 5a938500cd
commit 328d67254d

View file

@ -1270,8 +1270,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
struct wmi_block *wblock, *next;
union acpi_object *obj;
acpi_status status;
int retval = 0;
u32 i, total;
int retval;
status = acpi_evaluate_object(device->handle, "_WDG", NULL, &out);
if (ACPI_FAILURE(status))
@ -1282,8 +1282,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
return -ENXIO;
if (obj->type != ACPI_TYPE_BUFFER) {
retval = -ENXIO;
goto out_free_pointer;
kfree(obj);
return -ENXIO;
}
gblock = (const struct guid_block *)obj->buffer.pointer;
@ -1298,8 +1298,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
wblock = kzalloc(sizeof(*wblock), GFP_KERNEL);
if (!wblock) {
retval = -ENOMEM;
break;
dev_err(wmi_bus_dev, "Failed to allocate %pUL\n", &gblock[i].guid);
continue;
}
wblock->acpi_device = device;
@ -1338,9 +1338,9 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
}
}
out_free_pointer:
kfree(out.pointer);
return retval;
kfree(obj);
return 0;
}
/*