From patchwork Thu Jun 2 08:41:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Nowicki X-Patchwork-Id: 629120 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3rL12S5nlMz9sD5 for ; Thu, 2 Jun 2016 18:42:56 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=semihalf-com.20150623.gappssmtp.com header.i=@semihalf-com.20150623.gappssmtp.com header.b=xg2qMmg4; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932143AbcFBImc (ORCPT ); Thu, 2 Jun 2016 04:42:32 -0400 Received: from mail-lf0-f46.google.com ([209.85.215.46]:35305 "EHLO mail-lf0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752995AbcFBImE (ORCPT ); Thu, 2 Jun 2016 04:42:04 -0400 Received: by mail-lf0-f46.google.com with SMTP id w16so29124847lfd.2 for ; Thu, 02 Jun 2016 01:42:03 -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=uMFEW0dxfmxtlv1m4oQ39ElsyZG0sWhb2t4Ii9ST3gc=; b=xg2qMmg4u8rHRFQNQimmRE2HVB9GYPGKp7MB85y0lUEy/gjLRz1Z6JrxeehInSfQLw BQEMFYEpUY9Y2PSaBBfEjWyU2hVe6NMWYS0e27j5hwEU92OrumkYH50OKJmfh/4HLkIr uws/IodHajo2q2SImVPACcsVf32Lggxz9A3rUX1IAflQaDuC+MZze6DvJavuWwP4OxG7 LGYgMZqKHzXgVddOG0YZ0NTxk75/KWMWK0KuwvWCc9/stq8TE7lHmMDAMwPfM3fr6bka lG/qX6ymtKkRH+YhzSh5G2YRhdiC9OWKfHeiX8j01IMte1/RqP2hdfI+UUgaHlVoe0zD o4MQ== 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=uMFEW0dxfmxtlv1m4oQ39ElsyZG0sWhb2t4Ii9ST3gc=; b=BufpbHHfQBzg6PODjiOA2RWokIkMykl2qLOSrizHzwGZHZlghmdHcc2vVGji7jArzQ 9qE3zE5lO5TCj2FOfbJlReM5n2ir/eod+4RL2Cyc9HgTXDA5h9KQIhI+dhVwEP2ayWYS mawY9n5MICHRd07UrfpiGs5vbj6CEsQIFZ1exLmkrkX/2r0wTttu3g5BXZQzEvUEu5Fz 3R7FV7E1GPBj9Yx7lOMDLguSq+n5ljrDv1gGwVEiRyc+nHqOa6sOrVVG1+7TTDDSq4Pf OP2YC5FBrh63fK7WCDI7HZrCkPt5yX9wWn6B5IVICccE8mdyyxugVnI/6CbDDtg9ATDI zblQ== X-Gm-Message-State: ALyK8tLeOGaeS6zd+TDZTqqsPmJAW338pRmCRyElm5NGAYTAAvk/xIDRT1wN3iIwoCzyWA== X-Received: by 10.25.156.213 with SMTP id f204mr3852822lfe.51.1464856921860; Thu, 02 Jun 2016 01:42:01 -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 h23sm3972815lji.23.2016.06.02.01.41.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 02 Jun 2016 01:42:00 -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: [RFC PATCH 3/3] pci, pci-thunder-pem: Add ACPI support for ThunderX PEM. Date: Thu, 2 Jun 2016 10:41:03 +0200 Message-Id: <1464856864-18049-4-git-send-email-tn@semihalf.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1464856864-18049-1-git-send-email-tn@semihalf.com> References: <1464856864-18049-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 This patch uses DECLARE_ACPI_MCFG_FIXUP to overwrite PCI config accessors. Also, it provides alternative way to find additional configuration region: thunder_pem_get_acpi_res is looking for host bridge's child (_HID "THRX0001") which contains mentioned configuration region description. See example below: Device (PEM0) { Name (_HID, EISAID ("PNP0A08")) Name (_CID, EISAID ("PNP0A03")) [...] Device (CFG0) { Name (_HID, "THRX0001") // PEM configuration space resources Name (_CRS, ResourceTemplate () { QWordMemory(ResourceConsumer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite, 0, 0x87e0c5000000, 0x87E0C5FFFFFF, 0, 0x01000000) }) } } Signed-off-by: Tomasz Nowicki --- drivers/pci/host/pci-thunder-pem.c | 132 +++++++++++++++++++++++++++++++++---- 1 file changed, 119 insertions(+), 13 deletions(-) diff --git a/drivers/pci/host/pci-thunder-pem.c b/drivers/pci/host/pci-thunder-pem.c index 91f6fc6..8f002ef 100644 --- a/drivers/pci/host/pci-thunder-pem.c +++ b/drivers/pci/host/pci-thunder-pem.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -284,6 +285,83 @@ static int thunder_pem_config_write(struct pci_bus *bus, unsigned int devfn, return pci_generic_config_write(bus, devfn, where, size, val); } +#ifdef CONFIG_ACPI + +struct pem_acpi_res { + struct resource resource; + int found; +}; + +static acpi_status +thunder_pem_cfg(struct acpi_resource *resource, void *ctx) +{ + struct pem_acpi_res *pem_ctx = ctx; + struct resource *res = &pem_ctx->resource; + + if ((resource->type != ACPI_RESOURCE_TYPE_ADDRESS64) || + (resource->data.address32.resource_type != ACPI_MEMORY_RANGE)) + return AE_OK; + + res->start = resource->data.address64.address.minimum; + res->end = resource->data.address64.address.maximum; + res->flags = IORESOURCE_MEM; + + pem_ctx->found++; + return AE_OK; +} + +static acpi_status +thunder_pem_find_dev(acpi_handle handle, u32 level, void *ctx, void **ret) +{ + struct pem_acpi_res *pem_ctx = ctx; + struct acpi_device_info *info; + acpi_status status = AE_OK; + + status = acpi_get_object_info(handle, &info); + if (ACPI_FAILURE(status)) + return AE_OK; + + if (strncmp(info->hardware_id.string, "THRX0001", 8) != 0) + goto out; + + pem_ctx->found = 0; + status = acpi_walk_resources(handle, METHOD_NAME__CRS, thunder_pem_cfg, + pem_ctx); + if (ACPI_FAILURE(status)) + goto out; + + if (pem_ctx->found) + status = AE_CTRL_TERMINATE; +out: + kfree(info); + return status; +} + +static struct resource *thunder_pem_get_acpi_res(struct device *dev) +{ + struct acpi_device *adev = to_acpi_device(dev); + acpi_handle handle = acpi_device_handle(adev); + struct pem_acpi_res *pem_ctx; + acpi_status status; + + pem_ctx = devm_kzalloc(dev, sizeof(*pem_ctx), GFP_KERNEL); + if (!pem_ctx) + return NULL; + + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, + thunder_pem_find_dev, NULL, pem_ctx, NULL); + if (ACPI_FAILURE(status) || !pem_ctx->found) + return NULL; + + return &pem_ctx->resource; +} +#else +static struct resource *thunder_pem_get_acpi_res(struct device *dev) +{ + return NULL; +} +#endif + static int thunder_pem_init(struct pci_config_window *cfg) { struct device *dev = cfg->parent; @@ -292,24 +370,24 @@ static int thunder_pem_init(struct pci_config_window *cfg) struct thunder_pem_pci *pem_pci; struct platform_device *pdev; - /* Only OF support for now */ - if (!dev->of_node) - return -EINVAL; - pem_pci = devm_kzalloc(dev, sizeof(*pem_pci), GFP_KERNEL); if (!pem_pci) return -ENOMEM; - pdev = to_platform_device(dev); - - /* - * The second register range is the PEM bridge to the PCIe - * bus. It has a different config access method than those - * devices behind the bridge. - */ - res_pem = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (acpi_disabled) { + pdev = to_platform_device(dev); + + /* + * The second register range is the PEM bridge to the PCIe + * bus. It has a different config access method than those + * devices behind the bridge. + */ + res_pem = platform_get_resource(pdev, IORESOURCE_MEM, 1); + } else { + res_pem = thunder_pem_get_acpi_res(dev); + } if (!res_pem) { - dev_err(dev, "missing \"reg[1]\"property\n"); + dev_err(dev, "missing configuration region\n"); return -EINVAL; } @@ -362,5 +440,33 @@ static struct platform_driver thunder_pem_driver = { }; module_platform_driver(thunder_pem_driver); +#ifdef CONFIG_ACPI + +DECLARE_ACPI_MCFG_FIXUP(&pci_thunder_pem_ops, "CAVIUM", 1, + 4, PCI_MCFG_BUS_ANY); +DECLARE_ACPI_MCFG_FIXUP(&pci_thunder_pem_ops, "CAVIUM", 1, + 5, PCI_MCFG_BUS_ANY); +DECLARE_ACPI_MCFG_FIXUP(&pci_thunder_pem_ops, "CAVIUM", 1, + 6, PCI_MCFG_BUS_ANY); +DECLARE_ACPI_MCFG_FIXUP(&pci_thunder_pem_ops, "CAVIUM", 1, + 7, PCI_MCFG_BUS_ANY); +DECLARE_ACPI_MCFG_FIXUP(&pci_thunder_pem_ops, "CAVIUM", 1, + 8, PCI_MCFG_BUS_ANY); +DECLARE_ACPI_MCFG_FIXUP(&pci_thunder_pem_ops, "CAVIUM", 1, + 9, PCI_MCFG_BUS_ANY); +DECLARE_ACPI_MCFG_FIXUP(&pci_thunder_pem_ops, "CAVIUM", 1, + 14, PCI_MCFG_BUS_ANY); +DECLARE_ACPI_MCFG_FIXUP(&pci_thunder_pem_ops, "CAVIUM", 1, + 15, PCI_MCFG_BUS_ANY); +DECLARE_ACPI_MCFG_FIXUP(&pci_thunder_pem_ops, "CAVIUM", 1, + 16, PCI_MCFG_BUS_ANY); +DECLARE_ACPI_MCFG_FIXUP(&pci_thunder_pem_ops, "CAVIUM", 1, + 17, PCI_MCFG_BUS_ANY); +DECLARE_ACPI_MCFG_FIXUP(&pci_thunder_pem_ops, "CAVIUM", 1, + 18, PCI_MCFG_BUS_ANY); +DECLARE_ACPI_MCFG_FIXUP(&pci_thunder_pem_ops, "CAVIUM", 1, + 19, PCI_MCFG_BUS_ANY); +#endif + MODULE_DESCRIPTION("Thunder PEM PCIe host driver"); MODULE_LICENSE("GPL v2");