summaryrefslogtreecommitdiff
path: root/drivers/tty
diff options
context:
space:
mode:
authorZhao Qiang <B45475@freescale.com>2014-10-10 02:38:48 (GMT)
committerMatthew Weigel <Matthew.Weigel@freescale.com>2014-12-11 18:37:47 (GMT)
commit36396c5901f1067d25d9ada16acbd36edb716759 (patch)
tree98b102daa7f09ff6aef61422780f612dec4727c6 /drivers/tty
parent7ba5c48b5faf6fbd16e61263dfd4a380e3902569 (diff)
downloadlinux-fsl-qoriq-36396c5901f1067d25d9ada16acbd36edb716759.tar.xz
qe-uart: modify qe-uart to adapt both powerpc and arm
qe has been supported by arm board ls1021, qe-uart need to be supported by ls1021. modify the code to make qe-uart can work on both powerpc and ls1021. Signed-off-by: Zhao Qiang <B45475@freescale.com> --- upstream link: http://patchwork.ozlabs.org/patch/398471/ it is under discussion. Change-Id: I07a9a091882cd572330b38e7a6e0632aea9a9042 Reviewed-on: http://git.am.freescale.net:8181/21119 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Xiaobo Xie <X.Xie@freescale.com> Reviewed-by: Zhengxiong Jin <Jason.Jin@freescale.com>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/ucc_uart.c176
1 files changed, 90 insertions, 86 deletions
diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c
index 4718ebe..2c9a87c 100644
--- a/drivers/tty/serial/ucc_uart.c
+++ b/drivers/tty/serial/ucc_uart.c
@@ -26,13 +26,13 @@
#include <linux/tty_flip.h>
#include <linux/io.h>
#include <linux/of_platform.h>
+#include <linux/of_irq.h>
#include <linux/dma-mapping.h>
#include <linux/fs_uart_pd.h>
#include <linux/fsl/ucc_slow.h>
#include <linux/firmware.h>
-#include <asm/reg.h>
/*
* The GUMR flag for Soft UART. This would normally be defined in qe.h,
@@ -257,11 +257,11 @@ static unsigned int qe_uart_tx_empty(struct uart_port *port)
struct qe_bd *bdp = qe_port->tx_bd_base;
while (1) {
- if (in_be16(&bdp->status) & BD_SC_READY)
+ if (ioread16be(&bdp->status) & BD_SC_READY)
/* This BD is not done, so return "not done" */
return 0;
- if (in_be16(&bdp->status) & BD_SC_WRAP)
+ if (ioread16be(&bdp->status) & BD_SC_WRAP)
/*
* This BD is done and it's the last one, so return
* "done"
@@ -339,13 +339,13 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port)
/* Pick next descriptor and fill from buffer */
bdp = qe_port->tx_cur;
- p = qe2cpu_addr(bdp->buf, qe_port);
+ p = qe2cpu_addr(be32_to_cpu(bdp->buf), qe_port);
*p++ = port->x_char;
- out_be16(&bdp->length, 1);
+ iowrite16be(1, &bdp->length);
setbits16(&bdp->status, BD_SC_READY);
/* Get next BD. */
- if (in_be16(&bdp->status) & BD_SC_WRAP)
+ if (ioread16be(&bdp->status) & BD_SC_WRAP)
bdp = qe_port->tx_bd_base;
else
bdp++;
@@ -364,10 +364,10 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port)
/* Pick next descriptor and fill from buffer */
bdp = qe_port->tx_cur;
- while (!(in_be16(&bdp->status) & BD_SC_READY) &&
+ while (!(ioread16be(&bdp->status) & BD_SC_READY) &&
(xmit->tail != xmit->head)) {
count = 0;
- p = qe2cpu_addr(bdp->buf, qe_port);
+ p = qe2cpu_addr(be32_to_cpu(bdp->buf), qe_port);
while (count < qe_port->tx_fifosize) {
*p++ = xmit->buf[xmit->tail];
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
@@ -377,11 +377,11 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port)
break;
}
- out_be16(&bdp->length, count);
+ iowrite16be(count, &bdp->length);
setbits16(&bdp->status, BD_SC_READY);
/* Get next BD. */
- if (in_be16(&bdp->status) & BD_SC_WRAP)
+ if (ioread16be(&bdp->status) & BD_SC_WRAP)
bdp = qe_port->tx_bd_base;
else
bdp++;
@@ -414,7 +414,7 @@ static void qe_uart_start_tx(struct uart_port *port)
container_of(port, struct uart_qe_port, port);
/* If we currently are transmitting, then just return */
- if (in_be16(&qe_port->uccp->uccm) & UCC_UART_UCCE_TX)
+ if (ioread16be(&qe_port->uccp->uccm) & UCC_UART_UCCE_TX)
return;
/* Otherwise, pump the port and start transmission */
@@ -479,14 +479,14 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port)
*/
bdp = qe_port->rx_cur;
while (1) {
- status = in_be16(&bdp->status);
+ status = ioread16be(&bdp->status);
/* If this one is empty, then we assume we've read them all */
if (status & BD_SC_EMPTY)
break;
/* get number of characters, and check space in RX buffer */
- i = in_be16(&bdp->length);
+ i = ioread16be(&bdp->length);
/* If we don't have enough room in RX buffer for the entire BD,
* then we try later, which will be the next RX interrupt.
@@ -497,7 +497,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port)
}
/* get pointer */
- cp = qe2cpu_addr(bdp->buf, qe_port);
+ cp = qe2cpu_addr(be32_to_cpu(bdp->buf), qe_port);
/* loop through the buffer */
while (i-- > 0) {
@@ -519,7 +519,7 @@ error_return:
/* This BD is ready to be used again. Clear status. get next */
clrsetbits_be16(&bdp->status, BD_SC_BR | BD_SC_FR | BD_SC_PR |
BD_SC_OV | BD_SC_ID, BD_SC_EMPTY);
- if (in_be16(&bdp->status) & BD_SC_WRAP)
+ if (ioread16be(&bdp->status) & BD_SC_WRAP)
bdp = qe_port->rx_bd_base;
else
bdp++;
@@ -578,8 +578,8 @@ static irqreturn_t qe_uart_int(int irq, void *data)
u16 events;
/* Clear the interrupts */
- events = in_be16(&uccp->ucce);
- out_be16(&uccp->ucce, events);
+ events = ioread16be(&uccp->ucce);
+ iowrite16be(events, &uccp->ucce);
if (events & UCC_UART_UCCE_BRKE)
uart_handle_break(&qe_port->port);
@@ -610,17 +610,17 @@ static void qe_uart_initbd(struct uart_qe_port *qe_port)
bdp = qe_port->rx_bd_base;
qe_port->rx_cur = qe_port->rx_bd_base;
for (i = 0; i < (qe_port->rx_nrfifos - 1); i++) {
- out_be16(&bdp->status, BD_SC_EMPTY | BD_SC_INTRPT);
- out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port));
- out_be16(&bdp->length, 0);
+ iowrite16be(BD_SC_EMPTY | BD_SC_INTRPT, &bdp->status);
+ iowrite32be(cpu2qe_addr(bd_virt, qe_port), &bdp->buf);
+ iowrite16be(0, &bdp->length);
bd_virt += qe_port->rx_fifosize;
bdp++;
}
/* */
- out_be16(&bdp->status, BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT);
- out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port));
- out_be16(&bdp->length, 0);
+ iowrite16be(BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT, &bdp->status);
+ iowrite32be(cpu2qe_addr(bd_virt, qe_port), &bdp->buf);
+ iowrite16be(0, &bdp->length);
/* Set the physical address of the host memory
* buffers in the buffer descriptors, and the
@@ -631,9 +631,9 @@ static void qe_uart_initbd(struct uart_qe_port *qe_port)
qe_port->tx_cur = qe_port->tx_bd_base;
bdp = qe_port->tx_bd_base;
for (i = 0; i < (qe_port->tx_nrfifos - 1); i++) {
- out_be16(&bdp->status, BD_SC_INTRPT);
- out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port));
- out_be16(&bdp->length, 0);
+ iowrite16be(BD_SC_INTRPT, &bdp->status);
+ iowrite32be(cpu2qe_addr(bd_virt, qe_port), &bdp->buf);
+ iowrite16be(0, &bdp->length);
bd_virt += qe_port->tx_fifosize;
bdp++;
}
@@ -643,9 +643,9 @@ static void qe_uart_initbd(struct uart_qe_port *qe_port)
setbits16(&qe_port->tx_cur->status, BD_SC_P);
#endif
- out_be16(&bdp->status, BD_SC_WRAP | BD_SC_INTRPT);
- out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port));
- out_be16(&bdp->length, 0);
+ iowrite16be(BD_SC_WRAP | BD_SC_INTRPT, &bdp->status);
+ iowrite32be(cpu2qe_addr(bd_virt, qe_port), &bdp->buf);
+ iowrite16be(0, &bdp->length);
}
/*
@@ -667,21 +667,21 @@ static void qe_uart_init_ucc(struct uart_qe_port *qe_port)
ucc_slow_disable(qe_port->us_private, COMM_DIR_RX_AND_TX);
/* Program the UCC UART parameter RAM */
- out_8(&uccup->common.rbmr, UCC_BMR_GBL | UCC_BMR_BO_BE);
- out_8(&uccup->common.tbmr, UCC_BMR_GBL | UCC_BMR_BO_BE);
- out_be16(&uccup->common.mrblr, qe_port->rx_fifosize);
- out_be16(&uccup->maxidl, 0x10);
- out_be16(&uccup->brkcr, 1);
- out_be16(&uccup->parec, 0);
- out_be16(&uccup->frmec, 0);
- out_be16(&uccup->nosec, 0);
- out_be16(&uccup->brkec, 0);
- out_be16(&uccup->uaddr[0], 0);
- out_be16(&uccup->uaddr[1], 0);
- out_be16(&uccup->toseq, 0);
+ iowrite8(UCC_BMR_GBL | UCC_BMR_BO_BE, &uccup->common.rbmr);
+ iowrite8(UCC_BMR_GBL | UCC_BMR_BO_BE, &uccup->common.tbmr);
+ iowrite16be(qe_port->rx_fifosize, &uccup->common.mrblr);
+ iowrite16be(0x10, &uccup->maxidl);
+ iowrite16be(1, &uccup->brkcr);
+ iowrite16be(0, &uccup->parec);
+ iowrite16be(0, &uccup->frmec);
+ iowrite16be(0, &uccup->nosec);
+ iowrite16be(0, &uccup->brkec);
+ iowrite16be(0, &uccup->uaddr[0]);
+ iowrite16be(0, &uccup->uaddr[1]);
+ iowrite16be(0, &uccup->toseq);
for (i = 0; i < 8; i++)
- out_be16(&uccup->cchars[i], 0xC000);
- out_be16(&uccup->rccm, 0xc0ff);
+ iowrite16be(0xC000, &uccup->cchars[i]);
+ iowrite16be(0xc0ff, &uccup->rccm);
/* Configure the GUMR registers for UART */
if (soft_uart) {
@@ -715,30 +715,30 @@ static void qe_uart_init_ucc(struct uart_qe_port *qe_port)
#endif
/* Disable rx interrupts and clear all pending events. */
- out_be16(&uccp->uccm, 0);
- out_be16(&uccp->ucce, 0xffff);
- out_be16(&uccp->udsr, 0x7e7e);
+ iowrite16be(0, &uccp->uccm);
+ iowrite16be(0xffff, &uccp->ucce);
+ iowrite16be(0x7e7e, &uccp->udsr);
/* Initialize UPSMR */
- out_be16(&uccp->upsmr, 0);
+ iowrite16be(0, &uccp->upsmr);
if (soft_uart) {
- out_be16(&uccup->supsmr, 0x30);
- out_be16(&uccup->res92, 0);
- out_be32(&uccup->rx_state, 0);
- out_be32(&uccup->rx_cnt, 0);
- out_8(&uccup->rx_bitmark, 0);
- out_8(&uccup->rx_length, 10);
- out_be32(&uccup->dump_ptr, 0x4000);
- out_8(&uccup->rx_temp_dlst_qe, 0);
- out_be32(&uccup->rx_frame_rem, 0);
- out_8(&uccup->rx_frame_rem_size, 0);
+ iowrite16be(0x30, &uccup->supsmr);
+ iowrite16be(0, &uccup->res92);
+ iowrite32be(0, &uccup->rx_state);
+ iowrite32be(0, &uccup->rx_cnt);
+ iowrite8(0, &uccup->rx_bitmark);
+ iowrite8(10, &uccup->rx_length);
+ iowrite32be(0x4000, &uccup->dump_ptr);
+ iowrite8(0, &uccup->rx_temp_dlst_qe);
+ iowrite32be(0, &uccup->rx_frame_rem);
+ iowrite8(0, &uccup->rx_frame_rem_size);
/* Soft-UART requires TX to be 1X */
- out_8(&uccup->tx_mode,
- UCC_UART_TX_STATE_UART | UCC_UART_TX_STATE_X1);
- out_be16(&uccup->tx_state, 0);
- out_8(&uccup->resD4, 0);
- out_be16(&uccup->resD5, 0);
+ iowrite8(UCC_UART_TX_STATE_UART | UCC_UART_TX_STATE_X1,
+ &uccup->tx_mode);
+ iowrite16be(0, &uccup->tx_state);
+ iowrite8(0, &uccup->resD4);
+ iowrite16be(0, &uccup->resD5);
/* Set UART mode.
* Enable receive and transmit.
@@ -866,9 +866,9 @@ static void qe_uart_set_termios(struct uart_port *port,
struct ucc_slow __iomem *uccp = qe_port->uccp;
unsigned int baud;
unsigned long flags;
- u16 upsmr = in_be16(&uccp->upsmr);
+ u16 upsmr = ioread16be(&uccp->upsmr);
struct ucc_uart_pram __iomem *uccup = qe_port->uccup;
- u16 supsmr = in_be16(&uccup->supsmr);
+ u16 supsmr = ioread16be(&uccup->supsmr);
u8 char_length = 2; /* 1 + CL + PEN + 1 + SL */
/* Character length programmed into the mode register is the
@@ -966,10 +966,10 @@ static void qe_uart_set_termios(struct uart_port *port,
/* Update the per-port timeout. */
uart_update_timeout(port, termios->c_cflag, baud);
- out_be16(&uccp->upsmr, upsmr);
+ iowrite16be(upsmr, &uccp->upsmr);
if (soft_uart) {
- out_be16(&uccup->supsmr, supsmr);
- out_8(&uccup->rx_length, char_length);
+ iowrite16be(supsmr, &uccup->supsmr);
+ iowrite8(char_length, &uccup->rx_length);
/* Soft-UART requires a 1X multiplier for TX */
qe_setbrg(qe_port->us_info.rx_clock, baud, 16);
@@ -1139,7 +1139,9 @@ static unsigned int soc_info(unsigned int *rev_h, unsigned int *rev_l)
{
struct device_node *np;
const char *soc_string;
+#ifdef CONFIG_PPC_85xx
unsigned int svr;
+#endif
unsigned int soc;
/* Find the CPU node */
@@ -1156,10 +1158,12 @@ static unsigned int soc_info(unsigned int *rev_h, unsigned int *rev_l)
if ((sscanf(soc_string, "PowerPC,%u", &soc) != 1) || !soc)
return 0;
+#ifdef CONFIG_PPC_85xx
/* Get the revision from the SVR */
svr = mfspr(SPRN_SVR);
*rev_h = (svr >> 4) & 0xf;
*rev_l = svr & 0xf;
+#endif
return soc;
}
@@ -1202,7 +1206,7 @@ static void uart_firmware_cont(const struct firmware *fw, void *context)
static int ucc_uart_probe(struct platform_device *ofdev)
{
struct device_node *np = ofdev->dev.of_node;
- const unsigned int *iprop; /* Integer OF properties */
+ u32 val;
const char *sprop; /* String OF properties */
struct uart_qe_port *qe_port = NULL;
struct resource res;
@@ -1285,10 +1289,10 @@ static int ucc_uart_probe(struct platform_device *ofdev)
/* Get the UCC number (device ID) */
/* UCCs are numbered 1-7 */
- iprop = of_get_property(np, "cell-index", NULL);
- if (!iprop) {
- iprop = of_get_property(np, "device-id", NULL);
- if (!iprop) {
+ ret = of_property_read_u32_index(np, "cell-index", 0, &val);
+ if (ret) {
+ ret = of_property_read_u32_index(np, "device-id", 0, &val);
+ if (ret) {
dev_err(&ofdev->dev, "UCC is unspecified in "
"device tree\n");
ret = -EINVAL;
@@ -1296,12 +1300,12 @@ static int ucc_uart_probe(struct platform_device *ofdev)
}
}
- if ((*iprop < 1) || (*iprop > UCC_MAX_NUM)) {
- dev_err(&ofdev->dev, "no support for UCC%u\n", *iprop);
+ if ((val < 1) || (val > UCC_MAX_NUM)) {
+ dev_err(&ofdev->dev, "no support for UCC%u\n", val);
ret = -ENODEV;
goto out_free;
}
- qe_port->ucc_num = *iprop - 1;
+ qe_port->ucc_num = val - 1;
/*
* In the future, we should not require the BRG to be specified in the
@@ -1345,13 +1349,13 @@ static int ucc_uart_probe(struct platform_device *ofdev)
}
/* Get the port number, numbered 0-3 */
- iprop = of_get_property(np, "port-number", NULL);
- if (!iprop) {
+ ret = of_property_read_u32_index(np, "port-number", 0, &val);
+ if (ret) {
dev_err(&ofdev->dev, "missing port-number in device tree\n");
ret = -EINVAL;
goto out_free;
}
- qe_port->port.line = *iprop;
+ qe_port->port.line = val;
if (qe_port->port.line >= UCC_MAX_UART) {
dev_err(&ofdev->dev, "port-number must be 0-%u\n",
UCC_MAX_UART - 1);
@@ -1381,31 +1385,31 @@ static int ucc_uart_probe(struct platform_device *ofdev)
}
}
- iprop = of_get_property(np, "brg-frequency", NULL);
- if (!iprop) {
+ ret = of_property_read_u32_index(np, "brg-frequency", 0, &val);
+ if (ret) {
dev_err(&ofdev->dev,
"missing brg-frequency in device tree\n");
ret = -EINVAL;
goto out_np;
}
- if (*iprop)
- qe_port->port.uartclk = *iprop;
+ if (val)
+ qe_port->port.uartclk = val;
else {
/*
* Older versions of U-Boot do not initialize the brg-frequency
* property, so in this case we assume the BRG frequency is
* half the QE bus frequency.
*/
- iprop = of_get_property(np, "bus-frequency", NULL);
- if (!iprop) {
+ ret = of_property_read_u32_index(np, "bus-frequency", 0, &val);
+ if (ret) {
dev_err(&ofdev->dev,
"missing QE bus-frequency in device tree\n");
ret = -EINVAL;
goto out_np;
}
- if (*iprop)
- qe_port->port.uartclk = *iprop / 2;
+ if (val)
+ qe_port->port.uartclk = val / 2;
else {
dev_err(&ofdev->dev,
"invalid QE bus-frequency in device tree\n");