diff options
Diffstat (limited to 'recipes-kernel/linux/linux-hierofalcon/412-5-styx-linux-tracking.git-2a80b31ff435cd274a61d685a4861bf0da461c90.patch')
-rw-r--r-- | recipes-kernel/linux/linux-hierofalcon/412-5-styx-linux-tracking.git-2a80b31ff435cd274a61d685a4861bf0da461c90.patch | 384 |
1 files changed, 384 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-hierofalcon/412-5-styx-linux-tracking.git-2a80b31ff435cd274a61d685a4861bf0da461c90.patch b/recipes-kernel/linux/linux-hierofalcon/412-5-styx-linux-tracking.git-2a80b31ff435cd274a61d685a4861bf0da461c90.patch new file mode 100644 index 0000000..9d9af0e --- /dev/null +++ b/recipes-kernel/linux/linux-hierofalcon/412-5-styx-linux-tracking.git-2a80b31ff435cd274a61d685a4861bf0da461c90.patch | |||
@@ -0,0 +1,384 @@ | |||
1 | From 4343fa95a5f0e2e9c32faecc05e4aa1e12e27f72 Mon Sep 17 00:00:00 2001 | ||
2 | From: Adrian Calianu <adrian.calianu@enea.com> | ||
3 | Date: Tue, 11 Aug 2015 13:21:33 +0200 | ||
4 | Subject: [PATCH] [PATCH] DO NOT UPSTREAM YET: Clean up GIC irq domain for ACPI | ||
5 | |||
6 | From: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com> | ||
7 | Date: Tue, 20 Jan 2015 20:02:28 -0600 | ||
8 | |||
9 | Instead of using the irq_default_domain, define the acpi_irq_domain. | ||
10 | This still have the same assumption that ACPI only support a single | ||
11 | GIC domain. | ||
12 | |||
13 | Also, rename acpi_gic_init() to acpi_irq_init() | ||
14 | |||
15 | Signed-off-by: Adrian Calianu <adrian.calianu@enea.com> | ||
16 | --- | ||
17 | arch/arm64/kernel/acpi.c | 14 ++++-- | ||
18 | drivers/acpi/gsi.c | 31 ++++++++++---- | ||
19 | drivers/irqchip/irq-gic.c | 83 ++++++++++++++++++++++++++++++------ | ||
20 | drivers/irqchip/irqchip.c | 2 +- | ||
21 | drivers/pci/pci-acpi.c | 25 +++++++++++ | ||
22 | include/linux/irqchip/arm-gic-acpi.h | 6 ++- | ||
23 | include/linux/irqchip/arm-gic.h | 17 ++++++++ | ||
24 | 7 files changed, 151 insertions(+), 27 deletions(-) | ||
25 | |||
26 | diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c | ||
27 | index 8b83955..ea80ce2 100644 | ||
28 | --- a/arch/arm64/kernel/acpi.c | ||
29 | +++ b/arch/arm64/kernel/acpi.c | ||
30 | @@ -319,7 +319,7 @@ void __init acpi_boot_table_init(void) | ||
31 | } | ||
32 | } | ||
33 | |||
34 | -void __init acpi_gic_init(void) | ||
35 | +void __init acpi_irq_init(void) | ||
36 | { | ||
37 | struct acpi_table_header *table; | ||
38 | acpi_status status; | ||
39 | @@ -329,6 +329,14 @@ void __init acpi_gic_init(void) | ||
40 | if (acpi_disabled) | ||
41 | return; | ||
42 | |||
43 | + /** | ||
44 | + * NOTE: We need to declare this before we initialize the GIC | ||
45 | + * so that we can use pointers to MADT table and MSI_FRAME sub-table | ||
46 | + * for reference. | ||
47 | + */ | ||
48 | + acpi_gbl_permanent_mmap = 1; | ||
49 | + | ||
50 | + | ||
51 | status = acpi_get_table_with_size(ACPI_SIG_MADT, 0, &table, &tbl_size); | ||
52 | if (ACPI_FAILURE(status)) { | ||
53 | const char *msg = acpi_format_exception(status); | ||
54 | @@ -337,8 +345,8 @@ void __init acpi_gic_init(void) | ||
55 | return; | ||
56 | } | ||
57 | |||
58 | - err = gic_v2_acpi_init(table); | ||
59 | - if (err) | ||
60 | + err = gic_v2_acpi_init(table, &acpi_irq_domain); | ||
61 | + if (err || !acpi_irq_domain) | ||
62 | pr_err("Failed to initialize GIC IRQ controller"); | ||
63 | |||
64 | early_acpi_os_unmap_memory((char *)table, tbl_size); | ||
65 | diff --git a/drivers/acpi/gsi.c b/drivers/acpi/gsi.c | ||
66 | index 38208f2..7f1b8a0 100644 | ||
67 | --- a/drivers/acpi/gsi.c | ||
68 | +++ b/drivers/acpi/gsi.c | ||
69 | @@ -11,6 +11,7 @@ | ||
70 | #include <linux/acpi.h> | ||
71 | #include <linux/irq.h> | ||
72 | #include <linux/irqdomain.h> | ||
73 | +#include <linux/of.h> | ||
74 | |||
75 | enum acpi_irq_model_id acpi_irq_model; | ||
76 | |||
77 | @@ -43,6 +44,8 @@ static unsigned int acpi_gsi_get_irq_type(int trigger, int polarity) | ||
78 | * Returns: linux IRQ number on success (>0) | ||
79 | * -EINVAL on failure | ||
80 | */ | ||
81 | +static struct irq_domain *acpi_irq_domain; | ||
82 | + | ||
83 | int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) | ||
84 | { | ||
85 | /* | ||
86 | @@ -50,7 +53,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) | ||
87 | * the mapping corresponding to default domain by passing NULL | ||
88 | * as irq_domain parameter | ||
89 | */ | ||
90 | - *irq = irq_find_mapping(NULL, gsi); | ||
91 | + *irq = irq_find_mapping(acpi_irq_domain, gsi); | ||
92 | /* | ||
93 | * *irq == 0 means no mapping, that should | ||
94 | * be reported as a failure | ||
95 | @@ -74,20 +77,32 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, | ||
96 | { | ||
97 | unsigned int irq; | ||
98 | unsigned int irq_type = acpi_gsi_get_irq_type(trigger, polarity); | ||
99 | + struct gic_irq_alloc_info info; | ||
100 | + struct irq_data *d; | ||
101 | |||
102 | /* | ||
103 | * There is no way at present to look-up the IRQ domain on ACPI, | ||
104 | * hence always create mapping referring to the default domain | ||
105 | * by passing NULL as irq_domain parameter | ||
106 | */ | ||
107 | - irq = irq_create_mapping(NULL, gsi); | ||
108 | - if (!irq) | ||
109 | - return -EINVAL; | ||
110 | + if (!acpi_irq_domain) | ||
111 | + BUG(); | ||
112 | + | ||
113 | + if (gic_init_irq_alloc_info(GIC_INT_TYPE_NONE, | ||
114 | + gsi, irq_type, NULL, &info) < 0) | ||
115 | + return -EINVAL; | ||
116 | + | ||
117 | + irq = __irq_domain_alloc_irqs(acpi_irq_domain, -1, 1, | ||
118 | + dev_to_node(dev), &info, false); | ||
119 | + if (irq < 0) | ||
120 | + return -ENOSPC; | ||
121 | + | ||
122 | + d = irq_domain_get_irq_data(acpi_irq_domain, irq); | ||
123 | + if (!d) | ||
124 | + return -EFAULT; | ||
125 | + | ||
126 | + d->chip->irq_set_type(d, irq_type); | ||
127 | |||
128 | - /* Set irq type if specified and different than the current one */ | ||
129 | - if (irq_type != IRQ_TYPE_NONE && | ||
130 | - irq_type != irq_get_trigger_type(irq)) | ||
131 | - irq_set_irq_type(irq, irq_type); | ||
132 | return irq; | ||
133 | } | ||
134 | EXPORT_SYMBOL_GPL(acpi_register_gsi); | ||
135 | diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c | ||
136 | index 01999d7..997d073 100644 | ||
137 | --- a/drivers/irqchip/irq-gic.c | ||
138 | +++ b/drivers/irqchip/irq-gic.c | ||
139 | @@ -854,10 +854,13 @@ static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, | ||
140 | int i, ret; | ||
141 | irq_hw_number_t hwirq; | ||
142 | unsigned int type = IRQ_TYPE_NONE; | ||
143 | - struct of_phandle_args *irq_data = arg; | ||
144 | + struct gic_irq_alloc_info *info = arg; | ||
145 | + u32 intspec[3]; | ||
146 | |||
147 | - ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args, | ||
148 | - irq_data->args_count, &hwirq, &type); | ||
149 | + intspec[0] = info->gic_int_type; | ||
150 | + intspec[1] = info->hwirq; | ||
151 | + intspec[2] = info->irq_type; | ||
152 | + ret = gic_irq_domain_xlate(domain, info->ref, intspec, 3, &hwirq, &type); | ||
153 | if (ret) | ||
154 | return ret; | ||
155 | |||
156 | @@ -867,6 +870,51 @@ static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | +int gic_init_irq_alloc_info(unsigned int gic_int_type, unsigned int irq, | ||
161 | + unsigned int irq_type, void *ref, | ||
162 | + struct gic_irq_alloc_info *info) | ||
163 | +{ | ||
164 | + if (!info) | ||
165 | + return -EINVAL; | ||
166 | + | ||
167 | + if ((irq_type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_LEVEL_HIGH && | ||
168 | + (irq_type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_EDGE_RISING) | ||
169 | + return -EINVAL; | ||
170 | + | ||
171 | + info->ref = ref; | ||
172 | + info->irq_type = irq_type; | ||
173 | + | ||
174 | + /* | ||
175 | + * ACPI have no bindings to indicate SPI or PPI, so we | ||
176 | + * use different mappings from DT in ACPI. | ||
177 | + * | ||
178 | + * For FDT | ||
179 | + * PPI interrupt: in the range [0, 15]; | ||
180 | + * SPI interrupt: in the range [0, 987]; | ||
181 | + * | ||
182 | + * For ACPI, GSI should be unique so using | ||
183 | + * the hwirq directly for the mapping: | ||
184 | + * PPI interrupt: in the range [16, 31]; | ||
185 | + * SPI interrupt: in the range [32, 1019]; | ||
186 | + */ | ||
187 | + | ||
188 | + if (gic_int_type != ~0U) { | ||
189 | + info->gic_int_type = gic_int_type; | ||
190 | + info->hwirq = irq; | ||
191 | + | ||
192 | + } else { | ||
193 | + if (irq < 32) { | ||
194 | + info->gic_int_type = GIC_INT_TYPE_PPI; | ||
195 | + info->hwirq = irq - 16; | ||
196 | + } else { | ||
197 | + info->gic_int_type = GIC_INT_TYPE_SPI; | ||
198 | + info->hwirq = irq - 32; | ||
199 | + } | ||
200 | + } | ||
201 | + | ||
202 | + return 0; | ||
203 | +} | ||
204 | + | ||
205 | static const struct irq_domain_ops gic_irq_domain_hierarchy_ops = { | ||
206 | .xlate = gic_irq_domain_xlate, | ||
207 | .alloc = gic_irq_domain_alloc, | ||
208 | @@ -945,7 +993,10 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, | ||
209 | gic_irqs = 1020; | ||
210 | gic->gic_irqs = gic_irqs; | ||
211 | |||
212 | - if (node) { /* DT case */ | ||
213 | + if (!acpi_disabled) { /* ACPI case */ | ||
214 | + gic->domain = irq_domain_add_linear(node, gic_irqs, | ||
215 | + &gic_irq_domain_hierarchy_ops, gic); | ||
216 | + } else if (node) { /* DT case */ | ||
217 | gic->domain = irq_domain_add_linear(node, gic_irqs, | ||
218 | &gic_irq_domain_hierarchy_ops, | ||
219 | gic); | ||
220 | @@ -992,9 +1043,9 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, | ||
221 | gic_pm_init(gic); | ||
222 | } | ||
223 | |||
224 | -#ifdef CONFIG_OF | ||
225 | static int gic_cnt __initdata; | ||
226 | |||
227 | +#ifdef CONFIG_OF | ||
228 | static int __init | ||
229 | gic_of_init(struct device_node *node, struct device_node *parent) | ||
230 | { | ||
231 | @@ -1086,7 +1137,7 @@ gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header, | ||
232 | } | ||
233 | |||
234 | int __init | ||
235 | -gic_v2_acpi_init(struct acpi_table_header *table) | ||
236 | +gic_v2_acpi_init(struct acpi_table_header *table, struct irq_domain **domain) | ||
237 | { | ||
238 | void __iomem *cpu_base, *dist_base; | ||
239 | int count; | ||
240 | @@ -1130,13 +1181,19 @@ gic_v2_acpi_init(struct acpi_table_header *table) | ||
241 | return -ENOMEM; | ||
242 | } | ||
243 | |||
244 | - /* | ||
245 | - * Initialize zero GIC instance (no multi-GIC support). Also, set GIC | ||
246 | - * as default IRQ domain to allow for GSI registration and GSI to IRQ | ||
247 | - * number translation (see acpi_register_gsi() and acpi_gsi_to_irq()). | ||
248 | - */ | ||
249 | - gic_init_bases(0, -1, dist_base, cpu_base, 0, NULL); | ||
250 | - irq_set_default_host(gic_data[0].domain); | ||
251 | + gic_init_bases(gic_cnt, -1, dist_base, cpu_base, 0, NULL); | ||
252 | + *domain = gic_data[gic_cnt].domain; | ||
253 | + | ||
254 | + if (!*domain) { | ||
255 | + pr_err("Unable to create domain\n"); | ||
256 | + return -EFAULT; | ||
257 | + } | ||
258 | + | ||
259 | + if (IS_ENABLED(CONFIG_ARM_GIC_V2M)) { | ||
260 | + gicv2m_acpi_init(table, gic_data[gic_cnt].domain); | ||
261 | + } | ||
262 | + | ||
263 | + gic_cnt++; | ||
264 | |||
265 | acpi_irq_model = ACPI_IRQ_MODEL_GIC; | ||
266 | return 0; | ||
267 | diff --git a/drivers/irqchip/irqchip.c b/drivers/irqchip/irqchip.c | ||
268 | index afd1af3..0d3a8b1 100644 | ||
269 | --- a/drivers/irqchip/irqchip.c | ||
270 | +++ b/drivers/irqchip/irqchip.c | ||
271 | @@ -28,5 +28,5 @@ void __init irqchip_init(void) | ||
272 | { | ||
273 | of_irq_init(__irqchip_of_table); | ||
274 | |||
275 | - acpi_irq_init(); | ||
276 | + acpi_irq_init(); | ||
277 | } | ||
278 | diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c | ||
279 | index 6f6f175..fe42097 100644 | ||
280 | --- a/drivers/pci/pci-acpi.c | ||
281 | +++ b/drivers/pci/pci-acpi.c | ||
282 | @@ -12,6 +12,7 @@ | ||
283 | #include <linux/pci.h> | ||
284 | #include <linux/pci_hotplug.h> | ||
285 | #include <linux/module.h> | ||
286 | +#include <linux/msi.h> | ||
287 | #include <linux/pci-aspm.h> | ||
288 | #include <linux/pci-acpi.h> | ||
289 | #include <linux/pm_runtime.h> | ||
290 | @@ -714,3 +715,27 @@ static int __init acpi_pci_init(void) | ||
291 | return 0; | ||
292 | } | ||
293 | arch_initcall(acpi_pci_init); | ||
294 | + | ||
295 | +#ifdef CONFIG_PCI_MSI | ||
296 | +void pci_acpi_set_phb_msi_domain(struct pci_bus *bus) { | ||
297 | +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN | ||
298 | + u32 msi_frame_id = 0; | ||
299 | + int num; | ||
300 | + | ||
301 | + if (acpi_disabled) | ||
302 | + return; | ||
303 | + | ||
304 | + /** | ||
305 | + * Since ACPI 5.1 currently does not define | ||
306 | + * a way to associate MSI frame ID to a device, | ||
307 | + * we can only support single MSI frame at the moment. | ||
308 | + * Therefore, the id 0 is used as a default. | ||
309 | + */ | ||
310 | + num = msi_get_num_irq_domain(); | ||
311 | + if (num <= 0 || num > 1) | ||
312 | + return; | ||
313 | + | ||
314 | + dev_set_msi_domain(&bus->dev, irq_find_acpi_msi_domain(msi_frame_id)); | ||
315 | +#endif | ||
316 | +} | ||
317 | +#endif /* CONFIG_PCI_MSI */ | ||
318 | diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h | ||
319 | index de3419e..fa8033b 100644 | ||
320 | --- a/include/linux/irqchip/arm-gic-acpi.h | ||
321 | +++ b/include/linux/irqchip/arm-gic-acpi.h | ||
322 | @@ -10,6 +10,8 @@ | ||
323 | #ifndef ARM_GIC_ACPI_H_ | ||
324 | #define ARM_GIC_ACPI_H_ | ||
325 | |||
326 | +#include <linux/irqchip/arm-gic.h> | ||
327 | + | ||
328 | #ifdef CONFIG_ACPI | ||
329 | |||
330 | /* | ||
331 | @@ -22,8 +24,8 @@ | ||
332 | |||
333 | struct acpi_table_header; | ||
334 | |||
335 | -int gic_v2_acpi_init(struct acpi_table_header *table); | ||
336 | -void acpi_gic_init(void); | ||
337 | +void acpi_irq_init(void); | ||
338 | +int gic_v2_acpi_init(struct acpi_table_header *table, struct irq_domain **domain); | ||
339 | #else | ||
340 | static inline void acpi_gic_init(void) { } | ||
341 | #endif | ||
342 | diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h | ||
343 | index 9de976b..f490f26 100644 | ||
344 | --- a/include/linux/irqchip/arm-gic.h | ||
345 | +++ b/include/linux/irqchip/arm-gic.h | ||
346 | @@ -89,12 +89,25 @@ | ||
347 | #define GICH_MISR_EOI (1 << 0) | ||
348 | #define GICH_MISR_U (1 << 1) | ||
349 | |||
350 | +#define GIC_INT_TYPE_SPI 0 | ||
351 | +#define GIC_INT_TYPE_PPI 1 | ||
352 | +#define GIC_INT_TYPE_NONE ~0U | ||
353 | + | ||
354 | #ifndef __ASSEMBLY__ | ||
355 | |||
356 | #include <linux/irqdomain.h> | ||
357 | |||
358 | struct device_node; | ||
359 | |||
360 | +struct gic_irq_alloc_info { | ||
361 | + | ||
362 | + enum irq_domain_ref_type ref_type; | ||
363 | + void *ref; | ||
364 | + unsigned int irq_type; | ||
365 | + unsigned int gic_int_type; | ||
366 | + unsigned int hwirq; | ||
367 | +}; | ||
368 | + | ||
369 | void gic_set_irqchip_flags(unsigned long flags); | ||
370 | void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, | ||
371 | u32 offset, struct device_node *); | ||
372 | @@ -114,5 +127,9 @@ int gic_get_cpu_id(unsigned int cpu); | ||
373 | void gic_migrate_target(unsigned int new_cpu_id); | ||
374 | unsigned long gic_get_sgir_physaddr(void); | ||
375 | |||
376 | +extern int gic_init_irq_alloc_info(unsigned int gic_int_type, unsigned int irq, | ||
377 | + unsigned int irq_type, void *ref, | ||
378 | + struct gic_irq_alloc_info *info); | ||
379 | + | ||
380 | #endif /* __ASSEMBLY */ | ||
381 | #endif | ||
382 | -- | ||
383 | 1.9.1 | ||
384 | |||