linux-2.6.33/request_threaded_irq()
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
*参照元 [#q62dac76]
#backlinks
*説明 [#v672a222]
-パス: [[linux-2.6.33/kernel/irq/manage.c]]
-FIXME: これは何?
--説明
**引数 [#g21f2dad]
-unsigned int irq
--
-irq_handler_t handler
--
-irq_handler_t thread_fn
--
-unsigned long irqflags
--
-const char *devname
--
-void *dev_id
--
**返り値 [#e22af99e]
-int
--
**参考 [#kc4cfa75]
*実装 [#s2912c53]
/**
* 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
*
* This call allocates interrupt resources and enables the
* interrupt line and IRQ handling. From the point this
* call is made your handler function may be invoked. Si...
* your handler function must clear any interrupt the bo...
* raises, you must take care both to initialise your ha...
* and to set up the interrupt handler in the right order.
*
* If you want to set up a threaded irq handler for your...
* then you need to supply @handler and @thread_fn. @han...
* still called in hard interrupt context and has to check
* whether the interrupt originates from the device. If ...
* needs to disable the interrupt on the device and return
* IRQ_WAKE_THREAD which will wake up the handler thread...
* @thread_fn. This split handler design is necessary to...
* shared interrupts.
*
* Dev_id must be globally unique. Normally the address ...
* device data structure is used as the cookie. Since th...
* receives this value it makes sense to use it.
*
* If your interrupt is shared you must pass a non NULL ...
* as this is required when freeing the interrupt.
*
* Flags:
*
* IRQF_SHARED Interrupt is shared
* IRQF_DISABLED Disable local interrupts while processing
* IRQF_SAMPLE_RANDOM The interrupt can be used for entr...
* IRQF_TRIGGER_* Specify active edge(s) or level
*
*/
int request_threaded_irq(unsigned int irq, irq_handler_t...
irq_handler_t thread_fn, unsigned long irqflags,
const char *devname, void *dev_id)
{
struct irqaction *action;
-
--[[linux-2.6.33/irqaction]]
struct irq_desc *desc;
-
--[[linux-2.6.33/irq_desc]]
int retval;
/*
* handle_IRQ_event() always ignores IRQF_DISABLED exce...
* the _first_ irqaction (sigh). That can cause oopsin...
* the behavior is classified as "will not fix" so we n...
* start nudging drivers away from using that idiom.
*/
if ((irqflags & (IRQF_SHARED|IRQF_DISABLED)) ==
(IRQF_SHARED|IRQF_DISABLED)) {
pr_warning(
"IRQ %d/%s: IRQF_DISABLED is not guaranteed on share...
irq, devname);
}
-
--[[linux-2.6.33/pr_warning()]]
#ifdef CONFIG_LOCKDEP
/*
* Lockdep wants atomic interrupt handlers:
*/
irqflags |= IRQF_DISABLED;
#endif
/*
* Sanity-check: shared interrupts must pass in a real ...
* otherwise we'll have trouble later trying to figure ...
* which interrupt is which (messes up the interrupt fr...
* logic etc).
*/
if ((irqflags & IRQF_SHARED) && !dev_id)
return -EINVAL;
desc = irq_to_desc(irq);
if (!desc)
return -EINVAL;
-
--[[linux-2.6.33/irq_to_desc()]]
if (desc->status & IRQ_NOREQUEST)
return -EINVAL;
if (!handler) {
if (!thread_fn)
return -EINVAL;
handler = irq_default_primary_handler;
}
-
--[[linux-2.6.33/irq_default_primary_handler()]]
action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
if (!action)
return -ENOMEM;
-
--[[linux-2.6.33/kzalloc()]]
action->handler = handler;
action->thread_fn = thread_fn;
action->flags = irqflags;
action->name = devname;
action->dev_id = dev_id;
chip_bus_lock(irq, desc);
-
--[[linux-2.6.33/chip_bus_lock()]]
retval = __setup_irq(irq, desc, action);
-
--[[linux-2.6.33/__setup_irq()]]
chip_bus_sync_unlock(irq, desc);
-
--[[linux-2.6.33/chip_bus_sync_unlock()]]
if (retval)
kfree(action);
-
--[[linux-2.6.33/kfree()]]
#ifdef CONFIG_DEBUG_SHIRQ
if (!retval && (irqflags & IRQF_SHARED)) {
/*
* It's a shared IRQ -- the driver ought to be prepare...
* to happen immediately, so let's make sure....
* We disable the irq to make sure that a 'real' IRQ d...
* run in parallel with our fake.
*/
unsigned long flags;
disable_irq(irq);
local_irq_save(flags);
-
--[[linux-2.6.33/disable_irq()]]
--[[linux-2.6.33/local_irq_save()]]
handler(irq, dev_id);
local_irq_restore(flags);
enable_irq(irq);
-
--[[linux-2.6.33/local_irq_restore()]]
--[[linux-2.6.33/enable_irq()]]
}
#endif
return retval;
}
EXPORT_SYMBOL(request_threaded_irq);
-
--[[linux-2.6.33/EXPORT_SYMBOL()]]
*コメント [#l70c6c83]
終了行:
*参照元 [#q62dac76]
#backlinks
*説明 [#v672a222]
-パス: [[linux-2.6.33/kernel/irq/manage.c]]
-FIXME: これは何?
--説明
**引数 [#g21f2dad]
-unsigned int irq
--
-irq_handler_t handler
--
-irq_handler_t thread_fn
--
-unsigned long irqflags
--
-const char *devname
--
-void *dev_id
--
**返り値 [#e22af99e]
-int
--
**参考 [#kc4cfa75]
*実装 [#s2912c53]
/**
* 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
*
* This call allocates interrupt resources and enables the
* interrupt line and IRQ handling. From the point this
* call is made your handler function may be invoked. Si...
* your handler function must clear any interrupt the bo...
* raises, you must take care both to initialise your ha...
* and to set up the interrupt handler in the right order.
*
* If you want to set up a threaded irq handler for your...
* then you need to supply @handler and @thread_fn. @han...
* still called in hard interrupt context and has to check
* whether the interrupt originates from the device. If ...
* needs to disable the interrupt on the device and return
* IRQ_WAKE_THREAD which will wake up the handler thread...
* @thread_fn. This split handler design is necessary to...
* shared interrupts.
*
* Dev_id must be globally unique. Normally the address ...
* device data structure is used as the cookie. Since th...
* receives this value it makes sense to use it.
*
* If your interrupt is shared you must pass a non NULL ...
* as this is required when freeing the interrupt.
*
* Flags:
*
* IRQF_SHARED Interrupt is shared
* IRQF_DISABLED Disable local interrupts while processing
* IRQF_SAMPLE_RANDOM The interrupt can be used for entr...
* IRQF_TRIGGER_* Specify active edge(s) or level
*
*/
int request_threaded_irq(unsigned int irq, irq_handler_t...
irq_handler_t thread_fn, unsigned long irqflags,
const char *devname, void *dev_id)
{
struct irqaction *action;
-
--[[linux-2.6.33/irqaction]]
struct irq_desc *desc;
-
--[[linux-2.6.33/irq_desc]]
int retval;
/*
* handle_IRQ_event() always ignores IRQF_DISABLED exce...
* the _first_ irqaction (sigh). That can cause oopsin...
* the behavior is classified as "will not fix" so we n...
* start nudging drivers away from using that idiom.
*/
if ((irqflags & (IRQF_SHARED|IRQF_DISABLED)) ==
(IRQF_SHARED|IRQF_DISABLED)) {
pr_warning(
"IRQ %d/%s: IRQF_DISABLED is not guaranteed on share...
irq, devname);
}
-
--[[linux-2.6.33/pr_warning()]]
#ifdef CONFIG_LOCKDEP
/*
* Lockdep wants atomic interrupt handlers:
*/
irqflags |= IRQF_DISABLED;
#endif
/*
* Sanity-check: shared interrupts must pass in a real ...
* otherwise we'll have trouble later trying to figure ...
* which interrupt is which (messes up the interrupt fr...
* logic etc).
*/
if ((irqflags & IRQF_SHARED) && !dev_id)
return -EINVAL;
desc = irq_to_desc(irq);
if (!desc)
return -EINVAL;
-
--[[linux-2.6.33/irq_to_desc()]]
if (desc->status & IRQ_NOREQUEST)
return -EINVAL;
if (!handler) {
if (!thread_fn)
return -EINVAL;
handler = irq_default_primary_handler;
}
-
--[[linux-2.6.33/irq_default_primary_handler()]]
action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
if (!action)
return -ENOMEM;
-
--[[linux-2.6.33/kzalloc()]]
action->handler = handler;
action->thread_fn = thread_fn;
action->flags = irqflags;
action->name = devname;
action->dev_id = dev_id;
chip_bus_lock(irq, desc);
-
--[[linux-2.6.33/chip_bus_lock()]]
retval = __setup_irq(irq, desc, action);
-
--[[linux-2.6.33/__setup_irq()]]
chip_bus_sync_unlock(irq, desc);
-
--[[linux-2.6.33/chip_bus_sync_unlock()]]
if (retval)
kfree(action);
-
--[[linux-2.6.33/kfree()]]
#ifdef CONFIG_DEBUG_SHIRQ
if (!retval && (irqflags & IRQF_SHARED)) {
/*
* It's a shared IRQ -- the driver ought to be prepare...
* to happen immediately, so let's make sure....
* We disable the irq to make sure that a 'real' IRQ d...
* run in parallel with our fake.
*/
unsigned long flags;
disable_irq(irq);
local_irq_save(flags);
-
--[[linux-2.6.33/disable_irq()]]
--[[linux-2.6.33/local_irq_save()]]
handler(irq, dev_id);
local_irq_restore(flags);
enable_irq(irq);
-
--[[linux-2.6.33/local_irq_restore()]]
--[[linux-2.6.33/enable_irq()]]
}
#endif
return retval;
}
EXPORT_SYMBOL(request_threaded_irq);
-
--[[linux-2.6.33/EXPORT_SYMBOL()]]
*コメント [#l70c6c83]
ページ名: