From: Thierry Reding <[email protected]>

When a GPIO controller registers a pin range with a pin controller,
establish a device link between them in order to keep track of the
dependency, which will help keep the right suspend/resume ordering.

Signed-off-by: Thierry Reding <[email protected]>
---
 drivers/pinctrl/core.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index b70df27874d1..5079e8a5de61 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -404,6 +404,17 @@ void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev,
        mutex_lock(&pctldev->mutex);
        list_add_tail(&range->node, &pctldev->gpio_ranges);
        mutex_unlock(&pctldev->mutex);
+
+       if (range->gc) {
+               struct device_link *link;
+
+               link = device_link_add(range->gc->parent, pctldev->dev,
+                                      DL_FLAG_AUTOREMOVE_CONSUMER);
+               if (!link)
+                       dev_err(pctldev->dev,
+                               "failed to add device link to %s\n",
+                               dev_name(range->gc->parent));
+       }
 }
 EXPORT_SYMBOL_GPL(pinctrl_add_gpio_range);
 
@@ -2136,8 +2147,12 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev)
        pinctrl_free_pindescs(pctldev, pctldev->desc->pins,
                              pctldev->desc->npins);
        /* remove gpio ranges map */
-       list_for_each_entry_safe(range, n, &pctldev->gpio_ranges, node)
+       list_for_each_entry_safe(range, n, &pctldev->gpio_ranges, node) {
+               if (range->gc)
+                       device_link_remove(range->gc->parent, pctldev->dev);
+
                list_del(&range->node);
+       }
 
        mutex_unlock(&pctldev->mutex);
        mutex_destroy(&pctldev->mutex);
-- 
2.21.0

Reply via email to