Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: genirq: Add IRQF_RESUME_EARLY and resume such IRQs earlier genirq: Fix fatfinered fixup really genirq: percpu: allow interrupt type to be set at enable time genirq: Add support for per-cpu dev_id interrupts genirq: Add IRQCHIP_SKIP_SET_WAKE flag
This commit is contained in:
+30
-11
@@ -59,6 +59,8 @@
|
||||
* IRQF_NO_SUSPEND - Do not disable this IRQ during suspend
|
||||
* IRQF_FORCE_RESUME - Force enable it on resume even if IRQF_NO_SUSPEND is set
|
||||
* IRQF_NO_THREAD - Interrupt cannot be threaded
|
||||
* IRQF_EARLY_RESUME - Resume IRQ early during syscore instead of at device
|
||||
* resume time.
|
||||
*/
|
||||
#define IRQF_DISABLED 0x00000020
|
||||
#define IRQF_SAMPLE_RANDOM 0x00000040
|
||||
@@ -72,6 +74,7 @@
|
||||
#define IRQF_NO_SUSPEND 0x00004000
|
||||
#define IRQF_FORCE_RESUME 0x00008000
|
||||
#define IRQF_NO_THREAD 0x00010000
|
||||
#define IRQF_EARLY_RESUME 0x00020000
|
||||
|
||||
#define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD)
|
||||
|
||||
@@ -95,6 +98,7 @@ typedef irqreturn_t (*irq_handler_t)(int, void *);
|
||||
* @flags: flags (see IRQF_* above)
|
||||
* @name: name of the device
|
||||
* @dev_id: cookie to identify the device
|
||||
* @percpu_dev_id: cookie to identify the device
|
||||
* @next: pointer to the next irqaction for shared interrupts
|
||||
* @irq: interrupt number
|
||||
* @dir: pointer to the proc/irq/NN/name entry
|
||||
@@ -104,17 +108,18 @@ typedef irqreturn_t (*irq_handler_t)(int, void *);
|
||||
* @thread_mask: bitmask for keeping track of @thread activity
|
||||
*/
|
||||
struct irqaction {
|
||||
irq_handler_t handler;
|
||||
unsigned long flags;
|
||||
void *dev_id;
|
||||
struct irqaction *next;
|
||||
int irq;
|
||||
irq_handler_t thread_fn;
|
||||
struct task_struct *thread;
|
||||
unsigned long thread_flags;
|
||||
unsigned long thread_mask;
|
||||
const char *name;
|
||||
struct proc_dir_entry *dir;
|
||||
irq_handler_t handler;
|
||||
unsigned long flags;
|
||||
void *dev_id;
|
||||
void __percpu *percpu_dev_id;
|
||||
struct irqaction *next;
|
||||
int irq;
|
||||
irq_handler_t thread_fn;
|
||||
struct task_struct *thread;
|
||||
unsigned long thread_flags;
|
||||
unsigned long thread_mask;
|
||||
const char *name;
|
||||
struct proc_dir_entry *dir;
|
||||
} ____cacheline_internodealigned_in_smp;
|
||||
|
||||
extern irqreturn_t no_action(int cpl, void *dev_id);
|
||||
@@ -136,6 +141,10 @@ extern int __must_check
|
||||
request_any_context_irq(unsigned int irq, irq_handler_t handler,
|
||||
unsigned long flags, const char *name, void *dev_id);
|
||||
|
||||
extern int __must_check
|
||||
request_percpu_irq(unsigned int irq, irq_handler_t handler,
|
||||
const char *devname, void __percpu *percpu_dev_id);
|
||||
|
||||
extern void exit_irq_thread(void);
|
||||
#else
|
||||
|
||||
@@ -164,10 +173,18 @@ request_any_context_irq(unsigned int irq, irq_handler_t handler,
|
||||
return request_irq(irq, handler, flags, name, dev_id);
|
||||
}
|
||||
|
||||
static inline int __must_check
|
||||
request_percpu_irq(unsigned int irq, irq_handler_t handler,
|
||||
const char *devname, void __percpu *percpu_dev_id)
|
||||
{
|
||||
return request_irq(irq, handler, 0, devname, percpu_dev_id);
|
||||
}
|
||||
|
||||
static inline void exit_irq_thread(void) { }
|
||||
#endif
|
||||
|
||||
extern void free_irq(unsigned int, void *);
|
||||
extern void free_percpu_irq(unsigned int, void __percpu *);
|
||||
|
||||
struct device;
|
||||
|
||||
@@ -207,7 +224,9 @@ extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);
|
||||
|
||||
extern void disable_irq_nosync(unsigned int irq);
|
||||
extern void disable_irq(unsigned int irq);
|
||||
extern void disable_percpu_irq(unsigned int irq);
|
||||
extern void enable_irq(unsigned int irq);
|
||||
extern void enable_percpu_irq(unsigned int irq, unsigned int type);
|
||||
|
||||
/* The following three functions are for the core kernel use only. */
|
||||
#ifdef CONFIG_GENERIC_HARDIRQS
|
||||
|
||||
+17
-1
@@ -66,6 +66,7 @@ typedef void (*irq_preflow_handler_t)(struct irq_data *data);
|
||||
* IRQ_NO_BALANCING - Interrupt cannot be balanced (affinity set)
|
||||
* IRQ_MOVE_PCNTXT - Interrupt can be migrated from process context
|
||||
* IRQ_NESTED_TRHEAD - Interrupt nests into another thread
|
||||
* IRQ_PER_CPU_DEVID - Dev_id is a per-cpu variable
|
||||
*/
|
||||
enum {
|
||||
IRQ_TYPE_NONE = 0x00000000,
|
||||
@@ -88,12 +89,13 @@ enum {
|
||||
IRQ_MOVE_PCNTXT = (1 << 14),
|
||||
IRQ_NESTED_THREAD = (1 << 15),
|
||||
IRQ_NOTHREAD = (1 << 16),
|
||||
IRQ_PER_CPU_DEVID = (1 << 17),
|
||||
};
|
||||
|
||||
#define IRQF_MODIFY_MASK \
|
||||
(IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \
|
||||
IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_NO_BALANCING | \
|
||||
IRQ_PER_CPU | IRQ_NESTED_THREAD)
|
||||
IRQ_PER_CPU | IRQ_NESTED_THREAD | IRQ_NOTHREAD | IRQ_PER_CPU_DEVID)
|
||||
|
||||
#define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING)
|
||||
|
||||
@@ -336,12 +338,14 @@ struct irq_chip {
|
||||
* IRQCHIP_MASK_ON_SUSPEND: Mask non wake irqs in the suspend path
|
||||
* IRQCHIP_ONOFFLINE_ENABLED: Only call irq_on/off_line callbacks
|
||||
* when irq enabled
|
||||
* IRQCHIP_SKIP_SET_WAKE: Skip chip.irq_set_wake(), for this irq chip
|
||||
*/
|
||||
enum {
|
||||
IRQCHIP_SET_TYPE_MASKED = (1 << 0),
|
||||
IRQCHIP_EOI_IF_HANDLED = (1 << 1),
|
||||
IRQCHIP_MASK_ON_SUSPEND = (1 << 2),
|
||||
IRQCHIP_ONOFFLINE_ENABLED = (1 << 3),
|
||||
IRQCHIP_SKIP_SET_WAKE = (1 << 4),
|
||||
};
|
||||
|
||||
/* This include will go away once we isolated irq_desc usage to core code */
|
||||
@@ -365,6 +369,8 @@ enum {
|
||||
struct irqaction;
|
||||
extern int setup_irq(unsigned int irq, struct irqaction *new);
|
||||
extern void remove_irq(unsigned int irq, struct irqaction *act);
|
||||
extern int setup_percpu_irq(unsigned int irq, struct irqaction *new);
|
||||
extern void remove_percpu_irq(unsigned int irq, struct irqaction *act);
|
||||
|
||||
extern void irq_cpu_online(void);
|
||||
extern void irq_cpu_offline(void);
|
||||
@@ -392,6 +398,7 @@ extern void handle_edge_irq(unsigned int irq, struct irq_desc *desc);
|
||||
extern void handle_edge_eoi_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_percpu_devid_irq(unsigned int irq, struct irq_desc *desc);
|
||||
extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc);
|
||||
extern void handle_nested_irq(unsigned int irq);
|
||||
|
||||
@@ -420,6 +427,8 @@ static inline void irq_set_chip_and_handler(unsigned int irq, struct irq_chip *c
|
||||
irq_set_chip_and_handler_name(irq, chip, handle, NULL);
|
||||
}
|
||||
|
||||
extern int irq_set_percpu_devid(unsigned int irq);
|
||||
|
||||
extern void
|
||||
__irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
|
||||
const char *name);
|
||||
@@ -481,6 +490,13 @@ static inline void irq_set_nested_thread(unsigned int irq, bool nest)
|
||||
irq_clear_status_flags(irq, IRQ_NESTED_THREAD);
|
||||
}
|
||||
|
||||
static inline void irq_set_percpu_devid_flags(unsigned int irq)
|
||||
{
|
||||
irq_set_status_flags(irq,
|
||||
IRQ_NOAUTOEN | IRQ_PER_CPU | IRQ_NOTHREAD |
|
||||
IRQ_NOPROBE | IRQ_PER_CPU_DEVID);
|
||||
}
|
||||
|
||||
/* Handle dynamic irq creation and destruction */
|
||||
extern unsigned int create_irq_nr(unsigned int irq_want, int node);
|
||||
extern int create_irq(void);
|
||||
|
||||
@@ -53,6 +53,7 @@ struct irq_desc {
|
||||
unsigned long last_unhandled; /* Aging timer for unhandled count */
|
||||
unsigned int irqs_unhandled;
|
||||
raw_spinlock_t lock;
|
||||
struct cpumask *percpu_enabled;
|
||||
#ifdef CONFIG_SMP
|
||||
const struct cpumask *affinity_hint;
|
||||
struct irq_affinity_notify *affinity_notify;
|
||||
|
||||
Reference in New Issue
Block a user