aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/sh_intc.h
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-10-04 15:47:03 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-10-04 15:47:03 -0400
commitc1e30ad98fe210688edca872686db4a715c2fb23 (patch)
tree1ff151ccc9658d7a2d89da9cfc6a2d6817913a79 /include/linux/sh_intc.h
parent44629f57accccbb8e6d443246fe6f51b42f7f781 (diff)
sh: intc: Support virtual mappings for IRQ subgroups.
Many interrupts that share a single mask source but are on different hardware vectors will have an associated register tied to an INTEVT that denotes the precise cause for the interrupt exception being triggered. This introduces the concept of IRQ subgroups in the intc core, where a virtual IRQ map is constructed for each of the pre-defined cause bits, and a higher level chained handler takes control of the parent INTEVT. This enables CPUs with heavily muxed IRQ vectors (especially across disjoint blocks) to break things out in to a series of managed chained handlers while being able to dynamically lookup and adopt the IRQs created for them. This is largely an opt-in interface, requiring CPUs to manually submit IRQs for subgroup splitting, in addition to providing identifiers in their enum maps that can be used for lazy lookup via the radix tree. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'include/linux/sh_intc.h')
-rw-r--r--include/linux/sh_intc.h12
1 files changed, 11 insertions, 1 deletions
diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h
index d40fd77fa75c..04134a6c7b52 100644
--- a/include/linux/sh_intc.h
+++ b/include/linux/sh_intc.h
@@ -20,6 +20,12 @@ struct intc_group {
20 20
21#define INTC_GROUP(enum_id, ids...) { enum_id, { ids } } 21#define INTC_GROUP(enum_id, ids...) { enum_id, { ids } }
22 22
23struct intc_subgroup {
24 unsigned long reg, reg_width;
25 intc_enum parent_id;
26 intc_enum enum_ids[32];
27};
28
23struct intc_mask_reg { 29struct intc_mask_reg {
24 unsigned long set_reg, clr_reg, reg_width; 30 unsigned long set_reg, clr_reg, reg_width;
25 intc_enum enum_ids[32]; 31 intc_enum enum_ids[32];
@@ -69,9 +75,12 @@ struct intc_hw_desc {
69 unsigned int nr_sense_regs; 75 unsigned int nr_sense_regs;
70 struct intc_mask_reg *ack_regs; 76 struct intc_mask_reg *ack_regs;
71 unsigned int nr_ack_regs; 77 unsigned int nr_ack_regs;
78 struct intc_subgroup *subgroups;
79 unsigned int nr_subgroups;
72}; 80};
73 81
74#define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a) 82#define _INTC_ARRAY(a) a, a == NULL ? 0 : sizeof(a)/sizeof(*a)
83
75#define INTC_HW_DESC(vectors, groups, mask_regs, \ 84#define INTC_HW_DESC(vectors, groups, mask_regs, \
76 prio_regs, sense_regs, ack_regs) \ 85 prio_regs, sense_regs, ack_regs) \
77{ \ 86{ \
@@ -109,6 +118,7 @@ int __init register_intc_controller(struct intc_desc *desc);
109void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs); 118void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs);
110int intc_set_priority(unsigned int irq, unsigned int prio); 119int intc_set_priority(unsigned int irq, unsigned int prio);
111unsigned int intc_irq_lookup(const char *chipname, intc_enum enum_id); 120unsigned int intc_irq_lookup(const char *chipname, intc_enum enum_id);
121void intc_finalize(void);
112 122
113#ifdef CONFIG_INTC_USERIMASK 123#ifdef CONFIG_INTC_USERIMASK
114int register_intc_userimask(unsigned long addr); 124int register_intc_userimask(unsigned long addr);