From patchwork Mon Feb 12 05:15:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Stanley X-Patchwork-Id: 127926 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp2878903ljc; Sun, 11 Feb 2018 21:17:17 -0800 (PST) X-Google-Smtp-Source: AH8x225dHBRjsDaTsYFTOOd3uHevxKcS1jO16O7sCIGCWqHDnh0HAsweFf3ab6duQtwb3kfvDrSw X-Received: by 10.101.92.138 with SMTP id a10mr8459359pgt.191.1518412637653; Sun, 11 Feb 2018 21:17:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518412637; cv=none; d=google.com; s=arc-20160816; b=rcdtZpebk35ETfXuzaV2EnVXnPlFFwwmFZ56JY/dkxcCk4SVsZrBD269qdhkqtQDW9 DaalEmYi3luSLFCqEIt7ZZzSd6zlHFtDmCQDAi4iJov8E4sFP/49lVgf7WcWjBDplC11 jBqYV4OWIKN/AD+G6NowIdBt4K8MRFDbbN+7xDdlHgu8htLW0/Ir3NQavsDIqpx7HtXQ 6D8iEpd5aTYzUYv0FrVBgfIdlu1hOSwib4z3kxXv1OM6YeZqpXvvz4PoescbSv/rtmPN eQyrjSVyVoG0vsVwHB3MdGeWy2lrRUpQLtIzGometwaAHvfw0i+RAS2oxSCHxmoup0/u v74g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=of7diKi7tfMKvmwg2tF9YoG6ES7Rx3p5XxA+LNA5Ox4=; b=iczWMZLgPY4MOlg0H7DNRZU10frHqEym76oh8EFYilZ/qwLAK86sYic0p60BDTdjix JVdAsN1CBCfhZsXL1hw5VeDkul9rxdd94skIiolaCtAStr4RCOKFPmLwoZXHArb7MnW5 KWHj+8o7JBfj7/eX54mH4RsgKqtk5XFjWKOU08RPvg5UUiMep7wz1gE6+23o/Rldwzcz y8vxEeKlthfC95Egt8TKbIjXukxGZiAlQzGECfKqLthOhWXSTRUrDpnhrqj+51BsI4fS EXdCnZA7Q6xi5MmGNYS7UiVai7yPXM4gSyFSIJ3KMnfnMZQKfcRMmfqY89p7hF7Q8/Ez 4Dfw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=VUFwgm43; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g5si4781952pgp.433.2018.02.11.21.17.17; Sun, 11 Feb 2018 21:17:17 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=VUFwgm43; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932635AbeBLFRK (ORCPT + 13 others); Mon, 12 Feb 2018 00:17:10 -0500 Received: from mail-pg0-f68.google.com ([74.125.83.68]:38018 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932467AbeBLFRE (ORCPT ); Mon, 12 Feb 2018 00:17:04 -0500 Received: by mail-pg0-f68.google.com with SMTP id l24so783578pgc.5; Sun, 11 Feb 2018 21:17:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=of7diKi7tfMKvmwg2tF9YoG6ES7Rx3p5XxA+LNA5Ox4=; b=VUFwgm43TyNdBWv1nkJlt8U48bZpkt9M1ETvLMbh6IcKCFqLnVSmBYVnhQFRGp3Mva NhIp0ty4JIRC7irTWi4XuJ7dQ79BkRyE0V3JaPQHLzw0lZrRn9Sc3jhB1YQNnutXHj/8 IqD+IW1e+KIRuURhf+VU6O+aYoIs15yU6h1XkEiTBBGvAdJmMIGhJbaaPQ4l/ArT6BFh Wyybm5PpfaVqaYqhR8LU8x4wwkZz96N6yPzNGC3FYu2oMFFGpRIxmCngJIBPGjdaIje5 6jpMm3JUBgF/FcxzY44/SigRc4AQvRJfX4dGpde5UCHcbPqJey2YzUvFILXiIPv/cKWv FSEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=of7diKi7tfMKvmwg2tF9YoG6ES7Rx3p5XxA+LNA5Ox4=; b=MElAp6AcGpfBoIYvdsP7vnqXIOUcbDXiTHnvP/uzpLikJ6hA7btYFn+ypu08j0BYuF +Ha9QxmJ7h+pja20zO+URjXHLqgP/sxMMvSRdZWiYvOKlVBJ4AvuIOVR6/0XBq8EJe7O r3fdPS2jclUR8xJunpFHJJHtZGVlS+/owCUTeoBwST/WhfuSWCWPYqChu8z3OoZNr58Y 1rh3xL82E771rWq7TSmddP2Uj6XxYewAcpduaUe3lqgjdz/ZHbrf/oP3wSxtCmbiinWL fNciEH7GNi09c6szcdDvgFunu22WWLqX+laW2xZ69Jvy2Ijz8aLylwk2uz1+WQ/NkVsk be3g== X-Gm-Message-State: APf1xPA+8k9QcxbdPAOIOp48THGgNf+y7lgGnlEk49wt2JeawHwWp7F1 Fg5NahEeOdtgNzAsrnLujrM= X-Received: by 10.98.117.133 with SMTP id q127mr9447627pfc.225.1518412623322; Sun, 11 Feb 2018 21:17:03 -0800 (PST) Received: from aurora.jms.id.au ([203.0.153.9]) by smtp.gmail.com with ESMTPSA id s89sm23149511pfk.35.2018.02.11.21.16.58 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 11 Feb 2018 21:17:02 -0800 (PST) Received: by aurora.jms.id.au (sSMTP sendmail emulation); Mon, 12 Feb 2018 15:46:55 +1030 From: Joel Stanley To: Greg Kroah-Hartman , Rob Herring , Mark Rutland Cc: Jeremy Kerr , Christopher Bostic , Brad Bishop , Edward James , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Subject: [PATCH 06/10] fsi: Match fsi slaves and engines to available dt nodes Date: Mon, 12 Feb 2018 15:45:45 +1030 Message-Id: <20180212051549.8575-7-joel@jms.id.au> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180212051549.8575-1-joel@jms.id.au> References: <20180212051549.8575-1-joel@jms.id.au> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jeremy Kerr This change populates device tree nodes for scanned FSI slaves and engines. If the master populates ->of_node of the FSI master device, we'll look for matching slaves, and under those slaves we'll look for matching engines. This means that FSI drivers will have their ->of_node pointer populated if there's a corresponding DT node, which they can use for further device discover. Presence of device tree nodes is optional, and only required for fsi device drivers that need extra properties, or subordinate devices, to be enumerated. Signed-off-by: Jeremy Kerr Signed-off-by: Joel Stanley --- drivers/fsi/Kconfig | 1 + drivers/fsi/fsi-core.c | 99 +++++++++++++++++++++++++++++++++++++++++++ drivers/fsi/fsi-master-gpio.c | 4 ++ drivers/fsi/fsi-master-hub.c | 4 ++ 4 files changed, 108 insertions(+) -- 2.15.1 diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig index 513e35173aaa..a326ed663d3c 100644 --- a/drivers/fsi/Kconfig +++ b/drivers/fsi/Kconfig @@ -4,6 +4,7 @@ menuconfig FSI tristate "FSI support" + depends on OF select CRC4 ---help--- FSI - the FRU Support Interface - is a simple bus for low-level diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index e5dfece248a5..1069cb402bd3 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -142,6 +143,7 @@ static void fsi_device_release(struct device *_device) { struct fsi_device *device = to_fsi_dev(_device); + of_node_put(device->dev.of_node); kfree(device); } @@ -334,6 +336,57 @@ extern void fsi_slave_release_range(struct fsi_slave *slave, } EXPORT_SYMBOL_GPL(fsi_slave_release_range); +static bool fsi_device_node_matches(struct device *dev, struct device_node *np, + uint32_t addr, uint32_t size) +{ + unsigned int len, na, ns; + const __be32 *prop; + uint32_t psize; + + na = of_n_addr_cells(np); + ns = of_n_size_cells(np); + + if (na != 1 || ns != 1) + return false; + + prop = of_get_property(np, "reg", &len); + if (!prop || len != 8) + return false; + + if (of_read_number(prop, 1) != addr) + return false; + + psize = of_read_number(prop + 1, 1); + if (psize != size) { + dev_warn(dev, + "node %s matches probed address, but not size (got 0x%x, expected 0x%x)", + of_node_full_name(np), psize, size); + } + + return true; +} + +/* Find a matching node for the slave engine at @address, using @size bytes + * of space. Returns NULL if not found, or a matching node with refcount + * already incremented. + */ +static struct device_node *fsi_device_find_of_node(struct fsi_device *dev) +{ + struct device_node *parent, *np; + + parent = dev_of_node(&dev->slave->dev); + if (!parent) + return NULL; + + for_each_child_of_node(parent, np) { + if (fsi_device_node_matches(&dev->dev, np, + dev->addr, dev->size)) + return np; + } + + return NULL; +} + static int fsi_slave_scan(struct fsi_slave *slave) { uint32_t engine_addr; @@ -402,6 +455,7 @@ static int fsi_slave_scan(struct fsi_slave *slave) dev_set_name(&dev->dev, "%02x:%02x:%02x:%02x", slave->master->idx, slave->link, slave->id, i - 2); + dev->dev.of_node = fsi_device_find_of_node(dev); rc = device_register(&dev->dev); if (rc) { @@ -558,9 +612,53 @@ static void fsi_slave_release(struct device *dev) { struct fsi_slave *slave = to_fsi_slave(dev); + of_node_put(dev->of_node); kfree(slave); } +static bool fsi_slave_node_matches(struct device_node *np, + int link, uint8_t id) +{ + unsigned int len, na, ns; + const __be32 *prop; + + na = of_n_addr_cells(np); + ns = of_n_size_cells(np); + + /* Ensure we have the correct format for addresses and sizes in + * reg properties + */ + if (na != 2 || ns != 0) + return false; + + prop = of_get_property(np, "reg", &len); + if (!prop || len != 8) + return false; + + return (of_read_number(prop, 1) == link) && + (of_read_number(prop + 1, 1) == id); +} + +/* Find a matching node for the slave at (link, id). Returns NULL if none + * found, or a matching node with refcount already incremented. + */ +static struct device_node *fsi_slave_find_of_node(struct fsi_master *master, + int link, uint8_t id) +{ + struct device_node *parent, *np; + + parent = dev_of_node(&master->dev); + if (!parent) + return NULL; + + for_each_child_of_node(parent, np) { + if (fsi_slave_node_matches(np, link, id)) + return np; + } + + return NULL; +} + static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id) { uint32_t chip_id, llmode; @@ -623,6 +721,7 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id) slave->master = master; slave->dev.parent = &master->dev; + slave->dev.of_node = fsi_slave_find_of_node(master, link, id); slave->dev.release = fsi_slave_release; slave->link = link; slave->id = id; diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c index b54c213f3dcb..3f487449a277 100644 --- a/drivers/fsi/fsi-master-gpio.c +++ b/drivers/fsi/fsi-master-gpio.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -593,6 +594,7 @@ static int fsi_master_gpio_probe(struct platform_device *pdev) master->dev = &pdev->dev; master->master.dev.parent = master->dev; + master->master.dev.of_node = of_node_get(dev_of_node(master->dev)); gpio = devm_gpiod_get(&pdev->dev, "clock", 0); if (IS_ERR(gpio)) { @@ -664,6 +666,8 @@ static int fsi_master_gpio_remove(struct platform_device *pdev) devm_gpiod_put(&pdev->dev, master->gpio_mux); fsi_master_unregister(&master->master); + of_node_put(master->master.dev.of_node); + return 0; } diff --git a/drivers/fsi/fsi-master-hub.c b/drivers/fsi/fsi-master-hub.c index 133b9bff1d65..3223a671a0ef 100644 --- a/drivers/fsi/fsi-master-hub.c +++ b/drivers/fsi/fsi-master-hub.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "fsi-master.h" @@ -274,6 +275,7 @@ static int hub_master_probe(struct device *dev) hub->master.dev.parent = dev; hub->master.dev.release = hub_master_release; + hub->master.dev.of_node = of_node_get(dev_of_node(dev)); hub->master.n_links = links; hub->master.read = hub_master_read; @@ -302,6 +304,8 @@ static int hub_master_remove(struct device *dev) fsi_master_unregister(&hub->master); fsi_slave_release_range(hub->upstream->slave, hub->addr, hub->size); + of_node_put(hub->master.dev.of_node); + return 0; }