irqdesc.h 5.6 KB
Newer Older
T
Thomas Gleixner 已提交
1 2 3 4 5 6 7 8 9 10
#ifndef _LINUX_IRQDESC_H
#define _LINUX_IRQDESC_H

/*
 * Core internal functions to deal with irq descriptors
 *
 * This include will move to kernel/irq once we cleaned up the tree.
 * For now it's included from <linux/irq.h>
 */

11
struct irq_affinity_notify;
T
Thomas Gleixner 已提交
12 13 14 15 16 17 18 19 20 21
struct proc_dir_entry;
struct timer_rand_state;
/**
 * struct irq_desc - interrupt descriptor
 * @irq_data:		per irq and chip data passed down to chip functions
 * @timer_rand_state:	pointer to timer rand state struct
 * @kstat_irqs:		irq stats per cpu
 * @handle_irq:		highlevel irq-events handler [if NULL, __do_IRQ()]
 * @action:		the irq action chain
 * @status:		status information
22
 * @core_internal_state__do_not_mess_with_it: core internal status information
T
Thomas Gleixner 已提交
23 24 25 26 27 28
 * @depth:		disable-depth, for nested irq_disable() calls
 * @wake_depth:		enable depth, for multiple set_irq_wake() callers
 * @irq_count:		stats field to detect stalled irqs
 * @last_unhandled:	aging timer for unhandled count
 * @irqs_unhandled:	stats field for spurious unhandled interrupts
 * @lock:		locking for SMP
29
 * @affinity_notify:	context for notification of affinity changes
T
Thomas Gleixner 已提交
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
 * @pending_mask:	pending rebalanced interrupts
 * @threads_active:	number of irqaction threads currently running
 * @wait_for_threads:	wait queue for sync_irq to wait for threaded handlers
 * @dir:		/proc/irq/ procfs entry
 * @name:		flow handler name for /proc/interrupts output
 */
struct irq_desc {

#ifdef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED
	struct irq_data		irq_data;
#else
	/*
	 * This union will go away, once we fixed the direct access to
	 * irq_desc all over the place. The direct fields are a 1:1
	 * overlay of irq_data.
	 */
	union {
		struct irq_data		irq_data;
		struct {
			unsigned int		irq;
			unsigned int		node;
51
			unsigned int		pad_do_not_even_think_about_it;
T
Thomas Gleixner 已提交
52 53 54 55 56 57 58 59 60 61 62 63
			struct irq_chip		*chip;
			void			*handler_data;
			void			*chip_data;
			struct msi_desc		*msi_desc;
#ifdef CONFIG_SMP
			cpumask_var_t		affinity;
#endif
		};
	};
#endif

	struct timer_rand_state *timer_rand_state;
E
Eric Dumazet 已提交
64
	unsigned int __percpu	*kstat_irqs;
T
Thomas Gleixner 已提交
65
	irq_flow_handler_t	handle_irq;
66 67 68
#ifdef CONFIG_IRQ_PREFLOW_FASTEOI
	irq_preflow_handler_t	preflow_handler;
#endif
T
Thomas Gleixner 已提交
69
	struct irqaction	*action;	/* IRQ action list */
70 71 72
#ifdef CONFIG_GENERIC_HARDIRQS_NO_COMPAT
	unsigned int		status_use_accessors;
#else
T
Thomas Gleixner 已提交
73
	unsigned int		status;		/* IRQ status */
74
#endif
75
	unsigned int		core_internal_state__do_not_mess_with_it;
T
Thomas Gleixner 已提交
76 77 78 79 80 81 82 83
	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;
	raw_spinlock_t		lock;
#ifdef CONFIG_SMP
	const struct cpumask	*affinity_hint;
84
	struct irq_affinity_notify *affinity_notify;
T
Thomas Gleixner 已提交
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
#ifdef CONFIG_GENERIC_PENDING_IRQ
	cpumask_var_t		pending_mask;
#endif
#endif
	atomic_t		threads_active;
	wait_queue_head_t       wait_for_threads;
#ifdef CONFIG_PROC_FS
	struct proc_dir_entry	*dir;
#endif
	const char		*name;
} ____cacheline_internodealigned_in_smp;

#ifndef CONFIG_SPARSE_IRQ
extern struct irq_desc irq_desc[NR_IRQS];
#endif

101 102
/* Will be removed once the last users in power and sh are gone */
extern struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node);
T
Thomas Gleixner 已提交
103 104 105 106 107 108 109
static inline struct irq_desc *move_irq_desc(struct irq_desc *desc, int node)
{
	return desc;
}

#ifdef CONFIG_GENERIC_HARDIRQS

T
Thomas Gleixner 已提交
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
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)
{
	return desc->irq_data.handler_data;
}

static inline struct msi_desc *irq_desc_get_msi_desc(struct irq_desc *desc)
{
	return desc->irq_data.msi_desc;
}

#ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT
static inline struct irq_chip *get_irq_desc_chip(struct irq_desc *desc)
{
	return irq_desc_get_chip(desc);
}
static inline void *get_irq_desc_data(struct irq_desc *desc)
{
	return irq_desc_get_handler_data(desc);
}

static inline void *get_irq_desc_chip_data(struct irq_desc *desc)
{
	return irq_desc_get_chip_data(desc);
}

static inline struct msi_desc *get_irq_desc_msi(struct irq_desc *desc)
{
	return irq_desc_get_msi_desc(desc);
}
#endif
T
Thomas Gleixner 已提交
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173

/*
 * 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.
 */
static inline void generic_handle_irq_desc(unsigned int irq, struct irq_desc *desc)
{
	desc->handle_irq(irq, desc);
}

static inline void generic_handle_irq(unsigned int irq)
{
	generic_handle_irq_desc(irq, irq_to_desc(irq));
}

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

174
#ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT
T
Thomas Gleixner 已提交
175 176 177 178 179 180 181
static inline int irq_balancing_disabled(unsigned int irq)
{
	struct irq_desc *desc;

	desc = irq_to_desc(irq);
	return desc->status & IRQ_NO_BALANCING_MASK;
}
182
#endif
T
Thomas Gleixner 已提交
183 184 185 186 187 188 189 190 191 192

/* 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)
{
	struct irq_desc *desc;

	desc = irq_to_desc(irq);
	desc->handle_irq = handler;
}
193 194 195 196 197 198 199 200 201 202 203

#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 已提交
204 205 206
#endif

#endif