Commit 2f7d2fb71dd0c14f9c0fe66f2ed7b4685fa745e2
Committed by
Jason Cooper
1 parent
8b09a45dc1
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
irqchip: crossbar: Introduce ti, max-crossbar-sources to identify valid crossbar mapping
Currently we attempt to map any crossbar value to an IRQ, however, this is not correct from hardware perspective. There is a max crossbar event number upto which hardware supports. So describe the same in device tree using 'ti,max-crossbar-sources' property and use it to validate requests. [ jac - remove MAX_SOURCES from binding doc, use integer because we shouldn't put implementation details in the binding docs ] 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-14-git-send-email-r.sricharan@ti.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Showing 2 changed files with 21 additions and 2 deletions Side-by-side Diff
Documentation/devicetree/bindings/arm/omap/crossbar.txt
... | ... | @@ -10,6 +10,7 @@ |
10 | 10 | - compatible : Should be "ti,irq-crossbar" |
11 | 11 | - reg: Base address and the size of the crossbar registers. |
12 | 12 | - ti,max-irqs: Total number of irqs available at the interrupt controller. |
13 | +- ti,max-crossbar-sources: Maximum number of crossbar sources that can be routed. | |
13 | 14 | - ti,reg-size: Size of a individual register in bytes. Every individual |
14 | 15 | register is assumed to be of same size. Valid sizes are 1, 2, 4. |
15 | 16 | - ti,irqs-reserved: List of the reserved irq lines that are not muxed using |
... | ... | @@ -30,6 +31,7 @@ |
30 | 31 | compatible = "ti,irq-crossbar"; |
31 | 32 | reg = <0x4a002a48 0x130>; |
32 | 33 | ti,max-irqs = <160>; |
34 | + ti,max-crossbar-sources = <400>; | |
33 | 35 | ti,reg-size = <2>; |
34 | 36 | ti,irqs-reserved = <0 1 2 3 5 6 131 132 139 140>; |
35 | 37 | ti,irqs-skip = <10 133 139 140>; |
drivers/irqchip/irq-crossbar.c
... | ... | @@ -26,6 +26,7 @@ |
26 | 26 | * struct crossbar_device - crossbar device description |
27 | 27 | * @int_max: maximum number of supported interrupts |
28 | 28 | * @safe_map: safe default value to initialize the crossbar |
29 | + * @max_crossbar_sources: Maximum number of crossbar sources | |
29 | 30 | * @irq_map: array of interrupts to crossbar number mapping |
30 | 31 | * @crossbar_base: crossbar base address |
31 | 32 | * @register_offsets: offsets for each irq number |
... | ... | @@ -34,6 +35,7 @@ |
34 | 35 | struct crossbar_device { |
35 | 36 | uint int_max; |
36 | 37 | uint safe_map; |
38 | + uint max_crossbar_sources; | |
37 | 39 | uint *irq_map; |
38 | 40 | void __iomem *crossbar_base; |
39 | 41 | int *register_offsets; |
40 | 42 | |
41 | 43 | |
... | ... | @@ -117,12 +119,19 @@ |
117 | 119 | unsigned int *out_type) |
118 | 120 | { |
119 | 121 | int ret; |
122 | + int req_num = intspec[1]; | |
120 | 123 | |
121 | - ret = get_prev_map_irq(intspec[1]); | |
124 | + if (req_num >= cb->max_crossbar_sources) { | |
125 | + pr_err("%s: requested crossbar number %d > max %d\n", | |
126 | + __func__, req_num, cb->max_crossbar_sources); | |
127 | + return -EINVAL; | |
128 | + } | |
129 | + | |
130 | + ret = get_prev_map_irq(req_num); | |
122 | 131 | if (ret >= 0) |
123 | 132 | goto found; |
124 | 133 | |
125 | - ret = allocate_free_irq(intspec[1]); | |
134 | + ret = allocate_free_irq(req_num); | |
126 | 135 | |
127 | 136 | if (ret < 0) |
128 | 137 | return ret; |
... | ... | @@ -152,6 +161,14 @@ |
152 | 161 | cb->crossbar_base = of_iomap(node, 0); |
153 | 162 | if (!cb->crossbar_base) |
154 | 163 | goto err_cb; |
164 | + | |
165 | + of_property_read_u32(node, "ti,max-crossbar-sources", | |
166 | + &cb->max_crossbar_sources); | |
167 | + if (!cb->max_crossbar_sources) { | |
168 | + pr_err("missing 'ti,max-crossbar-sources' property\n"); | |
169 | + ret = -EINVAL; | |
170 | + goto err_base; | |
171 | + } | |
155 | 172 | |
156 | 173 | of_property_read_u32(node, "ti,max-irqs", &max); |
157 | 174 | if (!max) { |