sh_intc.h (3506B)
1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef __SH_INTC_H 3#define __SH_INTC_H 4 5#include <linux/ioport.h> 6 7#ifdef CONFIG_SUPERH 8#define INTC_NR_IRQS 512 9#else 10#define INTC_NR_IRQS 1024 11#endif 12 13/* 14 * Convert back and forth between INTEVT and IRQ values. 15 */ 16#ifdef CONFIG_CPU_HAS_INTEVT 17#define evt2irq(evt) (((evt) >> 5) - 16) 18#define irq2evt(irq) (((irq) + 16) << 5) 19#else 20#define evt2irq(evt) (evt) 21#define irq2evt(irq) (irq) 22#endif 23 24typedef unsigned char intc_enum; 25 26struct intc_vect { 27 intc_enum enum_id; 28 unsigned short vect; 29}; 30 31#define INTC_VECT(enum_id, vect) { enum_id, vect } 32#define INTC_IRQ(enum_id, irq) INTC_VECT(enum_id, irq2evt(irq)) 33 34struct intc_group { 35 intc_enum enum_id; 36 intc_enum enum_ids[32]; 37}; 38 39#define INTC_GROUP(enum_id, ids...) { enum_id, { ids } } 40 41struct intc_subgroup { 42 unsigned long reg, reg_width; 43 intc_enum parent_id; 44 intc_enum enum_ids[32]; 45}; 46 47struct intc_mask_reg { 48 unsigned long set_reg, clr_reg, reg_width; 49 intc_enum enum_ids[32]; 50#ifdef CONFIG_INTC_BALANCING 51 unsigned long dist_reg; 52#endif 53#ifdef CONFIG_SMP 54 unsigned long smp; 55#endif 56}; 57 58struct intc_prio_reg { 59 unsigned long set_reg, clr_reg, reg_width, field_width; 60 intc_enum enum_ids[16]; 61#ifdef CONFIG_SMP 62 unsigned long smp; 63#endif 64}; 65 66struct intc_sense_reg { 67 unsigned long reg, reg_width, field_width; 68 intc_enum enum_ids[16]; 69}; 70 71#ifdef CONFIG_INTC_BALANCING 72#define INTC_SMP_BALANCING(reg) .dist_reg = (reg) 73#else 74#define INTC_SMP_BALANCING(reg) 75#endif 76 77#ifdef CONFIG_SMP 78#define INTC_SMP(stride, nr) .smp = (stride) | ((nr) << 8) 79#else 80#define INTC_SMP(stride, nr) 81#endif 82 83struct intc_hw_desc { 84 struct intc_vect *vectors; 85 unsigned int nr_vectors; 86 struct intc_group *groups; 87 unsigned int nr_groups; 88 struct intc_mask_reg *mask_regs; 89 unsigned int nr_mask_regs; 90 struct intc_prio_reg *prio_regs; 91 unsigned int nr_prio_regs; 92 struct intc_sense_reg *sense_regs; 93 unsigned int nr_sense_regs; 94 struct intc_mask_reg *ack_regs; 95 unsigned int nr_ack_regs; 96 struct intc_subgroup *subgroups; 97 unsigned int nr_subgroups; 98}; 99 100#define _INTC_ARRAY(a) a, __same_type(a, NULL) ? 0 : sizeof(a)/sizeof(*a) 101 102#define INTC_HW_DESC(vectors, groups, mask_regs, \ 103 prio_regs, sense_regs, ack_regs) \ 104{ \ 105 _INTC_ARRAY(vectors), _INTC_ARRAY(groups), \ 106 _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \ 107 _INTC_ARRAY(sense_regs), _INTC_ARRAY(ack_regs), \ 108} 109 110struct intc_desc { 111 char *name; 112 struct resource *resource; 113 unsigned int num_resources; 114 intc_enum force_enable; 115 intc_enum force_disable; 116 bool skip_syscore_suspend; 117 struct intc_hw_desc hw; 118}; 119 120#define DECLARE_INTC_DESC(symbol, chipname, vectors, groups, \ 121 mask_regs, prio_regs, sense_regs) \ 122struct intc_desc symbol __initdata = { \ 123 .name = chipname, \ 124 .hw = INTC_HW_DESC(vectors, groups, mask_regs, \ 125 prio_regs, sense_regs, NULL), \ 126} 127 128#define DECLARE_INTC_DESC_ACK(symbol, chipname, vectors, groups, \ 129 mask_regs, prio_regs, sense_regs, ack_regs) \ 130struct intc_desc symbol __initdata = { \ 131 .name = chipname, \ 132 .hw = INTC_HW_DESC(vectors, groups, mask_regs, \ 133 prio_regs, sense_regs, ack_regs), \ 134} 135 136int register_intc_controller(struct intc_desc *desc); 137int intc_set_priority(unsigned int irq, unsigned int prio); 138int intc_irq_lookup(const char *chipname, intc_enum enum_id); 139void intc_finalize(void); 140 141#ifdef CONFIG_INTC_USERIMASK 142int register_intc_userimask(unsigned long addr); 143#else 144static inline int register_intc_userimask(unsigned long addr) 145{ 146 return 0; 147} 148#endif 149 150#endif /* __SH_INTC_H */