Commit a35057d1dcb11ae67c9347ef7987cf65ac743c36

Authored by Nishanth Menon
Committed by Jason Cooper
1 parent 64e0f8ba5c

irqchip: crossbar: Initialise the crossbar with a safe value

Since crossbar is s/w configurable, the initial settings of the
crossbar cannot be assumed to be sane. This implies that:
a) On initialization all un-reserved crossbars must be initialized to
   a known 'safe' value.
b) When unmapping the interrupt, the safe value must be written to
   ensure that the crossbar mapping matches with interrupt controller
   usage.

So provide a safe value in the dt data to map if
'0' is not safe for the platform and use it during init and unmap

While at this, fix the below checkpatch warning.
Fixes checkpatch warning:
WARNING: Unnecessary space before function pointer arguments
 #37: FILE: drivers/irqchip/irq-crossbar.c:37:
 +	void (*write) (int, int);

Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Sricharan R <r.sricharan@ti.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Link: https://lkml.kernel.org/r/1403766634-18543-5-git-send-email-r.sricharan@ti.com
Signed-off-by: Jason Cooper <jason@lakedaemon.net>

Showing 2 changed files with 20 additions and 2 deletions Side-by-side Diff

Documentation/devicetree/bindings/arm/omap/crossbar.txt
... ... @@ -22,6 +22,9 @@
22 22 SOC-specific hard-wiring of those irqs which unexpectedly bypasses the
23 23 crossbar. These irqs have a crossbar register, but still cannot be used.
24 24  
  25 +- ti,irqs-safe-map: integer which maps to a safe configuration to use
  26 + when the interrupt controller irq is unused (when not provided, default is 0)
  27 +
25 28 Examples:
26 29 crossbar_mpu: @4a020000 {
27 30 compatible = "ti,irq-crossbar";
drivers/irqchip/irq-crossbar.c
... ... @@ -23,16 +23,18 @@
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;
39 41  
... ... @@ -88,8 +90,10 @@
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,
... ... @@ -212,6 +216,17 @@
212 216  
213 217 cb->register_offsets[i] = reserved;
214 218 reserved += size;
  219 + }
  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);
215 230 }
216 231  
217 232 register_routable_domain_ops(&routable_irq_domain_ops);