*参照元 [#eacb05be]
*参照元 [#q62dac76]
#backlinks

*説明 [#x2e8d7ab]
-[[linux-2.6.33/request_irq()]] を見てください。
*説明 [#v672a222]
-パス: [[linux-2.6.33/kernel/irq/manage.c]]

-FIXME: これは何?
--説明

*コメント [#r0ce7163]

**引数 [#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. Since
  *	your handler function must clear any interrupt the board
  *	raises, you must take care both to initialise your hardware
  *	and to set up the interrupt handler in the right order.
  *
  *	If you want to set up a threaded irq handler for your device
  *	then you need to supply @handler and @thread_fn. @handler ist
  *	still called in hard interrupt context and has to check
  *	whether the interrupt originates from the device. If yes it
  *	needs to disable the interrupt on the device and return
  *	IRQ_WAKE_THREAD which will wake up the handler thread and run
  *	@thread_fn. This split handler design is necessary to support
  *	shared interrupts.
  *
  *	Dev_id must be globally unique. Normally the address of the
  *	device data structure is used as the cookie. Since the handler
  *	receives this value it makes sense to use it.
  *
  *	If your interrupt is shared you must pass a non NULL dev_id
  *	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 entropy
  *	IRQF_TRIGGER_*		Specify active edge(s) or level
  *
  */
 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;
-
--[[linux-2.6.33/irqaction]]

 	struct irq_desc *desc;
-
--[[linux-2.6.33/irq_desc]]

 	int retval;
 
 	/*
 	 * handle_IRQ_event() always ignores IRQF_DISABLED except for
 	 * the _first_ irqaction (sigh).  That can cause oopsing, but
 	 * the behavior is classified as "will not fix" so we need to
 	 * 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 shared IRQs\n",
 			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 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);
 	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 prepared for it
 		 * to happen immediately, so let's make sure....
 		 * We disable the irq to make sure that a 'real' IRQ doesn't
 		 * 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]


トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS