ACPI platform MSI support
Subsystems (5)
Hanjun Guo
maintainerv4 cover ACPI platform MSI support
From: Hanjun Guo <[email protected]>
v3 -> v4:
- Drop mbi-gen patches to just submit platform msi support because will rebase mbi-gen patches on top of Agustin's patchset, and discusion is going there.
- Add a patch to support device topology such as NC(named componant, paltform device) ->SMMU->ITS which suggested by Lorenzo;
- rebased on top of Lorenzo's v9 of ACPI IORT ARM SMMU support;
- rebased on top of 4.9-rc7
v2 -> v3:
- Drop RFC tag
- Rebase against v4.9-rc2 and Lorenzo's v6 of ACPI IORT ARM SMMU support [1]
- Add 3 cleanup patches (patch 1, 2, 3)
- Drop arch_init call patch from last version
- Introduce a callback for platform device to set msi domain
- Introduce a new API to get paltform device's domain instead of reusing the PCI one in previous version
- Add a patch to rework iort_node_get_id()
[1]: http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1251993.html
v1 -> v2:
- Fix the bug of if multi Interrupt() resoures in single _PRS, we need to calculate all the irq numbers (I missed it in previous version);
- Rebased on Marc's irq/irqchip-4.9 branch and Lorenzo's v5 SMMU patches (also Robin's SMMu patches)
- Add patch irqchip: mbigen: promote mbigen init.
With platform msi support landed in the kernel, and the introduction of IORT for GICv3 ITS (PCI MSI), the framework for platform msi is ready, this patch set add few patches to enable the ACPI platform msi support.
For platform device connecting to ITS on arm platform, we have IORT table with the named componant node to describe the mappings of paltform device and ITS, so we can retrieve the dev id and find its parent irqdomain (ITS) from IORT table (simlar with the ACPI ITS support).
The fisrt 3 patches are cleanups;
Patch 4,5 are refactoring its_pmsi_prepare() for both DT and ACPI then retrieve the dev id from iort;
Patch 6,7 to create platform msi domain to ACPI case which scanned the MADT table;
Patch 8,9,10,11 to setup the msi domain for platform device based on IORT table.
Teasted on Hisilicon D03.
Thanks
Hanjun
Hanjun Guo (11):
ACPI: ARM64: IORT: minor cleanup for iort_match_node_callback()
irqchip: gic-v3-its: keep the head file include in alphabetic order
ACPI: ARM64: IORT: add missing comment for iort_dev_find_its_id()
irqchip: gicv3-its: platform-msi: refactor its_pmsi_prepare()
ACPI: platform-msi: retrieve dev id from IORT
irqchip: gicv3-its: platform-msi: refactor its_pmsi_init() to prepare
for ACPI
irqchip: gicv3-its: platform-msi: scan MADT to create platform msi
domain
ACPI: ARM64: IORT: rework iort_node_get_id()
ACPI: platform: setup MSI domain for ACPI based platform device
ACPI: ARM64: IORT: rework iort_node_get_id() for NC->SMMU->ITS case
msi: platform: make platform_msi_create_device_domain() ACPI aware
drivers/acpi/acpi_platform.c | 11 ++ drivers/acpi/arm64/iort.c | 138 ++++++++++++++++++++------ drivers/base/platform-msi.c | 3 +- drivers/base/platform.c | 3 + drivers/irqchip/irq-gic-v3-its-platform-msi.c | 106 +++++++++++++++----- drivers/irqchip/irq-gic-v3-its.c | 3 +- include/linux/acpi_iort.h | 11 ++ include/linux/platform_device.h | 3 + 8 files changed, 217 insertions(+), 61 deletions(-)
Signature · 1 line
1.7.12.4
Hanjun Guo
maintainerPATCH v4 1/11 ACPI: ARM64: IORT: minor cleanup for iort_match_node_callback()
From: Hanjun Guo <[email protected]>
Cleanup iort_match_node_callback() a little bit to reduce some lines of code, aslo fix the indentation in iort_scan_node().
--- drivers/acpi/arm64/iort.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
drivers/acpi/arm64/iort.c +3 -7
@@ -225,7 +225,7 @@ static struct acpi_iort_node *iort_scan_node(enum acpi_iort_node_type type,if (iort_node->type == type &&ACPI_SUCCESS (callback (iort_node, context))) -return iort_node; +return iort_node; iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node, iort_node->length);
@@ -253,17 +253,15 @@ static acpi_status iort_match_node_callback(struct acpi_iort_node *node, void *context) {struct device *dev = context; -acpi_status status; +acpi_status status =AE_NOT_FOUND ;if (node->type ==ACPI_IORT_NODE_NAMED_COMPONENT ) {struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER ,NULL };struct acpi_device *adev =to_acpi_device_node (dev->fwnode);struct acpi_iort_named_component *ncomp; -if (!adev) { - status =AE_NOT_FOUND ; +if (!adev) goto out; - } status =acpi_get_name (adev->handle,ACPI_FULL_PATHNAME , &buf);if (ACPI_FAILURE (status)) {
@@ -289,8 +287,6 @@ static acpi_status iort_match_node_callback(struct acpi_iort_node *node,*/ status = pci_rc->pci_segment_number ==pci_domain_nr (bus) ?AE_OK :AE_NOT_FOUND ; - }else { - status =AE_NOT_FOUND ; } out:return status;
Signature · 1 line
1.7.12.4
Hanjun Guo
maintainerPATCH v4 2/11 irqchip: gic-v3-its: keep the head file include in alphabetic order
In reply to Hanjun GuoFrom: Hanjun Guo <[email protected]>
The head file is strictly in alphabetic order now, so let's be the rule breaker. As acpi_iort.h includes acpi.h so remove the duplidate acpi.h inclusion as well.
--- drivers/irqchip/irq-gic-v3-its.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/irqchip/irq-gic-v3-its.c +1 -2
@@ -15,14 +15,13 @@* along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <linux/acpi.h> +#include <linux/acpi_iort.h> #include <linux/bitmap.h> #include <linux/cpu.h> #include <linux/delay.h> #include <linux/dma-iommu.h> #include <linux/interrupt.h> #include <linux/irqdomain.h> -#include <linux/acpi_iort.h> #include <linux/log2.h> #include <linux/mm.h> #include <linux/msi.h>
Signature · 1 line
1.7.12.4
Hanjun Guo
maintainerPATCH v4 3/11 ACPI: ARM64: IORT: add missing comment for iort_dev_find_its_id()
In reply to Hanjun GuoFrom: Hanjun Guo <[email protected]>
We are missing req_id's comment for iort_dev_find_its_id(), add it back.
--- drivers/acpi/arm64/iort.c | 1 + 1 file changed, 1 insertion(+)
drivers/acpi/arm64/iort.c +1 -0
@@ -446,6 +446,7 @@ u32 iort_msi_map_rid(struct device *dev, u32 req_id)/** * iort_dev_find_its_id() - Find the ITS identifier for a device * @dev: The device. +* @req_id: Device's Requster ID * @idx: Index of the ITS identifier list. * @its_id: ITS identifier. *
Signature · 1 line
1.7.12.4
Hanjun Guo
maintainerPATCH v4 4/11 irqchip: gicv3-its: platform-msi: refactor its_pmsi_prepare()
In reply to Hanjun GuoFrom: Hanjun Guo <[email protected]>
Adding ACPI support for platform MSI, we need to retrieve the dev id in ACPI way instead of device tree, we already have a well formed function its_pmsi_prepare() to get the dev id but it's OF dependent, so collect OF related code and put them into a single function to make its_pmsi_prepare() more friendly to ACPI later.
--- drivers/irqchip/irq-gic-v3-its-platform-msi.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-)
drivers/irqchip/irq-gic-v3-its-platform-msi.c +16 -7
@@ -24,15 +24,11 @@ .name = "ITS-pMSI", }; -static int its_pmsi_prepare (struct irq_domain *domain,struct device *dev, -int nvec,msi_alloc_info_t *info) +static int of_pmsi_get_dev_id (struct irq_domain *domain,struct device *dev, +u32 *dev_id) { -struct msi_domain_info *msi_info; -u32 dev_id;int ret, index =0 ; - msi_info =msi_get_domain_info (domain->parent); -/* Suck the DeviceID out of the msi-parent property */ do { struct of_phandle_args args;
@@ -43,11 +39,24 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,if (args.np ==irq_domain_get_of_node (domain)) {if (WARN_ON (args.args_count !=1 ))return -EINVAL ; - dev_id = args.args[0 ]; + *dev_id = args.args[0 ];break ; } }while (!ret); +return ret; +} + +static int its_pmsi_prepare (struct irq_domain *domain,struct device *dev, +int nvec,msi_alloc_info_t *info) +{ +struct msi_domain_info *msi_info; +u32 dev_id; +int ret; + + msi_info =msi_get_domain_info (domain->parent); + + ret =of_pmsi_get_dev_id (domain, dev, &dev_id);if (ret)return ret;
Signature · 1 line
1.7.12.4
Hanjun Guo
maintainerPATCH v4 5/11 ACPI: platform-msi: retrieve dev id from IORT
In reply to Hanjun GuoFrom: Hanjun Guo <[email protected]>
For devices connecting to ITS, it needs dev id to identify itself, and this dev id is represented in the IORT table in named componant node [1] for platform devices, so in this patch we will scan the IORT to retrieve device's dev id.
Introduce iort_pmsi_get_dev_id() with pointer dev passed in for that purpose.
[1]: https://static.docs.arm.com/den0049/b/DEN0049B_IO_Remapping_Table.pdf
--- drivers/acpi/arm64/iort.c | 26 ++++++++++++++++++++++++++ drivers/irqchip/irq-gic-v3-its-platform-msi.c | 4 +++- include/linux/acpi_iort.h | 8 ++++++++ 3 files changed, 37 insertions(+), 1 deletion(-)
drivers/acpi/arm64/iort.c +26 -0
@@ -444,6 +444,32 @@ u32 iort_msi_map_rid(struct device *dev, u32 req_id) }/** +* iort_pmsi_get_dev_id() - Get the device id for a device +* @dev: The device for which the mapping is to be done. +* @dev_id: The device ID found. +* +* Returns: 0 for successful find a dev id, errors otherwise +*/ +int iort_pmsi_get_dev_id (struct device *dev,u32 *dev_id) +{ +struct acpi_iort_node *node; + +if (!iort_table) +return -ENODEV ; + + node =iort_find_dev_node (dev); +if (!node) { +dev_err (dev,"can't find related IORT node\n" ); +return -ENODEV ; + } + +if (!iort_node_get_id (node, dev_id,IORT_MSI_TYPE ,0 )) +return -ENODEV ; + +return 0 ; +} + +/** * iort_dev_find_its_id() - Find the ITS identifier for a device * @dev: The device. * @req_id: Device's Requster ID
drivers/irqchip/irq-gic-v3-its-platform-msi.c +3 -1
@@ -15,6 +15,7 @@* along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <linux/acpi_iort.h> #include <linux/device.h> #include <linux/msi.h> #include <linux/of.h>
@@ -56,7 +57,8 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev, msi_info =msi_get_domain_info (domain->parent); - ret =of_pmsi_get_dev_id (domain, dev, &dev_id); + ret = dev->of_node ?of_pmsi_get_dev_id (domain, dev, &dev_id) : +iort_pmsi_get_dev_id (dev, &dev_id);if (ret)return ret;
include/linux/acpi_iort.h +8 -0
@@ -33,6 +33,7 @@void acpi_iort_init (void );bool iort_node_match (u8 type);u32 iort_msi_map_rid (struct device *dev,u32 req_id); +int iort_pmsi_get_dev_id (struct device *dev,u32 *dev_id);struct irq_domain *iort_get_device_domain (struct device *dev,u32 req_id);/* IOMMU interface */ const struct iommu_ops *iort_iommu_configure (struct device *dev);
@@ -41,9 +42,16 @@ static inline void acpi_iort_init(void) { }static inline bool iort_node_match (u8 type) {return false; }static inline u32 iort_msi_map_rid (struct device *dev,u32 req_id) {return req_id; } +static inline struct irq_domain *iort_get_device_domain (struct device *dev,u32 req_id) {return NULL ; } + +static inline int iort_pmsi_get_dev_id (struct device *dev,u32 *dev_id) +{ +return -ENODEV ; +} +/* IOMMU interface */ static inline const struct iommu_ops *iort_iommu_configure (struct device *dev)
Signature · 1 line
1.7.12.4
Hanjun Guo
maintainerPATCH v4 6/11 irqchip: gicv3-its: platform-msi: refactor its_pmsi_init() to prepare for ACPI
In reply to Hanjun GuoFrom: Hanjun Guo <[email protected]>
Introduce its_pmsi_init_one() to refactor the code to isolate ACPI&DT common code to prepare for ACPI later.
--- drivers/irqchip/irq-gic-v3-its-platform-msi.c | 45 ++++++++++++++++----------- 1 file changed, 27 insertions(+), 18 deletions(-)
drivers/irqchip/irq-gic-v3-its-platform-msi.c +27 -18
@@ -84,34 +84,43 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev, {}, }; -static int __init its_pmsi_init (void ) +static int __init its_pmsi_init_one (struct fwnode_handle *fwnode, +const char *name) { -struct device_node *np;struct irq_domain *parent; + parent =irq_find_matching_fwnode (fwnode,DOMAIN_BUS_NEXUS ); +if (!parent || !msi_get_domain_info (parent)) { +pr_err ("%s: unable to locate ITS domain\n" , name); +return -ENXIO ; + } + +if (!platform_msi_create_irq_domain (fwnode, &its_pmsi_domain_info, + parent)) { +pr_err ("%s: unable to create platform domain\n" , name); +return -ENXIO ; + } + +pr_info ("Platform MSI: %s domain created\n" , name); +return 0 ; +} + +static void __init its_pmsi_of_init (void ) +{ +struct device_node *np; +for (np =of_find_matching_node (NULL , its_device_id); np; np =of_find_matching_node (np, its_device_id)) {if (!of_property_read_bool (np,"msi-controller" ))continue ; - parent =irq_find_matching_host (np,DOMAIN_BUS_NEXUS ); -if (!parent || !msi_get_domain_info (parent)) { -pr_err ("%s: unable to locate ITS domain\n" , - np->full_name); -continue ; - } - -if (!platform_msi_create_irq_domain (of_node_to_fwnode (np), - &its_pmsi_domain_info, - parent)) { -pr_err ("%s: unable to create platform domain\n" , - np->full_name); -continue ; - } - -pr_info ("Platform MSI: %s domain created\n" , np->full_name); +its_pmsi_init_one (of_node_to_fwnode (np), np->full_name); } +} +static int __init its_pmsi_init (void ) +{ +its_pmsi_of_init ();return 0 ; }early_initcall (its_pmsi_init);
Signature · 1 line
1.7.12.4
Hanjun Guo
maintainerPATCH v4 7/11 irqchip: gicv3-its: platform-msi: scan MADT to create platform msi domain
In reply to Hanjun GuoFrom: Hanjun Guo <[email protected]>
With the introduction of its_pmsi_init_one(), we can add some code on top for ACPI support of platform MSI.
We are scanning the MADT table to get the ITS entry(ies), then use the information to create the platform msi domain for devices connect to it, just like the PCI MSI for ITS did.
--- drivers/irqchip/irq-gic-v3-its-platform-msi.c | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
drivers/irqchip/irq-gic-v3-its-platform-msi.c +36 -0
@@ -105,6 +105,41 @@ static int __init its_pmsi_init_one(struct fwnode_handle *fwnode,return 0 ; } +#ifdef CONFIG_ACPI +static int __init +its_pmsi_parse_madt (struct acpi_subtable_header *header, +const unsigned long end) +{ +struct acpi_madt_generic_translator *its_entry; +struct fwnode_handle *domain_handle; +const char *node_name; +int err = -ENXIO ; + + its_entry = (struct acpi_madt_generic_translator *)header; + node_name =kasprintf (GFP_KERNEL ,"ITS at 0x%lx" , + (long )its_entry->base_address); + domain_handle =iort_find_domain_token (its_entry->translation_id); +if (!domain_handle) { +pr_err ("%s: Unable to locate ITS domain handle\n" , node_name); + goto out; + } + + err =its_pmsi_init_one (domain_handle, node_name); + +out: +kfree (node_name); +return err; +} + +static void __init its_acpi_pmsi_init (void ) +{ +acpi_table_parse_madt (ACPI_MADT_TYPE_GENERIC_TRANSLATOR , + its_pmsi_parse_madt,0 ); +} +#else +static inline void its_acpi_pmsi_init (void ) { } +#endif +static void __init its_pmsi_of_init (void ) {struct device_node *np;
@@ -121,6 +156,7 @@ static void __init its_pmsi_of_init(void)static int __init its_pmsi_init (void ) {its_pmsi_of_init (); +its_acpi_pmsi_init ();return 0 ; }early_initcall (its_pmsi_init);
Signature · 1 line
1.7.12.4
Hanjun Guo
maintainerPATCH v4 8/11 ACPI: ARM64: IORT: rework iort_node_get_id()
In reply to Hanjun GuoFrom: Hanjun Guo <[email protected]>
iort_node_get_id() has two output, one is the mapped ids, the other is the referenced parent node which is returned from the function.
For now we need a API just return its parent node for single mapping, so just update this function slightly then reuse it later.
--- drivers/acpi/arm64/iort.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/acpi/arm64/iort.c +2 -1
@@ -347,7 +347,8 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,if (map[index].flags &ACPI_IORT_ID_SINGLE_MAPPING ) {if (node->type ==ACPI_IORT_NODE_NAMED_COMPONENT || node->type ==ACPI_IORT_NODE_PCI_ROOT_COMPLEX ) { - *id_out = map[index].output_base; +if (id_out) + *id_out = map[index].output_base;return parent; } }
Signature · 1 line
1.7.12.4
Hanjun Guo
maintainerPATCH v4 9/11 ACPI: platform: setup MSI domain for ACPI based platform device
In reply to Hanjun GuoFrom: Hanjun Guo <[email protected]>
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.
--- 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(+)
drivers/acpi/acpi_platform.c +11 -0
@@ -12,6 +12,7 @@*/ #include <linux/acpi.h> +#include <linux/acpi_iort.h> #include <linux/device.h> #include <linux/err.h> #include <linux/kernel.h>
@@ -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 );
drivers/acpi/arm64/iort.c +43 -0
49 lines not on this page · raw message
drivers/base/platform.c +3 -0
@@ -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:
include/linux/acpi_iort.h +3 -0
@@ -37,6 +37,7 @@struct irq_domain *iort_get_device_domain (struct device *dev,u32 req_id);/* IOMMU interface */ 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; }
@@ -56,6 +57,8 @@ static inline int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)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) \
include/linux/platform_device.h +3 -0
@@ -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);
Signature · 1 line
1.7.12.4
Hanjun Guo
maintainerPATCH v4 10/11 ACPI: ARM64: IORT: rework iort_node_get_id() for NC->SMMU->ITS case
In reply to Hanjun GuoFrom: Hanjun Guo <[email protected]>
iort_node_get_id() for now only support NC(named componant)->SMMU or NC->ITS cases, we also have other device topology such NC-> SMMU->ITS, so rework iort_node_get_id() for those cases.
--- drivers/acpi/arm64/iort.c | 59 ++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 26 deletions(-)
drivers/acpi/arm64/iort.c +33 -26
@@ -292,22 +292,28 @@ static acpi_status iort_match_node_callback(struct acpi_iort_node *node,return status; } -static int iort_id_map (struct acpi_iort_id_mapping *map,u8 type,u32 rid_in, -u32 *rid_out) +static int iort_id_single_map (struct acpi_iort_id_mapping *map,u8 type, +u32 *rid_out) {/* Single mapping does not care for input id */ if (map->flags &ACPI_IORT_ID_SINGLE_MAPPING ) {if (type ==ACPI_IORT_NODE_NAMED_COMPONENT || type ==ACPI_IORT_NODE_PCI_ROOT_COMPLEX ) { - *rid_out = map->output_base; +if (rid_out) + *rid_out = map->output_base;return 0 ; }pr_warn (FW_BUG "[map %p] SINGLE MAPPING flag not allowed for node type %d, skipping ID map\n" , map, type); -return -ENXIO ; } +return -ENXIO ; +} + +static int iort_id_map (struct acpi_iort_id_mapping *map,u8 type,u32 rid_in, +u32 *rid_out) +{if (rid_in < map->input_base || (rid_in >= map->input_base + map->id_count))return -ENXIO ;
@@ -324,33 +330,34 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,struct acpi_iort_node *parent;struct acpi_iort_id_mapping *map; -if (!node->mapping_offset || !node->mapping_count || - index >= node->mapping_count) -return NULL ; - - map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node, - node->mapping_offset); +while (node) { +if (!node->mapping_offset || !node->mapping_count || + index >= node->mapping_count) +return NULL ; -/* Firmware bug! */ -if (!map->output_reference) { -pr_err (FW_BUG "[node %p type %d] ID map has NULL parent reference\n" , - node, node->type); -return NULL ; - } + map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node, + node->mapping_offset); - parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table, - map->output_reference); +/* Firmware bug! */ +if (!map->output_reference) { +pr_err (FW_BUG "[node %p type %d] ID map has NULL parent reference\n" , + node, node->type); +return NULL ; + } -if (!(IORT_TYPE_MASK (parent->type) & type_mask)) -return NULL ; + parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table, + map->output_reference); -if (map[index].flags &ACPI_IORT_ID_SINGLE_MAPPING ) { -if (node->type ==ACPI_IORT_NODE_NAMED_COMPONENT || - node->type ==ACPI_IORT_NODE_PCI_ROOT_COMPLEX ) { -if (id_out) - *id_out = map[index].output_base; -return parent; +/* go upstream to find its parent */ +if (!(IORT_TYPE_MASK (parent->type) & type_mask)) { + node = parent; +continue ; } + +if (iort_id_single_map (&map[index], node->type, id_out)) +break ; + +return parent; }return NULL ;
Signature · 1 line
1.7.12.4
Hanjun Guo
maintainerPATCH v4 11/11 msi: platform: make platform_msi_create_device_domain() ACPI aware
In reply to Hanjun GuoFrom: Hanjun Guo <[email protected]>
With the platform msi domain created for ITS, irqchip such as mbi-gen connecting ITS, which needs ctreate its own irqdomain.
Fortunately with the platform msi support upstreamed by Marc, we just need to add minor code to make it run properly.
platform_msi_create_device_domain() is almost ready for ACPI use except of_node_to_fwnode() is for dt only, make it ACPI aware then things will work in both DTS and ACPI.
--- drivers/base/platform-msi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/base/platform-msi.c +1 -2
@@ -345,8 +345,7 @@ struct irq_domain * data->host_data = host_data; domain =irq_domain_create_hierarchy (dev->msi_domain,0 , nvec, -of_node_to_fwnode (dev->of_node), - ops, data); + dev->fwnode, ops, data);if (!domain) goto free_priv;
Signature · 1 line
1.7.12.4