linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/9] Support for NXP LPC2K SoCs
@ 2011-03-20 20:30 Ithamar R. Adema
  2011-03-20 20:30 ` [PATCH v3 1/9] lpc2k: Core support Ithamar R. Adema
                   ` (8 more replies)
  0 siblings, 9 replies; 12+ messages in thread
From: Ithamar R. Adema @ 2011-03-20 20:30 UTC (permalink / raw)
  To: linux-arm-kernel

The following patch series implements support for the ARM7TDMI-S based
NXP LPC2K System-on-Chips, and, as first board, the EmbeddedArtists
LPC2478 Developer's Kit.

This code will work on the LPC23XX and LPC24XX ranges of chips, but will
need some more work for LPC21XX and LPC22XX chips.
---
v3 incorporates comments from Russell King and Kevin Wells.

v2 incorporates comments from Kevin Wells, Jamie Iles,
and Uwe Kleine-K??nig.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 1/9] lpc2k: Core support
  2011-03-20 20:30 [PATCH v3 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
@ 2011-03-20 20:30 ` Ithamar R. Adema
  2011-03-20 20:30 ` [PATCH v3 2/9] lpc2k: Exception vector handling Ithamar R. Adema
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Ithamar R. Adema @ 2011-03-20 20:30 UTC (permalink / raw)
  To: linux-arm-kernel

Core files (including IRQ handling) for NXP LPC2K architecture.

Signed-off-by: Ithamar R. Adema <ithamar.adema@team-embedded.nl>
---
changes since v2:
    * Removed GENERIC_TIME from selects.

changes since v1:
    * implement arch_idle() using PCON register.
    * implement arch_reset() using WDT block.
    * Fix PLL 'N' mask in regs-scb.h
---
 arch/arm/Kconfig                               |   13 ++++++
 arch/arm/Makefile                              |    1 +
 arch/arm/mach-lpc2k/Kconfig                    |    5 ++
 arch/arm/mach-lpc2k/Makefile                   |    1 +
 arch/arm/mach-lpc2k/Makefile.boot              |    3 +
 arch/arm/mach-lpc2k/include/mach/debug-macro.S |   19 +++++++++
 arch/arm/mach-lpc2k/include/mach/entry-macro.S |   33 +++++++++++++++
 arch/arm/mach-lpc2k/include/mach/hardware.h    |   25 ++++++++++++
 arch/arm/mach-lpc2k/include/mach/io.h          |   18 ++++++++
 arch/arm/mach-lpc2k/include/mach/irqs.h        |   49 +++++++++++++++++++++++
 arch/arm/mach-lpc2k/include/mach/memory.h      |   15 +++++++
 arch/arm/mach-lpc2k/include/mach/regs-scb.h    |   42 +++++++++++++++++++
 arch/arm/mach-lpc2k/include/mach/regs-wdt.h    |   26 ++++++++++++
 arch/arm/mach-lpc2k/include/mach/system.h      |   51 ++++++++++++++++++++++++
 arch/arm/mach-lpc2k/include/mach/timex.h       |   15 +++++++
 arch/arm/mach-lpc2k/include/mach/uncompress.h  |   50 +++++++++++++++++++++++
 arch/arm/mach-lpc2k/irq.c                      |   17 ++++++++
 17 files changed, 383 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-lpc2k/Kconfig
 create mode 100644 arch/arm/mach-lpc2k/Makefile
 create mode 100644 arch/arm/mach-lpc2k/Makefile.boot
 create mode 100644 arch/arm/mach-lpc2k/include/mach/debug-macro.S
 create mode 100644 arch/arm/mach-lpc2k/include/mach/entry-macro.S
 create mode 100644 arch/arm/mach-lpc2k/include/mach/hardware.h
 create mode 100644 arch/arm/mach-lpc2k/include/mach/io.h
 create mode 100644 arch/arm/mach-lpc2k/include/mach/irqs.h
 create mode 100644 arch/arm/mach-lpc2k/include/mach/memory.h
 create mode 100644 arch/arm/mach-lpc2k/include/mach/regs-scb.h
 create mode 100644 arch/arm/mach-lpc2k/include/mach/regs-wdt.h
 create mode 100644 arch/arm/mach-lpc2k/include/mach/system.h
 create mode 100644 arch/arm/mach-lpc2k/include/mach/timex.h
 create mode 100644 arch/arm/mach-lpc2k/include/mach/uncompress.h
 create mode 100644 arch/arm/mach-lpc2k/irq.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 599e163..a74c200 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -490,6 +490,17 @@ config ARCH_LOKI
 	help
 	  Support for the Marvell Loki (88RC8480) SoC.
 
+config ARCH_LPC2K
+	bool "NXP LPC2K Family"
+	depends on !MMU
+	select CPU_ARM7TDMI
+	select ARM_VIC
+	select GENERIC_CLOCKEVENTS
+	help
+	  Support for NXP LPC2K family of SoCs. These SoCs are based on
+	  an ARM7TDMI-S core, and have optional on-chip flash and SRAM,
+	  also UART, I2C, SPI, SSP, CAN, RTC, and other peripherals.
+
 config ARCH_LPC32XX
 	bool "NXP LPC32XX"
 	select CPU_ARM926T
@@ -931,6 +942,8 @@ source "arch/arm/mach-ks8695/Kconfig"
 
 source "arch/arm/mach-loki/Kconfig"
 
+source "arch/arm/mach-lpc2k/Kconfig"
+
 source "arch/arm/mach-lpc32xx/Kconfig"
 
 source "arch/arm/mach-msm/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c7d321a..9bf8421 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -151,6 +151,7 @@ machine-$(CONFIG_ARCH_IXP4XX)		:= ixp4xx
 machine-$(CONFIG_ARCH_KIRKWOOD)		:= kirkwood
 machine-$(CONFIG_ARCH_KS8695)		:= ks8695
 machine-$(CONFIG_ARCH_LOKI) 		:= loki
+machine-$(CONFIG_ARCH_LPC2K)		:= lpc2k
 machine-$(CONFIG_ARCH_LPC32XX)		:= lpc32xx
 machine-$(CONFIG_ARCH_MMP)		:= mmp
 machine-$(CONFIG_ARCH_MSM)		:= msm
diff --git a/arch/arm/mach-lpc2k/Kconfig b/arch/arm/mach-lpc2k/Kconfig
new file mode 100644
index 0000000..fad47b8
--- /dev/null
+++ b/arch/arm/mach-lpc2k/Kconfig
@@ -0,0 +1,5 @@
+if ARCH_LPC2K
+
+comment "LPC2K machines"
+
+endif
diff --git a/arch/arm/mach-lpc2k/Makefile b/arch/arm/mach-lpc2k/Makefile
new file mode 100644
index 0000000..546666b
--- /dev/null
+++ b/arch/arm/mach-lpc2k/Makefile
@@ -0,0 +1 @@
+obj-y	:= irq.o
diff --git a/arch/arm/mach-lpc2k/Makefile.boot b/arch/arm/mach-lpc2k/Makefile.boot
new file mode 100644
index 0000000..8b6b745
--- /dev/null
+++ b/arch/arm/mach-lpc2k/Makefile.boot
@@ -0,0 +1,3 @@
+   zreladdr-y	:= 0xa0008000
+params_phys-y	:= 0xa0000100
+initrd_phys-y	:= 0xa1800000
diff --git a/arch/arm/mach-lpc2k/include/mach/debug-macro.S b/arch/arm/mach-lpc2k/include/mach/debug-macro.S
new file mode 100644
index 0000000..0f581d3
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/debug-macro.S
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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.
+ */
+
+
+#include <mach/hardware.h>
+
+	.macro	addruart, rp, rv
+	ldr	\rp, =APB_UART0_BASE
+	ldr	\rv, =APB_UART0_BASE
+	.endm
+
+#define UART_SHIFT	2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-lpc2k/include/mach/entry-macro.S b/arch/arm/mach-lpc2k/include/mach/entry-macro.S
new file mode 100644
index 0000000..f6c7a46
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/entry-macro.S
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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.
+ */
+
+#include <mach/hardware.h>
+
+        .macro  disable_fiq
+        .endm
+
+		.macro	get_irqnr_preamble, base, tmp
+		ldr	\base, =APH_VIC_BASE
+		.endm
+
+		.macro	arch_ret_to_user, tmp1, tmp2
+		.endm
+
+		.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\irqstat, [\base, #0]
+		mov     \irqnr, #0
+1001:
+		tst     \irqstat, #1
+		bne     1002f
+		add     \irqnr, \irqnr, #1
+		mov     \irqstat, \irqstat, lsr #1
+		cmp     \irqnr, #32
+		bcc     1001b
+1002:
+		.endm
diff --git a/arch/arm/mach-lpc2k/include/mach/hardware.h b/arch/arm/mach-lpc2k/include/mach/hardware.h
new file mode 100644
index 0000000..3463b47
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/hardware.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 MACH_LPC2K_HARDWARE_H
+#define MACH_LPC2K_HARDWARE_H
+
+#include <asm/sizes.h>
+
+/* Default memory size if no ATAGS found */
+#define MEM_SIZE	(SZ_32M)
+
+#define APB_WDT_BASE		0xe0000000
+#define APB_TIMER0_BASE		0xe0004000
+#define APB_TIMER1_BASE		0xe0008000
+#define APB_UART0_BASE		0xe000c000
+#define APB_SCB_BASE		0xe01fc000
+#define APH_VIC_BASE		0xfffff000
+
+#endif /* MACH_LPC2K_HARDWARE_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/io.h b/arch/arm/mach-lpc2k/include/mach/io.h
new file mode 100644
index 0000000..e1a2b7f
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/io.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 MACH_LPC2K_IO_H
+#define MACH_LPC2K_IO_H
+
+#define IO_SPACE_LIMIT	0xffffffff
+
+#define __mem_pci(a)	(a)
+#define __io(a)		__typesafe_io(a)
+
+#endif /* MACH_LPC2K_IO_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/irqs.h b/arch/arm/mach-lpc2k/include/mach/irqs.h
new file mode 100644
index 0000000..87b80dd
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/irqs.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 MACH_LPC2K_IRQS_H
+#define MACH_LPC2K_IRQS_H
+
+/* VIC */
+#define IRQ_LPC2K_WDINT		0
+#define IRQ_LPC2K_RSV0		1
+#define IRQ_LPC2K_DBGRX		2
+#define IRQ_LPC2K_DBGTX		3
+#define IRQ_LPC2K_TIMER0	4
+#define IRQ_LPC2K_TIMER1	5
+#define IRQ_LPC2K_UART0		6
+#define IRQ_LPC2K_UART1		7
+#define IRQ_LPC2K_PWM0		8
+#define IRQ_LPC2K_I2C0		9
+#define IRQ_LPC2K_SPI0		10
+#define IRQ_LPC2K_SPI1		11
+#define IRQ_LPC2K_PLL		12
+#define IRQ_LPC2K_RTC		13
+#define IRQ_LPC2K_EINT0		14
+#define IRQ_LPC2K_EINT1		15
+#define IRQ_LPC2K_EINT2		16
+#define IRQ_LPC2K_EINT3		17
+#define IRQ_LPC2K_ADC		18
+#define IRQ_LPC2K_I2C1		19
+#define IRQ_LPC2K_BOD		20
+#define IRQ_LPC2K_ETH		21
+#define IRQ_LPC2K_USB		22
+#define IRQ_LPC2K_CAN		23
+#define IRQ_LPC2K_MCI		24
+#define IRQ_LPC2K_DMA		25
+#define IRQ_LPC2K_TIMER2	26
+#define IRQ_LPC2K_TIMER3	27
+#define IRQ_LPC2K_UART2		28
+#define IRQ_LPC2K_UART3		29
+#define IRQ_LPC2K_I2C2		30
+#define IRQ_LPC2K_I2S		31
+
+#define NR_IRQS			32
+
+#endif /* MACH_LPC2K_IRQS_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/memory.h b/arch/arm/mach-lpc2k/include/mach/memory.h
new file mode 100644
index 0000000..6432147
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/memory.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 MACH_LPC2K_MEMORY_H
+#define MACH_LPC2K_MEMORY_H
+
+#define PHYS_OFFSET	0xa0000000
+
+#endif /* MACH_LPC2K_MEMORY_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/regs-scb.h b/arch/arm/mach-lpc2k/include/mach/regs-scb.h
new file mode 100644
index 0000000..d914de9
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/regs-scb.h
@@ -0,0 +1,42 @@
+/*
+ * System Control Block register definitions
+ *
+ * Copyright 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 MACH_LPC2K_REGS_SCB_H
+#define MACH_LPC2K_REGS_SCB_H
+
+#define CLKSRCSEL	0x10c
+#define CLKSRC(x)	((x) & 3)
+#define PLLCON		0x080
+#define PLLCFG		0x084
+#define PLLSTAT		0x088
+#define M(x)		(((x) & 0x7fff) + 1)
+#define N(x)		((((x) >> 16) & 0xff) + 1)
+#define PLLE		(1 << 24)
+#define PLLC		(1 << 25)
+#define PLLFEED		0x08c
+
+#define CCLKCFG		0x104
+#define CCLKSEL(x)	((x) & 0xff)
+#define USBCLKCFG	0x108
+#define USBSEL(x)	((x) & 0xf)
+#define IRCTRIM		0x1a4
+#define PCLKSEL0	0x1a8
+#define PCLKSEL1	0x1ac
+
+#define PCON		0x0c0
+#define PCON_PM0	(1 << 0)
+#define PCON_PM1	(1 << 1)
+#define PCON_PM2	(1 << 7)
+#define PCON_PMMASK	(PCON_PM0 | PCON_PM1 | PCON_PM2)
+#define INTWAKE		0x144
+#define PCONP		0x0c4
+
+#endif /* MACH_LPC2K_REGS_SCB_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/regs-wdt.h b/arch/arm/mach-lpc2k/include/mach/regs-wdt.h
new file mode 100644
index 0000000..eb6ab91
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/regs-wdt.h
@@ -0,0 +1,26 @@
+/*
+ * Watchdog Timer register definitions
+ *
+ * Copyright 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 MACH_LPC2K_REGS_WDT_H
+#define MACH_LPC2K_REGS_WDT_H
+
+#define WDMOD		0x0000
+#define WDTC		0x0004
+#define WDFEED		0x0008
+#define WDTV		0x000a
+#define WDCLKSEL	0x0010
+
+#define WDMOD_WDEN	(1 << 0)
+#define WDMOD_WDRESET	(1 << 1)
+#define WDMOD_WDTOF	(1 << 2)
+#define WDMOD_WDINT	(1 << 3)
+
+#endif /* MACH_LPC2K_REGS_WDT_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/system.h b/arch/arm/mach-lpc2k/include/mach/system.h
new file mode 100644
index 0000000..48209e1
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/system.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 MACH_LPC2K_SYSTEM_H
+#define MACH_LPC2K_SYSTEM_H
+
+#include <mach/regs-scb.h>
+#include <mach/regs-wdt.h>
+#include <mach/hardware.h>
+
+static void arch_idle(void)
+{
+	/* Set PM0, IDL: idle mode */
+	iowrite32((ioread32(APB_SCB_BASE + PCON) & ~PCON_PMMASK) | PCON_PM0,
+		APB_SCB_BASE + PCON);
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+	switch (mode) {
+	case 's':
+	case 'h':
+		printk(KERN_CRIT "RESET: Rebooting system\n");
+
+		/* Disable interrupts */
+		local_irq_disable();
+
+		/* Setup WDT to fire on shortest allowed time */
+		iowrite32(0xff, APB_WDT_BASE + WDTC);
+		iowrite32(WDMOD_WDEN | WDMOD_WDRESET, APB_WDT_BASE + WDMOD);
+		iowrite32(0xaa, APB_WDT_BASE + WDFEED);
+		iowrite32(0x55, APB_WDT_BASE + WDFEED);
+		break;
+
+	default:
+		/* Do nothing */
+		break;
+	}
+
+	/* Wait for watchdog to reset system */
+	while (1)
+		;
+}
+
+#endif /* MACH_LPC2K_SYSTEM_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/timex.h b/arch/arm/mach-lpc2k/include/mach/timex.h
new file mode 100644
index 0000000..ba7c8dc
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/timex.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 MACH_LPC2K_TIMEX_H
+#define MACH_LPC2K_TIMEX_H
+
+#define CLOCK_TICK_RATE		(HZ * 100UL)
+
+#endif /* MACH_LPC2K_TIMEX_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/uncompress.h b/arch/arm/mach-lpc2k/include/mach/uncompress.h
new file mode 100644
index 0000000..1724d72
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/uncompress.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * based on uncompress.h from mach-loki.
+ *
+ * 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.
+ */
+
+#include <linux/serial_reg.h>
+#include <mach/hardware.h>
+
+#define SERIAL_BASE	((unsigned char *)APB_UART0_BASE)
+
+static void putc(const char c)
+{
+	unsigned char *base = SERIAL_BASE;
+	int i;
+
+	for (i = 0; i < 0x1000; i++) {
+		if (base[UART_LSR << 2] & UART_LSR_THRE)
+			break;
+		barrier();
+	}
+
+	base[UART_TX << 2] = c;
+}
+
+static void flush(void)
+{
+	unsigned char *base = SERIAL_BASE;
+	unsigned char mask;
+	int i;
+
+	mask = UART_LSR_TEMT | UART_LSR_THRE;
+
+	for (i = 0; i < 0x1000; i++) {
+		if ((base[UART_LSR << 2] & mask) == mask)
+			break;
+		barrier();
+	}
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-lpc2k/irq.c b/arch/arm/mach-lpc2k/irq.c
new file mode 100644
index 0000000..58d291d
--- /dev/null
+++ b/arch/arm/mach-lpc2k/irq.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2011 Team Embeded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <asm/hardware/vic.h>
+#include <mach/hardware.h>
+
+void __init lpc2k_init_irq(void)
+{
+	vic_init((void __iomem *)APH_VIC_BASE, 0, ~0, 0);
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 2/9] lpc2k: Exception vector handling
  2011-03-20 20:30 [PATCH v3 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
  2011-03-20 20:30 ` [PATCH v3 1/9] lpc2k: Core support Ithamar R. Adema
@ 2011-03-20 20:30 ` Ithamar R. Adema
  2011-03-20 20:30 ` [PATCH v3 3/9] lpc2k: clk API Ithamar R. Adema
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Ithamar R. Adema @ 2011-03-20 20:30 UTC (permalink / raw)
  To: linux-arm-kernel

The LPC2K optionally remaps the first 64 bytes of SRAM to address 0, to facilitate
writable low vectors. However, since it only remaps the first 64 bytes the stubs
can't be copied there and end up too far away from the vectors, requiring the
vectors to use an indirect jump instead of branch to get to the stubs.

Since now VECTOR_BASE is below PHYS_OFFSET, do not try to reserve the vector
page, as it will fail (and prevent the kernel from booting).

Also, commit 247055aa (6384/1: Remove the domain switching on ARMv6k/v7 CPUs) broke
the placement of vectors in the !MMU case, so fix this too.

Signed-off-by: Ithamar R. Adema <ithamar.adema@team-embedded.nl>
---
changes since v2:
        * reworded reason for vector branch changes.

changes since v1:
        * added comment to entry-armv.S vector #ifdef.
---
 arch/arm/Kconfig             |    1 +
 arch/arm/kernel/entry-armv.S |   23 +++++++++++++++++++++++
 arch/arm/kernel/traps.c      |    2 +-
 arch/arm/mm/nommu.c          |    2 ++
 4 files changed, 27 insertions(+), 1 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a74c200..7b5adab 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -186,6 +186,7 @@ config VECTORS_BASE
 	hex
 	default 0xffff0000 if MMU || CPU_HIGH_VECTOR
 	default DRAM_BASE if REMAP_VECTORS_TO_RAM
+	default 0x40000000 if ARCH_LPC2K
 	default 0x00000000
 	help
 	  The base address of exception vectors.
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index e8d8856..65be7b1 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -1208,6 +1208,7 @@ __stubs_end:
 
 	.globl	__vectors_start
 __vectors_start:
+#ifndef CONFIG_ARCH_LPC2K
  ARM(	swi	SYS_ERROR0	)
  THUMB(	svc	#0		)
  THUMB(	nop			)
@@ -1218,6 +1219,28 @@ __vectors_start:
 	W(b)	vector_addrexcptn + stubs_offset
 	W(b)	vector_irq + stubs_offset
 	W(b)	vector_fiq + stubs_offset
+#else /* CONFIG_ARCH_LPC2K */
+	/*
+	 * The LPC2K remaps 64 bytes of SRAM to address 0 for vectors. This
+	 * means that the stubs can't be in the same page, and end up too far
+	 * away from the vectors to use a branch instruction.
+	 */
+	swi	SYS_ERROR0
+	ldr	pc, .vector_und
+	ldr	pc, .vector_swi
+	ldr	pc, .vector_pabt
+	ldr	pc, .vector_dabt
+	ldr	pc, .vector_addrexcptn
+	ldr	pc, .vector_irq
+	ldr	pc, .vector_fiq
+.vector_und:		.word   vector_und
+.vector_swi:		.word   vector_swi
+.vector_pabt:		.word   vector_pabt
+.vector_dabt:		.word   vector_dabt
+.vector_addrexcptn:	.word   vector_addrexcptn
+.vector_irq:		.word   vector_irq
+.vector_fiq:		.word   vector_fiq
+#endif
 
 	.globl	__vectors_end
 __vectors_end:
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 21ac43f..639c4c8 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -758,7 +758,7 @@ static void __init kuser_get_tls_init(unsigned long vectors)
 
 void __init early_trap_init(void)
 {
-#if defined(CONFIG_CPU_USE_DOMAINS)
+#if defined(CONFIG_CPU_USE_DOMAINS) || !defined(CONFIG_MMU)
 	unsigned long vectors = CONFIG_VECTORS_BASE;
 #else
 	unsigned long vectors = (unsigned long)vectors_page;
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 687d023..e3bec02 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -24,7 +24,9 @@ void __init arm_mm_memblock_reserve(void)
 	 * some architectures which the DRAM is the exception vector to trap,
 	 * alloc_page breaks with error, although it is not NULL, but "0."
 	 */
+#if PHYS_OFFSET <= CONFIG_VECTORS_BASE
 	memblock_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE);
+#endif
 }
 
 /*
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 3/9] lpc2k: clk API
  2011-03-20 20:30 [PATCH v3 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
  2011-03-20 20:30 ` [PATCH v3 1/9] lpc2k: Core support Ithamar R. Adema
  2011-03-20 20:30 ` [PATCH v3 2/9] lpc2k: Exception vector handling Ithamar R. Adema
@ 2011-03-20 20:30 ` Ithamar R. Adema
  2011-03-22  0:16   ` Kevin Wells
  2011-03-20 20:30 ` [PATCH v3 4/9] lpc2k: generic time and clockevents Ithamar R. Adema
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 12+ messages in thread
From: Ithamar R. Adema @ 2011-03-20 20:30 UTC (permalink / raw)
  To: linux-arm-kernel

Implements clock API using the CLKDEV_LOOKUP common code.

Signed-off-by: Ithamar R. Adema <ithamar.adema@team-embedded.nl>
---
no changes since v2.

changes since v1:
        * changed mutex into spinlock
        * simplified clk_readl/clk_writel macros
---
 arch/arm/Kconfig                          |    1 +
 arch/arm/mach-lpc2k/Makefile              |    2 +-
 arch/arm/mach-lpc2k/clock.c               |  360 +++++++++++++++++++++++++++++
 arch/arm/mach-lpc2k/include/mach/clkdev.h |   17 ++
 4 files changed, 379 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-lpc2k/clock.c
 create mode 100644 arch/arm/mach-lpc2k/include/mach/clkdev.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 7b5adab..b046a49 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -496,6 +496,7 @@ config ARCH_LPC2K
 	depends on !MMU
 	select CPU_ARM7TDMI
 	select ARM_VIC
+	select CLKDEV_LOOKUP
 	select GENERIC_CLOCKEVENTS
 	help
 	  Support for NXP LPC2K family of SoCs. These SoCs are based on
diff --git a/arch/arm/mach-lpc2k/Makefile b/arch/arm/mach-lpc2k/Makefile
index 546666b..9eb0a6a 100644
--- a/arch/arm/mach-lpc2k/Makefile
+++ b/arch/arm/mach-lpc2k/Makefile
@@ -1 +1 @@
-obj-y	:= irq.o
+obj-y	:= clock.o irq.o
diff --git a/arch/arm/mach-lpc2k/clock.c b/arch/arm/mach-lpc2k/clock.c
new file mode 100644
index 0000000..7631c89
--- /dev/null
+++ b/arch/arm/mach-lpc2k/clock.c
@@ -0,0 +1,360 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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.
+ */
+
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <linux/clkdev.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-scb.h>
+
+#define clk_readl(a)	\
+	ioread32(APB_SCB_BASE + (a))
+#define clk_writel(v, a)	\
+	iowrite32(v, APB_SCB_BASE + (a))
+
+struct clk {
+	int		refcount;
+	struct clk	*parent;
+	unsigned long	rate;
+
+	u32		enable_mask;
+
+	long		(*round_rate)(struct clk *clk, unsigned long rate);
+	int		(*set_rate)(struct clk *clk, unsigned long rate);
+	unsigned long	(*get_rate)(struct clk *clk);
+	int		(*set_parent)(struct clk *clk, struct clk *parent);
+};
+
+static DEFINE_SPINLOCK(clk_lock);
+
+/*-------------------------------------------------------------------------
+ * Standard clock functions defined in include/linux/clk.h
+ *-------------------------------------------------------------------------*/
+
+static void __clk_disable(struct clk *clk)
+{
+	BUG_ON(clk->refcount == 0);
+
+	if (!(--clk->refcount)) {
+		if (clk->parent)
+			__clk_disable(clk->parent);
+
+		if (clk->enable_mask) {
+			/* Unconditionally disable the clock in hardware */
+			u32 value = clk_readl(PCONP);
+			clk_writel(value & ~clk->enable_mask, PCONP);
+		}
+	}
+}
+
+static int __clk_enable(struct clk *clk)
+{
+	int ret = 0;
+
+	if (clk->refcount++ == 0) {
+		if (clk->parent)
+			ret = __clk_enable(clk->parent);
+		if (ret)
+			return ret;
+		else if (clk->enable_mask) {
+			u32 value = clk_readl(PCONP);
+			clk_writel(value | clk->enable_mask, PCONP);
+		}
+	}
+
+	return 0;
+}
+
+/* This function increments the reference count on the clock and enables the
+ * clock if not already enabled. The parent clock tree is recursively enabled
+ */
+int clk_enable(struct clk *clk)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	if (!clk)
+		return -EINVAL;
+
+	spin_lock_irqsave(&clk_lock, flags);
+	ret = __clk_enable(clk);
+	spin_unlock_irqrestore(&clk_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(clk_enable);
+
+/* This function decrements the reference count on the clock and disables
+ * the clock when reference count is 0. The parent clock tree is
+ * recursively disabled
+ */
+void clk_disable(struct clk *clk)
+{
+	unsigned long flags;
+
+	if (!clk)
+		return;
+
+	spin_lock_irqsave(&clk_lock, flags);
+	__clk_disable(clk);
+	spin_unlock_irqrestore(&clk_lock, flags);
+}
+EXPORT_SYMBOL_GPL(clk_disable);
+
+/* Retrieve the *current* clock rate. If the clock itself
+ * does not provide a special calculation routine, ask
+ * its parent and so on, until one is able to return
+ * a valid clock rate
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (!clk)
+		return 0UL;
+
+	if (clk->get_rate)
+		return clk->get_rate(clk);
+
+	if (clk->parent)
+		return clk_get_rate(clk->parent);
+
+	return clk->rate;
+}
+EXPORT_SYMBOL_GPL(clk_get_rate);
+
+/* Round the requested clock rate to the nearest supported
+ * rate that is less than or equal to the requested rate.
+ * This is dependent on the clock's current parent.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	if (!clk)
+		return 0;
+	if (!clk->round_rate)
+		return 0;
+
+	return clk->round_rate(clk, rate);
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
+/* Set the clock to the requested clock rate. The rate must
+ * match a supported rate exactly based on what clk_round_rate returns
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	if (!clk)
+		return ret;
+	if (!clk->set_rate || !rate)
+		return ret;
+
+	spin_lock_irqsave(&clk_lock, flags);
+	ret = clk->set_rate(clk, rate);
+	spin_unlock_irqrestore(&clk_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+/* Set the clock's parent to another clock source */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	unsigned long flags;
+	struct clk *old;
+	int ret = -EINVAL;
+
+	if (!clk)
+		return ret;
+	if (!clk->set_parent || !parent)
+		return ret;
+
+	spin_lock_irqsave(&clk_lock, flags);
+	old = clk->parent;
+	if (clk->refcount)
+		__clk_enable(parent);
+	ret = clk->set_parent(clk, parent);
+	if (ret)
+		old = parent;
+	if (clk->refcount)
+		__clk_disable(old);
+	spin_unlock_irqrestore(&clk_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_parent);
+
+/* Retrieve the clock's parent clock source */
+struct clk *clk_get_parent(struct clk *clk)
+{
+	if (!clk)
+		return NULL;
+
+	return clk->parent;
+}
+EXPORT_SYMBOL_GPL(clk_get_parent);
+
+static struct clk clk_irc = {
+	.rate = 4000000
+};
+
+static struct clk clk_xtal;
+static struct clk clk_xrtc;
+
+static unsigned long pll_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	u32 pll_stat = clk_readl(PLLSTAT);
+
+	if (pll_stat & PLLE && pll_stat & PLLC)
+		rate = (2 * M(pll_stat) * rate) / N(pll_stat);
+
+	return rate;
+}
+
+static struct clk clk_pll = {
+	.parent = NULL,
+	.get_rate = pll_get_rate,
+};
+
+static unsigned long cpu_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	return rate / (CCLKSEL(clk_readl(CCLKCFG)) + 1);
+}
+
+static struct clk clk_cpu = {
+	.parent = &clk_pll,
+	.get_rate = cpu_get_rate,
+};
+
+static unsigned long usb_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	return rate / (USBSEL(clk_readl(USBCLKCFG)) + 1);
+}
+
+static struct clk clk_usb = {
+	.enable_mask = (1 << 31),
+	.parent = &clk_pll,
+	.get_rate = usb_get_rate,
+};
+
+static struct clk clk_apbpclk;
+
+static unsigned long pclkdiv[] = { 4, 1, 2, 8 };
+
+#define PERCLK(name, pnum)	\
+	static unsigned long name ## _get_rate(struct clk *clk) \
+	{	\
+		unsigned long rate = clk_get_rate(clk->parent);	\
+		u32 val = clk_readl((pnum < 16) ? PCLKSEL0 : PCLKSEL1); \
+		val >>= (pnum < 16) ? pnum * 2 : (pnum - 16) * 2;	\
+		return rate / pclkdiv[val & 3];	\
+	}	\
+	struct clk clk_ ## name = {	\
+		.parent = &clk_cpu,	\
+		.enable_mask = (1 << pnum),	\
+		.get_rate = name ## _get_rate,	\
+	}
+
+PERCLK(timer0, 1);
+PERCLK(timer1, 2);
+PERCLK(uart0, 3);
+PERCLK(uart1, 4);
+PERCLK(pwm0, 5);
+PERCLK(pwm1, 6);
+PERCLK(i2c0, 7);
+PERCLK(spi, 8);
+PERCLK(prtc, 9);
+PERCLK(ssp1, 10);
+PERCLK(emc, 11);
+PERCLK(adc, 12);
+PERCLK(can1, 13);
+PERCLK(can2, 14);
+PERCLK(i2c1, 19);
+PERCLK(lcd, 20);
+PERCLK(ssp0, 21);
+PERCLK(timer2, 22);
+PERCLK(timer3, 23);
+PERCLK(uart2, 24);
+PERCLK(uart3, 25);
+PERCLK(i2c2, 26);
+PERCLK(i2s, 27);
+PERCLK(mci, 28);
+PERCLK(dma, 29);
+PERCLK(eth, 30);
+
+#define INIT_CK(dev, con, ck)	\
+	{ .dev_id = dev, .con_id = con, .clk = ck }
+
+
+/* clk_rtc is a virtual clock used as glue to adjust at runtime
+ * if we're using the normal peripheral clock or an extern osc.
+ */
+static struct clk clk_rtc;
+
+static struct clk_lookup clocks[] = {
+	INIT_CK(NULL, "apb_pclk", &clk_apbpclk),
+	INIT_CK(NULL, "irc", &clk_irc),
+	INIT_CK(NULL, "xtal", &clk_xtal),
+	INIT_CK(NULL, "pll", &clk_pll),
+	INIT_CK(NULL, "cpu", &clk_cpu),
+	INIT_CK(NULL, "usb", &clk_usb),
+	INIT_CK(NULL, "timer0", &clk_timer0),
+	INIT_CK(NULL, "timer1", &clk_timer1),
+	INIT_CK(NULL, "timer2", &clk_timer2),
+	INIT_CK(NULL, "timer3", &clk_timer3),
+	INIT_CK("lpc2k-pwm.0", NULL, &clk_pwm0),
+	INIT_CK("lpc2k-pwm.1", NULL, &clk_pwm1),
+	INIT_CK("lpc2k-adc", NULL, &clk_adc),
+	INIT_CK("lpc2k-i2c.0", NULL, &clk_i2c0),
+	INIT_CK("lpc2k-i2c.1", NULL, &clk_i2c1),
+	INIT_CK("lpc2k-i2c.2", NULL, &clk_i2c2),
+	INIT_CK("serial8250.0", NULL, &clk_uart0),
+	INIT_CK("serial8250.1", NULL, &clk_uart1),
+	INIT_CK("serial8250.2", NULL, &clk_uart2),
+	INIT_CK("serial8250.3", NULL, &clk_uart3),
+	INIT_CK("lpc2k-ohci", NULL, &clk_usb),
+	INIT_CK("lpc2k-spi.0", NULL, &clk_ssp0),
+	INIT_CK("lpc2k-spi.1", NULL, &clk_ssp1),
+	INIT_CK("lpc2k-eth", NULL, &clk_eth),
+	INIT_CK("lpc2k-rtc", NULL, &clk_rtc),
+	INIT_CK("ssp0", NULL, &clk_ssp0),
+	INIT_CK("ssp1", NULL, &clk_ssp1),
+	INIT_CK("mci", NULL, &clk_mci),
+	INIT_CK("lcd", NULL, &clk_lcd),
+	INIT_CK("dma", NULL, &clk_dma),
+};
+
+void __init lpc2k_init_clocks(unsigned long xtal, unsigned long rtc)
+{
+	struct clk *pll_src_clk[] = { &clk_irc, &clk_xtal, &clk_xrtc };
+	int i;
+
+	clk_xtal.rate = xtal;
+
+	clk_pll.parent = pll_src_clk[CLKSRC(clk_readl(CLKSRCSEL))];
+	clk_xrtc.rate = rtc;
+	/* If no external RTC osc. is specified, make RTC clock child
+	   of peripheral RTC (CPU) clock */
+	clk_rtc.parent = rtc ? &clk_xrtc : &clk_prtc;
+
+	for (i = 0; i < ARRAY_SIZE(clocks); i++) {
+		pr_debug("clock '%s', rate %luHz\n",
+			clocks[i].con_id ? clocks[i].con_id : clocks[i].dev_id,
+			clk_get_rate(clocks[i].clk));
+
+		clkdev_add(&clocks[i]);
+	}
+}
diff --git a/arch/arm/mach-lpc2k/include/mach/clkdev.h b/arch/arm/mach-lpc2k/include/mach/clkdev.h
new file mode 100644
index 0000000..92267cc
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/clkdev.h
@@ -0,0 +1,17 @@
+/*
+ *  Copyright (C) 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef MACH_LPC2K_CLKDEV_H
+#define MACH_LPC2K_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif /* MACH_LPC2K_CLKDEV_H */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 4/9] lpc2k: generic time and clockevents
  2011-03-20 20:30 [PATCH v3 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
                   ` (2 preceding siblings ...)
  2011-03-20 20:30 ` [PATCH v3 3/9] lpc2k: clk API Ithamar R. Adema
@ 2011-03-20 20:30 ` Ithamar R. Adema
  2011-03-20 20:30 ` [PATCH v3 5/9] lpc2k: gpiolib Ithamar R. Adema
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Ithamar R. Adema @ 2011-03-20 20:30 UTC (permalink / raw)
  To: linux-arm-kernel

This code was mostly "borrowed" form the lpc32xx implementation.

Signed-off-by: Ithamar R. Adema <ithamar.adema@team-embedded.nl>
---
changes since v2:
        * Removed clk_put() from init code.
        * Added clk_get()/clk_enable() for timer0.

changes since v1:
        * make use of clockevents_calc_mult_shift.
---
 arch/arm/mach-lpc2k/Makefile |    2 +-
 arch/arm/mach-lpc2k/time.c   |  176 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 177 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-lpc2k/time.c

diff --git a/arch/arm/mach-lpc2k/Makefile b/arch/arm/mach-lpc2k/Makefile
index 9eb0a6a..267432c 100644
--- a/arch/arm/mach-lpc2k/Makefile
+++ b/arch/arm/mach-lpc2k/Makefile
@@ -1 +1 @@
-obj-y	:= clock.o irq.o
+obj-y	:= clock.o irq.o time.o
diff --git a/arch/arm/mach-lpc2k/time.c b/arch/arm/mach-lpc2k/time.c
new file mode 100644
index 0000000..1d1c9d6
--- /dev/null
+++ b/arch/arm/mach-lpc2k/time.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2011 Team Embeded VOF
+ *                    Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ * Copyright (C) 2009 - 2010 NXP Semiconductors
+ * Copyright (C) 2009 Fontys University of Applied Sciences, Eindhoven
+ *                    Ed Schouten <e.schouten@fontys.nl>
+ *                    Laurens Timmermans <l.timmermans@fontys.nl>
+ *
+ * Based on timer code from plat-lpc32xx.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/time.h>
+#include <linux/err.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+
+#include <asm/mach/time.h>
+
+#include <mach/hardware.h>
+
+#define IR		0x00
+#define TCR		0x04
+#define TC		0x08
+#define PR		0x0c
+#define PC		0x10
+#define MCR		0x14
+#define MR0		0x18
+#define MR1		0x1c
+#define MR2		0x20
+#define CCR		0x28
+#define CR0		0x2c
+#define CR1		0x30
+#define CR2		0x34
+#define CR3		0x38
+#define EMR		0x3c
+#define CTCR		0x70
+
+#define IR_MR_SHIFT	0
+#define IR_CR_SHIFT	4
+
+#define TCR_EN		(1 << 0)
+#define TCR_RESET	(1 << 1)
+
+
+static void __iomem *timer0 = (void __iomem *)APB_TIMER0_BASE;
+static void __iomem *timer1 = (void __iomem *)APB_TIMER1_BASE;
+
+static cycle_t lpc2k_clksrc_read(struct clocksource *cs)
+{
+	return __raw_readl(timer1 + TC);
+}
+
+static struct clocksource lpc2k_clksrc = {
+	.name	= "lpc2k_clksrc",
+	.rating	= 300,
+	.read	= lpc2k_clksrc_read,
+	.mask	= CLOCKSOURCE_MASK(32),
+	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int lpc2k_clkevt_next_event(unsigned long delta,
+	struct clock_event_device *dev)
+{
+	__raw_writel(TCR_RESET, timer0 + TCR);
+	__raw_writel(delta, timer0 + PR);
+	__raw_writel(TCR_EN, timer0 + TCR);
+
+	return 0;
+}
+
+static void lpc2k_clkevt_mode(enum clock_event_mode mode,
+	struct clock_event_device *dev)
+{
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		BUG();
+		break;
+
+	case CLOCK_EVT_MODE_ONESHOT:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		/*
+		 * Disable the timer. When using oneshot, we must also
+		 * disable the timer to wait for the first call to
+		 * set_next_event().
+		 */
+		__raw_writel(0, timer0 + TCR);
+		break;
+
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_RESUME:
+		break;
+	}
+}
+
+static struct clock_event_device lpc2k_clkevt = {
+	.name		= "lpc2k_clkevt",
+	.features	= CLOCK_EVT_FEAT_ONESHOT,
+	.rating		= 300,
+	.set_next_event	= lpc2k_clkevt_next_event,
+	.set_mode	= lpc2k_clkevt_mode,
+};
+
+static irqreturn_t lpc2k_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = &lpc2k_clkevt;
+
+	/* Clear match */
+	__raw_writel((1 << IR_MR_SHIFT), timer0 + IR);
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction lpc2k_timer_irq = {
+	.name		= "LPC2K Timer Tick",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= lpc2k_timer_interrupt,
+};
+
+/*
+ * The clock management driver isn't initialized at this point, so the
+ * clocks need to be enabled here manually and then tagged as used in
+ * the clock driver initialization
+ */
+static void __init lpc2k_timer_init(void)
+{
+	unsigned long rate;
+	struct clk *clk;
+
+	clk = clk_get(NULL, "timer1");
+	BUG_ON(IS_ERR(clk));
+	clk_enable(clk);
+
+	rate = clk_get_rate(clk);
+
+	clk = clk_get(NULL, "timer0");
+	BUG_ON(IS_ERR(clk));
+	clk_enable(clk);
+
+	/* Initial timer setup */
+	__raw_writel(0, timer0 + TCR);
+	__raw_writel(1 << IR_MR_SHIFT, timer0 + IR);
+	__raw_writel(1, timer0 + MR0);
+	__raw_writel(3 << 0, timer0 + MCR);
+
+	/* Setup tick interrupt */
+	setup_irq(IRQ_LPC2K_TIMER0, &lpc2k_timer_irq);
+
+	/* Setup the clockevent structure. */
+	clockevents_calc_mult_shift(&lpc2k_clkevt, rate, 5);
+	lpc2k_clkevt.max_delta_ns = clockevent_delta2ns(-1,
+		&lpc2k_clkevt);
+	lpc2k_clkevt.min_delta_ns = clockevent_delta2ns(1,
+		&lpc2k_clkevt) + 1;
+	lpc2k_clkevt.cpumask = cpumask_of(0);
+	clockevents_register_device(&lpc2k_clkevt);
+
+	/* Use timer1 as clock source. */
+	__raw_writel(TCR_RESET, timer1 + TCR);
+	__raw_writel(0, timer1 + PR);
+	__raw_writel(0, timer1 + MCR);
+	__raw_writel(TCR_EN, timer1 + TCR);
+	clocksource_register_hz(&lpc2k_clksrc, rate);
+}
+
+struct sys_timer lpc2k_timer = {
+	.init		= &lpc2k_timer_init,
+};
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 5/9] lpc2k: gpiolib
  2011-03-20 20:30 [PATCH v3 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
                   ` (3 preceding siblings ...)
  2011-03-20 20:30 ` [PATCH v3 4/9] lpc2k: generic time and clockevents Ithamar R. Adema
@ 2011-03-20 20:30 ` Ithamar R. Adema
  2011-03-20 20:30 ` [PATCH v3 6/9] lpc2k: multifunction pin configuration Ithamar R. Adema
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Ithamar R. Adema @ 2011-03-20 20:30 UTC (permalink / raw)
  To: linux-arm-kernel

gpiolib support, including gpio interrupts.

Signed-off-by: Ithamar R. Adema <ithamar.adema@team-embedded.nl>
---
changes since v2:
	* Added LPC2K_GPIO(port,pin) macro and used similar macros
	  to minimize declarations of GPIO IRQs.

no changes since v1.
---
 arch/arm/Kconfig                            |    1 +
 arch/arm/mach-lpc2k/Makefile                |    2 +-
 arch/arm/mach-lpc2k/gpio.c                  |  265 +++++++++++++++++++++++++++
 arch/arm/mach-lpc2k/include/mach/gpio.h     |   25 +++
 arch/arm/mach-lpc2k/include/mach/hardware.h |    2 +
 arch/arm/mach-lpc2k/include/mach/irqs.h     |    5 +-
 6 files changed, 298 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/mach-lpc2k/gpio.c
 create mode 100644 arch/arm/mach-lpc2k/include/mach/gpio.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b046a49..a95a232 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -498,6 +498,7 @@ config ARCH_LPC2K
 	select ARM_VIC
 	select CLKDEV_LOOKUP
 	select GENERIC_CLOCKEVENTS
+	select ARCH_REQUIRE_GPIOLIB
 	help
 	  Support for NXP LPC2K family of SoCs. These SoCs are based on
 	  an ARM7TDMI-S core, and have optional on-chip flash and SRAM,
diff --git a/arch/arm/mach-lpc2k/Makefile b/arch/arm/mach-lpc2k/Makefile
index 267432c..89596a7 100644
--- a/arch/arm/mach-lpc2k/Makefile
+++ b/arch/arm/mach-lpc2k/Makefile
@@ -1 +1 @@
-obj-y	:= clock.o irq.o time.o
+obj-y	:= clock.o irq.o gpio.o time.o
diff --git a/arch/arm/mach-lpc2k/gpio.c b/arch/arm/mach-lpc2k/gpio.c
new file mode 100644
index 0000000..b55864c
--- /dev/null
+++ b/arch/arm/mach-lpc2k/gpio.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2011 Team Embeded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+#define LPC2K_GPIO_CHIP(name, base_gpio, nr_gpio, irqbase)		\
+	{								\
+		.chip = {						\
+			.label		  = name,			\
+			.direction_input  = lpc2k_dir_input,		\
+			.direction_output = lpc2k_dir_output,		\
+			.to_irq           = lpc2k_to_irq,		\
+			.get		  = lpc2k_gpio_get,		\
+			.set		  = lpc2k_gpio_set,		\
+			.base		  = base_gpio,			\
+			.ngpio		  = nr_gpio,			\
+		},							\
+		.irq_base = irqbase,					\
+	}
+
+#define to_lpc2k_gpio_chip(c) container_of(c, struct lpc2k_gpio_chip, chip)
+
+#define FIODIR	0x00
+#define FIOMASK	0x10
+#define FIOPIN	0x14
+#define FIOSET	0x18
+#define FIOCLR	0x1c
+
+struct lpc2k_gpio_chip {
+	struct gpio_chip chip;
+	void __iomem *regbase;
+	int irq_base;
+	spinlock_t gpio_lock;
+};
+
+static int lpc2k_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	struct lpc2k_gpio_chip *lpc2k_gpio = to_lpc2k_gpio_chip(chip);
+	if (lpc2k_gpio->irq_base < 0)
+		return -EINVAL;
+
+	return lpc2k_gpio->irq_base + offset;
+}
+
+static int lpc2k_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct lpc2k_gpio_chip *lpc2k_gpio = to_lpc2k_gpio_chip(chip);
+
+	return !!(readl(lpc2k_gpio->regbase + FIOPIN) & (1 << offset));
+}
+
+static void lpc2k_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+	struct lpc2k_gpio_chip *lpc2k_gpio = to_lpc2k_gpio_chip(chip);
+
+	writel(1 << offset, lpc2k_gpio->regbase + (val ? FIOSET : FIOCLR));
+}
+
+static int lpc2k_dir_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct lpc2k_gpio_chip *lpc2k_gpio = to_lpc2k_gpio_chip(chip);
+	void __iomem *pio = lpc2k_gpio->regbase + FIODIR;
+	unsigned int regval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&lpc2k_gpio->gpio_lock, flags);
+
+	regval = readl(pio);
+	regval &= ~(1 << offset);
+	writel(regval, pio);
+
+	spin_unlock_irqrestore(&lpc2k_gpio->gpio_lock, flags);
+
+	return 0;
+}
+
+static int lpc2k_dir_output(struct gpio_chip *chip, unsigned offset, int val)
+{
+	struct lpc2k_gpio_chip *lpc2k_gpio = to_lpc2k_gpio_chip(chip);
+	unsigned int regval;
+	unsigned long flags;
+
+	spin_lock_irqsave(&lpc2k_gpio->gpio_lock, flags);
+
+	regval = readl(lpc2k_gpio->regbase + FIODIR);
+	regval |= (1 << offset);
+	writel(regval, lpc2k_gpio->regbase + FIODIR);
+
+	writel(1 << offset, lpc2k_gpio->regbase + (val ? FIOSET : FIOCLR));
+
+	spin_unlock_irqrestore(&lpc2k_gpio->gpio_lock, flags);
+
+	return 0;
+}
+
+static struct lpc2k_gpio_chip lpc2k_gpio[] = {
+	LPC2K_GPIO_CHIP("P0", 0, 32, IRQ_LPC2K_PORT0(0)),
+	LPC2K_GPIO_CHIP("P1", 32, 32, -1),
+	LPC2K_GPIO_CHIP("P2", 64, 32, IRQ_LPC2K_PORT2(0)),
+	LPC2K_GPIO_CHIP("P3", 96, 32, -1),
+	LPC2K_GPIO_CHIP("P4", 128, 32, -1),
+};
+
+#define IOINTSTAT	0x0080
+#define IO0INT		0x0084
+#define IO2INT		0x00a4
+
+#define IOINTSTATR	0x0000
+#define IOINTSTATF	0x0004
+#define IOINTCLR	0x0008
+#define IOINTENR	0x000c
+#define IOINTENF	0x0010
+
+static void lpc2k_gpio_enable_irq(struct irq_data *d)
+{
+	void __iomem *base = irq_data_get_irq_chip_data(d);
+	unsigned irq = d->irq & 31;
+	unsigned status = irq_to_desc(d->irq)->status;
+
+	status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
+	if (!status)
+		status = IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
+
+	if (status & IRQ_TYPE_EDGE_RISING)
+		writel(readl(base + IOINTENR) | (1 << irq), base + IOINTENR);
+	else
+		writel(readl(base + IOINTENR) & ~(1 << irq), base + IOINTENR);
+
+	if (status & IRQ_TYPE_EDGE_FALLING)
+		writel(readl(base + IOINTENF) | (1 << irq), base + IOINTENF);
+	else
+		writel(readl(base + IOINTENF) & ~(1 << irq), base + IOINTENF);
+}
+
+static void lpc2k_gpio_disable_irq(struct irq_data *d)
+{
+	void __iomem *base = irq_data_get_irq_chip_data(d);
+	unsigned irq = d->irq & 31;
+
+	writel(readl(base + IOINTENR) & ~(1 << irq), base + IOINTENR);
+	writel(readl(base + IOINTENF) & ~(1 << irq), base + IOINTENF);
+}
+
+static int lpc2k_gpio_set_type(struct irq_data *d, unsigned trigger)
+{
+	void __iomem *base = irq_data_get_irq_chip_data(d);
+	struct irq_desc *desc = irq_to_desc(d->irq);
+	unsigned irq = d->irq & 31;
+
+	if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+		return -EINVAL;
+
+	desc->status &= ~IRQ_TYPE_SENSE_MASK;
+	desc->status |= trigger;
+
+	/* don't enable the IRQ if it's currently disabled */
+	if (desc->depth == 0) {
+		if (trigger & IRQ_TYPE_EDGE_RISING)
+			writel(readl(base + IOINTENR) | (1 << irq),
+			       base + IOINTENR);
+		else
+			writel(readl(base + IOINTENR) & ~(1 << irq),
+			       base + IOINTENR);
+
+		if (trigger & IRQ_TYPE_EDGE_FALLING)
+			writel(readl(base + IOINTENF) | (1 << irq),
+			       base + IOINTENF);
+		else
+			writel(readl(base + IOINTENF) & ~(1 << irq),
+			       base + IOINTENF);
+	}
+
+	return 0;
+}
+
+struct irq_chip gpio_irq_chip_p0 = {
+	.name = "GPIO-P0",
+	.irq_enable = lpc2k_gpio_enable_irq,
+	.irq_disable = lpc2k_gpio_disable_irq,
+	.irq_set_type = lpc2k_gpio_set_type,
+};
+
+struct irq_chip gpio_irq_chip_p2 = {
+	.name = "GPIO-P2",
+	.irq_enable = lpc2k_gpio_enable_irq,
+	.irq_disable = lpc2k_gpio_disable_irq,
+	.irq_set_type = lpc2k_gpio_set_type,
+};
+
+static void lpc2k_demux_gpio_irq(unsigned int irq, struct irq_desc *desc)
+{
+	u32 status = readl(APB_GPIO_BASE + IOINTSTAT);
+	if (status & 1) {
+		int i, stat = readl(APB_GPIO_BASE + IO0INT + IOINTSTATR) |
+		    readl(APB_GPIO_BASE + IO0INT + IOINTSTATF);
+
+		writel(stat, APB_GPIO_BASE + IO0INT + IOINTCLR);
+
+		for (i = 0; i < 32; i++)
+			if (stat & (1 << i))
+				generic_handle_irq(IRQ_LPC2K_PORT0(i));
+	}
+
+	if (status & 4) {
+		int i, stat = readl(APB_GPIO_BASE + IO2INT + IOINTSTATR) |
+		    readl(APB_GPIO_BASE + IO2INT + IOINTSTATF);
+
+		writel(stat, APB_GPIO_BASE + IO2INT + IOINTCLR);
+
+		for (i = 0; i < 32; i++)
+			if (stat & (1 << i))
+				generic_handle_irq(IRQ_LPC2K_PORT2(i));
+	}
+}
+
+static int __init lpc2k_init_gpio(void)
+{
+	struct lpc2k_gpio_chip *gpio_chip;
+	void __iomem *base;
+	unsigned i;
+
+	for (i = 0; i < ARRAY_SIZE(lpc2k_gpio); i++) {
+		gpio_chip = &lpc2k_gpio[i];
+		spin_lock_init(&gpio_chip->gpio_lock);
+		gpio_chip->regbase =
+		    (void __iomem *)(FAST_GPIO_BASE + i * 0x20);
+		gpiochip_add(&gpio_chip->chip);
+
+		writel(0, gpio_chip->regbase + FIOMASK);
+	}
+
+	base = (void __iomem *)(APB_GPIO_BASE + IO0INT);
+	for (i = IRQ_LPC2K_PORT0(0); i <= IRQ_LPC2K_PORT0(31); i++) {
+		set_irq_chip(i, &gpio_irq_chip_p0);
+		set_irq_chip_data(i, base);
+		set_irq_handler(i, handle_simple_irq);
+		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+	}
+
+	base = (void __iomem *)(APB_GPIO_BASE + IO2INT);
+	for (i = IRQ_LPC2K_PORT2(0); i <= IRQ_LPC2K_PORT2(31); i++) {
+		set_irq_chip(i, &gpio_irq_chip_p2);
+		set_irq_chip_data(i, base);
+		set_irq_handler(i, handle_simple_irq);
+		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+	}
+
+	set_irq_chained_handler(IRQ_LPC2K_EINT3, lpc2k_demux_gpio_irq);
+
+	return 0;
+}
+
+postcore_initcall(lpc2k_init_gpio);
diff --git a/arch/arm/mach-lpc2k/include/mach/gpio.h b/arch/arm/mach-lpc2k/include/mach/gpio.h
new file mode 100644
index 0000000..533e3da
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/gpio.h
@@ -0,0 +1,25 @@
+/*
+ *  Copyright (C) 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef MACH_LPC2K_GPIO_H
+#define MACH_LPC2K_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value		__gpio_get_value
+#define gpio_set_value		__gpio_set_value
+#define gpio_cansleep		__gpio_cansleep
+#define gpio_to_irq		__gpio_to_irq
+
+/* Convert from PX.Y notation to GPIO number */
+#define LPC2K_GPIO(port,pin)	(((port) * 32) + (pin))
+
+#endif /* MACH_LPC2K_GPIO_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/hardware.h b/arch/arm/mach-lpc2k/include/mach/hardware.h
index 3463b47..b8c471b 100644
--- a/arch/arm/mach-lpc2k/include/mach/hardware.h
+++ b/arch/arm/mach-lpc2k/include/mach/hardware.h
@@ -15,10 +15,12 @@
 /* Default memory size if no ATAGS found */
 #define MEM_SIZE	(SZ_32M)
 
+#define FAST_GPIO_BASE		0x3fffc000
 #define APB_WDT_BASE		0xe0000000
 #define APB_TIMER0_BASE		0xe0004000
 #define APB_TIMER1_BASE		0xe0008000
 #define APB_UART0_BASE		0xe000c000
+#define APB_GPIO_BASE		0xe0028000
 #define APB_SCB_BASE		0xe01fc000
 #define APH_VIC_BASE		0xfffff000
 
diff --git a/arch/arm/mach-lpc2k/include/mach/irqs.h b/arch/arm/mach-lpc2k/include/mach/irqs.h
index 87b80dd..9207702 100644
--- a/arch/arm/mach-lpc2k/include/mach/irqs.h
+++ b/arch/arm/mach-lpc2k/include/mach/irqs.h
@@ -44,6 +44,9 @@
 #define IRQ_LPC2K_I2C2		30
 #define IRQ_LPC2K_I2S		31
 
-#define NR_IRQS			32
+#define IRQ_LPC2K_PORT0(pin)	(32 + (pin))
+#define IRQ_LPC2K_PORT2(pin)	(64 + (pin))
+
+#define NR_IRQS			96
 
 #endif /* MACH_LPC2K_IRQS_H */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 6/9] lpc2k: multifunction pin configuration
  2011-03-20 20:30 [PATCH v3 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
                   ` (4 preceding siblings ...)
  2011-03-20 20:30 ` [PATCH v3 5/9] lpc2k: gpiolib Ithamar R. Adema
@ 2011-03-20 20:30 ` Ithamar R. Adema
  2011-03-20 20:30 ` [PATCH v3 7/9] lpc2k: Add EmbeddedArtists LPC2478 Developer's Kit board Ithamar R. Adema
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Ithamar R. Adema @ 2011-03-20 20:30 UTC (permalink / raw)
  To: linux-arm-kernel

Inspired by the mfp support in PXA. Includes definition of pins
for NXP LPC2468/78.

Signed-off-by: Ithamar R. Adema <ithamar.adema@team-embedded.nl>
---
changes since v2:
	* Removed MFP_PIN_* enum.
	* Renamed GPIOx_signal defines to Px_y_signal.

no changes since v1.
---
 arch/arm/mach-lpc2k/Makefile                   |    2 +-
 arch/arm/mach-lpc2k/include/mach/hardware.h    |    1 +
 arch/arm/mach-lpc2k/include/mach/mfp-lpc24xx.h |   98 +++++++++++++++++++++++
 arch/arm/mach-lpc2k/include/mach/mfp.h         |   43 ++++++++++
 arch/arm/mach-lpc2k/mfp.c                      |  100 ++++++++++++++++++++++++
 5 files changed, 243 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-lpc2k/include/mach/mfp-lpc24xx.h
 create mode 100644 arch/arm/mach-lpc2k/include/mach/mfp.h
 create mode 100644 arch/arm/mach-lpc2k/mfp.c

diff --git a/arch/arm/mach-lpc2k/Makefile b/arch/arm/mach-lpc2k/Makefile
index 89596a7..2c50bb9 100644
--- a/arch/arm/mach-lpc2k/Makefile
+++ b/arch/arm/mach-lpc2k/Makefile
@@ -1 +1 @@
-obj-y	:= clock.o irq.o gpio.o time.o
+obj-y	:= clock.o irq.o gpio.o mfp.o time.o
diff --git a/arch/arm/mach-lpc2k/include/mach/hardware.h b/arch/arm/mach-lpc2k/include/mach/hardware.h
index b8c471b..1a20126 100644
--- a/arch/arm/mach-lpc2k/include/mach/hardware.h
+++ b/arch/arm/mach-lpc2k/include/mach/hardware.h
@@ -21,6 +21,7 @@
 #define APB_TIMER1_BASE		0xe0008000
 #define APB_UART0_BASE		0xe000c000
 #define APB_GPIO_BASE		0xe0028000
+#define APB_PINSEL_BASE		0xe002c000
 #define APB_SCB_BASE		0xe01fc000
 #define APH_VIC_BASE		0xfffff000
 
diff --git a/arch/arm/mach-lpc2k/include/mach/mfp-lpc24xx.h b/arch/arm/mach-lpc2k/include/mach/mfp-lpc24xx.h
new file mode 100644
index 0000000..dafb8f1
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/mfp-lpc24xx.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 MACH_LPC2K_MFP_LPC24XX_H
+#define MACH_LPC2K_MFP_LPC24XX_H
+
+#include <mach/mfp.h>
+
+#define P0_0_RD1		MFP_CFG(LPC2K_GPIO(0,0), AF1)
+#define P0_0_TXD3		MFP_CFG(LPC2K_GPIO(0,0), AF2)
+#define P0_0_SDA1		MFP_CFG(LPC2K_GPIO(0,0), AF3)
+#define P0_1_TD1		MFP_CFG(LPC2K_GPIO(0,1), AF1)
+#define P0_1_RXD3		MFP_CFG(LPC2K_GPIO(0,1), AF2)
+#define P0_1_SCL1		MFP_CFG(LPC2K_GPIO(0,1), AF3)
+#define P0_2_TXD0		MFP_CFG(LPC2K_GPIO(0,2), AF1)
+#define P0_3_RXD0		MFP_CFG(LPC2K_GPIO(0,3), AF1)
+#define P0_4_LCDVD0		MFP_CFG(LPC2K_GPIO(0,4), AF1)
+#define P0_5_LCDVD1		MFP_CFG(LPC2K_GPIO(0,5), AF1)
+#define P0_6_LCDVD8		MFP_CFG(LPC2K_GPIO(0,6), AF1)
+#define P0_7_LCDVD9		MFP_CFG(LPC2K_GPIO(0,7), AF1)
+#define P0_8_LCDVD16		MFP_CFG(LPC2K_GPIO(0,8), AF1)
+#define P0_9_LCDVD17		MFP_CFG(LPC2K_GPIO(0,9), AF1)
+#define P0_10_TXD2		MFP_CFG(LPC2K_GPIO(0,10), AF1)
+#define P0_11_RXD2		MFP_CFG(LPC2K_GPIO(0,11), AF1)
+#define P0_12_USB_PPWR2		MFP_CFG(LPC2K_GPIO(0,12), AF1)
+#define P0_13_USB_UP_LED2	MFP_CFG(LPC2K_GPIO(0,13), AF1)
+#define P0_15_SCK		MFP_CFG(LPC2K_GPIO(0,15), AF3)
+#define P0_17_MISO		MFP_CFG(LPC2K_GPIO(0,17), AF3)
+#define P0_18_MOSI		MFP_CFG(LPC2K_GPIO(0,18), AF3)
+#define P0_27_SDA0		MFP_CFG(LPC2K_GPIO(0,27), AF1)
+#define P0_28_SCL0		MFP_CFG(LPC2K_GPIO(0,28), AF1)
+#define P0_29_USB_Dp1		MFP_CFG(LPC2K_GPIO(0,29), AF1)
+#define P0_30_USB_Dn1		MFP_CFG(LPC2K_GPIO(0,30), AF1)
+#define P0_31_USB_Dp2		MFP_CFG(LPC2K_GPIO(0,31), AF1)
+#define P1_0_ENET_TXD0		MFP_CFG(LPC2K_GPIO(1,0), AF1)
+#define P1_1_ENET_TXD1		MFP_CFG(LPC2K_GPIO(1,1), AF1)
+#define P1_2_MCICLK		MFP_CFG(LPC2K_GPIO(1,2), AF2)
+#define P1_3_MCICMD		MFP_CFG(LPC2K_GPIO(1,3), AF2)
+#define P1_4_ENET_TX_EN		MFP_CFG(LPC2K_GPIO(1,4), AF1)
+#define P1_5_MCIPWR		MFP_CFG(LPC2K_GPIO(1,5), AF2)
+#define P1_6_ENET_TX_CLK	MFP_CFG(LPC2K_GPIO(1,6), AF1)
+#define P1_6_MCIDAT0		MFP_CFG(LPC2K_GPIO(1,6), AF2)
+#define P1_7_MCIDAT1		MFP_CFG(LPC2K_GPIO(1,7), AF2)
+#define P1_8_ENET_CRS		MFP_CFG(LPC2K_GPIO(1,8), AF1)
+#define P1_9_ENET_RXD0		MFP_CFG(LPC2K_GPIO(1,9), AF1)
+#define P1_10_ENET_RXD1		MFP_CFG(LPC2K_GPIO(1,10), AF1)
+#define P1_11_MCIDAT2		MFP_CFG(LPC2K_GPIO(1,11), AF2)
+#define P1_12_MCIDAT3		MFP_CFG(LPC2K_GPIO(1,12), AF2)
+#define P1_14_ENET_RX_ERR	MFP_CFG(LPC2K_GPIO(1,14), AF1)
+#define P1_15_ENET_REF_CLK	MFP_CFG(LPC2K_GPIO(1,15), AF1)
+#define P1_16_ENET_MDC		MFP_CFG(LPC2K_GPIO(1,16), AF1)
+#define P1_17_ENET_MDIO		MFP_CFG(LPC2K_GPIO(1,17), AF1)
+#define P1_18_PWM1		MFP_CFG(LPC2K_GPIO(1,18), AF2)
+#define P1_20_LCDVD10		MFP_CFG(LPC2K_GPIO(1,20), AF1)
+#define P1_21_LCDVD11		MFP_CFG(LPC2K_GPIO(1,21), AF1)
+#define P1_22_LCDVD12		MFP_CFG(LPC2K_GPIO(1,22), AF1)
+#define P1_23_LCDVD13		MFP_CFG(LPC2K_GPIO(1,23), AF1)
+#define P1_24_LCDVD14		MFP_CFG(LPC2K_GPIO(1,24), AF1)
+#define P1_25_LCDVD15		MFP_CFG(LPC2K_GPIO(1,25), AF1)
+#define P1_26_LCDVD20		MFP_CFG(LPC2K_GPIO(1,26), AF1)
+#define P1_27_LCDVD21		MFP_CFG(LPC2K_GPIO(1,27), AF1)
+#define P1_28_LCDVD22		MFP_CFG(LPC2K_GPIO(1,28), AF1)
+#define P1_29_LCDVD23		MFP_CFG(LPC2K_GPIO(1,29), AF1)
+#define P1_30_VBUS		MFP_CFG(LPC2K_GPIO(1,30), AF2)
+#define P1_31_USB_OVRCR2	MFP_CFG(LPC2K_GPIO(1,31), AF1)
+#define P2_0_LCDPWR		MFP_CFG(LPC2K_GPIO(2,0), AF3)
+#define P2_1_LCDLE		MFP_CFG(LPC2K_GPIO(2,1), AF3)
+#define P2_2_LCDDCLK		MFP_CFG(LPC2K_GPIO(2,2), AF3)
+#define P2_3_LCDFP		MFP_CFG(LPC2K_GPIO(2,3), AF3)
+#define P2_4_LCDM		MFP_CFG(LPC2K_GPIO(2,4), AF3)
+#define P2_5_LCDLP		MFP_CFG(LPC2K_GPIO(2,5), AF3)
+#define P2_6_LCDVP4		MFP_CFG(LPC2K_GPIO(2,6), AF3)
+#define P2_7_LCDVP5		MFP_CFG(LPC2K_GPIO(2,7), AF3)
+#define P2_8_LCDVP6		MFP_CFG(LPC2K_GPIO(2,8), AF3)
+#define P2_9_LCDVP7		MFP_CFG(LPC2K_GPIO(2,9), AF3)
+#define P2_11_LCDCLKIN		MFP_CFG(LPC2K_GPIO(2,11), AF1)
+#define P2_12_LCDVP18		MFP_CFG(LPC2K_GPIO(2,12), AF1)
+#define P2_13_LCDVP19		MFP_CFG(LPC2K_GPIO(2,13), AF1)
+#define P3_16_TXD1		MFP_CFG(LPC2K_GPIO(3,16), AF3)
+#define P3_17_RXD1		MFP_CFG(LPC2K_GPIO(3,17), AF3)
+#define P3_18_CTS1		MFP_CFG(LPC2K_GPIO(3,18), AF3)
+#define P3_19_DCD1		MFP_CFG(LPC2K_GPIO(3,19), AF3)
+#define P3_20_DSR1		MFP_CFG(LPC2K_GPIO(3,20), AF3)
+#define P3_21_DR1		MFP_CFG(LPC2K_GPIO(3,21), AF3)
+#define P3_22_RI1		MFP_CFG(LPC2K_GPIO(3,22), AF3)
+#define P3_30_RTS1		MFP_CFG(LPC2K_GPIO(3,30), AF3)
+#define P4_28_TXD3		MFP_CFG(LPC2K_GPIO(4,28), AF3)
+#define P4_28_LCDVP2		MFP_CFG(LPC2K_GPIO(4,28), AF2)
+#define P4_29_RXD3		MFP_CFG(LPC2K_GPIO(4,29), AF3)
+#define P4_29_LCDVP3		MFP_CFG(LPC2K_GPIO(4,29), AF2)
+
+#endif /* MACH_LPC2K_MFP_LPC24XX_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/mfp.h b/arch/arm/mach-lpc2k/include/mach/mfp.h
new file mode 100644
index 0000000..c3d0378
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/mfp.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 ARCH_LPC2K_MFP_H
+#define ARCH_LPC2K_MFP_H
+
+#define mfp_to_gpio(m)	((m) % 160)
+
+/* pin number; currently only 0-159 are used */
+#define MFP_PIN(x)	((x) & 0x3ff)
+
+/* Alternate functions, currently only 0-3 are used */
+#define MFP_AF0		(0x0 << 10)
+#define MFP_AF1		(0x1 << 10)
+#define MFP_AF2		(0x2 << 10)
+#define MFP_AF3		(0x3 << 10)
+#define MFP_AF_MASK	(0x3 << 10)
+#define MFP_AF(x)	(((x) >> 10) & 0x3)
+
+/* Pullup/down configuration, currently only none/high/low are used */
+#define MFP_PULL_NONE	(0x2 << 21)
+#define MFP_PULL_LOW	(0x3 << 21)
+#define MFP_PULL_HIGH	(0x0 << 21)
+#define MFP_PULL_MASK	(0x3 << 21)
+#define MFP_PULL(x)	(((x) >> 21) & 0x3)
+
+#define MFP_CFG_DEFAULT	(MFP_PULL_HIGH | MFP_AF0)
+
+#define MFP_CFG(pin, af)		\
+	((MFP_CFG_DEFAULT & ~MFP_AF_MASK) |\
+	 (MFP_PIN(pin) | MFP_##af))
+
+#define MFP_CFG_PULL(pin, af, pull)	\
+	((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_PULL_MASK)) |\
+	 (MFP_PIN(pin) | MFP_##af | MFP_##pull))
+
+#endif /* ARCH_LPC2K_MFP_H */
diff --git a/arch/arm/mach-lpc2k/mfp.c b/arch/arm/mach-lpc2k/mfp.c
new file mode 100644
index 0000000..c0d356b
--- /dev/null
+++ b/arch/arm/mach-lpc2k/mfp.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2011 Team Embeded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * Based on MFP code from mach-pxa.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/mfp.h>
+
+#define PINSEL(bank)	(0x00 + (bank)*4)
+#define PINMODE(bank)	(0x40 + (bank)*4)
+
+struct gpio_desc {
+	unsigned valid:1;
+	unsigned long config;
+};
+
+static struct gpio_desc gpio_desc[LPC2K_GPIO(4,31) + 1];
+
+static int __mfp_config_gpio(unsigned gpio, unsigned long c)
+{
+	unsigned bank = gpio >> 4;
+	unsigned shift = (gpio & 0xf) * 2;
+	unsigned val;
+
+	/* Configure alternate function */
+	val = __raw_readl(APB_PINSEL_BASE + PINSEL(bank));
+	if ((val & (3 << shift)) &&
+	    (val & (3 << shift)) != (MFP_AF(c) << shift))
+		pr_warning
+		    ("GPIO%d is already configured (%x), not reconfigured!\n",
+		     gpio, (val & (3 << shift)) >> shift);
+	else {
+		val &= ~(0x3 << shift);
+		val |= MFP_AF(c) << shift;
+		__raw_writel(val, APB_PINSEL_BASE + PINSEL(bank));
+	}
+
+	/* Configuration pullup/dn */
+	val = __raw_readl(APB_PINSEL_BASE + PINMODE(bank));
+	val &= ~(0x3 << shift);
+	val |= MFP_PULL(c) << shift;
+	__raw_writel(val, APB_PINSEL_BASE + PINMODE(bank));
+
+	return 0;
+}
+
+static inline int __mfp_validate(int mfp)
+{
+	int gpio = mfp_to_gpio(mfp);
+
+	if (!gpio_desc[gpio].valid) {
+		pr_warning("%s: GPIO%d is invalid pin\n", __func__, gpio);
+		return -1;
+	}
+
+	return gpio;
+}
+
+void lpc2k_mfp_config(unsigned long *mfp_cfgs, int num)
+{
+	unsigned long flags;
+	unsigned long *c;
+	int i, gpio;
+
+	for (i = 0, c = mfp_cfgs; i < num; i++, c++) {
+
+		gpio = __mfp_validate(MFP_PIN(*c));
+		if (gpio < 0)
+			continue;
+
+		local_irq_save(flags);
+
+		gpio_desc[gpio].config = *c;
+		__mfp_config_gpio(gpio, *c);
+
+		local_irq_restore(flags);
+	}
+}
+
+static int __init lpc2k_mfp_init(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(gpio_desc); i++)
+		gpio_desc[i].valid = 1;
+
+	return 0;
+}
+
+postcore_initcall(lpc2k_mfp_init);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 7/9] lpc2k: Add EmbeddedArtists LPC2478 Developer's Kit board
  2011-03-20 20:30 [PATCH v3 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
                   ` (5 preceding siblings ...)
  2011-03-20 20:30 ` [PATCH v3 6/9] lpc2k: multifunction pin configuration Ithamar R. Adema
@ 2011-03-20 20:30 ` Ithamar R. Adema
  2011-03-20 20:30 ` [PATCH v3 8/9] lpc2k: Add UART, SSP, and MCI devices Ithamar R. Adema
  2011-03-20 20:30 ` [PATCH v3 9/9] lpc2k: defconfig for NXP LPC2K platform Ithamar R. Adema
  8 siblings, 0 replies; 12+ messages in thread
From: Ithamar R. Adema @ 2011-03-20 20:30 UTC (permalink / raw)
  To: linux-arm-kernel

Add support for EmbeddedArtists LPC2478 Developer's Kit, consisting
of the LPC2478OEM board, with QVGA base board. For details, see:

http://www.embeddedartists.com/products/kits/lpc2478_kit.php

The mach-types change included is simply one generated from
http://www.arm.linux.org.uk/developer/machines/, and is only
included so this patch can be build.

Signed-off-by: Ithamar R. Adema <ithamar.adema@team-embedded.nl>
---
changes since v2:
        * Changed machine name from web interface, and
          included mach-types update generated from there.

changes since v1:
        * Fixed RTC clock rate
        * Marked mfp_cfgs as __initdata.
        * renamed LPC2478OEM to more appropriate EA2478DEVKIT.
---
 arch/arm/mach-lpc2k/Kconfig             |    7 ++
 arch/arm/mach-lpc2k/Makefile            |    2 +
 arch/arm/mach-lpc2k/common.h            |   21 +++++
 arch/arm/mach-lpc2k/mach-ea2478devkit.c |  122 +++++++++++++++++++++++++++++++
 arch/arm/tools/mach-types               |  113 +++++++++++++++++++++-------
 5 files changed, 237 insertions(+), 28 deletions(-)
 create mode 100644 arch/arm/mach-lpc2k/common.h
 create mode 100644 arch/arm/mach-lpc2k/mach-ea2478devkit.c

diff --git a/arch/arm/mach-lpc2k/Kconfig b/arch/arm/mach-lpc2k/Kconfig
index fad47b8..210b641 100644
--- a/arch/arm/mach-lpc2k/Kconfig
+++ b/arch/arm/mach-lpc2k/Kconfig
@@ -2,4 +2,11 @@ if ARCH_LPC2K
 
 comment "LPC2K machines"
 
+config MACH_EA2478DEVKIT
+	bool "Embedded Artists LPC2478 Developer's Kit"
+	help
+	  Say Y if you want the kernel to support the EmbeddedArtists
+	  LPC2478 Developer's Kit. For more hardware details, see:
+	  http://www.embeddedartists.com/products/kits/lpc2478_kit.php
+
 endif
diff --git a/arch/arm/mach-lpc2k/Makefile b/arch/arm/mach-lpc2k/Makefile
index 2c50bb9..93e27fb 100644
--- a/arch/arm/mach-lpc2k/Makefile
+++ b/arch/arm/mach-lpc2k/Makefile
@@ -1 +1,3 @@
 obj-y	:= clock.o irq.o gpio.o mfp.o time.o
+
+obj-$(CONFIG_MACH_EA2478DEVKIT) += mach-ea2478devkit.o
diff --git a/arch/arm/mach-lpc2k/common.h b/arch/arm/mach-lpc2k/common.h
new file mode 100644
index 0000000..6b775d9
--- /dev/null
+++ b/arch/arm/mach-lpc2k/common.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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 LPC2K_COMMON_H
+#define LPC2K_COMMON_H
+
+struct sys_timer;
+
+extern void lpc2k_init_clocks(unsigned long xtal, unsigned long rtc);
+extern void lpc2k_mfp_config(unsigned long *mfp_cfgs, int num);
+extern void lpc2k_init_irq(void);
+
+extern struct sys_timer lpc2k_timer;
+
+#endif /* LPC2K_COMMON_H */
diff --git a/arch/arm/mach-lpc2k/mach-ea2478devkit.c b/arch/arm/mach-lpc2k/mach-ea2478devkit.c
new file mode 100644
index 0000000..d59f5ba
--- /dev/null
+++ b/arch/arm/mach-lpc2k/mach-ea2478devkit.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2011 Team Embeded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/mfp-lpc24xx.h>
+#include <mach/hardware.h>
+
+#include "common.h"
+
+#define EXTPOLAR	0x14c
+
+static unsigned long mfp_cfgs[] __initdata = {
+	/* UART0 */
+	P0_2_TXD0,
+	P0_3_RXD0,
+	/* USB Host */
+	P0_12_USB_PPWR2,
+	P0_13_USB_UP_LED2,
+	P0_31_USB_Dp2,
+	P1_30_VBUS,
+	P1_31_USB_OVRCR2,
+	/* USB Gadget */
+	P0_29_USB_Dp1,
+	P0_30_USB_Dn1,
+	/* Ethernet */
+	P1_0_ENET_TXD0,
+	P1_1_ENET_TXD1,
+	P1_4_ENET_TX_EN,
+	P1_8_ENET_CRS,
+	P1_9_ENET_RXD0,
+	P1_10_ENET_RXD1,
+	P1_14_ENET_RX_ERR,
+	P1_15_ENET_REF_CLK,
+	P1_16_ENET_MDC,
+	P1_17_ENET_MDIO,
+	/* I2C0 */
+	P0_27_SDA0,
+	P0_28_SCL0,
+	/* SPI */
+	P0_15_SCK,
+	P0_17_MISO,
+	P0_18_MOSI,
+	/* LCD */
+	P0_4_LCDVD0,
+	P0_5_LCDVD1,
+	P0_6_LCDVD8,
+	P0_7_LCDVD9,
+	P0_8_LCDVD16,
+	P0_9_LCDVD17,
+	P1_20_LCDVD10,
+	P1_21_LCDVD11,
+	P1_22_LCDVD12,
+	P1_23_LCDVD13,
+	P1_24_LCDVD14,
+	P1_25_LCDVD15,
+	P1_26_LCDVD20,
+	P1_27_LCDVD21,
+	P1_28_LCDVD22,
+	P1_29_LCDVD23,
+	P2_0_LCDPWR,
+	P2_1_LCDLE,
+	P2_2_LCDDCLK,
+	P2_3_LCDFP,
+	P2_4_LCDM,
+	P2_5_LCDLP,
+	P2_6_LCDVP4,
+	P2_7_LCDVP5,
+	P2_8_LCDVP6,
+	P2_9_LCDVP7,
+	P2_11_LCDCLKIN,
+	P2_12_LCDVP18,
+	P2_13_LCDVP19,
+	P4_28_LCDVP2,
+	P4_29_LCDVP3,
+	/* Backlight */
+	P1_18_PWM1,
+	/* MMC/SD */
+	P1_2_MCICLK,
+	P1_3_MCICMD,
+	P1_5_MCIPWR,
+	P1_6_MCIDAT0,
+	P1_7_MCIDAT1,
+	P1_11_MCIDAT2,
+	P1_12_MCIDAT3,
+};
+
+void __init ea2478devkit_init_machine(void)
+{
+	lpc2k_mfp_config(mfp_cfgs, ARRAY_SIZE(mfp_cfgs));
+}
+
+static void __init ea2478devkit_init_irq(void)
+{
+	/* XXX workaround for the fact that EINT3 is connected to high-active
+	 * signal, but can't be disabled. As the EINT3 interrupt is also used
+	 * for GPIO interrupts, this will cause an interrupt storm without
+	 * this setting.
+	 */
+	iowrite32(ioread32(APB_SCB_BASE + EXTPOLAR) | (1 << 3),
+		APB_SCB_BASE + EXTPOLAR);
+
+	lpc2k_init_irq();
+	lpc2k_init_clocks(12000000UL, 32768UL);
+}
+
+MACHINE_START(EA2478DEVKIT, "Embedded Artists LPC2478 Developer's Kit")
+	.init_irq	= ea2478devkit_init_irq,
+	.timer		= &lpc2k_timer,
+	.init_machine	= ea2478devkit_init_machine,
+MACHINE_END
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 9d6feaa..852cc95 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Mon Feb 7 08:59:27 2011
+# Last update: Fri Mar 18 20:55:51 2011
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -1319,7 +1319,6 @@ mistral			MACH_MISTRAL		MISTRAL			1315
 msm			MACH_MSM		MSM			1316
 ct5910			MACH_CT5910		CT5910			1317
 ct5912			MACH_CT5912		CT5912			1318
-hynet_ine		MACH_HYNET_INE		HYNET_INE		1319
 hynet_app		MACH_HYNET_APP		HYNET_APP		1320
 msm7200			MACH_MSM7200		MSM7200			1321
 msm7600			MACH_MSM7600		MSM7600			1322
@@ -1777,7 +1776,6 @@ wdg002			MACH_WDG002		WDG002			1785
 sg560adsl		MACH_SG560ADSL		SG560ADSL		1786
 nextio_n2800_ica	MACH_NEXTIO_N2800_ICA	NEXTIO_N2800_ICA	1787
 dove_db			MACH_DOVE_DB		DOVE_DB			1788
-marvell_newdb		MACH_MARVELL_NEWDB	MARVELL_NEWDB		1789
 vandihud		MACH_VANDIHUD		VANDIHUD		1790
 magx_e8			MACH_MAGX_E8		MAGX_E8			1791
 magx_z6			MACH_MAGX_Z6		MAGX_Z6			1792
@@ -1877,7 +1875,6 @@ ued			MACH_UED		UED			1885
 esiblade		MACH_ESIBLADE		ESIBLADE		1886
 eye02			MACH_EYE02		EYE02			1887
 imx27kbd		MACH_IMX27KBD		IMX27KBD		1888
-sst61vc010_fpga		MACH_SST61VC010_FPGA	SST61VC010_FPGA		1889
 kixvp435		MACH_KIXVP435		KIXVP435		1890
 kixnp435		MACH_KIXNP435		KIXNP435		1891
 africa			MACH_AFRICA		AFRICA			1892
@@ -2308,7 +2305,6 @@ ecac2378		MACH_ECAC2378		ECAC2378		2319
 tazkiosk		MACH_TAZKIOSK		TAZKIOSK		2320
 whiterabbit_mch		MACH_WHITERABBIT_MCH	WHITERABBIT_MCH		2321
 sbox9263		MACH_SBOX9263		SBOX9263		2322
-oreo			MACH_OREO		OREO			2323
 smdk6442		MACH_SMDK6442		SMDK6442		2324
 openrd_base		MACH_OPENRD_BASE	OPENRD_BASE		2325
 incredible		MACH_INCREDIBLE		INCREDIBLE		2326
@@ -2374,7 +2370,6 @@ sch_m490		MACH_SCH_M490		SCH_M490		2386
 rbl01			MACH_RBL01		RBL01			2387
 omnifi			MACH_OMNIFI		OMNIFI			2388
 otavalo			MACH_OTAVALO		OTAVALO			2389
-sienna			MACH_SIENNA		SIENNA			2390
 htc_excalibur_s620	MACH_HTC_EXCALIBUR_S620	HTC_EXCALIBUR_S620	2391
 htc_opal		MACH_HTC_OPAL		HTC_OPAL		2392
 touchbook		MACH_TOUCHBOOK		TOUCHBOOK		2393
@@ -2446,7 +2441,6 @@ siogentoo1		MACH_SIOGENTOO1		SIOGENTOO1		2458
 siogentoo2		MACH_SIOGENTOO2		SIOGENTOO2		2459
 sm3k			MACH_SM3K		SM3K			2460
 acer_tempo_f900		MACH_ACER_TEMPO_F900	ACER_TEMPO_F900		2461
-sst61vc010_dev		MACH_SST61VC010_DEV	SST61VC010_DEV		2462
 glittertind		MACH_GLITTERTIND	GLITTERTIND		2463
 omap_zoom3		MACH_OMAP_ZOOM3		OMAP_ZOOM3		2464
 omap_3630sdp		MACH_OMAP_3630SDP	OMAP_3630SDP		2465
@@ -2498,7 +2492,6 @@ hiram			MACH_HIRAM		HIRAM			2510
 phy3250			MACH_PHY3250		PHY3250			2511
 ea3250			MACH_EA3250		EA3250			2512
 fdi3250			MACH_FDI3250		FDI3250			2513
-whitestone		MACH_WHITESTONE		WHITESTONE		2514
 at91sam9263nit		MACH_AT91SAM9263NIT	AT91SAM9263NIT		2515
 ccmx51			MACH_CCMX51		CCMX51			2516
 ccmx51js		MACH_CCMX51JS		CCMX51JS		2517
@@ -2561,7 +2554,6 @@ magnolia2		MACH_MAGNOLIA2		MAGNOLIA2		2573
 emxx			MACH_EMXX		EMXX			2574
 outlaw			MACH_OUTLAW		OUTLAW			2575
 riot_bei2		MACH_RIOT_BEI2		RIOT_BEI2		2576
-riot_vox		MACH_RIOT_VOX		RIOT_VOX		2577
 riot_x37		MACH_RIOT_X37		RIOT_X37		2578
 mega25mx		MACH_MEGA25MX		MEGA25MX		2579
 benzina2		MACH_BENZINA2		BENZINA2		2580
@@ -2582,7 +2574,6 @@ omap3_bulldog		MACH_OMAP3_BULLDOG	OMAP3_BULLDOG		2594
 pca101			MACH_PCA101		PCA101			2595
 buzzc			MACH_BUZZC		BUZZC			2596
 sasie2			MACH_SASIE2		SASIE2			2597
-davinci_cio		MACH_DAVINCI_CIO	DAVINCI_CIO		2598
 smartmeter_dl		MACH_SMARTMETER_DL	SMARTMETER_DL		2599
 wzl6410			MACH_WZL6410		WZL6410			2600
 wzl6410m		MACH_WZL6410M		WZL6410M		2601
@@ -2591,7 +2582,6 @@ wzl6410i		MACH_WZL6410I		WZL6410I		2603
 spacecom1		MACH_SPACECOM1		SPACECOM1		2604
 pingu920		MACH_PINGU920		PINGU920		2605
 bravoc			MACH_BRAVOC		BRAVOC			2606
-cybo2440		MACH_CYBO2440		CYBO2440		2607
 vdssw			MACH_VDSSW		VDSSW			2608
 romulus			MACH_ROMULUS		ROMULUS			2609
 omap_magic		MACH_OMAP_MAGIC		OMAP_MAGIC		2610
@@ -2667,7 +2657,7 @@ msm7x30_surf		MACH_MSM7X30_SURF	MSM7X30_SURF		2679
 micro2440		MACH_MICRO2440		MICRO2440		2680
 am2440			MACH_AM2440		AM2440			2681
 tq2440			MACH_TQ2440		TQ2440			2682
-lpc2478oem		MACH_LPC2478OEM		LPC2478OEM		2683
+ea2478devkit		MACH_EA2478DEVKIT	EA2478DEVKIT		2683
 ak880x			MACH_AK880X		AK880X			2684
 cobra3530		MACH_COBRA3530		COBRA3530		2685
 pmppb			MACH_PMPPB		PMPPB			2686
@@ -2683,7 +2673,6 @@ lkevm			MACH_LKEVM		LKEVM			2695
 mw6410			MACH_MW6410		MW6410			2696
 terastation_wxl		MACH_TERASTATION_WXL	TERASTATION_WXL		2697
 cpu8000e		MACH_CPU8000E		CPU8000E		2698
-catania			MACH_CATANIA		CATANIA			2699
 tokyo			MACH_TOKYO		TOKYO			2700
 msm7201a_surf		MACH_MSM7201A_SURF	MSM7201A_SURF		2701
 msm7201a_ffa		MACH_MSM7201A_FFA	MSM7201A_FFA		2702
@@ -2741,7 +2730,6 @@ wbd222			MACH_WBD222		WBD222			2753
 mt65xx			MACH_MT65XX		MT65XX			2754
 msm8x60_surf		MACH_MSM8X60_SURF	MSM8X60_SURF		2755
 msm8x60_sim		MACH_MSM8X60_SIM	MSM8X60_SIM		2756
-vmc300			MACH_VMC300		VMC300			2757
 tcc8000_sdk		MACH_TCC8000_SDK	TCC8000_SDK		2758
 nanos			MACH_NANOS		NANOS			2759
 stamp9g10		MACH_STAMP9G10		STAMP9G10		2760
@@ -2750,7 +2738,6 @@ h6053			MACH_H6053		H6053			2762
 smint01			MACH_SMINT01		SMINT01			2763
 prtlvt2			MACH_PRTLVT2		PRTLVT2			2764
 ap420			MACH_AP420		AP420			2765
-htcshift		MACH_HTCSHIFT		HTCSHIFT		2766
 davinci_dm365_fc	MACH_DAVINCI_DM365_FC	DAVINCI_DM365_FC	2767
 msm8x55_surf		MACH_MSM8X55_SURF	MSM8X55_SURF		2768
 msm8x55_ffa		MACH_MSM8X55_FFA	MSM8X55_FFA		2769
@@ -2761,7 +2748,6 @@ oreo_controller		MACH_OREO_CONTROLLER	OREO_CONTROLLER		2773
 kopin_models		MACH_KOPIN_MODELS	KOPIN_MODELS		2774
 ttc_vision2		MACH_TTC_VISION2	TTC_VISION2		2775
 cns3420vb		MACH_CNS3420VB		CNS3420VB		2776
-lpc2			MACH_LPC2		LPC2			2777
 olympus			MACH_OLYMPUS		OLYMPUS			2778
 vortex			MACH_VORTEX		VORTEX			2779
 s5pc200			MACH_S5PC200		S5PC200			2780
@@ -2788,7 +2774,6 @@ ti8168evm		MACH_TI8168EVM		TI8168EVM		2800
 neocoreomap		MACH_NEOCOREOMAP	NEOCOREOMAP		2801
 withings_wbp		MACH_WITHINGS_WBP	WITHINGS_WBP		2802
 dbps			MACH_DBPS		DBPS			2803
-sbc9261			MACH_SBC9261		SBC9261			2804
 pcbfp0001		MACH_PCBFP0001		PCBFP0001		2805
 speedy			MACH_SPEEDY		SPEEDY			2806
 chrysaor		MACH_CHRYSAOR		CHRYSAOR		2807
@@ -2812,7 +2797,6 @@ p565			MACH_P565		P565			2824
 acer_a4			MACH_ACER_A4		ACER_A4			2825
 davinci_dm368_bip	MACH_DAVINCI_DM368_BIP	DAVINCI_DM368_BIP	2826
 eshare			MACH_ESHARE		ESHARE			2827
-hw_omapl138_europa	MACH_HW_OMAPL138_EUROPA	HW_OMAPL138_EUROPA	2828
 wlbargn			MACH_WLBARGN		WLBARGN			2829
 bm170			MACH_BM170		BM170			2830
 netspace_mini_v2	MACH_NETSPACE_MINI_V2	NETSPACE_MINI_V2	2831
@@ -2879,7 +2863,6 @@ davinci_picto		MACH_DAVINCI_PICTO	DAVINCI_PICTO		2891
 mecha			MACH_MECHA		MECHA			2892
 bubba3			MACH_BUBBA3		BUBBA3			2893
 pupitre			MACH_PUPITRE		PUPITRE			2894
-tegra_harmony		MACH_TEGRA_HARMONY	TEGRA_HARMONY		2895
 tegra_vogue		MACH_TEGRA_VOGUE	TEGRA_VOGUE		2896
 tegra_e1165		MACH_TEGRA_E1165	TEGRA_E1165		2897
 simplenet		MACH_SIMPLENET		SIMPLENET		2898
@@ -2969,7 +2952,6 @@ netspace_lite_v2	MACH_NETSPACE_LITE_V2	NETSPACE_LITE_V2	2983
 ssc			MACH_SSC		SSC			2984
 premierwave_en		MACH_PREMIERWAVE_EN	PREMIERWAVE_EN		2985
 wasabi			MACH_WASABI		WASABI			2986
-vivow			MACH_VIVOW		VIVOW			2987
 mx50_rdp		MACH_MX50_RDP		MX50_RDP		2988
 universal_c210		MACH_UNIVERSAL_C210	UNIVERSAL_C210		2989
 real6410		MACH_REAL6410		REAL6410		2990
@@ -3017,12 +2999,10 @@ remus			MACH_REMUS		REMUS			3031
 at91cap7xdk		MACH_AT91CAP7XDK	AT91CAP7XDK		3032
 at91cap7stk		MACH_AT91CAP7STK	AT91CAP7STK		3033
 kt_sbc_sam9_1		MACH_KT_SBC_SAM9_1	KT_SBC_SAM9_1		3034
-oratisrouter		MACH_ORATISROUTER	ORATISROUTER		3035
 armada_xp_db		MACH_ARMADA_XP_DB	ARMADA_XP_DB		3036
 spdm			MACH_SPDM		SPDM			3037
 gtib			MACH_GTIB		GTIB			3038
 dgm3240			MACH_DGM3240		DGM3240			3039
-atlas_i_lpe		MACH_ATLAS_I_LPE	ATLAS_I_LPE		3040
 htcmega			MACH_HTCMEGA		HTCMEGA			3041
 tricorder		MACH_TRICORDER		TRICORDER		3042
 tx28			MACH_TX28		TX28			3043
@@ -3062,7 +3042,6 @@ clod			MACH_CLOD		CLOD			3077
 rump			MACH_RUMP		RUMP			3078
 tenderloin		MACH_TENDERLOIN		TENDERLOIN		3079
 shortloin		MACH_SHORTLOIN		SHORTLOIN		3080
-crespo			MACH_CRESPO		CRESPO			3081
 antares			MACH_ANTARES		ANTARES			3082
 wb40n			MACH_WB40N		WB40N			3083
 herring			MACH_HERRING		HERRING			3084
@@ -3111,7 +3090,6 @@ smartqv3		MACH_SMARTQV3		SMARTQV3		3126
 smartqv7		MACH_SMARTQV7		SMARTQV7		3127
 paz00			MACH_PAZ00		PAZ00			3128
 acmenetusfoxg20		MACH_ACMENETUSFOXG20	ACMENETUSFOXG20		3129
-htcwillow		MACH_HTCWILLOW		HTCWILLOW		3130
 fwbd_0404		MACH_FWBD_0404		FWBD_0404		3131
 hdgu			MACH_HDGU		HDGU			3132
 pyramid			MACH_PYRAMID		PYRAMID			3133
@@ -3162,7 +3140,6 @@ b5500			MACH_B5500		B5500			3177
 s5500			MACH_S5500		S5500			3178
 icon			MACH_ICON		ICON			3179
 elephant		MACH_ELEPHANT		ELEPHANT		3180
-msm8x60_fusion		MACH_MSM8X60_FUSION	MSM8X60_FUSION		3181
 shooter			MACH_SHOOTER		SHOOTER			3182
 spade_lte		MACH_SPADE_LTE		SPADE_LTE		3183
 philhwani		MACH_PHILHWANI		PHILHWANI		3184
@@ -3174,13 +3151,11 @@ ag5evm			MACH_AG5EVM		AG5EVM			3189
 sc575plc		MACH_SC575PLC		SC575PLC		3190
 sc575hmi		MACH_SC575IPC		SC575IPC		3191
 omap3_tdm3730		MACH_OMAP3_TDM3730	OMAP3_TDM3730		3192
-g7			MACH_G7			G7			3193
 top9000_eval		MACH_TOP9000_EVAL	TOP9000_EVAL		3194
 top9000_su		MACH_TOP9000_SU		TOP9000_SU		3195
 utm300			MACH_UTM300		UTM300			3196
 tsunagi			MACH_TSUNAGI		TSUNAGI			3197
 ts75xx			MACH_TS75XX		TS75XX			3198
-msm8x60_fusn_ffa	MACH_MSM8X60_FUSN_FFA	MSM8X60_FUSN_FFA	3199
 ts47xx			MACH_TS47XX		TS47XX			3200
 da850_k5		MACH_DA850_K5		DA850_K5		3201
 ax502			MACH_AX502		AX502			3202
@@ -3285,7 +3260,7 @@ rfl109145_ssrv		MACH_RFL109145_SSRV	RFL109145_SSRV		3304
 nmh			MACH_NMH		NMH			3305
 wn802t			MACH_WN802T		WN802T			3306
 dragonet		MACH_DRAGONET		DRAGONET		3307
-geneva_b		MACH_GENEVA_B		GENEVA_B		3308
+geneva_b4		MACH_GENEVA_B		GENEVA_B		3308
 at91sam9263desk16l	MACH_AT91SAM9263DESK16L	AT91SAM9263DESK16L	3309
 bcmhana_sv		MACH_BCMHANA_SV		BCMHANA_SV		3310
 bcmhana_tablet		MACH_BCMHANA_TABLET	BCMHANA_TABLET		3311
@@ -3316,3 +3291,85 @@ rover_g8		MACH_ROVER_G8		ROVER_G8		3335
 t5388p			MACH_T5388P		T5388P			3336
 dingo			MACH_DINGO		DINGO			3337
 goflexhome		MACH_GOFLEXHOME		GOFLEXHOME		3338
+lanreadyfn511		MACH_LANREADYFN511	LANREADYFN511		3340
+omap3_baia		MACH_OMAP3_BAIA		OMAP3_BAIA		3341
+omap3smartdisplay	MACH_OMAP3SMARTDISPLAY	OMAP3SMARTDISPLAY	3342
+xilinx			MACH_XILINX		XILINX			3343
+a2f			MACH_A2F		A2F			3344
+sky25			MACH_SKY25		SKY25			3345
+ccmx53			MACH_CCMX53		CCMX53			3346
+ccmx53js		MACH_CCMX53JS		CCMX53JS		3347
+ccwmx53			MACH_CCWMX53		CCWMX53			3348
+ccwmx53js		MACH_CCWMX53JS		CCWMX53JS		3349
+frisms			MACH_FRISMS		FRISMS			3350
+msm7x27a_ffa		MACH_MSM7X27A_FFA	MSM7X27A_FFA		3351
+msm7x27a_surf		MACH_MSM7X27A_SURF	MSM7X27A_SURF		3352
+msm7x27a_rumi3		MACH_MSM7X27A_RUMI3	MSM7X27A_RUMI3		3353
+dimmsam9g20		MACH_DIMMSAM9G20	DIMMSAM9G20		3354
+dimm_imx28		MACH_DIMM_IMX28		DIMM_IMX28		3355
+amk_a4			MACH_AMK_A4		AMK_A4			3356
+gnet_sgme		MACH_GNET_SGME		GNET_SGME		3357
+shooter_u		MACH_SHOOTER_U		SHOOTER_U		3358
+vmx53			MACH_VMX53		VMX53			3359
+rhino			MACH_RHINO		RHINO			3360
+armlex4210		MACH_ARMLEX4210		ARMLEX4210		3361
+swarcoextmodem		MACH_SWARCOEXTMODEM	SWARCOEXTMODEM		3362
+snowball		MACH_SNOWBALL		SNOWBALL		3363
+pcm049			MACH_PCM049		PCM049			3364
+vigor			MACH_VIGOR		VIGOR			3365
+oslo_amundsen		MACH_OSLO_AMUNDSEN	OSLO_AMUNDSEN		3366
+gsl_diamond		MACH_GSL_DIAMOND	GSL_DIAMOND		3367
+cv2201			MACH_CV2201		CV2201			3368
+cv2202			MACH_CV2202		CV2202			3369
+cv2203			MACH_CV2203		CV2203			3370
+vit_ibox		MACH_VIT_IBOX		VIT_IBOX		3371
+dm6441_esp		MACH_DM6441_ESP		DM6441_ESP		3372
+at91sam9x5ek		MACH_AT91SAM9X5EK	AT91SAM9X5EK		3373
+libra			MACH_LIBRA		LIBRA			3374
+easycrrh		MACH_EASYCRRH		EASYCRRH		3375
+tripel			MACH_TRIPEL		TRIPEL			3376
+endian_mini		MACH_ENDIAN_MINI	ENDIAN_MINI		3377
+xilinx_ep107		MACH_XILINX_EP107	XILINX_EP107		3378
+nuri			MACH_NURI		NURI			3379
+janus			MACH_JANUS		JANUS			3380
+ddnas			MACH_DDNAS		DDNAS			3381
+tag			MACH_TAG		TAG			3382
+tagw			MACH_TAGW		TAGW			3383
+nitrogen_vm_imx51	MACH_NITROGEN_VM_IMX51	NITROGEN_VM_IMX51	3384
+viprinet		MACH_VIPRINET		VIPRINET		3385
+bockw			MACH_BOCKW		BOCKW			3386
+eva2000			MACH_EVA2000		EVA2000			3387
+steelyard		MACH_STEELYARD		STEELYARD		3388
+ea2468devkit		MACH_LPC2468OEM		LPC2468OEM		3389
+sdh001			MACH_MACH_SDH001	MACH_SDH001		3390
+fe2478microblox		MACH_LPC2478MICROBLOX	LPC2478MICROBLOX	3391
+nsslsboard		MACH_NSSLSBOARD		NSSLSBOARD		3392
+geneva_b5		MACH_GENEVA_B5		GENEVA_B5		3393
+spear1340		MACH_SPEAR1340		SPEAR1340		3394
+rexmas			MACH_REXMAS		REXMAS			3395
+msm8960_cdp		MACH_MSM8960_CDP	MSM8960_CDP		3396
+msm8960_mdp		MACH_MSM8960_MDP	MSM8960_MDP		3397
+msm8960_fluid		MACH_MSM8960_FLUID	MSM8960_FLUID		3398
+msm8960_apq		MACH_MSM8960_APQ	MSM8960_APQ		3399
+helios_v2		MACH_HELIOS_V2		HELIOS_V2		3400
+mif10p			MACH_MIF10P		MIF10P			3401
+iam28			MACH_IAM28		IAM28			3402
+picasso			MACH_PICASSO		PICASSO			3403
+mr301a			MACH_MR301A		MR301A			3404
+notle			MACH_NOTLE		NOTLE			3405
+eelx2			MACH_EELX2		EELX2			3406
+moon			MACH_MOON		MOON			3407
+ruby			MACH_RUBY		RUBY			3408
+goldengate		MACH_GOLDENGATE		GOLDENGATE		3409
+ctbu_gen2		MACH_CTBU_GEN2		CTBU_GEN2		3410
+kmp_am17_01		MACH_KMP_AM17_01	KMP_AM17_01		3411
+wtplug			MACH_WTPLUG		WTPLUG			3412
+mx27su2			MACH_MX27SU2		MX27SU2			3413
+nb31			MACH_NB31		NB31			3414
+hjsdu			MACH_HJSDU		HJSDU			3415
+td3_rev1		MACH_TD3_REV1		TD3_REV1		3416
+eag_ci4000		MACH_EAG_CI4000		EAG_CI4000		3417
+net5big_nand_v2		MACH_NET5BIG_NAND_V2	NET5BIG_NAND_V2		3418
+cpx2			MACH_CPX2		CPX2			3419
+net2big_nand_v2		MACH_NET2BIG_NAND_V2	NET2BIG_NAND_V2		3420
+ecuv5			MACH_ECUV5		ECUV5			3421
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 8/9] lpc2k: Add UART, SSP, and MCI devices
  2011-03-20 20:30 [PATCH v3 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
                   ` (6 preceding siblings ...)
  2011-03-20 20:30 ` [PATCH v3 7/9] lpc2k: Add EmbeddedArtists LPC2478 Developer's Kit board Ithamar R. Adema
@ 2011-03-20 20:30 ` Ithamar R. Adema
  2011-03-20 20:30 ` [PATCH v3 9/9] lpc2k: defconfig for NXP LPC2K platform Ithamar R. Adema
  8 siblings, 0 replies; 12+ messages in thread
From: Ithamar R. Adema @ 2011-03-20 20:30 UTC (permalink / raw)
  To: linux-arm-kernel

Adds devices for which the drivers are already in the tree. For
the relevant devices, let the ea2478devkit board set them up.

Signed-off-by: Ithamar R. Adema <ithamar.adema@team-embedded.nl>
---
changes since v2:
	* removed clk_put() from UART init routine.

no changes since v1.
---
 arch/arm/Kconfig                            |    1 +
 arch/arm/mach-lpc2k/Makefile                |    2 +-
 arch/arm/mach-lpc2k/common.h                |    4 +
 arch/arm/mach-lpc2k/devices.c               |  173 +++++++++++++++++++++++++++
 arch/arm/mach-lpc2k/include/mach/hardware.h |    6 +
 arch/arm/mach-lpc2k/mach-ea2478devkit.c     |   20 +++
 6 files changed, 205 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-lpc2k/devices.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a95a232..13b436b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -496,6 +496,7 @@ config ARCH_LPC2K
 	depends on !MMU
 	select CPU_ARM7TDMI
 	select ARM_VIC
+	select ARM_AMBA
 	select CLKDEV_LOOKUP
 	select GENERIC_CLOCKEVENTS
 	select ARCH_REQUIRE_GPIOLIB
diff --git a/arch/arm/mach-lpc2k/Makefile b/arch/arm/mach-lpc2k/Makefile
index 93e27fb..aa2b353 100644
--- a/arch/arm/mach-lpc2k/Makefile
+++ b/arch/arm/mach-lpc2k/Makefile
@@ -1,3 +1,3 @@
 obj-y	:= clock.o irq.o gpio.o mfp.o time.o
 
-obj-$(CONFIG_MACH_EA2478DEVKIT) += mach-ea2478devkit.o
+obj-$(CONFIG_MACH_EA2478DEVKIT) += mach-ea2478devkit.o devices.o
diff --git a/arch/arm/mach-lpc2k/common.h b/arch/arm/mach-lpc2k/common.h
index 6b775d9..1d4c21e 100644
--- a/arch/arm/mach-lpc2k/common.h
+++ b/arch/arm/mach-lpc2k/common.h
@@ -16,6 +16,10 @@ extern void lpc2k_init_clocks(unsigned long xtal, unsigned long rtc);
 extern void lpc2k_mfp_config(unsigned long *mfp_cfgs, int num);
 extern void lpc2k_init_irq(void);
 
+extern void lpc2k_add_uart(int nr);
+extern void lpc2k_add_ssp(int nr, void *platform_data);
+extern void lpc2k_add_mci(void *platform_data, int pwr_high);
+
 extern struct sys_timer lpc2k_timer;
 
 #endif /* LPC2K_COMMON_H */
diff --git a/arch/arm/mach-lpc2k/devices.c b/arch/arm/mach-lpc2k/devices.c
new file mode 100644
index 0000000..8e7de6d
--- /dev/null
+++ b/arch/arm/mach-lpc2k/devices.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2011 Team Embeded VOF
+ *     Ithamar R. Adema <ihamar.adema@team-embedded.nl>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <linux/amba/bus.h>
+#include <linux/amba/mmci.h>
+#include <linux/amba/pl022.h>
+
+#include <mach/hardware.h>
+
+/* System Control Block - System Controls and Status register */
+#define SCS		0x1a0
+
+#define __IORESOURCE_MEM_16K(x)	{	\
+	.start = x,			\
+	.end   = x + SZ_16K - 1,	\
+	.flags = IORESOURCE_MEM,	\
+	}
+
+#define __IORESOURCE_IRQ(x)	{	\
+	.start = x,			\
+	. end  = x,			\
+	}
+
+/* UARTs
+ *   0/1 are available on all LPC2Ks
+ *   2/3 are available on LPC23XX and up.
+ *
+ * NOTE: the dev.init_name assignment is there so we can use the clk API to
+ *       retrieve and enable the clock, since dev_name() is called from
+ *       the clk_get implementation before the platform device is registered.
+ */
+
+#define LPC2K_UART(uartnum) \
+	static struct plat_serial8250_port lpc2k_pdata_uart##uartnum[] = { \
+		{ \
+			.mapbase	= APB_UART##uartnum##_BASE, \
+			.membase	= (void __iomem *) \
+						APB_UART##uartnum##_BASE, \
+			.irq		= IRQ_LPC2K_UART##uartnum, \
+			.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, \
+			.iotype		= UPIO_MEM, \
+			.regshift	= 2, \
+			.uartclk	= 0, \
+		}, \
+		{ }, \
+	}; \
+	static struct resource lpc2k_resources_uart##uartnum[] = { \
+		[0] = __IORESOURCE_MEM_16K(APB_UART##uartnum##_BASE), \
+		[1] = __IORESOURCE_IRQ(IRQ_LPC2K_UART##uartnum), \
+	}; \
+	static struct platform_device lpc2k_device_uart##uartnum = { \
+		.dev = { \
+			.init_name = "serial8250." __stringify(uartnum), \
+			.platform_data = lpc2k_pdata_uart##uartnum, \
+		}, \
+		.name		= "serial8250", \
+		.id		= uartnum, \
+		.resource	= lpc2k_resources_uart##uartnum, \
+		.num_resources	= ARRAY_SIZE(lpc2k_resources_uart##uartnum), \
+	}
+
+
+LPC2K_UART(0);
+LPC2K_UART(1);
+LPC2K_UART(2);
+LPC2K_UART(3);
+
+static struct platform_device *uarts[] __initdata = {
+	&lpc2k_device_uart0,
+	&lpc2k_device_uart1,
+	&lpc2k_device_uart2,
+	&lpc2k_device_uart3,
+};
+
+void __init lpc2k_add_uart(int nr)
+{
+	struct platform_device *pdev;
+	struct clk *clk;
+	int res;
+
+	BUG_ON(nr < 0 || nr > ARRAY_SIZE(uarts));
+	pdev = uarts[nr];
+
+	clk = clk_get(&pdev->dev, NULL);
+	BUG_ON(IS_ERR(clk));
+	clk_enable(clk);
+	((struct plat_serial8250_port *)pdev->dev.platform_data)->uartclk =
+		clk_get_rate(clk);
+
+	res = platform_device_register(pdev);
+	if (res)
+		dev_err(&pdev->dev, "Unable to register: %d\n", res);
+}
+
+/* SSP, aka pl022
+ *
+ * 1-only available on enhanced LPC21XX and LPC22XX.
+ * 0/1 available on LPC23XX and up.
+ */
+
+static struct amba_device lpc2k_device_ssp0 = {
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.init_name = "ssp0",
+	},
+	.res = __IORESOURCE_MEM_16K(APB_SSP0_BASE),
+	.irq = { IRQ_LPC2K_SPI0, NO_IRQ },
+};
+
+static struct amba_device lpc2k_device_ssp1 = {
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.init_name = "ssp1",
+	},
+	.res = __IORESOURCE_MEM_16K(APB_SSP1_BASE),
+	.irq = { IRQ_LPC2K_SPI1, NO_IRQ },
+};
+
+void __init lpc2k_add_ssp(int nr, void *platform_data)
+{
+	struct amba_device *adev;
+	int res;
+
+	BUG_ON(nr < 0 || nr > 1);
+	adev = nr ? &lpc2k_device_ssp1 : &lpc2k_device_ssp0;
+	adev->dev.platform_data = platform_data;
+
+	res = amba_device_register(adev, &iomem_resource);
+	if (res)
+		dev_err(&adev->dev, "Unable to register: %d\n", res);
+}
+
+/* SD/MMC, aka pl180/1
+ *
+ * Available on LPC23XX and up.
+ */
+
+static struct amba_device lpc2k_device_mci = {
+	.dev = {
+		.coherent_dma_mask = ~0,
+		.init_name = "mci",
+	},
+	.res = __IORESOURCE_MEM_16K(APB_MCI_BASE),
+	.irq = { IRQ_LPC2K_MCI, NO_IRQ },
+};
+
+void __init lpc2k_add_mci(void *platform_data, int pwr_high)
+{
+	int res;
+	u32 scs;
+
+	/* Set MCIPWR pin to be active high or low */
+	scs = ioread32(APB_SCB_BASE + SCS);
+	scs = pwr_high ? scs | (1 << 3) : scs & ~(1 << 3);
+	iowrite32(scs, APB_SCB_BASE + SCS);
+
+	lpc2k_device_mci.dev.platform_data = platform_data;
+	res = amba_device_register(&lpc2k_device_mci, &iomem_resource);
+	if (res)
+		dev_err(&lpc2k_device_mci.dev, "Unable to register: %d\n", res);
+}
diff --git a/arch/arm/mach-lpc2k/include/mach/hardware.h b/arch/arm/mach-lpc2k/include/mach/hardware.h
index 1a20126..b2e3a18 100644
--- a/arch/arm/mach-lpc2k/include/mach/hardware.h
+++ b/arch/arm/mach-lpc2k/include/mach/hardware.h
@@ -20,8 +20,14 @@
 #define APB_TIMER0_BASE		0xe0004000
 #define APB_TIMER1_BASE		0xe0008000
 #define APB_UART0_BASE		0xe000c000
+#define APB_UART1_BASE		0xe0010000
 #define APB_GPIO_BASE		0xe0028000
 #define APB_PINSEL_BASE		0xe002c000
+#define APB_SSP1_BASE		0xe0030000
+#define APB_SSP0_BASE		0xe0068000
+#define APB_UART2_BASE		0xe0078000
+#define APB_UART3_BASE		0xe007c000
+#define APB_MCI_BASE		0xe008c000
 #define APB_SCB_BASE		0xe01fc000
 #define APH_VIC_BASE		0xfffff000
 
diff --git a/arch/arm/mach-lpc2k/mach-ea2478devkit.c b/arch/arm/mach-lpc2k/mach-ea2478devkit.c
index d59f5ba..4d7e95b 100644
--- a/arch/arm/mach-lpc2k/mach-ea2478devkit.c
+++ b/arch/arm/mach-lpc2k/mach-ea2478devkit.c
@@ -8,6 +8,8 @@
  */
 
 #include <linux/module.h>
+#include <linux/amba/pl022.h>
+#include <linux/amba/mmci.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
 
@@ -96,9 +98,27 @@ static unsigned long mfp_cfgs[] __initdata = {
 	P1_12_MCIDAT3,
 };
 
+static struct pl022_ssp_controller ssp0_plat_data = {
+	.bus_id = 0,
+	.enable_dma = 0,
+	.num_chipselect = 1,
+};
+
+static struct mmci_platform_data mci_plat_data = {
+	.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+	.capabilities = MMC_CAP_4_BIT_DATA,
+	.f_max = 200000,
+	.gpio_cd = -1,
+	.gpio_wp = -1,
+};
+
 void __init ea2478devkit_init_machine(void)
 {
 	lpc2k_mfp_config(mfp_cfgs, ARRAY_SIZE(mfp_cfgs));
+
+	lpc2k_add_uart(0);
+	lpc2k_add_ssp(0, &ssp0_plat_data);
+	lpc2k_add_mci(&mci_plat_data, 0 /* active low */);
 }
 
 static void __init ea2478devkit_init_irq(void)
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 9/9] lpc2k: defconfig for NXP LPC2K platform
  2011-03-20 20:30 [PATCH v3 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
                   ` (7 preceding siblings ...)
  2011-03-20 20:30 ` [PATCH v3 8/9] lpc2k: Add UART, SSP, and MCI devices Ithamar R. Adema
@ 2011-03-20 20:30 ` Ithamar R. Adema
  8 siblings, 0 replies; 12+ messages in thread
From: Ithamar R. Adema @ 2011-03-20 20:30 UTC (permalink / raw)
  To: linux-arm-kernel

Add a defconfig that is setup to support booting a uClinux based
system. This enables ROMFS/CRAMFS, initrd, and FLAT binaries besides
the drivers for the devices added in the previous patch.

Signed-off-by: Ithamar R. Adema <ithamar.adema@team-embedded.nl>
---
no changes since v2.

changes since v1:
        * enabled CONFIG_MAGIC_SYSRQ for testing arch_reset.
---
 arch/arm/configs/lpc2k_defconfig |   57 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 57 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/configs/lpc2k_defconfig

diff --git a/arch/arm/configs/lpc2k_defconfig b/arch/arm/configs/lpc2k_defconfig
new file mode 100644
index 0000000..47a7bcf
--- /dev/null
+++ b/arch/arm/configs/lpc2k_defconfig
@@ -0,0 +1,57 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_TINY_RCU=y
+# CONFIG_UTS_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_MMU is not set
+CONFIG_ARCH_LPC2K=y
+CONFIG_MACH_EA2478DEVKIT=y
+CONFIG_PROCESSOR_ID=0x41007700
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_CMDLINE="root=/dev/ram initrd=0xa1a00000,4000k console=ttyS0,115200N8 debug rw earlyprintk"
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+CONFIG_BINFMT_SHARED_FLAT=y
+# CONFIG_SUSPEND is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+# CONFIG_HWMON is not set
+# CONFIG_MFD_SUPPORT is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_ARMMMCI=y
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+CONFIG_CRAMFS=y
+CONFIG_ROMFS_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 3/9] lpc2k: clk API
  2011-03-20 20:30 ` [PATCH v3 3/9] lpc2k: clk API Ithamar R. Adema
@ 2011-03-22  0:16   ` Kevin Wells
  2011-03-22  1:13     ` Ithamar R. Adema
  0 siblings, 1 reply; 12+ messages in thread
From: Kevin Wells @ 2011-03-22  0:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Ithamar,

> +#define clk_readl(a)	\
> +	ioread32(APB_SCB_BASE + (a))
> +#define clk_writel(v, a)	\
> +	iowrite32(v, APB_SCB_BASE + (a))
> +
> +struct clk {
> +	int		refcount;
> +	struct clk	*parent;
> +	unsigned long	rate;

It looks like this rate field is only used in 3 clock
descriptors. It might save some space to get rid of this field
and associated code and have those 3 clocks just use functions
for get_rate() that return the direct value.

> +
> +static unsigned long pclkdiv[] = { 4, 1, 2, 8 };
> +
> +#define PERCLK(name, pnum)	\
> +	static unsigned long name ## _get_rate(struct clk *clk) \
> +	{	\
> +		unsigned long rate = clk_get_rate(clk->parent);	\
> +		u32 val = clk_readl((pnum < 16) ? PCLKSEL0 : PCLKSEL1); \
> +		val >>= (pnum < 16) ? pnum * 2 : (pnum - 16) * 2;	\
> +		return rate / pclkdiv[val & 3];	\
> +	}	\
> +	struct clk clk_ ## name = {	\
> +		.parent = &clk_cpu,	\
> +		.enable_mask = (1 << pnum),	\
> +		.get_rate = name ## _get_rate,	\
> +	}
> +

This macro will generate multiple functions with different names but the same
code. Can the function be made common to the supported clocks and the macro
just handle clock descriptor setup?

> +PERCLK(timer0, 1);
> +PERCLK(timer1, 2);

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 3/9] lpc2k: clk API
  2011-03-22  0:16   ` Kevin Wells
@ 2011-03-22  1:13     ` Ithamar R. Adema
  0 siblings, 0 replies; 12+ messages in thread
From: Ithamar R. Adema @ 2011-03-22  1:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 2011-03-22 at 01:16 +0100, Kevin Wells wrote:
> > +struct clk {
> > +	int		refcount;
> > +	struct clk	*parent;
> > +	unsigned long	rate;
> 
> It looks like this rate field is only used in 3 clock
> descriptors. It might save some space to get rid of this field
> and associated code and have those 3 clocks just use functions
> for get_rate() that return the direct value.

Fair enough, I can update that....

> > +static unsigned long pclkdiv[] = { 4, 1, 2, 8 };
> > +
> > +#define PERCLK(name, pnum)	\
> > +	static unsigned long name ## _get_rate(struct clk *clk) \
> > +	{	\
> > +		unsigned long rate = clk_get_rate(clk->parent);	\
> > +		u32 val = clk_readl((pnum < 16) ? PCLKSEL0 : PCLKSEL1); \
> > +		val >>= (pnum < 16) ? pnum * 2 : (pnum - 16) * 2;	\
> > +		return rate / pclkdiv[val & 3];	\
> > +	}	\
> > +	struct clk clk_ ## name = {	\
> > +		.parent = &clk_cpu,	\
> > +		.enable_mask = (1 << pnum),	\
> > +		.get_rate = name ## _get_rate,	\
> > +	}
> > +
> 
> This macro will generate multiple functions with different names but the same
> code. Can the function be made common to the supported clocks and the macro
> just handle clock descriptor setup?

I could add a field to the clk struct to store it, since the peripheral
clock is the most common type of clk in the system, so it wouldn't waste
too much.

Regards,

Ithamar.

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2011-03-22  1:13 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-20 20:30 [PATCH v3 0/9] Support for NXP LPC2K SoCs Ithamar R. Adema
2011-03-20 20:30 ` [PATCH v3 1/9] lpc2k: Core support Ithamar R. Adema
2011-03-20 20:30 ` [PATCH v3 2/9] lpc2k: Exception vector handling Ithamar R. Adema
2011-03-20 20:30 ` [PATCH v3 3/9] lpc2k: clk API Ithamar R. Adema
2011-03-22  0:16   ` Kevin Wells
2011-03-22  1:13     ` Ithamar R. Adema
2011-03-20 20:30 ` [PATCH v3 4/9] lpc2k: generic time and clockevents Ithamar R. Adema
2011-03-20 20:30 ` [PATCH v3 5/9] lpc2k: gpiolib Ithamar R. Adema
2011-03-20 20:30 ` [PATCH v3 6/9] lpc2k: multifunction pin configuration Ithamar R. Adema
2011-03-20 20:30 ` [PATCH v3 7/9] lpc2k: Add EmbeddedArtists LPC2478 Developer's Kit board Ithamar R. Adema
2011-03-20 20:30 ` [PATCH v3 8/9] lpc2k: Add UART, SSP, and MCI devices Ithamar R. Adema
2011-03-20 20:30 ` [PATCH v3 9/9] lpc2k: defconfig for NXP LPC2K platform Ithamar R. Adema

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).