| From d5dcce0c414fcbfe4c2037b66ac69ea5f9b3f75c Mon Sep 17 00:00:00 2001 |
| From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> |
| Date: Thu, 22 Oct 2020 21:40:59 +0300 |
| Subject: device property: Keep secondary firmware node secondary by type |
| |
| From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> |
| |
| commit d5dcce0c414fcbfe4c2037b66ac69ea5f9b3f75c upstream. |
| |
| Behind primary and secondary we understand the type of the nodes |
| which might define their ordering. However, if primary node gone, |
| we can't maintain the ordering by definition of the linked list. |
| Thus, by ordering secondary node becomes first in the list. |
| But in this case the meaning of it is still secondary (or auxiliary). |
| The type of the node is maintained by the secondary pointer in it: |
| |
| secondary pointer Meaning |
| NULL or valid primary node |
| ERR_PTR(-ENODEV) secondary node |
| |
| So, if by some reason we do the following sequence of calls |
| |
| set_primary_fwnode(dev, NULL); |
| set_primary_fwnode(dev, primary); |
| |
| we should preserve secondary node. |
| |
| This concept is supported by the description of set_primary_fwnode() |
| along with implementation of set_secondary_fwnode(). Hence, fix |
| the commit c15e1bdda436 to follow this as well. |
| |
| Fixes: c15e1bdda436 ("device property: Fix the secondary firmware node handling in set_primary_fwnode()") |
| Cc: Ferry Toth <fntoth@gmail.com> |
| Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> |
| Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> |
| Tested-by: Ferry Toth <fntoth@gmail.com> |
| Cc: 5.9+ <stable@vger.kernel.org> # 5.9+ |
| Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/base/core.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/drivers/base/core.c |
| +++ b/drivers/base/core.c |
| @@ -4274,7 +4274,7 @@ void set_primary_fwnode(struct device *d |
| } else { |
| if (fwnode_is_primary(fn)) { |
| dev->fwnode = fn->secondary; |
| - fn->secondary = NULL; |
| + fn->secondary = ERR_PTR(-ENODEV); |
| } else { |
| dev->fwnode = NULL; |
| } |