ep93xx: uart support (pl010)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch adds support for the three UARTs in the Cirrus EP93xx
SoC to the amba-pl010 serial driver.

Signed-off-by: Lennert Buytenhek <buytenh@xxxxxxxxxxxxxx>

Index: linux-2.6.16/arch/arm/mach-ep93xx/core.c
===================================================================
--- linux-2.6.16.orig/arch/arm/mach-ep93xx/core.c
+++ linux-2.6.16/arch/arm/mach-ep93xx/core.c
@@ -370,6 +370,45 @@ void __init ep93xx_init_irq(void)
 /*************************************************************************
  * EP93xx peripheral handling
  *************************************************************************/
+static struct amba_device uart1_device = {
+	.dev		= {
+		.bus_id = "apb:uart1",
+	},
+	.res		= {
+		.start	= EP93XX_UART1_PHYS_BASE,
+		.end	= EP93XX_UART1_PHYS_BASE + 0x0fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	.irq		= { IRQ_EP93XX_UART1, NO_IRQ },
+	.periphid	= 0x00041010,
+};
+
+static struct amba_device uart2_device = {
+	.dev		= {
+		.bus_id = "apb:uart2",
+	},
+	.res		= {
+		.start	= EP93XX_UART2_PHYS_BASE,
+		.end	= EP93XX_UART2_PHYS_BASE + 0x0fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	.irq		= { IRQ_EP93XX_UART2, NO_IRQ },
+	.periphid	= 0x00041010,
+};
+
+static struct amba_device uart3_device = {
+	.dev		= {
+		.bus_id = "apb:uart3",
+	},
+	.res		= {
+		.start	= EP93XX_UART3_PHYS_BASE,
+		.end	= EP93XX_UART3_PHYS_BASE + 0x0fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	.irq		= { IRQ_EP93XX_UART3, NO_IRQ },
+	.periphid	= 0x00041010,
+};
+
 void __init ep93xx_init_devices(void)
 {
 	unsigned int v;
@@ -381,4 +420,8 @@ void __init ep93xx_init_devices(void)
 	v &= ~EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE;
 	__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
 	__raw_writel(v, EP93XX_SYSCON_DEVICE_CONFIG);
+
+	amba_device_register(&uart1_device, &iomem_resource);
+	amba_device_register(&uart2_device, &iomem_resource);
+	amba_device_register(&uart3_device, &iomem_resource);
 }
Index: linux-2.6.16/drivers/serial/amba-pl010.c
===================================================================
--- linux-2.6.16.orig/drivers/serial/amba-pl010.c
+++ linux-2.6.16/drivers/serial/amba-pl010.c
@@ -54,11 +54,8 @@
 #include <asm/irq.h>
 #include <asm/hardware.h>
 
-#define UART_NR		2
-
 #define SERIAL_AMBA_MAJOR	204
 #define SERIAL_AMBA_MINOR	16
-#define SERIAL_AMBA_NR		UART_NR
 
 #define AMBA_ISR_PASS_LIMIT	256
 
@@ -86,6 +83,23 @@
 #define UART_DUMMY_RSR_RX	/*256*/0
 #define UART_PORT_SIZE		64
 
+#ifdef CONFIG_ARCH_EP93XX
+/*
+ * On the EP93xx, RTS and DTR are in the two least significant bits
+ * of the Modem Control Register, which is an EP93xx add-on to the
+ * pl010 UART located at offset 0x100.
+ *
+ * bit 1: RTS (inverted)
+ * bit 0: DTR (inverted)
+ */
+#define UART010_MCR		(0x0100)
+#define UART_PUT_MCR(p,c)	writel((c), (p)->membase + UART010_MCR);
+
+#undef UART_PORT_SIZE
+#define UART_PORT_SIZE		0x1000
+#endif
+
+#ifdef CONFIG_ARCH_INTEGRATOR
 /*
  * On the Integrator platform, the port RTS and DTR are provided by
  * bits in the following SC_CTRLS register bits:
@@ -95,6 +109,7 @@
  */
 #define SC_CTRLC	(IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
 #define SC_CTRLS	(IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)
+#endif
 
 /*
  * We wrap our port structure around the generic uart_port.
@@ -315,6 +330,22 @@ static unsigned int pl010_get_mctrl(stru
 	return result;
 }
 
+#ifdef CONFIG_ARCH_EP93XX
+static void pl010_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	unsigned int mcr;
+
+	mcr = 0;
+	if (!(mctrl & TIOCM_RTS))
+		mcr |= 2;
+	if (!(mctrl & TIOCM_DTR))
+		mcr |= 1;
+
+	UART_PUT_MCR(port, mcr);
+}
+#endif
+
+#ifdef CONFIG_ARCH_INTEGRATOR
 static void pl010_set_mctrl(struct uart_port *port, unsigned int mctrl)
 {
 	struct uart_amba_port *uap = (struct uart_amba_port *)port;
@@ -333,6 +364,7 @@ static void pl010_set_mctrl(struct uart_
 	__raw_writel(ctrls, SC_CTRLS);
 	__raw_writel(ctrlc, SC_CTRLC);
 }
+#endif
 
 static void pl010_break_ctl(struct uart_port *port, int break_state)
 {
@@ -556,7 +588,52 @@ static struct uart_ops amba_pl010_pops =
 	.verify_port	= pl010_verify_port,
 };
 
-static struct uart_amba_port amba_ports[UART_NR] = {
+#ifdef CONFIG_ARCH_EP93XX
+static struct uart_amba_port amba_ports[] = {
+	{
+		.port	= {
+			.membase	= (void *)EP93XX_UART1_BASE,
+			.mapbase	= EP93XX_UART1_PHYS_BASE,
+			.iotype		= UPIO_MEM,
+			.irq		= IRQ_EP93XX_UART1,
+			.uartclk	= 14745600,
+			.fifosize	= 16,
+			.ops		= &amba_pl010_pops,
+			.flags		= UPF_BOOT_AUTOCONF,
+			.line		= 0,
+		},
+	},
+	{
+		.port	= {
+			.membase	= (void *)EP93XX_UART2_BASE,
+			.mapbase	= EP93XX_UART2_PHYS_BASE,
+			.iotype		= UPIO_MEM,
+			.irq		= IRQ_EP93XX_UART2,
+			.uartclk	= 14745600,
+			.fifosize	= 16,
+			.ops		= &amba_pl010_pops,
+			.flags		= UPF_BOOT_AUTOCONF,
+			.line		= 1,
+		},
+	},
+	{
+		.port	= {
+			.membase	= (void *)EP93XX_UART3_BASE,
+			.mapbase	= EP93XX_UART3_PHYS_BASE,
+			.iotype		= UPIO_MEM,
+			.irq		= IRQ_EP93XX_UART3,
+			.uartclk	= 14745600,
+			.fifosize	= 16,
+			.ops		= &amba_pl010_pops,
+			.flags		= UPF_BOOT_AUTOCONF,
+			.line		= 2,
+		},
+	},
+};
+#endif
+
+#ifdef CONFIG_ARCH_INTEGRATOR
+static struct uart_amba_port amba_ports[] = {
 	{
 		.port	= {
 			.membase	= (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE),
@@ -588,6 +665,7 @@ static struct uart_amba_port amba_ports[
 		.rts_mask	= 1 << 6,
 	}
 };
+#endif
 
 #ifdef CONFIG_SERIAL_AMBA_PL010_CONSOLE
 
@@ -669,7 +747,7 @@ static int __init pl010_console_setup(st
 	 * if so, search for the first available port that does have
 	 * console support.
 	 */
-	if (co->index >= UART_NR)
+	if (co->index >= ARRAY_SIZE(amba_ports))
 		co->index = 0;
 	port = &amba_ports[co->index].port;
 
@@ -721,7 +799,7 @@ static struct uart_driver amba_reg = {
 	.dev_name		= "ttyAM",
 	.major			= SERIAL_AMBA_MAJOR,
 	.minor			= SERIAL_AMBA_MINOR,
-	.nr			= UART_NR,
+	.nr			= ARRAY_SIZE(amba_ports),
 	.cons			= AMBA_CONSOLE,
 };
 
@@ -729,7 +807,7 @@ static int pl010_probe(struct amba_devic
 {
 	int i;
 
-	for (i = 0; i < UART_NR; i++) {
+	for (i = 0; i < ARRAY_SIZE(amba_ports); i++) {
 		if (amba_ports[i].port.mapbase != dev->res.start)
 			continue;
 
-
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux