mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
firmware: arm_scmi: provide the mandatory device release callback
The device/driver model clearly mandates that bus driver that discover
and allocate the device must set the release callback. This callback
will be used to free the device after all references have gone away.
scmi bus driver is missing the obvious callback which will result in
the following warning if the device is unregistered:
Device 'scmi_dev.1' does not have a release() function, it is broken and
must be fixed. See Documentation/kobject.txt.
WARNING at drivers/base/core.c:922 device_release+0x8c/0xa0
Hardware name: ARM LTD Juno Development Platform BIOS EDK II Jan 21 2019
Workqueue: events deferred_probe_work_func
pstate: 60000005 (nZCv daif -PAN -UAO)
pc : device_release+0x8c/0xa0
lr : device_release+0x8c/0xa0
Call trace:
device_release+0x8c/0xa0
kobject_put+0x8c/0x208
device_unregister+0x30/0x78
scmi_device_destroy+0x28/0x50
scmi_probe+0x354/0x5b0
platform_drv_probe+0x58/0xa8
really_probe+0x2c4/0x3e8
driver_probe_device+0x12c/0x148
__device_attach_driver+0xac/0x150
bus_for_each_drv+0x78/0xd8
__device_attach+0xe0/0x168
device_initial_probe+0x24/0x30
bus_probe_device+0xa0/0xa8
deferred_probe_work_func+0x8c/0xe0
process_one_work+0x1f0/0x478
worker_thread+0x22c/0x450
kthread+0x134/0x138
ret_from_fork+0x10/0x1c
---[ end trace 420bdb7f6af50937 ]---
Fix the issue by providing scmi_device_release callback. We have
everything required for device release already in scmi_device_destroy,
so we just need to move freeing of the device to scmi_device_release.
Fixes: 933c504424
("firmware: arm_scmi: add scmi protocol bus to enumerate protocol devices")
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Cc: stable@vger.kernel.org # 4.17+
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
parent
db4090920b
commit
46edb8d132
1 changed files with 7 additions and 2 deletions
|
@ -119,6 +119,11 @@ void scmi_driver_unregister(struct scmi_driver *driver)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(scmi_driver_unregister);
|
||||
|
||||
static void scmi_device_release(struct device *dev)
|
||||
{
|
||||
kfree(to_scmi_dev(dev));
|
||||
}
|
||||
|
||||
struct scmi_device *
|
||||
scmi_device_create(struct device_node *np, struct device *parent, int protocol)
|
||||
{
|
||||
|
@ -138,6 +143,7 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol)
|
|||
scmi_dev->dev.parent = parent;
|
||||
scmi_dev->dev.of_node = np;
|
||||
scmi_dev->dev.bus = &scmi_bus_type;
|
||||
scmi_dev->dev.release = scmi_device_release;
|
||||
dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id);
|
||||
|
||||
retval = device_register(&scmi_dev->dev);
|
||||
|
@ -156,9 +162,8 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol)
|
|||
void scmi_device_destroy(struct scmi_device *scmi_dev)
|
||||
{
|
||||
scmi_handle_put(scmi_dev->handle);
|
||||
device_unregister(&scmi_dev->dev);
|
||||
ida_simple_remove(&scmi_bus_id, scmi_dev->id);
|
||||
kfree(scmi_dev);
|
||||
device_unregister(&scmi_dev->dev);
|
||||
}
|
||||
|
||||
void scmi_set_handle(struct scmi_device *scmi_dev)
|
||||
|
|
Loading…
Reference in a new issue