diff options
author | Tomasz Nowicki <tn@semihalf.com> | 2015-09-03 14:19:36 +0200 |
---|---|---|
committer | Tomasz Nowicki <tn@semihalf.com> | 2015-09-28 18:55:10 +0200 |
commit | 4751d01eec52681e284a22812bcf001547bc31f4 (patch) | |
tree | 11d001a4ac8e86e404fb056a60d19fa8e0380957 | |
parent | d0fd38a5aaacdea839ea9311b18dddbf9617cfbc (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.c | 43 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v3-its-platform-msi.c | 43 |
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); |