From patchwork Tue Feb 7 01:41:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 651487 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 64786C636D6 for ; Tue, 7 Feb 2023 01:42:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230333AbjBGBm0 (ORCPT ); Mon, 6 Feb 2023 20:42:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40532 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230249AbjBGBmQ (ORCPT ); Mon, 6 Feb 2023 20:42:16 -0500 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E3E4C113D7 for ; Mon, 6 Feb 2023 17:42:13 -0800 (PST) Received: by mail-pl1-x64a.google.com with SMTP id k14-20020a170902ce0e00b001992e19d3beso285604plg.5 for ; Mon, 06 Feb 2023 17:42:13 -0800 (PST) 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:subject:date:message-id:reply-to; bh=qilJcjCuMQ+UEcym7b4h9C92RRJ6Qj6pHG5dlY6nsNI=; b=W3xpeO/Rx34noJBz5nd6A4bxsUDyoqIhh7Cb2x3UmXZsoK8ED+AALcboiCZqoyinys 1toeCq44NyFwUzZ+gzQLgSl+KCNP+GEf6kLLEg+JXta1FpZzeLUU2keUV7ERvssI1FOu hpIoNUBWt2EucoDAErFvCDxGsmVEr2TJ6EKK7+n9BQxjio75CJwBibBIhOgfvSYZL/gy afaIUUJIivpS9OSgOyPy1/Ekhq88quTU3lpmMYtruya4C6g0GeUFX8y9KkixEga6+mtF BrJdWYEvqyNBme4s39lZ7YjVtDKbb6Vre9yguxW8VdqTPi5yoBdDTn8iTA1PZhhsB6Kx CwaQ== 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:subject:date:message-id:reply-to; bh=qilJcjCuMQ+UEcym7b4h9C92RRJ6Qj6pHG5dlY6nsNI=; b=MyNzoMFsORBMbP67SxoesvbPUj9eE9yFakQxUPZaOPhFCGKeg33D0qg0eQmOgkIqy/ 3w14zQKdbWf5Yib654YATcejKAV3d4V2b0Tvt9wIvdMre93GoG4unkF7NypfBvKOlxOa An+4vH5nn3YC2oJ1geSVpnhRLnLo+RC98W3oFLtppOeUH04VFjk+obE1Ed443B08NsT+ cLwLm0mhnIYjR4YhiFhAkgM+m2J7FXB+qiGJgTJ0/yXCDCIdi+ljdD7Zp4h2Jm50rCEb ZXDrQeQ1IN3pwDj6KHA+KE2bDIMM/2D0S/rk7IXG0+HV1dJX2dVhwlm03N7NHIh5KT8Q /ngw== X-Gm-Message-State: AO0yUKUiQYv574CsXS/GBw12uR2Nkv2S40UnEIW9h77ixfg+G94ocMfF ZAR/2kbBjF/7764dmVRAdTFmVAMXavbgSq0= X-Google-Smtp-Source: AK7set9WA6uQ/1FNztyQpvzAT03IkHDfAC4BORG9y1kTW3w7tVvng8KdB/nV5PiGcKyoyrHyfOxaYgRn3+dBCkM= X-Received: from saravanak.san.corp.google.com ([2620:15c:2d:3:ae1:aba6:f21c:4a94]) (user=saravanak job=sendgmr) by 2002:a17:90a:bd04:b0:215:f80c:18e6 with SMTP id y4-20020a17090abd0400b00215f80c18e6mr4002191pjr.45.1675734133267; Mon, 06 Feb 2023 17:42:13 -0800 (PST) Date: Mon, 6 Feb 2023 17:41:53 -0800 In-Reply-To: <20230207014207.1678715-1-saravanak@google.com> Message-Id: <20230207014207.1678715-2-saravanak@google.com> Mime-Version: 1.0 References: <20230207014207.1678715-1-saravanak@google.com> X-Mailer: git-send-email 2.39.1.519.gcb327c4b5f-goog Subject: [PATCH v3 01/12] driver core: fw_devlink: Don't purge child fwnode's consumer links From: Saravana Kannan To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Sudeep Holla , Cristian Marussi , Linus Walleij , Bartosz Golaszewski , Thomas Gleixner , Marc Zyngier , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Frank Rowand , Geert Uytterhoeven , Magnus Damm , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Len Brown , Saravana Kannan , " =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= " Cc: Abel Vesa , Alexander Stein , Tony Lindgren , Geert Uytterhoeven , John Stultz , Doug Anderson , Guenter Roeck , Dmitry Baryshkov , Maxim Kiselev , Maxim Kochetkov , Luca Weiss , Colin Foster , Martin Kepplinger , Jean-Philippe Brucker , Vladimir Oltean , kernel-team@android.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, linux-mtd@lists.infradead.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 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 Tested-by: Colin Foster Tested-by: Sudeep Holla --- drivers/base/core.c | 97 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 79 insertions(+), 18 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index a3e14143ec0c..001e1914858d 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -54,11 +54,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. * @@ -74,22 +75,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); @@ -100,9 +97,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; + + mutex_lock(&fwnode_link_lock); + ret = __fwnode_link_add(con, sup); + mutex_unlock(&fwnode_link_lock); return ret; } @@ -181,6 +186,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); @@ -1267,16 +1317,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); @@ -1855,7 +1912,11 @@ static int fw_devlink_create_devlink(struct device *con, fwnode_is_ancestor_of(sup_handle, con->fwnode)) return -EINVAL; - sup_dev = get_dev_from_fwnode(sup_handle); + if (sup_handle->flags & FWNODE_FLAG_NOT_DEVICE) + sup_dev = fwnode_get_next_parent_dev(sup_handle); + else + sup_dev = get_dev_from_fwnode(sup_handle); + if (sup_dev) { /* * If it's one of those drivers that don't actually bind to From patchwork Tue Feb 7 01:41:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 651486 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 A3DB9C05027 for ; Tue, 7 Feb 2023 01:42:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230345AbjBGBmp (ORCPT ); Mon, 6 Feb 2023 20:42:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40922 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230319AbjBGBm2 (ORCPT ); Mon, 6 Feb 2023 20:42:28 -0500 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 025A236080 for ; Mon, 6 Feb 2023 17:42:21 -0800 (PST) Received: by mail-pg1-x54a.google.com with SMTP id h16-20020a63df50000000b004f74bc0c71fso3575107pgj.18 for ; Mon, 06 Feb 2023 17:42:21 -0800 (PST) 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:subject:date:message-id:reply-to; bh=ORUuC30mhLyGGOfOGNQGmV2Hk9NLu8NgqlPyUePgVtw=; b=W3ks5YEw7SKIgSIZBtQHBL9lJVPSdYZt5YLLOMNiqg39kU3nN1EI6XuA+B32uaPZGb v5zyhRmRRHO+O/PDHZr10O4cRAMqIo+F89AcNblg/s/+76O4QIK+2qBAbUZrxge36Zai oUQ3lkDhN+g7lBRIxR1KVI98eol03ANv+ysGxNp9Jy33gMZ7+KWT14YWjTKmLM4h0Sde uDNF/Fk2U8cuXtdVSlDGUvhsCS+fTpqnyi3ghq5nNuitlb38EuGaeD8xzBpXE/R4GDSO N9LcyuvRftt3ULpiqwLSIoYSZ3EjoLNyWNXZS4LCua4bI5CqUx3cJx+UrAWXqFnajwKW grxg== 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:subject:date:message-id:reply-to; bh=ORUuC30mhLyGGOfOGNQGmV2Hk9NLu8NgqlPyUePgVtw=; b=FKR1xScZsUNlkdL5RysMxi9A3ljk6Dpt2MAK8p+5quhEtLXOwYCCpdZaFErCWPzc3/ 5kuJ9EiR5hiLHMNA1aezlneeYQxC5mA2OqB1JSyHPd3x+9tKDA8PiOFV7giydfoFbVNj 3GpxSf2QWsRCnUBG04Vnp23lRcn5pTvr5VVOJ2dwSVaEpANtyEtDcT22/NpDe/I1eajp jaadMCNi29l0suIK0cyy6kIbY5ZYjC6nWOkkumEm20qLbxKzP+478epgHRajVS5K3Cdg nC0q0XMKqR4l3Qdm7VZDFe7X5wV93SU7UgqqF4ETcRDDx1Ra9zBitk+jywnruloKhkn5 vqoA== X-Gm-Message-State: AO0yUKUT4zs6YsJLN0JW8qG+CQGE6K9i/I5Kg6A3rP89y9JQclxTCfez yRT1KH6M88TlOPT/sNT1KsJ+sbG3B5AccKs= X-Google-Smtp-Source: AK7set8txtYYhJ0J+28pL4WUJBO9Kkr3uP9QQWYQBMNjYhLp0mg9chNGGE1J5xNq3IdUI/epAkGwDw5ZAcogFH0= X-Received: from saravanak.san.corp.google.com ([2620:15c:2d:3:ae1:aba6:f21c:4a94]) (user=saravanak job=sendgmr) by 2002:a17:90a:3f8f:b0:230:792d:7519 with SMTP id m15-20020a17090a3f8f00b00230792d7519mr425744pjc.22.1675734141281; Mon, 06 Feb 2023 17:42:21 -0800 (PST) Date: Mon, 6 Feb 2023 17:41:56 -0800 In-Reply-To: <20230207014207.1678715-1-saravanak@google.com> Message-Id: <20230207014207.1678715-5-saravanak@google.com> Mime-Version: 1.0 References: <20230207014207.1678715-1-saravanak@google.com> X-Mailer: git-send-email 2.39.1.519.gcb327c4b5f-goog Subject: [PATCH v3 04/12] gpiolib: Clear the gpio_device's fwnode initialized flag before adding From: Saravana Kannan To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Sudeep Holla , Cristian Marussi , Linus Walleij , Bartosz Golaszewski , Thomas Gleixner , Marc Zyngier , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Frank Rowand , Geert Uytterhoeven , Magnus Damm , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Len Brown , Saravana Kannan , " =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= " Cc: Abel Vesa , Alexander Stein , Tony Lindgren , Geert Uytterhoeven , John Stultz , Doug Anderson , Guenter Roeck , Dmitry Baryshkov , Maxim Kiselev , Maxim Kochetkov , Luca Weiss , Colin Foster , Martin Kepplinger , Jean-Philippe Brucker , Vladimir Oltean , kernel-team@android.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, linux-mtd@lists.infradead.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 Acked-by: Bartosz Golaszewski Tested-by: Colin Foster Tested-by: Sudeep Holla --- drivers/gpio/gpiolib.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 939c776b9488..bdb9493857eb 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -578,6 +578,13 @@ 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 && !gdev->dev.fwnode->dev) + fwnode_dev_initialized(gdev->dev.fwnode, false); + ret = gcdev_register(gdev, gpio_devt); if (ret) return ret; From patchwork Tue Feb 7 01:41:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 651485 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 31CDBC64EC5 for ; Tue, 7 Feb 2023 01:43:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230489AbjBGBnE (ORCPT ); Mon, 6 Feb 2023 20:43:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40902 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230403AbjBGBmq (ORCPT ); Mon, 6 Feb 2023 20:42:46 -0500 Received: from mail-pf1-x449.google.com (mail-pf1-x449.google.com [IPv6:2607:f8b0:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CFED016333 for ; Mon, 6 Feb 2023 17:42:27 -0800 (PST) Received: by mail-pf1-x449.google.com with SMTP id j14-20020aa7928e000000b00593bca77b0dso7247465pfa.9 for ; Mon, 06 Feb 2023 17:42:27 -0800 (PST) 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:subject:date:message-id:reply-to; bh=7vpmPQ8JVcoFw6jzJt0l+ZlsP/nzUPWiHo9dJCqmqxg=; b=ZVUxcLXcuHpH7fPEW4j4omclrdQvGfH8R1Vewn8I0GThoas9mW+GLo2sjSyOKV3npY DsGQu11CHb6WnNb+y3GZPqWhQ6O3cz3xiYf037/sdq9nFz8XU64plVHqi0wGnHI/rnh2 kDoKcQ3viwNlT96/A4ZecaIDJZMX2kMBpfxVlyPZFeajMa66cDDL9Mb1Ds/7UEUQwtJK R/Xs8z5ijn/Nd67K7O2YD2iruYwx4Q9hECaWntP7FJqQKrMrH+xfnF9gGv9X3lbFtL8X HEmJDslkFRhae3S1tV11iNbb6wmW0J8xAcXwhzislt+Z//qMzPcwqA3I9SL4dXDTfs2E DxQA== 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:subject:date:message-id:reply-to; bh=7vpmPQ8JVcoFw6jzJt0l+ZlsP/nzUPWiHo9dJCqmqxg=; b=TixtwaKiSfChN/dDqa5RanbummgZxpwKOBVVjWShIe03ofzIHcssVyy0Zpydf07fx8 wC5Vp2PwVY66CAfqm62tdy5ZW1SFjSXE3QrczwodvwCUG/drpuubFFuHcULi2+kYaVvs HM7Bxkgi9vo70eu8ZhIJqfgw0VbQXmSJBZrESzgA4MScmYV2l7bsVX4MwymIOgV4PMia sc+WdRSt4D0XLKdKwCClG8kPaMgxEuZyZ45mckM6ZdZWtm9OJOTSKbO6qEFpeJbaxPug 3bxP+OXhCSEAV95IzotzHtdgE69btu3PiFMitcxAbiK2NHcgSEoYBE7zWs9PluFKtm+J Cs1Q== X-Gm-Message-State: AO0yUKWTVFVKD+S3zy5hcSxCKOJtDK1dNM1fSbVeHwjqqoW0+t+Ire74 dzBGoK/ipQjtUZXkk2KHTqBW4EGA1QqumyQ= X-Google-Smtp-Source: AK7set9NPOGC0oetOP/gaLFUP+MpzpqBfkZ8gulYNDZYMwFtOcGmzB6taII+HbQld9AZdrAJI3zqaMUoDmkG+Fo= X-Received: from saravanak.san.corp.google.com ([2620:15c:2d:3:ae1:aba6:f21c:4a94]) (user=saravanak job=sendgmr) by 2002:a17:90a:49c8:b0:230:9fa1:8cbb with SMTP id l8-20020a17090a49c800b002309fa18cbbmr1636995pjm.78.1675734146756; Mon, 06 Feb 2023 17:42:26 -0800 (PST) Date: Mon, 6 Feb 2023 17:41:58 -0800 In-Reply-To: <20230207014207.1678715-1-saravanak@google.com> Message-Id: <20230207014207.1678715-7-saravanak@google.com> Mime-Version: 1.0 References: <20230207014207.1678715-1-saravanak@google.com> X-Mailer: git-send-email 2.39.1.519.gcb327c4b5f-goog Subject: [PATCH v3 06/12] 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" , Sudeep Holla , Cristian Marussi , Linus Walleij , Bartosz Golaszewski , Thomas Gleixner , Marc Zyngier , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Frank Rowand , Geert Uytterhoeven , Magnus Damm , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Len Brown , Saravana Kannan , " =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= " Cc: Abel Vesa , Alexander Stein , Tony Lindgren , Geert Uytterhoeven , John Stultz , Doug Anderson , Guenter Roeck , Dmitry Baryshkov , Maxim Kiselev , Maxim Kochetkov , Luca Weiss , Colin Foster , Martin Kepplinger , Jean-Philippe Brucker , Vladimir Oltean , kernel-team@android.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, linux-mtd@lists.infradead.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 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. Fixes: 2de9d8e0d2fe ("driver core: fw_devlink: Improve handling of cyclic dependencies") Signed-off-by: Saravana Kannan Tested-by: Colin Foster Tested-by: Sudeep Holla --- drivers/base/core.c | 50 +++++++++++++++++++++++++++++++++--------- include/linux/fwnode.h | 11 +++++++++- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 071c454844d6..4869b6fdfeaf 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -76,13 +76,15 @@ static bool fw_devlink_best_effort; * are ignored and there is no reference counting. */ static int __fwnode_link_add(struct fwnode_handle *con, - struct fwnode_handle *sup) + struct fwnode_handle *sup, u8 flags) { struct fwnode_link *link; list_for_each_entry(link, &sup->consumers, s_hook) - if (link->consumer == con) + if (link->consumer == con) { + link->flags |= flags; return 0; + } link = kzalloc(sizeof(*link), GFP_KERNEL); if (!link) @@ -92,6 +94,7 @@ static int __fwnode_link_add(struct fwnode_handle *con, INIT_LIST_HEAD(&link->s_hook); link->consumer = con; INIT_LIST_HEAD(&link->c_hook); + link->flags = flags; list_add(&link->s_hook, &sup->consumers); list_add(&link->c_hook, &con->suppliers); @@ -106,7 +109,7 @@ int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup) int ret; mutex_lock(&fwnode_link_lock); - ret = __fwnode_link_add(con, sup); + ret = __fwnode_link_add(con, sup, 0); mutex_unlock(&fwnode_link_lock); return ret; } @@ -126,6 +129,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 @@ -199,7 +215,7 @@ static void __fwnode_links_move_consumers(struct fwnode_handle *from, struct fwnode_link *link, *tmp; list_for_each_entry_safe(link, tmp, &from->consumers, s_hook) { - __fwnode_link_add(link->consumer, to); + __fwnode_link_add(link->consumer, to, link->flags); __fwnode_link_del(link); } } @@ -1041,6 +1057,21 @@ 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)) + return link->supplier; + + return NULL; +} + /** * device_links_check_suppliers - Check presence of supplier drivers. * @dev: Consumer device. @@ -1068,11 +1099,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, @@ -1261,7 +1289,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 Tue Feb 7 01:42:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 651484 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 79EE1C61DA4 for ; Tue, 7 Feb 2023 01:43:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230389AbjBGBnh (ORCPT ); Mon, 6 Feb 2023 20:43:37 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41840 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230340AbjBGBnC (ORCPT ); Mon, 6 Feb 2023 20:43:02 -0500 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 661293647E for ; Mon, 6 Feb 2023 17:42:34 -0800 (PST) Received: by mail-pg1-x54a.google.com with SMTP id q130-20020a632a88000000b004a03cfb3ac6so5915856pgq.6 for ; Mon, 06 Feb 2023 17:42:34 -0800 (PST) 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:subject:date:message-id:reply-to; bh=hRJNJ021j7UgZ8yd2Te0gTbEExX2Q8vfI2YN74+S+Pk=; b=dNDuUGRBP6AHiDwbpmxQqlp5/eMem+cgKsBSstj04w5Bsq+orHEudVsHqovBJORYTD lDim37xAo+som1CvlE+uWlC5Wi3dO7dR/p372KByV/Rf81Et/iNkZgwEpriQTuskTcoZ FkT+rliRLGZaodn9xQ+a02TAQE3jwJ8WQssWp0Xlisqa6QXLET3Hx9LzqafJtwQ4YdI7 FEtQL0oq01J2gNcCminYJYVwK+sL8QegmmG3kCUgRPPPGJq4UdbIH0DkEfmQ4i8LM+B3 rkGkVMHqexDkL320QfVBECH7FMSBy7rTsmZg0oSpnNO5gE5wZ1VOPKZBlEzsYIqfaCAz MPKA== 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:subject:date:message-id:reply-to; bh=hRJNJ021j7UgZ8yd2Te0gTbEExX2Q8vfI2YN74+S+Pk=; b=ydUusoxqjd2KY2f2ScoYhRiqeQeq/kdBcDpoym3cr09sKw2UdmKES0XnFzzMHfvuYB 7hG3yooeA3BOQf3xIjzXl8np5KVzW5ciWBIWOC2xQxLPg5rUaxp0+Qm6yVpuNbQf2RGF GayE2N+RLVrAlicxj7rv99esN7gf846Cw3JGcYSAsUoeXIKqSrEL2gHzaHy+ODoCBykQ Pj939RlhmOMnHgxuwUnbd65SNASi8LyoMWEjFI54tu2mpAowXePlD0TKooIuBO3QrCeq eM+BgvMut/yWYP4c0279yl/RrZp5Zt097L0cUEYNjqmdvghJFH3OZm6iCK56wqjAZLwZ mrZg== X-Gm-Message-State: AO0yUKXKsOwG9Ze6hVx/0j5Ir+loGzJRErZZGE+fqVVOr6oOLS6esErx zQVJlIl28uSYMQdiDMPs04XMUWfN3XPaKyM= X-Google-Smtp-Source: AK7set+JD8rPeC2hegH4ejuI8kh9p9ED2NDjDjOz59Trt1oxF7eZ1XZzrFKU8beum79ewrCq/mRBfrIqCq4zX2k= X-Received: from saravanak.san.corp.google.com ([2620:15c:2d:3:ae1:aba6:f21c:4a94]) (user=saravanak job=sendgmr) by 2002:a63:9259:0:b0:4db:2ad4:5997 with SMTP id s25-20020a639259000000b004db2ad45997mr169546pgn.29.1675734152305; Mon, 06 Feb 2023 17:42:32 -0800 (PST) Date: Mon, 6 Feb 2023 17:42:00 -0800 In-Reply-To: <20230207014207.1678715-1-saravanak@google.com> Message-Id: <20230207014207.1678715-9-saravanak@google.com> Mime-Version: 1.0 References: <20230207014207.1678715-1-saravanak@google.com> X-Mailer: git-send-email 2.39.1.519.gcb327c4b5f-goog Subject: [PATCH v3 08/12] driver core: fw_devlink: Make cycle detection more robust From: Saravana Kannan To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Sudeep Holla , Cristian Marussi , Linus Walleij , Bartosz Golaszewski , Thomas Gleixner , Marc Zyngier , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Frank Rowand , Geert Uytterhoeven , Magnus Damm , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Len Brown , Saravana Kannan , " =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= " Cc: Abel Vesa , Alexander Stein , Tony Lindgren , Geert Uytterhoeven , John Stultz , Doug Anderson , Guenter Roeck , Dmitry Baryshkov , Maxim Kiselev , Maxim Kochetkov , Luca Weiss , Colin Foster , Martin Kepplinger , Jean-Philippe Brucker , Vladimir Oltean , kernel-team@android.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, linux-mtd@lists.infradead.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. Fixes: 2de9d8e0d2fe ("driver core: fw_devlink: Improve handling of cyclic dependencies") Signed-off-by: Saravana Kannan Tested-by: Colin Foster Tested-by: Sudeep Holla --- drivers/base/core.c | 248 +++++++++++++++++++++++--------------------- 1 file changed, 129 insertions(+), 119 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index e4b60436a4a4..aaf79ea9647c 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1866,47 +1866,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) { @@ -1937,6 +1896,111 @@ 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 device *sup_dev = NULL, *par_dev = NULL; + struct fwnode_link *link; + struct device_link *dev_link; + 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 = get_device(sup_dev->parent); + else + par_dev = fwnode_get_next_parent_dev(sup_handle); + + if (par_dev && __fw_devlink_relax_cycles(con, par_dev->fwnode)) + ret = true; + + 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 + * 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 @@ -1989,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(); + } + if (sup_handle->flags & FWNODE_FLAG_NOT_DEVICE) sup_dev = fwnode_get_next_parent_dev(sup_handle); else @@ -2002,23 +2081,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; } @@ -2031,49 +2103,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; @@ -2156,10 +2191,7 @@ static void __fw_devlink_link_to_consumers(struct device *dev) * * The function creates normal (non-SYNC_STATE_ONLY) device links between @dev * and the real suppliers of @dev. Once these device links are created, the - * fwnode links are deleted. When such device links are successfully created, - * this function is called recursively on those supplier devices. This is - * needed to detect and break some invalid cycles in fwnode links. See - * fw_devlink_create_devlink() for more details. + * fwnode links are deleted. * * In addition, it also looks at all the suppliers of the entire fwnode tree * because some of the child devices of @dev that have not been added yet @@ -2180,7 +2212,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); @@ -2188,27 +2219,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 Tue Feb 7 01:42:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 651483 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 93474C64EC4 for ; Tue, 7 Feb 2023 01:43:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230321AbjBGBnw (ORCPT ); Mon, 6 Feb 2023 20:43:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41004 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230480AbjBGBnE (ORCPT ); Mon, 6 Feb 2023 20:43:04 -0500 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E3D86360BA for ; Mon, 6 Feb 2023 17:42:40 -0800 (PST) Received: by mail-pg1-x549.google.com with SMTP id k16-20020a635a50000000b0042986056df6so5892569pgm.2 for ; Mon, 06 Feb 2023 17:42:40 -0800 (PST) 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:subject:date:message-id:reply-to; bh=qO7SA/IWYPEhdvQ3bg5afBtNBnjngejmFoW2WqOrddI=; b=GazeBruttlU5oTI33IWVV1tAUn4JRdRTAmGz0onik+n6U1T5h3g5Eqk7gGdOGMDK/b pISWVmhqDorcgwiUsTtbwUhwsXkQBy9FbOADGd10qeFLJKcjSWm9FlwkrDf0YSZnQ9+5 MlI9mebazN/CBNgen9ENy7akZji0sNSLpJDHAKCcuu7sotue0FW2RA5Bj0NTsc48DOU1 BJ2j+WUhTu8DoyxWUtbwaehDC8ppns7BWt2T/8qAizu6/ITBGfNfqXYJKkF1ZM6CyRxn ZcscZDUsMpAZKiRckNDj1rDjE8L096aAxpbX+tYBH1Uk2VlibG8o8TaOGQfpibf5qmCu A4Ug== 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:subject:date:message-id:reply-to; bh=qO7SA/IWYPEhdvQ3bg5afBtNBnjngejmFoW2WqOrddI=; b=X0+o9rA1Od9j3B9c8tPwfqHFP8vVFqJkdMNaQ8U2UKif7cT5i+oGQMmYoHbf9wHflF AsQdGF+PZZZJmAqj3j3P19JGiIE+q7dRayuOcIYqtP6T0f33x3o7vdKFc+7shZgOf+2q IsCH8P6g0F4wIBxPy8ozJHhbCNy3NlqbbyhNCW3p55YOLoE8d5Zs8WQsBKuAWwX9HPHd mN8ABjT8lCoOmT23jQ+opzKXmjdEH7DgDAzrsO1vwjiInkow7nJhNGrCPHC4p065uvoJ ra93PDi4r2QQqF0DjMaJcZRe9czRY26FoG9qKN8McMcT8XrOGcSeMCsf7u067bAvHU3J QeEg== X-Gm-Message-State: AO0yUKWYTrB/XGqad83tEQxPodI53/SaLOY5veahmZsBd7F0CDj0qK1d xw2lp9wzqLaBbXeb3qC/QG8CF3TtZ87/qW4= X-Google-Smtp-Source: AK7set8CF2GrP/NVxAgKrUj8AGlYPMKVoXXaqrQpeXZ8O8WzceQ78vPHdt/Q5BozlBJGRB5LWE1p0PTeySIpdfY= X-Received: from saravanak.san.corp.google.com ([2620:15c:2d:3:ae1:aba6:f21c:4a94]) (user=saravanak job=sendgmr) by 2002:a63:7304:0:b0:4da:d745:98dd with SMTP id o4-20020a637304000000b004dad74598ddmr170930pgc.62.1675734160457; Mon, 06 Feb 2023 17:42:40 -0800 (PST) Date: Mon, 6 Feb 2023 17:42:03 -0800 In-Reply-To: <20230207014207.1678715-1-saravanak@google.com> Message-Id: <20230207014207.1678715-12-saravanak@google.com> Mime-Version: 1.0 References: <20230207014207.1678715-1-saravanak@google.com> X-Mailer: git-send-email 2.39.1.519.gcb327c4b5f-goog Subject: [PATCH v3 11/12] firmware: arm_scmi: Set fwnode for the scmi_device From: Saravana Kannan To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Sudeep Holla , Cristian Marussi , Linus Walleij , Bartosz Golaszewski , Thomas Gleixner , Marc Zyngier , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Frank Rowand , Geert Uytterhoeven , Magnus Damm , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Len Brown , Saravana Kannan , " =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= " Cc: Abel Vesa , Alexander Stein , Tony Lindgren , Geert Uytterhoeven , John Stultz , Doug Anderson , Guenter Roeck , Dmitry Baryshkov , Maxim Kiselev , Maxim Kochetkov , Luca Weiss , Colin Foster , Martin Kepplinger , Jean-Philippe Brucker , Vladimir Oltean , kernel-team@android.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, linux-mtd@lists.infradead.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 This allows fw_devlink to track and enforce supplier-consumer dependencies for scmi_device. Signed-off-by: Saravana Kannan Acked-by: Sudeep Holla Tested-by: Colin Foster Tested-by: Sudeep Holla --- drivers/firmware/arm_scmi/bus.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c index 35bb70724d44..cc2eba067575 100644 --- a/drivers/firmware/arm_scmi/bus.c +++ b/drivers/firmware/arm_scmi/bus.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "common.h" @@ -191,7 +192,7 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol, scmi_dev->id = id; scmi_dev->protocol_id = protocol; scmi_dev->dev.parent = parent; - scmi_dev->dev.of_node = np; + device_set_node(&scmi_dev->dev, of_fwnode_handle(np)); scmi_dev->dev.bus = &scmi_bus_type; scmi_dev->dev.release = scmi_device_release; dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id); From patchwork Tue Feb 7 01:42:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 651482 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 61FC9C05027 for ; Tue, 7 Feb 2023 01:44:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229711AbjBGBoT (ORCPT ); Mon, 6 Feb 2023 20:44:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41098 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229726AbjBGBn2 (ORCPT ); Mon, 6 Feb 2023 20:43:28 -0500 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 C340E3668C for ; Mon, 6 Feb 2023 17:42:51 -0800 (PST) Received: by mail-pj1-x1049.google.com with SMTP id dt6-20020a17090afa4600b00230183006c3so5292208pjb.7 for ; Mon, 06 Feb 2023 17:42:51 -0800 (PST) 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:subject:date:message-id:reply-to; bh=YX1zBRfC33D3rDRElKAdT20jJS5RQeSlv0JzqWYnjho=; b=UGmq1xHhmv8QgalRGnvex5vaBwzzKCS6zloJhLFOA04JYhf7s2xljRYpy9kTAoNsHa iBC98QSDMciwj7mZAoPpI2usajIcl1gF62f5Z4nG2GjxXwW1tEOTSt3uCwYi8iyDdG37 BQfwQH+F5b5B8hHp73/BToUo9eBPbPtsoJG7VHsq9ww2xJmU91i6mybd4OadC8hcmn4L z/JS/fusQ1z+bJZfl9x8ljB4BFuvxFXBUNKd3sGG9GJYtq6qpJhSHd3ZvicyZg0osOk+ QxgZAlVpjyrodYVEXosDI3FM0qnhjaVmzWT6ld85NejZtUeLAUKpBMz5nIKrGLcp4W86 p/oQ== 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:subject:date:message-id:reply-to; bh=YX1zBRfC33D3rDRElKAdT20jJS5RQeSlv0JzqWYnjho=; b=lpJJIbbQrnhAbJW6Rs+IMO3lHq9m+jNTGjlWfRi7OPLOnCEGgqZLS9X9HANd5fNbu0 yy9A33Iu4YF5C8DAGAmr9MdwZfefAtWHHis0X8bJvRVJyUBUmfVjzonZfulrudbKk1uf +kwXS2LUZ4wl7Y64hqV5Ac30G2kttTTNbQPcCaj0VLZFXyckjnzMO8GNMvDYu6vZ2ziR GZ3Gx6PpsEv0+llBU+Q0+NRp2H0BI+h5RyBkZtoWDLawYEcwO1OFTFVifSv+em/yVZik iSyrocrKIpaqmKfXJplFYBta7KwKs7J6K9obu2GCxeYfrU8lFwTZFRszEYrVbpLeUgsH tHxg== X-Gm-Message-State: AO0yUKUhp0ey+YtYrYGWALdb8lFeKgqAKLn/x6T9jwGZ9msoP65BiSFU t1EP0aUvjmkWI/wl2Rca+mUecGNTJudk0Qs= X-Google-Smtp-Source: AK7set8Gcli9J3BzSmSCx9wcmgEyp38uzEhI1HIWAsHDVULR2jB9pwdeXZpjU2A6RPq1Ak9f9gnun0I1Kq/a1mU= X-Received: from saravanak.san.corp.google.com ([2620:15c:2d:3:ae1:aba6:f21c:4a94]) (user=saravanak job=sendgmr) by 2002:a17:90a:1d4e:b0:230:ae97:c349 with SMTP id u14-20020a17090a1d4e00b00230ae97c349mr441075pju.8.1675734163194; Mon, 06 Feb 2023 17:42:43 -0800 (PST) Date: Mon, 6 Feb 2023 17:42:04 -0800 In-Reply-To: <20230207014207.1678715-1-saravanak@google.com> Message-Id: <20230207014207.1678715-13-saravanak@google.com> Mime-Version: 1.0 References: <20230207014207.1678715-1-saravanak@google.com> X-Mailer: git-send-email 2.39.1.519.gcb327c4b5f-goog Subject: [PATCH v3 12/12] mtd: mtdpart: Don't create platform device that'll never probe From: Saravana Kannan To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Sudeep Holla , Cristian Marussi , Linus Walleij , Bartosz Golaszewski , Thomas Gleixner , Marc Zyngier , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Rob Herring , Frank Rowand , Geert Uytterhoeven , Magnus Damm , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Len Brown , Saravana Kannan , " =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= " Cc: Abel Vesa , Alexander Stein , Tony Lindgren , Geert Uytterhoeven , John Stultz , Doug Anderson , Guenter Roeck , Dmitry Baryshkov , Maxim Kiselev , Maxim Kochetkov , Luca Weiss , Colin Foster , Martin Kepplinger , Jean-Philippe Brucker , Vladimir Oltean , kernel-team@android.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, linux-mtd@lists.infradead.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 These "nvmem-cells" platform devices never get probed because there's no platform driver for it and it's never used anywhere else. So it's a waste of memory. These devices also cause fw_devlink to block nvmem consumers of "nvmem-cells" partition from probing because the supplier device never probes. So stop creating platform devices for nvmem-cells partitions to avoid wasting memory and to avoid blocking probing of consumers. Reported-by: Maxim Kiselev Fixes: bcdf0315a61a ("mtd: call of_platform_populate() for MTD partitions") Signed-off-by: Saravana Kannan --- drivers/mtd/mtdpart.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index d442fa94c872..85f5ee6f06fc 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -577,6 +577,7 @@ static int mtd_part_of_parse(struct mtd_info *master, { struct mtd_part_parser *parser; struct device_node *np; + struct device_node *child; struct property *prop; struct device *dev; const char *compat; @@ -594,6 +595,15 @@ static int mtd_part_of_parse(struct mtd_info *master, else np = of_get_child_by_name(np, "partitions"); + /* + * Don't create devices that are added to a bus but will never get + * probed. That'll cause fw_devlink to block probing of consumers of + * this partition until the partition device is probed. + */ + for_each_child_of_node(np, child) + if (of_device_is_compatible(child, "nvmem-cells")) + of_node_set_flag(child, OF_POPULATED); + of_property_for_each_string(np, "compatible", prop, compat) { parser = mtd_part_get_compatible_parser(compat); if (!parser)