From patchwork Wed Jan 13 13:21:05 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Nowicki X-Patchwork-Id: 8025541 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id BAE76BEEED for ; Wed, 13 Jan 2016 13:29:50 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 409B4204A0 for ; Wed, 13 Jan 2016 13:29:49 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 283D72047D for ; Wed, 13 Jan 2016 13:29:48 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aJLSL-0006yK-Vh; Wed, 13 Jan 2016 13:27:22 +0000 Received: from mail-wm0-x22e.google.com ([2a00:1450:400c:c09::22e]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aJLNO-0001K8-A1 for linux-arm-kernel@lists.infradead.org; Wed, 13 Jan 2016 13:22:20 +0000 Received: by mail-wm0-x22e.google.com with SMTP id f206so371480887wmf.0 for ; Wed, 13 Jan 2016 05:21:55 -0800 (PST) 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=j1yxHcEnL7qT15ngk+iTS8wvPODMUPzAhSfkTkyK9QA=; b=zg3ViCBmu/FoF53XgRE6pWEP43wPZbKtw5ogP0wIB9sbQAtFvjTc9gxflQ8kIpoNbd sKiVcPKPhteIUT2DEWIuPrs2nZq5ZF4dzO726mTW+kYiCtcc4YSSFwLr2cu9op6rV23O qrd9pg4ba90CC3bKRKfLLUR6rNyJSEXz9U96JtMjYzceLHVNV4KsUtED5+Jeffc4YmSh fvE+Wcl9gRDESUezvI8+olehC1q51LukrmaldK81mgxHHxt5aTXCvDhsT/3eVKtVPP/P IZDDV9i6iuLgNPo7lI/Tl9iwTCK7u0DhzALbADesQVuXxNjlB15wmmsLmcHUdmjDmI04 Um5Q== 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=j1yxHcEnL7qT15ngk+iTS8wvPODMUPzAhSfkTkyK9QA=; b=acPRWGL2tvmye4HMYsF/ULVm1ux9pqhWVFcbmpsV5edVUWk3QPJxVi7piZe9AX2kU5 jno7d89oFFbklBFj6gs/nm3Ay0GYXxvfYhet9Jjd11xPpI8CBslNGAa4mxMCIHQi4o/1 bS4olsJoMJDQI/gy0NmtjZr95ccFOxBqrCLdGssO8AAczF24Jagdk2SAluub5iw2HIJv HMIOjfbtG6bRGHBqExGjiyOeR+nDsqETOC+HIPxNHlaUInj6XVmyef64cppuufte80Xd 2LOe6LtllhsD4WUZ1oIP9dF0DKWLrFpRRXN/Z/zz0hC9iXrernTguV7Xh7vqgmwoR2df Enaw== X-Gm-Message-State: ALoCoQnP/AMPVAKwZ2Hx7RmM53XjcuebK7bVsHLZmX5pQnACJWbjmT3wKfFxM/DGtN2B6zrVaZ+C8mbQPkTkERICRa0ek8Go2A== X-Received: by 10.194.103.234 with SMTP id fz10mr102413646wjb.31.1452691314519; Wed, 13 Jan 2016 05:21:54 -0800 (PST) Received: from tn-HP-4.semihalf.local (cardhu.semihalf.com. [213.17.239.108]) by smtp.gmail.com with ESMTPSA id y124sm8858741wmg.3.2016.01.13.05.21.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 13 Jan 2016 05:21:53 -0800 (PST) From: Tomasz Nowicki To: bhelgaas@google.com, arnd@arndb.de, will.deacon@arm.com, catalin.marinas@arm.com, rjw@rjwysocki.net, hanjun.guo@linaro.org, Lorenzo.Pieralisi@arm.com, okaya@codeaurora.org, jiang.liu@linux.intel.com, Stefano.Stabellini@eu.citrix.com Subject: [PATCH V3 19/21] pci, acpi: Support for ACPI based generic PCI host controller init Date: Wed, 13 Jan 2016 14:21:05 +0100 Message-Id: <1452691267-32240-20-git-send-email-tn@semihalf.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1452691267-32240-1-git-send-email-tn@semihalf.com> References: <1452691267-32240-1-git-send-email-tn@semihalf.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160113_052214_797410_4CFCDF4C X-CRM114-Status: GOOD ( 17.13 ) X-Spam-Score: -2.6 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jchandra@broadcom.com, jcm@redhat.com, linaro-acpi@lists.linaro.org, linux-pci@vger.kernel.org, Liviu.Dudau@arm.com, ddaney@caviumnetworks.com, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, robert.richter@caviumnetworks.com, Suravee.Suthikulpanit@amd.com, msalter@redhat.com, wangyijing@huawei.com, Tomasz Nowicki , tglx@linutronix.de, mw@semihalf.com, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,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 Because of two patch series: 1. Jiang Liu's common interface to support PCI host controller init 2. MMCONFIG refactoring (part of this patch set) now we can think about generic ACPI based PCI host controller init implementation out of arch/ directory. These calls use information from MCFG table (PCI config space regions) and _CRS method (IO/irq resources) to initialize PCI hostbridge. TBD: We are still not sure whether we should reassign resources after PCI bus enumeration or trust firmware to do all that work for us properly. Signed-off-by: Tomasz Nowicki Signed-off-by: Hanjun Guo Signed-off-by: Suravee Suthikulpanit CC: Arnd Bergmann CC: Catalin Marinas CC: Liviu Dudau CC: Lorenzo Pieralisi CC: Will Deacon Tested-by: Suravee Suthikulpanit Tested-by: Jeremy Linton --- drivers/acpi/Kconfig | 5 ++ drivers/acpi/pci_root.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index c3664be..e315061 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -335,6 +335,11 @@ config ACPI_PCI_SLOT i.e., segment/bus/device/function tuples, with physical slots in the system. If you are unsure, say N. +config ACPI_PCI_HOST_GENERIC + bool "Generic ACPI PCI host controller" + help + Say Y here if you want to support generic ACPI PCI host controller. + config X86_PM_TIMER bool "Power Management Timer Support" if EXPERT depends on X86 diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index a65c8c2..d483e2a 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -514,6 +515,136 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm) } } +#ifdef CONFIG_ACPI_PCI_HOST_GENERIC +static int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (pci_dev_msi_enabled(dev)) + return 0; + + acpi_pci_irq_enable(dev); + return dev->irq; +} + +static void pci_mcfg_release_info(struct acpi_pci_root_info *ci) +{ + pci_mmcfg_teardown_map(ci); + kfree(ci); +} + +static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci) +{ + struct list_head *list = &ci->resources; + struct acpi_device *device = ci->bridge; + struct resource_entry *entry, *tmp; + unsigned long flags; + int ret; + + flags = IORESOURCE_IO | IORESOURCE_MEM; + ret = acpi_dev_get_resources(device, list, + acpi_dev_filter_resource_type_cb, + (void *)flags); + if (ret < 0) { + dev_warn(&device->dev, + "failed to parse _CRS method, error code %d\n", ret); + return ret; + } else if (ret == 0) + dev_dbg(&device->dev, + "no IO and memory resources present in _CRS\n"); + + resource_list_for_each_entry_safe(entry, tmp, &ci->resources) { + resource_size_t cpu_addr, length; + struct resource *res = entry->res; + + if (entry->res->flags & IORESOURCE_DISABLED) + resource_list_destroy_entry(entry); + else + res->name = ci->name; + + /* PCI -> CPU space translation */ + cpu_addr = res->start + entry->offset; + length = res->end - res->start + 1; + + if (res->flags & IORESOURCE_MEM) { + res->start = cpu_addr; + res->end = cpu_addr + length - 1; + } else if (res->flags & IORESOURCE_IO) { + resource_size_t pci_addr = res->start; + unsigned long port; + + if (pci_register_io_range(cpu_addr, length)) { + resource_list_destroy_entry(entry); + continue; + } + + port = pci_address_to_pio(cpu_addr); + if (port == (unsigned long)-1) { + resource_list_destroy_entry(entry); + continue; + } + + res->start = port; + res->end = port + length - 1; + entry->offset = port - pci_addr; + + if (pci_remap_iospace(res, cpu_addr) < 0) + resource_list_destroy_entry(entry); + } + } + return ret; +} + +static struct acpi_pci_root_ops acpi_pci_root_ops = { + .init_info = pci_mmcfg_setup_map, + .release_info = pci_mcfg_release_info, + .prepare_resources = pci_acpi_root_prepare_resources, +}; + +/* Root bridge scanning */ +struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) +{ + int node = acpi_get_node(root->device->handle); + int domain = root->segment; + int busnum = root->secondary.start; + struct acpi_pci_root_info *info; + struct pci_host_bridge *bridge; + struct pci_bus *bus, *child; + + if (domain && !pci_domains_supported) { + pr_warn("PCI %04x:%02x: multiple domains not supported.\n", + domain, busnum); + return NULL; + } + + info = kzalloc_node(sizeof(*info), GFP_KERNEL, node); + if (!info) { + dev_err(&root->device->dev, + "pci_bus %04x:%02x: ignored (out of memory)\n", + domain, busnum); + return NULL; + } + + acpi_pci_root_ops.pci_ops = pci_mcfg_get_ops(root); + bus = acpi_pci_root_create(root, &acpi_pci_root_ops, info, root); + if (!bus) + return NULL; + + bridge = pci_find_host_bridge(bus); + bridge->map_irq = pcibios_map_irq; + + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); + + /* + * After the PCI-E bus has been walked and all devices discovered, + * configure any settings of the fabric that might be necessary. + */ + list_for_each_entry(child, &bus->children, node) + pcie_bus_configure_settings(child); + + return bus; +} +#endif /* CONFIG_ARCH_PCI_HOST_GENERIC_ACPI */ + static int acpi_pci_root_add(struct acpi_device *device, const struct acpi_device_id *not_used) {