|
@@ -93,6 +93,10 @@ static u16 pl011_std_offsets[REG_ARRAY_SIZE] = {
|
|
|
struct vendor_data {
|
|
|
const u16 *reg_offset;
|
|
|
unsigned int ifls;
|
|
|
+ unsigned int fr_busy;
|
|
|
+ unsigned int fr_dsr;
|
|
|
+ unsigned int fr_cts;
|
|
|
+ unsigned int fr_ri;
|
|
|
bool access_32b;
|
|
|
bool oversampling;
|
|
|
bool dma_threshold;
|
|
@@ -111,6 +115,10 @@ static unsigned int get_fifosize_arm(struct amba_device *dev)
|
|
|
static struct vendor_data vendor_arm = {
|
|
|
.reg_offset = pl011_std_offsets,
|
|
|
.ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
|
|
|
+ .fr_busy = UART01x_FR_BUSY,
|
|
|
+ .fr_dsr = UART01x_FR_DSR,
|
|
|
+ .fr_cts = UART01x_FR_CTS,
|
|
|
+ .fr_ri = UART011_FR_RI,
|
|
|
.oversampling = false,
|
|
|
.dma_threshold = false,
|
|
|
.cts_event_workaround = false,
|
|
@@ -121,6 +129,10 @@ static struct vendor_data vendor_arm = {
|
|
|
|
|
|
static struct vendor_data vendor_sbsa = {
|
|
|
.reg_offset = pl011_std_offsets,
|
|
|
+ .fr_busy = UART01x_FR_BUSY,
|
|
|
+ .fr_dsr = UART01x_FR_DSR,
|
|
|
+ .fr_cts = UART01x_FR_CTS,
|
|
|
+ .fr_ri = UART011_FR_RI,
|
|
|
.access_32b = true,
|
|
|
.oversampling = false,
|
|
|
.dma_threshold = false,
|
|
@@ -164,6 +176,10 @@ static unsigned int get_fifosize_st(struct amba_device *dev)
|
|
|
static struct vendor_data vendor_st = {
|
|
|
.reg_offset = pl011_st_offsets,
|
|
|
.ifls = UART011_IFLS_RX_HALF|UART011_IFLS_TX_HALF,
|
|
|
+ .fr_busy = UART01x_FR_BUSY,
|
|
|
+ .fr_dsr = UART01x_FR_DSR,
|
|
|
+ .fr_cts = UART01x_FR_CTS,
|
|
|
+ .fr_ri = UART011_FR_RI,
|
|
|
.oversampling = true,
|
|
|
.dma_threshold = true,
|
|
|
.cts_event_workaround = true,
|
|
@@ -192,6 +208,10 @@ static struct vendor_data vendor_zte __maybe_unused = {
|
|
|
.reg_offset = pl011_zte_offsets,
|
|
|
.access_32b = true,
|
|
|
.ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
|
|
|
+ .fr_busy = ZX_UART01x_FR_BUSY,
|
|
|
+ .fr_dsr = ZX_UART01x_FR_DSR,
|
|
|
+ .fr_cts = ZX_UART01x_FR_CTS,
|
|
|
+ .fr_ri = ZX_UART011_FR_RI,
|
|
|
.get_fifosize = get_fifosize_arm,
|
|
|
};
|
|
|
|
|
@@ -1167,7 +1187,7 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap)
|
|
|
return;
|
|
|
|
|
|
/* Disable RX and TX DMA */
|
|
|
- while (pl011_read(uap, REG_FR) & UART01x_FR_BUSY)
|
|
|
+ while (pl011_read(uap, REG_FR) & uap->vendor->fr_busy)
|
|
|
cpu_relax();
|
|
|
|
|
|
spin_lock_irq(&uap->port.lock);
|
|
@@ -1416,11 +1436,12 @@ static void pl011_modem_status(struct uart_amba_port *uap)
|
|
|
if (delta & UART01x_FR_DCD)
|
|
|
uart_handle_dcd_change(&uap->port, status & UART01x_FR_DCD);
|
|
|
|
|
|
- if (delta & UART01x_FR_DSR)
|
|
|
+ if (delta & uap->vendor->fr_dsr)
|
|
|
uap->port.icount.dsr++;
|
|
|
|
|
|
- if (delta & UART01x_FR_CTS)
|
|
|
- uart_handle_cts_change(&uap->port, status & UART01x_FR_CTS);
|
|
|
+ if (delta & uap->vendor->fr_cts)
|
|
|
+ uart_handle_cts_change(&uap->port,
|
|
|
+ status & uap->vendor->fr_cts);
|
|
|
|
|
|
wake_up_interruptible(&uap->port.state->port.delta_msr_wait);
|
|
|
}
|
|
@@ -1493,7 +1514,8 @@ static unsigned int pl011_tx_empty(struct uart_port *port)
|
|
|
struct uart_amba_port *uap =
|
|
|
container_of(port, struct uart_amba_port, port);
|
|
|
unsigned int status = pl011_read(uap, REG_FR);
|
|
|
- return status & (UART01x_FR_BUSY|UART01x_FR_TXFF) ? 0 : TIOCSER_TEMT;
|
|
|
+ return status & (uap->vendor->fr_busy | UART01x_FR_TXFF) ?
|
|
|
+ 0 : TIOCSER_TEMT;
|
|
|
}
|
|
|
|
|
|
static unsigned int pl011_get_mctrl(struct uart_port *port)
|
|
@@ -1508,9 +1530,9 @@ static unsigned int pl011_get_mctrl(struct uart_port *port)
|
|
|
result |= tiocmbit
|
|
|
|
|
|
TIOCMBIT(UART01x_FR_DCD, TIOCM_CAR);
|
|
|
- TIOCMBIT(UART01x_FR_DSR, TIOCM_DSR);
|
|
|
- TIOCMBIT(UART01x_FR_CTS, TIOCM_CTS);
|
|
|
- TIOCMBIT(UART011_FR_RI, TIOCM_RNG);
|
|
|
+ TIOCMBIT(uap->vendor->fr_dsr, TIOCM_DSR);
|
|
|
+ TIOCMBIT(uap->vendor->fr_cts, TIOCM_CTS);
|
|
|
+ TIOCMBIT(uap->vendor->fr_ri, TIOCM_RNG);
|
|
|
#undef TIOCMBIT
|
|
|
return result;
|
|
|
}
|
|
@@ -2191,7 +2213,7 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
|
|
|
* Finally, wait for transmitter to become empty
|
|
|
* and restore the TCR
|
|
|
*/
|
|
|
- while (pl011_read(uap, REG_FR) & UART01x_FR_BUSY)
|
|
|
+ while (pl011_read(uap, REG_FR) & uap->vendor->fr_busy)
|
|
|
cpu_relax();
|
|
|
if (!uap->vendor->always_enabled)
|
|
|
pl011_write(old_cr, uap, REG_CR);
|
|
@@ -2303,13 +2325,16 @@ static struct console amba_console = {
|
|
|
|
|
|
static void pl011_putc(struct uart_port *port, int c)
|
|
|
{
|
|
|
+ struct uart_amba_port *uap =
|
|
|
+ container_of(port, struct uart_amba_port, port);
|
|
|
+
|
|
|
while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF)
|
|
|
cpu_relax();
|
|
|
if (port->iotype == UPIO_MEM32)
|
|
|
writel(c, port->membase + UART01x_DR);
|
|
|
else
|
|
|
writeb(c, port->membase + UART01x_DR);
|
|
|
- while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY)
|
|
|
+ while (readl(port->membase + UART01x_FR) & uap->vendor->fr_busy)
|
|
|
cpu_relax();
|
|
|
}
|
|
|
|