diff options
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/atmel_serial.c | 43 | ||||
-rw-r--r-- | drivers/tty/serial/msm_serial.c | 13 | ||||
-rw-r--r-- | drivers/tty/serial/serial_core.c | 1 | ||||
-rw-r--r-- | drivers/tty/serial/sprd_serial.c | 3 | ||||
-rw-r--r-- | drivers/tty/serial/ucc_uart.c | 385 | ||||
-rw-r--r-- | drivers/tty/tty_port.c | 3 |
6 files changed, 240 insertions, 208 deletions
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index a8dc8af83f39..1ba9bc667e13 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -2270,27 +2270,6 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, mode |= ATMEL_US_USMODE_NORMAL; } - /* set the mode, clock divisor, parity, stop bits and data size */ - atmel_uart_writel(port, ATMEL_US_MR, mode); - - /* - * when switching the mode, set the RTS line state according to the - * new mode, otherwise keep the former state - */ - if ((old_mode & ATMEL_US_USMODE) != (mode & ATMEL_US_USMODE)) { - unsigned int rts_state; - - if ((mode & ATMEL_US_USMODE) == ATMEL_US_USMODE_HWHS) { - /* let the hardware control the RTS line */ - rts_state = ATMEL_US_RTSDIS; - } else { - /* force RTS line to low level */ - rts_state = ATMEL_US_RTSEN; - } - - atmel_uart_writel(port, ATMEL_US_CR, rts_state); - } - /* * Set the baud rate: * Fractional baudrate allows to setup output frequency more @@ -2317,6 +2296,28 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, if (!(port->iso7816.flags & SER_ISO7816_ENABLED)) atmel_uart_writel(port, ATMEL_US_BRGR, quot); + + /* set the mode, clock divisor, parity, stop bits and data size */ + atmel_uart_writel(port, ATMEL_US_MR, mode); + + /* + * when switching the mode, set the RTS line state according to the + * new mode, otherwise keep the former state + */ + if ((old_mode & ATMEL_US_USMODE) != (mode & ATMEL_US_USMODE)) { + unsigned int rts_state; + + if ((mode & ATMEL_US_USMODE) == ATMEL_US_USMODE_HWHS) { + /* let the hardware control the RTS line */ + rts_state = ATMEL_US_RTSDIS; + } else { + /* force RTS line to low level */ + rts_state = ATMEL_US_RTSEN; + } + + atmel_uart_writel(port, ATMEL_US_CR, rts_state); + } + atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_TXEN | ATMEL_US_RXEN); atmel_port->tx_stopped = false; diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 1cbae0768b1f..f6c45a796433 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -1580,6 +1580,7 @@ static void __msm_console_write(struct uart_port *port, const char *s, int num_newlines = 0; bool replaced = false; void __iomem *tf; + int locked = 1; if (is_uartdm) tf = port->membase + UARTDM_TF; @@ -1592,7 +1593,13 @@ static void __msm_console_write(struct uart_port *port, const char *s, num_newlines++; count += num_newlines; - spin_lock(&port->lock); + if (port->sysrq) + locked = 0; + else if (oops_in_progress) + locked = spin_trylock(&port->lock); + else + spin_lock(&port->lock); + if (is_uartdm) msm_reset_dm_count(port, count); @@ -1628,7 +1635,9 @@ static void __msm_console_write(struct uart_port *port, const char *s, iowrite32_rep(tf, buf, 1); i += num_chars; } - spin_unlock(&port->lock); + + if (locked) + spin_unlock(&port->lock); } static void msm_console_write(struct console *co, const char *s, diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index b0a6eb106edb..7c2782785736 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2834,6 +2834,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) if (uport->cons && uport->dev) of_console_check(uport->dev->of_node, uport->cons->name, uport->line); + tty_port_link_device(port, drv->tty_driver, uport->line); uart_configure_port(drv, state, uport); port->console = uart_console(uport); diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 31df23502562..f60a59d9bf27 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -679,6 +679,9 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id) if (ims & SPRD_IMSR_TIMEOUT) serial_out(port, SPRD_ICLR, SPRD_ICLR_TIMEOUT); + if (ims & SPRD_IMSR_BREAK_DETECT) + serial_out(port, SPRD_ICLR, SPRD_IMSR_BREAK_DETECT); + if (ims & (SPRD_IMSR_RX_FIFO_FULL | SPRD_IMSR_BREAK_DETECT | SPRD_IMSR_TIMEOUT)) sprd_rx(port); diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index a0555ae2b1ef..afc2a5d69202 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -32,7 +32,11 @@ #include <soc/fsl/qe/ucc_slow.h> #include <linux/firmware.h> -#include <asm/reg.h> +#include <soc/fsl/cpm.h> + +#ifdef CONFIG_PPC32 +#include <asm/reg.h> /* mfspr, SPRN_SVR */ +#endif /* * The GUMR flag for Soft UART. This would normally be defined in qe.h, @@ -257,11 +261,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 (qe_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 (qe_ioread16be(&bdp->status) & BD_SC_WRAP) /* * This BD is done and it's the last one, so return * "done" @@ -307,7 +311,7 @@ static void qe_uart_stop_tx(struct uart_port *port) struct uart_qe_port *qe_port = container_of(port, struct uart_qe_port, port); - clrbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_TX); + qe_clrbits_be16(&qe_port->uccp->uccm, UCC_UART_UCCE_TX); } /* @@ -339,13 +343,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); - setbits16(&bdp->status, BD_SC_READY); + qe_iowrite16be(1, &bdp->length); + qe_setbits_be16(&bdp->status, BD_SC_READY); /* Get next BD. */ - if (in_be16(&bdp->status) & BD_SC_WRAP) + if (qe_ioread16be(&bdp->status) & BD_SC_WRAP) bdp = qe_port->tx_bd_base; else bdp++; @@ -364,10 +368,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 (!(qe_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 +381,11 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port) break; } - out_be16(&bdp->length, count); - setbits16(&bdp->status, BD_SC_READY); + qe_iowrite16be(count, &bdp->length); + qe_setbits_be16(&bdp->status, BD_SC_READY); /* Get next BD. */ - if (in_be16(&bdp->status) & BD_SC_WRAP) + if (qe_ioread16be(&bdp->status) & BD_SC_WRAP) bdp = qe_port->tx_bd_base; else bdp++; @@ -414,12 +418,12 @@ 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 (qe_ioread16be(&qe_port->uccp->uccm) & UCC_UART_UCCE_TX) return; /* Otherwise, pump the port and start transmission */ if (qe_uart_tx_pump(qe_port)) - setbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_TX); + qe_setbits_be16(&qe_port->uccp->uccm, UCC_UART_UCCE_TX); } /* @@ -430,7 +434,7 @@ static void qe_uart_stop_rx(struct uart_port *port) struct uart_qe_port *qe_port = container_of(port, struct uart_qe_port, port); - clrbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_RX); + qe_clrbits_be16(&qe_port->uccp->uccm, UCC_UART_UCCE_RX); } /* Start or stop sending break signal @@ -469,14 +473,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 = qe_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 = qe_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. @@ -487,7 +491,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) { @@ -507,9 +511,10 @@ 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) + qe_clrsetbits_be16(&bdp->status, + BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID, + BD_SC_EMPTY); + if (qe_ioread16be(&bdp->status) & BD_SC_WRAP) bdp = qe_port->rx_bd_base; else bdp++; @@ -568,8 +573,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 = qe_ioread16be(&uccp->ucce); + qe_iowrite16be(events, &uccp->ucce); if (events & UCC_UART_UCCE_BRKE) uart_handle_break(&qe_port->port); @@ -600,17 +605,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); + qe_iowrite16be(BD_SC_EMPTY | BD_SC_INTRPT, &bdp->status); + qe_iowrite32be(cpu2qe_addr(bd_virt, qe_port), &bdp->buf); + qe_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); + qe_iowrite16be(BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT, &bdp->status); + qe_iowrite32be(cpu2qe_addr(bd_virt, qe_port), &bdp->buf); + qe_iowrite16be(0, &bdp->length); /* Set the physical address of the host memory * buffers in the buffer descriptors, and the @@ -621,21 +626,21 @@ 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); + qe_iowrite16be(BD_SC_INTRPT, &bdp->status); + qe_iowrite32be(cpu2qe_addr(bd_virt, qe_port), &bdp->buf); + qe_iowrite16be(0, &bdp->length); bd_virt += qe_port->tx_fifosize; bdp++; } /* Loopback requires the preamble bit to be set on the first TX BD */ #ifdef LOOPBACK - setbits16(&qe_port->tx_cur->status, BD_SC_P); + qe_setbits_be16(&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); + qe_iowrite16be(BD_SC_WRAP | BD_SC_INTRPT, &bdp->status); + qe_iowrite32be(cpu2qe_addr(bd_virt, qe_port), &bdp->buf); + qe_iowrite16be(0, &bdp->length); } /* @@ -657,78 +662,74 @@ 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); + qe_iowrite8(UCC_BMR_GBL | UCC_BMR_BO_BE, &uccup->common.rbmr); + qe_iowrite8(UCC_BMR_GBL | UCC_BMR_BO_BE, &uccup->common.tbmr); + qe_iowrite16be(qe_port->rx_fifosize, &uccup->common.mrblr); + qe_iowrite16be(0x10, &uccup->maxidl); + qe_iowrite16be(1, &uccup->brkcr); + qe_iowrite16be(0, &uccup->parec); + qe_iowrite16be(0, &uccup->frmec); + qe_iowrite16be(0, &uccup->nosec); + qe_iowrite16be(0, &uccup->brkec); + qe_iowrite16be(0, &uccup->uaddr[0]); + qe_iowrite16be(0, &uccup->uaddr[1]); + qe_iowrite16be(0, &uccup->toseq); for (i = 0; i < 8; i++) - out_be16(&uccup->cchars[i], 0xC000); - out_be16(&uccup->rccm, 0xc0ff); + qe_iowrite16be(0xC000, &uccup->cchars[i]); + qe_iowrite16be(0xc0ff, &uccup->rccm); /* Configure the GUMR registers for UART */ if (soft_uart) { /* Soft-UART requires a 1X multiplier for TX */ - clrsetbits_be32(&uccp->gumr_l, - UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK | - UCC_SLOW_GUMR_L_RDCR_MASK, - UCC_SLOW_GUMR_L_MODE_UART | UCC_SLOW_GUMR_L_TDCR_1 | - UCC_SLOW_GUMR_L_RDCR_16); - - clrsetbits_be32(&uccp->gumr_h, UCC_SLOW_GUMR_H_RFW, - UCC_SLOW_GUMR_H_TRX | UCC_SLOW_GUMR_H_TTX); + qe_clrsetbits_be32(&uccp->gumr_l, + UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK | UCC_SLOW_GUMR_L_RDCR_MASK, + UCC_SLOW_GUMR_L_MODE_UART | UCC_SLOW_GUMR_L_TDCR_1 | UCC_SLOW_GUMR_L_RDCR_16); + + qe_clrsetbits_be32(&uccp->gumr_h, UCC_SLOW_GUMR_H_RFW, + UCC_SLOW_GUMR_H_TRX | UCC_SLOW_GUMR_H_TTX); } else { - clrsetbits_be32(&uccp->gumr_l, - UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK | - UCC_SLOW_GUMR_L_RDCR_MASK, - UCC_SLOW_GUMR_L_MODE_UART | UCC_SLOW_GUMR_L_TDCR_16 | - UCC_SLOW_GUMR_L_RDCR_16); - - clrsetbits_be32(&uccp->gumr_h, - UCC_SLOW_GUMR_H_TRX | UCC_SLOW_GUMR_H_TTX, - UCC_SLOW_GUMR_H_RFW); + qe_clrsetbits_be32(&uccp->gumr_l, + UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK | UCC_SLOW_GUMR_L_RDCR_MASK, + UCC_SLOW_GUMR_L_MODE_UART | UCC_SLOW_GUMR_L_TDCR_16 | UCC_SLOW_GUMR_L_RDCR_16); + + qe_clrsetbits_be32(&uccp->gumr_h, + UCC_SLOW_GUMR_H_TRX | UCC_SLOW_GUMR_H_TTX, + UCC_SLOW_GUMR_H_RFW); } #ifdef LOOPBACK - clrsetbits_be32(&uccp->gumr_l, UCC_SLOW_GUMR_L_DIAG_MASK, - UCC_SLOW_GUMR_L_DIAG_LOOP); - clrsetbits_be32(&uccp->gumr_h, - UCC_SLOW_GUMR_H_CTSP | UCC_SLOW_GUMR_H_RSYN, - UCC_SLOW_GUMR_H_CDS); + qe_clrsetbits_be32(&uccp->gumr_l, UCC_SLOW_GUMR_L_DIAG_MASK, + UCC_SLOW_GUMR_L_DIAG_LOOP); + qe_clrsetbits_be32(&uccp->gumr_h, + UCC_SLOW_GUMR_H_CTSP | UCC_SLOW_GUMR_H_RSYN, + UCC_SLOW_GUMR_H_CDS); #endif /* Disable rx interrupts and clear all pending events. */ - out_be16(&uccp->uccm, 0); - out_be16(&uccp->ucce, 0xffff); - out_be16(&uccp->udsr, 0x7e7e); + qe_iowrite16be(0, &uccp->uccm); + qe_iowrite16be(0xffff, &uccp->ucce); + qe_iowrite16be(0x7e7e, &uccp->udsr); /* Initialize UPSMR */ - out_be16(&uccp->upsmr, 0); + qe_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); + qe_iowrite16be(0x30, &uccup->supsmr); + qe_iowrite16be(0, &uccup->res92); + qe_iowrite32be(0, &uccup->rx_state); + qe_iowrite32be(0, &uccup->rx_cnt); + qe_iowrite8(0, &uccup->rx_bitmark); + qe_iowrite8(10, &uccup->rx_length); + qe_iowrite32be(0x4000, &uccup->dump_ptr); + qe_iowrite8(0, &uccup->rx_temp_dlst_qe); + qe_iowrite32be(0, &uccup->rx_frame_rem); + qe_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); + qe_iowrite8(UCC_UART_TX_STATE_UART | UCC_UART_TX_STATE_X1, + &uccup->tx_mode); + qe_iowrite16be(0, &uccup->tx_state); + qe_iowrite8(0, &uccup->resD4); + qe_iowrite16be(0, &uccup->resD5); /* Set UART mode. * Enable receive and transmit. @@ -742,22 +743,19 @@ static void qe_uart_init_ucc(struct uart_qe_port *qe_port) * ... * 6.Receiver must use 16x over sampling */ - clrsetbits_be32(&uccp->gumr_l, - UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK | - UCC_SLOW_GUMR_L_RDCR_MASK, - UCC_SLOW_GUMR_L_MODE_QMC | UCC_SLOW_GUMR_L_TDCR_16 | - UCC_SLOW_GUMR_L_RDCR_16); + qe_clrsetbits_be32(&uccp->gumr_l, + UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK | UCC_SLOW_GUMR_L_RDCR_MASK, + UCC_SLOW_GUMR_L_MODE_QMC | UCC_SLOW_GUMR_L_TDCR_16 | UCC_SLOW_GUMR_L_RDCR_16); - clrsetbits_be32(&uccp->gumr_h, - UCC_SLOW_GUMR_H_RFW | UCC_SLOW_GUMR_H_RSYN, - UCC_SLOW_GUMR_H_SUART | UCC_SLOW_GUMR_H_TRX | - UCC_SLOW_GUMR_H_TTX | UCC_SLOW_GUMR_H_TFL); + qe_clrsetbits_be32(&uccp->gumr_h, + UCC_SLOW_GUMR_H_RFW | UCC_SLOW_GUMR_H_RSYN, + UCC_SLOW_GUMR_H_SUART | UCC_SLOW_GUMR_H_TRX | UCC_SLOW_GUMR_H_TTX | UCC_SLOW_GUMR_H_TFL); #ifdef LOOPBACK - clrsetbits_be32(&uccp->gumr_l, UCC_SLOW_GUMR_L_DIAG_MASK, - UCC_SLOW_GUMR_L_DIAG_LOOP); - clrbits32(&uccp->gumr_h, UCC_SLOW_GUMR_H_CTSP | - UCC_SLOW_GUMR_H_CDS); + qe_clrsetbits_be32(&uccp->gumr_l, UCC_SLOW_GUMR_L_DIAG_MASK, + UCC_SLOW_GUMR_L_DIAG_LOOP); + qe_clrbits_be32(&uccp->gumr_h, + UCC_SLOW_GUMR_H_CTSP | UCC_SLOW_GUMR_H_CDS); #endif cecr_subblock = ucc_slow_get_qe_cr_subblock(qe_port->ucc_num); @@ -800,7 +798,7 @@ static int qe_uart_startup(struct uart_port *port) } /* Startup rx-int */ - setbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_RX); + qe_setbits_be16(&qe_port->uccp->uccm, UCC_UART_UCCE_RX); ucc_slow_enable(qe_port->us_private, COMM_DIR_RX_AND_TX); return 0; @@ -836,7 +834,7 @@ static void qe_uart_shutdown(struct uart_port *port) /* Stop uarts */ ucc_slow_disable(qe_port->us_private, COMM_DIR_RX_AND_TX); - clrbits16(&uccp->uccm, UCC_UART_UCCE_TX | UCC_UART_UCCE_RX); + qe_clrbits_be16(&uccp->uccm, UCC_UART_UCCE_TX | UCC_UART_UCCE_RX); /* Shut them really down and reinit buffer descriptors */ ucc_slow_graceful_stop_tx(qe_port->us_private); @@ -856,9 +854,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 = qe_ioread16be(&uccp->upsmr); struct ucc_uart_pram __iomem *uccup = qe_port->uccup; - u16 supsmr = in_be16(&uccup->supsmr); + u16 supsmr = qe_ioread16be(&uccup->supsmr); u8 char_length = 2; /* 1 + CL + PEN + 1 + SL */ /* Character length programmed into the mode register is the @@ -956,10 +954,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); + qe_iowrite16be(upsmr, &uccp->upsmr); if (soft_uart) { - out_be16(&uccup->supsmr, supsmr); - out_8(&uccup->rx_length, char_length); + qe_iowrite16be(supsmr, &uccup->supsmr); + qe_iowrite8(char_length, &uccup->rx_length); /* Soft-UART requires a 1X multiplier for TX */ qe_setbrg(qe_port->us_info.rx_clock, baud, 16); @@ -1101,6 +1099,8 @@ static const struct uart_ops qe_uart_pops = { .verify_port = qe_uart_verify_port, }; + +#ifdef CONFIG_PPC32 /* * Obtain the SOC model number and revision level * @@ -1188,70 +1188,86 @@ static void uart_firmware_cont(const struct firmware *fw, void *context) release_firmware(fw); } -static int ucc_uart_probe(struct platform_device *ofdev) +static int soft_uart_init(struct platform_device *ofdev) { struct device_node *np = ofdev->dev.of_node; - const unsigned int *iprop; /* Integer OF properties */ - const char *sprop; /* String OF properties */ - struct uart_qe_port *qe_port = NULL; - struct resource res; + struct qe_firmware_info *qe_fw_info; int ret; - /* - * Determine if we need Soft-UART mode - */ if (of_find_property(np, "soft-uart", NULL)) { dev_dbg(&ofdev->dev, "using Soft-UART mode\n"); soft_uart = 1; + } else { + return 0; } - /* - * If we are using Soft-UART, determine if we need to upload the - * firmware, too. - */ - if (soft_uart) { - struct qe_firmware_info *qe_fw_info; - - qe_fw_info = qe_get_firmware_info(); - - /* Check if the firmware has been uploaded. */ - if (qe_fw_info && strstr(qe_fw_info->id, "Soft-UART")) { - firmware_loaded = 1; - } else { - char filename[32]; - unsigned int soc; - unsigned int rev_h; - unsigned int rev_l; - - soc = soc_info(&rev_h, &rev_l); - if (!soc) { - dev_err(&ofdev->dev, "unknown CPU model\n"); - return -ENXIO; - } - sprintf(filename, "fsl_qe_ucode_uart_%u_%u%u.bin", - soc, rev_h, rev_l); - - dev_info(&ofdev->dev, "waiting for firmware %s\n", - filename); + qe_fw_info = qe_get_firmware_info(); - /* - * We call request_firmware_nowait instead of - * request_firmware so that the driver can load and - * initialize the ports without holding up the rest of - * the kernel. If hotplug support is enabled in the - * kernel, then we use it. - */ - ret = request_firmware_nowait(THIS_MODULE, - FW_ACTION_HOTPLUG, filename, &ofdev->dev, - GFP_KERNEL, &ofdev->dev, uart_firmware_cont); - if (ret) { - dev_err(&ofdev->dev, - "could not load firmware %s\n", - filename); - return ret; - } + /* Check if the firmware has been uploaded. */ + if (qe_fw_info && strstr(qe_fw_info->id, "Soft-UART")) { + firmware_loaded = 1; + } else { + char filename[32]; + unsigned int soc; + unsigned int rev_h; + unsigned int rev_l; + + soc = soc_info(&rev_h, &rev_l); + if (!soc) { + dev_err(&ofdev->dev, "unknown CPU model\n"); + return -ENXIO; + } + sprintf(filename, "fsl_qe_ucode_uart_%u_%u%u.bin", + soc, rev_h, rev_l); + + dev_info(&ofdev->dev, "waiting for firmware %s\n", + filename); + + /* + * We call request_firmware_nowait instead of + * request_firmware so that the driver can load and + * initialize the ports without holding up the rest of + * the kernel. If hotplug support is enabled in the + * kernel, then we use it. + */ + ret = request_firmware_nowait(THIS_MODULE, + FW_ACTION_HOTPLUG, filename, &ofdev->dev, + GFP_KERNEL, &ofdev->dev, uart_firmware_cont); + if (ret) { + dev_err(&ofdev->dev, + "could not load firmware %s\n", + filename); + return ret; } } + return 0; +} + +#else /* !CONFIG_PPC32 */ + +static int soft_uart_init(struct platform_device *ofdev) +{ + return 0; +} + +#endif + + +static int ucc_uart_probe(struct platform_device *ofdev) +{ + struct device_node *np = ofdev->dev.of_node; + const char *sprop; /* String OF properties */ + struct uart_qe_port *qe_port = NULL; + struct resource res; + u32 val; + int ret; + + /* + * Determine if we need Soft-UART mode + */ + ret = soft_uart_init(ofdev); + if (ret) + return ret; qe_port = kzalloc(sizeof(struct uart_qe_port), GFP_KERNEL); if (!qe_port) { @@ -1274,23 +1290,20 @@ 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) { - dev_err(&ofdev->dev, "UCC is unspecified in " - "device tree\n"); + if (of_property_read_u32(np, "cell-index", &val)) { + if (of_property_read_u32(np, "device-id", &val)) { + dev_err(&ofdev->dev, "UCC is unspecified in device tree\n"); ret = -EINVAL; goto out_free; } } - 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 @@ -1334,13 +1347,12 @@ 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) { + if (of_property_read_u32(np, "port-number", &val)) { 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); @@ -1370,31 +1382,36 @@ static int ucc_uart_probe(struct platform_device *ofdev) } } - iprop = of_get_property(np, "brg-frequency", NULL); - if (!iprop) { + if (of_property_read_u32(np, "brg-frequency", &val)) { 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 { + if (!IS_ENABLED(CONFIG_PPC32)) { + dev_err(&ofdev->dev, + "invalid brg-frequency in device tree\n"); + ret = -EINVAL; + goto out_np; + } + /* * 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) { + if (of_property_read_u32(np, "bus-frequency", &val)) { 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"); diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 044c3cbdcfa4..5023c85ebc6e 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -89,7 +89,8 @@ void tty_port_link_device(struct tty_port *port, { if (WARN_ON(index >= driver->num)) return; - driver->ports[index] = port; + if (!driver->ports[index]) + driver->ports[index] = port; } EXPORT_SYMBOL_GPL(tty_port_link_device); |