summaryrefslogtreecommitdiff
path: root/drivers/tty/serial/imx.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-02 18:32:06 (GMT)
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-02 18:32:06 (GMT)
commit0de10f9ea67d1046b1e16c91fa26accf23939aab (patch)
tree1255e106529d0c708b3744dfd10367a535bda6f9 /drivers/tty/serial/imx.c
parenta84270189e2afc7028b1123415a66d444f460977 (diff)
parent828c6a102b1f2b8583fadc0e779c46b31d448f0b (diff)
downloadlinux-fsl-qoriq-0de10f9ea67d1046b1e16c91fa26accf23939aab.tar.xz
Merge tag 'tty-3.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial updates from Greg KH: "Here is the big TTY / Serial driver merge for 3.11-rc1. It's not all that big, nothing major changed in the tty api, which is a nice change, just a number of serial driver fixes and updates and new drivers, along with some n_tty fixes to help resolve some reported issues. All of these have been in the linux-next releases for a while, with the exception of the last revert patch, which was reported this past weekend by two different people as being needed." * tag 'tty-3.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (51 commits) Revert "serial: 8250_pci: add support for another kind of NetMos Technology PCI 9835 Multi-I/O Controller" pch_uart: Add uart_clk selection for the MinnowBoard tty: atmel_serial: prepare clk before calling enable tty: Reset itty for other pty n_tty: Buffer work should not reschedule itself n_tty: Fix unsafe update of available buffer space n_tty: Untangle read completion variables n_tty: Encapsulate minimum_to_wake within N_TTY serial: omap: Fix device tree based PM runtime serial: imx: Fix serial clock unbalance serial/mpc52xx_uart: fix kernel panic when system reboot serial: mfd: Add sysrq support serial: imx: enable the clocks for console tty: serial: add Freescale lpuart driver support serial: imx: Improve Kconfig text serial: imx: Allow module build serial: imx: Fix warning when !CONFIG_SERIAL_IMX_CONSOLE tty/serial/sirf: fix error propagation in sirfsoc_uart_probe() serial: omap: fix potential NULL pointer dereference in serial_omap_runtime_suspend() tty: serial: Enable uartlite for ARM zynq ...
Diffstat (limited to 'drivers/tty/serial/imx.c')
-rw-r--r--drivers/tty/serial/imx.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 8cdfbd3..415cec6 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -201,6 +201,7 @@ struct imx_port {
unsigned int old_status;
int txirq, rxirq, rtsirq;
unsigned int have_rtscts:1;
+ unsigned int dte_mode:1;
unsigned int use_irda:1;
unsigned int irda_inv_rx:1;
unsigned int irda_inv_tx:1;
@@ -271,6 +272,7 @@ static inline int is_imx21_uart(struct imx_port *sport)
/*
* Save and restore functions for UCR1, UCR2 and UCR3 registers
*/
+#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_IMX_CONSOLE)
static void imx_port_ucrs_save(struct uart_port *port,
struct imx_port_ucrs *ucr)
{
@@ -288,6 +290,7 @@ static void imx_port_ucrs_restore(struct uart_port *port,
writel(ucr->ucr2, port->membase + UCR2);
writel(ucr->ucr3, port->membase + UCR3);
}
+#endif
/*
* Handle any change of modem status signal since we were last called.
@@ -449,6 +452,13 @@ static void imx_start_tx(struct uart_port *port)
temp &= ~(UCR1_RRDYEN);
writel(temp, sport->port.membase + UCR1);
}
+ /* Clear any pending ORE flag before enabling interrupt */
+ temp = readl(sport->port.membase + USR2);
+ writel(temp | USR2_ORE, sport->port.membase + USR2);
+
+ temp = readl(sport->port.membase + UCR4);
+ temp |= UCR4_OREN;
+ writel(temp, sport->port.membase + UCR4);
temp = readl(sport->port.membase + UCR1);
writel(temp | UCR1_TXMPTYEN, sport->port.membase + UCR1);
@@ -582,6 +592,7 @@ static irqreturn_t imx_int(int irq, void *dev_id)
{
struct imx_port *sport = dev_id;
unsigned int sts;
+ unsigned int sts2;
sts = readl(sport->port.membase + USR1);
@@ -598,6 +609,13 @@ static irqreturn_t imx_int(int irq, void *dev_id)
if (sts & USR1_AWAKE)
writel(USR1_AWAKE, sport->port.membase + USR1);
+ sts2 = readl(sport->port.membase + USR2);
+ if (sts2 & USR2_ORE) {
+ dev_err(sport->port.dev, "Rx FIFO overrun\n");
+ sport->port.icount.overrun++;
+ writel(sts2 | USR2_ORE, sport->port.membase + USR2);
+ }
+
return IRQ_HANDLED;
}
@@ -684,6 +702,17 @@ static int imx_startup(struct uart_port *port)
int retval;
unsigned long flags, temp;
+ if (!uart_console(port)) {
+ retval = clk_prepare_enable(sport->clk_per);
+ if (retval)
+ goto error_out1;
+ retval = clk_prepare_enable(sport->clk_ipg);
+ if (retval) {
+ clk_disable_unprepare(sport->clk_per);
+ goto error_out1;
+ }
+ }
+
imx_setup_ufcr(sport, 0);
/* disable the DREN bit (Data Ready interrupt enable) before
@@ -871,6 +900,11 @@ static void imx_shutdown(struct uart_port *port)
writel(temp, sport->port.membase + UCR1);
spin_unlock_irqrestore(&sport->port.lock, flags);
+
+ if (!uart_console(&sport->port)) {
+ clk_disable_unprepare(sport->clk_per);
+ clk_disable_unprepare(sport->clk_ipg);
+ }
}
static void
@@ -1007,6 +1041,8 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
ufcr = readl(sport->port.membase + UFCR);
ufcr = (ufcr & (~UFCR_RFDIV)) | UFCR_RFDIV_REG(div);
+ if (sport->dte_mode)
+ ufcr |= UFCR_DCEDTE;
writel(ufcr, sport->port.membase + UFCR);
writel(num, sport->port.membase + UBIR);
@@ -1431,6 +1467,9 @@ static int serial_imx_probe_dt(struct imx_port *sport,
if (of_get_property(np, "fsl,irda-mode", NULL))
sport->use_irda = 1;
+ if (of_get_property(np, "fsl,dte-mode", NULL))
+ sport->dte_mode = 1;
+
sport->devdata = of_id->data;
return 0;
@@ -1544,6 +1583,11 @@ static int serial_imx_probe(struct platform_device *pdev)
goto deinit;
platform_set_drvdata(pdev, sport);
+ if (!uart_console(&sport->port)) {
+ clk_disable_unprepare(sport->clk_per);
+ clk_disable_unprepare(sport->clk_ipg);
+ }
+
return 0;
deinit:
if (pdata && pdata->exit)
@@ -1565,9 +1609,6 @@ static int serial_imx_remove(struct platform_device *pdev)
uart_remove_one_port(&imx_reg, &sport->port);
- clk_disable_unprepare(sport->clk_per);
- clk_disable_unprepare(sport->clk_ipg);
-
if (pdata && pdata->exit)
pdata->exit(pdev);