From patchwork Thu Dec 22 05:35:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hanjun Guo X-Patchwork-Id: 9484345 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 8823E601D3 for ; Thu, 22 Dec 2016 05:49:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7936A280FC for ; Thu, 22 Dec 2016 05:49:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6D8C6282DC; Thu, 22 Dec 2016 05:49:06 +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=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 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.wl.linuxfoundation.org (Postfix) with ESMTPS id AEDCA280FC for ; Thu, 22 Dec 2016 05:49:04 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1cJwDT-00031L-Pw; Thu, 22 Dec 2016 05:46:59 +0000 Received: from szxga01-in.huawei.com ([58.251.152.64]) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1cJwCi-0001Fu-37 for linux-arm-kernel@lists.infradead.org; Thu, 22 Dec 2016 05:46:39 +0000 Received: from 172.24.1.36 (EHLO szxeml425-hub.china.huawei.com) ([172.24.1.36]) by szxrg01-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id DWT84637; Thu, 22 Dec 2016 13:38:50 +0800 (CST) Received: from linux-ibm.site (10.175.102.37) by szxeml425-hub.china.huawei.com (10.82.67.180) with Microsoft SMTP Server id 14.3.235.1; Thu, 22 Dec 2016 13:38:43 +0800 From: Hanjun Guo To: Marc Zyngier , "Rafael J. Wysocki" , Lorenzo Pieralisi Subject: [PATCH v5 09/14] ACPI: platform: setup MSI domain for ACPI based platform device Date: Thu, 22 Dec 2016 13:35:17 +0800 Message-ID: <1482384922-21507-10-git-send-email-guohanjun@huawei.com> X-Mailer: git-send-email 1.7.12.4 In-Reply-To: <1482384922-21507-1-git-send-email-guohanjun@huawei.com> References: <1482384922-21507-1-git-send-email-guohanjun@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.102.37] X-CFilter-Loop: Reflected X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20161221_214631_491454_8A80552F X-CRM114-Status: GOOD ( 17.77 ) 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: huxinwei@huawei.com, Kefeng Wang , Charles Garcia-Tobin , jcm@redhat.com, yimin@huawei.com, Tomasz Nowicki , linux-kernel@vger.kernel.org, linuxarm@huawei.com, Sinan Kaya , linux-acpi@vger.kernel.org, Hanjun Guo , Greg KH , Thomas Gleixner , Agustin Vega-Frias , linux-arm-kernel@lists.infradead.org, Ma Jun 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 From: Hanjun Guo With the platform msi domain created, we can set up the msi domain for a platform device when it's probed. In order to do that, we need to get the domain that the platform device connecting to, so the iort_get_platform_device_domain() is introduced to retrieve the domain from iort. After the domain is retrieved, we need a proper way to set the domain to paltform device, as some platform devices such as an irqchip needs the msi irqdomain to be the interrupt parent domain, we need to get irqdomain before platform device is probed but after the platform device is allocated, so introduce a callback (pre_add_cb) in pdevinfo to prepare firmware related information which is needed for device probe, then set the msi domain in that callback. Signed-off-by: Hanjun Guo Cc: Marc Zyngier Cc: Rafael J. Wysocki Cc: Greg KH Cc: Lorenzo Pieralisi Cc: Thomas Gleixner Tested-by: Xinwei Kong --- drivers/acpi/acpi_platform.c | 11 +++++++++++ drivers/acpi/arm64/iort.c | 43 +++++++++++++++++++++++++++++++++++++++++ drivers/base/platform.c | 3 +++ include/linux/acpi_iort.h | 3 +++ include/linux/platform_device.h | 3 +++ 5 files changed, 63 insertions(+) diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index b4c1a6a..5d8d61b4 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include @@ -48,6 +49,15 @@ static void acpi_platform_fill_resource(struct acpi_device *adev, } /** + * acpi_platform_pre_add_cb - callback before platform device is added, to + * prepare firmware related information which is needed for device probe + */ +static void acpi_platform_pre_add_cb(struct device *dev) +{ + acpi_configure_pmsi_domain(dev); +} + +/** * acpi_create_platform_device - Create platform device for ACPI device node * @adev: ACPI device node to create a platform device for. * @properties: Optional collection of build-in properties. @@ -109,6 +119,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev, pdevinfo.num_res = count; pdevinfo.fwnode = acpi_fwnode_handle(adev); pdevinfo.properties = properties; + pdevinfo.pre_add_cb = acpi_platform_pre_add_cb; if (acpi_dma_supported(adev)) pdevinfo.dma_mask = DMA_BIT_MASK(32); diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index bc68d93..6b72fcb 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -527,6 +527,49 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id) return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI); } +/** + * iort_get_platform_device_domain() - Find MSI domain related to a + * platform device + * @dev: the dev pointer associated with the platform device + * + * Returns: the MSI domain for this device, NULL otherwise + */ +static struct irq_domain *iort_get_platform_device_domain(struct device *dev) +{ + struct acpi_iort_node *node, *msi_parent; + struct fwnode_handle *iort_fwnode; + struct acpi_iort_its_group *its; + + /* find its associated iort node */ + node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT, + iort_match_node_callback, dev); + if (!node) + return NULL; + + /* then find its msi parent node */ + msi_parent = iort_node_get_id(node, NULL, IORT_MSI_TYPE, 0); + if (!msi_parent) + return NULL; + + /* Move to ITS specific data */ + its = (struct acpi_iort_its_group *)msi_parent->node_data; + + iort_fwnode = iort_find_domain_token(its->identifiers[0]); + if (!iort_fwnode) + return NULL; + + return irq_find_matching_fwnode(iort_fwnode, DOMAIN_BUS_PLATFORM_MSI); +} + +void acpi_configure_pmsi_domain(struct device *dev) +{ + struct irq_domain *msi_domain; + + msi_domain = iort_get_platform_device_domain(dev); + if (msi_domain) + dev_set_msi_domain(dev, msi_domain); +} + static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data) { u32 *rid = data; diff --git a/drivers/base/platform.c b/drivers/base/platform.c index c4af003..3e68f31 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -537,6 +537,9 @@ struct platform_device *platform_device_register_full( goto err; } + if (pdevinfo->pre_add_cb) + pdevinfo->pre_add_cb(&pdev->dev); + ret = platform_device_add(pdev); if (ret) { err: diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h index ef99fd52..33f5ac3 100644 --- a/include/linux/acpi_iort.h +++ b/include/linux/acpi_iort.h @@ -38,6 +38,7 @@ /* IOMMU interface */ void iort_set_dma_mask(struct device *dev); const struct iommu_ops *iort_iommu_configure(struct device *dev); +void acpi_configure_pmsi_domain(struct device *dev); #else static inline void acpi_iort_init(void) { } static inline bool iort_node_match(u8 type) { return false; } @@ -58,6 +59,8 @@ static inline void iort_set_dma_mask(struct device *dev) { } static inline const struct iommu_ops *iort_iommu_configure(struct device *dev) { return NULL; } + +static inline void acpi_configure_pmsi_domain(struct device *dev) { } #endif #define IORT_ACPI_DECLARE(name, table_id, fn) \ diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 98c2a7c..280d366fb 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -74,6 +74,9 @@ struct platform_device_info { u64 dma_mask; struct property_entry *properties; + + /* preparation callback before the platform device is added */ + void (*pre_add_cb)(struct device *); }; extern struct platform_device *platform_device_register_full( const struct platform_device_info *pdevinfo);