diff options
author | Nishanth Menon <nm@ti.com> | 2014-06-26 03:10:31 -0400 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2014-06-30 15:20:49 -0400 |
commit | 2f7d2fb71dd0c14f9c0fe66f2ed7b4685fa745e2 (patch) | |
tree | 41e0a9ae3da65a99c8913fb321c0e20faa063a22 | |
parent | 8b09a45dc12f83f2312a47f0f0087ec4004ebacc (diff) |
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>
-rw-r--r-- | Documentation/devicetree/bindings/arm/omap/crossbar.txt | 2 | ||||
-rw-r--r-- | drivers/irqchip/irq-crossbar.c | 21 |
2 files changed, 21 insertions, 2 deletions
diff --git a/Documentation/devicetree/bindings/arm/omap/crossbar.txt b/Documentation/devicetree/bindings/arm/omap/crossbar.txt index 5f45c78e31a9..a6e462f88889 100644 --- a/Documentation/devicetree/bindings/arm/omap/crossbar.txt +++ b/Documentation/devicetree/bindings/arm/omap/crossbar.txt | |||
@@ -10,6 +10,7 @@ Required properties: | |||
10 | - compatible : Should be "ti,irq-crossbar" | 10 | - compatible : Should be "ti,irq-crossbar" |
11 | - reg: Base address and the size of the crossbar registers. | 11 | - reg: Base address and the size of the crossbar registers. |
12 | - ti,max-irqs: Total number of irqs available at the interrupt controller. | 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 | - ti,reg-size: Size of a individual register in bytes. Every individual | 14 | - ti,reg-size: Size of a individual register in bytes. Every individual |
14 | register is assumed to be of same size. Valid sizes are 1, 2, 4. | 15 | register is assumed to be of same size. Valid sizes are 1, 2, 4. |
15 | - ti,irqs-reserved: List of the reserved irq lines that are not muxed using | 16 | - ti,irqs-reserved: List of the reserved irq lines that are not muxed using |
@@ -30,6 +31,7 @@ Examples: | |||
30 | compatible = "ti,irq-crossbar"; | 31 | compatible = "ti,irq-crossbar"; |
31 | reg = <0x4a002a48 0x130>; | 32 | reg = <0x4a002a48 0x130>; |
32 | ti,max-irqs = <160>; | 33 | ti,max-irqs = <160>; |
34 | ti,max-crossbar-sources = <400>; | ||
33 | ti,reg-size = <2>; | 35 | ti,reg-size = <2>; |
34 | ti,irqs-reserved = <0 1 2 3 5 6 131 132 139 140>; | 36 | ti,irqs-reserved = <0 1 2 3 5 6 131 132 139 140>; |
35 | ti,irqs-skip = <10 133 139 140>; | 37 | ti,irqs-skip = <10 133 139 140>; |
diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c index 518d712c475a..c9f068ca7bc9 100644 --- a/drivers/irqchip/irq-crossbar.c +++ b/drivers/irqchip/irq-crossbar.c | |||
@@ -26,6 +26,7 @@ | |||
26 | * struct crossbar_device - crossbar device description | 26 | * struct crossbar_device - crossbar device description |
27 | * @int_max: maximum number of supported interrupts | 27 | * @int_max: maximum number of supported interrupts |
28 | * @safe_map: safe default value to initialize the crossbar | 28 | * @safe_map: safe default value to initialize the crossbar |
29 | * @max_crossbar_sources: Maximum number of crossbar sources | ||
29 | * @irq_map: array of interrupts to crossbar number mapping | 30 | * @irq_map: array of interrupts to crossbar number mapping |
30 | * @crossbar_base: crossbar base address | 31 | * @crossbar_base: crossbar base address |
31 | * @register_offsets: offsets for each irq number | 32 | * @register_offsets: offsets for each irq number |
@@ -34,6 +35,7 @@ | |||
34 | struct crossbar_device { | 35 | struct crossbar_device { |
35 | uint int_max; | 36 | uint int_max; |
36 | uint safe_map; | 37 | uint safe_map; |
38 | uint max_crossbar_sources; | ||
37 | uint *irq_map; | 39 | uint *irq_map; |
38 | void __iomem *crossbar_base; | 40 | void __iomem *crossbar_base; |
39 | int *register_offsets; | 41 | int *register_offsets; |
@@ -117,12 +119,19 @@ static int crossbar_domain_xlate(struct irq_domain *d, | |||
117 | unsigned int *out_type) | 119 | unsigned int *out_type) |
118 | { | 120 | { |
119 | int ret; | 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 | if (ret >= 0) | 131 | if (ret >= 0) |
123 | goto found; | 132 | goto found; |
124 | 133 | ||
125 | ret = allocate_free_irq(intspec[1]); | 134 | ret = allocate_free_irq(req_num); |
126 | 135 | ||
127 | if (ret < 0) | 136 | if (ret < 0) |
128 | return ret; | 137 | return ret; |
@@ -153,6 +162,14 @@ static int __init crossbar_of_init(struct device_node *node) | |||
153 | if (!cb->crossbar_base) | 162 | if (!cb->crossbar_base) |
154 | goto err_cb; | 163 | goto err_cb; |
155 | 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 | } | ||
172 | |||
156 | of_property_read_u32(node, "ti,max-irqs", &max); | 173 | of_property_read_u32(node, "ti,max-irqs", &max); |
157 | if (!max) { | 174 | if (!max) { |
158 | pr_err("missing 'ti,max-irqs' property\n"); | 175 | pr_err("missing 'ti,max-irqs' property\n"); |