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>
This commit is contained in:
Nishanth Menon 2014-06-26 12:40:31 +05:30 committed by Jason Cooper
parent 8b09a45dc1
commit 2f7d2fb71d
2 changed files with 21 additions and 2 deletions

View File

@ -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:
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>;

View File

@ -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 @@
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,
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)
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");