aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNishanth Menon <nm@ti.com>2014-06-26 03:10:31 -0400
committerJason Cooper <jason@lakedaemon.net>2014-06-30 15:20:49 -0400
commit2f7d2fb71dd0c14f9c0fe66f2ed7b4685fa745e2 (patch)
tree41e0a9ae3da65a99c8913fb321c0e20faa063a22
parent8b09a45dc12f83f2312a47f0f0087ec4004ebacc (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.txt2
-rw-r--r--drivers/irqchip/irq-crossbar.c21
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 @@
34struct crossbar_device { 35struct 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");