From patchwork Tue Oct 8 19:43:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rob Herring \(Arm\)" X-Patchwork-Id: 175556 Delivered-To: patch@linaro.org Received: by 2002:a92:7e96:0:0:0:0:0 with SMTP id q22csp6140000ill; Tue, 8 Oct 2019 12:43:03 -0700 (PDT) X-Google-Smtp-Source: APXvYqxC5Z85YoONKEXI+FeVfmBmUbJcS/eMfhe4zuaPNS0GGJxLgISYjWk+lVStOtuOGrrh6IUN X-Received: by 2002:a50:ac03:: with SMTP id v3mr35850400edc.113.1570563783670; Tue, 08 Oct 2019 12:43:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1570563783; cv=none; d=google.com; s=arc-20160816; b=psnnl5a1hiSvsbBTbEYNGZ0/YfPLCc+0Z6NBIGlEyR7dUnzOyl2qQOwJFzHhlSKoMM TY7L7+A5G0Rlm1jh95X4mxToS1mupN8609C8mp+YN482mTa7x7EcCe0nvRTSNfhvuf5e 9xSVEDEVPkCAZzIPwBb5fcn+QYOOXfwhIWfpAkDrJmlStcCzkVByoIqRr4Wp41egzJty Oe9ZTYzG8OAb85bHljx1zbF6yxzf+miL8PDRU3YuU3RUBIfGgCIDTRDjyOjFHG5wapul 8wh5o70l4CMZ2IQr90JqfMPgLmxP/LkLoa7DqmVx1iaR7nYalFAE5tnstUQYXv0GagB9 4/mg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=+hHpNdmx6ZCCeIfcgfwoHn6k+baku1ya57GjAAC0jCk=; b=oQnY3fOwTh8+S21DXfXdSNz1s9wMyMLs257bSsRzDCSDypsxvB2dpzwBRqJXdd5/zU TElsBEA63QnkxXbIUpcfo4qqa1GuFW6bNmJM77ypjLs/m0rIKuafeepbh0yRwhvhPg5/ MV/9plqDGJKQ1BF8HkMEzO4KFj19HRsOWQSHHMNTv9RUKWcTZX7an7Tmr5VSFeIYqq57 IFIp6Pqw1j0GJWBMhgVkj+wkrlG4PUjs2ktev2PJtGOylbbBzDNAAmBj8S4YCgZgFzNK wyjt55l8+7asQq5kv08ygMIVQR8cnjhuCJ3eo8GdcHDTu/1XbjXsU9CCdOPlt/4eNTZe RRjA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c31si12037edb.309.2019.10.08.12.43.03; Tue, 08 Oct 2019 12:43:03 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729602AbfJHTnC (ORCPT + 8 others); Tue, 8 Oct 2019 15:43:02 -0400 Received: from mail-ot1-f67.google.com ([209.85.210.67]:38956 "EHLO mail-ot1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728465AbfJHTnC (ORCPT ); Tue, 8 Oct 2019 15:43:02 -0400 Received: by mail-ot1-f67.google.com with SMTP id s22so15083381otr.6; Tue, 08 Oct 2019 12:43:02 -0700 (PDT) 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:mime-version :content-transfer-encoding; bh=+hHpNdmx6ZCCeIfcgfwoHn6k+baku1ya57GjAAC0jCk=; b=oVMOrScYCgwZwoLm6suVpoQ48XNuV/hsv27J3e6kOJ58qaqJwGePsPohrR7qid6FwF ukTuoyBJuOWT5xW/w0CTncrA6Qu11PcvLRpLm8JGwXInCnlomV5aZ6Smjry8U3uG0SWY jPqNIzeEGbTpkZms4tcQXqZiumjmbpFCRIuHfbuFfnEtExrMmVCvmKAzEQVurMr/Q4ue RGPBLB9mAaoNr4dmeohU/cBk+CbsjobbnnrTxbK6niZN08aMb23xiclojI6s81XaaosQ l4ASVArzGK9ep01LqVdl5xNFKtnj6pExmMH8ECWOB+wINuKH4JzKWgEY893+bQq/0erQ AmdQ== X-Gm-Message-State: APjAAAWgVX4u37p02RlsfDm5CEyzffxU9p1ExbUZ0rUBvrH2kb+C/6qw 0fkBRxMYqj4nOR0kD1AoozxUCoI= X-Received: by 2002:a9d:64c8:: with SMTP id n8mr5431476otl.342.1570563781495; Tue, 08 Oct 2019 12:43:01 -0700 (PDT) Received: from xps15.herring.priv (24-155-109-49.dyn.grandenetworks.net. [24.155.109.49]) by smtp.googlemail.com with ESMTPSA id y16sm5481079otg.7.2019.10.08.12.43.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Oct 2019 12:43:00 -0700 (PDT) From: Rob Herring To: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Robin Murphy Subject: [PATCH v2] of: Make of_dma_get_range() work on bus nodes Date: Tue, 8 Oct 2019 14:43:00 -0500 Message-Id: <20191008194300.12626-1-robh@kernel.org> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Robin Murphy Since the "dma-ranges" property is only valid for a node representing a bus, of_dma_get_range() currently assumes the node passed in is a leaf representing a device, and starts the walk from its parent. In cases like PCI host controllers on typical FDT systems, however, where the PCI endpoints are probed dynamically the initial leaf node represents the 'bus' itself, and this logic means we fail to consider any "dma-ranges" describing the host bridge itself. Rework the logic such that of_dma_get_range() also works correctly starting from a bus node containing "dma-ranges". While this does mean "dma-ranges" could incorrectly be in a device leaf node, there isn't really any way in this function to ensure that a leaf node is or isn't a bus node. Signed-off-by: Robin Murphy [robh: Allow for the bus child node to still be passed in] Signed-off-by: Rob Herring --- v2: - Ensure once we find dma-ranges, every parent has it. - Only get the #{size,address}-cells after we find non-empty dma-ranges - Add a check on the 'dma-ranges' length --- drivers/of/address.c | 44 ++++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) -- 2.20.1 diff --git a/drivers/of/address.c b/drivers/of/address.c index 5ce69d026584..99c1b8058559 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -930,47 +930,39 @@ int of_dma_get_range(struct device_node *np, u64 *dma_addr, u64 *paddr, u64 *siz const __be32 *ranges = NULL; int len, naddr, nsize, pna; int ret = 0; + bool found_dma_ranges = false; u64 dmaaddr; - if (!node) - return -EINVAL; - - while (1) { - struct device_node *parent; - - naddr = of_n_addr_cells(node); - nsize = of_n_size_cells(node); - - parent = __of_get_dma_parent(node); - of_node_put(node); - - node = parent; - if (!node) - break; - + while (node) { ranges = of_get_property(node, "dma-ranges", &len); /* Ignore empty ranges, they imply no translation required */ if (ranges && len > 0) break; - /* - * At least empty ranges has to be defined for parent node if - * DMA is supported - */ - if (!ranges) - break; + /* Once we find 'dma-ranges', then a missing one is an error */ + if (found_dma_ranges && !ranges) { + ret = -ENODEV; + goto out; + } + found_dma_ranges = true; + + node = of_get_next_dma_parent(node); } - if (!ranges) { + if (!node || !ranges) { pr_debug("no dma-ranges found for node(%pOF)\n", np); ret = -ENODEV; goto out; } - len /= sizeof(u32); - + naddr = of_bus_n_addr_cells(node); + nsize = of_bus_n_size_cells(node); pna = of_n_addr_cells(node); + if ((len / sizeof(__be32)) % (pna + naddr + nsize)) { + ret = -EINVAL; + goto out; + } /* dma-ranges format: * DMA addr : naddr cells @@ -978,7 +970,7 @@ int of_dma_get_range(struct device_node *np, u64 *dma_addr, u64 *paddr, u64 *siz * size : nsize cells */ dmaaddr = of_read_number(ranges, naddr); - *paddr = of_translate_dma_address(np, ranges); + *paddr = of_translate_dma_address(node, ranges + naddr); if (*paddr == OF_BAD_ADDR) { pr_err("translation of DMA address(%llx) to CPU address failed node(%pOF)\n", dmaaddr, np);