From patchwork Fri Apr 15 17:06:40 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Nowicki X-Patchwork-Id: 8852721 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.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 0DA7D9F36E for ; Fri, 15 Apr 2016 17:11:01 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EF6A2203B7 for ; Fri, 15 Apr 2016 17:10:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D64C82037C for ; Fri, 15 Apr 2016 17:10:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753123AbcDORHZ (ORCPT ); Fri, 15 Apr 2016 13:07:25 -0400 Received: from mail-wm0-f41.google.com ([74.125.82.41]:37551 "EHLO mail-wm0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753082AbcDORHW (ORCPT ); Fri, 15 Apr 2016 13:07:22 -0400 Received: by mail-wm0-f41.google.com with SMTP id n3so41526885wmn.0 for ; Fri, 15 Apr 2016 10:07:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=3PINxNQeWzwHOWH86WNH57Otu4n78Ct8gxUm1O5FGyQ=; b=piW3kmifBPSeV4PHhJg0pmFpoly6UcCEd2+a4tEfjWBv5suiaGzudLrw4jN6urCEWN xEY1MjtBomzg2J7tPZudOIXOWGC3uqMYqkG6ByZxwB8CKbF0sB84DRTNP1pfZmM+/KVd wdwXK1zzjW/PYT8jYJ8Nsz2mOAv4oXqUaM0PQtOaaT4EjJRHipsJxCZEl+ERpeEdJ0BH K2J/J6p39ThUFMoraxXBbyxPC5ayF+cxSCTNmsvIq1odtXnumVIkEny29gplRNoZgNeH xYBx2Lnk15ZPN+bNM3dFwceozc7NEx7mJa2PuNK8TG8DGkvGGuVgBF+qW0uRe1c5htIv 24Xw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=3PINxNQeWzwHOWH86WNH57Otu4n78Ct8gxUm1O5FGyQ=; b=EAn6nHX4u9jHlUTmc+ot+VvXf5d/PcOc0aebUIPsy4VS9F5fTanIq09k3hgClear4r B9Leq8LloMGALvCAh27c0Q3+jLAVhQ8JthoIji2rfuR+ydYHbVMlYcxb8EoYhTOXGAC5 OiXPqrMqGzX2G5/mHmh29dgFqnuRCDlVkSGAhIEezH2A0SZeqLLZ8W+kM3D7Uh6FSlHj rdBtI/V3Z1Z9P4NWYZbWfM34nzc8K3pj3647ACTsoQ2SVo97UI4LLv0SSEWsDoR0BBl0 gfmyEErVrB3vkJ/o3StbA6N3CBRbpi/kCilCE7/uvsNKK/oExlqrCo8slrYmrU2GUJLl zqJQ== X-Gm-Message-State: AOPr4FV3WGpyCVuqXN7kyu44azLypBsAXZm/tRr+OFD4bdUN6Rw22FAajfyXT8pJn9ZxGA== X-Received: by 10.194.61.231 with SMTP id t7mr12612101wjr.32.1460740041153; Fri, 15 Apr 2016 10:07:21 -0700 (PDT) Received: from tn-HP-4.semihalf.local (cardhu.semihalf.com. [213.17.239.108]) by smtp.gmail.com with ESMTPSA id gr4sm14282723wjd.23.2016.04.15.10.07.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 15 Apr 2016 10:07:20 -0700 (PDT) From: Tomasz Nowicki To: helgaas@kernel.org, arnd@arndb.de, will.deacon@arm.com, catalin.marinas@arm.com, rafael@kernel.org, hanjun.guo@linaro.org, Lorenzo.Pieralisi@arm.com, okaya@codeaurora.org, jiang.liu@linux.intel.com, jchandra@broadcom.com Cc: robert.richter@caviumnetworks.com, mw@semihalf.com, Liviu.Dudau@arm.com, ddaney@caviumnetworks.com, wangyijing@huawei.com, Suravee.Suthikulpanit@amd.com, msalter@redhat.com, linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, linaro-acpi@lists.linaro.org, jcm@redhat.com, Tomasz Nowicki Subject: [PATCH V6 05/13] acpi, pci: Support IO resources when parsing PCI host bridge resources. Date: Fri, 15 Apr 2016 19:06:40 +0200 Message-Id: <1460740008-19489-6-git-send-email-tn@semihalf.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1460740008-19489-1-git-send-email-tn@semihalf.com> References: <1460740008-19489-1-git-send-email-tn@semihalf.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.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, 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 Platforms that have memory mapped IO port (such as ARM64) need special handling for PCI I/O resources. For host bridge's resource probing case these resources need to be fixed up with pci_register_io_range/pci_remap_iospace etc. Furthermore, the same I/O resources need to be released after hotplug removal so that it can be re-added back by the pci_remap_iospace function during insertion. Therefore we implement new pci_unmap_iospace call which unmaps I/O space as the symmetry to pci_remap_iospace. Signed-off-by: Jayachandran C Signed-off-by: Sinan Kaya Signed-off-by: Tomasz Nowicki --- drivers/acpi/pci_root.c | 33 +++++++++++++++++++++++++++++++++ drivers/pci/pci.c | 24 ++++++++++++++++++++++++ include/linux/pci.h | 1 + 3 files changed, 58 insertions(+) diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index d9a70c4..815b6ca 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -742,6 +742,34 @@ next: resource_list_add_tail(entry, resources); } } +static void acpi_pci_root_remap_iospace(struct resource_entry *entry) +{ +#ifdef PCI_IOBASE + struct resource *res = entry->res; + resource_size_t cpu_addr = res->start; + resource_size_t pci_addr = cpu_addr - entry->offset; + resource_size_t length = resource_size(res); + unsigned long port; + + if (pci_register_io_range(cpu_addr, length)) + goto err; + + port = pci_address_to_pio(cpu_addr); + if (port == (unsigned long)-1) + goto err; + + res->start = port; + res->end = port + length - 1; + entry->offset = port - pci_addr; + + if (pci_remap_iospace(res, cpu_addr) < 0) + goto err; + pr_info("Remapped I/O %pa to %pR\n", &cpu_addr, res); + return; +err: + res->flags |= IORESOURCE_DISABLED; +#endif +} int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info) { @@ -763,6 +791,9 @@ int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info) "no IO and memory resources present in _CRS\n"); else { resource_list_for_each_entry_safe(entry, tmp, list) { + if (entry->res->flags & IORESOURCE_IO) + acpi_pci_root_remap_iospace(entry); + if (entry->res->flags & IORESOURCE_DISABLED) resource_list_destroy_entry(entry); else @@ -834,6 +865,8 @@ static void acpi_pci_root_release_info(struct pci_host_bridge *bridge) resource_list_for_each_entry(entry, &bridge->windows) { res = entry->res; + if (res->flags & IORESOURCE_IO) + pci_unmap_iospace(res); if (res->parent && (res->flags & (IORESOURCE_MEM | IORESOURCE_IO))) release_resource(res); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 89e9996..c0f8a4e 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include "pci.h" @@ -3168,6 +3169,29 @@ int __weak pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr) #endif } +/** + * pci_unmap_iospace - Unmap the memory mapped I/O space + * @res: resource to be unmapped + * + * Unmap the CPU virtual address @res from virtual address space. + * Only architectures that have memory mapped IO functions defined + * (and the PCI_IOBASE value defined) should call this function. + */ +void pci_unmap_iospace(struct resource *res) +{ +#if defined(PCI_IOBASE) && defined(CONFIG_MMU) + unsigned long vaddr = (unsigned long)PCI_IOBASE + res->start; + + unmap_kernel_range(vaddr, resource_size(res)); +#else + /* + * This architecture does not have memory mapped I/O space, + * so this function should never be called. + */ + WARN_ONCE(1, "This architecture does not support memory mapped I/O\n"); +#endif +} + static void __pci_set_master(struct pci_dev *dev, bool enable) { u16 old_cmd, cmd; diff --git a/include/linux/pci.h b/include/linux/pci.h index c28adb4..df1f33d 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1168,6 +1168,7 @@ int pci_register_io_range(phys_addr_t addr, resource_size_t size); unsigned long pci_address_to_pio(phys_addr_t addr); phys_addr_t pci_pio_to_address(unsigned long pio); int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr); +void pci_unmap_iospace(struct resource *res); static inline pci_bus_addr_t pci_bus_address(struct pci_dev *pdev, int bar) {