From patchwork Wed Aug 10 06:00:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 596680 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 71BB8C25B0E for ; Wed, 10 Aug 2022 06:01:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231153AbiHJGB1 (ORCPT ); Wed, 10 Aug 2022 02:01:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59814 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231134AbiHJGAx (ORCPT ); Wed, 10 Aug 2022 02:00:53 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B3CE1160 for ; Tue, 9 Aug 2022 23:00:51 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31f58599ad3so119778167b3.20 for ; Tue, 09 Aug 2022 23:00:51 -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=yrSVoQ6qAYfctoHLwpmXbxKbM2DM2+R0yDzKfNT+j3U=; b=izJdAflNpJVWEHox4ERNJay3x/S/To+x9+9KV2R1NX8mVvLkWbAu6pJiC9H/0M2NLn ocfw4JmzrHQavKYT18YDK+gRqRMLcmdMUlfVbEdUf1j5kocdA8ySJfeFlofn11B2cfFz L++awHGTPcRZ7ppPUyPRLd9hJzIs+EpLqWOSJazPVt5H2lMeAtFzeElMKf++YUZJHiLb isRQVJNIFzGeSCHAvXXWt4EwTkNgXEVtj5u56DjinNjAVlJDGrYeypA2UodBtn4uxhAR g5j/JPv9wvCk1M9zcUEHPTHcUKe5W/ChBf53weBSEyaV0ZknXYDa9svnM+XwA9IPjEhH CkhA== 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=yrSVoQ6qAYfctoHLwpmXbxKbM2DM2+R0yDzKfNT+j3U=; b=rvZq5Uk9cn4lsVUAF7jsS7ZNp/T3Ln8+3YGeJ8gOrLg0um99+p/Y0qSmeAUtA6e6wf 8wjNVneE+Oag6ui/IA3k4sh/z5JYfUXDorNWN8dz60WdW8QlQRfHi9xVVq87Vq5Nredh KByfYaZwpNsUTagVcoNAa4VRVrfQAasKqQ2j4Rk0jtyT/TstgOLmGtNfI0oa1a3Xq4Rd Qvn1inWsSigMvX8LAkUuT4PRWY40SoZIxC5cJ5oWHDFnBSDMyFKCollp16SV3w4jA11f y7HhehJq9qXYkn285CVSFxEfHtHiAsUiC0a+2dIF1ytSlkfYVH+GuTfiUF4bOEgq5N7d 2TZQ== X-Gm-Message-State: ACgBeo3NDp5f6v/exuJzJkK4seiAxA1xPOE6AbYJW42w7Ju37ZHl2UJi cn7tIcAn2gd7L2NXtuaNa9SUsUqnr0qklwA= X-Google-Smtp-Source: AA6agR6oBnWJI1pwT9B0nAdocGFOqlZelz8ZvTX+uF4itGLdhkdgHLvMyL5bD42EBVo8bfxVt++iHuhLW/lxloY= X-Received: from saravanak.san.corp.google.com ([2620:15c:2d:3:f21:76ca:766f:e0ab]) (user=saravanak job=sendgmr) by 2002:a25:8101:0:b0:676:c7fd:2143 with SMTP id o1-20020a258101000000b00676c7fd2143mr22340191ybk.364.1660111250277; Tue, 09 Aug 2022 23:00:50 -0700 (PDT) Date: Tue, 9 Aug 2022 23:00:30 -0700 In-Reply-To: <20220810060040.321697-1-saravanak@google.com> Message-Id: <20220810060040.321697-2-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 1/9] driver core: fw_devlink: Don't purge child fwnode's consumer links 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: linux-acpi@vger.kernel.org When a device X is bound successfully to a driver, if it has a child firmware node Y that doesn't have a struct device created by then, we delete fwnode links where the child firmware node Y is the supplier. We did this to avoid blocking the consumers of the child firmware node Y from deferring probe indefinitely. While that a step in the right direction, it's better to make the consumers of the child firmware node Y to be consumers of the device X because device X is probably implementing whatever functionality is represented by child firmware node Y. By doing this, we capture the device dependencies more accurately and ensure better probe/suspend/resume ordering. Signed-off-by: Saravana Kannan --- drivers/base/core.c | 91 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 17 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 753e7cca0f40..6f575c2a24ad 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -53,11 +53,12 @@ static LIST_HEAD(deferred_sync); static unsigned int defer_sync_state_count = 1; static DEFINE_MUTEX(fwnode_link_lock); static bool fw_devlink_is_permissive(void); +static void __fw_devlink_link_to_consumers(struct device *dev); static bool fw_devlink_drv_reg_done; static bool fw_devlink_best_effort; /** - * fwnode_link_add - Create a link between two fwnode_handles. + * __fwnode_link_add - Create a link between two fwnode_handles. * @con: Consumer end of the link. * @sup: Supplier end of the link. * @@ -73,22 +74,18 @@ static bool fw_devlink_best_effort; * Attempts to create duplicate links between the same pair of fwnode handles * are ignored and there is no reference counting. */ -int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup) +static int __fwnode_link_add(struct fwnode_handle *con, + struct fwnode_handle *sup) { struct fwnode_link *link; - int ret = 0; - - mutex_lock(&fwnode_link_lock); list_for_each_entry(link, &sup->consumers, s_hook) if (link->consumer == con) - goto out; + return 0; link = kzalloc(sizeof(*link), GFP_KERNEL); - if (!link) { - ret = -ENOMEM; - goto out; - } + if (!link) + return -ENOMEM; link->supplier = sup; INIT_LIST_HEAD(&link->s_hook); @@ -99,9 +96,17 @@ int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup) list_add(&link->c_hook, &con->suppliers); pr_debug("%pfwP Linked as a fwnode consumer to %pfwP\n", con, sup); -out: - mutex_unlock(&fwnode_link_lock); + return 0; +} + +int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup) +{ + int ret = 0; + + mutex_lock(&fwnode_link_lock); + ret = __fwnode_link_add(con, sup); + mutex_unlock(&fwnode_link_lock); return ret; } @@ -180,6 +185,51 @@ void fw_devlink_purge_absent_suppliers(struct fwnode_handle *fwnode) } EXPORT_SYMBOL_GPL(fw_devlink_purge_absent_suppliers); +/** + * __fwnode_links_move_consumers - Move consumer from @from to @to fwnode_handle + * @from: move consumers away from this fwnode + * @to: move consumers to this fwnode + * + * Move all consumer links from @from fwnode to @to fwnode. + */ +static void __fwnode_links_move_consumers(struct fwnode_handle *from, + struct fwnode_handle *to) +{ + struct fwnode_link *link, *tmp; + + list_for_each_entry_safe(link, tmp, &from->consumers, s_hook) { + __fwnode_link_add(link->consumer, to); + __fwnode_link_del(link); + } +} + +/** + * __fw_devlink_pickup_dangling_consumers - Pick up dangling consumers + * @fwnode: fwnode from which to pick up dangling consumers + * @new_sup: fwnode of new supplier + * + * If the @fwnode has a corresponding struct device and the device supports + * probing (that is, added to a bus), then we want to let fw_devlink create + * MANAGED device links to this device, so leave @fwnode and its descendant's + * fwnode links alone. + * + * Otherwise, move its consumers to the new supplier @new_sup. + */ +static void __fw_devlink_pickup_dangling_consumers(struct fwnode_handle *fwnode, + struct fwnode_handle *new_sup) +{ + struct fwnode_handle *child; + + if (fwnode->dev && fwnode->dev->bus) + return; + + fwnode->flags |= FWNODE_FLAG_NOT_DEVICE; + __fwnode_links_move_consumers(fwnode, new_sup); + + fwnode_for_each_available_child_node(fwnode, child) + __fw_devlink_pickup_dangling_consumers(child, new_sup); +} + #ifdef CONFIG_SRCU static DEFINE_MUTEX(device_links_lock); DEFINE_STATIC_SRCU(device_links_srcu); @@ -1266,16 +1316,23 @@ void device_links_driver_bound(struct device *dev) * them. So, fw_devlink no longer needs to create device links to any * of the device's suppliers. * - * Also, if a child firmware node of this bound device is not added as - * a device by now, assume it is never going to be added and make sure - * other devices don't defer probe indefinitely by waiting for such a - * child device. + * Also, if a child firmware node of this bound device is not added as a + * device by now, assume it is never going to be added. Make this bound + * device the fallback supplier to the dangling consumers of the child + * firmware node because this bound device is probably implementing the + * child firmware node functionality and we don't want the dangling + * consumers to defer probe indefinitely waiting for a device for the + * child firmware node. */ if (dev->fwnode && dev->fwnode->dev == dev) { struct fwnode_handle *child; fwnode_links_purge_suppliers(dev->fwnode); + mutex_lock(&fwnode_link_lock); fwnode_for_each_available_child_node(dev->fwnode, child) - fw_devlink_purge_absent_suppliers(child); + __fw_devlink_pickup_dangling_consumers(child, + dev->fwnode); + __fw_devlink_link_to_consumers(dev); + mutex_unlock(&fwnode_link_lock); } device_remove_file(dev, &dev_attr_waiting_for_supplier); From patchwork Wed Aug 10 06:00:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 596451 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 33D00C32757 for ; Wed, 10 Aug 2022 06:01:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231244AbiHJGB3 (ORCPT ); Wed, 10 Aug 2022 02:01:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59846 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230410AbiHJGAy (ORCPT ); Wed, 10 Aug 2022 02:00:54 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DF8EFE50 for ; Tue, 9 Aug 2022 23:00:53 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31f4e870a17so117598687b3.9 for ; Tue, 09 Aug 2022 23:00:53 -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=4jRmKhAnaVbGZ2PreR5yx2mRFJMw6J4dpUJKDGI8VVo=; b=OxT4AfmfLdEyfSQy0e92Efv0g+qYB6QYUz9bkXmQdeby668KcDAmVDJ7bOyUq7V0F2 QALyFz4wMMi53j3QRCAb8qA9F+kZ1RKov1W6yjvk3SKS5E1/4yAukI31vXSaR+iB3oH4 km0WTV6SkAwda2RS0hxEubyt9id8QjSpq7NCkQLS8tmgOqv78QQNaHTuxCkqp8rBkGOH fcESgAQOAIZcbW5as7agp9686kHQSepZw1hJrV0JV73xCs8a7LY61agm1fKZt383OK3W 84tW+occS8vIst00z0DYIJCMd4j9nmKVCYBFqM+yy8FYxe+FfwkJaFWeg01XxWaXlojV Zmrw== 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=4jRmKhAnaVbGZ2PreR5yx2mRFJMw6J4dpUJKDGI8VVo=; b=7b1/6CpINV6Mq3/nYGp0LYo1KmyMCjKK3TNqn8YW1rNxR2Cs5Xzs4jtWNNbXJ+0FNM RYVGY80LX4rTy/hYeB42n5Q9G9McYjETLSNwS3lEVOBAe8VEadOAkfjyDKQuQWas2aXg G38BpUMCRhRnKs6xTbo7BYsWQjruW+CkIEbMY7RlE9AnvQprkx4tQ0OAwbxDyu/l1nJd KfvErXFUNWiYePMQ5Q4pk6AFm7hhqPCM1UdbvFefxJXKL5G7LWNmc96i1sFua4D0yjAA 7XTbAIcVKXk1S6a1OYFChcykIn+ZENmDb3ziDceZglHNnmbK9h1Tl9E2njuvoGld33h+ BZFg== X-Gm-Message-State: ACgBeo1IiGa5KTNmAYTTyZh2Na/FFNltiZb5cIrlpYYAdA1FsqJXckwc GxZPOq8U57kIbpyrcaW3h2A+qAAhfv6Ot5U= X-Google-Smtp-Source: AA6agR4LK1d08yF8VFqxVeTLzEMYhLg37uu6dTwQPfrrHS+Sz8rRBpZ19EPAFfrDH7CMKMId84Ir4l+P4wWpB8o= X-Received: from saravanak.san.corp.google.com ([2620:15c:2d:3:f21:76ca:766f:e0ab]) (user=saravanak job=sendgmr) by 2002:a05:6902:108c:b0:67b:bc33:ef01 with SMTP id v12-20020a056902108c00b0067bbc33ef01mr15758584ybu.251.1660111253153; Tue, 09 Aug 2022 23:00:53 -0700 (PDT) Date: Tue, 9 Aug 2022 23:00:31 -0700 In-Reply-To: <20220810060040.321697-1-saravanak@google.com> Message-Id: <20220810060040.321697-3-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 2/9] driver core: fw_devlink: Improve check for fwnode with no device/driver 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: linux-acpi@vger.kernel.org fw_devlink shouldn't defer the probe of a device to wait on a supplier that'll never have a struct device or will never be probed by a driver. We currently check if a supplier falls into this category, but don't check its ancestors. We need to check the ancestors too because if the ancestor will never probe, then the supplier will never probe either. Signed-off-by: Saravana Kannan --- drivers/base/core.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 6f575c2a24ad..8ec2236b1f9c 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1866,6 +1866,35 @@ static int fw_devlink_relax_cycle(struct device *con, void *sup) return ret; } +static bool fwnode_init_without_drv(struct fwnode_handle *fwnode) +{ + struct device *dev; + bool ret; + + if (!(fwnode->flags & FWNODE_FLAG_INITIALIZED)) + return false; + + dev = get_dev_from_fwnode(fwnode); + ret = !dev || dev->links.status == DL_DEV_NO_DRIVER; + put_device(dev); + + return ret; +} + +static bool fwnode_ancestor_init_without_drv(struct fwnode_handle *fwnode) +{ + struct fwnode_handle *parent; + + fwnode_for_each_parent_node(fwnode, parent) { + if (fwnode_init_without_drv(parent)) { + fwnode_handle_put(parent); + return true; + } + } + + return false; +} + /** * fw_devlink_create_devlink - Create a device link from a consumer to fwnode * @con: consumer device for the device link @@ -1943,9 +1972,16 @@ static int fw_devlink_create_devlink(struct device *con, goto out; } - /* Supplier that's already initialized without a struct device. */ - if (sup_handle->flags & FWNODE_FLAG_INITIALIZED) + /* + * Supplier or supplier's ancestor already initialized without a struct + * device or being probed by a driver. + */ + if (fwnode_init_without_drv(sup_handle) || + fwnode_ancestor_init_without_drv(sup_handle)) { + dev_dbg(con, "Not linking %pfwP - Might never probe\n", + sup_handle); return -EINVAL; + } /* * DL_FLAG_SYNC_STATE_ONLY doesn't block probing and supports 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: 596679 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 43877C2BBC5 for ; Wed, 10 Aug 2022 06:01:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230410AbiHJGBa (ORCPT ); Wed, 10 Aug 2022 02:01:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59926 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231178AbiHJGA5 (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 DD5306423 for ; Tue, 9 Aug 2022 23:00:56 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id v19-20020a252f13000000b0067174f085e9so11342208ybv.1 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=XWDT9fguFi7T8a1StHC3P70JiNo+sEYS/PH0phJy2Nz+bzxpuTHZtYS1OgapvL8J1K BCyTLUej8jyxLwC4YKvFsJJGWbveAjWBWk7Bj6mUsqFPRZE4xl0QU39BElP3TqsAhfYT OO/IWJ0qsqSzM+7QD4puJIQoPrddFUTe8e9ZHQ0SAVfhwIv/SG1ulkSIU+r0/6dl9CDv i1UkoEokXBCpD5LMogz3oSXj06EGPoSd1M4h3nTUUpJKuxkpKkj4ZV3cSFq2xromO3ox TrLpAwwq0smnatl2To5smtiaAJj84/y59zTPBUT/fSCST3QwjJjBZzRY0LOvApB+XER5 YyBA== X-Gm-Message-State: ACgBeo2sKas7oYRC/Tgh/cd0s0gjF/yIG3+2BXYPAKRgWA/YBRYPz0rr Gehzov2mHfOXdT8R4TKJQ127ndaIOYy+wLc= 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: linux-acpi@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: 596450 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 A1EA3C32766 for ; Wed, 10 Aug 2022 06:01:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231252AbiHJGBb (ORCPT ); Wed, 10 Aug 2022 02:01:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59988 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231183AbiHJGBA (ORCPT ); Wed, 10 Aug 2022 02:01:00 -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 13ED61EAE7 for ; Tue, 9 Aug 2022 23:00:59 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id u44-20020a25ab2f000000b0067c1b3e9fceso3738804ybi.17 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=0Gzh7FiLWBHnLLlb3wkq9RfTSWas7DOhE299Jx4rJ5MmkE4au4DZ0IaSiwv85XY7Av bxXL2aGgPR8MSHdBK/IVZZZX19ujJDnaRslKhEAtzzh0MITt7llfELzmf9RSCA820FJI eqNkDVDpoSxvYmNbKC0Ditp6UrFuQrJzJ0Qr/ue66+aU1LVMxeBhwjdLd5M9AevqAV6k dFHb6T5nxrJmykP7e/pVQb6D6SyunAXiVnMSCmYsuRNtltYPyEtwkdDXKKXAIutDDczV bikhN/GKys5626hR7LRFufu5WFzwBBb+33eEESsb35HQk7Z0TcNd+pbXjRm3wI6Hhx97 wHsQ== X-Gm-Message-State: ACgBeo0m3iMYD951UU7v4gerWirLncTQHwtvnREFoSWNG4FOnHZFWnuj zqflfjKlI1COaWYqY8kyBjTXn9KZdc3ilzE= 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: linux-acpi@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 Acked-by: Bartosz Golaszewski --- 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:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 596678 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 6FADFC00140 for ; Wed, 10 Aug 2022 06:02:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231256AbiHJGBc (ORCPT ); Wed, 10 Aug 2022 02:01:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60058 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231194AbiHJGBD (ORCPT ); Wed, 10 Aug 2022 02:01:03 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3EE8D1ADA6 for ; Tue, 9 Aug 2022 23:01:02 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31f58599ad3so119782797b3.20 for ; Tue, 09 Aug 2022 23:01:02 -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=zsc6LReCkj1qjWFHoe9RU5QlsrwqzoWhqcv1gy5ixZY=; b=qAChj47DwLOrFVomS2lGpLSpKGvd1Ma7wbTL3BaBnyvNDdaT6wQcELiK3Z2S6rKmW6 4RCg3rt6j2rD/dXyIpiJAt0rXCb4GtTf9uNP6hZi708k7YPc7ZxFVW1djWMkZKngZUyC 9ZOMJL5O3k7bMThCT+oPldcDnUF4i0ommrfHppvhsYUq/eEQsh/fyoQBlUi7r5vctc/F 9u/dHFrzIRRFZvBW99iEWRVEUfrxv+VRxXw6eyDf8bHeE9dwuyd1QG8zMM9IyxoXCqpp yxsC7TNyQiZWMwjfcKw173fewjgqVWZOvnFwQB5H8vymYFjevDNXEPOljd/VGIQLMaOQ 7eew== 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=zsc6LReCkj1qjWFHoe9RU5QlsrwqzoWhqcv1gy5ixZY=; b=yyuCGhC/Q2KmGkc6ogt7Jy3cjScXDDtUacTQNB+rGAMNl0Do/xhY8FgTvw+R3NEnXG VAzIqTvvCrp1wMZ0LSKKXhSkjgDQFh+/ZpwwuKXKiTMVVr2vIUIN8h22ahpkLjN5ghvT nI9ADO/xU7LBUEZDyS/zOwCcAYkiBtjAiXg8+T3eXnbF7OxIcXeTVa5SEQshkARqo3fV K8lN7r8jbHs5+KB1ru3GoLBfzGCLfv0gA6C3l8yfgH0llfjS8q6kh4uQXXJNdQz2wmMI hPkOawxAmPO1ajSTCAkqJ6kfytzk7heAK/uVIo+jVzYTj0Fj+M/XP3iHGvaAKgIVEqxt p6og== X-Gm-Message-State: ACgBeo0Xo24Sxh2E5y3BAK+muQ9Ucs4NlhRVsyePgsU1SxS5psXQOqRZ oHcUgt1fRLDmZTuiUjEZnK7dnxavlDKIdpA= X-Google-Smtp-Source: AA6agR7UHIfPmQyEJpTq1ANtIM/YpnjUfuF4LCqgIoVdmjpw9+J9eqTmKa2fu2A5mGFX/RbYZr7v9jvnFZ4Lhg0= X-Received: from saravanak.san.corp.google.com ([2620:15c:2d:3:f21:76ca:766f:e0ab]) (user=saravanak job=sendgmr) by 2002:a05:6902:100d:b0:67a:7141:a2bf with SMTP id w13-20020a056902100d00b0067a7141a2bfmr23586344ybt.54.1660111261905; Tue, 09 Aug 2022 23:01:01 -0700 (PDT) Date: Tue, 9 Aug 2022 23:00:34 -0700 In-Reply-To: <20220810060040.321697-1-saravanak@google.com> Message-Id: <20220810060040.321697-6-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 5/9] driver core: fw_devlink: Add DL_FLAG_CYCLE support to device links 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: linux-acpi@vger.kernel.org fw_devlink uses DL_FLAG_SYNC_STATE_ONLY device link flag for two purposes: 1. To allow a parent device to proxy its child device's dependency on a supplier so that the supplier doesn't get its sync_state() callback before the child device/consumer can be added and probed. In this usage scenario, we need to ignore cycles for ensure correctness of sync_state() callbacks. 2. When there are dependency cycles in firmware, we don't know which of those dependencies are valid. So, we have to ignore them all wrt probe ordering while still making sure the sync_state() callbacks come correctly. However, when detecting dependency cycles, there can be multiple dependency cycles between two devices that we need to detect. For example: A -> B -> A and A -> C -> B -> A. To detect multiple cycles correct, we need to be able to differentiate DL_FLAG_SYNC_STATE_ONLY device links used for (1) vs (2) above. To allow this differentiation, add a DL_FLAG_CYCLE that can be use to mark use case (2). We can then use the DL_FLAG_CYCLE to decide which DL_FLAG_SYNC_STATE_ONLY device links to follow when looking for dependency cycles. Signed-off-by: Saravana Kannan --- drivers/base/core.c | 28 ++++++++++++++++++---------- include/linux/device.h | 1 + 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 8ec2236b1f9c..afa660d14172 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -321,6 +321,12 @@ static bool device_is_ancestor(struct device *dev, struct device *target) return false; } +static inline bool device_link_flag_is_sync_state_only(u32 flags) +{ + return (flags & ~(DL_FLAG_INFERRED | DL_FLAG_CYCLE)) + == (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED); +} + /** * device_is_dependent - Check if one device depends on another one * @dev: Device to check dependencies for. @@ -347,8 +353,7 @@ int device_is_dependent(struct device *dev, void *target) return ret; list_for_each_entry(link, &dev->links.consumers, s_node) { - if ((link->flags & ~DL_FLAG_INFERRED) == - (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED)) + if (device_link_flag_is_sync_state_only(link->flags)) continue; if (link->consumer == target) @@ -421,8 +426,7 @@ static int device_reorder_to_tail(struct device *dev, void *not_used) device_for_each_child(dev, NULL, device_reorder_to_tail); list_for_each_entry(link, &dev->links.consumers, s_node) { - if ((link->flags & ~DL_FLAG_INFERRED) == - (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED)) + if (device_link_flag_is_sync_state_only(link->flags)) continue; device_reorder_to_tail(link->consumer, NULL); } @@ -683,7 +687,8 @@ postcore_initcall(devlink_class_init); DL_FLAG_AUTOREMOVE_SUPPLIER | \ DL_FLAG_AUTOPROBE_CONSUMER | \ DL_FLAG_SYNC_STATE_ONLY | \ - DL_FLAG_INFERRED) + DL_FLAG_INFERRED | \ + DL_FLAG_CYCLE) #define DL_ADD_VALID_FLAGS (DL_MANAGED_LINK_FLAGS | DL_FLAG_STATELESS | \ DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE) @@ -752,8 +757,6 @@ struct device_link *device_link_add(struct device *consumer, if (!consumer || !supplier || consumer == supplier || flags & ~DL_ADD_VALID_FLAGS || (flags & DL_FLAG_STATELESS && flags & DL_MANAGED_LINK_FLAGS) || - (flags & DL_FLAG_SYNC_STATE_ONLY && - (flags & ~DL_FLAG_INFERRED) != DL_FLAG_SYNC_STATE_ONLY) || (flags & DL_FLAG_AUTOPROBE_CONSUMER && flags & (DL_FLAG_AUTOREMOVE_CONSUMER | DL_FLAG_AUTOREMOVE_SUPPLIER))) @@ -769,6 +772,10 @@ struct device_link *device_link_add(struct device *consumer, if (!(flags & DL_FLAG_STATELESS)) flags |= DL_FLAG_MANAGED; + if (flags & DL_FLAG_SYNC_STATE_ONLY && + !device_link_flag_is_sync_state_only(flags)) + return NULL; + device_links_write_lock(); device_pm_lock(); @@ -1728,7 +1735,7 @@ static void fw_devlink_relax_link(struct device_link *link) if (!(link->flags & DL_FLAG_INFERRED)) return; - if (link->flags == (DL_FLAG_MANAGED | FW_DEVLINK_FLAGS_PERMISSIVE)) + if (device_link_flag_is_sync_state_only(link->flags)) return; pm_runtime_drop_link(link); @@ -1852,8 +1859,8 @@ static int fw_devlink_relax_cycle(struct device *con, void *sup) return ret; list_for_each_entry(link, &con->links.consumers, s_node) { - if ((link->flags & ~DL_FLAG_INFERRED) == - (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED)) + if (!(link->flags & DL_FLAG_CYCLE) && + device_link_flag_is_sync_state_only(link->flags)) continue; if (!fw_devlink_relax_cycle(link->consumer, sup)) @@ -1862,6 +1869,7 @@ static int fw_devlink_relax_cycle(struct device *con, void *sup) ret = 1; fw_devlink_relax_link(link); + link->flags |= DL_FLAG_CYCLE; } return ret; } diff --git a/include/linux/device.h b/include/linux/device.h index 424b55df0272..7cf24330d681 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -327,6 +327,7 @@ enum device_link_state { #define DL_FLAG_MANAGED BIT(6) #define DL_FLAG_SYNC_STATE_ONLY BIT(7) #define DL_FLAG_INFERRED BIT(8) +#define DL_FLAG_CYCLE BIT(9) /** * enum dl_dev_state - Device driver presence tracking information. From patchwork Wed Aug 10 06:00:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 596449 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 87418C32771 for ; Wed, 10 Aug 2022 06:02:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231266AbiHJGBe (ORCPT ); Wed, 10 Aug 2022 02:01:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60146 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231210AbiHJGBH (ORCPT ); Wed, 10 Aug 2022 02:01:07 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 09B7C26AF1 for ; Tue, 9 Aug 2022 23:01:06 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31f5d66fcdeso119607107b3.21 for ; Tue, 09 Aug 2022 23:01:06 -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=fFDScMpOoLwobJ0B+gx6h8x63gnncNppR9XtZLm6ulE=; b=oKH1GriWJVrABfs62WEip/+gg6Dy4kEs7RfdBPtZv1dDVp8IM8ot+pJYb0FYC/j+dW Jmct5LS3sgXZwdmnm2b/XxlhH1LoIyQ0qPOCXNhwwxH+wse2QMfHhqHGs/zhkg4RSn4D g1/uaVkRiojaOGGVwYog0xljtT9cpl4VQHiuhxaZrs5KGEF9koqVuHd1InJ75qg7O6Yo UzvrcZg7E0hHEIPRlyq+1T8XU9GcavBPIWNzQ8biwtu3oLc/cA4w7xVUya1qG9ZCvGlY c3HHAhKT9W4/Jp/npKG8Ei+2a9D86hwmHHvF5aX70NJY8d3uWZXJnFQQeGMksKOP8dTI m+RA== 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=fFDScMpOoLwobJ0B+gx6h8x63gnncNppR9XtZLm6ulE=; b=F8fMLqsIF2tGXnitYKD4R0dSempMqAkpDmzzpH/DT+rXT0QORGBBe1V7XyuVOaG6qt BndhqRP7kRDjzMZH5SP3EbWyFIPayMy62oww5+WzEjhdnRBoRXYlzWIAKg835aIRpCtw hDur+PRi1hn2lNir37+0A2cZlRBn3gg+ru9MVVmpMGtFhjikM7iJ4Vj5lbqnpwK8dd0q tpPXbfd7J2DcB7nOl6kar4zL9c9JIYGu08C1qX3TN4jtuVFmLR+PKKeI/MsZg23ifa6p oyxKmqgISC9C3TXSdtbSIwrh5FGgBcZtm/KG9nMbY3Qbzr8USF+/uRp3CiV0GSyeBEX+ 657A== X-Gm-Message-State: ACgBeo2zY7NWqQpjrzqluk2xQ/nYx67xHusS/LgpJX6R1vmuEhHAvLeQ DAUjO4NDeanISU7l9NVAwn9O+L7QhuhrmxQ= X-Google-Smtp-Source: AA6agR7Ig43NfwU15CHf57OeGOFh7gsI84hi8fC26IKcScIBv/6FfxWUkEv3BAnHx8V4jzQ/X/BwXiqy9EgrIBc= X-Received: from saravanak.san.corp.google.com ([2620:15c:2d:3:f21:76ca:766f:e0ab]) (user=saravanak job=sendgmr) by 2002:a25:fc0f:0:b0:67b:b846:4db2 with SMTP id v15-20020a25fc0f000000b0067bb8464db2mr15311111ybd.566.1660111265238; Tue, 09 Aug 2022 23:01:05 -0700 (PDT) Date: Tue, 9 Aug 2022 23:00:35 -0700 In-Reply-To: <20220810060040.321697-1-saravanak@google.com> Message-Id: <20220810060040.321697-7-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 6/9] driver core: fw_devlink: Allow marking a fwnode link as being part of a cycle 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: linux-acpi@vger.kernel.org To improve detection and handling of dependency cycles, we need to be able to mark fwnode links as being part of cycles. fwnode links marked as being part of a cycle should not block their consumers from probing. Signed-off-by: Saravana Kannan --- drivers/base/core.c | 41 +++++++++++++++++++++++++++++++++++------ include/linux/fwnode.h | 11 ++++++++++- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index afa660d14172..0ec2c4d5ffaa 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -125,6 +125,19 @@ static void __fwnode_link_del(struct fwnode_link *link) kfree(link); } +/** + * __fwnode_link_cycle - Mark a fwnode link as being part of a cycle. + * @link: the fwnode_link to be marked + * + * The fwnode_link_lock needs to be held when this function is called. + */ +static void __fwnode_link_cycle(struct fwnode_link *link) +{ + pr_debug("%pfwf: Relaxing link with %pfwf\n", + link->consumer, link->supplier); + link->flags |= FWLINK_FLAG_CYCLE; +} + /** * fwnode_links_purge_suppliers - Delete all supplier links of fwnode_handle. * @fwnode: fwnode whose supplier links need to be deleted @@ -1040,6 +1053,23 @@ static bool dev_is_best_effort(struct device *dev) (dev->fwnode && (dev->fwnode->flags & FWNODE_FLAG_BEST_EFFORT)); } +static struct fwnode_handle *fwnode_links_check_suppliers( + struct fwnode_handle *fwnode) +{ + struct fwnode_link *link; + + if (!fwnode || fw_devlink_is_permissive()) + return NULL; + + list_for_each_entry(link, &fwnode->suppliers, c_hook) { + if (link->flags & FWLINK_FLAG_CYCLE) + continue; + return link->supplier; + } + + return NULL; +} + /** * device_links_check_suppliers - Check presence of supplier drivers. * @dev: Consumer device. @@ -1067,11 +1097,8 @@ int device_links_check_suppliers(struct device *dev) * probe. */ mutex_lock(&fwnode_link_lock); - if (dev->fwnode && !list_empty(&dev->fwnode->suppliers) && - !fw_devlink_is_permissive()) { - sup_fw = list_first_entry(&dev->fwnode->suppliers, - struct fwnode_link, - c_hook)->supplier; + sup_fw = fwnode_links_check_suppliers(dev->fwnode); + if (sup_fw) { if (!dev_is_best_effort(dev)) { fwnode_ret = -EPROBE_DEFER; dev_err_probe(dev, -EPROBE_DEFER, @@ -1260,7 +1287,9 @@ static ssize_t waiting_for_supplier_show(struct device *dev, bool val; device_lock(dev); - val = !list_empty(&dev->fwnode->suppliers); + mutex_lock(&fwnode_link_lock); + val = !!fwnode_links_check_suppliers(dev->fwnode); + mutex_unlock(&fwnode_link_lock); device_unlock(dev); return sysfs_emit(buf, "%u\n", val); } diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h index 89b9bdfca925..fdf2ee0285b7 100644 --- a/include/linux/fwnode.h +++ b/include/linux/fwnode.h @@ -18,7 +18,7 @@ struct fwnode_operations; struct device; /* - * fwnode link flags + * fwnode flags * * LINKS_ADDED: The fwnode has already be parsed to add fwnode links. * NOT_DEVICE: The fwnode will never be populated as a struct device. @@ -36,6 +36,7 @@ struct device; #define FWNODE_FLAG_INITIALIZED BIT(2) #define FWNODE_FLAG_NEEDS_CHILD_BOUND_ON_ADD BIT(3) #define FWNODE_FLAG_BEST_EFFORT BIT(4) +#define FWNODE_FLAG_VISITED BIT(5) struct fwnode_handle { struct fwnode_handle *secondary; @@ -46,11 +47,19 @@ struct fwnode_handle { u8 flags; }; +/* + * fwnode link flags + * + * CYCLE: The fwnode link is part of a cycle. Don't defer probe. + */ +#define FWLINK_FLAG_CYCLE BIT(0) + struct fwnode_link { struct fwnode_handle *supplier; struct list_head s_hook; struct fwnode_handle *consumer; struct list_head c_hook; + u8 flags; }; /** 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: 596677 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 1276BC38145 for ; Wed, 10 Aug 2022 06:02:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231224AbiHJGBf (ORCPT ); Wed, 10 Aug 2022 02:01:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60206 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231213AbiHJGBK (ORCPT ); Wed, 10 Aug 2022 02:01:10 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2291E1EAE7 for ; Tue, 9 Aug 2022 23:01:09 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id f16-20020a17090a4a9000b001f234757bbbso6908554pjh.6 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=jRltpNWzYQkFEdBGDWkaI7C/+eKd3i2i2+6vEIP7xmn2jNqLvAVhtEVmOTEAu2MIzd OjXqkZJ1Q0XUeMjFNduv5QN6pvZzjvLAFl+hv0k02gqaA3WWusufRX7SyoAdXvJO6grh g7iS/aFIbiF77+b/WhQLYpzcw/hiBkS3AVKgcOip0SjmLh0uUZOlFaMxaezOMV2hi3+a tKHAAOp/JNw9LzrNX65qwwvB+TNG0HI9LGGBhLdCvXeK8t4i8QhI3alJVxmIhJ1Zk5m/ avRVaVYbeezvw4nXTCJ+iuqVviZYbS6xW4d0p6Pp+U0NSCpLLxO0UxwI/fN3OYSb33gf 2ljQ== X-Gm-Message-State: ACgBeo1Lolf/S6tE6udSLhU1xC4trGKqn/t6mT3pLTYKqBcah5fRqegP Ei6ydISN7jIFutKfKU8k90QIZDnnA6jfiDM= 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: linux-acpi@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: 596676 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 31BE1C3814E for ; Wed, 10 Aug 2022 06:02:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231281AbiHJGBg (ORCPT ); Wed, 10 Aug 2022 02:01:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60268 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231218AbiHJGBN (ORCPT ); Wed, 10 Aug 2022 02:01:13 -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 E221A326C1 for ; Tue, 9 Aug 2022 23:01:11 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id bu13-20020a056902090d00b00671743601f1so11335974ybb.0 for ; Tue, 09 Aug 2022 23:01:11 -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=g+gIXR3PsuWczDxBl2wFK1u/jMJUm5YNEJSluPqMcca3gARDDnIE7EiuqluqvbJJWn RN2goLkzsIas5De05r+Z/it5bmK267Mcgi2yA3Rwxx8W7/EGzj6bhL0EBD7Tji4JV6gL nFgsNy/BbM6uizGUtMpo8CmI7CQYZ83kfoCNnHaDm+TI1EkWbREByTIXTj4qi//a+MaO GZHrQC55CeKJbQJwdqejelb5mthdnCDu1d+Qhf1w4S+YPN7zRySUSaVwlykE3TapnLmH AohlwKDk6fpk+V4mDVglR5HQ81K0zSY4PQi3raP7aKKxPM/vcK70ibJQpaW6VDFHeyAo /BPg== X-Gm-Message-State: ACgBeo26IJdByGla+39Umg5ZQYIaueF84eEWkfBuRYVB8jXeGFZM8CRM jK4BivnK/6FBRMXZhl+NvWm0554L+qZquII= 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: linux-acpi@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); } /* From patchwork Wed Aug 10 06:00:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 596448 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 41284C38147 for ; Wed, 10 Aug 2022 06:02:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231218AbiHJGBh (ORCPT ); Wed, 10 Aug 2022 02:01:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60344 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231225AbiHJGBQ (ORCPT ); Wed, 10 Aug 2022 02:01:16 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C12B8326C3 for ; Tue, 9 Aug 2022 23:01:14 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-329a474c437so68109847b3.18 for ; Tue, 09 Aug 2022 23:01:14 -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=vx+dUbGYOv+iuawfVE7Ay+tk/KEU0DVIy9gKSjJSbfM=; b=DHsiPm8AGi/hRuAdwy5HbH6s2r/Oy5+6hpbTVaZ+kokvPnDRVEbJgOyfLDYxmu38/4 6c/USgm4pyf2vbNHq2+wO1DqxDN5IleK1JLrmt4AmI8cQZgYb+f2P8+NrSaqXDmNELCn CG/sox7zZCWs8YPB3eduZ7lrqv9LIN7coqgFfSQDtS+H7/JcQsLLKRN2VBjD4MmQ7DpP V+5QayoprOrleKbfgiC/nxCDcHAwk4cSCm1cUXlQqVrZJZ//d/l82UMam/ZZEF7Q/FKj 9IuQ3rPDGmmZL1xAEzGgeod2tuD2Rqc7w2LAiEWL8rfN2QjYE28QmkM4/wTaMPoRbas6 UhAw== 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=vx+dUbGYOv+iuawfVE7Ay+tk/KEU0DVIy9gKSjJSbfM=; b=ECaTvHs1XbAYHkj/XrB6QDLG3zzdAuX84Y07MQz1xVVnt+6lpZWDS+UXTlEZ7DC6Kg onffhEKEwPF1nNT2xqtTcfTeuwsTBfJSZ7691Ca923eIlbE2GVVOsGkEdmCE6tyABZZ6 yAMbV/FaG+lkmjKMV+W2ggix3j00FoIQGZ4mosTqH+vNc2uL5uqEyoIfJavMSEuYtBmE DBU6CejTMl81ryB3eoN4KCnfERbIdWhMMaopNYFCTNJNCT8Le5F7vhj0T45LEkPeWbKg PWDI34YGZdyUq9fd7PXWPYNzfRzG9loKBmK6cvsfP4+2VBN4QuDWVVTRlZZcV0dVix7a BvmA== X-Gm-Message-State: ACgBeo3BopcqszRSqYg7VRBg/mledvj99D2tvFOR1gJoOKTo7fASYrBY D5QZwkLqJK4VAYQG8A0JkW+K2380XRo6Jho= X-Google-Smtp-Source: AA6agR4Khze5AtD+WD0fh1ffw9yPithpzLXIHHaEEIY0YlMjElr9n+/FhIjncVMO9+wvqV/HHySsaIt/gn01T+Q= X-Received: from saravanak.san.corp.google.com ([2620:15c:2d:3:f21:76ca:766f:e0ab]) (user=saravanak job=sendgmr) by 2002:a5b:b8e:0:b0:67c:237b:760b with SMTP id l14-20020a5b0b8e000000b0067c237b760bmr5624436ybq.627.1660111274504; Tue, 09 Aug 2022 23:01:14 -0700 (PDT) Date: Tue, 9 Aug 2022 23:00:38 -0700 In-Reply-To: <20220810060040.321697-1-saravanak@google.com> Message-Id: <20220810060040.321697-10-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 9/9] of: property: Simplify of_link_to_phandle() 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: linux-acpi@vger.kernel.org The driver core now: - Has the parent device of a supplier pick up the consumers if the supplier never has a device created for it. - Ignores a supplier if the supplier has no parent device and will never be probed by a driver And already prevents creating a device link with the consumer as a supplier of a parent. So, we no longer need to find the "compatible" node of the supplier or do any other checks in of_link_to_phandle(). We simply need to make sure that the supplier is available in DT. Signed-off-by: Saravana Kannan Reviewed-by: Tony Lindgren Tested-by: Tony Lindgren --- drivers/of/property.c | 84 +++++++------------------------------------ 1 file changed, 13 insertions(+), 71 deletions(-) diff --git a/drivers/of/property.c b/drivers/of/property.c index 967f79b59016..98ca0399a354 100644 --- a/drivers/of/property.c +++ b/drivers/of/property.c @@ -1060,20 +1060,6 @@ of_fwnode_device_get_match_data(const struct fwnode_handle *fwnode, return of_device_get_match_data(dev); } -static bool of_is_ancestor_of(struct device_node *test_ancestor, - struct device_node *child) -{ - of_node_get(child); - while (child) { - if (child == test_ancestor) { - of_node_put(child); - return true; - } - child = of_get_next_parent(child); - } - return false; -} - static struct device_node *of_get_compat_node(struct device_node *np) { of_node_get(np); @@ -1104,71 +1090,27 @@ static struct device_node *of_get_compat_node_parent(struct device_node *np) return node; } -/** - * of_link_to_phandle - Add fwnode link to supplier from supplier phandle - * @con_np: consumer device tree node - * @sup_np: supplier device tree node - * - * Given a phandle to a supplier device tree node (@sup_np), this function - * finds the device that owns the supplier device tree node and creates a - * device link from @dev consumer device to the supplier device. This function - * doesn't create device links for invalid scenarios such as trying to create a - * link with a parent device as the consumer of its child device. In such - * cases, it returns an error. - * - * Returns: - * - 0 if fwnode link successfully created to supplier - * - -EINVAL if the supplier link is invalid and should not be created - * - -ENODEV if struct device will never be create for supplier - */ -static int of_link_to_phandle(struct device_node *con_np, +static void of_link_to_phandle(struct device_node *con_np, struct device_node *sup_np) { - struct device *sup_dev; - struct device_node *tmp_np = sup_np; + struct device_node *tmp_np = of_node_get(sup_np); - /* - * Find the device node that contains the supplier phandle. It may be - * @sup_np or it may be an ancestor of @sup_np. - */ - sup_np = of_get_compat_node(sup_np); - if (!sup_np) { - pr_debug("Not linking %pOFP to %pOFP - No device\n", - con_np, tmp_np); - return -ENODEV; - } + /* Check that sup_np and its ancestors are available. */ + while (tmp_np) { + if (of_fwnode_handle(tmp_np)->dev) { + of_node_put(tmp_np); + break; + } - /* - * Don't allow linking a device node as a consumer of one of its - * descendant nodes. By definition, a child node can't be a functional - * dependency for the parent node. - */ - if (of_is_ancestor_of(con_np, sup_np)) { - pr_debug("Not linking %pOFP to %pOFP - is descendant\n", - con_np, sup_np); - of_node_put(sup_np); - return -EINVAL; - } + if (!of_device_is_available(tmp_np)) { + of_node_put(tmp_np); + return; + } - /* - * Don't create links to "early devices" that won't have struct devices - * created for them. - */ - sup_dev = get_dev_from_fwnode(&sup_np->fwnode); - if (!sup_dev && - (of_node_check_flag(sup_np, OF_POPULATED) || - sup_np->fwnode.flags & FWNODE_FLAG_NOT_DEVICE)) { - pr_debug("Not linking %pOFP to %pOFP - No struct device\n", - con_np, sup_np); - of_node_put(sup_np); - return -ENODEV; + tmp_np = of_get_next_parent(tmp_np); } - put_device(sup_dev); fwnode_link_add(of_fwnode_handle(con_np), of_fwnode_handle(sup_np)); - of_node_put(sup_np); - - return 0; } /**