2 * Support for hardware-managed IRQ auto-distribution.
4 * Copyright (C) 2010 Paul Mundt
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
10 #include "internals.h"
12 static unsigned long dist_handle
[INTC_NR_IRQS
];
14 void intc_balancing_enable(unsigned int irq
)
16 struct intc_desc_int
*d
= get_intc_desc(irq
);
17 unsigned long handle
= dist_handle
[irq
];
20 if (irq_balancing_disabled(irq
) || !handle
)
23 addr
= INTC_REG(d
, _INTC_ADDR_D(handle
), 0);
24 intc_reg_fns
[_INTC_FN(handle
)](addr
, handle
, 1);
27 void intc_balancing_disable(unsigned int irq
)
29 struct intc_desc_int
*d
= get_intc_desc(irq
);
30 unsigned long handle
= dist_handle
[irq
];
33 if (irq_balancing_disabled(irq
) || !handle
)
36 addr
= INTC_REG(d
, _INTC_ADDR_D(handle
), 0);
37 intc_reg_fns
[_INTC_FN(handle
)](addr
, handle
, 0);
40 static unsigned int intc_dist_data(struct intc_desc
*desc
,
41 struct intc_desc_int
*d
,
44 struct intc_mask_reg
*mr
= desc
->hw
.mask_regs
;
45 unsigned int i
, j
, fn
, mode
;
46 unsigned long reg_e
, reg_d
;
48 for (i
= 0; mr
&& enum_id
&& i
< desc
->hw
.nr_mask_regs
; i
++) {
49 mr
= desc
->hw
.mask_regs
+ i
;
52 * Skip this entry if there's no auto-distribution
53 * register associated with it.
58 for (j
= 0; j
< ARRAY_SIZE(mr
->enum_ids
); j
++) {
59 if (mr
->enum_ids
[j
] != enum_id
)
62 fn
= REG_FN_MODIFY_BASE
;
63 mode
= MODE_ENABLE_REG
;
67 fn
+= (mr
->reg_width
>> 3) - 1;
68 return _INTC_MK(fn
, mode
,
69 intc_get_reg(d
, reg_e
),
70 intc_get_reg(d
, reg_d
),
72 (mr
->reg_width
- 1) - j
);
77 * It's possible we've gotten here with no distribution options
78 * available for the IRQ in question, so we just skip over those.
83 void intc_set_dist_handle(unsigned int irq
, struct intc_desc
*desc
,
84 struct intc_desc_int
*d
, intc_enum id
)
89 * Nothing to do for this IRQ.
91 if (!desc
->hw
.mask_regs
)
94 raw_spin_lock_irqsave(&intc_big_lock
, flags
);
95 dist_handle
[irq
] = intc_dist_data(desc
, d
, id
);
96 raw_spin_unlock_irqrestore(&intc_big_lock
, flags
);