irq.h 14.7 KB
Newer Older
1 2
#ifndef _LINUX_IRQ_H
#define _LINUX_IRQ_H
L
Linus Torvalds 已提交
3 4 5 6 7 8 9 10 11

/*
 * Please do not include this file in generic code.  There is currently
 * no requirement for any architecture to implement anything held
 * within this file.
 *
 * Thanks. --rmk
 */

12
#include <linux/smp.h>
L
Linus Torvalds 已提交
13

14
#ifndef CONFIG_S390
L
Linus Torvalds 已提交
15 16 17 18 19

#include <linux/linkage.h>
#include <linux/cache.h>
#include <linux/spinlock.h>
#include <linux/cpumask.h>
20
#include <linux/irqreturn.h>
T
Thomas Gleixner 已提交
21
#include <linux/irqnr.h>
D
David Howells 已提交
22
#include <linux/errno.h>
L
Linus Torvalds 已提交
23 24 25

#include <asm/irq.h>
#include <asm/ptrace.h>
26
#include <asm/irq_regs.h>
L
Linus Torvalds 已提交
27

28
struct irq_desc;
29
typedef	void (*irq_flow_handler_t)(unsigned int irq,
30
					    struct irq_desc *desc);
31 32


L
Linus Torvalds 已提交
33 34
/*
 * IRQ line status.
35
 *
36
 * Bits 0-7 are reserved for the IRQF_* bits in linux/interrupt.h
37 38
 *
 * IRQ types
L
Linus Torvalds 已提交
39
 */
40 41 42 43 44 45 46 47 48 49
#define IRQ_TYPE_NONE		0x00000000	/* Default, unspecified type */
#define IRQ_TYPE_EDGE_RISING	0x00000001	/* Edge rising type */
#define IRQ_TYPE_EDGE_FALLING	0x00000002	/* Edge falling type */
#define IRQ_TYPE_EDGE_BOTH (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
#define IRQ_TYPE_LEVEL_HIGH	0x00000004	/* Level high type */
#define IRQ_TYPE_LEVEL_LOW	0x00000008	/* Level low type */
#define IRQ_TYPE_SENSE_MASK	0x0000000f	/* Mask of the above */
#define IRQ_TYPE_PROBE		0x00000010	/* Probing in progress */

/* Internal flags */
50 51 52 53 54 55 56 57 58 59 60 61
#define IRQ_INPROGRESS		0x00000100	/* IRQ handler active - do not enter! */
#define IRQ_DISABLED		0x00000200	/* IRQ disabled - do not enter! */
#define IRQ_PENDING		0x00000400	/* IRQ pending - replay on enable */
#define IRQ_REPLAY		0x00000800	/* IRQ has been replayed but not acked yet */
#define IRQ_AUTODETECT		0x00001000	/* IRQ is being autodetected */
#define IRQ_WAITING		0x00002000	/* IRQ not yet seen - for autodetection */
#define IRQ_LEVEL		0x00004000	/* IRQ level triggered */
#define IRQ_MASKED		0x00008000	/* IRQ masked - shouldn't be seen again */
#define IRQ_PER_CPU		0x00010000	/* IRQ is per CPU */
#define IRQ_NOPROBE		0x00020000	/* IRQ is not valid for probing */
#define IRQ_NOREQUEST		0x00040000	/* IRQ cannot be requested */
#define IRQ_NOAUTOEN		0x00080000	/* IRQ will not be enabled on request irq */
62 63 64
#define IRQ_WAKEUP		0x00100000	/* IRQ triggers system wakeup */
#define IRQ_MOVE_PENDING	0x00200000	/* need to re-target IRQ destination */
#define IRQ_NO_BALANCING	0x00400000	/* IRQ is excluded from balancing */
65
#define IRQ_SPURIOUS_DISABLED	0x00800000	/* IRQ was disabled by the spurious trap */
66 67
#define IRQ_MOVE_PCNTXT		0x01000000	/* IRQ migration from process context */
#define IRQ_AFFINITY_SET	0x02000000	/* IRQ affinity was set from userspace*/
68

69
#ifdef CONFIG_IRQ_PER_CPU
70
# define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU)
71
# define IRQ_NO_BALANCING_MASK	(IRQ_PER_CPU | IRQ_NO_BALANCING)
72 73
#else
# define CHECK_IRQ_PER_CPU(var) 0
74
# define IRQ_NO_BALANCING_MASK	IRQ_NO_BALANCING
75
#endif
L
Linus Torvalds 已提交
76

T
Thomas Gleixner 已提交
77
struct proc_dir_entry;
78
struct msi_desc;
T
Thomas Gleixner 已提交
79

80
/**
T
Thomas Gleixner 已提交
81
 * struct irq_chip - hardware interrupt chip descriptor
82 83 84 85 86 87 88 89 90 91
 *
 * @name:		name for /proc/interrupts
 * @startup:		start up the interrupt (defaults to ->enable if NULL)
 * @shutdown:		shut down the interrupt (defaults to ->disable if NULL)
 * @enable:		enable the interrupt (defaults to chip->unmask if NULL)
 * @disable:		disable the interrupt (defaults to chip->mask if NULL)
 * @ack:		start of a new interrupt
 * @mask:		mask an interrupt source
 * @mask_ack:		ack and mask an interrupt source
 * @unmask:		unmask an interrupt source
92 93
 * @eoi:		end of interrupt - chip level
 * @end:		end of interrupt - flow level
94 95 96 97 98 99
 * @set_affinity:	set the CPU affinity on SMP machines
 * @retrigger:		resend an IRQ to the CPU
 * @set_type:		set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ
 * @set_wake:		enable/disable power-management wake-on of an IRQ
 *
 * @release:		release function solely used by UML
T
Thomas Gleixner 已提交
100
 * @typename:		obsoleted by name, kept as migration helper
L
Linus Torvalds 已提交
101
 */
T
Thomas Gleixner 已提交
102 103
struct irq_chip {
	const char	*name;
104 105 106 107
	unsigned int	(*startup)(unsigned int irq);
	void		(*shutdown)(unsigned int irq);
	void		(*enable)(unsigned int irq);
	void		(*disable)(unsigned int irq);
T
Thomas Gleixner 已提交
108

109
	void		(*ack)(unsigned int irq);
T
Thomas Gleixner 已提交
110 111 112
	void		(*mask)(unsigned int irq);
	void		(*mask_ack)(unsigned int irq);
	void		(*unmask)(unsigned int irq);
113
	void		(*eoi)(unsigned int irq);
T
Thomas Gleixner 已提交
114

115
	void		(*end)(unsigned int irq);
116 117
	void		(*set_affinity)(unsigned int irq,
					const struct cpumask *dest);
118
	int		(*retrigger)(unsigned int irq);
T
Thomas Gleixner 已提交
119 120
	int		(*set_type)(unsigned int irq, unsigned int flow_type);
	int		(*set_wake)(unsigned int irq, unsigned int on);
121

122 123
	/* Currently used only by UML, might disappear one day.*/
#ifdef CONFIG_IRQ_RELEASE_METHOD
124
	void		(*release)(unsigned int irq, void *dev_id);
125
#endif
T
Thomas Gleixner 已提交
126 127 128 129 130
	/*
	 * For compatibility, ->typename is copied into ->name.
	 * Will disappear.
	 */
	const char	*typename;
L
Linus Torvalds 已提交
131 132
};

133 134
struct timer_rand_state;
struct irq_2_iommu;
135 136
/**
 * struct irq_desc - interrupt descriptor
R
Randy Dunlap 已提交
137
 * @irq:		interrupt number for this descriptor
138 139 140
 * @timer_rand_state:	pointer to timer rand state struct
 * @kstat_irqs:		irq stats per cpu
 * @irq_2_iommu:	iommu with this irq
T
Thomas Gleixner 已提交
141 142
 * @handle_irq:		highlevel irq-events handler [if NULL, __do_IRQ()]
 * @chip:		low level interrupt hardware access
R
Randy Dunlap 已提交
143
 * @msi_desc:		MSI descriptor
T
Thomas Gleixner 已提交
144 145 146
 * @handler_data:	per-IRQ data for the irq_chip methods
 * @chip_data:		platform-specific per-chip private data for the chip
 *			methods, to allow shared chip implementations
147 148 149
 * @action:		the irq action chain
 * @status:		status information
 * @depth:		disable-depth, for nested irq_disable() calls
150
 * @wake_depth:		enable depth, for multiple set_irq_wake() callers
151
 * @irq_count:		stats field to detect stalled irqs
R
Randy Dunlap 已提交
152
 * @last_unhandled:	aging timer for unhandled count
153
 * @irqs_unhandled:	stats field for spurious unhandled interrupts
154 155
 * @lock:		locking for SMP
 * @affinity:		IRQ affinity on SMP
T
Thomas Gleixner 已提交
156
 * @cpu:		cpu index useful for balancing
157 158
 * @pending_mask:	pending rebalanced interrupts
 * @dir:		/proc/irq/ procfs entry
159
 * @name:		flow handler name for /proc/interrupts output
L
Linus Torvalds 已提交
160
 */
161
struct irq_desc {
162
	unsigned int		irq;
163 164
	struct timer_rand_state *timer_rand_state;
	unsigned int            *kstat_irqs;
165
#ifdef CONFIG_INTR_REMAP
166 167
	struct irq_2_iommu      *irq_2_iommu;
#endif
168
	irq_flow_handler_t	handle_irq;
T
Thomas Gleixner 已提交
169
	struct irq_chip		*chip;
170
	struct msi_desc		*msi_desc;
T
Thomas Gleixner 已提交
171
	void			*handler_data;
172 173 174
	void			*chip_data;
	struct irqaction	*action;	/* IRQ action list */
	unsigned int		status;		/* IRQ status */
T
Thomas Gleixner 已提交
175

176
	unsigned int		depth;		/* nested irq disables */
177
	unsigned int		wake_depth;	/* nested wake enables */
178
	unsigned int		irq_count;	/* For detecting broken IRQs */
179
	unsigned long		last_unhandled;	/* Aging timer for unhandled count */
180
	unsigned int		irqs_unhandled;
181
	spinlock_t		lock;
182
#ifdef CONFIG_SMP
183
	cpumask_var_t		affinity;
T
Thomas Gleixner 已提交
184
	unsigned int		cpu;
185
#ifdef CONFIG_GENERIC_PENDING_IRQ
186 187
	cpumask_var_t		pending_mask;
#endif
188
#endif
189
#ifdef CONFIG_PROC_FS
190
	struct proc_dir_entry	*dir;
191
#endif
192
	const char		*name;
193
} ____cacheline_internodealigned_in_smp;
L
Linus Torvalds 已提交
194

195 196 197
extern void arch_init_copy_chip_data(struct irq_desc *old_desc,
					struct irq_desc *desc, int cpu);
extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);
Y
Yinghai Lu 已提交
198

199
#ifndef CONFIG_SPARSE_IRQ
200
extern struct irq_desc irq_desc[NR_IRQS];
201
#else /* CONFIG_SPARSE_IRQ */
202
extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int cpu);
203
#endif /* CONFIG_SPARSE_IRQ */
204

205
extern struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu);
206

207 208 209 210 211 212 213 214
static inline struct irq_desc *
irq_remap_to_desc(unsigned int irq, struct irq_desc *desc)
{
#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC
	return irq_to_desc(irq);
#else
	return desc;
#endif
215 216
}

217 218 219
/*
 * Migration helpers for obsolete names, they will go away:
 */
T
Thomas Gleixner 已提交
220 221
#define hw_interrupt_type	irq_chip
#define no_irq_type		no_irq_chip
222 223 224 225 226 227
typedef struct irq_desc		irq_desc_t;

/*
 * Pick up the arch-dependent methods:
 */
#include <asm/hw_irq.h>
L
Linus Torvalds 已提交
228

229
extern int setup_irq(unsigned int irq, struct irqaction *new);
230
extern void remove_irq(unsigned int irq, struct irqaction *act);
L
Linus Torvalds 已提交
231 232

#ifdef CONFIG_GENERIC_HARDIRQS
233

234 235
#ifdef CONFIG_SMP

236
#ifdef CONFIG_GENERIC_PENDING_IRQ
237

238
void move_native_irq(int irq);
239
void move_masked_irq(int irq);
240

241
#else /* CONFIG_GENERIC_PENDING_IRQ */
242 243 244 245 246 247 248 249 250

static inline void move_irq(int irq)
{
}

static inline void move_native_irq(int irq)
{
}

251 252 253 254
static inline void move_masked_irq(int irq)
{
}

255
#endif /* CONFIG_GENERIC_PENDING_IRQ */
256

257
#else /* CONFIG_SMP */
258 259

#define move_native_irq(x)
260
#define move_masked_irq(x)
261

262
#endif /* CONFIG_SMP */
263

L
Linus Torvalds 已提交
264 265
extern int no_irq_affinity;

266 267
static inline int irq_balancing_disabled(unsigned int irq)
{
268 269 270 271
	struct irq_desc *desc;

	desc = irq_to_desc(irq);
	return desc->status & IRQ_NO_BALANCING_MASK;
272 273
}

T
Thomas Gleixner 已提交
274
/* Handle irq action chains: */
275
extern irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action);
T
Thomas Gleixner 已提交
276 277 278 279 280

/*
 * Built-in IRQ handlers for various IRQ types,
 * callable via desc->chip->handle_irq()
 */
281 282 283 284 285 286
extern void handle_level_irq(unsigned int irq, struct irq_desc *desc);
extern void handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc);
extern void handle_edge_irq(unsigned int irq, struct irq_desc *desc);
extern void handle_simple_irq(unsigned int irq, struct irq_desc *desc);
extern void handle_percpu_irq(unsigned int irq, struct irq_desc *desc);
extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc);
T
Thomas Gleixner 已提交
287

288
/*
T
Thomas Gleixner 已提交
289
 * Monolithic do_IRQ implementation.
290
 */
291
#ifndef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ
292
extern unsigned int __do_IRQ(unsigned int irq);
293
#endif
294

I
Ingo Molnar 已提交
295 296 297 298 299 300
/*
 * Architectures call this to let the generic IRQ layer
 * handle an interrupt. If the descriptor is attached to an
 * irqchip-style controller then we call the ->handle_irq() handler,
 * and it calls __do_IRQ() if it's attached to an irqtype-style controller.
 */
301
static inline void generic_handle_irq_desc(unsigned int irq, struct irq_desc *desc)
I
Ingo Molnar 已提交
302
{
303
#ifdef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ
304
	desc->handle_irq(irq, desc);
305
#else
I
Ingo Molnar 已提交
306
	if (likely(desc->handle_irq))
307
		desc->handle_irq(irq, desc);
I
Ingo Molnar 已提交
308
	else
309
		__do_IRQ(irq);
310
#endif
I
Ingo Molnar 已提交
311 312
}

313 314 315 316 317
static inline void generic_handle_irq(unsigned int irq)
{
	generic_handle_irq_desc(irq, irq_to_desc(irq));
}

T
Thomas Gleixner 已提交
318
/* Handling of unhandled and spurious interrupts: */
319
extern void note_interrupt(unsigned int irq, struct irq_desc *desc,
320
			   irqreturn_t action_ret);
L
Linus Torvalds 已提交
321

322 323 324
/* Resending of interrupts :*/
void check_irq_resend(struct irq_desc *desc, unsigned int irq);

T
Thomas Gleixner 已提交
325 326 327 328 329 330
/* Enable/disable irq debugging output: */
extern int noirqdebug_setup(char *str);

/* Checks whether the interrupt can be requested by request_irq(): */
extern int can_request_irq(unsigned int irq, unsigned long irqflags);

331
/* Dummy irq-chip implementations: */
T
Thomas Gleixner 已提交
332
extern struct irq_chip no_irq_chip;
333
extern struct irq_chip dummy_irq_chip;
T
Thomas Gleixner 已提交
334

335 336 337
extern void
set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip,
			 irq_flow_handler_t handle);
T
Thomas Gleixner 已提交
338
extern void
339 340 341
set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
			      irq_flow_handler_t handle, const char *name);

T
Thomas Gleixner 已提交
342
extern void
343 344
__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
		  const char *name);
L
Linus Torvalds 已提交
345

346 347 348 349
/* caller has locked the irq_desc and both params are valid */
static inline void __set_irq_handler_unlocked(int irq,
					      irq_flow_handler_t handler)
{
350 351 352 353
	struct irq_desc *desc;

	desc = irq_to_desc(irq);
	desc->handle_irq = handler;
354 355
}

T
Thomas Gleixner 已提交
356 357 358 359
/*
 * Set a highlevel flow handler for a given IRQ:
 */
static inline void
360
set_irq_handler(unsigned int irq, irq_flow_handler_t handle)
T
Thomas Gleixner 已提交
361
{
362
	__set_irq_handler(irq, handle, 0, NULL);
T
Thomas Gleixner 已提交
363 364 365 366 367 368 369 370 371
}

/*
 * Set a highlevel chained flow handler for a given IRQ.
 * (a chained handler is automatically enabled and set to
 *  IRQ_NOREQUEST and IRQ_NOPROBE)
 */
static inline void
set_irq_chained_handler(unsigned int irq,
372
			irq_flow_handler_t handle)
T
Thomas Gleixner 已提交
373
{
374
	__set_irq_handler(irq, handle, 1, NULL);
T
Thomas Gleixner 已提交
375 376
}

R
Ralf Baechle 已提交
377 378 379
extern void set_irq_noprobe(unsigned int irq);
extern void set_irq_probe(unsigned int irq);

380
/* Handle dynamic irq creation and destruction */
381
extern unsigned int create_irq_nr(unsigned int irq_want);
382 383 384
extern int create_irq(void);
extern void destroy_irq(unsigned int irq);

385 386 387
/* Test to see if a driver has successfully requested an irq */
static inline int irq_has_action(unsigned int irq)
{
388
	struct irq_desc *desc = irq_to_desc(irq);
389 390 391
	return desc->action != NULL;
}

392 393 394
/* Dynamic irq helper functions */
extern void dynamic_irq_init(unsigned int irq);
extern void dynamic_irq_cleanup(unsigned int irq);
395

396
/* Set/get chip/data for an IRQ: */
397 398 399 400
extern int set_irq_chip(unsigned int irq, struct irq_chip *chip);
extern int set_irq_data(unsigned int irq, void *data);
extern int set_irq_chip_data(unsigned int irq, void *data);
extern int set_irq_type(unsigned int irq, unsigned int type);
401
extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
402

403 404 405 406
#define get_irq_chip(irq)	(irq_to_desc(irq)->chip)
#define get_irq_chip_data(irq)	(irq_to_desc(irq)->chip_data)
#define get_irq_data(irq)	(irq_to_desc(irq)->handler_data)
#define get_irq_msi(irq)	(irq_to_desc(irq)->msi_desc)
407

408 409 410 411 412
#define get_irq_desc_chip(desc)		((desc)->chip)
#define get_irq_desc_chip_data(desc)	((desc)->chip_data)
#define get_irq_desc_data(desc)		((desc)->handler_data)
#define get_irq_desc_msi(desc)		((desc)->msi_desc)

T
Thomas Gleixner 已提交
413
#endif /* CONFIG_GENERIC_HARDIRQS */
L
Linus Torvalds 已提交
414

415
#endif /* !CONFIG_S390 */
L
Linus Torvalds 已提交
416

417 418 419 420
#ifdef CONFIG_SMP
/**
 * init_alloc_desc_masks - allocate cpumasks for irq_desc
 * @desc:	pointer to irq_desc struct
421
 * @cpu:	cpu which will be handling the cpumasks
422 423 424 425 426 427
 * @boot:	true if need bootmem
 *
 * Allocates affinity and pending_mask cpumask if required.
 * Returns true if successful (or not required).
 * Side effect: affinity has all bits set, pending_mask has all bits clear.
 */
428
static inline bool init_alloc_desc_masks(struct irq_desc *desc, int cpu,
429 430
								bool boot)
{
431 432
	int node;

433 434 435 436 437 438 439 440 441 442 443
	if (boot) {
		alloc_bootmem_cpumask_var(&desc->affinity);
		cpumask_setall(desc->affinity);

#ifdef CONFIG_GENERIC_PENDING_IRQ
		alloc_bootmem_cpumask_var(&desc->pending_mask);
		cpumask_clear(desc->pending_mask);
#endif
		return true;
	}

444 445
	node = cpu_to_node(cpu);

446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
	if (!alloc_cpumask_var_node(&desc->affinity, GFP_ATOMIC, node))
		return false;
	cpumask_setall(desc->affinity);

#ifdef CONFIG_GENERIC_PENDING_IRQ
	if (!alloc_cpumask_var_node(&desc->pending_mask, GFP_ATOMIC, node)) {
		free_cpumask_var(desc->affinity);
		return false;
	}
	cpumask_clear(desc->pending_mask);
#endif
	return true;
}

/**
 * init_copy_desc_masks - copy cpumasks for irq_desc
 * @old_desc:	pointer to old irq_desc struct
 * @new_desc:	pointer to new irq_desc struct
 *
 * Insures affinity and pending_masks are copied to new irq_desc.
 * If !CONFIG_CPUMASKS_OFFSTACK the cpumasks are embedded in the
 * irq_desc struct so the copy is redundant.
 */

static inline void init_copy_desc_masks(struct irq_desc *old_desc,
					struct irq_desc *new_desc)
{
#ifdef CONFIG_CPUMASKS_OFFSTACK
	cpumask_copy(new_desc->affinity, old_desc->affinity);

#ifdef CONFIG_GENERIC_PENDING_IRQ
	cpumask_copy(new_desc->pending_mask, old_desc->pending_mask);
#endif
#endif
}

#else /* !CONFIG_SMP */

484
static inline bool init_alloc_desc_masks(struct irq_desc *desc, int cpu,
485 486 487 488 489 490 491 492 493 494 495 496
								bool boot)
{
	return true;
}

static inline void init_copy_desc_masks(struct irq_desc *old_desc,
					struct irq_desc *new_desc)
{
}

#endif	/* CONFIG_SMP */

497
#endif /* _LINUX_IRQ_H */