From mboxrd@z Thu Jan 1 00:00:00 1970 From: Suravee Suthikulpanit Subject: [PATCH v6 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices Date: Wed, 9 Dec 2015 11:24:31 -0800 Message-ID: <1449689074-30609-2-git-send-email-Suravee.Suthikulpanit@amd.com> References: <1449689074-30609-1-git-send-email-Suravee.Suthikulpanit@amd.com> Mime-Version: 1.0 Content-Type: text/plain Return-path: In-Reply-To: <1449689074-30609-1-git-send-email-Suravee.Suthikulpanit@amd.com> Sender: linux-kernel-owner@vger.kernel.org To: marc.zyngier@arm.com, tglx@linutronix.de, jason@lakedaemon.net, rjw@rjwysocki.net Cc: Lorenzo Pieralisi , Will Deacon , Catalin Marinas , hanjun.guo@linaro.org, tomasz.nowicki@linaro.org, graeme.gregory@linaro.org, dhdang@apm.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, Suravee Suthikulpanit List-Id: linux-acpi@vger.kernel.org This patch introduces pci_msi_register_fwnode_provider() for irqchip to register a callback, to provide a way to determine appropriate MSI domain for a pci device. It also introduces pci_host_bridge_acpi_msi_domain(), which returns the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI bus token. Then, it is assigned to pci device. Reviewed-by: Marc Zyngier Signed-off-by: Suravee Suthikulpanit --- drivers/pci/pci-acpi.c | 42 ++++++++++++++++++++++++++++++++++++++++++ drivers/pci/probe.c | 2 ++ include/linux/irqdomain.h | 5 +++++ include/linux/pci.h | 10 ++++++++++ 4 files changed, 59 insertions(+) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index a32ba75..d3f32d6 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -9,7 +9,9 @@ #include #include +#include #include +#include #include #include #include @@ -689,6 +691,46 @@ static struct acpi_bus_type acpi_pci_bus = { .cleanup = pci_acpi_cleanup, }; + +static struct fwnode_handle *(*pci_msi_get_fwnode_cb)(struct device *dev); + +/** + * pci_msi_register_fwnode_provider - Register callback to retrieve fwnode + * @fn: Callback matching a device to a fwnode that identifies a PCI + * MSI domain. + * + * This should be called by irqchip driver, which is the parent of + * the MSI domain to provide callback interface to query fwnode. + */ +void +pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *)) +{ + pci_msi_get_fwnode_cb = fn; +} + +/** + * pci_host_bridge_acpi_msi_domain - Retrieve MSI domain of a PCI host bridge + * @bus: The PCI host bridge bus. + * + * This function uses the callback function registered by + * pci_msi_register_fwnode_provider() to retrieve the irq_domain with + * type DOMAIN_BUS_PCI_MSI of the specified host bridge bus. + * This returns NULL on error or when the domain is not found. + */ +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) +{ + struct fwnode_handle *fwnode; + + if (!pci_msi_get_fwnode_cb) + return NULL; + + fwnode = pci_msi_get_fwnode_cb(&bus->dev); + if (!fwnode) + return NULL; + + return irq_find_matching_fwnode(fwnode, DOMAIN_BUS_PCI_MSI); +} + static int __init acpi_pci_init(void) { int ret; diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index edb1984..553a029 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -672,6 +672,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus) * should be called from here. */ d = pci_host_bridge_of_msi_domain(bus); + if (!d) + d = pci_host_bridge_acpi_msi_domain(bus); return d; } diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index d5e5c5b..a06feda 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -410,6 +410,11 @@ static inline bool irq_domain_is_hierarchy(struct irq_domain *domain) static inline void irq_dispose_mapping(unsigned int virq) { } static inline void irq_domain_activate_irq(struct irq_data *data) { } static inline void irq_domain_deactivate_irq(struct irq_data *data) { } +static inline struct irq_domain *irq_find_matching_fwnode( + struct fwnode_handle *fwnode, enum irq_domain_bus_token bus_token) +{ + return NULL; +} #endif /* !CONFIG_IRQ_DOMAIN */ #endif /* _LINUX_IRQDOMAIN_H */ diff --git a/include/linux/pci.h b/include/linux/pci.h index 6ae25aa..d86378c 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1946,6 +1946,16 @@ static inline struct irq_domain * pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; } #endif /* CONFIG_OF */ +#ifdef CONFIG_ACPI +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus); + +void +pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *)); +#else +static inline struct irq_domain * +pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; } +#endif + #ifdef CONFIG_EEH static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev) { -- 2.1.0 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753951AbbLITY7 (ORCPT ); Wed, 9 Dec 2015 14:24:59 -0500 Received: from mail-bn1on0069.outbound.protection.outlook.com ([157.56.110.69]:32354 "EHLO na01-bn1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753830AbbLITYy (ORCPT ); Wed, 9 Dec 2015 14:24:54 -0500 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Suravee.Suthikulpanit@amd.com; From: Suravee Suthikulpanit To: , , , CC: Lorenzo Pieralisi , Will Deacon , Catalin Marinas , , , , , , , , Suravee Suthikulpanit Subject: [PATCH v6 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices Date: Wed, 9 Dec 2015 11:24:31 -0800 Message-ID: <1449689074-30609-2-git-send-email-Suravee.Suthikulpanit@amd.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1449689074-30609-1-git-send-email-Suravee.Suthikulpanit@amd.com> References: <1449689074-30609-1-git-send-email-Suravee.Suthikulpanit@amd.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: CY1PR20CA0108.namprd20.prod.outlook.com (25.164.213.162) To BLUPR12MB0433.namprd12.prod.outlook.com (25.162.92.139) X-Microsoft-Exchange-Diagnostics: 1;BLUPR12MB0433;2:MGJIXDzgMfO4qd7k0OHFbP0MJW54ry4/0clfzbwf7Oit0dyFLDxdw+MPax1aY/WIGYu8Ye+OUZ1bYl0+P6AS3IF8udf5E0ggHGu5yuopd7490AK2EJngZBNWfRS5nutyrjztt1Dlr2iRk82ik+AgIA==;3:ybCX2ZCPcmCY+/tYFDUqe6niRImjbJAJibgKIL6wJuEteu0MSlezISNWv+WuBwoDZDQtu5mt/HiVJ5303Ye2wlc61FigCKlRftOYABGoE2OQ8Znt9aDB6TxNQ/18c6c1;25:Gpd3Z2B8qmSgGsmPeiSUqxd73L1jJZyNBW6xD66zfQeNRjUOgAuKScHJo+hW8/I2XXsI3fEJz4RLKs4Q2IkggUWRGwWqaXQdCAyT/AdETUMqdGVnvM5P/kZcFkOhW5RO7KPSfSIOZmkHba9n7RGDlWPxLB4Sg9xUDga/gTnJc1Zc8FEBzUHt5ttSqmxd4dHQmrzVTkjQxayqQD5IGF/S7qMnI+m4wGcr64CaM30H7ZKSNTGZ7JTlhZVMKGJH+cPgg87AoEj1wemipSJdRRsibQ== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BLUPR12MB0433; X-Microsoft-Exchange-Diagnostics: 1;BLUPR12MB0433;20:QQJHDe8tAodC92tsOMu04rAP1ngKUj+Xx6b3lcwgsZfns7KYYFyVNFG5Ui3coEEZWzMtqKowA6YaGo1nNTd04kwQUNfnIXo8lcAGm6xS1go5fa+eYDOUuWwhk+Yew4tpsc1qqCTImH7WP1kWyswerpFsguPwN2lBrnPdKaqMXQKUS47k4ijVez8X2/98Xa2NG8P8OcgzHduzfMb3Nk9Hjc+EZ7xsJrdLBfE5IxmsSw22p9yxywbN+piNRGeZ5BYFw4NPEk41pDGqJj+bzC9wSAP5fdsbL2JpBkV7TVBmzGGgknKxZ0kQUWhb3gArtl+J5hmiKtjRTHH5ApCMG8IxSgPlHyUWAHsOnPkD3Rp4dE2RY/1HcLEugt1RHiOq0zImAKA5yDqgvidLPEFrsNLf5BxNJxhiJ5BwgjVwLoXlq963utSrr9byUilqmtlGDw56LORhGj94Zji6uHvYoOSdGSlmn74hwSTYI1yCLb8OknYXhaZAiV/7Mi7twVYhD/1F X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110)(180628864354917); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(8121501046)(5005006)(520078)(3002001)(10201501046);SRVR:BLUPR12MB0433;BCL:0;PCL:0;RULEID:;SRVR:BLUPR12MB0433; X-Microsoft-Exchange-Diagnostics: 1;BLUPR12MB0433;4:MfY7mTKzsljfesbwXVo+En+SHqvWOisuYkRMqFRFNlmuRskcjvf2tDr/DbKNM3gjD2+EkLZS5rWcdk55MMatFLh18tSGEztBUC/lmW3UWTJ10+DJ4qoyb18n6/D+Mg+h5R6Ht5aNBLOQ3QXgnZ2smUI1FSEJBR6YbOg9k5NCyVX8+F+jTaahxXg8fe53n9Tr2B1RyMwCi39G/xuokMqZB8tCWkQ1aeak5IK3U0e8T79BELwVAEvexEoNVSF7pfO+ZDnnTLB0Z3SB7aWiHc1gB3RN/kg4zl6i4385KCb9BFibYl38pOjWsdqyCHFE9LRGe0hlCM2Rqe7p3sh7lx6aHVklmZRoVL6Fx+8BYQhKY1zkh1cNqL2QJXf0sSVdSpp0rkuDAksWWYyxLQ0iS6g89+k26Ix1OLoNtUVCHOTD0baKArzr8TqZHVRmsxFUgoihFQPdge/CldR48UW63wMIwQ== X-Forefront-PRVS: 0785459C39 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(979002)(6009001)(199003)(189002)(5001770100001)(50226001)(122386002)(229853001)(36756003)(42186005)(106356001)(105586002)(5004730100002)(86362001)(5003940100001)(2201001)(66066001)(47776003)(53416004)(92566002)(76176999)(97736004)(586003)(189998001)(101416001)(5008740100001)(1096002)(50986999)(50466002)(40100003)(3846002)(2950100001)(77096005)(6116002)(48376002)(87976001)(19580395003)(19580405001)(969003)(989001)(999001)(1009001)(1019001);DIR:OUT;SFP:1101;SCL:1;SRVR:BLUPR12MB0433;H:ssuthiku-fedora-lt.amd.com;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BLUPR12MB0433;23:RQd8C7SiL8vb686ym2FI2gIf0zDnGEU+h7oHQo3kE?= =?us-ascii?Q?d/CD6xjiJ2dMl5VUWERP9M+1SKW7H/gukgZzMoWxCU4tkWJ2jYy90QlljE2d?= =?us-ascii?Q?NlWA7ld8HTwz4r2cAmEL+oxvOUJzPpyM4Ot/0mO2vs7FoESKoR8Ftg4+SG1e?= =?us-ascii?Q?I/mo2He336395ldnk8WD3XpyWZVeDgR3NDMK/zXAaPXOuVtBlzvt34co2a0n?= =?us-ascii?Q?soiy+VNwXHKAhQvxyFFZJgabW5v+Sotsor80c9qoF8FvenGxkEjqcBZbATuN?= =?us-ascii?Q?ARp/tZQ8XbSiLKPD9v21HanCvvPlTixlE5cwCWdnQtI/ZnAV5Kqv34ux+iSO?= =?us-ascii?Q?BAP6SG5Ahlwp0Cs3U17qVtHmYEexKgz5h1XmPc3GtbjcDdiWIX4iyZpPtQ6Q?= =?us-ascii?Q?7GNpzMmBwtcetG9oiTQ7VFVYA2cKqrRXKLcHMz2n0P4WxBPrRQFPTgVmuEwT?= =?us-ascii?Q?D2VhqUpGkheBHHaqwkf+8kQZzwVWCw7CdfMObzqFicPEuFsfVxOh45xEXmRL?= =?us-ascii?Q?daDsvPWrOgM9Nsj/0pTLkMUq3rvkk8YaRYdtK1ZujMEgX36EEi/IYw4O8zvW?= =?us-ascii?Q?0tRSNwGM/PjAoKOPHY9btMiBgdZNOGGta+Pm7qxB3iR+MwdFZJnVw7SCtTfZ?= =?us-ascii?Q?yJ1tRisdQw8kFlfU2rwNPtgIMrPIccejw0jt4+tN5sEdhTHT19LbZgxMze6B?= =?us-ascii?Q?ZotnVc3Rl+0Ba2Cd6DQwD4J9YpVvUurvpEULTpF2poLOeyVa1NjgzrS8siBs?= =?us-ascii?Q?Op3Q+FP7i9Eoaa1R+gQjJphP7SO2nZk1q+lqMVaiea/7rssUBpiZu3T8F+Gh?= =?us-ascii?Q?8Bc/BTzlpLVAnAqn7eKn2/Q/q/aQIZsFIton26m6mKkiyUhM7pyoG+quNuir?= =?us-ascii?Q?C1A3/IBb7+ak04lCYTHnlLjpqYQYZr6ME3OR4LUHIvSlw0w6nRiVkBe5BnR2?= =?us-ascii?Q?ISj+HBJUJNpDdJuE6nCn71QBEZ0TKj1LnCKq/sfl/v2b2ir8pMGR/Su3KU1C?= =?us-ascii?Q?UQ4GHQdRt8QwHlLY0y6+HHiAkoDdNOUpwMIv6UlXWJu+ubkZx+5tJ9sud+Q5?= =?us-ascii?Q?zdKL3jq1Srfrf1x8yrNFRE9Bayt1ApiTblS53bXBwUfssxyJA=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;BLUPR12MB0433;5:idqRPHPDLAfnD2zGHijygF3AUliG+K49/yFjElBR3LSdmN0jF3n6QInpSlXEtdtrMrHvNx9BWvcr2D8ujzObgIAhPQ40S7O3c9ufYjJYZpoCTZaXXkgKTUNUHBBhnt+hEjZ2B2dsvN7ZwizYQ8DGyw==;24:rJtFhzuzm5ldwGsTOiXi5x8QabfhHWtkHqkQLRqqqpxkOG91BI6rlK27pY3DEog29wNcz1d8+P3uiAcbxgk/HX15JpJEQwmPL6Q/4dyhu48=;20:gEIB2uCwCpA2Ae7KaBEzFtZHsyro8zBX33xL+amugftwAGInPZFDyTdviuOd8Ze5Tkce7yz5iwJfAWDk/NaHEg3jEpaTiTETmy9lTZyb0uyhW4yBNGf+hR2xpQ3SqIUugkFMjyy1KeRxSul1Bt7WDTOPynb+BjRJurn2LmBSWaAga9rwDPkk73pIkoxKJ0knEWDdwKegWLM29ATCLzwKwzlJqCMSkKnSZYMbPQYJT+rvrn1w8T89Q3+VHIZ3osg3 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 09 Dec 2015 19:24:48.9067 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BLUPR12MB0433 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch introduces pci_msi_register_fwnode_provider() for irqchip to register a callback, to provide a way to determine appropriate MSI domain for a pci device. It also introduces pci_host_bridge_acpi_msi_domain(), which returns the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI bus token. Then, it is assigned to pci device. Reviewed-by: Marc Zyngier Signed-off-by: Suravee Suthikulpanit --- drivers/pci/pci-acpi.c | 42 ++++++++++++++++++++++++++++++++++++++++++ drivers/pci/probe.c | 2 ++ include/linux/irqdomain.h | 5 +++++ include/linux/pci.h | 10 ++++++++++ 4 files changed, 59 insertions(+) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index a32ba75..d3f32d6 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -9,7 +9,9 @@ #include #include +#include #include +#include #include #include #include @@ -689,6 +691,46 @@ static struct acpi_bus_type acpi_pci_bus = { .cleanup = pci_acpi_cleanup, }; + +static struct fwnode_handle *(*pci_msi_get_fwnode_cb)(struct device *dev); + +/** + * pci_msi_register_fwnode_provider - Register callback to retrieve fwnode + * @fn: Callback matching a device to a fwnode that identifies a PCI + * MSI domain. + * + * This should be called by irqchip driver, which is the parent of + * the MSI domain to provide callback interface to query fwnode. + */ +void +pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *)) +{ + pci_msi_get_fwnode_cb = fn; +} + +/** + * pci_host_bridge_acpi_msi_domain - Retrieve MSI domain of a PCI host bridge + * @bus: The PCI host bridge bus. + * + * This function uses the callback function registered by + * pci_msi_register_fwnode_provider() to retrieve the irq_domain with + * type DOMAIN_BUS_PCI_MSI of the specified host bridge bus. + * This returns NULL on error or when the domain is not found. + */ +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) +{ + struct fwnode_handle *fwnode; + + if (!pci_msi_get_fwnode_cb) + return NULL; + + fwnode = pci_msi_get_fwnode_cb(&bus->dev); + if (!fwnode) + return NULL; + + return irq_find_matching_fwnode(fwnode, DOMAIN_BUS_PCI_MSI); +} + static int __init acpi_pci_init(void) { int ret; diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index edb1984..553a029 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -672,6 +672,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus) * should be called from here. */ d = pci_host_bridge_of_msi_domain(bus); + if (!d) + d = pci_host_bridge_acpi_msi_domain(bus); return d; } diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index d5e5c5b..a06feda 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -410,6 +410,11 @@ static inline bool irq_domain_is_hierarchy(struct irq_domain *domain) static inline void irq_dispose_mapping(unsigned int virq) { } static inline void irq_domain_activate_irq(struct irq_data *data) { } static inline void irq_domain_deactivate_irq(struct irq_data *data) { } +static inline struct irq_domain *irq_find_matching_fwnode( + struct fwnode_handle *fwnode, enum irq_domain_bus_token bus_token) +{ + return NULL; +} #endif /* !CONFIG_IRQ_DOMAIN */ #endif /* _LINUX_IRQDOMAIN_H */ diff --git a/include/linux/pci.h b/include/linux/pci.h index 6ae25aa..d86378c 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1946,6 +1946,16 @@ static inline struct irq_domain * pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; } #endif /* CONFIG_OF */ +#ifdef CONFIG_ACPI +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus); + +void +pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *)); +#else +static inline struct irq_domain * +pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; } +#endif + #ifdef CONFIG_EEH static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev) { -- 2.1.0 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Suravee.Suthikulpanit@amd.com (Suravee Suthikulpanit) Date: Wed, 9 Dec 2015 11:24:31 -0800 Subject: [PATCH v6 1/4] acpi: pci: Setup MSI domain for ACPI based pci devices In-Reply-To: <1449689074-30609-1-git-send-email-Suravee.Suthikulpanit@amd.com> References: <1449689074-30609-1-git-send-email-Suravee.Suthikulpanit@amd.com> Message-ID: <1449689074-30609-2-git-send-email-Suravee.Suthikulpanit@amd.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org This patch introduces pci_msi_register_fwnode_provider() for irqchip to register a callback, to provide a way to determine appropriate MSI domain for a pci device. It also introduces pci_host_bridge_acpi_msi_domain(), which returns the MSI domain of the specified PCI host bridge with DOMAIN_BUS_PCI_MSI bus token. Then, it is assigned to pci device. Reviewed-by: Marc Zyngier Signed-off-by: Suravee Suthikulpanit --- drivers/pci/pci-acpi.c | 42 ++++++++++++++++++++++++++++++++++++++++++ drivers/pci/probe.c | 2 ++ include/linux/irqdomain.h | 5 +++++ include/linux/pci.h | 10 ++++++++++ 4 files changed, 59 insertions(+) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index a32ba75..d3f32d6 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -9,7 +9,9 @@ #include #include +#include #include +#include #include #include #include @@ -689,6 +691,46 @@ static struct acpi_bus_type acpi_pci_bus = { .cleanup = pci_acpi_cleanup, }; + +static struct fwnode_handle *(*pci_msi_get_fwnode_cb)(struct device *dev); + +/** + * pci_msi_register_fwnode_provider - Register callback to retrieve fwnode + * @fn: Callback matching a device to a fwnode that identifies a PCI + * MSI domain. + * + * This should be called by irqchip driver, which is the parent of + * the MSI domain to provide callback interface to query fwnode. + */ +void +pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *)) +{ + pci_msi_get_fwnode_cb = fn; +} + +/** + * pci_host_bridge_acpi_msi_domain - Retrieve MSI domain of a PCI host bridge + * @bus: The PCI host bridge bus. + * + * This function uses the callback function registered by + * pci_msi_register_fwnode_provider() to retrieve the irq_domain with + * type DOMAIN_BUS_PCI_MSI of the specified host bridge bus. + * This returns NULL on error or when the domain is not found. + */ +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) +{ + struct fwnode_handle *fwnode; + + if (!pci_msi_get_fwnode_cb) + return NULL; + + fwnode = pci_msi_get_fwnode_cb(&bus->dev); + if (!fwnode) + return NULL; + + return irq_find_matching_fwnode(fwnode, DOMAIN_BUS_PCI_MSI); +} + static int __init acpi_pci_init(void) { int ret; diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index edb1984..553a029 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -672,6 +672,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus) * should be called from here. */ d = pci_host_bridge_of_msi_domain(bus); + if (!d) + d = pci_host_bridge_acpi_msi_domain(bus); return d; } diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index d5e5c5b..a06feda 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -410,6 +410,11 @@ static inline bool irq_domain_is_hierarchy(struct irq_domain *domain) static inline void irq_dispose_mapping(unsigned int virq) { } static inline void irq_domain_activate_irq(struct irq_data *data) { } static inline void irq_domain_deactivate_irq(struct irq_data *data) { } +static inline struct irq_domain *irq_find_matching_fwnode( + struct fwnode_handle *fwnode, enum irq_domain_bus_token bus_token) +{ + return NULL; +} #endif /* !CONFIG_IRQ_DOMAIN */ #endif /* _LINUX_IRQDOMAIN_H */ diff --git a/include/linux/pci.h b/include/linux/pci.h index 6ae25aa..d86378c 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1946,6 +1946,16 @@ static inline struct irq_domain * pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; } #endif /* CONFIG_OF */ +#ifdef CONFIG_ACPI +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus); + +void +pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *)); +#else +static inline struct irq_domain * +pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; } +#endif + #ifdef CONFIG_EEH static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev) { -- 2.1.0