summaryrefslogtreecommitdiff
path: root/drivers/tty/serial/qcom_geni_serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/qcom_geni_serial.c')
-rw-r--r--drivers/tty/serial/qcom_geni_serial.c319
1 files changed, 177 insertions, 142 deletions
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index f9f7ac1a10df..a80ce7aaf309 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -124,13 +124,14 @@ struct qcom_geni_serial_port {
dma_addr_t tx_dma_addr;
dma_addr_t rx_dma_addr;
bool setup;
- unsigned int baud;
+ unsigned long poll_timeout_us;
unsigned long clk_rate;
void *rx_buf;
u32 loopback;
bool brk;
unsigned int tx_remaining;
+ unsigned int tx_queued;
int wakeup_irq;
bool rx_tx_swap;
bool cts_rts_swap;
@@ -144,6 +145,10 @@ static const struct uart_ops qcom_geni_uart_pops;
static struct uart_driver qcom_geni_console_driver;
static struct uart_driver qcom_geni_uart_driver;
+static void __qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport);
+static void qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport);
+static int qcom_geni_serial_port_setup(struct uart_port *uport);
+
static inline struct qcom_geni_serial_port *to_dev_port(struct uart_port *uport)
{
return container_of(uport, struct qcom_geni_serial_port, uport);
@@ -265,27 +270,18 @@ static bool qcom_geni_serial_secondary_active(struct uart_port *uport)
return readl(uport->membase + SE_GENI_STATUS) & S_GENI_CMD_ACTIVE;
}
-static bool qcom_geni_serial_poll_bit(struct uart_port *uport,
- int offset, int field, bool set)
+static bool qcom_geni_serial_poll_bitfield(struct uart_port *uport,
+ unsigned int offset, u32 field, u32 val)
{
u32 reg;
struct qcom_geni_serial_port *port;
- unsigned int baud;
- unsigned int fifo_bits;
unsigned long timeout_us = 20000;
struct qcom_geni_private_data *private_data = uport->private_data;
if (private_data->drv) {
port = to_dev_port(uport);
- baud = port->baud;
- if (!baud)
- baud = 115200;
- fifo_bits = port->tx_fifo_depth * port->tx_fifo_width;
- /*
- * Total polling iterations based on FIFO worth of bytes to be
- * sent at current baud. Add a little fluff to the wait.
- */
- timeout_us = ((fifo_bits * USEC_PER_SEC) / baud) + 500;
+ if (port->poll_timeout_us)
+ timeout_us = port->poll_timeout_us;
}
/*
@@ -295,7 +291,7 @@ static bool qcom_geni_serial_poll_bit(struct uart_port *uport,
timeout_us = DIV_ROUND_UP(timeout_us, 10) * 10;
while (timeout_us) {
reg = readl(uport->membase + offset);
- if ((bool)(reg & field) == set)
+ if ((reg & field) == val)
return true;
udelay(10);
timeout_us -= 10;
@@ -303,6 +299,12 @@ static bool qcom_geni_serial_poll_bit(struct uart_port *uport,
return false;
}
+static bool qcom_geni_serial_poll_bit(struct uart_port *uport,
+ unsigned int offset, u32 field, bool set)
+{
+ return qcom_geni_serial_poll_bitfield(uport, offset, field, set ? field : 0);
+}
+
static void qcom_geni_serial_setup_tx(struct uart_port *uport, u32 xmit_size)
{
u32 m_cmd;
@@ -315,18 +317,16 @@ static void qcom_geni_serial_setup_tx(struct uart_port *uport, u32 xmit_size)
static void qcom_geni_serial_poll_tx_done(struct uart_port *uport)
{
int done;
- u32 irq_clear = M_CMD_DONE_EN;
done = qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
M_CMD_DONE_EN, true);
if (!done) {
writel(M_GENI_CMD_ABORT, uport->membase +
SE_GENI_M_CMD_CTRL_REG);
- irq_clear |= M_CMD_ABORT_EN;
qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
M_CMD_ABORT_EN, true);
+ writel(M_CMD_ABORT_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
}
- writel(irq_clear, uport->membase + SE_GENI_M_IRQ_CLEAR);
}
static void qcom_geni_serial_abort_rx(struct uart_port *uport)
@@ -386,17 +386,44 @@ static int qcom_geni_serial_get_char(struct uart_port *uport)
static void qcom_geni_serial_poll_put_char(struct uart_port *uport,
unsigned char c)
{
- writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG);
+ if (qcom_geni_serial_main_active(uport)) {
+ qcom_geni_serial_poll_tx_done(uport);
+ __qcom_geni_serial_cancel_tx_cmd(uport);
+ }
+
+ writel(M_CMD_DONE_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
qcom_geni_serial_setup_tx(uport, 1);
- WARN_ON(!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
- M_TX_FIFO_WATERMARK_EN, true));
writel(c, uport->membase + SE_GENI_TX_FIFOn);
- writel(M_TX_FIFO_WATERMARK_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
qcom_geni_serial_poll_tx_done(uport);
}
+
+static int qcom_geni_serial_poll_init(struct uart_port *uport)
+{
+ struct qcom_geni_serial_port *port = to_dev_port(uport);
+ int ret;
+
+ if (!port->setup) {
+ ret = qcom_geni_serial_port_setup(uport);
+ if (ret)
+ return ret;
+ }
+
+ if (!qcom_geni_serial_secondary_active(uport))
+ geni_se_setup_s_cmd(&port->se, UART_START_READ, 0);
+
+ return 0;
+}
#endif
#ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE
+static void qcom_geni_serial_drain_fifo(struct uart_port *uport)
+{
+ struct qcom_geni_serial_port *port = to_dev_port(uport);
+
+ qcom_geni_serial_poll_bitfield(uport, SE_GENI_M_GP_LENGTH, GP_LENGTH,
+ port->tx_queued);
+}
+
static void qcom_geni_serial_wr_char(struct uart_port *uport, unsigned char ch)
{
struct qcom_geni_private_data *private_data = uport->private_data;
@@ -431,6 +458,7 @@ __qcom_geni_serial_console_write(struct uart_port *uport, const char *s,
}
writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG);
+ writel(M_CMD_DONE_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
qcom_geni_serial_setup_tx(uport, bytes_to_send);
for (i = 0; i < count; ) {
size_t chars_to_write = 0;
@@ -469,10 +497,9 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
{
struct uart_port *uport;
struct qcom_geni_serial_port *port;
+ u32 m_irq_en, s_irq_en;
bool locked = true;
unsigned long flags;
- u32 geni_status;
- u32 irq_en;
WARN_ON(co->index < 0 || co->index >= GENI_UART_CONS_PORTS);
@@ -486,40 +513,28 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
else
uart_port_lock_irqsave(uport, &flags);
- geni_status = readl(uport->membase + SE_GENI_STATUS);
-
- if (!locked) {
- /*
- * We can only get here if an oops is in progress then we were
- * unable to get the lock. This means we can't safely access
- * our state variables like tx_remaining. About the best we
- * can do is wait for the FIFO to be empty before we start our
- * transfer, so we'll do that.
- */
- qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
- M_TX_FIFO_NOT_EMPTY_EN, false);
- } else if ((geni_status & M_GENI_CMD_ACTIVE) && !port->tx_remaining) {
- /*
- * It seems we can't interrupt existing transfers if all data
- * has been sent, in which case we need to look for done first.
- */
- qcom_geni_serial_poll_tx_done(uport);
-
- if (!uart_circ_empty(&uport->state->xmit)) {
- irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
- writel(irq_en | M_TX_FIFO_WATERMARK_EN,
- uport->membase + SE_GENI_M_IRQ_EN);
- }
+ m_irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+ s_irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN);
+ writel(0, uport->membase + SE_GENI_M_IRQ_EN);
+ writel(0, uport->membase + SE_GENI_S_IRQ_EN);
+
+ if (qcom_geni_serial_main_active(uport)) {
+ /* Wait for completion or drain FIFO */
+ if (!locked || port->tx_remaining == 0)
+ qcom_geni_serial_poll_tx_done(uport);
+ else
+ qcom_geni_serial_drain_fifo(uport);
+
+ qcom_geni_serial_cancel_tx_cmd(uport);
}
__qcom_geni_serial_console_write(uport, s, count);
+ writel(m_irq_en, uport->membase + SE_GENI_M_IRQ_EN);
+ writel(s_irq_en, uport->membase + SE_GENI_S_IRQ_EN);
- if (locked) {
- if (port->tx_remaining)
- qcom_geni_serial_setup_tx(uport, port->tx_remaining);
+ if (locked)
uart_port_unlock_irqrestore(uport, flags);
- }
}
static void handle_rx_console(struct uart_port *uport, u32 bytes, bool drop)
@@ -565,7 +580,7 @@ static void handle_rx_console(struct uart_port *uport, u32 bytes, bool drop)
}
#endif /* CONFIG_SERIAL_QCOM_GENI_CONSOLE */
-static void handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop)
+static void handle_rx_uart(struct uart_port *uport, u32 bytes)
{
struct qcom_geni_serial_port *port = to_dev_port(uport);
struct tty_port *tport = &uport->state->port;
@@ -573,9 +588,8 @@ static void handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop)
ret = tty_insert_flip_string(tport, port->rx_buf, bytes);
if (ret != bytes) {
- dev_err(uport->dev, "%s:Unable to push data ret %d_bytes %d\n",
- __func__, ret, bytes);
- WARN_ON_ONCE(1);
+ dev_err_ratelimited(uport->dev, "failed to push data (%d < %u)\n",
+ ret, bytes);
}
uport->icount.rx += ret;
tty_flip_buffer_push(tport);
@@ -620,22 +634,24 @@ static void qcom_geni_serial_stop_tx_dma(struct uart_port *uport)
static void qcom_geni_serial_start_tx_dma(struct uart_port *uport)
{
struct qcom_geni_serial_port *port = to_dev_port(uport);
- struct circ_buf *xmit = &uport->state->xmit;
+ struct tty_port *tport = &uport->state->port;
unsigned int xmit_size;
+ u8 *tail;
int ret;
if (port->tx_dma_addr)
return;
- if (uart_circ_empty(xmit))
+ if (kfifo_is_empty(&tport->xmit_fifo))
return;
- xmit_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
+ xmit_size = kfifo_out_linear_ptr(&tport->xmit_fifo, &tail,
+ UART_XMIT_SIZE);
qcom_geni_serial_setup_tx(uport, xmit_size);
- ret = geni_se_tx_dma_prep(&port->se, &xmit->buf[xmit->tail],
- xmit_size, &port->tx_dma_addr);
+ ret = geni_se_tx_dma_prep(&port->se, tail, xmit_size,
+ &port->tx_dma_addr);
if (ret) {
dev_err(uport->dev, "unable to start TX SE DMA: %d\n", ret);
qcom_geni_serial_stop_tx_dma(uport);
@@ -647,15 +663,25 @@ static void qcom_geni_serial_start_tx_dma(struct uart_port *uport)
static void qcom_geni_serial_start_tx_fifo(struct uart_port *uport)
{
+ unsigned char c;
u32 irq_en;
- if (qcom_geni_serial_main_active(uport) ||
- !qcom_geni_serial_tx_empty(uport))
- return;
+ /*
+ * Start a new transfer in case the previous command was cancelled and
+ * left data in the FIFO which may prevent the watermark interrupt
+ * from triggering. Note that the stale data is discarded.
+ */
+ if (!qcom_geni_serial_main_active(uport) &&
+ !qcom_geni_serial_tx_empty(uport)) {
+ if (uart_fifo_out(uport, &c, 1) == 1) {
+ writel(M_CMD_DONE_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
+ qcom_geni_serial_setup_tx(uport, 1);
+ writel(c, uport->membase + SE_GENI_TX_FIFOn);
+ }
+ }
irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
irq_en |= M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN;
-
writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG);
writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
}
@@ -663,15 +689,16 @@ static void qcom_geni_serial_start_tx_fifo(struct uart_port *uport)
static void qcom_geni_serial_stop_tx_fifo(struct uart_port *uport)
{
u32 irq_en;
- struct qcom_geni_serial_port *port = to_dev_port(uport);
irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
irq_en &= ~(M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN);
writel(0, uport->membase + SE_GENI_TX_WATERMARK_REG);
writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
- /* Possible stop tx is called multiple times. */
- if (!qcom_geni_serial_main_active(uport))
- return;
+}
+
+static void __qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport)
+{
+ struct qcom_geni_serial_port *port = to_dev_port(uport);
geni_se_cancel_m_cmd(&port->se);
if (!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
@@ -684,6 +711,19 @@ static void qcom_geni_serial_stop_tx_fifo(struct uart_port *uport)
writel(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
}
+static void qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport)
+{
+ struct qcom_geni_serial_port *port = to_dev_port(uport);
+
+ if (!qcom_geni_serial_main_active(uport))
+ return;
+
+ __qcom_geni_serial_cancel_tx_cmd(uport);
+
+ port->tx_remaining = 0;
+ port->tx_queued = 0;
+}
+
static void qcom_geni_serial_handle_rx_fifo(struct uart_port *uport, bool drop)
{
u32 status;
@@ -764,17 +804,27 @@ static void qcom_geni_serial_start_rx_fifo(struct uart_port *uport)
static void qcom_geni_serial_stop_rx_dma(struct uart_port *uport)
{
struct qcom_geni_serial_port *port = to_dev_port(uport);
+ bool done;
if (!qcom_geni_serial_secondary_active(uport))
return;
geni_se_cancel_s_cmd(&port->se);
- qcom_geni_serial_poll_bit(uport, SE_GENI_S_IRQ_STATUS,
- S_CMD_CANCEL_EN, true);
-
- if (qcom_geni_serial_secondary_active(uport))
+ done = qcom_geni_serial_poll_bit(uport, SE_DMA_RX_IRQ_STAT,
+ RX_EOT, true);
+ if (done) {
+ writel(RX_EOT | RX_DMA_DONE,
+ uport->membase + SE_DMA_RX_IRQ_CLR);
+ } else {
qcom_geni_serial_abort_rx(uport);
+ writel(1, uport->membase + SE_DMA_RX_FSM_RST);
+ qcom_geni_serial_poll_bit(uport, SE_DMA_RX_IRQ_STAT,
+ RX_RESET_DONE, true);
+ writel(RX_RESET_DONE | RX_DMA_DONE,
+ uport->membase + SE_DMA_RX_IRQ_CLR);
+ }
+
if (port->rx_dma_addr) {
geni_se_rx_dma_unprep(&port->se, port->rx_dma_addr,
DMA_RX_BUF_SIZE);
@@ -823,7 +873,7 @@ static void qcom_geni_serial_handle_rx_dma(struct uart_port *uport, bool drop)
}
if (!drop)
- handle_rx_uart(uport, rx_in, drop);
+ handle_rx_uart(uport, rx_in);
ret = geni_se_rx_dma_prep(&port->se, port->rx_buf,
DMA_RX_BUF_SIZE,
@@ -853,18 +903,14 @@ static void qcom_geni_serial_send_chunk_fifo(struct uart_port *uport,
unsigned int chunk)
{
struct qcom_geni_serial_port *port = to_dev_port(uport);
- struct circ_buf *xmit = &uport->state->xmit;
- unsigned int tx_bytes, c, remaining = chunk;
+ unsigned int tx_bytes, remaining = chunk;
u8 buf[BYTES_PER_FIFO_WORD];
while (remaining) {
memset(buf, 0, sizeof(buf));
tx_bytes = min(remaining, BYTES_PER_FIFO_WORD);
- for (c = 0; c < tx_bytes ; c++) {
- buf[c] = xmit->buf[xmit->tail];
- uart_xmit_advance(uport, 1);
- }
+ uart_fifo_out(uport, buf, tx_bytes);
iowrite32_rep(uport->membase + SE_GENI_TX_FIFOn, buf, 1);
@@ -877,7 +923,7 @@ static void qcom_geni_serial_handle_tx_fifo(struct uart_port *uport,
bool done, bool active)
{
struct qcom_geni_serial_port *port = to_dev_port(uport);
- struct circ_buf *xmit = &uport->state->xmit;
+ struct tty_port *tport = &uport->state->port;
size_t avail;
size_t pending;
u32 status;
@@ -890,24 +936,29 @@ static void qcom_geni_serial_handle_tx_fifo(struct uart_port *uport,
if (active)
pending = port->tx_remaining;
else
- pending = uart_circ_chars_pending(xmit);
+ pending = kfifo_len(&tport->xmit_fifo);
- /* All data has been transmitted and acknowledged as received */
- if (!pending && !status && done) {
+ /* All data has been transmitted or command has been cancelled */
+ if (!pending && done) {
qcom_geni_serial_stop_tx_fifo(uport);
goto out_write_wakeup;
}
- avail = port->tx_fifo_depth - (status & TX_FIFO_WC);
+ if (active)
+ avail = port->tx_fifo_depth - (status & TX_FIFO_WC);
+ else
+ avail = port->tx_fifo_depth;
+
avail *= BYTES_PER_FIFO_WORD;
chunk = min(avail, pending);
if (!chunk)
goto out_write_wakeup;
- if (!port->tx_remaining) {
+ if (!active) {
qcom_geni_serial_setup_tx(uport, pending);
port->tx_remaining = pending;
+ port->tx_queued = 0;
irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
if (!(irq_en & M_TX_FIFO_WATERMARK_EN))
@@ -916,6 +967,7 @@ static void qcom_geni_serial_handle_tx_fifo(struct uart_port *uport,
}
qcom_geni_serial_send_chunk_fifo(uport, chunk);
+ port->tx_queued += chunk;
/*
* The tx fifo watermark is level triggered and latched. Though we had
@@ -933,24 +985,24 @@ out_write_wakeup:
uport->membase + SE_GENI_M_IRQ_EN);
}
- if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
uart_write_wakeup(uport);
}
static void qcom_geni_serial_handle_tx_dma(struct uart_port *uport)
{
struct qcom_geni_serial_port *port = to_dev_port(uport);
- struct circ_buf *xmit = &uport->state->xmit;
+ struct tty_port *tport = &uport->state->port;
uart_xmit_advance(uport, port->tx_remaining);
geni_se_tx_dma_unprep(&port->se, port->tx_dma_addr, port->tx_remaining);
port->tx_dma_addr = 0;
port->tx_remaining = 0;
- if (!uart_circ_empty(xmit))
+ if (!kfifo_is_empty(&tport->xmit_fifo))
qcom_geni_serial_start_tx_dma(uport);
- if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
uart_write_wakeup(uport);
}
@@ -1071,11 +1123,17 @@ static void qcom_geni_serial_shutdown(struct uart_port *uport)
{
disable_irq(uport->irq);
- if (uart_console(uport))
- return;
-
+ uart_port_lock_irq(uport);
qcom_geni_serial_stop_tx(uport);
qcom_geni_serial_stop_rx(uport);
+
+ qcom_geni_serial_cancel_tx_cmd(uport);
+ uart_port_unlock_irq(uport);
+}
+
+static void qcom_geni_serial_flush_buffer(struct uart_port *uport)
+{
+ qcom_geni_serial_cancel_tx_cmd(uport);
}
static int qcom_geni_serial_port_setup(struct uart_port *uport)
@@ -1123,7 +1181,6 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
false, true, true);
geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2);
geni_se_select_mode(&port->se, port->dev_data->mode);
- qcom_geni_serial_start_rx(uport);
port->setup = true;
return 0;
@@ -1139,6 +1196,11 @@ static int qcom_geni_serial_startup(struct uart_port *uport)
if (ret)
return ret;
}
+
+ uart_port_lock_irq(uport);
+ qcom_geni_serial_start_rx(uport);
+ uart_port_unlock_irq(uport);
+
enable_irq(uport->irq);
return 0;
@@ -1222,11 +1284,10 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
unsigned long clk_rate;
u32 ver, sampling_rate;
unsigned int avg_bw_core;
+ unsigned long timeout;
- qcom_geni_serial_stop_rx(uport);
/* baud rate */
baud = uart_get_baud_rate(uport, termios, old, 300, 4000000);
- port->baud = baud;
sampling_rate = UART_OVERSAMPLING;
/* Sampling rate is halved for IP versions >= 2.5 */
@@ -1240,7 +1301,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
dev_err(port->se.dev,
"Couldn't find suitable clock rate for %u\n",
baud * sampling_rate);
- goto out_restart_rx;
+ return;
}
dev_dbg(port->se.dev, "desired_rate = %u, clk_rate = %lu, clk_div = %u\n",
@@ -1304,9 +1365,21 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
else
tx_trans_cfg |= UART_CTS_MASK;
- if (baud)
+ if (baud) {
uart_update_timeout(uport, termios->c_cflag, baud);
+ /*
+ * Make sure that qcom_geni_serial_poll_bitfield() waits for
+ * the FIFO, two-word intermediate transfer register and shift
+ * register to clear.
+ *
+ * Note that uart_fifo_timeout() also adds a 20 ms margin.
+ */
+ timeout = jiffies_to_usecs(uart_fifo_timeout(uport));
+ timeout += 3 * timeout / port->tx_fifo_depth;
+ WRITE_ONCE(port->poll_timeout_us, timeout);
+ }
+
if (!uart_console(uport))
writel(port->loopback,
uport->membase + SE_UART_LOOPBACK_CFG);
@@ -1319,8 +1392,6 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN);
writel(ser_clk_cfg, uport->membase + GENI_SER_M_CLK_CFG);
writel(ser_clk_cfg, uport->membase + GENI_SER_S_CLK_CFG);
-out_restart_rx:
- qcom_geni_serial_start_rx(uport);
}
#ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE
@@ -1534,13 +1605,14 @@ static const struct uart_ops qcom_geni_console_pops = {
.request_port = qcom_geni_serial_request_port,
.config_port = qcom_geni_serial_config_port,
.shutdown = qcom_geni_serial_shutdown,
+ .flush_buffer = qcom_geni_serial_flush_buffer,
.type = qcom_geni_serial_get_type,
.set_mctrl = qcom_geni_serial_set_mctrl,
.get_mctrl = qcom_geni_serial_get_mctrl,
#ifdef CONFIG_CONSOLE_POLL
.poll_get_char = qcom_geni_serial_get_char,
.poll_put_char = qcom_geni_serial_poll_put_char,
- .poll_init = qcom_geni_serial_port_setup,
+ .poll_init = qcom_geni_serial_poll_init,
#endif
.pm = qcom_geni_serial_pm,
};
@@ -1707,7 +1779,7 @@ static void qcom_geni_serial_remove(struct platform_device *pdev)
uart_remove_one_port(drv, &port->uport);
}
-static int qcom_geni_serial_sys_suspend(struct device *dev)
+static int qcom_geni_serial_suspend(struct device *dev)
{
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
struct uart_port *uport = &port->uport;
@@ -1724,7 +1796,7 @@ static int qcom_geni_serial_sys_suspend(struct device *dev)
return uart_suspend_port(private_data->drv, uport);
}
-static int qcom_geni_serial_sys_resume(struct device *dev)
+static int qcom_geni_serial_resume(struct device *dev)
{
int ret;
struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
@@ -1739,38 +1811,6 @@ static int qcom_geni_serial_sys_resume(struct device *dev)
return ret;
}
-static int qcom_geni_serial_sys_hib_resume(struct device *dev)
-{
- int ret = 0;
- struct uart_port *uport;
- struct qcom_geni_private_data *private_data;
- struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
-
- uport = &port->uport;
- private_data = uport->private_data;
-
- if (uart_console(uport)) {
- geni_icc_set_tag(&port->se, QCOM_ICC_TAG_ALWAYS);
- geni_icc_set_bw(&port->se);
- ret = uart_resume_port(private_data->drv, uport);
- /*
- * For hibernation usecase clients for
- * console UART won't call port setup during restore,
- * hence call port setup for console uart.
- */
- qcom_geni_serial_port_setup(uport);
- } else {
- /*
- * Peripheral register settings are lost during hibernation.
- * Update setup flag such that port setup happens again
- * during next session. Clients of HS-UART will close and
- * open the port during hibernation.
- */
- port->setup = false;
- }
- return ret;
-}
-
static const struct qcom_geni_device_data qcom_geni_console_data = {
.console = true,
.mode = GENI_SE_FIFO,
@@ -1782,12 +1822,7 @@ static const struct qcom_geni_device_data qcom_geni_uart_data = {
};
static const struct dev_pm_ops qcom_geni_serial_pm_ops = {
- .suspend = pm_sleep_ptr(qcom_geni_serial_sys_suspend),
- .resume = pm_sleep_ptr(qcom_geni_serial_sys_resume),
- .freeze = pm_sleep_ptr(qcom_geni_serial_sys_suspend),
- .poweroff = pm_sleep_ptr(qcom_geni_serial_sys_suspend),
- .restore = pm_sleep_ptr(qcom_geni_serial_sys_hib_resume),
- .thaw = pm_sleep_ptr(qcom_geni_serial_sys_hib_resume),
+ SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_suspend, qcom_geni_serial_resume)
};
static const struct of_device_id qcom_geni_serial_match_table[] = {
@@ -1804,7 +1839,7 @@ static const struct of_device_id qcom_geni_serial_match_table[] = {
MODULE_DEVICE_TABLE(of, qcom_geni_serial_match_table);
static struct platform_driver qcom_geni_serial_platform_driver = {
- .remove_new = qcom_geni_serial_remove,
+ .remove = qcom_geni_serial_remove,
.probe = qcom_geni_serial_probe,
.driver = {
.name = "qcom_geni_serial",