c10abfbf87d2914b3f144cba09042dce90a1ca41
[openwrt/staging/hauke.git] / target / linux / layerscape / patches-4.9 / 811-irqchip-support-layerscape.patch
1 From 1d596855b596db88f10b12a1be6fd19e249be170 Mon Sep 17 00:00:00 2001
2 From: Yangbo Lu <yangbo.lu@nxp.com>
3 Date: Mon, 25 Sep 2017 12:13:29 +0800
4 Subject: [PATCH] irqchip: support layerscape
5
6 This is a integrated patch for layerscape gic support.
7
8 Signed-off-by: Eric Auger <eric.auger@redhat.com>
9 Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
10 Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
11 ---
12 drivers/irqchip/Makefile | 1 +
13 drivers/irqchip/irq-gic-v3-its.c | 1 +
14 include/linux/irqdomain.h | 36 ++++++++++++++++++++++++++++++++++++
15 kernel/irq/irqdomain.c | 39 +++++++++++++++++++++++++++++++++++++++
16 kernel/irq/msi.c | 4 ++--
17 5 files changed, 79 insertions(+), 2 deletions(-)
18
19 diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
20 index e4dbfc85..53d2cd54 100644
21 --- a/drivers/irqchip/Makefile
22 +++ b/drivers/irqchip/Makefile
23 @@ -74,3 +74,4 @@ obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o
24 obj-$(CONFIG_EZNPS_GIC) += irq-eznps.o
25 obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o
26 obj-$(CONFIG_STM32_EXTI) += irq-stm32-exti.o
27 +obj-$(CONFIG_QUICC_ENGINE) += irq-qeic.o
28 diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
29 index acb9d250..2f1c8826 100644
30 --- a/drivers/irqchip/irq-gic-v3-its.c
31 +++ b/drivers/irqchip/irq-gic-v3-its.c
32 @@ -1659,6 +1659,7 @@ static int its_init_domain(struct fwnode_handle *handle, struct its_node *its)
33
34 inner_domain->parent = its_parent;
35 inner_domain->bus_token = DOMAIN_BUS_NEXUS;
36 + inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_REMAP;
37 info->ops = &its_msi_domain_ops;
38 info->data = its;
39 inner_domain->host_data = info;
40 diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
41 index ffb84604..188eced6 100644
42 --- a/include/linux/irqdomain.h
43 +++ b/include/linux/irqdomain.h
44 @@ -183,6 +183,12 @@ enum {
45 /* Irq domain is an IPI domain with single virq */
46 IRQ_DOMAIN_FLAG_IPI_SINGLE = (1 << 3),
47
48 + /* Irq domain implements MSIs */
49 + IRQ_DOMAIN_FLAG_MSI = (1 << 4),
50 +
51 + /* Irq domain implements MSI remapping */
52 + IRQ_DOMAIN_FLAG_MSI_REMAP = (1 << 5),
53 +
54 /*
55 * Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
56 * for implementation specific purposes and ignored by the
57 @@ -216,6 +222,7 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
58 void *host_data);
59 extern struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
60 enum irq_domain_bus_token bus_token);
61 +extern bool irq_domain_check_msi_remap(void);
62 extern void irq_set_default_host(struct irq_domain *host);
63 extern int irq_domain_alloc_descs(int virq, unsigned int nr_irqs,
64 irq_hw_number_t hwirq, int node,
65 @@ -446,6 +453,19 @@ static inline bool irq_domain_is_ipi_single(struct irq_domain *domain)
66 {
67 return domain->flags & IRQ_DOMAIN_FLAG_IPI_SINGLE;
68 }
69 +
70 +static inline bool irq_domain_is_msi(struct irq_domain *domain)
71 +{
72 + return domain->flags & IRQ_DOMAIN_FLAG_MSI;
73 +}
74 +
75 +static inline bool irq_domain_is_msi_remap(struct irq_domain *domain)
76 +{
77 + return domain->flags & IRQ_DOMAIN_FLAG_MSI_REMAP;
78 +}
79 +
80 +extern bool irq_domain_hierarchical_is_msi_remap(struct irq_domain *domain);
81 +
82 #else /* CONFIG_IRQ_DOMAIN_HIERARCHY */
83 static inline void irq_domain_activate_irq(struct irq_data *data) { }
84 static inline void irq_domain_deactivate_irq(struct irq_data *data) { }
85 @@ -477,6 +497,22 @@ static inline bool irq_domain_is_ipi_single(struct irq_domain *domain)
86 {
87 return false;
88 }
89 +
90 +static inline bool irq_domain_is_msi(struct irq_domain *domain)
91 +{
92 + return false;
93 +}
94 +
95 +static inline bool irq_domain_is_msi_remap(struct irq_domain *domain)
96 +{
97 + return false;
98 +}
99 +
100 +static inline bool
101 +irq_domain_hierarchical_is_msi_remap(struct irq_domain *domain)
102 +{
103 + return false;
104 +}
105 #endif /* CONFIG_IRQ_DOMAIN_HIERARCHY */
106
107 #else /* CONFIG_IRQ_DOMAIN */
108 diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
109 index b59e6768..31805f23 100644
110 --- a/kernel/irq/irqdomain.c
111 +++ b/kernel/irq/irqdomain.c
112 @@ -277,6 +277,31 @@ struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
113 }
114 EXPORT_SYMBOL_GPL(irq_find_matching_fwspec);
115
116 +/**
117 + * irq_domain_check_msi_remap - Check whether all MSI irq domains implement
118 + * IRQ remapping
119 + *
120 + * Return: false if any MSI irq domain does not support IRQ remapping,
121 + * true otherwise (including if there is no MSI irq domain)
122 + */
123 +bool irq_domain_check_msi_remap(void)
124 +{
125 + struct irq_domain *h;
126 + bool ret = true;
127 +
128 + mutex_lock(&irq_domain_mutex);
129 + list_for_each_entry(h, &irq_domain_list, link) {
130 + if (irq_domain_is_msi(h) &&
131 + !irq_domain_hierarchical_is_msi_remap(h)) {
132 + ret = false;
133 + break;
134 + }
135 + }
136 + mutex_unlock(&irq_domain_mutex);
137 + return ret;
138 +}
139 +EXPORT_SYMBOL_GPL(irq_domain_check_msi_remap);
140 +
141 /**
142 * irq_set_default_host() - Set a "default" irq domain
143 * @domain: default domain pointer
144 @@ -1408,6 +1433,20 @@ static void irq_domain_check_hierarchy(struct irq_domain *domain)
145 if (domain->ops->alloc)
146 domain->flags |= IRQ_DOMAIN_FLAG_HIERARCHY;
147 }
148 +
149 +/**
150 + * irq_domain_hierarchical_is_msi_remap - Check if the domain or any
151 + * parent has MSI remapping support
152 + * @domain: domain pointer
153 + */
154 +bool irq_domain_hierarchical_is_msi_remap(struct irq_domain *domain)
155 +{
156 + for (; domain; domain = domain->parent) {
157 + if (irq_domain_is_msi_remap(domain))
158 + return true;
159 + }
160 + return false;
161 +}
162 #else /* CONFIG_IRQ_DOMAIN_HIERARCHY */
163 /**
164 * irq_domain_get_irq_data - Get irq_data associated with @virq and @domain
165 diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c
166 index 8a3e8727..2e2b2c45 100644
167 --- a/kernel/irq/msi.c
168 +++ b/kernel/irq/msi.c
169 @@ -272,8 +272,8 @@ struct irq_domain *msi_create_irq_domain(struct fwnode_handle *fwnode,
170 if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
171 msi_domain_update_chip_ops(info);
172
173 - return irq_domain_create_hierarchy(parent, 0, 0, fwnode,
174 - &msi_domain_ops, info);
175 + return irq_domain_create_hierarchy(parent, IRQ_DOMAIN_FLAG_MSI, 0,
176 + fwnode, &msi_domain_ops, info);
177 }
178
179 int msi_domain_prepare_irqs(struct irq_domain *domain, struct device *dev,
180 --
181 2.14.1
182