Commit f785f7d2 authored by Hanjun Guo's avatar Hanjun Guo Committed by Marc Zyngier

irqchip/gicv3-its: platform-msi: Scan MADT to create platform msi domain

With the introduction of its_pmsi_init_one(), support for ACPI
firmware interface can be plugged into the gicv3 ITS driver.

Add code to scan the MADT table to get the ITS entry(ies), then use
the information to create the platform msi domain for devices
connected to it, mirroring the ITS PCI MSI code path.
Signed-off-by: default avatarHanjun Guo <hanjun.guo@linaro.org>
[lorenzo.pieralisi@arm.com: rewrote commit log]
Signed-off-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Reviewed-by: default avatarMatthias Brugger <mbrugger@suse.com>
Tested-by: default avatarMing Lei <ming.lei@canonical.com>
Tested-by: default avatarWei Xu <xuwei5@hisilicon.com>
Tested-by: default avatarSinan Kaya <okaya@codeaurora.org>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent 42677db9
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <linux/acpi_iort.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/msi.h> #include <linux/msi.h>
#include <linux/of.h> #include <linux/of.h>
...@@ -103,6 +104,41 @@ static int __init its_pmsi_init_one(struct fwnode_handle *fwnode, ...@@ -103,6 +104,41 @@ static int __init its_pmsi_init_one(struct fwnode_handle *fwnode,
return 0; 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@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_pmsi_acpi_init(void)
{
acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
its_pmsi_parse_madt, 0);
}
#else
static inline void its_pmsi_acpi_init(void) { }
#endif
static void __init its_pmsi_of_init(void) static void __init its_pmsi_of_init(void)
{ {
struct device_node *np; struct device_node *np;
...@@ -119,6 +155,7 @@ static void __init its_pmsi_of_init(void) ...@@ -119,6 +155,7 @@ static void __init its_pmsi_of_init(void)
static int __init its_pmsi_init(void) static int __init its_pmsi_init(void)
{ {
its_pmsi_of_init(); its_pmsi_of_init();
its_pmsi_acpi_init();
return 0; return 0;
} }
early_initcall(its_pmsi_init); early_initcall(its_pmsi_init);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment