|
@@ -48,7 +48,6 @@
|
|
|
|
|
|
#include <asm/io.h>
|
|
|
#include <asm/irq.h>
|
|
|
-#include <mach/hardware.h>
|
|
|
#include <mach/imx-uart.h>
|
|
|
|
|
|
/* Register definitions */
|
|
@@ -66,8 +65,9 @@
|
|
|
#define UBIR 0xa4 /* BRM Incremental Register */
|
|
|
#define UBMR 0xa8 /* BRM Modulator Register */
|
|
|
#define UBRC 0xac /* Baud Rate Count Register */
|
|
|
-#define MX2_ONEMS 0xb0 /* One Millisecond register */
|
|
|
-#define UTS (cpu_is_mx1() ? 0xd0 : 0xb4) /* UART Test Register */
|
|
|
+#define IMX21_ONEMS 0xb0 /* One Millisecond register */
|
|
|
+#define IMX1_UTS 0xd0 /* UART Test Register on i.mx1 */
|
|
|
+#define IMX21_UTS 0xb4 /* UART Test Register on all other i.mx*/
|
|
|
|
|
|
/* UART Control Register Bit Fields.*/
|
|
|
#define URXD_CHARRDY (1<<15)
|
|
@@ -87,7 +87,7 @@
|
|
|
#define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */
|
|
|
#define UCR1_SNDBRK (1<<4) /* Send break */
|
|
|
#define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */
|
|
|
-#define MX1_UCR1_UARTCLKEN (1<<2) /* UART clock enabled, mx1 only */
|
|
|
+#define IMX1_UCR1_UARTCLKEN (1<<2) /* UART clock enabled, i.mx1 only */
|
|
|
#define UCR1_DOZE (1<<1) /* Doze */
|
|
|
#define UCR1_UARTEN (1<<0) /* UART enabled */
|
|
|
#define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */
|
|
@@ -113,9 +113,7 @@
|
|
|
#define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */
|
|
|
#define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */
|
|
|
#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */
|
|
|
-#define MX1_UCR3_REF25 (1<<3) /* Ref freq 25 MHz, only on mx1 */
|
|
|
-#define MX1_UCR3_REF30 (1<<2) /* Ref Freq 30 MHz, only on mx1 */
|
|
|
-#define MX2_UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select, on mx2/mx3 */
|
|
|
+#define IMX21_UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select */
|
|
|
#define UCR3_INVT (1<<1) /* Inverted Infrared transmission */
|
|
|
#define UCR3_BPEN (1<<0) /* Preset registers enable */
|
|
|
#define UCR4_CTSTL_SHF 10 /* CTS trigger level shift */
|
|
@@ -181,6 +179,18 @@
|
|
|
|
|
|
#define UART_NR 8
|
|
|
|
|
|
+/* i.mx21 type uart runs on all i.mx except i.mx1 */
|
|
|
+enum imx_uart_type {
|
|
|
+ IMX1_UART,
|
|
|
+ IMX21_UART,
|
|
|
+};
|
|
|
+
|
|
|
+/* device type dependent stuff */
|
|
|
+struct imx_uart_data {
|
|
|
+ unsigned uts_reg;
|
|
|
+ enum imx_uart_type devtype;
|
|
|
+};
|
|
|
+
|
|
|
struct imx_port {
|
|
|
struct uart_port port;
|
|
|
struct timer_list timer;
|
|
@@ -192,6 +202,7 @@ struct imx_port {
|
|
|
unsigned int irda_inv_tx:1;
|
|
|
unsigned short trcv_delay; /* transceiver delay */
|
|
|
struct clk *clk;
|
|
|
+ struct imx_uart_data *devdata;
|
|
|
};
|
|
|
|
|
|
#ifdef CONFIG_IRDA
|
|
@@ -200,6 +211,45 @@ struct imx_port {
|
|
|
#define USE_IRDA(sport) (0)
|
|
|
#endif
|
|
|
|
|
|
+static struct imx_uart_data imx_uart_devdata[] = {
|
|
|
+ [IMX1_UART] = {
|
|
|
+ .uts_reg = IMX1_UTS,
|
|
|
+ .devtype = IMX1_UART,
|
|
|
+ },
|
|
|
+ [IMX21_UART] = {
|
|
|
+ .uts_reg = IMX21_UTS,
|
|
|
+ .devtype = IMX21_UART,
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+static struct platform_device_id imx_uart_devtype[] = {
|
|
|
+ {
|
|
|
+ .name = "imx1-uart",
|
|
|
+ .driver_data = (kernel_ulong_t) &imx_uart_devdata[IMX1_UART],
|
|
|
+ }, {
|
|
|
+ .name = "imx21-uart",
|
|
|
+ .driver_data = (kernel_ulong_t) &imx_uart_devdata[IMX21_UART],
|
|
|
+ }, {
|
|
|
+ /* sentinel */
|
|
|
+ }
|
|
|
+};
|
|
|
+MODULE_DEVICE_TABLE(platform, imx_uart_devtype);
|
|
|
+
|
|
|
+static inline unsigned uts_reg(struct imx_port *sport)
|
|
|
+{
|
|
|
+ return sport->devdata->uts_reg;
|
|
|
+}
|
|
|
+
|
|
|
+static inline int is_imx1_uart(struct imx_port *sport)
|
|
|
+{
|
|
|
+ return sport->devdata->devtype == IMX1_UART;
|
|
|
+}
|
|
|
+
|
|
|
+static inline int is_imx21_uart(struct imx_port *sport)
|
|
|
+{
|
|
|
+ return sport->devdata->devtype == IMX21_UART;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Handle any change of modem status signal since we were last called.
|
|
|
*/
|
|
@@ -326,7 +376,8 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
|
|
|
struct circ_buf *xmit = &sport->port.state->xmit;
|
|
|
|
|
|
while (!uart_circ_empty(xmit) &&
|
|
|
- !(readl(sport->port.membase + UTS) & UTS_TXFULL)) {
|
|
|
+ !(readl(sport->port.membase + uts_reg(sport))
|
|
|
+ & UTS_TXFULL)) {
|
|
|
/* send xmit->buf[xmit->tail]
|
|
|
* out the port here */
|
|
|
writel(xmit->buf[xmit->tail], sport->port.membase + URTX0);
|
|
@@ -373,7 +424,7 @@ static void imx_start_tx(struct uart_port *port)
|
|
|
writel(temp, sport->port.membase + UCR4);
|
|
|
}
|
|
|
|
|
|
- if (readl(sport->port.membase + UTS) & UTS_TXEMPTY)
|
|
|
+ if (readl(sport->port.membase + uts_reg(sport)) & UTS_TXEMPTY)
|
|
|
imx_transmit_buffer(sport);
|
|
|
}
|
|
|
|
|
@@ -689,9 +740,9 @@ static int imx_startup(struct uart_port *port)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (!cpu_is_mx1()) {
|
|
|
+ if (is_imx21_uart(sport)) {
|
|
|
temp = readl(sport->port.membase + UCR3);
|
|
|
- temp |= MX2_UCR3_RXDMUXSEL;
|
|
|
+ temp |= IMX21_UCR3_RXDMUXSEL;
|
|
|
writel(temp, sport->port.membase + UCR3);
|
|
|
}
|
|
|
|
|
@@ -923,9 +974,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
|
|
|
writel(num, sport->port.membase + UBIR);
|
|
|
writel(denom, sport->port.membase + UBMR);
|
|
|
|
|
|
- if (!cpu_is_mx1())
|
|
|
+ if (is_imx21_uart(sport))
|
|
|
writel(sport->port.uartclk / div / 1000,
|
|
|
- sport->port.membase + MX2_ONEMS);
|
|
|
+ sport->port.membase + IMX21_ONEMS);
|
|
|
|
|
|
writel(old_ucr1, sport->port.membase + UCR1);
|
|
|
|
|
@@ -1041,7 +1092,7 @@ static void imx_console_putchar(struct uart_port *port, int ch)
|
|
|
{
|
|
|
struct imx_port *sport = (struct imx_port *)port;
|
|
|
|
|
|
- while (readl(sport->port.membase + UTS) & UTS_TXFULL)
|
|
|
+ while (readl(sport->port.membase + uts_reg(sport)) & UTS_TXFULL)
|
|
|
barrier();
|
|
|
|
|
|
writel(ch, sport->port.membase + URTX0);
|
|
@@ -1062,8 +1113,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
|
|
|
ucr1 = old_ucr1 = readl(sport->port.membase + UCR1);
|
|
|
old_ucr2 = readl(sport->port.membase + UCR2);
|
|
|
|
|
|
- if (cpu_is_mx1())
|
|
|
- ucr1 |= MX1_UCR1_UARTCLKEN;
|
|
|
+ if (is_imx1_uart(sport))
|
|
|
+ ucr1 |= IMX1_UCR1_UARTCLKEN;
|
|
|
ucr1 |= UCR1_UARTEN;
|
|
|
ucr1 &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
|
|
|
|
|
@@ -1262,6 +1313,7 @@ static int serial_imx_probe(struct platform_device *pdev)
|
|
|
init_timer(&sport->timer);
|
|
|
sport->timer.function = imx_timeout;
|
|
|
sport->timer.data = (unsigned long)sport;
|
|
|
+ sport->devdata = (struct imx_uart_data *) pdev->id_entry->driver_data;
|
|
|
|
|
|
sport->clk = clk_get(&pdev->dev, "uart");
|
|
|
if (IS_ERR(sport->clk)) {
|
|
@@ -1340,6 +1392,7 @@ static struct platform_driver serial_imx_driver = {
|
|
|
|
|
|
.suspend = serial_imx_suspend,
|
|
|
.resume = serial_imx_resume,
|
|
|
+ .id_table = imx_uart_devtype,
|
|
|
.driver = {
|
|
|
.name = "imx-uart",
|
|
|
.owner = THIS_MODULE,
|