|
23 | 23 |
|
24 | 24 | /*
|
25 | 25 | * @int_max: maximum number of supported interrupts
|
| 26 | + * @safe_map: safe default value to initialize the crossbar |
26 | 27 | * @irq_map: array of interrupts to crossbar number mapping
|
27 | 28 | * @crossbar_base: crossbar base address
|
28 | 29 | * @register_offsets: offsets for each irq number
|
29 | 30 | */
|
30 | 31 | struct crossbar_device {
|
31 | 32 | uint int_max;
|
| 33 | + uint safe_map; |
32 | 34 | uint *irq_map;
|
33 | 35 | void __iomem *crossbar_base;
|
34 | 36 | int *register_offsets;
|
35 |
| - void (*write) (int, int); |
| 37 | + void (*write)(int, int); |
36 | 38 | };
|
37 | 39 |
|
38 | 40 | static struct crossbar_device *cb;
|
@@ -88,8 +90,10 @@ static void crossbar_domain_unmap(struct irq_domain *d, unsigned int irq)
|
88 | 90 | {
|
89 | 91 | irq_hw_number_t hw = irq_get_irq_data(irq)->hwirq;
|
90 | 92 |
|
91 |
| - if (hw > GIC_IRQ_START) |
| 93 | + if (hw > GIC_IRQ_START) { |
92 | 94 | cb->irq_map[hw - GIC_IRQ_START] = IRQ_FREE;
|
| 95 | + cb->write(hw - GIC_IRQ_START, cb->safe_map); |
| 96 | + } |
93 | 97 | }
|
94 | 98 |
|
95 | 99 | static int crossbar_domain_xlate(struct irq_domain *d,
|
@@ -214,6 +218,17 @@ static int __init crossbar_of_init(struct device_node *node)
|
214 | 218 | reserved += size;
|
215 | 219 | }
|
216 | 220 |
|
| 221 | + of_property_read_u32(node, "ti,irqs-safe-map", &cb->safe_map); |
| 222 | + |
| 223 | + /* Initialize the crossbar with safe map to start with */ |
| 224 | + for (i = 0; i < max; i++) { |
| 225 | + if (cb->irq_map[i] == IRQ_RESERVED || |
| 226 | + cb->irq_map[i] == IRQ_SKIP) |
| 227 | + continue; |
| 228 | + |
| 229 | + cb->write(i, cb->safe_map); |
| 230 | + } |
| 231 | + |
217 | 232 | register_routable_domain_ops(&routable_irq_domain_ops);
|
218 | 233 | return 0;
|
219 | 234 |
|
|
0 commit comments