mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 08:44:41 +00:00 
			
		
		
		
	ARM: LPC32xx: Device tree support
This patch does the actual device tree switch for the LPC32xx SoC. Signed-off-by: Roland Stigge <stigge@antcom.de>
This commit is contained in:
		
							parent
							
								
									e04920d9ef
								
							
						
					
					
						commit
						f5c4227133
					
				
					 7 changed files with 158 additions and 311 deletions
				
			
		
							
								
								
									
										38
									
								
								Documentation/devicetree/bindings/arm/lpc32xx-mic.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								Documentation/devicetree/bindings/arm/lpc32xx-mic.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,38 @@ | ||||||
|  | * NXP LPC32xx Main Interrupt Controller | ||||||
|  |   (MIC, including SIC1 and SIC2 secondary controllers) | ||||||
|  | 
 | ||||||
|  | Required properties: | ||||||
|  | - compatible: Should be "nxp,lpc3220-mic" | ||||||
|  | - interrupt-controller: Identifies the node as an interrupt controller. | ||||||
|  | - interrupt-parent: Empty for the interrupt controller itself | ||||||
|  | - #interrupt-cells: The number of cells to define the interrupts. Should be 2. | ||||||
|  |   The first cell is the IRQ number | ||||||
|  |   The second cell is used to specify mode: | ||||||
|  |       1 = low-to-high edge triggered | ||||||
|  |       2 = high-to-low edge triggered | ||||||
|  |       4 = active high level-sensitive | ||||||
|  |       8 = active low level-sensitive | ||||||
|  |       Default for internal sources should be set to 4 (active high). | ||||||
|  | - reg: Should contain MIC registers location and length | ||||||
|  | 
 | ||||||
|  | Examples: | ||||||
|  | 	/* | ||||||
|  | 	 * MIC | ||||||
|  | 	 */ | ||||||
|  | 	mic: interrupt-controller@40008000 { | ||||||
|  | 		compatible = "nxp,lpc3220-mic"; | ||||||
|  | 		interrupt-controller; | ||||||
|  | 		interrupt-parent; | ||||||
|  | 		#interrupt-cells = <2>; | ||||||
|  | 		reg = <0x40008000 0xC000>; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	/* | ||||||
|  | 	 * ADC | ||||||
|  | 	 */ | ||||||
|  | 	adc@40048000 { | ||||||
|  | 		compatible = "nxp,lpc3220-adc"; | ||||||
|  | 		reg = <0x40048000 0x1000>; | ||||||
|  | 		interrupt-parent = <&mic>; | ||||||
|  | 		interrupts = <39 4>; | ||||||
|  | 	}; | ||||||
							
								
								
									
										8
									
								
								Documentation/devicetree/bindings/arm/lpc32xx.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								Documentation/devicetree/bindings/arm/lpc32xx.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | ||||||
|  | NXP LPC32xx Platforms Device Tree Bindings | ||||||
|  | ------------------------------------------ | ||||||
|  | 
 | ||||||
|  | Boards with the NXP LPC32xx SoC shall have the following properties: | ||||||
|  | 
 | ||||||
|  | Required root node property: | ||||||
|  | 
 | ||||||
|  | compatible: must be "nxp,lpc3220", "nxp,lpc3230", "nxp,lpc3240" or "nxp,lpc3250" | ||||||
|  | @ -597,6 +597,7 @@ config ARCH_LPC32XX | ||||||
| 	select USB_ARCH_HAS_OHCI | 	select USB_ARCH_HAS_OHCI | ||||||
| 	select CLKDEV_LOOKUP | 	select CLKDEV_LOOKUP | ||||||
| 	select GENERIC_CLOCKEVENTS | 	select GENERIC_CLOCKEVENTS | ||||||
|  | 	select USE_OF | ||||||
| 	help | 	help | ||||||
| 	  Support for the NXP LPC32XX family of processors | 	  Support for the NXP LPC32XX family of processors | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -31,198 +31,6 @@ | ||||||
| #include <mach/platform.h> | #include <mach/platform.h> | ||||||
| #include "common.h" | #include "common.h" | ||||||
| 
 | 
 | ||||||
| /*
 |  | ||||||
|  * Watchdog timer |  | ||||||
|  */ |  | ||||||
| static struct resource watchdog_resources[] = { |  | ||||||
| 	[0] = { |  | ||||||
| 		.start = LPC32XX_WDTIM_BASE, |  | ||||||
| 		.end = LPC32XX_WDTIM_BASE + SZ_4K - 1, |  | ||||||
| 		.flags = IORESOURCE_MEM, |  | ||||||
| 	}, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct platform_device lpc32xx_watchdog_device = { |  | ||||||
| 	.name = "pnx4008-watchdog", |  | ||||||
| 	.id = -1, |  | ||||||
| 	.num_resources = ARRAY_SIZE(watchdog_resources), |  | ||||||
| 	.resource = watchdog_resources, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * I2C busses |  | ||||||
|  */ |  | ||||||
| static struct resource i2c0_resources[] = { |  | ||||||
| 	[0] = { |  | ||||||
| 		.start = LPC32XX_I2C1_BASE, |  | ||||||
| 		.end = LPC32XX_I2C1_BASE + 0x100 - 1, |  | ||||||
| 		.flags = IORESOURCE_MEM, |  | ||||||
| 	}, |  | ||||||
| 	[1] = { |  | ||||||
| 		.start = IRQ_LPC32XX_I2C_1, |  | ||||||
| 		.end = IRQ_LPC32XX_I2C_1, |  | ||||||
| 		.flags = IORESOURCE_IRQ, |  | ||||||
| 	}, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| static struct resource i2c1_resources[] = { |  | ||||||
| 	[0] = { |  | ||||||
| 		.start = LPC32XX_I2C2_BASE, |  | ||||||
| 		.end = LPC32XX_I2C2_BASE + 0x100 - 1, |  | ||||||
| 		.flags = IORESOURCE_MEM, |  | ||||||
| 	}, |  | ||||||
| 	[1] = { |  | ||||||
| 		.start = IRQ_LPC32XX_I2C_2, |  | ||||||
| 		.end = IRQ_LPC32XX_I2C_2, |  | ||||||
| 		.flags = IORESOURCE_IRQ, |  | ||||||
| 	}, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| static struct resource i2c2_resources[] = { |  | ||||||
| 	[0] = { |  | ||||||
| 		.start = LPC32XX_OTG_I2C_BASE, |  | ||||||
| 		.end = LPC32XX_OTG_I2C_BASE + 0x100 - 1, |  | ||||||
| 		.flags = IORESOURCE_MEM, |  | ||||||
| 	}, |  | ||||||
| 	[1] = { |  | ||||||
| 		.start = IRQ_LPC32XX_USB_I2C, |  | ||||||
| 		.end = IRQ_LPC32XX_USB_I2C, |  | ||||||
| 		.flags = IORESOURCE_IRQ, |  | ||||||
| 	}, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct platform_device lpc32xx_i2c0_device = { |  | ||||||
| 	.name = "pnx-i2c.0", |  | ||||||
| 	.id = 0, |  | ||||||
| 	.num_resources = ARRAY_SIZE(i2c0_resources), |  | ||||||
| 	.resource = i2c0_resources, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct platform_device lpc32xx_i2c1_device = { |  | ||||||
| 	.name = "pnx-i2c.1", |  | ||||||
| 	.id = 1, |  | ||||||
| 	.num_resources = ARRAY_SIZE(i2c1_resources), |  | ||||||
| 	.resource = i2c1_resources, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct platform_device lpc32xx_i2c2_device = { |  | ||||||
| 	.name = "pnx-i2c.2", |  | ||||||
| 	.id = 2, |  | ||||||
| 	.num_resources = ARRAY_SIZE(i2c2_resources), |  | ||||||
| 	.resource = i2c2_resources, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* TSC (Touch Screen Controller) */ |  | ||||||
| 
 |  | ||||||
| static struct resource lpc32xx_tsc_resources[] = { |  | ||||||
| 	{ |  | ||||||
| 		.start = LPC32XX_ADC_BASE, |  | ||||||
| 		.end = LPC32XX_ADC_BASE + SZ_4K - 1, |  | ||||||
| 		.flags = IORESOURCE_MEM, |  | ||||||
| 	}, { |  | ||||||
| 		.start = IRQ_LPC32XX_TS_IRQ, |  | ||||||
| 		.end = IRQ_LPC32XX_TS_IRQ, |  | ||||||
| 		.flags = IORESOURCE_IRQ, |  | ||||||
| 	}, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct platform_device lpc32xx_tsc_device = { |  | ||||||
| 	.name =  "ts-lpc32xx", |  | ||||||
| 	.id = -1, |  | ||||||
| 	.num_resources = ARRAY_SIZE(lpc32xx_tsc_resources), |  | ||||||
| 	.resource = lpc32xx_tsc_resources, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* RTC */ |  | ||||||
| 
 |  | ||||||
| static struct resource lpc32xx_rtc_resources[] = { |  | ||||||
| 	{ |  | ||||||
| 		.start = LPC32XX_RTC_BASE, |  | ||||||
| 		.end = LPC32XX_RTC_BASE + SZ_4K - 1, |  | ||||||
| 		.flags = IORESOURCE_MEM, |  | ||||||
| 	},{ |  | ||||||
| 		.start = IRQ_LPC32XX_RTC, |  | ||||||
| 		.end = IRQ_LPC32XX_RTC, |  | ||||||
| 		.flags = IORESOURCE_IRQ, |  | ||||||
| 	}, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct platform_device lpc32xx_rtc_device = { |  | ||||||
| 	.name =  "rtc-lpc32xx", |  | ||||||
| 	.id = -1, |  | ||||||
| 	.num_resources = ARRAY_SIZE(lpc32xx_rtc_resources), |  | ||||||
| 	.resource = lpc32xx_rtc_resources, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * ADC support |  | ||||||
|  */ |  | ||||||
| static struct resource adc_resources[] = { |  | ||||||
| 	{ |  | ||||||
| 		.start = LPC32XX_ADC_BASE, |  | ||||||
| 		.end = LPC32XX_ADC_BASE + SZ_4K - 1, |  | ||||||
| 		.flags = IORESOURCE_MEM, |  | ||||||
| 	}, { |  | ||||||
| 		.start = IRQ_LPC32XX_TS_IRQ, |  | ||||||
| 		.end = IRQ_LPC32XX_TS_IRQ, |  | ||||||
| 		.flags = IORESOURCE_IRQ, |  | ||||||
| 	}, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct platform_device lpc32xx_adc_device = { |  | ||||||
| 	.name =  "lpc32xx-adc", |  | ||||||
| 	.id = -1, |  | ||||||
| 	.num_resources = ARRAY_SIZE(adc_resources), |  | ||||||
| 	.resource = adc_resources, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * USB support |  | ||||||
|  */ |  | ||||||
| /* The dmamask must be set for OHCI to work */ |  | ||||||
| static u64 ohci_dmamask = ~(u32) 0; |  | ||||||
| static struct resource ohci_resources[] = { |  | ||||||
| 	{ |  | ||||||
| 		.start = IO_ADDRESS(LPC32XX_USB_BASE), |  | ||||||
| 		.end = IO_ADDRESS(LPC32XX_USB_BASE + 0x100 - 1), |  | ||||||
| 		.flags = IORESOURCE_MEM, |  | ||||||
| 	}, { |  | ||||||
| 		.start = IRQ_LPC32XX_USB_HOST, |  | ||||||
| 		.flags = IORESOURCE_IRQ, |  | ||||||
| 	}, |  | ||||||
| }; |  | ||||||
| struct platform_device lpc32xx_ohci_device = { |  | ||||||
| 	.name = "usb-ohci", |  | ||||||
| 	.id = -1, |  | ||||||
| 	.dev = { |  | ||||||
| 		.dma_mask = &ohci_dmamask, |  | ||||||
| 		.coherent_dma_mask = 0xFFFFFFFF, |  | ||||||
| 	}, |  | ||||||
| 	.num_resources = ARRAY_SIZE(ohci_resources), |  | ||||||
| 	.resource = ohci_resources, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * Network Support |  | ||||||
|  */ |  | ||||||
| static struct resource net_resources[] = { |  | ||||||
| 	[0] = DEFINE_RES_MEM(LPC32XX_ETHERNET_BASE, SZ_4K), |  | ||||||
| 	[1] = DEFINE_RES_MEM(LPC32XX_IRAM_BASE, SZ_128K), |  | ||||||
| 	[2] = DEFINE_RES_IRQ(IRQ_LPC32XX_ETHERNET), |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| static u64 lpc32xx_mac_dma_mask = 0xffffffffUL; |  | ||||||
| struct platform_device lpc32xx_net_device = { |  | ||||||
| 	.name = "lpc-eth", |  | ||||||
| 	.id = 0, |  | ||||||
| 	.dev = { |  | ||||||
| 		.dma_mask = &lpc32xx_mac_dma_mask, |  | ||||||
| 		.coherent_dma_mask = 0xffffffffUL, |  | ||||||
| 	}, |  | ||||||
| 	.num_resources = ARRAY_SIZE(net_resources), |  | ||||||
| 	.resource = net_resources, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /*
 | /*
 | ||||||
|  * Returns the unique ID for the device |  * Returns the unique ID for the device | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | @ -22,19 +22,6 @@ | ||||||
| #include <mach/board.h> | #include <mach/board.h> | ||||||
| #include <linux/platform_device.h> | #include <linux/platform_device.h> | ||||||
| 
 | 
 | ||||||
| /*
 |  | ||||||
|  * Arch specific platform device structures |  | ||||||
|  */ |  | ||||||
| extern struct platform_device lpc32xx_watchdog_device; |  | ||||||
| extern struct platform_device lpc32xx_i2c0_device; |  | ||||||
| extern struct platform_device lpc32xx_i2c1_device; |  | ||||||
| extern struct platform_device lpc32xx_i2c2_device; |  | ||||||
| extern struct platform_device lpc32xx_tsc_device; |  | ||||||
| extern struct platform_device lpc32xx_adc_device; |  | ||||||
| extern struct platform_device lpc32xx_rtc_device; |  | ||||||
| extern struct platform_device lpc32xx_ohci_device; |  | ||||||
| extern struct platform_device lpc32xx_net_device; |  | ||||||
| 
 |  | ||||||
| /*
 | /*
 | ||||||
|  * Other arch specific structures and functions |  * Other arch specific structures and functions | ||||||
|  */ |  */ | ||||||
|  | @ -42,7 +29,6 @@ extern struct sys_timer lpc32xx_timer; | ||||||
| extern void __init lpc32xx_init_irq(void); | extern void __init lpc32xx_init_irq(void); | ||||||
| extern void __init lpc32xx_map_io(void); | extern void __init lpc32xx_map_io(void); | ||||||
| extern void __init lpc32xx_serial_init(void); | extern void __init lpc32xx_serial_init(void); | ||||||
| extern void __init lpc32xx_gpio_init(void); |  | ||||||
| extern void lpc23xx_restart(char, const char *); | extern void lpc23xx_restart(char, const char *); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -22,6 +22,11 @@ | ||||||
| #include <linux/irq.h> | #include <linux/irq.h> | ||||||
| #include <linux/err.h> | #include <linux/err.h> | ||||||
| #include <linux/io.h> | #include <linux/io.h> | ||||||
|  | #include <linux/of.h> | ||||||
|  | #include <linux/of_address.h> | ||||||
|  | #include <linux/of_irq.h> | ||||||
|  | #include <linux/irqdomain.h> | ||||||
|  | #include <linux/module.h> | ||||||
| 
 | 
 | ||||||
| #include <mach/irqs.h> | #include <mach/irqs.h> | ||||||
| #include <mach/hardware.h> | #include <mach/hardware.h> | ||||||
|  | @ -44,6 +49,9 @@ | ||||||
| #define SIC1_ATR_DEFAULT	0x00026000 | #define SIC1_ATR_DEFAULT	0x00026000 | ||||||
| #define SIC2_ATR_DEFAULT	0x00000000 | #define SIC2_ATR_DEFAULT	0x00000000 | ||||||
| 
 | 
 | ||||||
|  | static struct irq_domain *lpc32xx_mic_domain; | ||||||
|  | static struct device_node *lpc32xx_mic_np; | ||||||
|  | 
 | ||||||
| struct lpc32xx_event_group_regs { | struct lpc32xx_event_group_regs { | ||||||
| 	void __iomem *enab_reg; | 	void __iomem *enab_reg; | ||||||
| 	void __iomem *edge_reg; | 	void __iomem *edge_reg; | ||||||
|  | @ -203,7 +211,7 @@ static void lpc32xx_mask_irq(struct irq_data *d) | ||||||
| { | { | ||||||
| 	unsigned int reg, ctrl, mask; | 	unsigned int reg, ctrl, mask; | ||||||
| 
 | 
 | ||||||
| 	get_controller(d->irq, &ctrl, &mask); | 	get_controller(d->hwirq, &ctrl, &mask); | ||||||
| 
 | 
 | ||||||
| 	reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) & ~mask; | 	reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) & ~mask; | ||||||
| 	__raw_writel(reg, LPC32XX_INTC_MASK(ctrl)); | 	__raw_writel(reg, LPC32XX_INTC_MASK(ctrl)); | ||||||
|  | @ -213,7 +221,7 @@ static void lpc32xx_unmask_irq(struct irq_data *d) | ||||||
| { | { | ||||||
| 	unsigned int reg, ctrl, mask; | 	unsigned int reg, ctrl, mask; | ||||||
| 
 | 
 | ||||||
| 	get_controller(d->irq, &ctrl, &mask); | 	get_controller(d->hwirq, &ctrl, &mask); | ||||||
| 
 | 
 | ||||||
| 	reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) | mask; | 	reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) | mask; | ||||||
| 	__raw_writel(reg, LPC32XX_INTC_MASK(ctrl)); | 	__raw_writel(reg, LPC32XX_INTC_MASK(ctrl)); | ||||||
|  | @ -223,14 +231,14 @@ static void lpc32xx_ack_irq(struct irq_data *d) | ||||||
| { | { | ||||||
| 	unsigned int ctrl, mask; | 	unsigned int ctrl, mask; | ||||||
| 
 | 
 | ||||||
| 	get_controller(d->irq, &ctrl, &mask); | 	get_controller(d->hwirq, &ctrl, &mask); | ||||||
| 
 | 
 | ||||||
| 	__raw_writel(mask, LPC32XX_INTC_RAW_STAT(ctrl)); | 	__raw_writel(mask, LPC32XX_INTC_RAW_STAT(ctrl)); | ||||||
| 
 | 
 | ||||||
| 	/* Also need to clear pending wake event */ | 	/* Also need to clear pending wake event */ | ||||||
| 	if (lpc32xx_events[d->irq].mask != 0) | 	if (lpc32xx_events[d->hwirq].mask != 0) | ||||||
| 		__raw_writel(lpc32xx_events[d->irq].mask, | 		__raw_writel(lpc32xx_events[d->hwirq].mask, | ||||||
| 			lpc32xx_events[d->irq].event_group->rawstat_reg); | 			lpc32xx_events[d->hwirq].event_group->rawstat_reg); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void __lpc32xx_set_irq_type(unsigned int irq, int use_high_level, | static void __lpc32xx_set_irq_type(unsigned int irq, int use_high_level, | ||||||
|  | @ -274,22 +282,22 @@ static int lpc32xx_set_irq_type(struct irq_data *d, unsigned int type) | ||||||
| 	switch (type) { | 	switch (type) { | ||||||
| 	case IRQ_TYPE_EDGE_RISING: | 	case IRQ_TYPE_EDGE_RISING: | ||||||
| 		/* Rising edge sensitive */ | 		/* Rising edge sensitive */ | ||||||
| 		__lpc32xx_set_irq_type(d->irq, 1, 1); | 		__lpc32xx_set_irq_type(d->hwirq, 1, 1); | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	case IRQ_TYPE_EDGE_FALLING: | 	case IRQ_TYPE_EDGE_FALLING: | ||||||
| 		/* Falling edge sensitive */ | 		/* Falling edge sensitive */ | ||||||
| 		__lpc32xx_set_irq_type(d->irq, 0, 1); | 		__lpc32xx_set_irq_type(d->hwirq, 0, 1); | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	case IRQ_TYPE_LEVEL_LOW: | 	case IRQ_TYPE_LEVEL_LOW: | ||||||
| 		/* Low level sensitive */ | 		/* Low level sensitive */ | ||||||
| 		__lpc32xx_set_irq_type(d->irq, 0, 0); | 		__lpc32xx_set_irq_type(d->hwirq, 0, 0); | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	case IRQ_TYPE_LEVEL_HIGH: | 	case IRQ_TYPE_LEVEL_HIGH: | ||||||
| 		/* High level sensitive */ | 		/* High level sensitive */ | ||||||
| 		__lpc32xx_set_irq_type(d->irq, 1, 0); | 		__lpc32xx_set_irq_type(d->hwirq, 1, 0); | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	/* Other modes are not supported */ | 	/* Other modes are not supported */ | ||||||
|  | @ -298,7 +306,7 @@ static int lpc32xx_set_irq_type(struct irq_data *d, unsigned int type) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Ok to use the level handler for all types */ | 	/* Ok to use the level handler for all types */ | ||||||
| 	irq_set_handler(d->irq, handle_level_irq); | 	irq_set_handler(d->hwirq, handle_level_irq); | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | @ -307,33 +315,33 @@ static int lpc32xx_irq_wake(struct irq_data *d, unsigned int state) | ||||||
| { | { | ||||||
| 	unsigned long eventreg; | 	unsigned long eventreg; | ||||||
| 
 | 
 | ||||||
| 	if (lpc32xx_events[d->irq].mask != 0) { | 	if (lpc32xx_events[d->hwirq].mask != 0) { | ||||||
| 		eventreg = __raw_readl(lpc32xx_events[d->irq]. | 		eventreg = __raw_readl(lpc32xx_events[d->hwirq]. | ||||||
| 			event_group->enab_reg); | 			event_group->enab_reg); | ||||||
| 
 | 
 | ||||||
| 		if (state) | 		if (state) | ||||||
| 			eventreg |= lpc32xx_events[d->irq].mask; | 			eventreg |= lpc32xx_events[d->hwirq].mask; | ||||||
| 		else { | 		else { | ||||||
| 			eventreg &= ~lpc32xx_events[d->irq].mask; | 			eventreg &= ~lpc32xx_events[d->hwirq].mask; | ||||||
| 
 | 
 | ||||||
| 			/*
 | 			/*
 | ||||||
| 			 * When disabling the wakeup, clear the latched | 			 * When disabling the wakeup, clear the latched | ||||||
| 			 * event | 			 * event | ||||||
| 			 */ | 			 */ | ||||||
| 			__raw_writel(lpc32xx_events[d->irq].mask, | 			__raw_writel(lpc32xx_events[d->hwirq].mask, | ||||||
| 				lpc32xx_events[d->irq]. | 				lpc32xx_events[d->hwirq]. | ||||||
| 				event_group->rawstat_reg); | 				event_group->rawstat_reg); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		__raw_writel(eventreg, | 		__raw_writel(eventreg, | ||||||
| 			lpc32xx_events[d->irq].event_group->enab_reg); | 			lpc32xx_events[d->hwirq].event_group->enab_reg); | ||||||
| 
 | 
 | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Clear event */ | 	/* Clear event */ | ||||||
| 	__raw_writel(lpc32xx_events[d->irq].mask, | 	__raw_writel(lpc32xx_events[d->hwirq].mask, | ||||||
| 		lpc32xx_events[d->irq].event_group->rawstat_reg); | 		lpc32xx_events[d->hwirq].event_group->rawstat_reg); | ||||||
| 
 | 
 | ||||||
| 	return -ENODEV; | 	return -ENODEV; | ||||||
| } | } | ||||||
|  | @ -353,6 +361,7 @@ static void __init lpc32xx_set_default_mappings(unsigned int apr, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static struct irq_chip lpc32xx_irq_chip = { | static struct irq_chip lpc32xx_irq_chip = { | ||||||
|  | 	.name = "MIC", | ||||||
| 	.irq_ack = lpc32xx_ack_irq, | 	.irq_ack = lpc32xx_ack_irq, | ||||||
| 	.irq_mask = lpc32xx_mask_irq, | 	.irq_mask = lpc32xx_mask_irq, | ||||||
| 	.irq_unmask = lpc32xx_unmask_irq, | 	.irq_unmask = lpc32xx_unmask_irq, | ||||||
|  | @ -386,9 +395,23 @@ static void lpc32xx_sic2_handler(unsigned int irq, struct irq_desc *desc) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static int __init __lpc32xx_mic_of_init(struct device_node *node, | ||||||
|  | 					struct device_node *parent) | ||||||
|  | { | ||||||
|  | 	lpc32xx_mic_np = node; | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static const struct of_device_id mic_of_match[] __initconst = { | ||||||
|  | 	{ .compatible = "nxp,lpc3220-mic", .data = __lpc32xx_mic_of_init }, | ||||||
|  | 	{ } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| void __init lpc32xx_init_irq(void) | void __init lpc32xx_init_irq(void) | ||||||
| { | { | ||||||
| 	unsigned int i; | 	unsigned int i; | ||||||
|  | 	int irq_base; | ||||||
| 
 | 
 | ||||||
| 	/* Setup MIC */ | 	/* Setup MIC */ | ||||||
| 	__raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE)); | 	__raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE)); | ||||||
|  | @ -448,4 +471,19 @@ void __init lpc32xx_init_irq(void) | ||||||
| 		LPC32XX_CLKPWR_PIN_RS); | 		LPC32XX_CLKPWR_PIN_RS); | ||||||
| 	__raw_writel(__raw_readl(LPC32XX_CLKPWR_INT_RS), | 	__raw_writel(__raw_readl(LPC32XX_CLKPWR_INT_RS), | ||||||
| 		LPC32XX_CLKPWR_INT_RS); | 		LPC32XX_CLKPWR_INT_RS); | ||||||
|  | 
 | ||||||
|  | 	of_irq_init(mic_of_match); | ||||||
|  | 
 | ||||||
|  | 	irq_base = irq_alloc_descs(-1, 0, NR_IRQS, 0); | ||||||
|  | 	if (irq_base < 0) { | ||||||
|  | 		pr_warn("Cannot allocate irq_descs, assuming pre-allocated\n"); | ||||||
|  | 		irq_base = 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	lpc32xx_mic_domain = irq_domain_add_legacy(lpc32xx_mic_np, NR_IRQS, | ||||||
|  | 						   irq_base, 0, | ||||||
|  | 						   &irq_domain_simple_ops, | ||||||
|  | 						   NULL); | ||||||
|  | 	if (!lpc32xx_mic_domain) | ||||||
|  | 		panic("Unable to add MIC irq domain\n"); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,8 +1,9 @@ | ||||||
| /*
 | /*
 | ||||||
|  * arch/arm/mach-lpc32xx/phy3250.c |  * Platform support for LPC32xx SoC | ||||||
|  * |  * | ||||||
|  * Author: Kevin Wells <kevin.wells@nxp.com> |  * Author: Kevin Wells <kevin.wells@nxp.com> | ||||||
|  * |  * | ||||||
|  |  * Copyright (C) 2012 Roland Stigge <stigge@antcom.de> | ||||||
|  * Copyright (C) 2010 NXP Semiconductors |  * Copyright (C) 2010 NXP Semiconductors | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  | @ -25,11 +26,16 @@ | ||||||
| #include <linux/device.h> | #include <linux/device.h> | ||||||
| #include <linux/spi/spi.h> | #include <linux/spi/spi.h> | ||||||
| #include <linux/spi/eeprom.h> | #include <linux/spi/eeprom.h> | ||||||
| #include <linux/leds.h> |  | ||||||
| #include <linux/gpio.h> | #include <linux/gpio.h> | ||||||
| #include <linux/amba/bus.h> | #include <linux/amba/bus.h> | ||||||
| #include <linux/amba/clcd.h> | #include <linux/amba/clcd.h> | ||||||
| #include <linux/amba/pl022.h> | #include <linux/amba/pl022.h> | ||||||
|  | #include <linux/of.h> | ||||||
|  | #include <linux/of_address.h> | ||||||
|  | #include <linux/of_irq.h> | ||||||
|  | #include <linux/of_platform.h> | ||||||
|  | #include <linux/clk.h> | ||||||
|  | #include <linux/amba/pl08x.h> | ||||||
| 
 | 
 | ||||||
| #include <asm/setup.h> | #include <asm/setup.h> | ||||||
| #include <asm/mach-types.h> | #include <asm/mach-types.h> | ||||||
|  | @ -47,7 +53,6 @@ | ||||||
| #define SPI0_CS_GPIO	LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5) | #define SPI0_CS_GPIO	LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5) | ||||||
| #define LCD_POWER_GPIO	LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 0) | #define LCD_POWER_GPIO	LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 0) | ||||||
| #define BKL_POWER_GPIO	LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 4) | #define BKL_POWER_GPIO	LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 4) | ||||||
| #define LED_GPIO	LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 1) |  | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * AMBA LCD controller |  * AMBA LCD controller | ||||||
|  | @ -150,9 +155,6 @@ static struct clcd_board lpc32xx_clcd_data = { | ||||||
| 	.remove		= lpc32xx_clcd_remove, | 	.remove		= lpc32xx_clcd_remove, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static AMBA_AHB_DEVICE(lpc32xx_clcd, "dev:clcd", 0, |  | ||||||
| 	LPC32XX_LCD_BASE, { IRQ_LPC32XX_LCD }, &lpc32xx_clcd_data); |  | ||||||
| 
 |  | ||||||
| /*
 | /*
 | ||||||
|  * AMBA SSP (SPI) |  * AMBA SSP (SPI) | ||||||
|  */ |  */ | ||||||
|  | @ -180,8 +182,11 @@ static struct pl022_ssp_controller lpc32xx_ssp0_data = { | ||||||
| 	.enable_dma		= 0, | 	.enable_dma		= 0, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static AMBA_APB_DEVICE(lpc32xx_ssp0, "dev:ssp0", 0, | static struct pl022_ssp_controller lpc32xx_ssp1_data = { | ||||||
| 	LPC32XX_SSP0_BASE, { IRQ_LPC32XX_SSP0 }, &lpc32xx_ssp0_data); | 	.bus_id			= 1, | ||||||
|  | 	.num_chipselect		= 1, | ||||||
|  | 	.enable_dma		= 0, | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| /* AT25 driver registration */ | /* AT25 driver registration */ | ||||||
| static int __init phy3250_spi_board_register(void) | static int __init phy3250_spi_board_register(void) | ||||||
|  | @ -221,73 +226,20 @@ static int __init phy3250_spi_board_register(void) | ||||||
| } | } | ||||||
| arch_initcall(phy3250_spi_board_register); | arch_initcall(phy3250_spi_board_register); | ||||||
| 
 | 
 | ||||||
| static struct i2c_board_info __initdata phy3250_i2c_board_info[] = { | static struct pl08x_platform_data pl08x_pd = { | ||||||
| 	{ |  | ||||||
| 		I2C_BOARD_INFO("pcf8563", 0x51), |  | ||||||
| 	}, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static struct gpio_led phy_leds[] = { | static const struct of_dev_auxdata lpc32xx_auxdata_lookup[] __initconst = { | ||||||
| 	{ | 	OF_DEV_AUXDATA("arm,pl022", 0x20084000, "dev:ssp0", &lpc32xx_ssp0_data), | ||||||
| 		.name			= "led0", | 	OF_DEV_AUXDATA("arm,pl022", 0x2008C000, "dev:ssp1", &lpc32xx_ssp1_data), | ||||||
| 		.gpio			= LED_GPIO, | 	OF_DEV_AUXDATA("arm,pl110", 0x31040000, "dev:clcd", &lpc32xx_clcd_data), | ||||||
| 		.active_low		= 1, | 	OF_DEV_AUXDATA("arm,pl080", 0x31000000, "pl08xdmac", &pl08x_pd), | ||||||
| 		.default_trigger	= "heartbeat", | 	{ } | ||||||
| 	}, |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static struct gpio_led_platform_data led_data = { | static void __init lpc3250_machine_init(void) | ||||||
| 	.leds = phy_leds, |  | ||||||
| 	.num_leds = ARRAY_SIZE(phy_leds), |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| static struct platform_device lpc32xx_gpio_led_device = { |  | ||||||
| 	.name			= "leds-gpio", |  | ||||||
| 	.id			= -1, |  | ||||||
| 	.dev.platform_data	= &led_data, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| static struct platform_device *phy3250_devs[] __initdata = { |  | ||||||
| 	&lpc32xx_rtc_device, |  | ||||||
| 	&lpc32xx_tsc_device, |  | ||||||
| 	&lpc32xx_i2c0_device, |  | ||||||
| 	&lpc32xx_i2c1_device, |  | ||||||
| 	&lpc32xx_i2c2_device, |  | ||||||
| 	&lpc32xx_watchdog_device, |  | ||||||
| 	&lpc32xx_gpio_led_device, |  | ||||||
| 	&lpc32xx_adc_device, |  | ||||||
| 	&lpc32xx_ohci_device, |  | ||||||
| 	&lpc32xx_net_device, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| static struct amba_device *amba_devs[] __initdata = { |  | ||||||
| 	&lpc32xx_clcd_device, |  | ||||||
| 	&lpc32xx_ssp0_device, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * Board specific functions |  | ||||||
|  */ |  | ||||||
| static void __init phy3250_board_init(void) |  | ||||||
| { | { | ||||||
| 	u32 tmp; | 	u32 tmp; | ||||||
| 	int i; |  | ||||||
| 
 |  | ||||||
| 	lpc32xx_gpio_init(); |  | ||||||
| 
 |  | ||||||
| 	/* Register GPIOs used on this board */ |  | ||||||
| 	if (gpio_request(SPI0_CS_GPIO, "spi0 cs")) |  | ||||||
| 		printk(KERN_ERR "Error requesting gpio %u", |  | ||||||
| 			SPI0_CS_GPIO); |  | ||||||
| 	else if (gpio_direction_output(SPI0_CS_GPIO, 1)) |  | ||||||
| 		printk(KERN_ERR "Error setting gpio %u to output", |  | ||||||
| 			SPI0_CS_GPIO); |  | ||||||
| 
 |  | ||||||
| 	/* Setup network interface for RMII mode */ |  | ||||||
| 	tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL); |  | ||||||
| 	tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK; |  | ||||||
| 	tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS; |  | ||||||
| 	__raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL); |  | ||||||
| 
 | 
 | ||||||
| 	/* Setup SLC NAND controller muxing */ | 	/* Setup SLC NAND controller muxing */ | ||||||
| 	__raw_writel(LPC32XX_CLKPWR_NANDCLK_SEL_SLC, | 	__raw_writel(LPC32XX_CLKPWR_NANDCLK_SEL_SLC, | ||||||
|  | @ -300,6 +252,12 @@ static void __init phy3250_board_init(void) | ||||||
| 	tmp |= LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT16; | 	tmp |= LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT16; | ||||||
| 	__raw_writel(tmp, LPC32XX_CLKPWR_LCDCLK_CTRL); | 	__raw_writel(tmp, LPC32XX_CLKPWR_LCDCLK_CTRL); | ||||||
| 
 | 
 | ||||||
|  | 	/* Set up USB power */ | ||||||
|  | 	tmp = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); | ||||||
|  | 	tmp |= LPC32XX_CLKPWR_USBCTRL_HCLK_EN | | ||||||
|  | 		LPC32XX_CLKPWR_USBCTRL_USBI2C_EN; | ||||||
|  | 	__raw_writel(tmp, LPC32XX_CLKPWR_USB_CTRL); | ||||||
|  | 
 | ||||||
| 	/* Set up I2C pull levels */ | 	/* Set up I2C pull levels */ | ||||||
| 	tmp = __raw_readl(LPC32XX_CLKPWR_I2C_CLK_CTRL); | 	tmp = __raw_readl(LPC32XX_CLKPWR_I2C_CLK_CTRL); | ||||||
| 	tmp |= LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE | | 	tmp |= LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE | | ||||||
|  | @ -321,33 +279,35 @@ static void __init phy3250_board_init(void) | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * AMBA peripheral clocks need to be enabled prior to AMBA device | 	 * AMBA peripheral clocks need to be enabled prior to AMBA device | ||||||
| 	 * detection or a data fault will occur, so enable the clocks | 	 * detection or a data fault will occur, so enable the clocks | ||||||
| 	 * here. However, we don't want to enable them if the peripheral | 	 * here. | ||||||
| 	 * isn't included in the image |  | ||||||
| 	 */ | 	 */ | ||||||
| #ifdef CONFIG_FB_ARMCLCD |  | ||||||
| 	tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL); | 	tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL); | ||||||
| 	__raw_writel((tmp | LPC32XX_CLKPWR_LCDCTRL_CLK_EN), | 	__raw_writel((tmp | LPC32XX_CLKPWR_LCDCTRL_CLK_EN), | ||||||
| 		LPC32XX_CLKPWR_LCDCLK_CTRL); | 		LPC32XX_CLKPWR_LCDCLK_CTRL); | ||||||
| #endif | 
 | ||||||
| #ifdef CONFIG_SPI_PL022 |  | ||||||
| 	tmp = __raw_readl(LPC32XX_CLKPWR_SSP_CLK_CTRL); | 	tmp = __raw_readl(LPC32XX_CLKPWR_SSP_CLK_CTRL); | ||||||
| 	__raw_writel((tmp | LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN), | 	__raw_writel((tmp | LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN), | ||||||
| 		LPC32XX_CLKPWR_SSP_CLK_CTRL); | 		LPC32XX_CLKPWR_SSP_CLK_CTRL); | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| 	platform_add_devices(phy3250_devs, ARRAY_SIZE(phy3250_devs)); | 	tmp = __raw_readl(LPC32XX_CLKPWR_DMA_CLK_CTRL); | ||||||
| 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { | 	__raw_writel((tmp | LPC32XX_CLKPWR_DMACLKCTRL_CLK_EN), | ||||||
| 		struct amba_device *d = amba_devs[i]; | 		     LPC32XX_CLKPWR_DMA_CLK_CTRL); | ||||||
| 		amba_device_register(d, &iomem_resource); |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	/* Test clock needed for UDA1380 initial init */ | 	/* Test clock needed for UDA1380 initial init */ | ||||||
| 	__raw_writel(LPC32XX_CLKPWR_TESTCLK2_SEL_MOSC | | 	__raw_writel(LPC32XX_CLKPWR_TESTCLK2_SEL_MOSC | | ||||||
| 		LPC32XX_CLKPWR_TESTCLK_TESTCLK2_EN, | 		LPC32XX_CLKPWR_TESTCLK_TESTCLK2_EN, | ||||||
| 		LPC32XX_CLKPWR_TEST_CLK_SEL); | 		LPC32XX_CLKPWR_TEST_CLK_SEL); | ||||||
| 
 | 
 | ||||||
| 	i2c_register_board_info(0, phy3250_i2c_board_info, | 	of_platform_populate(NULL, of_default_bus_match_table, | ||||||
| 		ARRAY_SIZE(phy3250_i2c_board_info)); | 			     lpc32xx_auxdata_lookup, NULL); | ||||||
|  | 
 | ||||||
|  | 	/* Register GPIOs used on this board */ | ||||||
|  | 	if (gpio_request(SPI0_CS_GPIO, "spi0 cs")) | ||||||
|  | 		printk(KERN_ERR "Error requesting gpio %u", | ||||||
|  | 			SPI0_CS_GPIO); | ||||||
|  | 	else if (gpio_direction_output(SPI0_CS_GPIO, 1)) | ||||||
|  | 		printk(KERN_ERR "Error setting gpio %u to output", | ||||||
|  | 			SPI0_CS_GPIO); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int __init lpc32xx_display_uid(void) | static int __init lpc32xx_display_uid(void) | ||||||
|  | @ -363,12 +323,20 @@ static int __init lpc32xx_display_uid(void) | ||||||
| } | } | ||||||
| arch_initcall(lpc32xx_display_uid); | arch_initcall(lpc32xx_display_uid); | ||||||
| 
 | 
 | ||||||
| MACHINE_START(PHY3250, "Phytec 3250 board with the LPC3250 Microcontroller") | static char const *lpc32xx_dt_compat[] __initdata = { | ||||||
| 	/* Maintainer: Kevin Wells, NXP Semiconductors */ | 	"nxp,lpc3220", | ||||||
|  | 	"nxp,lpc3230", | ||||||
|  | 	"nxp,lpc3240", | ||||||
|  | 	"nxp,lpc3250", | ||||||
|  | 	NULL | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | DT_MACHINE_START(LPC32XX_DT, "LPC32XX SoC (Flattened Device Tree)") | ||||||
| 	.atag_offset	= 0x100, | 	.atag_offset	= 0x100, | ||||||
| 	.map_io		= lpc32xx_map_io, | 	.map_io		= lpc32xx_map_io, | ||||||
| 	.init_irq	= lpc32xx_init_irq, | 	.init_irq	= lpc32xx_init_irq, | ||||||
| 	.timer		= &lpc32xx_timer, | 	.timer		= &lpc32xx_timer, | ||||||
| 	.init_machine	= phy3250_board_init, | 	.init_machine	= lpc3250_machine_init, | ||||||
|  | 	.dt_compat	= lpc32xx_dt_compat, | ||||||
| 	.restart	= lpc23xx_restart, | 	.restart	= lpc23xx_restart, | ||||||
| MACHINE_END | MACHINE_END | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Roland Stigge
						Roland Stigge