|
@@ -23,16 +23,18 @@
|
|
|
|
|
|
/*
|
|
|
* @int_max: maximum number of supported interrupts
|
|
|
+ * @safe_map: safe default value to initialize the crossbar
|
|
|
* @irq_map: array of interrupts to crossbar number mapping
|
|
|
* @crossbar_base: crossbar base address
|
|
|
* @register_offsets: offsets for each irq number
|
|
|
*/
|
|
|
struct crossbar_device {
|
|
|
uint int_max;
|
|
|
+ uint safe_map;
|
|
|
uint *irq_map;
|
|
|
void __iomem *crossbar_base;
|
|
|
int *register_offsets;
|
|
|
- void (*write) (int, int);
|
|
|
+ void (*write)(int, int);
|
|
|
};
|
|
|
|
|
|
static struct crossbar_device *cb;
|
|
@@ -88,8 +90,10 @@ static void crossbar_domain_unmap(struct irq_domain *d, unsigned int irq)
|
|
|
{
|
|
|
irq_hw_number_t hw = irq_get_irq_data(irq)->hwirq;
|
|
|
|
|
|
- if (hw > GIC_IRQ_START)
|
|
|
+ if (hw > GIC_IRQ_START) {
|
|
|
cb->irq_map[hw - GIC_IRQ_START] = IRQ_FREE;
|
|
|
+ cb->write(hw - GIC_IRQ_START, cb->safe_map);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static int crossbar_domain_xlate(struct irq_domain *d,
|
|
@@ -214,6 +218,17 @@ static int __init crossbar_of_init(struct device_node *node)
|
|
|
reserved += size;
|
|
|
}
|
|
|
|
|
|
+ of_property_read_u32(node, "ti,irqs-safe-map", &cb->safe_map);
|
|
|
+
|
|
|
+ /* Initialize the crossbar with safe map to start with */
|
|
|
+ for (i = 0; i < max; i++) {
|
|
|
+ if (cb->irq_map[i] == IRQ_RESERVED ||
|
|
|
+ cb->irq_map[i] == IRQ_SKIP)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ cb->write(i, cb->safe_map);
|
|
|
+ }
|
|
|
+
|
|
|
register_routable_domain_ops(&routable_irq_domain_ops);
|
|
|
return 0;
|
|
|
|