Commit 2f7d2fb7 authored by Nishanth Menon's avatar Nishanth Menon Committed by Jason Cooper

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: default avatarNishanth Menon <nm@ti.com>
Signed-off-by: default avatarSricharan R <r.sricharan@ti.com>
Acked-by: default avatarSantosh Shilimkar <santosh.shilimkar@ti.com>
Link: https://lkml.kernel.org/r/1403766634-18543-14-git-send-email-r.sricharan@ti.comSigned-off-by: default avatarJason Cooper <jason@lakedaemon.net>
parent 8b09a45d
...@@ -10,6 +10,7 @@ Required properties: ...@@ -10,6 +10,7 @@ Required properties:
- compatible : Should be "ti,irq-crossbar" - compatible : Should be "ti,irq-crossbar"
- reg: Base address and the size of the crossbar registers. - reg: Base address and the size of the crossbar registers.
- ti,max-irqs: Total number of irqs available at the interrupt controller. - ti,max-irqs: Total number of irqs available at the interrupt controller.
- ti,max-crossbar-sources: Maximum number of crossbar sources that can be routed.
- ti,reg-size: Size of a individual register in bytes. Every individual - ti,reg-size: Size of a individual register in bytes. Every individual
register is assumed to be of same size. Valid sizes are 1, 2, 4. register is assumed to be of same size. Valid sizes are 1, 2, 4.
- ti,irqs-reserved: List of the reserved irq lines that are not muxed using - ti,irqs-reserved: List of the reserved irq lines that are not muxed using
...@@ -30,6 +31,7 @@ Examples: ...@@ -30,6 +31,7 @@ Examples:
compatible = "ti,irq-crossbar"; compatible = "ti,irq-crossbar";
reg = <0x4a002a48 0x130>; reg = <0x4a002a48 0x130>;
ti,max-irqs = <160>; ti,max-irqs = <160>;
ti,max-crossbar-sources = <400>;
ti,reg-size = <2>; ti,reg-size = <2>;
ti,irqs-reserved = <0 1 2 3 5 6 131 132 139 140>; ti,irqs-reserved = <0 1 2 3 5 6 131 132 139 140>;
ti,irqs-skip = <10 133 139 140>; ti,irqs-skip = <10 133 139 140>;
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
* struct crossbar_device - crossbar device description * struct crossbar_device - crossbar device description
* @int_max: maximum number of supported interrupts * @int_max: maximum number of supported interrupts
* @safe_map: safe default value to initialize the crossbar * @safe_map: safe default value to initialize the crossbar
* @max_crossbar_sources: Maximum number of crossbar sources
* @irq_map: array of interrupts to crossbar number mapping * @irq_map: array of interrupts to crossbar number mapping
* @crossbar_base: crossbar base address * @crossbar_base: crossbar base address
* @register_offsets: offsets for each irq number * @register_offsets: offsets for each irq number
...@@ -34,6 +35,7 @@ ...@@ -34,6 +35,7 @@
struct crossbar_device { struct crossbar_device {
uint int_max; uint int_max;
uint safe_map; uint safe_map;
uint max_crossbar_sources;
uint *irq_map; uint *irq_map;
void __iomem *crossbar_base; void __iomem *crossbar_base;
int *register_offsets; int *register_offsets;
...@@ -117,12 +119,19 @@ static int crossbar_domain_xlate(struct irq_domain *d, ...@@ -117,12 +119,19 @@ static int crossbar_domain_xlate(struct irq_domain *d,
unsigned int *out_type) unsigned int *out_type)
{ {
int ret; int ret;
int req_num = intspec[1];
ret = get_prev_map_irq(intspec[1]); if (req_num >= cb->max_crossbar_sources) {
pr_err("%s: requested crossbar number %d > max %d\n",
__func__, req_num, cb->max_crossbar_sources);
return -EINVAL;
}
ret = get_prev_map_irq(req_num);
if (ret >= 0) if (ret >= 0)
goto found; goto found;
ret = allocate_free_irq(intspec[1]); ret = allocate_free_irq(req_num);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -153,6 +162,14 @@ static int __init crossbar_of_init(struct device_node *node) ...@@ -153,6 +162,14 @@ static int __init crossbar_of_init(struct device_node *node)
if (!cb->crossbar_base) if (!cb->crossbar_base)
goto err_cb; goto err_cb;
of_property_read_u32(node, "ti,max-crossbar-sources",
&cb->max_crossbar_sources);
if (!cb->max_crossbar_sources) {
pr_err("missing 'ti,max-crossbar-sources' property\n");
ret = -EINVAL;
goto err_base;
}
of_property_read_u32(node, "ti,max-irqs", &max); of_property_read_u32(node, "ti,max-irqs", &max);
if (!max) { if (!max) {
pr_err("missing 'ti,max-irqs' property\n"); pr_err("missing 'ti,max-irqs' property\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment