From patchwork Fri Apr 15 17:06:46 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Nowicki X-Patchwork-Id: 8853311 Return-Path: X-Original-To: patchwork-linux-arm@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 503419F36E for ; Fri, 15 Apr 2016 17:14:21 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4C76320154 for ; Fri, 15 Apr 2016 17:14:20 +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 49DB620125 for ; Fri, 15 Apr 2016 17:14:19 +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 1ar7IN-0000O8-Hr; Fri, 15 Apr 2016 17:12:39 +0000 Received: from merlin.infradead.org ([2001:4978:20e::2]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ar7FH-0004od-Uy for linux-arm-kernel@bombadil.infradead.org; Fri, 15 Apr 2016 17:09:28 +0000 Received: from mail-wm0-x233.google.com ([2a00:1450:400c:c09::233]) by merlin.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1ar7FG-0001IR-NL for linux-arm-kernel@lists.infradead.org; Fri, 15 Apr 2016 17:09:27 +0000 Received: by mail-wm0-x233.google.com with SMTP id u206so41262969wme.1 for ; Fri, 15 Apr 2016 10:09:06 -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=YDe7UXF8BwEXCA5MVrlU1gYg3/PiV6KJPx0dwtG/y3g=; b=Y8C0Ijl4Z841XJxRztsLrhrNiZadsAmJEWFKweEpP5A71ri4iCR3hdxKhIeC0LdA2i /3wShMIb4pfdorwl+5xyO8slJWpHhtB46FTis7wWD4iDBsRW6UrKfkdbAgvBjZ1u7zq4 bLqox6sY8qQNWKnhOEaFOVVxObnmudcWLcxdmnuSH4ynMpiGNZSWDrArAKurh4giYRdl ONqDbyVor+MpVBdHLNG+7h+01QepEqLxcvFFGZXnJa7h62QciiQPHtI/3lGgmtrG9CbX Ahnqiqr0tYOVW/Dd+ufM3LzRaxOMxvaZehQppHpgwkY2QfZAFoM7/ueQlr7JXDt7dV9t PlSQ== 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=YDe7UXF8BwEXCA5MVrlU1gYg3/PiV6KJPx0dwtG/y3g=; b=iPpest7sgkNogucfeDU8FMi2FMgJHf+hwALlyqhKTc9o8GGmo/U8G3jxr+13cPzwzx /VkMt7YJ6BYPKkMEfbtHfPDBRn/4UGAz0T9Qf96BYHMY1qYqZ2vhOt7Os8P3/Td6o+Xu Vnba6gN74BscrFfrRKXKP704uAVluSnHTZjvBa2j1/b2NhLhPagJVTfAjft9ZIgLhiXC DrXN0txDWLWYjbcO/xkFhzDsqmgbLp0Aa8yU3qvRezmx0+VGxK3WPu4c5OhNbu7ouOzj 9ssaZ8GALiR+oahLNfUPiplDOLnsCFi6q1M4UxiBgP4WbKUK2kYMp7J02ftUHvlOdjFV 11bA== X-Gm-Message-State: AOPr4FUpZs/tFTCYNI6GoR3MtUyCXvPO95LBzgegb8gFX9byQDe8Fbe6ilnZDr+YrYdTnQ== X-Received: by 10.28.168.72 with SMTP id r69mr5340999wme.37.1460740054726; Fri, 15 Apr 2016 10:07:34 -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.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 15 Apr 2016 10:07:33 -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 Subject: [PATCH V6 11/13] pci, acpi: Match PCI config space accessors against platfrom specific quirks. Date: Fri, 15 Apr 2016 19:06:46 +0200 Message-Id: <1460740008-19489-12-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> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160415_130926_894453_1DF0485D X-CRM114-Status: GOOD ( 17.84 ) 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: 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 , 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=-5.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 Some platforms may not be fully compliant with generic set of PCI config accessors. For these cases we implement the way to overwrite accessors set prior to PCI buses enumeration. Algorithm traverses available quirk list, matches against tuple and an extra match call and returns corresponding PCI config ops. All quirks can be defined using: DECLARE_ACPI_MCFG_FIXUP() macro and kept self contained. Example: /* Additional DMI platform identification (optional) */ static const struct dmi_system_id foo_dmi[] = { { .ident = "", .matches = { DMI_MATCH(DMI_SYS_VENDOR, ""), DMI_MATCH(DMI_PRODUCT_NAME, ""), DMI_MATCH(DMI_PRODUCT_VERSION, "product version"), }, }, { } }; /* Custom PCI config ops */ static struct pci_generic_ecam_ops foo_pci_ops = { .bus_shift = 24, .pci_ops = { .map_bus = pci_mcfg_dev_base, .read = foo_ecam_config_read, .write = foo_ecam_config_write, } }; static int foo_match(struct pci_mcfg_fixup *fixup, struct acpi_pci_root *root) { if (additional platform identification) return true; return false; } DECLARE_ACPI_MCFG_FIXUP(foo_dmi, foo_init, &foo_root_ops, , ); Signed-off-by: Tomasz Nowicki --- drivers/acpi/pci_gen_host.c | 30 +++++++++++++++++++++++++++++- include/asm-generic/vmlinux.lds.h | 7 +++++++ include/linux/pci-acpi.h | 18 ++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/pci_gen_host.c b/drivers/acpi/pci_gen_host.c index fd360b5..e55dfca 100644 --- a/drivers/acpi/pci_gen_host.c +++ b/drivers/acpi/pci_gen_host.c @@ -11,6 +11,8 @@ * You should have received a copy of the GNU General Public License * version 2 (GPLv2) along with this source code. */ + +#include #include #include #include @@ -54,6 +56,32 @@ static struct mcfg_entry *pci_mcfg_lookup(u16 seg, u8 bus_start) return NULL; } +extern struct pci_cfg_fixup __start_acpi_mcfg_fixups[]; +extern struct pci_cfg_fixup __end_acpi_mcfg_fixups[]; + +static struct pci_generic_ecam_ops *pci_acpi_get_ops(struct acpi_pci_root *root) +{ + int bus_num = root->secondary.start; + int domain = root->segment; + struct pci_cfg_fixup *f; + + /* + * Match against platform specific quirks and return corresponding + * CAM ops. + * + * First match against PCI topology then use DMI or + * custom match handler. + */ + for (f = __start_acpi_mcfg_fixups; f < __end_acpi_mcfg_fixups; f++) { + if ((f->domain == domain || f->domain == PCI_MCFG_DOMAIN_ANY) && + (f->bus_num == bus_num || f->bus_num == PCI_MCFG_BUS_ANY) && + (f->system ? dmi_check_system(f->system) : 1) && + (f->match ? f->match(f, root) : 1)) + return f->ops; + } + /* No quirks, use ECAM */ + return &pci_generic_ecam_default_ops; +} /* * Lookup the bus range for the domain in MCFG, and set up config space @@ -95,7 +123,7 @@ static int pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root, } cfg = pci_generic_ecam_create(&root->device->dev, addr, bus_start, - bus_end, &pci_generic_ecam_default_ops); + bus_end, pci_acpi_get_ops(root)); if (IS_ERR(cfg)) { err = PTR_ERR(cfg); pr_err("%04x:%02x-%02x error %d mapping CAM\n", seg, diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 339125b..c53b6b7 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -298,6 +298,13 @@ VMLINUX_SYMBOL(__end_pci_fixups_suspend_late) = .; \ } \ \ + /* ACPI MCFG quirks */ \ + .acpi_fixup : AT(ADDR(.acpi_fixup) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start_acpi_mcfg_fixups) = .; \ + *(.acpi_fixup_mcfg) \ + VMLINUX_SYMBOL(__end_acpi_mcfg_fixups) = .; \ + } \ + \ /* Built-in firmware blobs */ \ .builtin_fw : AT(ADDR(.builtin_fw) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start_builtin_fw) = .; \ diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index a72e22d..9545988 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h @@ -71,6 +71,24 @@ struct acpi_pci_root_ops { int (*prepare_resources)(struct acpi_pci_root_info *info); }; +struct pci_cfg_fixup { + const struct dmi_system_id *system; + bool (*match)(struct pci_cfg_fixup *, struct acpi_pci_root *); + struct pci_generic_ecam_ops *ops; + int domain; + int bus_num; +}; + +#define PCI_MCFG_DOMAIN_ANY -1 +#define PCI_MCFG_BUS_ANY -1 + +/* Designate a routine to fix up buggy MCFG */ +#define DECLARE_ACPI_MCFG_FIXUP(system, match, ops, dom, bus) \ + static const struct pci_cfg_fixup __mcfg_fixup_##system##dom##bus\ + __used __attribute__((__section__(".acpi_fixup_mcfg"), \ + aligned((sizeof(void *))))) = \ + { system, match, ops, dom, bus }; + extern int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info); extern struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root, struct acpi_pci_root_ops *ops,