From patchwork Sat Aug 12 00:02:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Khuong Dinh X-Patchwork-Id: 9896765 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 2EC0C603B4 for ; Sat, 12 Aug 2017 00:04:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1475B28C6A for ; Sat, 12 Aug 2017 00:04:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 091C428C73; Sat, 12 Aug 2017 00:04:15 +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=-2.6 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id DF6EF28C70 for ; Sat, 12 Aug 2017 00:04:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Owner; bh=mXJz/Colvrz/yV/R9iRAbrAbz9jwJdSB1IwmtmJ7cm4=; b=J5i QOPLtVgZ88sg94WBQwIvsjdfhc6GDSM8UdMwSiAeun4Z67UMEQzYYgTuKRi1lUfzGm2Q8w/hDiBNd Al+Anf4k7bRTE1ytPagjkx2SPw8kJTib/ZXJvLnxMP9hF/I4cAueaugcDu/9XoDa5QMx7uD6TMSDD ulSZEeSvXCzhLdC8MPrpY85dwhJo34BGmh0EWUA9Zw+57mf/qs4WNu+z/vVoHicUKSIDyV06npKSq NnqkA6R05EPbc2FdNnqf+XzhXAAh0mwfSH5msnLkP8vDLMhrY2T6lkCEQHwj+MoMJRgnIDGK6REgI bbieJ+B/4PcZfEfPc/ujXRI7ocEtWUw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dgJu4-00049G-Vz; Sat, 12 Aug 2017 00:03:45 +0000 Received: from [198.137.200.161] (helo=denmail01.amcc.com) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dgJu0-000454-6M for linux-arm-kernel@lists.infradead.org; Sat, 12 Aug 2017 00:03:42 +0000 Received: from apm.com (denlwv018.amcc.com [10.88.160.121]) by denmail01.amcc.com (8.13.8/8.13.8) with ESMTP id v7C03BK7013814; Fri, 11 Aug 2017 18:03:11 -0600 Received: (from kdinh@localhost) by apm.com (8.14.4/8.14.4/Submit) id v7C0391D006121; Fri, 11 Aug 2017 18:03:09 -0600 From: Khuong Dinh To: lorenzo.pieralisi@arm.com, marc.zyngier@arm.com, msalter@redhat.com, bhelgaas@google.com, linux-pci@vger.kernel.org, jcm@redhat.com Subject: [PATCH v3 pci] PCI/MSI: pci-xgene-msi: Enable MSI support in ACPI boot for X-Gene v1 Date: Fri, 11 Aug 2017 18:02:53 -0600 Message-Id: <1502496173-6017-1-git-send-email-kdinh@apm.com> X-Mailer: git-send-email 1.7.1 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170811_170340_446090_7575F5C6 X-CRM114-Status: GOOD ( 18.48 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: rjw@rjwysocki.net, Khuong Dinh , patches@apm.com, linux-kernel@vger.kernel.org, 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-Virus-Scanned: ClamAV using ClamSMTP This patch makes pci-xgene-msi driver ACPI-aware and provides MSI capability for X-Gene v1 PCIe controllers in ACPI boot mode. Signed-off-by: Khuong Dinh [Take over from Duc Dang] Acked-by: Marc Zyngier --- v3: - Input X-Gene MSI base address for irq_domain_alloc_fwnode - Add a hook to enforce X-Gene MSI be probed prior acpi_bus_scan happens v2: - Verify with BIOS version 3.06.25 and 3.07.09 v1: - Initial version --- drivers/acpi/Makefile | 2 +- drivers/acpi/acpi_msi.c | 74 ++++++++++++++++++++++++++++++++++++++ drivers/acpi/internal.h | 1 + drivers/acpi/scan.c | 1 + drivers/pci/host/pci-xgene-msi.c | 36 +++++++++++++++++-- 5 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 drivers/acpi/acpi_msi.c diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index b1aacfc..c15f5cd 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -40,7 +40,7 @@ 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_lpss.o acpi_apd.o acpi_msi.o acpi-y += acpi_platform.o acpi-y += acpi_pnp.o acpi-$(CONFIG_ARM_AMBA) += acpi_amba.o diff --git a/drivers/acpi/acpi_msi.c b/drivers/acpi/acpi_msi.c new file mode 100644 index 0000000..c2f8d26 --- /dev/null +++ b/drivers/acpi/acpi_msi.c @@ -0,0 +1,74 @@ +/* + * Enforce MSI driver loaded by PCIe controller driver + * + * Copyright (c) 2017, MACOM Technology Solutions Corporation + * Author: Khuong Dinh + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * 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 for more details. + */ + +#include +#include "internal.h" + +static acpi_status acpi_create_msi_device(acpi_handle handle, u32 Level, + void *context, void **retval) +{ + struct acpi_device *device = NULL; + int type = ACPI_BUS_TYPE_DEVICE; + unsigned long long sta; + acpi_status status; + int ret = 0; + + acpi_bus_get_device(handle, &device); + status = acpi_bus_get_status_handle(handle, &sta); + if (ACPI_FAILURE(status)) + sta = 0; + + device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL); + if (!device) + return -ENOMEM; + + acpi_init_device_object(device, handle, type, sta); + ret = acpi_device_add(device, NULL); + if (ret) + return ret; + device->parent = kzalloc(sizeof(struct acpi_device), GFP_KERNEL); + INIT_LIST_HEAD(&device->parent->physical_node_list); + + acpi_device_add_finalize(device); + + ret = device_attach(&device->dev); + if (ret < 0) + return ret; + + acpi_create_platform_device(device, NULL); + acpi_device_set_enumerated(device); + + return ret; +} + +static const struct acpi_device_id acpi_msi_device_ids[] = { + {"APMC0D0E", 0}, + { } +}; + +int __init acpi_msi_init(void) +{ + acpi_status status; + int ret = 0; + + status = acpi_get_devices(acpi_msi_device_ids[0].id, + acpi_create_msi_device, NULL, NULL); + if (ACPI_FAILURE(status)) + ret = -ENODEV; + + return ret; +} diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 58dd7ab..3da50d3 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -80,6 +80,7 @@ int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler, void acpi_lpss_init(void); void acpi_apd_init(void); +int acpi_msi_init(void); acpi_status acpi_hotplug_schedule(struct acpi_device *adev, u32 src); bool acpi_queue_hotplug_work(struct work_struct *work); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 3389729..8ec4d39 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -2029,6 +2029,7 @@ int __init acpi_scan_init(void) acpi_status status; struct acpi_table_stao *stao_ptr; + acpi_msi_init(); acpi_pci_root_init(); acpi_pci_link_init(); acpi_processor_init(); diff --git a/drivers/pci/host/pci-xgene-msi.c b/drivers/pci/host/pci-xgene-msi.c index f1b633b..b1768a1 100644 --- a/drivers/pci/host/pci-xgene-msi.c +++ b/drivers/pci/host/pci-xgene-msi.c @@ -24,6 +24,7 @@ #include #include #include +#include #define MSI_IR0 0x000000 #define MSI_INT0 0x800000 @@ -39,7 +40,7 @@ struct xgene_msi_group { }; struct xgene_msi { - struct device_node *node; + struct fwnode_handle *fwnode; struct irq_domain *inner_domain; struct irq_domain *msi_domain; u64 msi_addr; @@ -249,6 +250,13 @@ static void xgene_irq_domain_free(struct irq_domain *domain, .free = xgene_irq_domain_free, }; +#ifdef CONFIG_ACPI +static struct fwnode_handle *xgene_msi_get_fwnode(struct device *dev) +{ + return xgene_msi_ctrl.fwnode; +} +#endif + static int xgene_allocate_domains(struct xgene_msi *msi) { msi->inner_domain = irq_domain_add_linear(NULL, NR_MSI_VEC, @@ -256,7 +264,7 @@ static int xgene_allocate_domains(struct xgene_msi *msi) if (!msi->inner_domain) return -ENOMEM; - msi->msi_domain = pci_msi_create_irq_domain(of_node_to_fwnode(msi->node), + msi->msi_domain = pci_msi_create_irq_domain(msi->fwnode, &xgene_msi_domain_info, msi->inner_domain); @@ -265,6 +273,9 @@ static int xgene_allocate_domains(struct xgene_msi *msi) return -ENOMEM; } +#ifdef CONFIG_ACPI + pci_msi_register_fwnode_provider(&xgene_msi_get_fwnode); +#endif return 0; } @@ -449,6 +460,13 @@ static int xgene_msi_hwirq_free(unsigned int cpu) {}, }; +#ifdef CONFIG_ACPI +static const struct acpi_device_id xgene_msi_acpi_ids[] = { + {"APMC0D0E", 0}, + { }, +}; +#endif + static int xgene_msi_probe(struct platform_device *pdev) { struct resource *res; @@ -469,7 +487,18 @@ static int xgene_msi_probe(struct platform_device *pdev) goto error; } xgene_msi->msi_addr = res->start; - xgene_msi->node = pdev->dev.of_node; + + xgene_msi->fwnode = of_node_to_fwnode(pdev->dev.of_node); + if (!xgene_msi->fwnode) { + xgene_msi->fwnode = + irq_domain_alloc_fwnode((void *)xgene_msi->msi_addr); + if (!xgene_msi->fwnode) { + dev_err(&pdev->dev, "Failed to create fwnode\n"); + rc = ENOMEM; + goto error; + } + } + xgene_msi->num_cpus = num_possible_cpus(); rc = xgene_msi_init_allocator(xgene_msi); @@ -540,6 +569,7 @@ static int xgene_msi_probe(struct platform_device *pdev) .driver = { .name = "xgene-msi", .of_match_table = xgene_msi_match_table, + .acpi_match_table = ACPI_PTR(xgene_msi_acpi_ids), }, .probe = xgene_msi_probe, .remove = xgene_msi_remove,