aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-4.9/811-irqchip-support-layerscape.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-4.9/811-irqchip-support-layerscape.patch')
-rw-r--r--target/linux/layerscape/patches-4.9/811-irqchip-support-layerscape.patch182
1 files changed, 182 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-4.9/811-irqchip-support-layerscape.patch b/target/linux/layerscape/patches-4.9/811-irqchip-support-layerscape.patch
new file mode 100644
index 0000000000..c10abfbf87
--- /dev/null
+++ b/target/linux/layerscape/patches-4.9/811-irqchip-support-layerscape.patch
@@ -0,0 +1,182 @@
+From 1d596855b596db88f10b12a1be6fd19e249be170 Mon Sep 17 00:00:00 2001
+From: Yangbo Lu <yangbo.lu@nxp.com>
+Date: Mon, 25 Sep 2017 12:13:29 +0800
+Subject: [PATCH] irqchip: support layerscape
+
+This is a integrated patch for layerscape gic support.
+
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
+Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+---
+ drivers/irqchip/Makefile | 1 +
+ drivers/irqchip/irq-gic-v3-its.c | 1 +
+ include/linux/irqdomain.h | 36 ++++++++++++++++++++++++++++++++++++
+ kernel/irq/irqdomain.c | 39 +++++++++++++++++++++++++++++++++++++++
+ kernel/irq/msi.c | 4 ++--
+ 5 files changed, 79 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
+index e4dbfc85..53d2cd54 100644
+--- a/drivers/irqchip/Makefile
++++ b/drivers/irqchip/Makefile
+@@ -74,3 +74,4 @@ obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o
+ obj-$(CONFIG_EZNPS_GIC) += irq-eznps.o
+ obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o
+ obj-$(CONFIG_STM32_EXTI) += irq-stm32-exti.o
++obj-$(CONFIG_QUICC_ENGINE) += irq-qeic.o
+diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
+index acb9d250..2f1c8826 100644
+--- a/drivers/irqchip/irq-gic-v3-its.c
++++ b/drivers/irqchip/irq-gic-v3-its.c
+@@ -1659,6 +1659,7 @@ static int its_init_domain(struct fwnode_handle *handle, struct its_node *its)
+
+ inner_domain->parent = its_parent;
+ inner_domain->bus_token = DOMAIN_BUS_NEXUS;
++ inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_REMAP;
+ info->ops = &its_msi_domain_ops;
+ info->data = its;
+ inner_domain->host_data = info;
+diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
+index ffb84604..188eced6 100644
+--- a/include/linux/irqdomain.h
++++ b/include/linux/irqdomain.h
+@@ -183,6 +183,12 @@ enum {
+ /* Irq domain is an IPI domain with single virq */
+ IRQ_DOMAIN_FLAG_IPI_SINGLE = (1 << 3),
+
++ /* Irq domain implements MSIs */
++ IRQ_DOMAIN_FLAG_MSI = (1 << 4),
++
++ /* Irq domain implements MSI remapping */
++ IRQ_DOMAIN_FLAG_MSI_REMAP = (1 << 5),
++
+ /*
+ * Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
+ * for implementation specific purposes and ignored by the
+@@ -216,6 +222,7 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
+ void *host_data);
+ extern struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
+ enum irq_domain_bus_token bus_token);
++extern bool irq_domain_check_msi_remap(void);
+ extern void irq_set_default_host(struct irq_domain *host);
+ extern int irq_domain_alloc_descs(int virq, unsigned int nr_irqs,
+ irq_hw_number_t hwirq, int node,
+@@ -446,6 +453,19 @@ static inline bool irq_domain_is_ipi_single(struct irq_domain *domain)
+ {
+ return domain->flags & IRQ_DOMAIN_FLAG_IPI_SINGLE;
+ }
++
++static inline bool irq_domain_is_msi(struct irq_domain *domain)
++{
++ return domain->flags & IRQ_DOMAIN_FLAG_MSI;
++}
++
++static inline bool irq_domain_is_msi_remap(struct irq_domain *domain)
++{
++ return domain->flags & IRQ_DOMAIN_FLAG_MSI_REMAP;
++}
++
++extern bool irq_domain_hierarchical_is_msi_remap(struct irq_domain *domain);
++
+ #else /* CONFIG_IRQ_DOMAIN_HIERARCHY */
+ static inline void irq_domain_activate_irq(struct irq_data *data) { }
+ static inline void irq_domain_deactivate_irq(struct irq_data *data) { }
+@@ -477,6 +497,22 @@ static inline bool irq_domain_is_ipi_single(struct irq_domain *domain)
+ {
+ return false;
+ }
++
++static inline bool irq_domain_is_msi(struct irq_domain *domain)
++{
++ return false;
++}
++
++static inline bool irq_domain_is_msi_remap(struct irq_domain *domain)
++{
++ return false;
++}
++
++static inline bool
++irq_domain_hierarchical_is_msi_remap(struct irq_domain *domain)
++{
++ return false;
++}
+ #endif /* CONFIG_IRQ_DOMAIN_HIERARCHY */
+
+ #else /* CONFIG_IRQ_DOMAIN */
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index b59e6768..31805f23 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -277,6 +277,31 @@ struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
+ }
+ EXPORT_SYMBOL_GPL(irq_find_matching_fwspec);
+
++/**
++ * irq_domain_check_msi_remap - Check whether all MSI irq domains implement
++ * IRQ remapping
++ *
++ * Return: false if any MSI irq domain does not support IRQ remapping,
++ * true otherwise (including if there is no MSI irq domain)
++ */
++bool irq_domain_check_msi_remap(void)
++{
++ struct irq_domain *h;
++ bool ret = true;
++
++ mutex_lock(&irq_domain_mutex);
++ list_for_each_entry(h, &irq_domain_list, link) {
++ if (irq_domain_is_msi(h) &&
++ !irq_domain_hierarchical_is_msi_remap(h)) {
++ ret = false;
++ break;
++ }
++ }
++ mutex_unlock(&irq_domain_mutex);
++ return ret;
++}
++EXPORT_SYMBOL_GPL(irq_domain_check_msi_remap);
++
+ /**
+ * irq_set_default_host() - Set a "default" irq domain
+ * @domain: default domain pointer
+@@ -1408,6 +1433,20 @@ static void irq_domain_check_hierarchy(struct irq_domain *domain)
+ if (domain->ops->alloc)
+ domain->flags |= IRQ_DOMAIN_FLAG_HIERARCHY;
+ }
++
++/**
++ * irq_domain_hierarchical_is_msi_remap - Check if the domain or any
++ * parent has MSI remapping support
++ * @domain: domain pointer
++ */
++bool irq_domain_hierarchical_is_msi_remap(struct irq_domain *domain)
++{
++ for (; domain; domain = domain->parent) {
++ if (irq_domain_is_msi_remap(domain))
++ return true;
++ }
++ return false;
++}
+ #else /* CONFIG_IRQ_DOMAIN_HIERARCHY */
+ /**
+ * irq_domain_get_irq_data - Get irq_data associated with @virq and @domain
+diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c
+index 8a3e8727..2e2b2c45 100644
+--- a/kernel/irq/msi.c
++++ b/kernel/irq/msi.c
+@@ -272,8 +272,8 @@ struct irq_domain *msi_create_irq_domain(struct fwnode_handle *fwnode,
+ if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
+ msi_domain_update_chip_ops(info);
+
+- return irq_domain_create_hierarchy(parent, 0, 0, fwnode,
+- &msi_domain_ops, info);
++ return irq_domain_create_hierarchy(parent, IRQ_DOMAIN_FLAG_MSI, 0,
++ fwnode, &msi_domain_ops, info);
+ }
+
+ int msi_domain_prepare_irqs(struct irq_domain *domain, struct device *dev,
+--
+2.14.1
+