Some chained IRQ handlers are written to cope with primary chips of potentially different flow types. Whether this a sensible thing to do is a point of contention. This patch introduces entry/exit functions for chained handlers which infer the flow type of the primary chip as fasteoi or level-type by checking whether or not the ->irq_eoi function pointer is present and calling back to the primary chip as necessary. Other methods of flow control are not considered. Acked-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
		
			
				
	
	
		
			68 lines
		
	
	
	
		
			1.5 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			68 lines
		
	
	
	
		
			1.5 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 *  arch/arm/include/asm/mach/irq.h
 | 
						|
 *
 | 
						|
 *  Copyright (C) 1995-2000 Russell King.
 | 
						|
 *
 | 
						|
 * This program is free software; you can redistribute it and/or modify
 | 
						|
 * it under the terms of the GNU General Public License version 2 as
 | 
						|
 * published by the Free Software Foundation.
 | 
						|
 */
 | 
						|
#ifndef __ASM_ARM_MACH_IRQ_H
 | 
						|
#define __ASM_ARM_MACH_IRQ_H
 | 
						|
 | 
						|
#include <linux/irq.h>
 | 
						|
 | 
						|
struct seq_file;
 | 
						|
 | 
						|
/*
 | 
						|
 * This is internal.  Do not use it.
 | 
						|
 */
 | 
						|
extern void init_FIQ(void);
 | 
						|
extern int show_fiq_list(struct seq_file *, int);
 | 
						|
 | 
						|
#ifdef CONFIG_MULTI_IRQ_HANDLER
 | 
						|
extern void (*handle_arch_irq)(struct pt_regs *);
 | 
						|
#endif
 | 
						|
 | 
						|
/*
 | 
						|
 * This is for easy migration, but should be changed in the source
 | 
						|
 */
 | 
						|
#define do_bad_IRQ(irq,desc)				\
 | 
						|
do {							\
 | 
						|
	raw_spin_lock(&desc->lock);			\
 | 
						|
	handle_bad_irq(irq, desc);			\
 | 
						|
	raw_spin_unlock(&desc->lock);			\
 | 
						|
} while(0)
 | 
						|
 | 
						|
#ifndef __ASSEMBLY__
 | 
						|
/*
 | 
						|
 * Entry/exit functions for chained handlers where the primary IRQ chip
 | 
						|
 * may implement either fasteoi or level-trigger flow control.
 | 
						|
 */
 | 
						|
static inline void chained_irq_enter(struct irq_chip *chip,
 | 
						|
				     struct irq_desc *desc)
 | 
						|
{
 | 
						|
	/* FastEOI controllers require no action on entry. */
 | 
						|
	if (chip->irq_eoi)
 | 
						|
		return;
 | 
						|
 | 
						|
	if (chip->irq_mask_ack) {
 | 
						|
		chip->irq_mask_ack(&desc->irq_data);
 | 
						|
	} else {
 | 
						|
		chip->irq_mask(&desc->irq_data);
 | 
						|
		if (chip->irq_ack)
 | 
						|
			chip->irq_ack(&desc->irq_data);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static inline void chained_irq_exit(struct irq_chip *chip,
 | 
						|
				    struct irq_desc *desc)
 | 
						|
{
 | 
						|
	if (chip->irq_eoi)
 | 
						|
		chip->irq_eoi(&desc->irq_data);
 | 
						|
	else
 | 
						|
		chip->irq_unmask(&desc->irq_data);
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#endif
 |