From patchwork Wed Aug 10 06:00:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 596526 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 12468C2BB9D for ; Wed, 10 Aug 2022 06:01:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231246AbiHJGB3 (ORCPT ); Wed, 10 Aug 2022 02:01:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59914 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230419AbiHJGA5 (ORCPT ); Wed, 10 Aug 2022 02:00:57 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7A786625A for ; Tue, 9 Aug 2022 23:00:56 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id bu13-20020a056902090d00b00671743601f1so11335396ybb.0 for ; Tue, 09 Aug 2022 23:00:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=YZpb5QMLSiLGJVomN8fbI7EvU2NAh/GQGzK/ScajhVo=; b=kdufMKJarzPJUSUXa9Lkyppvpmugt3JrF1lgKjodq0AS8PmSnyNnsq5cSojkvWFydP 4SlosfOvXqDnb9Otj4vuNf4C9sjbZeyEg/pJMTXQe026M/y9/1hjbxROqrTHxBCE1754 oBloAVDejrDfhsaIqrAL6utmIa3sceIQqZEseSzOdVx/5c7Xg+AOdDBJ+nkSyNuwTOPd qotXnqs5f2mFDey1C4raGc6DlxYepToi5rZGMEx5ZpcTB4d54i3ScEmzcurJy+/1YfTe CH/n1d3h37wT/JtauKwkMlnMGxKOuLKCxLdzeVmnrYXONHl60Vld8ABImyxhgBPBLYqj frqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=YZpb5QMLSiLGJVomN8fbI7EvU2NAh/GQGzK/ScajhVo=; b=JDrLAyZ/OKlqFWzhX0X0f1SZ37ozlPtv8u/+LyeF1Yt8cEJV8/JbyxEQ5P7gjyFxKT RfPDqQu2CTr+sO9SRoDRVb2qHZ/hT24OqoKQvATybpF8lGN5LJ2SMhu8qyAtC/R7d0E2 ZTnfpAv2i3kMP233Wlv5Y6AZHFHzVXROZAy9PdrAE4bjDjr+AZpOseL27rxDoCLayHzX W3BzdPm4OZEo5jLM/An16zdx7Qy0OxeJPJDylY0H5/Tj5O9YN/uzZPA8bDnxuWN/SPjt qN88EJ+B4iAXZgfaXyump+mjWZo6S793BL1tOzHAaNf8tV3JY+k+3x/Vtxi/TgqXSKBL o9RQ== X-Gm-Message-State: ACgBeo39iKhinxC342gwrA9jQ0HTPQp+4c+vhL6K8LtRwSCOkTIEIFP+ 3m/Jq8CGrWzVcfYYxDsaV5qDM3alaD+O5u0= X-Google-Smtp-Source: AA6agR7ZTfYG48/VyeszVgW+xw1hG2i1zXLZfrMjpmwx4bEiOBYzEVkJ83eHKaSOJD8LIzkwYIYdbUt4DUfVhhY= X-Received: from saravanak.san.corp.google.com ([2620:15c:2d:3:f21:76ca:766f:e0ab]) (user=saravanak job=sendgmr) by 2002:a0d:cc8b:0:b0:328:3005:37a0 with SMTP id o133-20020a0dcc8b000000b00328300537a0mr27540603ywd.470.1660111255729; Tue, 09 Aug 2022 23:00:55 -0700 (PDT) Date: Tue, 9 Aug 2022 23:00:32 -0700 In-Reply-To: <20220810060040.321697-1-saravanak@google.com> Message-Id: <20220810060040.321697-4-saravanak@google.com> Mime-Version: 1.0 References: <20220810060040.321697-1-saravanak@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v1 3/9] soc: renesas: Move away from using OF_POPULATED for fw_devlink From: Saravana Kannan To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Linus Walleij , Bartosz Golaszewski , Rob Herring , Frank Rowand , Geert Uytterhoeven , Magnus Damm , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Len Brown Cc: Saravana Kannan , Abel Vesa , Alexander Stein , Tony Lindgren , Sudeep Holla , Geert Uytterhoeven , John Stultz , Doug Anderson , Guenter Roeck , kernel-team@android.com, linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-acpi@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org The OF_POPULATED flag was set to let fw_devlink know that the device tree node will not have a struct device created for it. This information is used by fw_devlink to avoid deferring the probe of consumers of this device tree node. Let's use fwnode_dev_initialized() instead because it achieves the same effect without using OF specific flags. This allows more generic code to be written in driver core. Signed-off-by: Saravana Kannan --- drivers/soc/renesas/rcar-sysc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c index b0a80de34c98..03246ed4a79e 100644 --- a/drivers/soc/renesas/rcar-sysc.c +++ b/drivers/soc/renesas/rcar-sysc.c @@ -437,7 +437,7 @@ static int __init rcar_sysc_pd_init(void) error = of_genpd_add_provider_onecell(np, &domains->onecell_data); if (!error) - of_node_set_flag(np, OF_POPULATED); + fwnode_dev_initialized(&np->fwnode, true); out_put: of_node_put(np); From patchwork Wed Aug 10 06:00:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 596525 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72B00C32765 for ; Wed, 10 Aug 2022 06:01:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230390AbiHJGBa (ORCPT ); Wed, 10 Aug 2022 02:01:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59996 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231187AbiHJGBA (ORCPT ); Wed, 10 Aug 2022 02:01:00 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9BB5526AF1 for ; Tue, 9 Aug 2022 23:00:59 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id j144-20020a25d296000000b0067ba828624fso9572716ybg.16 for ; Tue, 09 Aug 2022 23:00:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=NqpNj2ocNlieJvtq2Rsc6gGxelmaBpd53cWZI4hRdYA=; b=MzzjYm5HiDy/e+AAiaA8O6qiqZTeuWaSmUul6mrOTOGDjmtqabFjSlUNlBvvqWqvOu jF8wpL3gD98q8iaJmJbPNXu5Jcq8MaF5znAghQHPSyfDKTPcRmFjFafFYiQiT0r/WTpG +pdffSn/lWfXQ2MYHZ1u8WuOaTCyJmQBiBsejjHkXUCYJVGFcgsxP6qjdh6pQLU4RxSh MxKKjJC87FeBV3cirBR0UWIGiLTcZlyT5xuhr0DEtPacLRS5oC3vA1APF7Rb9kLp3z3n pFISfY34zzCPsGmOLdR3XFq8QeDaH/onImXVvKiUASr7k3HuVan3sxyNgwF3q+8F4/HV B+2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=NqpNj2ocNlieJvtq2Rsc6gGxelmaBpd53cWZI4hRdYA=; b=UxqmO+so7nvIoaUb2DBZiHXnKfLFrNaBezGn2xQnpIIJ4HVYKbO85ZCUKJokrzMPxz jXIWNItKelO8Yhlk+36uozPlffC0gnD7l49g1lfCaZgzq3mB8p5rHM+koWe9NUPeu4wf qjl7ZrLDqMyhu8oq/FlMta3wcKgBoQBjvHeLDZPKc6k3DGu/+HBOvYBJo7AcoEfOi1mc 31MHe/MH+X4iMJSAbrB/Y5H9WJy2Hi7IscKt0GglvhmiWIV7M5sKSBvIbvreT3pbMl4s AYjhCJCaQB0Z7JVl/Bt+1ELrytoXdZk+0y+vtazoOnCiZ7OkLPMrSg58co019/WAgakZ DCXQ== X-Gm-Message-State: ACgBeo0osbiuonEL/g/UB0WQir9yfoAFvK6HTDhnnNSCQK7TBeJJcT4F 07hC3SYSk158IwZXZVI16Lc1D6htq0KFHjU= X-Google-Smtp-Source: AA6agR4iq9bUQootDJRxvaaJGo0ZWuATHd7U0JhEzjkGXqE16C2kiMrkJpaNY9G0SstRjMkM93lN22NFoI50pzI= X-Received: from saravanak.san.corp.google.com ([2620:15c:2d:3:f21:76ca:766f:e0ab]) (user=saravanak job=sendgmr) by 2002:a25:b9c3:0:b0:668:a418:13c with SMTP id y3-20020a25b9c3000000b00668a418013cmr22880523ybj.498.1660111258798; Tue, 09 Aug 2022 23:00:58 -0700 (PDT) Date: Tue, 9 Aug 2022 23:00:33 -0700 In-Reply-To: <20220810060040.321697-1-saravanak@google.com> Message-Id: <20220810060040.321697-5-saravanak@google.com> Mime-Version: 1.0 References: <20220810060040.321697-1-saravanak@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v1 4/9] gpiolib: Clear the gpio_device's fwnode initialized flag before adding From: Saravana Kannan To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Linus Walleij , Bartosz Golaszewski , Rob Herring , Frank Rowand , Geert Uytterhoeven , Magnus Damm , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Len Brown Cc: Saravana Kannan , Abel Vesa , Alexander Stein , Tony Lindgren , Sudeep Holla , Geert Uytterhoeven , John Stultz , Doug Anderson , Guenter Roeck , kernel-team@android.com, linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-acpi@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Registering an irqdomain sets the flag for the fwnode. But having the flag set when a device is added is interpreted by fw_devlink to mean the device has already been initialized and will never probe. This prevents fw_devlink from creating device links with the gpio_device as a supplier. So, clear the flag before adding the device. Signed-off-by: Saravana Kannan --- drivers/gpio/gpiolib.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index cc9c0a12259e..1d57d6f24632 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -522,6 +522,12 @@ static int gpiochip_setup_dev(struct gpio_device *gdev) { int ret; + /* + * If fwnode doesn't belong to another device, it's safe to clear its + * initialized flag. + */ + if (!gdev->dev.fwnode->dev) + fwnode_dev_initialized(gdev->dev.fwnode, false); ret = gcdev_register(gdev, gpio_devt); if (ret) return ret; From patchwork Wed Aug 10 06:00:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 596524 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 44E31C32770 for ; Wed, 10 Aug 2022 06:02:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231260AbiHJGBd (ORCPT ); Wed, 10 Aug 2022 02:01:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60208 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231216AbiHJGBK (ORCPT ); Wed, 10 Aug 2022 02:01:10 -0400 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 27F5923168 for ; Tue, 9 Aug 2022 23:01:09 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id b8-20020a17090a010800b001f1f4fc8178so566859pjb.8 for ; Tue, 09 Aug 2022 23:01:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=QlBa19npdjPgpjrCBQ6hdELMXhm8tkXE401pFqPbnb0=; b=eJmKIYCYCN91qGdXy7dqkM9QOmKtLlEdwFwNdU/NZG0JQuX+kMk9l2lpLVW26gS0xn kb1NHLqMsTBWLP5U6mLKXexB0rk/CifLn9hnGa/mjgeoY2ccfLaW07tOhrvM7hR626sI o1Wxf6k53d9enK4htKjLblZQkmtY2thm+sSPKA/YnztNkYjyLQiiHu7pgjBV9ndsMjEh pFs5qTn8XZdMyRnnPBN3fI5zloYW1GMq0HQyY5dSump5PVfdqEkRTmTSGIOB+3+Rzouw Vb8tYX2Edlrw8s9/NhIqxxJacQe8dgGAqtp30kKKkHE8RdXPPnT1cGXkSUpwpWq378Kp ahng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=QlBa19npdjPgpjrCBQ6hdELMXhm8tkXE401pFqPbnb0=; b=stNHvmuyXOJILcJaDQ5lRVNFd+Zn4VyeMqOgAC6kltuGGO0UMJgYVMMk3+8i/ZIGZe mDPtUyPa188WJZlOgUoh/b5/FbWgvgBeeoDfmLs1D4cZb6NrXlObydr7pYBictXHp8tw FfBNyrMTD81gQyC5GIlHcIYvSc2dDkvceKwmZdTK1i27jDRiTIbELEHgjxq7WIkrPY5Y vvTDIjObfYS+Ivm2XG9Mz4e3s8/UC8yHI72QzaKovxCAJ/dBKjXVb4vS5hLGcE9vuAwi YEGhZJLCa5lErDOjS9hXmZ9sdD+eszGVUweOBfLW+n9hia1mXDzuuaqvG1CW5DzirIPn yPhg== X-Gm-Message-State: ACgBeo2ONXjsytHHMXauVBLyoEQcmSGa2pAaPhiz3qSfLoUgHlPdzLL6 rVW7O32aKCLXuvMG4RqdMqGtwdEnMK5ibyc= X-Google-Smtp-Source: AA6agR79A9bVNKcbOAqy5O1SaUATcI7RM0MJmEL+q94u6z+rhD9R5vGMbVZ3HSjFjJYMpl/fyYQLNX6k6hpJ4xs= X-Received: from saravanak.san.corp.google.com ([2620:15c:2d:3:f21:76ca:766f:e0ab]) (user=saravanak job=sendgmr) by 2002:a63:6884:0:b0:415:b761:efa4 with SMTP id d126-20020a636884000000b00415b761efa4mr22285314pgc.274.1660111268410; Tue, 09 Aug 2022 23:01:08 -0700 (PDT) Date: Tue, 9 Aug 2022 23:00:36 -0700 In-Reply-To: <20220810060040.321697-1-saravanak@google.com> Message-Id: <20220810060040.321697-8-saravanak@google.com> Mime-Version: 1.0 References: <20220810060040.321697-1-saravanak@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v1 7/9] driver core: fw_devlink: Consolidate device link flag computation From: Saravana Kannan To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Linus Walleij , Bartosz Golaszewski , Rob Herring , Frank Rowand , Geert Uytterhoeven , Magnus Damm , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Len Brown Cc: Saravana Kannan , Abel Vesa , Alexander Stein , Tony Lindgren , Sudeep Holla , Geert Uytterhoeven , John Stultz , Doug Anderson , Guenter Roeck , kernel-team@android.com, linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-acpi@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Consolidate the code that computes the flags to be used when creating a device link from a fwnode link. Signed-off-by: Saravana Kannan --- drivers/base/core.c | 28 +++++++++++++++------------- include/linux/fwnode.h | 1 - 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 0ec2c4d5ffaa..296cfb714fe1 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1725,8 +1725,11 @@ static int __init fw_devlink_strict_setup(char *arg) } early_param("fw_devlink.strict", fw_devlink_strict_setup); -u32 fw_devlink_get_flags(void) +static inline u32 fw_devlink_get_flags(u8 fwlink_flags) { + if (fwlink_flags & FWLINK_FLAG_CYCLE) + return FW_DEVLINK_FLAGS_PERMISSIVE | DL_FLAG_CYCLE; + return fw_devlink_flags; } @@ -1936,7 +1939,7 @@ static bool fwnode_ancestor_init_without_drv(struct fwnode_handle *fwnode) * fw_devlink_create_devlink - Create a device link from a consumer to fwnode * @con: consumer device for the device link * @sup_handle: fwnode handle of supplier - * @flags: devlink flags + * @link: fwnode link that's being converted to a device link * * This function will try to create a device link between the consumer device * @con and the supplier device represented by @sup_handle. @@ -1953,10 +1956,17 @@ static bool fwnode_ancestor_init_without_drv(struct fwnode_handle *fwnode) * possible to do that in the future */ static int fw_devlink_create_devlink(struct device *con, - struct fwnode_handle *sup_handle, u32 flags) + struct fwnode_handle *sup_handle, + struct fwnode_link *link) { struct device *sup_dev; int ret = 0; + u32 flags; + + if (con->fwnode == link->consumer) + flags = fw_devlink_get_flags(link->flags); + else + flags = FW_DEVLINK_FLAGS_PERMISSIVE; /* * In some cases, a device P might also be a supplier to its child node @@ -2085,7 +2095,6 @@ static void __fw_devlink_link_to_consumers(struct device *dev) struct fwnode_link *link, *tmp; list_for_each_entry_safe(link, tmp, &fwnode->consumers, s_hook) { - u32 dl_flags = fw_devlink_get_flags(); struct device *con_dev; bool own_link = true; int ret; @@ -2115,14 +2124,13 @@ static void __fw_devlink_link_to_consumers(struct device *dev) con_dev = NULL; } else { own_link = false; - dl_flags = FW_DEVLINK_FLAGS_PERMISSIVE; } } if (!con_dev) continue; - ret = fw_devlink_create_devlink(con_dev, fwnode, dl_flags); + ret = fw_devlink_create_devlink(con_dev, fwnode, link); put_device(con_dev); if (!own_link || ret == -EAGAIN) continue; @@ -2163,19 +2171,13 @@ static void __fw_devlink_link_to_suppliers(struct device *dev, bool own_link = (dev->fwnode == fwnode); struct fwnode_link *link, *tmp; struct fwnode_handle *child = NULL; - u32 dl_flags; - - if (own_link) - dl_flags = fw_devlink_get_flags(); - else - dl_flags = FW_DEVLINK_FLAGS_PERMISSIVE; list_for_each_entry_safe(link, tmp, &fwnode->suppliers, c_hook) { int ret; struct device *sup_dev; struct fwnode_handle *sup = link->supplier; - ret = fw_devlink_create_devlink(dev, sup, dl_flags); + ret = fw_devlink_create_devlink(dev, sup, link); if (!own_link || ret == -EAGAIN) continue; diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h index fdf2ee0285b7..5700451b300f 100644 --- a/include/linux/fwnode.h +++ b/include/linux/fwnode.h @@ -207,7 +207,6 @@ static inline void fwnode_dev_initialized(struct fwnode_handle *fwnode, fwnode->flags &= ~FWNODE_FLAG_INITIALIZED; } -extern u32 fw_devlink_get_flags(void); extern bool fw_devlink_is_strict(void); int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup); void fwnode_links_purge(struct fwnode_handle *fwnode); From patchwork Wed Aug 10 06:00:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 596523 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B5D5DC32789 for ; Wed, 10 Aug 2022 06:02:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231272AbiHJGBe (ORCPT ); Wed, 10 Aug 2022 02:01:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60292 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231221AbiHJGBO (ORCPT ); Wed, 10 Aug 2022 02:01:14 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6B03426AF1 for ; Tue, 9 Aug 2022 23:01:12 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id m5-20020a2598c5000000b0066faab590c5so11288414ybo.7 for ; Tue, 09 Aug 2022 23:01:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=0OeIVdqZFtuzFksZAGEwimHr/eXJ/y/bblGdVkQb4U4=; b=bsicgi1AognCScR7IjuFDncgNtikVlD9KUavrAswfny8Y58HX2O4KWrmg7Bgbp9S6J Mb+K0qEiRH9gnwPyjwKAAm12+nvbOWCt3Laji+xXknuaznkjsEM6presQXX9TW88985V /QnPntgMffouMG0JWAktuzBvvLMrGixQuJGcvS7tUg9eTWnYiQZQ1MQRNNqRKMfw7DnH yCfzmDUcaYY3uJc3r5ifz7+4DAfAm3Zz5x1tEtoRyGtzGryxszxXQmjYehvMoPH3ypLQ G3bkgMUtDBnFG2IrUAyWDVgaCM8zD+PXhc/KFqgRQbDJLtq6PQO2ezZvzdcb3UwzMsTJ pseg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=0OeIVdqZFtuzFksZAGEwimHr/eXJ/y/bblGdVkQb4U4=; b=XmqejM9zisaBDMUQ1Jqu0ChZtfPfsDr73OK0tg5hjKs/qleHqi7vql2uMkx/3Q9gvH DAbSzHX32qXA1V7In0swbDRLe13Bw8ORHIevz0yJ6Tf8QtFO1BxD/sOt/gtWtrmcRmpE X6ltbup57giJ1FBzxKm/hCXndg8x7GprerhA6b7N9KmypzLR2nNZMbEWyDhvJv0xUzlV NDVLUoVxCFEkT5wKRHWq1FoV7cPkd1XAGcmigldqgHjn3ys3PA47RvTITi1IzMu8vwg7 +B3Fqx30k2nBHjOeMmOxQvHRLcAXtjVQVNBYgji4QHbXraeT/hJ7vh3HxRiaNa1qMEq/ 2QaA== X-Gm-Message-State: ACgBeo029vGKbvNfGFRZ7ljiy6XbM+DlNVVh/n/K+reqdIDph9eD1Ba/ mGpPF4ryyrD9gSOcj6qYHCv1bXL4l3r7eGw= X-Google-Smtp-Source: AA6agR4lRb1pOFi9LBMVZwF0W1xxhUoosjbkh/XGmyo3Z++3BkWQS/essjhb7uDiESA7FHHA1sMr7x4IMOj5OaU= X-Received: from saravanak.san.corp.google.com ([2620:15c:2d:3:f21:76ca:766f:e0ab]) (user=saravanak job=sendgmr) by 2002:a0d:ee07:0:b0:324:cb8a:130f with SMTP id x7-20020a0dee07000000b00324cb8a130fmr26672570ywe.409.1660111271650; Tue, 09 Aug 2022 23:01:11 -0700 (PDT) Date: Tue, 9 Aug 2022 23:00:37 -0700 In-Reply-To: <20220810060040.321697-1-saravanak@google.com> Message-Id: <20220810060040.321697-9-saravanak@google.com> Mime-Version: 1.0 References: <20220810060040.321697-1-saravanak@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v1 8/9] driver core: fw_devlink: Make cycle detection more robust From: Saravana Kannan To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Linus Walleij , Bartosz Golaszewski , Rob Herring , Frank Rowand , Geert Uytterhoeven , Magnus Damm , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Len Brown Cc: Saravana Kannan , Abel Vesa , Alexander Stein , Tony Lindgren , Sudeep Holla , Geert Uytterhoeven , John Stultz , Doug Anderson , Guenter Roeck , kernel-team@android.com, linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-acpi@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org fw_devlink could only detect a single and simple cycle because it relied mainly on device link cycle detection code that only checked for cycles between devices. The expectation was that the firmware wouldn't have complicated cycles and multiple cycles between devices. That expectation has been proven to be wrong. For example, fw_devlink could handle: +-+ +-+ |A+------> |B+ +-+ +++ ^ | | | +----------+ But it couldn't handle even something as "simple" as: +---------------------+ | | v | +-+ +-+ +++ |A+------> |B+------> |C| +-+ +++ +-+ ^ | | | +----------+ But firmware has even more complicated cycles like: +---------------------+ | | v | +-+ +---+ +++ +--+A+------>| B +-----> |C|<--+ | +-+ ++--+ +++ | | ^ | ^ | | | | | | | | | +---------+ +---------+ | | | +------------------------------+ And this is without including parent child dependencies or nodes in the cycle that are just firmware nodes that'll never have a struct device created for them. The proper way to treat these devices it to not force any probe ordering between them, while still enforce dependencies between node in the cycles (A, B and C) and their consumers. So this patch goes all out and just deals with all types of cycles. It does this by: 1. Following dependencies across device links, parent-child and fwnode links. 2. When it find cycles, it mark the device links and fwnode links as such instead of just deleting them or making the indistinguishable from proxy SYNC_STATE_ONLY device links. This way, when new nodes get added, we can immediately find and mark any new cycles whether the new node is a device or firmware node. Signed-off-by: Saravana Kannan --- drivers/base/core.c | 245 +++++++++++++++++++++++--------------------- 1 file changed, 130 insertions(+), 115 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 296cfb714fe1..2f012e826986 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1864,47 +1864,6 @@ static void fw_devlink_unblock_consumers(struct device *dev) device_links_write_unlock(); } -/** - * fw_devlink_relax_cycle - Convert cyclic links to SYNC_STATE_ONLY links - * @con: Device to check dependencies for. - * @sup: Device to check against. - * - * Check if @sup depends on @con or any device dependent on it (its child or - * its consumer etc). When such a cyclic dependency is found, convert all - * device links created solely by fw_devlink into SYNC_STATE_ONLY device links. - * This is the equivalent of doing fw_devlink=permissive just between the - * devices in the cycle. We need to do this because, at this point, fw_devlink - * can't tell which of these dependencies is not a real dependency. - * - * Return 1 if a cycle is found. Otherwise, return 0. - */ -static int fw_devlink_relax_cycle(struct device *con, void *sup) -{ - struct device_link *link; - int ret; - - if (con == sup) - return 1; - - ret = device_for_each_child(con, sup, fw_devlink_relax_cycle); - if (ret) - return ret; - - list_for_each_entry(link, &con->links.consumers, s_node) { - if (!(link->flags & DL_FLAG_CYCLE) && - device_link_flag_is_sync_state_only(link->flags)) - continue; - - if (!fw_devlink_relax_cycle(link->consumer, sup)) - continue; - - ret = 1; - - fw_devlink_relax_link(link); - link->flags |= DL_FLAG_CYCLE; - } - return ret; -} static bool fwnode_init_without_drv(struct fwnode_handle *fwnode) { @@ -1935,6 +1894,113 @@ static bool fwnode_ancestor_init_without_drv(struct fwnode_handle *fwnode) return false; } +/** + * __fw_devlink_relax_cycles - Relax and mark dependency cycles. + * @con: Potential consumer device. + * @sup_handle: Potential supplier's fwnode. + * + * Needs to be called with fwnode_lock and device link lock held. + * + * Check if @sup_handle or any of its ancestors or suppliers direct/indirectly + * depend on @con. This function can detect multiple cyles between @sup_handle + * and @con. When such dependency cycles are found, convert all device links + * created solely by fw_devlink into SYNC_STATE_ONLY device links. Also, mark + * all fwnode links in the cycle with FWLINK_FLAG_CYCLE so that when they are + * converted into a device link in the future, they are created as + * SYNC_STATE_ONLY device links. This is the equivalent of doing + * fw_devlink=permissive just between the devices in the cycle. We need to do + * this because, at this point, fw_devlink can't tell which of these + * dependencies is not a real dependency. + * + * Return true if one or more cycles were found. Otherwise, return false. + */ +static bool __fw_devlink_relax_cycles(struct device *con, + struct fwnode_handle *sup_handle) +{ + struct fwnode_link *link; + struct device_link *dev_link; + struct device *sup_dev = NULL, *par_dev = NULL; + bool ret = false; + + if (!sup_handle) + return false; + + /* + * We aren't trying to find all cycles. Just a cycle between con and + * sup_handle. + */ + if (sup_handle->flags & FWNODE_FLAG_VISITED) + return false; + + sup_handle->flags |= FWNODE_FLAG_VISITED; + + sup_dev = get_dev_from_fwnode(sup_handle); + + /* Termination condition. */ + if (sup_dev == con) { + ret = true; + goto out; + } + + /* + * If sup_dev is bound to a driver and @con hasn't started binding to + * a driver, @sup_dev can't be a consumer of @con. So, no need to + * check further. + */ + if (sup_dev && sup_dev->links.status == DL_DEV_DRIVER_BOUND && + con->links.status == DL_DEV_NO_DRIVER) { + ret = false; + goto out; + } + + list_for_each_entry(link, &sup_handle->suppliers, c_hook) { + if (__fw_devlink_relax_cycles(con, link->supplier)) { + __fwnode_link_cycle(link); + ret = true; + } + } + + /* + * Give priority to device parent over fwnode parent to account for any + * quirks in how fwnodes are converted to devices. + */ + if (sup_dev) { + par_dev = sup_dev->parent; + get_device(par_dev); + } else { + par_dev = fwnode_get_next_parent_dev(sup_handle); + } + + if (par_dev) + ret |= __fw_devlink_relax_cycles(con, par_dev->fwnode); + + if (!sup_dev) + goto out; + + list_for_each_entry(dev_link, &sup_dev->links.suppliers, c_node) { + /* + * Ignore a SYNC_STATE_ONLY flag only if it wasn't marked as a + * such due to a cycle. + */ + if (device_link_flag_is_sync_state_only(dev_link->flags) && + !(dev_link->flags & DL_FLAG_CYCLE)) + continue; + + if (__fw_devlink_relax_cycles(con, + dev_link->supplier->fwnode)) { + fw_devlink_relax_link(dev_link); + dev_link->flags |= DL_FLAG_CYCLE; + ret = true; + } + } + +out: + sup_handle->flags &= ~FWNODE_FLAG_VISITED; + put_device(sup_dev); + put_device(par_dev); + return ret; +} + /** * fw_devlink_create_devlink - Create a device link from a consumer to fwnode * @con: consumer device for the device link @@ -1987,6 +2053,21 @@ static int fw_devlink_create_devlink(struct device *con, fwnode_is_ancestor_of(sup_handle, con->fwnode)) return -EINVAL; + /* + * SYNC_STATE_ONLY device links don't block probing and supports cycles. + * So cycle detection isn't necessary and shouldn't be done. + */ + if (!(flags & DL_FLAG_SYNC_STATE_ONLY)) { + device_links_write_lock(); + if (__fw_devlink_relax_cycles(con, sup_handle)) { + __fwnode_link_cycle(link); + flags = fw_devlink_get_flags(link->flags); + dev_info(con, "Fixed dependency cycle(s) with %pfwf\n", + sup_handle); + } + device_links_write_unlock(); + } + sup_dev = get_dev_from_fwnode(sup_handle); if (sup_dev) { /* @@ -1996,23 +2077,16 @@ static int fw_devlink_create_devlink(struct device *con, */ if (sup_dev->links.status == DL_DEV_NO_DRIVER && sup_handle->flags & FWNODE_FLAG_INITIALIZED) { + dev_dbg(con, + "Not linking %pfwf - dev might never probe\n", + sup_handle); ret = -EINVAL; goto out; } - /* - * If this fails, it is due to cycles in device links. Just - * give up on this link and treat it as invalid. - */ - if (!device_link_add(con, sup_dev, flags) && - !(flags & DL_FLAG_SYNC_STATE_ONLY)) { - dev_info(con, "Fixing up cyclic dependency with %s\n", - dev_name(sup_dev)); - device_links_write_lock(); - fw_devlink_relax_cycle(con, sup_dev); - device_links_write_unlock(); - device_link_add(con, sup_dev, - FW_DEVLINK_FLAGS_PERMISSIVE); + if (!device_link_add(con, sup_dev, flags)) { + dev_err(con, "Failed to create device link with %s\n", + dev_name(sup_dev)); ret = -EINVAL; } @@ -2025,49 +2099,12 @@ static int fw_devlink_create_devlink(struct device *con, */ if (fwnode_init_without_drv(sup_handle) || fwnode_ancestor_init_without_drv(sup_handle)) { - dev_dbg(con, "Not linking %pfwP - Might never probe\n", + dev_dbg(con, "Not linking %pfwf - might never become dev\n", sup_handle); return -EINVAL; } - /* - * DL_FLAG_SYNC_STATE_ONLY doesn't block probing and supports - * cycles. So cycle detection isn't necessary and shouldn't be - * done. - */ - if (flags & DL_FLAG_SYNC_STATE_ONLY) - return -EAGAIN; - - /* - * If we can't find the supplier device from its fwnode, it might be - * due to a cyclic dependency between fwnodes. Some of these cycles can - * be broken by applying logic. Check for these types of cycles and - * break them so that devices in the cycle probe properly. - * - * If the supplier's parent is dependent on the consumer, then the - * consumer and supplier have a cyclic dependency. Since fw_devlink - * can't tell which of the inferred dependencies are incorrect, don't - * enforce probe ordering between any of the devices in this cyclic - * dependency. Do this by relaxing all the fw_devlink device links in - * this cycle and by treating the fwnode link between the consumer and - * the supplier as an invalid dependency. - */ - sup_dev = fwnode_get_next_parent_dev(sup_handle); - if (sup_dev && device_is_dependent(con, sup_dev)) { - dev_info(con, "Fixing up cyclic dependency with %pfwP (%s)\n", - sup_handle, dev_name(sup_dev)); - device_links_write_lock(); - fw_devlink_relax_cycle(con, sup_dev); - device_links_write_unlock(); - ret = -EINVAL; - } else { - /* - * Can't check for cycles or no cycles. So let's try - * again later. - */ - ret = -EAGAIN; - } - + ret = -EAGAIN; out: put_device(sup_dev); return ret; @@ -2174,7 +2211,6 @@ static void __fw_devlink_link_to_suppliers(struct device *dev, list_for_each_entry_safe(link, tmp, &fwnode->suppliers, c_hook) { int ret; - struct device *sup_dev; struct fwnode_handle *sup = link->supplier; ret = fw_devlink_create_devlink(dev, sup, link); @@ -2182,27 +2218,6 @@ static void __fw_devlink_link_to_suppliers(struct device *dev, continue; __fwnode_link_del(link); - - /* If no device link was created, nothing more to do. */ - if (ret) - continue; - - /* - * If a device link was successfully created to a supplier, we - * now need to try and link the supplier to all its suppliers. - * - * This is needed to detect and delete false dependencies in - * fwnode links that haven't been converted to a device link - * yet. See comments in fw_devlink_create_devlink() for more - * details on the false dependency. - * - * Without deleting these false dependencies, some devices will - * never probe because they'll keep waiting for their false - * dependency fwnode links to be converted to device links. - */ - sup_dev = get_dev_from_fwnode(sup); - __fw_devlink_link_to_suppliers(sup_dev, sup_dev->fwnode); - put_device(sup_dev); } /*