err =
request_irq(irq, button_interrupt, IRQ_TYPE_EDGE_BOTH,
buttons[i].name, (void *)&
buttons[i]);
static inline
int __must_check request_irq(unsigned
int irq,
irq_handler_t handler, unsigned long flags,
const char *
name,
void *
dev)
{
return request_threaded_irq(irq, handler, NULL, flags, name, dev);
##
/**
* request_threaded_irq - allocate an interrupt line
* @irq: Interrupt line to allocate
* @handler: Function to be called when the IRQ occurs.
* Primary handler for threaded interrupts
* If NULL and thread_fn != NULL the default
* primary handler is installed
* @thread_fn: Function called from the irq handler thread
* If NULL, no irq thread is created
* @irqflags: Interrupt type flags
* @devname: An ascii name for the claiming device
* @dev_id: A cookie passed back to the handler function*/
int request_threaded_irq(unsigned
int irq, irq_handler_t handler,
irq_handler_t thread_fn, unsigned long irqflags,
const char *devname,
void *
dev_id)
{
struct irqaction *
action;
struct irq_desc *
desc;
int retval;
/*
* Sanity-check: shared interrupts must pass in a real dev-ID,
* otherwise we'll have trouble later trying to figure out
* which interrupt is which (messes up the interrupt freeing
* logic etc).
*/
if ((irqflags & IRQF_SHARED) && !
dev_id)
return -
EINVAL;
desc =
irq_to_desc(irq);
###
#define NR_IRQS (IRQ_EINT(31) + S5P_GPIOINT_COUNT + 1)
//IRQ_EINT(31) = 160 +31-16 = 175
#define S5P_GPIOINT_COUNT (S5P_GPIOINT_GROUP_COUNT * S5P_GPIOINT_GROUP_SIZE)
#define S5P_GPIOINT_GROUP_COUNT 4
#define S5P_GPIOINT_GROUP_SIZE 8
//#define S5P_GPIOINT_COUNT 12
#define NR_IRQS (175+12+ 1)
//#define NR_IRQS 188
####
#ifndef CONFIG_SPARSE_IRQ
extern struct irq_desc irq_desc[NR_IRQS];
#endif
####
struct irq_desc *irq_to_desc(unsigned
int irq)
{
return (irq < NR_IRQS) ? irq_desc +
irq : NULL;
}
//desc = irq_desc[irq]
//irqdesc.c
#else /* !CONFIG_SPARSE_IRQ */
struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp =
{
[0 ... NR_IRQS-
1] =
{
.handle_irq =
handle_bad_irq,
.depth =
1,
.lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->
lock),
}
}
###
if (!
desc)
return -
EINVAL;
###
static inline
bool irq_settings_can_request(
struct irq_desc *
desc)
{
return !(desc->status_use_accessors &
_IRQ_NOREQUEST);
}
###
if (!
irq_settings_can_request(desc))
return -
EINVAL;
if (!
handler) {
if (!
thread_fn)
return -
EINVAL;
handler =
irq_default_primary_handler;
}
action = kzalloc(
sizeof(
struct irqaction), GFP_KERNEL);
###
/**
* struct irqaction - per interrupt action descriptor
* @handler: interrupt handler function
* @flags: flags (see IRQF_* above)
* @name: name of the device
* @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
* @thread_fn: interrupt handler function for threaded interrupts
* @thread: thread pointer for threaded interrupts
* @thread_flags: flags related to @thread
* @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;
} ____cacheline_internodealigned_in_smp;
###
if (!
action)
return -
ENOMEM;
action->handler =
handler;
action->thread_fn =
thread_fn;
action->flags =
irqflags;
action->name =
devname;
action->dev_id =
dev_id;
chip_bus_lock(desc);
retval =
__setup_irq(irq, desc, action);
###
static int
__setup_irq(unsigned int irq,
struct irq_desc *
desc,
struct irqaction *
new)
{
register_irq_proc(irq, desc);
new->dir =
NULL;
register_handler_proc(irq, new);
free_cpumask_var(mask);
return 0;
}
###
chip_bus_sync_unlock(desc);
if (retval)
kfree(action);
return retval;
}
##
}
转载于:https://www.cnblogs.com/embeded-linux/p/11063952.html