mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-31 14:04:26 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			169 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 6be3809614db2d52724eb4b5193c27d2466142be Mon Sep 17 00:00:00 2001
 | |
| From: notro <notro@tronnes.org>
 | |
| Date: Wed, 9 Jul 2014 14:47:48 +0200
 | |
| Subject: [PATCH 050/114] BCM2708: armctrl: Add IRQ Device Tree support
 | |
| 
 | |
| Add Device Tree IRQ support for BCM2708.
 | |
| Usage is the same as for irq-bcm2835.
 | |
| See binding document: brcm,bcm2835-armctrl-ic.txt
 | |
| 
 | |
| A bank 3 is added to handle GPIO interrupts. This is done because
 | |
| armctrl also handles GPIO interrupts.
 | |
| 
 | |
| Signed-off-by: Noralf Tronnes <notro@tronnes.org>
 | |
| 
 | |
| BCM2708: armctrl: remove irq bank 3
 | |
| 
 | |
| irq bank 3 was needed by the pinctrl-bcm2708 and bcm2708_gpio
 | |
| combination. It is no longer required.
 | |
| 
 | |
| Signed-off-by: Noralf Tronnes <notro@tronnes.org>
 | |
| ---
 | |
|  arch/arm/boot/dts/bcm2708.dtsi  |  9 ++++
 | |
|  arch/arm/mach-bcm2708/armctrl.c | 96 +++++++++++++++++++++++++++++++++++++++++
 | |
|  2 files changed, 105 insertions(+)
 | |
| 
 | |
| --- a/arch/arm/boot/dts/bcm2708.dtsi
 | |
| +++ b/arch/arm/boot/dts/bcm2708.dtsi
 | |
| @@ -4,6 +4,8 @@
 | |
|  	compatible = "brcm,bcm2708";
 | |
|  	model = "BCM2708";
 | |
|  
 | |
| +	interrupt-parent = <&intc>;
 | |
| +
 | |
|  	chosen {
 | |
|  		/*
 | |
|  		   bootargs must be 1024 characters long because the
 | |
| @@ -17,6 +19,13 @@
 | |
|  		#address-cells = <1>;
 | |
|  		#size-cells = <1>;
 | |
|  		ranges = <0x7e000000 0x20000000 0x02000000>;
 | |
| +
 | |
| +		intc: interrupt-controller {
 | |
| +			compatible = "brcm,bcm2708-armctrl-ic";
 | |
| +			reg = <0x7e00b200 0x200>;
 | |
| +			interrupt-controller;
 | |
| +			#interrupt-cells = <2>;
 | |
| +		};
 | |
|  	};
 | |
|  
 | |
|  	clocks {
 | |
| --- a/arch/arm/mach-bcm2708/armctrl.c
 | |
| +++ b/arch/arm/mach-bcm2708/armctrl.c
 | |
| @@ -23,6 +23,8 @@
 | |
|  #include <linux/version.h>
 | |
|  #include <linux/syscore_ops.h>
 | |
|  #include <linux/interrupt.h>
 | |
| +#include <linux/irqdomain.h>
 | |
| +#include <linux/of.h>
 | |
|  
 | |
|  #include <asm/mach/irq.h>
 | |
|  #include <mach/hardware.h>
 | |
| @@ -79,6 +81,99 @@ static void armctrl_unmask_irq(struct ir
 | |
|  	}
 | |
|  }
 | |
|  
 | |
| +#ifdef CONFIG_OF
 | |
| +
 | |
| +#define NR_IRQS_BANK0           21
 | |
| +#define NR_BANKS                3
 | |
| +#define IRQS_PER_BANK           32
 | |
| +
 | |
| +/* from drivers/irqchip/irq-bcm2835.c */
 | |
| +static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr,
 | |
| +        const u32 *intspec, unsigned int intsize,
 | |
| +        unsigned long *out_hwirq, unsigned int *out_type)
 | |
| +{
 | |
| +        if (WARN_ON(intsize != 2))
 | |
| +                return -EINVAL;
 | |
| +
 | |
| +        if (WARN_ON(intspec[0] >= NR_BANKS))
 | |
| +                return -EINVAL;
 | |
| +
 | |
| +        if (WARN_ON(intspec[1] >= IRQS_PER_BANK))
 | |
| +                return -EINVAL;
 | |
| +
 | |
| +        if (WARN_ON(intspec[0] == 0 && intspec[1] >= NR_IRQS_BANK0))
 | |
| +                return -EINVAL;
 | |
| +
 | |
| +	if (intspec[0] == 0)
 | |
| +		*out_hwirq = ARM_IRQ0_BASE + intspec[1];
 | |
| +	else if (intspec[0] == 1)
 | |
| +		*out_hwirq = ARM_IRQ1_BASE + intspec[1];
 | |
| +	else
 | |
| +		*out_hwirq = ARM_IRQ2_BASE + intspec[1];
 | |
| +
 | |
| +	/* reverse remap_irqs[] */
 | |
| +	switch (*out_hwirq) {
 | |
| +	case INTERRUPT_VC_JPEG:
 | |
| +		*out_hwirq = INTERRUPT_JPEG;
 | |
| +		break;
 | |
| +	case INTERRUPT_VC_USB:
 | |
| +		*out_hwirq = INTERRUPT_USB;
 | |
| +		break;
 | |
| +	case INTERRUPT_VC_3D:
 | |
| +		*out_hwirq = INTERRUPT_3D;
 | |
| +		break;
 | |
| +	case INTERRUPT_VC_DMA2:
 | |
| +		*out_hwirq = INTERRUPT_DMA2;
 | |
| +		break;
 | |
| +	case INTERRUPT_VC_DMA3:
 | |
| +		*out_hwirq = INTERRUPT_DMA3;
 | |
| +		break;
 | |
| +	case INTERRUPT_VC_I2C:
 | |
| +		*out_hwirq = INTERRUPT_I2C;
 | |
| +		break;
 | |
| +	case INTERRUPT_VC_SPI:
 | |
| +		*out_hwirq = INTERRUPT_SPI;
 | |
| +		break;
 | |
| +	case INTERRUPT_VC_I2SPCM:
 | |
| +		*out_hwirq = INTERRUPT_I2SPCM;
 | |
| +		break;
 | |
| +	case INTERRUPT_VC_SDIO:
 | |
| +		*out_hwirq = INTERRUPT_SDIO;
 | |
| +		break;
 | |
| +	case INTERRUPT_VC_UART:
 | |
| +		*out_hwirq = INTERRUPT_UART;
 | |
| +		break;
 | |
| +	case INTERRUPT_VC_ARASANSDIO:
 | |
| +		*out_hwirq = INTERRUPT_ARASANSDIO;
 | |
| +		break;
 | |
| +	}
 | |
| +
 | |
| +        *out_type = IRQ_TYPE_NONE;
 | |
| +        return 0;
 | |
| +}
 | |
| +
 | |
| +static struct irq_domain_ops armctrl_ops = {
 | |
| +        .xlate = armctrl_xlate
 | |
| +};
 | |
| +
 | |
| +void __init armctrl_dt_init(void)
 | |
| +{
 | |
| +	struct device_node *np;
 | |
| +	struct irq_domain *domain;
 | |
| +
 | |
| +	np = of_find_compatible_node(NULL, NULL, "brcm,bcm2708-armctrl-ic");
 | |
| +	if (!np)
 | |
| +		return;
 | |
| +
 | |
| +	domain = irq_domain_add_legacy(np, BCM2708_ALLOC_IRQS,
 | |
| +					IRQ_ARMCTRL_START, 0,
 | |
| +					&armctrl_ops, NULL);
 | |
| +        WARN_ON(!domain);
 | |
| +}
 | |
| +#else
 | |
| +void __init armctrl_dt_init(void) { }
 | |
| +#endif /* CONFIG_OF */
 | |
| +
 | |
|  #if defined(CONFIG_PM)
 | |
|  
 | |
|  /* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */
 | |
| @@ -215,5 +310,6 @@ int __init armctrl_init(void __iomem * b
 | |
|  
 | |
|  	armctrl_pm_register(base, irq_start, resume_sources);
 | |
|  	init_FIQ(FIQ_START);
 | |
| +	armctrl_dt_init();
 | |
|  	return 0;
 | |
|  }
 |