diff options
author | Magnus Damm <damm@igel.co.jp> | 2007-07-18 17:25:09 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2007-07-20 12:18:20 +0900 |
commit | 02ab3f70791f7d5c9098acaa31a72dd7d0961cb0 (patch) | |
tree | b95f0ec8cc57ed2166eb28e53bb604374e6f0f44 /include/asm-sh/hw_irq.h | |
parent | 53aba19f82045c1df838570b8484043e93c4442a (diff) |
sh: intc - shared IPR and INTC2 controller
This is the second version of the shared interrupt controller patch
for the sh architecture, fixing up handling of intc_reg_fns[].
The three main advantages with this controller over the existing
ones are:
- Both priority (ipr) and bitmap (intc2) registers are
supported
- External pin sense configuration is supported, ie edge
vs level triggered
- CPU/Board specific code maps 1:1 with datasheet for
easy verification
This controller can easily coexist with the current IPR and INTC2
controllers, but the idea is that CPUs/Boards should be moved over
to this controller over time so we have a single code base to
maintain.
Signed-off-by: Magnus Damm <damm@igel.co.jp>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'include/asm-sh/hw_irq.h')
-rw-r--r-- | include/asm-sh/hw_irq.h | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index 4ca3f765bac..34ff8c7cfb5 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h @@ -1,6 +1,7 @@ #ifndef __ASM_SH_HW_IRQ_H #define __ASM_SH_HW_IRQ_H +#include <linux/init.h> #include <asm/atomic.h> extern atomic_t irq_err_count; @@ -47,4 +48,71 @@ void init_IRQ_ipr(void); */ void ipr_irq_enable_irlm(void); +typedef unsigned char intc_enum; + +struct intc_vect { + intc_enum enum_id; + unsigned short vect; +}; + +#define INTC_VECT(enum_id, vect) { enum_id, vect } + +struct intc_prio { + intc_enum enum_id; + unsigned char priority; +}; + +#define INTC_PRIO(enum_id, prio) { enum_id, prio } + +struct intc_group { + intc_enum enum_id; + intc_enum *enum_ids; +}; + +#define INTC_GROUP(enum_id, ids...) { enum_id, (intc_enum []) { ids, 0 } } + +struct intc_mask_reg { + unsigned long set_reg, clr_reg, reg_width; + intc_enum enum_ids[32]; +}; + +struct intc_prio_reg { + unsigned long reg, reg_width, field_width; + intc_enum enum_ids[16]; +}; + +struct intc_sense_reg { + unsigned long reg, reg_width, field_width; + intc_enum enum_ids[16]; +}; + +struct intc_desc { + struct intc_vect *vectors; + unsigned int nr_vectors; + struct intc_group *groups; + unsigned int nr_groups; + struct intc_prio *priorities; + unsigned int nr_priorities; + struct intc_mask_reg *mask_regs; + unsigned int nr_mask_regs; + struct intc_prio_reg *prio_regs; + unsigned int nr_prio_regs; + struct intc_sense_reg *sense_regs; + unsigned int nr_sense_regs; + struct irq_chip chip; +}; + +#define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a) +#define DECLARE_INTC_DESC(symbol, chipname, vectors, groups, \ + priorities, mask_regs, prio_regs, sense_regs) \ +static struct intc_desc symbol = { \ + _INTC_ARRAY(vectors), _INTC_ARRAY(groups), \ + _INTC_ARRAY(priorities), \ + _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \ + _INTC_ARRAY(sense_regs), \ + .chip.name = chipname, \ +} + +void __init register_intc_controller(struct intc_desc *desc); + #endif /* __ASM_SH_HW_IRQ_H */ |