From patchwork Fri Jul 11 07:08:25 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 4531011 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id CE8059F36A for ; Fri, 11 Jul 2014 07:08:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E2A192018E for ; Fri, 11 Jul 2014 07:08:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5B182201F4 for ; Fri, 11 Jul 2014 07:08:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751154AbaGKHId (ORCPT ); Fri, 11 Jul 2014 03:08:33 -0400 Received: from mail-wg0-f48.google.com ([74.125.82.48]:59572 "EHLO mail-wg0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751438AbaGKHIc (ORCPT ); Fri, 11 Jul 2014 03:08:32 -0400 Received: by mail-wg0-f48.google.com with SMTP id x13so606094wgg.7 for ; Fri, 11 Jul 2014 00:08:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Q2GM1lPlhvJpWxlg3kE7bW4YYzrd5tUOX2b3wZyCFUI=; b=x66Bd5ZBjA5xbIgMRo6wCl1GYgm4NT1YhakwydBXtT0n/SZkP8EXI03sRjrRH7OSO9 yJM2CAMt0lTKS5ZBAzBaEJ+XWz/hQx3gRyNL4BAC48uWHKPAI7Mt5OMlC3MbBh6Dcq2z 0ygSux7eb3JG1jqXnoJoOnLyjVz9z9nPJbb4bYnA/6te0zFLmXVmwJ4kY7PNS6Q5ZsQu WfW8sWlBXpTD8UlxAy5PldsSMSczRezGb9A0IfSG7CYfFE0B0fuPfQVKNQnk0sgFXf/J IBJVZp6455xwJyhT7sXZPnxZhrmUGkmvmwrc5zrOCaSW9jfdkfAb6tgcnlAOGfYXMRwm Pqrw== X-Received: by 10.194.249.98 with SMTP id yt2mr49924858wjc.66.1405062511371; Fri, 11 Jul 2014 00:08:31 -0700 (PDT) Received: from localhost (port-3164.pppoe.wtnet.de. [84.46.12.104]) by mx.google.com with ESMTPSA id ec8sm4088560wic.10.2014.07.11.00.08.30 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 11 Jul 2014 00:08:30 -0700 (PDT) From: Thierry Reding To: Bjorn Helgaas Cc: Stephen Warren , linux-pci@vger.kernel.org, linux-tegra@vger.kernel.org Subject: [PATCH 2/2] PCI: tegra: Implement a proper resource hierarchy Date: Fri, 11 Jul 2014 09:08:25 +0200 Message-Id: <1405062505-2606-2-git-send-email-thierry.reding@gmail.com> X-Mailer: git-send-email 2.0.1 In-Reply-To: <1405062505-2606-1-git-send-email-thierry.reding@gmail.com> References: <1405062505-2606-1-git-send-email-thierry.reding@gmail.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Thierry Reding Currently the resource hierarchy generated from the PCIe host bridge is completely flat: $ cat /proc/iomem 00000000-00000fff : /pcie-controller@00003000/pci@1,0 00003000-000037ff : pads 00003800-000039ff : afi 10000000-1fffffff : cs 28000000-28003fff : r8169 28004000-28004fff : r8169 ... The host bridge driver doesn't request all the resources that are used. Windows allocated to each of the root ports aren't tracked, so there is no way for resources allocated to individual devices to be matched up with the correct parent resource by the PCI core. This patch addresses this in two steps. It first takes the union of all regions associated with the PCIe host bridge (control registers, root port registers, configuration space, I/O and prefetchable as well as non-prefetchable memory regions) and uses it as the new root of the resource hierarchy. Subsequently, regions are allocated from within this new root resource so that the resource tree looks much more like what's expected: # cat /proc/iomem 00000000-3fffffff : /pcie-controller@00003000 00000000-00000fff : /pcie-controller@00003000/pci@1,0 00003000-000037ff : pads 00003800-000039ff : afi 10000000-1fffffff : cs 20000000-27ffffff : non-prefetchable 28000000-3fffffff : prefetchable 28000000-280fffff : PCI Bus 0000:01 28000000-28003fff : 0000:01:00.0 28000000-28003fff : r8169 28004000-28004fff : 0000:01:00.0 28004000-28004fff : r8169 ... Signed-off-by: Thierry Reding Reviewed-by: Stephen Warren --- drivers/pci/host/pci-tegra.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 49b3bd5f5926..b0b337ebaf48 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c @@ -252,6 +252,7 @@ struct tegra_pcie { struct list_head buses; struct resource *cs; + struct resource all; struct resource io; struct resource mem; struct resource prefetch; @@ -625,6 +626,15 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable); static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) { struct tegra_pcie *pcie = sys_to_pcie(sys); + int err; + + err = devm_request_resource(pcie->dev, &pcie->all, &pcie->mem); + if (err < 0) + return err; + + err = devm_request_resource(pcie->dev, &pcie->all, &pcie->prefetch); + if (err) + return err; pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); pci_add_resource_offset(&sys->resources, &pcie->prefetch, @@ -1439,6 +1449,12 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) struct resource res; int err; + memset(&pcie->all, 0, sizeof(pcie->all)); + pcie->all.flags = IORESOURCE_MEM; + pcie->all.name = np->full_name; + pcie->all.start = ~0; + pcie->all.end = 0; + if (of_pci_range_parser_init(&parser, np)) { dev_err(pcie->dev, "missing \"ranges\" property\n"); return -EINVAL; @@ -1450,21 +1466,31 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) switch (res.flags & IORESOURCE_TYPE_BITS) { case IORESOURCE_IO: memcpy(&pcie->io, &res, sizeof(res)); - pcie->io.name = "I/O"; + pcie->io.name = np->full_name; break; case IORESOURCE_MEM: if (res.flags & IORESOURCE_PREFETCH) { memcpy(&pcie->prefetch, &res, sizeof(res)); - pcie->prefetch.name = "PREFETCH"; + pcie->prefetch.name = "prefetchable"; } else { memcpy(&pcie->mem, &res, sizeof(res)); - pcie->mem.name = "MEM"; + pcie->mem.name = "non-prefetchable"; } break; } + + if (res.start <= pcie->all.start) + pcie->all.start = res.start; + + if (res.end >= pcie->all.end) + pcie->all.end = res.end; } + err = devm_request_resource(pcie->dev, &iomem_resource, &pcie->all); + if (err < 0) + return err; + err = of_pci_parse_bus_range(np, &pcie->busn); if (err < 0) { dev_err(pcie->dev, "failed to parse ranges property: %d\n",