diff options
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.patch | 182 |
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 + |