From: Makarand Pawagi <makarand.paw...@nxp.com>

ACPI support is added in the fsl-mc driver. Driver will parse
MC DSDT table to extract memory and other resorces.

Interrupt (GIC ITS) information will be extracted from MADT table
by drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c.

IORT table will be parsed to configure DMA.

Signed-off-by: Makarand Pawagi <makarand.paw...@nxp.com>
---
Previous attempt, here: https://patchwork.kernel.org/patch/11353735/

 drivers/bus/fsl-mc/fsl-mc-bus.c             | 35 ++++++-----
 drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c | 69 ++++++++++++++++++++-
 2 files changed, 87 insertions(+), 17 deletions(-)

diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
index eafaa0e0b906..c4742a9c0714 100644
--- a/drivers/bus/fsl-mc/fsl-mc-bus.c
+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
@@ -941,7 +941,7 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
        phys_addr_t mc_portal_phys_addr;
        u32 mc_portal_size;
        struct mc_version mc_version;
-       struct resource res;
+       struct resource *plat_res;
 
        /*
         * The MC firmware requires full access to the whole address space plus
@@ -967,16 +967,9 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
        /*
         * Get physical address of MC portal for the root DPRC:
         */
-       error = of_address_to_resource(pdev->dev.of_node, 0, &res);
-       if (error < 0) {
-               dev_err(&pdev->dev,
-                       "of_address_to_resource() failed for %pOF\n",
-                       pdev->dev.of_node);
-               return error;
-       }
-
-       mc_portal_phys_addr = res.start;
-       mc_portal_size = resource_size(&res);
+       plat_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       mc_portal_phys_addr = plat_res->start;
+       mc_portal_size = resource_size(plat_res);
        error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr,
                                 mc_portal_size, NULL,
                                 FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, &mc_io);
@@ -993,11 +986,13 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
        dev_info(&pdev->dev, "MC firmware version: %u.%u.%u\n",
                 mc_version.major, mc_version.minor, mc_version.revision);
 
-       error = get_mc_addr_translation_ranges(&pdev->dev,
-                                              &mc->translation_ranges,
-                                              &mc->num_translation_ranges);
-       if (error < 0)
-               goto error_cleanup_mc_io;
+       if (dev_of_node(&pdev->dev)) {
+               error = get_mc_addr_translation_ranges(&pdev->dev,
+                                               &mc->translation_ranges,
+                                               &mc->num_translation_ranges);
+               if (error < 0)
+                       goto error_cleanup_mc_io;
+       }
 
        error = dprc_get_container_id(mc_io, 0, &container_id);
        if (error < 0) {
@@ -1024,6 +1019,7 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
                goto error_cleanup_mc_io;
 
        mc->root_mc_bus_dev = mc_bus_dev;
+       mc_bus_dev->dev.fwnode = pdev->dev.fwnode;
        return 0;
 
 error_cleanup_mc_io:
@@ -1064,11 +1060,18 @@ static const struct of_device_id 
fsl_mc_bus_match_table[] = {
 
 MODULE_DEVICE_TABLE(of, fsl_mc_bus_match_table);
 
+static const struct acpi_device_id fsl_mc_bus_acpi_match_table[] = {
+       {"NXP0008", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(acpi, fsl_mc_bus_acpi_match_table);
+
 static struct platform_driver fsl_mc_bus_driver = {
        .driver = {
                   .name = "fsl_mc_bus",
                   .pm = NULL,
                   .of_match_table = fsl_mc_bus_match_table,
+                  .acpi_match_table = fsl_mc_bus_acpi_match_table,
                   },
        .probe = fsl_mc_bus_probe,
        .remove = fsl_mc_bus_remove,
diff --git a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c 
b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
index 606efa64adff..6d67834722c9 100644
--- a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
@@ -4,9 +4,11 @@
  *
  * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
  * Author: German Rivera <german.riv...@freescale.com>
+ * Copyright 2020 NXP
  *
  */
 
+#include <linux/acpi_iort.h>
 #include <linux/of_device.h>
 #include <linux/of_address.h>
 #include <linux/irq.h>
@@ -66,7 +68,65 @@ static const struct of_device_id its_device_id[] = {
        {},
 };
 
-static int __init its_fsl_mc_msi_init(void)
+static int __init its_fsl_mc_msi_init_one(struct fwnode_handle *handle,
+                                         const char *name)
+{
+       struct irq_domain *parent;
+       struct irq_domain *mc_msi_domain;
+
+       parent = irq_find_matching_fwnode(handle, DOMAIN_BUS_NEXUS);
+       if (!parent || !msi_get_domain_info(parent)) {
+               pr_err("%s: Unable to locate ITS domain\n", name);
+               return -ENXIO;
+       }
+
+       mc_msi_domain = fsl_mc_msi_create_irq_domain(handle,
+                                                    
&its_fsl_mc_msi_domain_info,
+                                                    parent);
+       if (!mc_msi_domain)
+               pr_err("ACPIF: unable to create fsl-mc domain\n");
+
+       pr_info("fsl-mc MSI: domain created\n");
+
+       return 0;
+}
+
+static int __init
+its_fsl_mc_msi_parse_madt(union acpi_subtable_headers *header,
+                         const unsigned long end)
+{
+       struct acpi_madt_generic_translator *its_entry;
+       struct fwnode_handle *dom_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);
+
+       dom_handle = iort_find_domain_token(its_entry->translation_id);
+       if (!dom_handle) {
+               pr_err("%s: Unable to locate ITS domain handle\n", node_name);
+               goto out;
+       }
+
+       err = its_fsl_mc_msi_init_one(dom_handle, node_name);
+       if (!err)
+               pr_info("fsl-mc MSI: %s domain created\n", node_name);
+
+out:
+       kfree(node_name);
+       return err;
+}
+
+static int __init its_fsl_mc_acpi_msi_init(void)
+{
+       acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
+                             its_fsl_mc_msi_parse_madt, 0);
+       return 0;
+}
+
+static int __init its_fsl_mc_of_msi_init(void)
 {
        struct device_node *np;
        struct irq_domain *parent;
@@ -100,4 +160,11 @@ static int __init its_fsl_mc_msi_init(void)
        return 0;
 }
 
+static int __init its_fsl_mc_msi_init(void)
+{
+       its_fsl_mc_of_msi_init();
+       its_fsl_mc_acpi_msi_init();
+
+       return 0;
+}
 early_initcall(its_fsl_mc_msi_init);
-- 
2.17.1

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to