irqdesc.h 7.5 KB
Newer Older
T
Thomas Gleixner 已提交
1 2 3
#ifndef _LINUX_IRQDESC_H
#define _LINUX_IRQDESC_H

T
Thomas Gleixner 已提交
4
#include <linux/rcupdate.h>
5
#include <linux/kobject.h>
T
Thomas Gleixner 已提交
6

T
Thomas Gleixner 已提交
7 8 9 10
/*
 * Core internal functions to deal with irq descriptors
 */

11
struct irq_affinity_notify;
T
Thomas Gleixner 已提交
12
struct proc_dir_entry;
13
struct module;
14
struct irq_desc;
15 16
struct irq_domain;
struct pt_regs;
17

T
Thomas Gleixner 已提交
18 19
/**
 * struct irq_desc - interrupt descriptor
20
 * @irq_common_data:	per irq and chip data passed down to chip functions
T
Thomas Gleixner 已提交
21
 * @kstat_irqs:		irq stats per cpu
22 23
 * @handle_irq:		highlevel irq-events handler
 * @preflow_handler:	handler called before the flow handler (currently used by sparc)
T
Thomas Gleixner 已提交
24 25
 * @action:		the irq action chain
 * @status:		status information
26
 * @core_internal_state__do_not_mess_with_it: core internal status information
T
Thomas Gleixner 已提交
27
 * @depth:		disable-depth, for nested irq_disable() calls
28
 * @wake_depth:		enable depth, for multiple irq_set_irq_wake() callers
T
Thomas Gleixner 已提交
29 30 31
 * @irq_count:		stats field to detect stalled irqs
 * @last_unhandled:	aging timer for unhandled count
 * @irqs_unhandled:	stats field for spurious unhandled interrupts
32 33
 * @threads_handled:	stats field for deferred spurious detection of threaded handlers
 * @threads_handled_last: comparator field for deferred spurious detection of theraded handlers
T
Thomas Gleixner 已提交
34
 * @lock:		locking for SMP
35
 * @affinity_hint:	hint to user space for preferred irq affinity
36
 * @affinity_notify:	context for notification of affinity changes
T
Thomas Gleixner 已提交
37
 * @pending_mask:	pending rebalanced interrupts
38
 * @threads_oneshot:	bitfield to handle shared oneshot threads
T
Thomas Gleixner 已提交
39 40
 * @threads_active:	number of irqaction threads currently running
 * @wait_for_threads:	wait queue for sync_irq to wait for threaded handlers
41 42 43 44 45
 * @nr_actions:		number of installed actions on this descriptor
 * @no_suspend_depth:	number of irqactions on a irq descriptor with
 *			IRQF_NO_SUSPEND set
 * @force_resume_depth:	number of irqactions on a irq descriptor with
 *			IRQF_FORCE_RESUME set
T
Thomas Gleixner 已提交
46
 * @rcu:		rcu head for delayed free
47
 * @kobj:		kobject used to represent this struct in sysfs
T
Thomas Gleixner 已提交
48 49 50 51
 * @dir:		/proc/irq/ procfs entry
 * @name:		flow handler name for /proc/interrupts output
 */
struct irq_desc {
52
	struct irq_common_data	irq_common_data;
T
Thomas Gleixner 已提交
53
	struct irq_data		irq_data;
E
Eric Dumazet 已提交
54
	unsigned int __percpu	*kstat_irqs;
T
Thomas Gleixner 已提交
55
	irq_flow_handler_t	handle_irq;
56 57 58
#ifdef CONFIG_IRQ_PREFLOW_FASTEOI
	irq_preflow_handler_t	preflow_handler;
#endif
T
Thomas Gleixner 已提交
59
	struct irqaction	*action;	/* IRQ action list */
60
	unsigned int		status_use_accessors;
61
	unsigned int		core_internal_state__do_not_mess_with_it;
T
Thomas Gleixner 已提交
62 63 64 65 66
	unsigned int		depth;		/* nested irq disables */
	unsigned int		wake_depth;	/* nested wake enables */
	unsigned int		irq_count;	/* For detecting broken IRQs */
	unsigned long		last_unhandled;	/* Aging timer for unhandled count */
	unsigned int		irqs_unhandled;
67 68
	atomic_t		threads_handled;
	int			threads_handled_last;
T
Thomas Gleixner 已提交
69
	raw_spinlock_t		lock;
70
	struct cpumask		*percpu_enabled;
71
	const struct cpumask	*percpu_affinity;
T
Thomas Gleixner 已提交
72 73
#ifdef CONFIG_SMP
	const struct cpumask	*affinity_hint;
74
	struct irq_affinity_notify *affinity_notify;
T
Thomas Gleixner 已提交
75 76 77 78
#ifdef CONFIG_GENERIC_PENDING_IRQ
	cpumask_var_t		pending_mask;
#endif
#endif
79
	unsigned long		threads_oneshot;
T
Thomas Gleixner 已提交
80 81
	atomic_t		threads_active;
	wait_queue_head_t       wait_for_threads;
82 83 84
#ifdef CONFIG_PM_SLEEP
	unsigned int		nr_actions;
	unsigned int		no_suspend_depth;
85
	unsigned int		cond_suspend_depth;
86 87
	unsigned int		force_resume_depth;
#endif
T
Thomas Gleixner 已提交
88 89
#ifdef CONFIG_PROC_FS
	struct proc_dir_entry	*dir;
T
Thomas Gleixner 已提交
90 91 92
#endif
#ifdef CONFIG_SPARSE_IRQ
	struct rcu_head		rcu;
93
	struct kobject		kobj;
T
Thomas Gleixner 已提交
94
#endif
95
	int			parent_irq;
96
	struct module		*owner;
T
Thomas Gleixner 已提交
97 98 99
	const char		*name;
} ____cacheline_internodealigned_in_smp;

100 101 102 103 104 105
#ifdef CONFIG_SPARSE_IRQ
extern void irq_lock_sparse(void);
extern void irq_unlock_sparse(void);
#else
static inline void irq_lock_sparse(void) { }
static inline void irq_unlock_sparse(void) { }
T
Thomas Gleixner 已提交
106 107 108
extern struct irq_desc irq_desc[NR_IRQS];
#endif

109 110
static inline struct irq_desc *irq_data_to_desc(struct irq_data *data)
{
111
	return container_of(data->common, struct irq_desc, irq_common_data);
112 113
}

114 115 116 117 118
static inline unsigned int irq_desc_get_irq(struct irq_desc *desc)
{
	return desc->irq_data.irq;
}

119 120 121 122 123
static inline struct irq_data *irq_desc_get_irq_data(struct irq_desc *desc)
{
	return &desc->irq_data;
}

T
Thomas Gleixner 已提交
124 125 126 127 128 129 130 131 132 133 134 135
static inline struct irq_chip *irq_desc_get_chip(struct irq_desc *desc)
{
	return desc->irq_data.chip;
}

static inline void *irq_desc_get_chip_data(struct irq_desc *desc)
{
	return desc->irq_data.chip_data;
}

static inline void *irq_desc_get_handler_data(struct irq_desc *desc)
{
136
	return desc->irq_common_data.handler_data;
T
Thomas Gleixner 已提交
137 138 139 140
}

static inline struct msi_desc *irq_desc_get_msi_desc(struct irq_desc *desc)
{
141
	return desc->irq_common_data.msi_desc;
T
Thomas Gleixner 已提交
142 143
}

T
Thomas Gleixner 已提交
144 145
/*
 * Architectures call this to let the generic IRQ layer
146
 * handle an interrupt.
T
Thomas Gleixner 已提交
147
 */
148
static inline void generic_handle_irq_desc(struct irq_desc *desc)
T
Thomas Gleixner 已提交
149
{
150
	desc->handle_irq(desc);
T
Thomas Gleixner 已提交
151 152
}

153
int generic_handle_irq(unsigned int irq);
T
Thomas Gleixner 已提交
154

155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
#ifdef CONFIG_HANDLE_DOMAIN_IRQ
/*
 * Convert a HW interrupt number to a logical one using a IRQ domain,
 * and handle the result interrupt number. Return -EINVAL if
 * conversion failed. Providing a NULL domain indicates that the
 * conversion has already been done.
 */
int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,
			bool lookup, struct pt_regs *regs);

static inline int handle_domain_irq(struct irq_domain *domain,
				    unsigned int hwirq, struct pt_regs *regs)
{
	return __handle_domain_irq(domain, hwirq, true, regs);
}
#endif

T
Thomas Gleixner 已提交
172
/* Test to see if a driver has successfully requested an irq */
173
static inline int irq_desc_has_action(struct irq_desc *desc)
T
Thomas Gleixner 已提交
174 175 176 177
{
	return desc->action != NULL;
}

178 179 180 181 182
static inline int irq_has_action(unsigned int irq)
{
	return irq_desc_has_action(irq_to_desc(irq));
}

183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
/**
 * irq_set_handler_locked - Set irq handler from a locked region
 * @data:	Pointer to the irq_data structure which identifies the irq
 * @handler:	Flow control handler function for this interrupt
 *
 * Sets the handler in the irq descriptor associated to @data.
 *
 * Must be called with irq_desc locked and valid parameters. Typical
 * call site is the irq_set_type() callback.
 */
static inline void irq_set_handler_locked(struct irq_data *data,
					  irq_flow_handler_t handler)
{
	struct irq_desc *desc = irq_data_to_desc(data);

	desc->handle_irq = handler;
}

/**
 * irq_set_chip_handler_name_locked - Set chip, handler and name from a locked region
 * @data:	Pointer to the irq_data structure for which the chip is set
 * @chip:	Pointer to the new irq chip
 * @handler:	Flow control handler function for this interrupt
 * @name:	Name of the interrupt
 *
 * Replace the irq chip at the proper hierarchy level in @data and
 * sets the handler and name in the associated irq descriptor.
 *
 * Must be called with irq_desc locked and valid parameters.
 */
static inline void
irq_set_chip_handler_name_locked(struct irq_data *data, struct irq_chip *chip,
				 irq_flow_handler_t handler, const char *name)
{
	struct irq_desc *desc = irq_data_to_desc(data);

	desc->handle_irq = handler;
	desc->name = name;
	data->chip = chip;
}

224
static inline int irq_balancing_disabled(unsigned int irq)
T
Thomas Gleixner 已提交
225 226 227 228
{
	struct irq_desc *desc;

	desc = irq_to_desc(irq);
T
Thomas Gleixner 已提交
229
	return desc->status_use_accessors & IRQ_NO_BALANCING_MASK;
T
Thomas Gleixner 已提交
230
}
231

232 233 234 235 236 237 238 239
static inline int irq_is_percpu(unsigned int irq)
{
	struct irq_desc *desc;

	desc = irq_to_desc(irq);
	return desc->status_use_accessors & IRQ_PER_CPU;
}

240 241 242 243 244 245 246 247 248
static inline void
irq_set_lockdep_class(unsigned int irq, struct lock_class_key *class)
{
	struct irq_desc *desc = irq_to_desc(irq);

	if (desc)
		lockdep_set_class(&desc->lock, class);
}

249 250 251 252 253 254 255 256 257 258
#ifdef CONFIG_IRQ_PREFLOW_FASTEOI
static inline void
__irq_set_preflow_handler(unsigned int irq, irq_preflow_handler_t handler)
{
	struct irq_desc *desc;

	desc = irq_to_desc(irq);
	desc->preflow_handler = handler;
}
#endif
T
Thomas Gleixner 已提交
259 260

#endif