diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-05-23 07:49:05 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-05-23 07:49:05 -0700 |
| commit | c8561c73b4a8669bb13c57a5853318cd02655f9b (patch) | |
| tree | a9ac004283e3930c47a717576756b8d4a44857dd | |
| parent | 3f264650ca7d2a2d6de86234d919f305211632cd (diff) | |
| parent | 215c90ee656114f5e8c32408228d97082f8e0eef (diff) | |
Merge tag 'driver-core-7.1-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core
Pull driver core fixes from Danilo Krummrich:
- Remove the software node on platform device release(); without this,
the software node remains registered after the device is gone and a
subsequent platform_device_register_full() reusing the same node
fails with -EBUSY
- In sysfs_update_group(), do not remove a pre-existing directory when
create_files() fails; the previous code would silently destroy a
sysfs group that the caller did not create
- Set fwnode->secondary to NULL in fwnode_init() to avoid dereferencing
uninitialized memory (e.g. in dev_to_swnode()) when the firmware node
is allocated on the stack or via a non-zeroing allocator
* tag 'driver-core-7.1-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core:
device property: set fwnode->secondary to NULL in fwnode_init()
sysfs: don't remove existing directory on update failure
driver core: platform: remove software node on release()
| -rw-r--r-- | drivers/base/platform.c | 16 | ||||
| -rw-r--r-- | fs/sysfs/group.c | 2 | ||||
| -rw-r--r-- | include/linux/fwnode.h | 1 |
3 files changed, 17 insertions, 2 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 75b4698d0e58..a19dd22deef2 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -606,6 +606,12 @@ static void platform_device_release(struct device *dev) kfree(pa); } +static void platform_device_release_full(struct device *dev) +{ + device_remove_software_node(dev); + platform_device_release(dev); +} + /** * platform_device_alloc - create a platform device * @name: base name of the device we're adding @@ -848,7 +854,13 @@ struct platform_device *platform_device_register_full(const struct platform_devi int ret; struct platform_device *pdev; - if (pdevinfo->swnode && pdevinfo->properties) + /* + * Only one software node per device is allowed. Make sure we don't + * accept or create two. + */ + if ((pdevinfo->swnode && pdevinfo->properties) || + (pdevinfo->swnode && is_software_node(pdevinfo->fwnode)) || + (pdevinfo->properties && is_software_node(pdevinfo->fwnode))) return ERR_PTR(-EINVAL); pdev = platform_device_alloc(pdevinfo->name, pdevinfo->id); @@ -878,6 +890,8 @@ struct platform_device *platform_device_register_full(const struct platform_devi ret = device_add_software_node(&pdev->dev, pdevinfo->swnode); if (ret) goto err; + + pdev->dev.release = platform_device_release_full; } else if (pdevinfo->properties) { ret = device_create_managed_software_node(&pdev->dev, pdevinfo->properties, NULL); diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index 182e54e575ee..4e1e4f18a166 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -188,7 +188,7 @@ static int internal_create_group(struct kobject *kobj, int update, kernfs_get(kn); error = create_files(kn, kobj, uid, gid, grp, update); if (error) { - if (grp->name) + if (grp->name && !update) kernfs_remove(kn); } kernfs_put(kn); diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h index 80b38fbf2121..31df7608737e 100644 --- a/include/linux/fwnode.h +++ b/include/linux/fwnode.h @@ -208,6 +208,7 @@ struct fwnode_operations { static inline void fwnode_init(struct fwnode_handle *fwnode, const struct fwnode_operations *ops) { + fwnode->secondary = NULL; fwnode->ops = ops; INIT_LIST_HEAD(&fwnode->consumers); INIT_LIST_HEAD(&fwnode->suppliers); |
