From e254b758976f651c47ec902d92306bd49f452ab0 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 29 Dec 2025 15:43:25 +0100 Subject: driver core: make bus_find_device_by_acpi_dev() stub prototype aligned Currently the bus_find_device_by_acpi_dev() stub for !CONFIG_ACPI case takes a const void * parameter instead of const struct acpi_device *. As long as it's a pointer, we may named it as we want to with the help of a forward declaration. Hence move the declaration out of the ifdeffery and use the same prototype in both cases. This adds a bit of an additional type checking at a compilation time. Signed-off-by: Andy Shevchenko Link: https://patch.msgid.link/20251229144325.1252197-1-andriy.shevchenko@linux.intel.com [ Fix minor typo in the commit message. - Danilo ] Signed-off-by: Danilo Krummrich --- include/linux/device/bus.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux/device') diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h index 99b1002b3e31..99c3c83ea520 100644 --- a/include/linux/device/bus.h +++ b/include/linux/device/bus.h @@ -215,9 +215,9 @@ bus_find_next_device(const struct bus_type *bus,struct device *cur) return bus_find_device(bus, cur, NULL, device_match_any); } -#ifdef CONFIG_ACPI struct acpi_device; +#ifdef CONFIG_ACPI /** * bus_find_device_by_acpi_dev : device iterator for locating a particular device * matching the ACPI COMPANION device. @@ -231,7 +231,7 @@ bus_find_device_by_acpi_dev(const struct bus_type *bus, const struct acpi_device } #else static inline struct device * -bus_find_device_by_acpi_dev(const struct bus_type *bus, const void *adev) +bus_find_device_by_acpi_dev(const struct bus_type *bus, const struct acpi_device *adev) { return NULL; } -- cgit v1.2.3 From a995fe1a3aa78b7d06cc1cc7b6b8436c5e93b07f Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Wed, 7 Jan 2026 11:35:05 +0100 Subject: rust: driver: drop device private data post unbind Currently, the driver's device private data is allocated and initialized from driver core code called from bus abstractions after the driver's probe() callback returned the corresponding initializer. Similarly, the driver's device private data is dropped within the remove() callback of bus abstractions after calling the remove() callback of the corresponding driver. However, commit 6f61a2637abe ("rust: device: introduce Device::drvdata()") introduced an accessor for the driver's device private data for a Device, i.e. a device that is currently bound to a driver. Obviously, this is in conflict with dropping the driver's device private data in remove(), since a device can not be considered to be fully unbound after remove() has finished: We also have to consider registrations guarded by devres - such as IRQ or class device registrations - which are torn down after remove() in devres_release_all(). Thus, it can happen that, for instance, a class device or IRQ callback still calls Device::drvdata(), which then runs concurrently to remove() (which sets dev->driver_data to NULL and drops the driver's device private data), before devres_release_all() started to tear down the corresponding registration. This is because devres guarded registrations can, as expected, access the corresponding Device that defines their scope. In C it simply is the driver's responsibility to ensure that its device private data is freed after e.g. an IRQ registration is unregistered. Typically, C drivers achieve this by allocating their device private data with e.g. devm_kzalloc() before doing anything else, i.e. before e.g. registering an IRQ with devm_request_threaded_irq(), relying on the reverse order cleanup of devres. Technically, we could do something similar in Rust. However, the resulting code would be pretty messy: In Rust we have to differentiate between allocated but uninitialized memory and initialized memory in the type system. Thus, we would need to somehow keep track of whether the driver's device private data object has been initialized (i.e. probe() was successful and returned a valid initializer for this memory) and conditionally call the destructor of the corresponding object when it is freed. This is because we'd need to allocate and register the memory of the driver's device private data *before* it is initialized by the initializer returned by the driver's probe() callback, because the driver could already register devres guarded registrations within probe() outside of the driver's device private data initializer. Luckily there is a much simpler solution: Instead of dropping the driver's device private data at the end of remove(), we just drop it after the device has been fully unbound, i.e. after all devres callbacks have been processed. For this, we introduce a new post_unbind() callback private to the driver-core, i.e. the callback is neither exposed to drivers, nor to bus abstractions. This way, the driver-core code can simply continue to conditionally allocate the memory for the driver's device private data when the driver's initializer is returned from probe() - no change needed - and drop it when the driver-core code receives the post_unbind() callback. Closes: https://lore.kernel.org/all/DEZMS6Y4A7XE.XE7EUBT5SJFJ@kernel.org/ Fixes: 6f61a2637abe ("rust: device: introduce Device::drvdata()") Acked-by: Alice Ryhl Acked-by: Greg Kroah-Hartman Acked-by: Igor Korotin Link: https://patch.msgid.link/20260107103511.570525-7-dakr@kernel.org [ Remove #ifdef CONFIG_RUST, rename post_unbind() to post_unbind_rust(). - Danilo] Signed-off-by: Danilo Krummrich --- include/linux/device/driver.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux/device') diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h index cd8e0f0a634b..bbc67ec513ed 100644 --- a/include/linux/device/driver.h +++ b/include/linux/device/driver.h @@ -85,6 +85,8 @@ enum probe_type { * uevent. * @p: Driver core's private data, no one other than the driver * core can touch this. + * @p_cb: Callbacks private to the driver core; no one other than the + * driver core is allowed to touch this. * * The device driver-model tracks all of the drivers known to the system. * The main reason for this tracking is to enable the driver core to match @@ -119,6 +121,13 @@ struct device_driver { void (*coredump) (struct device *dev); struct driver_private *p; + struct { + /* + * Called after remove() and after all devres entries have been + * processed. This is a Rust only callback. + */ + void (*post_unbind_rust)(struct device *dev); + } p_cb; }; -- cgit v1.2.3 From 08a55792245a7bd395c947ff88b08b6abdd56f93 Mon Sep 17 00:00:00 2001 From: Danilo Krummrich Date: Mon, 19 Jan 2026 17:27:57 +0100 Subject: driver-core: move devres_for_each_res() to base.h devres_for_each_res() is only used by .../firmware_loader/main.c, which already includes base.h. The usage of devres_for_each_res() by code outside of driver-core is questionable, hence move it to base.h. Acked-by: Greg Kroah-Hartman Link: https://patch.msgid.link/20260119162920.77189-1-dakr@kernel.org Signed-off-by: Danilo Krummrich --- include/linux/device/devres.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux/device') diff --git a/include/linux/device/devres.h b/include/linux/device/devres.h index 9c1e3d643d69..14ab9159bdda 100644 --- a/include/linux/device/devres.h +++ b/include/linux/device/devres.h @@ -26,10 +26,6 @@ __devres_alloc_node(dr_release_t release, size_t size, gfp_t gfp, int nid, const #define devres_alloc_node(release, size, gfp, nid) \ __devres_alloc_node(release, size, gfp, nid, #release) -void devres_for_each_res(struct device *dev, dr_release_t release, - dr_match_t match, void *match_data, - void (*fn)(struct device *, void *, void *), - void *data); void devres_free(void *res); void devres_add(struct device *dev, void *res); void *devres_find(struct device *dev, dr_release_t release, dr_match_t match, void *match_data); -- cgit v1.2.3