From patchwork Mon May 30 15:14:20 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Nowicki X-Patchwork-Id: 9141661 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E7DAD60777 for ; Mon, 30 May 2016 15:17:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D935928225 for ; Mon, 30 May 2016 15:17:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CD4BE28222; Mon, 30 May 2016 15:17:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1B7F128222 for ; Mon, 30 May 2016 15:17:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933494AbcE3PPR (ORCPT ); Mon, 30 May 2016 11:15:17 -0400 Received: from mail-lf0-f45.google.com ([209.85.215.45]:34201 "EHLO mail-lf0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933483AbcE3PPN (ORCPT ); Mon, 30 May 2016 11:15:13 -0400 Received: by mail-lf0-f45.google.com with SMTP id k98so74027971lfi.1 for ; Mon, 30 May 2016 08:15:12 -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=GhlDPZ5EhOxyh0HxoYs7BPp0BxdpPhheIeGPifwV8Wg=; b=GRR1ICPTMpMMQr9913jCAQ7rZmAD2w+/md9hd8vljGXryxdWmf1h0vYfrEQ6BPvQdJ 4ONiHcLtFTArVB4jb35Ux7YPIL3ZqwQhTMdqXnJHgu/wifQv102EkpXQkOIjnV2Fo2Mb Vmy9+PhHL5Y6tEvGS67IHNFTNHQPdsJ5Ri1Mc4QwmT+jTz9DGMr7NDyU0JKA7oZswHdp othN4ZbccyKouIOThc48gzJMJVwoic/xX2jr5mvlIpJWl3+N2JNRjoxXFc3xpH9yD9a8 1kAoJwOiTL9nRJrTBs6+RYIFE+Hc09Wx1sD6CAqO7Y1msjqZmRsukx8Tdfr3Mc8BSFV5 j0/g== 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=GhlDPZ5EhOxyh0HxoYs7BPp0BxdpPhheIeGPifwV8Wg=; b=aJnM7XiCspI0FmU+tY1EnGQvVGE/1nbI0FFqbViB0FXSgCDdnN0PuYJgdyRdCQbmIu 3WxaQNaH/elRVr5W90ktkMTI4UxPG4OM2N+UuLLjoSoyStaL8+tU69PKo+kRHu5G+rJe dZFf2JuNUcMwlRyEiw/A9NCJgBdYHIjHpOnr020Uk2pQg8HsQq5v8PeaJ23NXy83vKRL 5vBy3APRW9SjC0kIaDsG0iPW05qW3Jgb9MB9RfoREZoL4ujzVH5bMLEqW6FqiCV4g8Hw fxB3zFwcuCDvcdQSQl1EA9CghBsC8VMCaDP3pBE7HW9DED8BqJ49HVpUTTAFrWBA8eOe +GaQ== X-Gm-Message-State: ALyK8tK8kUw7blV3+qicaEkFL/Z3+1SvIVq5Brocsd7arEEwZY4Aztcujvwz0kRdKivtpA== X-Received: by 10.25.89.81 with SMTP id n78mr9027060lfb.89.1464621311558; Mon, 30 May 2016 08:15:11 -0700 (PDT) Received: from tn-HP-4.semihalf.local (31-172-191-173.noc.fibertech.net.pl. [31.172.191.173]) by smtp.gmail.com with ESMTPSA id n13sm1392264lfb.33.2016.05.30.08.15.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 30 May 2016 08:15:10 -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, 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, andrea.gallo@linaro.org, dhdang@apm.com, jeremy.linton@arm.com, liudongdong3@huawei.com, cov@codeaurora.org, Tomasz Nowicki Subject: [PATCH V8 7/9] acpi: Add generic MCFG table handling Date: Mon, 30 May 2016 17:14:20 +0200 Message-Id: <1464621262-26770-8-git-send-email-tn@semihalf.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1464621262-26770-1-git-send-email-tn@semihalf.com> References: <1464621262-26770-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-Virus-Scanned: ClamAV using ClamSMTP In order to handle PCI config space regions properly in ACPI, new MCFG interface is defined which does sanity checks on MCFG table and keeps its root pointer. The user is able to lookup MCFG regions based on host bridge root structure and domain:bus_start:bus_end touple. Use pci_mmcfg_late_init old prototype to avoid another function name. Signed-off-by: Tomasz Nowicki Signed-off-by: Jayachandran C Reviewed-by: Lorenzo Pieralisi --- drivers/acpi/Kconfig | 3 ++ drivers/acpi/Makefile | 1 + drivers/acpi/pci_mcfg.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/pci-acpi.h | 2 ++ include/linux/pci.h | 2 +- 5 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 drivers/acpi/pci_mcfg.c diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index b7e2e77..f98c328 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -217,6 +217,9 @@ config ACPI_PROCESSOR_IDLE bool select CPU_IDLE +config ACPI_MCFG + bool + config ACPI_CPPC_LIB bool depends on ACPI_PROCESSOR diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 251ce85..632e81f 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -40,6 +40,7 @@ acpi-$(CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC) += processor_pdc.o acpi-y += ec.o acpi-$(CONFIG_ACPI_DOCK) += dock.o acpi-y += pci_root.o pci_link.o pci_irq.o +obj-$(CONFIG_ACPI_MCFG) += pci_mcfg.o acpi-y += acpi_lpss.o acpi_apd.o acpi-y += acpi_platform.o acpi-y += acpi_pnp.o diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c new file mode 100644 index 0000000..1847f74 --- /dev/null +++ b/drivers/acpi/pci_mcfg.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2016 Broadcom + * Author: Jayachandran C + * Copyright (C) 2016 Semihalf + * Author: Tomasz Nowicki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation (the "GPL"). + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 (GPLv2) for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 (GPLv2) along with this source code. + */ + +#define pr_fmt(fmt) "ACPI: " fmt + +#include +#include +#include + +/* Root pointer to the mapped MCFG table */ +static struct acpi_table_mcfg *mcfg_table; +static int mcfg_entries; + +int pci_mcfg_lookup(struct acpi_pci_root *root) +{ + struct acpi_mcfg_allocation *mptr, *entry = NULL; + struct resource *bus_res = &root->secondary; + int i; + + if (mcfg_table) { + mptr = (struct acpi_mcfg_allocation *) &mcfg_table[1]; + for (i = 0; i < mcfg_entries && !entry; i++, mptr++) + if (mptr->pci_segment == root->segment && + mptr->start_bus_number == bus_res->start) + entry = mptr; + } + + /* not found, use _CBA if available, else error */ + if (!entry) { + if (root->mcfg_addr) + return root->mcfg_addr; + pr_err("%04x:%pR MCFG lookup failed\n", root->segment, bus_res); + return -ENOENT; + } else if (root->mcfg_addr && entry->address != root->mcfg_addr) { + pr_warn("%04x:%pR CBA %pa != MCFG %lx, using CBA\n", + root->segment, bus_res, &root->mcfg_addr, + (unsigned long)entry->address); + return 0; + } + + /* found matching entry, bus range check */ + if (entry->end_bus_number != bus_res->end) { + resource_size_t bus_end = min_t(resource_size_t, + entry->end_bus_number, bus_res->end); + pr_warn("%04x:%pR bus end mismatch, using %02lx\n", + root->segment, bus_res, (unsigned long)bus_end); + bus_res->end = bus_end; + } + + if (!root->mcfg_addr) + root->mcfg_addr = entry->address; + return 0; +} + +static __init int pci_mcfg_parse(struct acpi_table_header *header) +{ + if (header->length < sizeof(struct acpi_table_mcfg)) + return -EINVAL; + + mcfg_entries = (header->length - sizeof(struct acpi_table_mcfg)) / + sizeof(struct acpi_mcfg_allocation); + if (mcfg_entries == 0) { + pr_err("MCFG has no entries\n"); + return -EINVAL; + } + + mcfg_table = (struct acpi_table_mcfg *)header; + pr_info("MCFG table detected, %d entries\n", mcfg_entries); + return 0; +} + +/* Interface called by ACPI - parse and save MCFG table */ +void __init pci_mmcfg_late_init(void) +{ + int err = acpi_table_parse(ACPI_SIG_MCFG, pci_mcfg_parse); + if (err) + pr_err("Failed to parse MCFG (%d)\n", err); +} diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index 89ab057..e0e6dfc 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h @@ -24,6 +24,8 @@ static inline acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) } extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle); +extern int pci_mcfg_lookup(struct acpi_pci_root *root); + static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev) { struct pci_bus *pbus = pdev->bus; diff --git a/include/linux/pci.h b/include/linux/pci.h index bba4053..9661c85 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1724,7 +1724,7 @@ void pcibios_free_irq(struct pci_dev *dev); extern struct dev_pm_ops pcibios_pm_ops; #endif -#ifdef CONFIG_PCI_MMCONFIG +#if defined(CONFIG_PCI_MMCONFIG) || defined(CONFIG_ACPI_MCFG) void __init pci_mmcfg_early_init(void); void __init pci_mmcfg_late_init(void); #else