75 lines
		
	
	
	
		
			1.5 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			75 lines
		
	
	
	
		
			1.5 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /*
 | ||
|  |  * s6000 irq crossbar | ||
|  |  * | ||
|  |  * Copyright (c) 2009 emlix GmbH | ||
|  |  * Authors:	Johannes Weiner <jw@emlix.com> | ||
|  |  *		Oskar Schirmer <os@emlix.com> | ||
|  |  */ | ||
|  | #include <linux/io.h>
 | ||
|  | #include <asm/irq.h>
 | ||
|  | #include <variant/hardware.h>
 | ||
|  | 
 | ||
|  | /* S6_REG_INTC */ | ||
|  | #define INTC_STATUS	0x000
 | ||
|  | #define INTC_RAW	0x010
 | ||
|  | #define INTC_STATUS_AG	0x100
 | ||
|  | #define INTC_CFG(n)	(0x200 + 4 * (n))
 | ||
|  | 
 | ||
|  | /*
 | ||
|  |  * The s6000 has a crossbar that multiplexes interrupt output lines | ||
|  |  * from the peripherals to input lines on the xtensa core. | ||
|  |  * | ||
|  |  * We leave the mapping decisions to the platform as it depends on the | ||
|  |  * actually connected peripherals which distribution makes sense. | ||
|  |  */ | ||
|  | extern const signed char *platform_irq_mappings[NR_IRQS]; | ||
|  | 
 | ||
|  | static unsigned long scp_to_intc_enable[] = { | ||
|  | #define	TO_INTC_ENABLE(n)	(((n) << 1) + 1)
 | ||
|  | 	TO_INTC_ENABLE(0), | ||
|  | 	TO_INTC_ENABLE(1), | ||
|  | 	TO_INTC_ENABLE(2), | ||
|  | 	TO_INTC_ENABLE(3), | ||
|  | 	TO_INTC_ENABLE(4), | ||
|  | 	TO_INTC_ENABLE(5), | ||
|  | 	TO_INTC_ENABLE(6), | ||
|  | 	TO_INTC_ENABLE(7), | ||
|  | 	TO_INTC_ENABLE(8), | ||
|  | 	TO_INTC_ENABLE(9), | ||
|  | 	TO_INTC_ENABLE(10), | ||
|  | 	TO_INTC_ENABLE(11), | ||
|  | 	TO_INTC_ENABLE(12), | ||
|  | 	-1, | ||
|  | 	-1, | ||
|  | 	TO_INTC_ENABLE(13), | ||
|  | 	-1, | ||
|  | 	TO_INTC_ENABLE(14), | ||
|  | 	-1, | ||
|  | 	TO_INTC_ENABLE(15), | ||
|  | #undef	TO_INTC_ENABLE
 | ||
|  | }; | ||
|  | 
 | ||
|  | static void irq_set(unsigned int irq, int enable) | ||
|  | { | ||
|  | 	unsigned long en; | ||
|  | 	const signed char *m = platform_irq_mappings[irq]; | ||
|  | 
 | ||
|  | 	if (!m) | ||
|  | 		return; | ||
|  | 	en = enable ? scp_to_intc_enable[irq] : 0; | ||
|  | 	while (*m >= 0) { | ||
|  | 		writel(en, S6_REG_INTC + INTC_CFG(*m)); | ||
|  | 		m++; | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void variant_irq_enable(unsigned int irq) | ||
|  | { | ||
|  | 	irq_set(irq, 1); | ||
|  | } | ||
|  | 
 | ||
|  | void variant_irq_disable(unsigned int irq) | ||
|  | { | ||
|  | 	irq_set(irq, 0); | ||
|  | } |