SOC-specific hard-wiring of those irqs which unexpectedly bypasses the
crossbar. These irqs have a crossbar register, but still cannot be used.
+- ti,irqs-safe-map: integer which maps to a safe configuration to use
+ when the interrupt controller irq is unused (when not provided, default is 0)
+
Examples:
crossbar_mpu: @4a020000 {
compatible = "ti,irq-crossbar";
/*
* @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;
{
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,
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;