2005-04-16 15:20:36 -07:00
/*
* IRQ subsystem internal functions and variables :
2011-02-07 20:19:55 +01:00
*
* Do not ever include this file from anything else than
* kernel / irq / . Do not even think about using any information outside
* of this file for your non core code .
2005-04-16 15:20:36 -07:00
*/
2010-10-01 16:03:45 +02:00
# include <linux/irqdesc.h>
2005-04-16 15:20:36 -07:00
2011-02-17 17:45:15 +01:00
# ifdef CONFIG_SPARSE_IRQ
# define IRQ_BITMAP_BITS (NR_IRQS + 8196)
# else
# define IRQ_BITMAP_BITS NR_IRQS
# endif
2011-02-07 21:48:49 +01:00
# include "compat.h"
2011-02-09 13:16:52 +01:00
# include "settings.h"
2011-02-07 20:19:55 +01:00
# define istate core_internal_state__do_not_mess_with_it
2005-04-16 15:20:36 -07:00
extern int noirqdebug ;
2011-02-07 01:55:43 +01:00
/*
* Bits used by threaded handlers :
* IRQTF_RUNTHREAD - signals that the interrupt handler thread should run
* IRQTF_DIED - handler thread died
* IRQTF_WARNED - warning " IRQ_WAKE_THREAD w/o thread_fn " has been printed
* IRQTF_AFFINITY - irq thread is requested to adjust affinity
*/
enum {
IRQTF_RUNTHREAD ,
IRQTF_DIED ,
IRQTF_WARNED ,
IRQTF_AFFINITY ,
} ;
2011-02-07 20:25:25 +01:00
/*
* Bit masks for desc - > state
*
* IRQS_AUTODETECT - autodetection in progress
2011-02-07 20:40:54 +01:00
* IRQS_SPURIOUS_DISABLED - was disabled due to spurious interrupt
* detection
2011-02-07 20:55:35 +01:00
* IRQS_POLL_INPROGRESS - polling in progress
2011-02-07 21:48:49 +01:00
* IRQS_INPROGRESS - Interrupt in progress
2011-02-07 21:02:10 +01:00
* IRQS_ONESHOT - irq is not unmasked in primary handler
2011-02-08 11:39:15 +01:00
* IRQS_REPLAY - irq is replayed
* IRQS_WAITING - irq is waiting
2011-02-07 22:11:30 +01:00
* IRQS_DISABLED - irq is disabled
2011-02-08 12:17:57 +01:00
* IRQS_PENDING - irq is pending and replayed later
2011-02-07 20:25:25 +01:00
*/
enum {
IRQS_AUTODETECT = 0x00000001 ,
2011-02-07 20:40:54 +01:00
IRQS_SPURIOUS_DISABLED = 0x00000002 ,
2011-02-07 20:55:35 +01:00
IRQS_POLL_INPROGRESS = 0x00000008 ,
2011-02-07 21:48:49 +01:00
IRQS_INPROGRESS = 0x00000010 ,
2011-02-07 21:02:10 +01:00
IRQS_ONESHOT = 0x00000020 ,
2011-02-08 11:39:15 +01:00
IRQS_REPLAY = 0x00000040 ,
IRQS_WAITING = 0x00000080 ,
2011-02-07 22:11:30 +01:00
IRQS_DISABLED = 0x00000100 ,
2011-02-08 12:17:57 +01:00
IRQS_PENDING = 0x00000200 ,
2011-02-07 20:25:25 +01:00
} ;
2010-10-01 14:44:58 +02:00
# define irq_data_to_desc(data) container_of(data, struct irq_desc, irq_data)
2006-06-29 02:24:51 -07:00
/* Set default functions for irq_chip structures: */
extern void irq_chip_set_defaults ( struct irq_chip * chip ) ;
/* Set default handler: */
extern void compat_irq_chip_set_default_handler ( struct irq_desc * desc ) ;
2008-10-01 14:46:18 -07:00
extern int __irq_set_trigger ( struct irq_desc * desc , unsigned int irq ,
unsigned long flags ) ;
2009-03-16 22:33:49 +01:00
extern void __disable_irq ( struct irq_desc * desc , unsigned int irq , bool susp ) ;
extern void __enable_irq ( struct irq_desc * desc , unsigned int irq , bool resume ) ;
2008-10-01 14:46:18 -07:00
2011-02-02 21:41:14 +00:00
extern int irq_startup ( struct irq_desc * desc ) ;
extern void irq_shutdown ( struct irq_desc * desc ) ;
2011-02-03 12:27:44 +01:00
extern void irq_enable ( struct irq_desc * desc ) ;
extern void irq_disable ( struct irq_desc * desc ) ;
2011-02-02 21:41:14 +00:00
2009-04-27 18:00:38 -07:00
extern void init_kstat_irqs ( struct irq_desc * desc , int node , int nr ) ;
2009-01-10 22:24:06 -08:00
2011-02-07 01:08:49 +01:00
irqreturn_t handle_irq_event_percpu ( struct irq_desc * desc , struct irqaction * action ) ;
irqreturn_t handle_irq_event ( struct irq_desc * desc ) ;
2010-10-01 16:03:45 +02:00
/* Resending of interrupts :*/
void check_irq_resend ( struct irq_desc * desc , unsigned int irq ) ;
2011-02-07 10:34:30 +01:00
bool irq_wait_for_poll ( struct irq_desc * desc ) ;
2010-10-01 16:03:45 +02:00
2005-04-16 15:20:36 -07:00
# ifdef CONFIG_PROC_FS
2008-08-19 20:50:11 -07:00
extern void register_irq_proc ( unsigned int irq , struct irq_desc * desc ) ;
2010-09-30 02:46:07 +02:00
extern void unregister_irq_proc ( unsigned int irq , struct irq_desc * desc ) ;
2005-04-16 15:20:36 -07:00
extern void register_handler_proc ( unsigned int irq , struct irqaction * action ) ;
extern void unregister_handler_proc ( unsigned int irq , struct irqaction * action ) ;
# else
2008-08-19 20:50:11 -07:00
static inline void register_irq_proc ( unsigned int irq , struct irq_desc * desc ) { }
2010-09-30 02:46:07 +02:00
static inline void unregister_irq_proc ( unsigned int irq , struct irq_desc * desc ) { }
2005-04-16 15:20:36 -07:00
static inline void register_handler_proc ( unsigned int irq ,
struct irqaction * action ) { }
static inline void unregister_handler_proc ( unsigned int irq ,
struct irqaction * action ) { }
# endif
2011-02-07 16:02:20 +01:00
extern int irq_select_affinity_usr ( unsigned int irq , struct cpumask * mask ) ;
2008-11-07 13:18:30 +01:00
2009-07-21 11:09:39 +02:00
extern void irq_set_thread_affinity ( struct irq_desc * desc ) ;
2009-04-27 17:59:53 -07:00
2009-08-13 12:17:48 +02:00
/* Inline functions for support of irq chips on slow busses */
2010-09-27 12:44:35 +00:00
static inline void chip_bus_lock ( struct irq_desc * desc )
2009-08-13 12:17:48 +02:00
{
2010-09-27 12:44:35 +00:00
if ( unlikely ( desc - > irq_data . chip - > irq_bus_lock ) )
desc - > irq_data . chip - > irq_bus_lock ( & desc - > irq_data ) ;
2009-08-13 12:17:48 +02:00
}
2010-09-27 12:44:35 +00:00
static inline void chip_bus_sync_unlock ( struct irq_desc * desc )
2009-08-13 12:17:48 +02:00
{
2010-09-27 12:44:35 +00:00
if ( unlikely ( desc - > irq_data . chip - > irq_bus_sync_unlock ) )
desc - > irq_data . chip - > irq_bus_sync_unlock ( & desc - > irq_data ) ;
2009-08-13 12:17:48 +02:00
}
2006-06-29 02:24:58 -07:00
/*
* Debugging printout :
*/
# include <linux/kallsyms.h>
# define P(f) if (desc->status & f) printk("%14s set\n", #f)
2011-02-07 20:25:25 +01:00
# define PS(f) if (desc->istate & f) printk("%14s set\n", #f)
2006-06-29 02:24:58 -07:00
static inline void print_irq_desc ( unsigned int irq , struct irq_desc * desc )
{
printk ( " irq %d, desc: %p, depth: %d, count: %d, unhandled: %d \n " ,
irq , desc , desc - > depth , desc - > irq_count , desc - > irqs_unhandled ) ;
printk ( " ->handle_irq(): %p, " , desc - > handle_irq ) ;
print_symbol ( " %s \n " , ( unsigned long ) desc - > handle_irq ) ;
2010-10-01 12:58:38 +02:00
printk ( " ->irq_data.chip(): %p, " , desc - > irq_data . chip ) ;
print_symbol ( " %s \n " , ( unsigned long ) desc - > irq_data . chip ) ;
2006-06-29 02:24:58 -07:00
printk ( " ->action(): %p \n " , desc - > action ) ;
if ( desc - > action ) {
printk ( " ->action->handler(): %p, " , desc - > action - > handler ) ;
print_symbol ( " %s \n " , ( unsigned long ) desc - > action - > handler ) ;
}
P ( IRQ_LEVEL ) ;
P ( IRQ_MASKED ) ;
# ifdef CONFIG_IRQ_PER_CPU
P ( IRQ_PER_CPU ) ;
# endif
P ( IRQ_NOPROBE ) ;
P ( IRQ_NOREQUEST ) ;
P ( IRQ_NOAUTOEN ) ;
2011-02-07 20:25:25 +01:00
PS ( IRQS_AUTODETECT ) ;
2011-02-07 21:48:49 +01:00
PS ( IRQS_INPROGRESS ) ;
2011-02-08 11:39:15 +01:00
PS ( IRQS_REPLAY ) ;
PS ( IRQS_WAITING ) ;
2011-02-07 22:11:30 +01:00
PS ( IRQS_DISABLED ) ;
2011-02-08 12:17:57 +01:00
PS ( IRQS_PENDING ) ;
2006-06-29 02:24:58 -07:00
}
# undef P
2011-02-07 20:25:25 +01:00
# undef PS