Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp302812pxu; Thu, 7 Jan 2021 05:34:54 -0800 (PST) X-Google-Smtp-Source: ABdhPJxS7QrjVfkPEt7MMMozvxPN0VyGL5zPm/Nu1QT9X8S10D73JRC2JWGwarEVBPmug6nT5K08 X-Received: by 2002:a17:906:d152:: with SMTP id br18mr6425173ejb.297.1610026494370; Thu, 07 Jan 2021 05:34:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1610026494; cv=none; d=google.com; s=arc-20160816; b=Cre8qiCnDJuSzbZksGUJiyS97rx2L5sS5TeZZx/5T4ltGmu4guPgNXEikY2wAJYNYF jxLwinqPHxok0PABLDrAM/XkFbaKjXFoyLiqRWgZeW47X+cH4RsM/u9RvyQQy3990gPR iuioA1fpYNsgqxBoXueNruxEVk265F3m6qEXJx5ozvZ+MBb1fjc/4VtXVOMtBvVlEAY8 FEv+H+LYaFzW35gpNN6yITejA9HQdsxZ5b/kmhvJDrvDt+mSHnWcmasZr8HpOzB3HTxW 0s78he5r0fWfsa+v6SqljAUz2dmpMSQSNVNhi6EECnRH/44r5aHiRrcc8adpBIZAVYMf lt/g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=D4i6s7/VLVeW8cmhjedIhbBrwFwI0HednQDhcygFPUk=; b=pRGDME+EKZUaDxl4DhmxG4XCPHOoD3SBfkoPeWE0yRHTluImSf/Rk7WVugL+9oTfOx cmee5mtoWKAqlmDvTM9mBm5dfeA6wNQJ0P39PE2t1ug7fTs9FbugT366ru/0wUTtPuAp /MdZl/Wd9V6vDsLfB+kbJr2C3zDRYngPF8ODY2otGCqA2fS+GEZ5qELpZ6I8hYOEayCs 2PN8tO7Q80T07/TKgA6no22Dnn4cSDHLWt/3Hfsn7h+vMIpDZ8sEPubwgmScPyguloDf GMbQfPj02nbIn73ywCPXq4PBIsZTZLuwbn9SelonjsFEmh0quStaEtcczgVrTwFXQZBy ZQlg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=eCVXX8QO; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id co1si2230909edb.571.2021.01.07.05.34.30; Thu, 07 Jan 2021 05:34:54 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=eCVXX8QO; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728781AbhAGNbJ (ORCPT + 99 others); Thu, 7 Jan 2021 08:31:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47182 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728612AbhAGNaR (ORCPT ); Thu, 7 Jan 2021 08:30:17 -0500 Received: from mail-wm1-x32b.google.com (mail-wm1-x32b.google.com [IPv6:2a00:1450:4864:20::32b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E8AFBC0612FD; Thu, 7 Jan 2021 05:29:05 -0800 (PST) Received: by mail-wm1-x32b.google.com with SMTP id a6so5163180wmc.2; Thu, 07 Jan 2021 05:29:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=D4i6s7/VLVeW8cmhjedIhbBrwFwI0HednQDhcygFPUk=; b=eCVXX8QOlddbkO5fbSW13fDBxrWGjADa/YOp5tnEQagV/Hk0HS5i5Hw+vM8JdFec7+ TIg1+S4XacTcdVNpLHQCXt93JQg42VYb/x64nvTvlbpnWTp4u0xrKphgJLYpGhUKuvmJ 7PUvqFZ+/6ljFoSVqJI0iRWJrXJsTwxtUpKVO1xzhxjd2uIpiwhGNSvvyfBmqBSriqQx WDKRbst2tu+6pTCteLN53X0Vzddl34ZHfJ2mwE93NoeT9oSmfj2jfDmZujwDph/RJq2V AybtPlPYuJtuHtL+wcYBDvzy3h3gQFTKBVyt/OAF5OYoJB9vAYRoXJ0Fzu5t/L+7N3VH bFUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=D4i6s7/VLVeW8cmhjedIhbBrwFwI0HednQDhcygFPUk=; b=ehI8XGzQXn0PAnUtsRtAmVxy9GOIvk1nkmnq96pNIiWhpUJ9UvZZTNbB97IGh1RoGv dOv+ohmvCif2Pn8pqAZ0bgOTwsb7KXRfZTENjYa1qK+ZcgeEt+qpK3Fb9AVn+5xE9uQU I47ywI9z/O+OOYQ8NvCPyLe5fhLAq4G/23SE/AxvXXzcaemisUXKwCbVkyvoy6HiZBkt 5yNoU70Ccif/08CefCWfOUqej9Ip7kulOLpC0LIUnGJ8EwK8I9NUVjVzaJbSolv0USyG z/2G81uM9/QHWJLn9h6vqATKLjrGSL1/uKH5dMSaQv+vRK0v/J3SVS+bK3fe6D3+fdQt /MhA== X-Gm-Message-State: AOAM530JZTa4PclqV8ZHDiO1YfRUETB4+X3PEa4ToCWJePwrZcSL987T Ib2TB9lCmqVIGSHbTYRViAkTU7rHrapH3BU2 X-Received: by 2002:a1c:4645:: with SMTP id t66mr7935159wma.152.1610026144707; Thu, 07 Jan 2021 05:29:04 -0800 (PST) Received: from valhalla.home ([2.29.208.120]) by smtp.gmail.com with ESMTPSA id o83sm7660125wme.21.2021.01.07.05.29.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Jan 2021 05:29:04 -0800 (PST) From: Daniel Scally To: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-media@vger.kernel.org, devel@acpica.org, rjw@rjwysocki.net, lenb@kernel.org, gregkh@linuxfoundation.org, mchehab@kernel.org, sergey.senozhatsky@gmail.com Cc: yong.zhi@intel.com, sakari.ailus@linux.intel.com, bingbu.cao@intel.com, tian.shu.qiu@intel.com, robert.moore@intel.com, erik.kaneda@intel.com, pmladek@suse.com, rostedt@goodmis.org, andriy.shevchenko@linux.intel.com, linux@rasmusvillemoes.dk, laurent.pinchart+renesas@ideasonboard.com, jacopo+renesas@jmondi.org, kieran.bingham+renesas@ideasonboard.com, hverkuil-cisco@xs4all.nl, m.felsch@pengutronix.de, niklas.soderlund+renesas@ragnatech.se, prabhakar.mahadev-lad.rj@bp.renesas.com, slongerbeam@gmail.com, heikki.krogerus@linux.intel.com, Laurent Pinchart , Andy Shevchenko Subject: [PATCH v5 08/15] software_node: Add support for fwnode_graph*() family of functions Date: Thu, 7 Jan 2021 13:28:31 +0000 Message-Id: <20210107132838.396641-9-djrscally@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210107132838.396641-1-djrscally@gmail.com> References: <20210107132838.396641-1-djrscally@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Heikki Krogerus This implements the remaining .graph_*() callbacks in the fwnode operations structure for the software nodes. That makes the fwnode_graph_*() functions available in the drivers also when software nodes are used. The implementation tries to mimic the "OF graph" as much as possible, but there is no support for the "reg" device property. The ports will need to have the index in their name which starts with "port@" (for example "port@0", "port@1", ...) and endpoints will use the index of the software node that is given to them during creation. The port nodes can also be grouped under a specially named "ports" subnode, just like in DT, if necessary. The remote-endpoints are reference properties under the endpoint nodes that are named "remote-endpoint". Reviewed-by: Laurent Pinchart Reviewed-by: Andy Shevchenko Signed-off-by: Heikki Krogerus Co-developed-by: Daniel Scally Signed-off-by: Daniel Scally --- Changes in v5: - Cosmetic changes only drivers/base/swnode.c | 115 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 1 deletion(-) diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c index 6f7443c6d3b5..9104a0abd531 100644 --- a/drivers/base/swnode.c +++ b/drivers/base/swnode.c @@ -540,6 +540,115 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode, return 0; } +static struct fwnode_handle * +swnode_graph_find_next_port(const struct fwnode_handle *parent, + struct fwnode_handle *port) +{ + struct fwnode_handle *old = port; + + while ((port = software_node_get_next_child(parent, old))) { + /* + * fwnode ports have naming style "port@", so we search for any + * children that follow that convention. + */ + if (!strncmp(to_swnode(port)->node->name, "port@", + strlen("port@"))) + return port; + old = port; + } + + return NULL; +} + +static struct fwnode_handle * +software_node_graph_get_next_endpoint(const struct fwnode_handle *fwnode, + struct fwnode_handle *endpoint) +{ + struct swnode *swnode = to_swnode(fwnode); + struct fwnode_handle *parent; + struct fwnode_handle *port; + + if (!swnode) + return NULL; + + if (endpoint) { + port = software_node_get_parent(endpoint); + parent = software_node_get_parent(port); + } else { + parent = software_node_get_named_child_node(fwnode, "ports"); + if (!parent) + parent = software_node_get(&swnode->fwnode); + + port = swnode_graph_find_next_port(parent, NULL); + } + + for (; port; port = swnode_graph_find_next_port(parent, port)) { + endpoint = software_node_get_next_child(port, endpoint); + if (endpoint) { + fwnode_handle_put(port); + break; + } + } + + fwnode_handle_put(parent); + + return endpoint; +} + +static struct fwnode_handle * +software_node_graph_get_remote_endpoint(const struct fwnode_handle *fwnode) +{ + struct swnode *swnode = to_swnode(fwnode); + const struct software_node_ref_args *ref; + const struct property_entry *prop; + + if (!swnode) + return NULL; + + prop = property_entry_get(swnode->node->properties, "remote-endpoint"); + if (!prop || prop->type != DEV_PROP_REF || prop->is_inline) + return NULL; + + ref = prop->pointer; + + return software_node_get(software_node_fwnode(ref[0].node)); +} + +static struct fwnode_handle * +software_node_graph_get_port_parent(struct fwnode_handle *fwnode) +{ + struct swnode *swnode = to_swnode(fwnode); + + swnode = swnode->parent; + if (swnode && !strcmp(swnode->node->name, "ports")) + swnode = swnode->parent; + + return swnode ? software_node_get(&swnode->fwnode) : NULL; +} + +static int +software_node_graph_parse_endpoint(const struct fwnode_handle *fwnode, + struct fwnode_endpoint *endpoint) +{ + struct swnode *swnode = to_swnode(fwnode); + const char *parent_name = swnode->parent->node->name; + int ret; + + if (strlen("port@") >= strlen(parent_name) || + strncmp(parent_name, "port@", strlen("port@"))) + return -EINVAL; + + /* Ports have naming style "port@n", we need to select the n */ + ret = kstrtou32(parent_name + strlen("port@"), 10, &endpoint->port); + if (ret) + return ret; + + endpoint->id = swnode->id; + endpoint->local_fwnode = fwnode; + + return 0; +} + static const struct fwnode_operations software_node_ops = { .get = software_node_get, .put = software_node_put, @@ -551,7 +660,11 @@ static const struct fwnode_operations software_node_ops = { .get_parent = software_node_get_parent, .get_next_child_node = software_node_get_next_child, .get_named_child_node = software_node_get_named_child_node, - .get_reference_args = software_node_get_reference_args + .get_reference_args = software_node_get_reference_args, + .graph_get_next_endpoint = software_node_graph_get_next_endpoint, + .graph_get_remote_endpoint = software_node_graph_get_remote_endpoint, + .graph_get_port_parent = software_node_graph_get_port_parent, + .graph_parse_endpoint = software_node_graph_parse_endpoint, }; /* -------------------------------------------------------------------------- */ -- 2.25.1