Viewing file: sh_intc.h (3.63 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SH_INTC_H #define __SH_INTC_H
#include <linux/ioport.h>
#ifdef CONFIG_SUPERH #define INTC_NR_IRQS 512 #else #define INTC_NR_IRQS 1024 #endif
/* * Convert back and forth between INTEVT and IRQ values. */ #ifdef CONFIG_CPU_HAS_INTEVT /* Avoid IRQ0 (invalid for platform devices) */ #define evt2irq(evt) ((evt) >> 5) #define irq2evt(irq) ((irq) << 5) #else #define evt2irq(evt) (evt) #define irq2evt(irq) (irq) #endif
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_group { intc_enum enum_id; intc_enum enum_ids[32]; };
#define INTC_GROUP(enum_id, ids...) { enum_id, { ids } }
struct intc_subgroup { unsigned long reg, reg_width; intc_enum parent_id; intc_enum enum_ids[32]; };
struct intc_mask_reg { unsigned long set_reg, clr_reg, reg_width; intc_enum enum_ids[32]; #ifdef CONFIG_INTC_BALANCING unsigned long dist_reg; #endif #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_INTC_BALANCING #define INTC_SMP_BALANCING(reg) .dist_reg = (reg) #else #define INTC_SMP_BALANCING(reg) #endif
#ifdef CONFIG_SMP #define INTC_SMP(stride, nr) .smp = (stride) | ((nr) << 8) #else #define INTC_SMP(stride, nr) #endif
struct intc_hw_desc { struct intc_vect *vectors; unsigned int nr_vectors; struct intc_group *groups; unsigned int nr_groups; 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 intc_mask_reg *ack_regs; unsigned int nr_ack_regs; struct intc_subgroup *subgroups; unsigned int nr_subgroups; };
#define _INTC_SIZEOF_OR_ZERO(a) (_Generic(a, \ typeof(NULL): 0, \ default: sizeof(a))) #define _INTC_ARRAY(a) a, _INTC_SIZEOF_OR_ZERO(a)/sizeof(*a)
#define INTC_HW_DESC(vectors, groups, mask_regs, \ prio_regs, sense_regs, ack_regs) \ { \ _INTC_ARRAY(vectors), _INTC_ARRAY(groups), \ _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \ _INTC_ARRAY(sense_regs), _INTC_ARRAY(ack_regs), \ }
struct intc_desc { char *name; struct resource *resource; unsigned int num_resources; intc_enum force_enable; intc_enum force_disable; bool skip_syscore_suspend; struct intc_hw_desc hw; };
#define DECLARE_INTC_DESC(symbol, chipname, vectors, groups, \ mask_regs, prio_regs, sense_regs) \ struct intc_desc symbol __initdata = { \ .name = chipname, \ .hw = INTC_HW_DESC(vectors, groups, mask_regs, \ prio_regs, sense_regs, NULL), \ }
#define DECLARE_INTC_DESC_ACK(symbol, chipname, vectors, groups, \ mask_regs, prio_regs, sense_regs, ack_regs) \ struct intc_desc symbol __initdata = { \ .name = chipname, \ .hw = INTC_HW_DESC(vectors, groups, mask_regs, \ prio_regs, sense_regs, ack_regs), \ }
int register_intc_controller(struct intc_desc *desc); int intc_set_priority(unsigned int irq, unsigned int prio); int intc_irq_lookup(const char *chipname, intc_enum enum_id); void intc_finalize(void);
#ifdef CONFIG_INTC_USERIMASK int register_intc_userimask(unsigned long addr); #else static inline int register_intc_userimask(unsigned long addr) { return 0; } #endif
#endif /* __SH_INTC_H */
|