summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Nowicki <tn@semihalf.com>2015-09-03 14:19:36 +0200
committerTomasz Nowicki <tn@semihalf.com>2015-09-28 18:55:10 +0200
commit4751d01eec52681e284a22812bcf001547bc31f4 (patch)
tree11d001a4ac8e86e404fb056a60d19fa8e0380957
parentd0fd38a5aaacdea839ea9311b18dddbf9617cfbc (diff)
acpi, gicv3, msi: Use MADT ITS subtable to do MSI domain initialization.acpi-gicv2/3
After refactoring DT code, we let ACPI to build ITS MSI domain too. Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
-rw-r--r--drivers/irqchip/irq-gic-v3-its-pci-msi.c43
-rw-r--r--drivers/irqchip/irq-gic-v3-its-platform-msi.c43
2 files changed, 85 insertions, 1 deletions
diff --git a/drivers/irqchip/irq-gic-v3-its-pci-msi.c b/drivers/irqchip/irq-gic-v3-its-pci-msi.c
index a9bbc22629f0..8f71f341a95e 100644
--- a/drivers/irqchip/irq-gic-v3-its-pci-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-pci-msi.c
@@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/iort.h>
#include <linux/msi.h>
#include <linux/of.h>
#include <linux/of_irq.h>
@@ -59,8 +60,10 @@ static int its_pci_msi_vec_count(struct pci_dev *pdev)
static int its_get_pci_alias(struct pci_dev *pdev, u16 alias, void *data)
{
struct its_pci_alias *dev_alias = data;
+ u32 dev_id;
- dev_alias->dev_id = alias;
+ dev_alias->dev_id = iort_find_pci_id(pdev, alias, &dev_id) == 0 ?
+ dev_id : alias;
if (pdev != dev_alias->pdev)
dev_alias->count += its_pci_msi_vec_count(dev_alias->pdev);
@@ -144,4 +147,42 @@ static int __init its_pci_of_msi_init(void)
return 0;
}
+
+#ifdef CONFIG_ACPI
+
+static int __init
+its_pci_msi_parse_madt(struct acpi_subtable_header *header,
+ const unsigned long end)
+{
+ struct acpi_madt_generic_translator *its_entry =
+ (struct acpi_madt_generic_translator *)header;
+
+ if (its_pci_msi_init_one((void *)its_entry->base_address))
+ return 0;
+
+ pr_info("PCI/MSI: ITS@ID[%d] domain created\n",
+ its_entry->translation_id);
+ return 0;
+}
+
+static int __init its_pci_acpi_msi_init(void)
+{
+ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
+ its_pci_msi_parse_madt, 0);
+ return 0;
+}
+#else
+inline static int __init its_pci_acpi_msi_init(void)
+{
+ return 0;
+}
+#endif
+
+static int __init its_pci_msi_init(void)
+{
+ its_pci_of_msi_init();
+ its_pci_acpi_msi_init();
+
+ return 0;
+}
early_initcall(its_pci_msi_init);
diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index 1c737c4bfee8..4a81944762e8 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -15,7 +15,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/acpi.h>
#include <linux/device.h>
+#include <linux/iort.h>
#include <linux/msi.h>
#include <linux/of.h>
#include <linux/of_irq.h>
@@ -37,6 +39,9 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
ret = of_property_read_u32_index(dev->of_node, "msi-parent",
1, &dev_id);
if (ret)
+ ret = iort_find_dev_id(dev, &dev_id);
+
+ if (ret)
return ret;
/* ITS specific DeviceID, as the core ITS ignores dev. */
@@ -97,4 +102,42 @@ static int __init its_pmsi_of_init(void)
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 acpi_madt_generic_translator *)header;
+
+ if (its_pmsi_init_one((void *)its_entry->base_address))
+ return 0;
+
+ pr_info("Platform MSI: ITS@ID[%d] domain created\n",
+ its_entry->translation_id);
+ return 0;
+}
+
+static int __init its_pmsi_acpi_init(void)
+{
+ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
+ its_pmsi_parse_madt, 0);
+ return 0;
+}
+#else
+inline static int __init its_pmsi_acpi_init(void)
+{
+ return 0;
+}
+#endif
+
+static int __init its_pmsi_init(void)
+{
+ its_pmsi_of_init();
+ its_pmsi_acpi_init();
+
+ return 0;
+}
early_initcall(its_pmsi_init);