diff options
author | Olof Johansson <olof@lixom.net> | 2020-01-16 12:47:12 -0800 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2020-01-16 12:47:13 -0800 |
commit | a9e3e12f3f58083b4c0fda7bcb95d05841e982bb (patch) | |
tree | afe97a74424467b52b054b23279c5625929ae731 /drivers/tty | |
parent | 0f827273178f5656edf1210dc94b8653df7580bf (diff) | |
parent | 6e62bd36e9ad85a22d92b1adce6a0336ea549733 (diff) | |
download | linux-a9e3e12f3f58083b4c0fda7bcb95d05841e982bb.tar.bz2 |
Merge tag 'soc-fsl-next-v5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/leo/linux into arm/drivers
NXP/FSL SoC driver updates for v5.6
QUICC Engine drivers
- Improve the QE drivers to be compatible with ARM/ARM64/PPC64
architectures
- Various cleanups to the QE drivers
* tag 'soc-fsl-next-v5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/leo/linux: (49 commits)
soc: fsl: qe: remove set but not used variable 'mm_gc'
soc: fsl: qe: remove PPC32 dependency from CONFIG_QUICC_ENGINE
soc: fsl: qe: remove unused #include of asm/irq.h from ucc.c
net: ethernet: freescale: make UCC_GETH explicitly depend on PPC32
net/wan/fsl_ucc_hdlc: reject muram offsets above 64K
net/wan/fsl_ucc_hdlc: fix reading of __be16 registers
net/wan/fsl_ucc_hdlc: avoid use of IS_ERR_VALUE()
soc: fsl: qe: avoid IS_ERR_VALUE in ucc_fast.c
soc: fsl: qe: drop pointless check in qe_sdma_init()
soc: fsl: qe: drop use of IS_ERR_VALUE in qe_sdma_init()
soc: fsl: qe: avoid IS_ERR_VALUE in ucc_slow.c
soc: fsl: qe: refactor cpm_muram_alloc_common to prevent BUG on error path
soc: fsl: qe: drop broken lazy call of cpm_muram_init()
soc: fsl: qe: make cpm_muram_free() ignore a negative offset
soc: fsl: qe: make cpm_muram_free() return void
soc: fsl: qe: change return type of cpm_muram_alloc() to s32
serial: ucc_uart: access __be32 field using be32_to_cpu
serial: ucc_uart: limit brg-frequency workaround to PPC32
serial: ucc_uart: use of_property_read_u32() in ucc_uart_probe()
serial: ucc_uart: stub out soft_uart_init for !CONFIG_PPC32
...
Link: https://lore.kernel.org/r/1578608351-23289-1-git-send-email-leoyang.li@nxp.com
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/ucc_uart.c | 385 |
1 files changed, 201 insertions, 184 deletions
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"); |