f18d533e3c
This implements initial support for the SMP INTC (particularly INTC2) controllers. These are largely implemented as conventional blocks, with register sets grouped together at fixed strides relative to the CPU id. Signed-off-by: Magnus Damm <damm@igel.co.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
115 lines
2.6 KiB
C
115 lines
2.6 KiB
C
#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;
|
|
|
|
struct ipr_data {
|
|
unsigned char irq;
|
|
unsigned char ipr_idx; /* Index for the IPR registered */
|
|
unsigned char shift; /* Number of bits to shift the data */
|
|
unsigned char priority; /* The priority */
|
|
};
|
|
|
|
struct ipr_desc {
|
|
unsigned long *ipr_offsets;
|
|
unsigned int nr_offsets;
|
|
struct ipr_data *ipr_data;
|
|
unsigned int nr_irqs;
|
|
struct irq_chip chip;
|
|
};
|
|
|
|
void register_ipr_controller(struct ipr_desc *);
|
|
|
|
typedef unsigned char intc_enum;
|
|
|
|
struct intc_vect {
|
|
intc_enum enum_id;
|
|
unsigned short vect;
|
|
};
|
|
|
|
#define INTC_VECT(enum_id, vect) { enum_id, vect }
|
|
#define INTC_IRQ(enum_id, irq) INTC_VECT(enum_id, irq2evt(irq))
|
|
|
|
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[32];
|
|
};
|
|
|
|
#define INTC_GROUP(enum_id, ids...) { enum_id, { ids } }
|
|
|
|
struct intc_mask_reg {
|
|
unsigned long set_reg, clr_reg, reg_width;
|
|
intc_enum enum_ids[32];
|
|
#ifdef CONFIG_SMP
|
|
unsigned long smp;
|
|
#endif
|
|
};
|
|
|
|
struct intc_prio_reg {
|
|
unsigned long set_reg, clr_reg, reg_width, field_width;
|
|
intc_enum enum_ids[16];
|
|
#ifdef CONFIG_SMP
|
|
unsigned long smp;
|
|
#endif
|
|
};
|
|
|
|
struct intc_sense_reg {
|
|
unsigned long reg, reg_width, field_width;
|
|
intc_enum enum_ids[16];
|
|
};
|
|
|
|
#ifdef CONFIG_SMP
|
|
#define INTC_SMP(stride, nr) .smp = (stride) | ((nr) << 8)
|
|
#else
|
|
#define INTC_SMP(stride, nr)
|
|
#endif
|
|
|
|
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;
|
|
char *name;
|
|
};
|
|
|
|
#define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a)
|
|
#define DECLARE_INTC_DESC(symbol, chipname, vectors, groups, \
|
|
priorities, mask_regs, prio_regs, sense_regs) \
|
|
struct intc_desc symbol __initdata = { \
|
|
_INTC_ARRAY(vectors), _INTC_ARRAY(groups), \
|
|
_INTC_ARRAY(priorities), \
|
|
_INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \
|
|
_INTC_ARRAY(sense_regs), \
|
|
chipname, \
|
|
}
|
|
|
|
void __init register_intc_controller(struct intc_desc *desc);
|
|
int intc_set_priority(unsigned int irq, unsigned int prio);
|
|
|
|
void __init plat_irq_setup(void);
|
|
|
|
enum { IRQ_MODE_IRQ, IRQ_MODE_IRQ7654, IRQ_MODE_IRQ3210,
|
|
IRQ_MODE_IRL7654_MASK, IRQ_MODE_IRL3210_MASK,
|
|
IRQ_MODE_IRL7654, IRQ_MODE_IRL3210 };
|
|
void __init plat_irq_setup_pins(int mode);
|
|
|
|
#endif /* __ASM_SH_HW_IRQ_H */
|