Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp1661983pxu; Thu, 17 Dec 2020 15:47:40 -0800 (PST) X-Google-Smtp-Source: ABdhPJxcfh4OJPrVQ5KtO5oQwrivZ1WBK5Txhy1lhBo70tdBiTX3z42cwU0mWu+76gj/xMVFP5Np X-Received: by 2002:a50:9ea4:: with SMTP id a33mr1845524edf.70.1608248860394; Thu, 17 Dec 2020 15:47:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1608248860; cv=none; d=google.com; s=arc-20160816; b=drFrAv39CIPNBRLpwY98S/1I3CCoNAMosI032yqWVaxkNnlboPkuiw/mTfbT4JrQ/X sxUofes+WSSGCuJoLGt+E+wzYGisCyfCGNspZGQyI8eokMhzs6Xc8w6VpgW83QtlrIpd 7ZXaLtiJHzV9d8cHK9teVdNK65hECT5FzbVdu9kXhMwisFxGHa1yxRepRRFyKmnfvEgJ xvyA2HSmXxv6vcufsnjAiO/wGIW8s81Q8kgk5o7wYkUPbF9VOKT18608KN+MgAf85gBh /Xd4ZwZYJXmiTzrTLVKfDI6i1vB75SKRZrJFNKTWfG+pLrXAWCVNzN9F6YXhDsFZ+H7w F4Mg== 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=gU5HhP1TeKrMyBxy7gnZuPRoeb13x3wsqwC/lwANoFU=; b=o38Nrh8DwAyBfEB25xeEK9R0nt1OxrqNW0wk+/2Jf6PcPm/xCZh7qCeH0i4mjuV2KD bnoLIbClKlUKfCP30XsO9pr4GEPJfcPeGuOFFtrxZwpNmwsynHT/tghHbDQ4mq/569FO J7SX6yIOVYIpDYhW0UG1FA9UUUg3Kf9ljKBb01tyKiMaddeLNAXyWjxt4bq7FE7Q5deF 5PxHNBqMEst+Y+2ARvxrzYBdJ5JzRbu24k5TF5VegI2UEm1yklGlp2kdZ1R9Njm8fFyz cgJdFOVf0Jcs6Ut0BsCT+nBJ/pZpH7O+QYlA5G7+a9Cdq8X0uo9O7uQbROKp1Go4ezgu HIeA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=o0nqPDOo; 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 o2si3577906ejn.501.2020.12.17.15.47.17; Thu, 17 Dec 2020 15:47:40 -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=o0nqPDOo; 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 S1732403AbgLQXpP (ORCPT + 99 others); Thu, 17 Dec 2020 18:45:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37424 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732337AbgLQXpO (ORCPT ); Thu, 17 Dec 2020 18:45:14 -0500 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6B0F3C061248; Thu, 17 Dec 2020 15:44:01 -0800 (PST) Received: by mail-wr1-x435.google.com with SMTP id c5so232302wrp.6; Thu, 17 Dec 2020 15:44:01 -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=gU5HhP1TeKrMyBxy7gnZuPRoeb13x3wsqwC/lwANoFU=; b=o0nqPDOoz78PdLm4/ZdIUMMVLu3XQvGP2Bp8YwXHCO9SWEIJ23FgNBp41yH5JZz8iJ Z1Nfq38KXTats2hEXlLkjowypJr6nbfSjq+bQ3/wQ6G8Om/O8yz07CudjoZO5Yt24p/d ep5Rv5Uxs7+9/eNzF8XPnZOTQVf0lKfQzkJSfjRmkqfNXRQJikHzAVbbpQfvoCV/JiZi yo0JtKsP5rnBwwSz+A/KS4JsZuSG1Z/eUDh2gzj9bUaPuOaMfews1PvSvt2FXqFHOqtF XK5U2K+m46yCq+LZrtyroRIFe1a+mbPhTkylwyTzJ/SB9PKozUu2H4uGZvTK8VV5+wVG jIOg== 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=gU5HhP1TeKrMyBxy7gnZuPRoeb13x3wsqwC/lwANoFU=; b=fcvW5S6zBiLXkn2Z3QcybwxhpXRzLDiJIG5a/hlWa+Wez7SYeuXfnUxwtei7+hTsRi B2wN9gGvsZOQ6kWWIc6FqX3+cCOTmAOncg0Iuh70ZiAsQPVY/Kh48XUnSUwCdkpcsQwU BNLBUDLNxQvD/PMediTPwy2BlNCfjO5vzc1elsjoJK16UkTdcp3WQ0aMBWazqBmE4dfb 7CxXKWq0E16jsg0J/1LabW0gbyQql7pQqcGxOB6skBdV7DbijNGpfzSGgiPcmN3ZLzvM 2+nn6amDa2MUD4EEslF2ouLPX10cp652un3BL3jq0SMWoOepjDIpzdf5hIIPJMVuojv/ 2TEg== X-Gm-Message-State: AOAM5314HmVAHsePkOWS9HFHN20e7YjR6QDTAG40jo20nvPDNsc2Ep8e WFcmJc2n2lnrXBr3437+Yr2YudENu22SmZVQ X-Received: by 2002:a5d:5401:: with SMTP id g1mr1221389wrv.93.1608248640141; Thu, 17 Dec 2020 15:44:00 -0800 (PST) Received: from valhalla.home ([2.29.208.56]) by smtp.gmail.com with ESMTPSA id o3sm1873575wrc.93.2020.12.17.15.43.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Dec 2020 15:43:59 -0800 (PST) From: Daniel Scally To: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-media@vger.kernel.org, devel@acpica.org Cc: rjw@rjwysocki.net, lenb@kernel.org, gregkh@linuxfoundation.org, yong.zhi@intel.com, sakari.ailus@linux.intel.com, bingbu.cao@intel.com, tian.shu.qiu@intel.com, mchehab@kernel.org, robert.moore@intel.com, erik.kaneda@intel.com, pmladek@suse.com, rostedt@goodmis.org, sergey.senozhatsky@gmail.com, andriy.shevchenko@linux.intel.com, linux@rasmusvillemoes.dk, laurent.pinchart+renesas@ideasonboard.com, jacopo+renesas@jmondi.org, kieran.bingham+renesas@ideasonboard.com, linus.walleij@linaro.org, heikki.krogerus@linux.intel.com, kitakar@gmail.com, jorhand@linux.microsoft.com Subject: [PATCH v2 06/12] software_node: Add support for fwnode_graph*() family of functions Date: Thu, 17 Dec 2020 23:43:31 +0000 Message-Id: <20201217234337.1983732-7-djrscally@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201217234337.1983732-1-djrscally@gmail.com> References: <20201217234337.1983732-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". Signed-off-by: Heikki Krogerus Co-developed-by: Daniel Scally Signed-off-by: Daniel Scally --- Changes in v2: - Changed commit to specify port name prefix as port@ - Accounted for that rename in *parse_endpoint() drivers/base/swnode.c | 110 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-) diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c index 2b90d380039b..0d14d5ebe441 100644 --- a/drivers/base/swnode.c +++ b/drivers/base/swnode.c @@ -540,6 +540,110 @@ 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))) { + if (!strncmp(to_swnode(port)->node->name, "port", 4)) + 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 *old = endpoint; + 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, old); + if (endpoint) { + fwnode_handle_put(port); + break; + } + + /* No more endpoints for that port, so stop passing old */ + old = NULL; + } + + 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); + struct fwnode_handle *parent; + + if (!strcmp(swnode->parent->node->name, "ports")) + parent = &swnode->parent->parent->fwnode; + else + parent = &swnode->parent->fwnode; + + return software_node_get(parent); +} + +static int +software_node_graph_parse_endpoint(const struct fwnode_handle *fwnode, + struct fwnode_endpoint *endpoint) +{ + struct swnode *swnode = to_swnode(fwnode); + int ret; + + ret = kstrtou32(swnode->parent->node->name + 5, 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 +655,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