It appears that firmware nodes can be shared between devices. In such case
when a (child) device is about to be deleted, its firmware node may be shared
and ACPI_COMPANION_SET(..., NULL) call for it breaks the secondary link
of the shared primary firmware node.

In order to prevent that, check, if the device has a parent and parent's
firmware node is shared with its child, and avoid crashing the link.

Fixes: c15e1bdda436 ("device property: Fix the secondary firmware node handling 
in set_primary_fwnode()")
Reported-by: Ferry Toth <fnt...@gmail.com>
Signed-off-by: Andy Shevchenko <andriy.shevche...@linux.intel.com>
---
 drivers/base/core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index 41feab679fa1..78114ddac755 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -4264,6 +4264,7 @@ static inline bool fwnode_is_primary(struct fwnode_handle 
*fwnode)
  */
 void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
 {
+       struct device *parent = dev->parent;
        struct fwnode_handle *fn = dev->fwnode;
 
        if (fwnode) {
@@ -4278,7 +4279,8 @@ void set_primary_fwnode(struct device *dev, struct 
fwnode_handle *fwnode)
        } else {
                if (fwnode_is_primary(fn)) {
                        dev->fwnode = fn->secondary;
-                       fn->secondary = ERR_PTR(-ENODEV);
+                       if (!(parent && fn == parent->fwnode))
+                               fn->secondary = ERR_PTR(-ENODEV);
                } else {
                        dev->fwnode = NULL;
                }
-- 
2.28.0

Reply via email to