Newer
Older
// SPDX-License-Identifier: GPL-2.0
/*
* 8250-core based driver for the OMAP internal UART
*
* based on omap-serial.c, Copyright (C) 2010 Texas Instruments.
*
* Copyright (C) 2014 Sebastian Andrzej Siewior
*
*/
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/serial_8250.h>
#include <linux/serial_reg.h>
#include <linux/tty_flip.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/delay.h>
#include <linux/pm_runtime.h>
#include <linux/console.h>
#include <linux/pm_qos.h>
#include <linux/pm_wakeirq.h>
#include <linux/dma-mapping.h>
#include <linux/sys_soc.h>
#include "8250.h"
#define DEFAULT_CLK_SPEED 48000000
#define UART_ERRATA_i202_MDR1_ACCESS (1 << 0)
#define OMAP_UART_WER_HAS_TX_WAKEUP (1 << 1)
#define OMAP_DMA_TX_KICK (1 << 2)
/*
* See Advisory 21 in AM437x errata SPRZ408B, updated April 2015.
* The same errata is applicable to AM335x and DRA7x processors too.
*/
#define UART_ERRATA_CLOCK_DISABLE (1 << 3)
#define UART_HAS_EFR2 BIT(4)
#define UART_HAS_RHR_IT_DIS BIT(5)
#define UART_RX_TIMEOUT_QUIRK BIT(6)
#define OMAP_UART_FCR_RX_TRIG 6
#define OMAP_UART_FCR_TX_TRIG 4
/* SCR register bitmasks */
#define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7)
#define OMAP_UART_SCR_TX_TRIG_GRANU1_MASK (1 << 6)
#define OMAP_UART_SCR_TX_EMPTY (1 << 3)
#define OMAP_UART_SCR_DMAMODE_MASK (3 << 1)
#define OMAP_UART_SCR_DMAMODE_1 (1 << 1)
#define OMAP_UART_SCR_DMAMODE_CTL (1 << 0)
/* MVR register bitmasks */
#define OMAP_UART_MVR_SCHEME_SHIFT 30
#define OMAP_UART_LEGACY_MVR_MAJ_MASK 0xf0
#define OMAP_UART_LEGACY_MVR_MAJ_SHIFT 4
#define OMAP_UART_LEGACY_MVR_MIN_MASK 0x0f
#define OMAP_UART_MVR_MAJ_MASK 0x700
#define OMAP_UART_MVR_MAJ_SHIFT 8
#define OMAP_UART_MVR_MIN_MASK 0x3f
/* SYSC register bitmasks */
#define OMAP_UART_SYSC_SOFTRESET (1 << 1)
/* SYSS register bitmasks */
#define OMAP_UART_SYSS_RESETDONE (1 << 0)
#define UART_TI752_TLR_TX 0
#define UART_TI752_TLR_RX 4
#define TRIGGER_TLR_MASK(x) ((x & 0x3c) >> 2)
#define TRIGGER_FCR_MASK(x) (x & 3)
/* Enable XON/XOFF flow control on output */
#define OMAP_UART_SW_TX 0x08
/* Enable XON/XOFF flow control on input */
#define OMAP_UART_SW_RX 0x02
#define OMAP_UART_WER_MOD_WKUP 0x7f
#define OMAP_UART_TX_WAKEUP_EN (1 << 7)
#define TX_TRIGGER 1
#define RX_TRIGGER 48
#define OMAP_UART_TCR_RESTORE(x) ((x / 4) << 4)
#define OMAP_UART_TCR_HALT(x) ((x / 4) << 0)
#define UART_BUILD_REVISION(x, y) (((x) << 8) | (y))
#define OMAP_UART_REV_46 0x0406
#define OMAP_UART_REV_52 0x0502
#define OMAP_UART_REV_63 0x0603
/* Interrupt Enable Register 2 */
#define UART_OMAP_IER2 0x1B
#define UART_OMAP_IER2_RHR_IT_DIS BIT(2)
/* Enhanced features register 2 */
#define UART_OMAP_EFR2 0x23
#define UART_OMAP_EFR2_TIMEOUT_BEHAVE BIT(6)
/* RX FIFO occupancy indicator */
#define UART_OMAP_RX_LVL 0x19
struct omap8250_priv {
int line;
u8 habit;
u8 mdr1;
u8 efr;
u8 scr;
u8 wer;
u8 xon;
u8 xoff;
u8 delayed_restore;
u8 tx_trigger;
u8 rx_trigger;
bool is_suspending;
int wakeirq;
int wakeups_enabled;
u32 latency;
u32 calc_latency;
struct pm_qos_request pm_qos_request;
struct work_struct qos_work;
struct uart_8250_dma omap8250_dma;
Sebastian Andrzej Siewior
committed
bool rx_dma_broken;
struct omap8250_dma_params {
u32 rx_size;
u8 rx_trigger;
u8 tx_trigger;
};
struct omap8250_platdata {
struct omap8250_dma_params *dma_params;
u8 habit;
};
#ifdef CONFIG_SERIAL_8250_DMA
static void omap_8250_rx_dma_flush(struct uart_8250_port *p);
#else
static inline void omap_8250_rx_dma_flush(struct uart_8250_port *p) { }
#endif
static u32 uart_read(struct uart_8250_port *up, u32 reg)
{
return readl(up->port.membase + (reg << up->port.regshift));
}
static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
struct uart_8250_port *up = up_to_u8250p(port);
struct omap8250_priv *priv = up->port.private_data;
u8 lcr;
serial8250_do_set_mctrl(port, mctrl);
if (!mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_RTS)) {
/*
* Turn off autoRTS if RTS is lowered and restore autoRTS
* setting if RTS is raised
*/
lcr = serial_in(up, UART_LCR);
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS))
priv->efr |= UART_EFR_RTS;
else
priv->efr &= ~UART_EFR_RTS;
serial_out(up, UART_EFR, priv->efr);
serial_out(up, UART_LCR, lcr);
}
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
/*
* Work Around for Errata i202 (2430, 3430, 3630, 4430 and 4460)
* The access to uart register after MDR1 Access
* causes UART to corrupt data.
*
* Need a delay =
* 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS)
* give 10 times as much
*/
static void omap_8250_mdr1_errataset(struct uart_8250_port *up,
struct omap8250_priv *priv)
{
u8 timeout = 255;
serial_out(up, UART_OMAP_MDR1, priv->mdr1);
udelay(2);
serial_out(up, UART_FCR, up->fcr | UART_FCR_CLEAR_XMIT |
UART_FCR_CLEAR_RCVR);
/*
* Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and
* TX_FIFO_E bit is 1.
*/
while (UART_LSR_THRE != (serial_in(up, UART_LSR) &
(UART_LSR_THRE | UART_LSR_DR))) {
timeout--;
if (!timeout) {
/* Should *never* happen. we warn and carry on */
dev_crit(up->port.dev, "Errata i202: timedout %x\n",
serial_in(up, UART_LSR));
break;
}
udelay(1);
}
}
static void omap_8250_get_divisor(struct uart_port *port, unsigned int baud,
struct omap8250_priv *priv)
{
unsigned int uartclk = port->uartclk;
unsigned int div_13, div_16;
unsigned int abs_d13, abs_d16;
/*
* Old custom speed handling.
*/
if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) {
priv->quot = port->custom_divisor & UART_DIV_MAX;
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
/*
* I assume that nobody is using this. But hey, if somebody
* would like to specify the divisor _and_ the mode then the
* driver is ready and waiting for it.
*/
if (port->custom_divisor & (1 << 16))
priv->mdr1 = UART_OMAP_MDR1_13X_MODE;
else
priv->mdr1 = UART_OMAP_MDR1_16X_MODE;
return;
}
div_13 = DIV_ROUND_CLOSEST(uartclk, 13 * baud);
div_16 = DIV_ROUND_CLOSEST(uartclk, 16 * baud);
if (!div_13)
div_13 = 1;
if (!div_16)
div_16 = 1;
abs_d13 = abs(baud - uartclk / 13 / div_13);
abs_d16 = abs(baud - uartclk / 16 / div_16);
if (abs_d13 >= abs_d16) {
priv->mdr1 = UART_OMAP_MDR1_16X_MODE;
priv->quot = div_16;
} else {
priv->mdr1 = UART_OMAP_MDR1_13X_MODE;
priv->quot = div_13;
}
}
static void omap8250_update_scr(struct uart_8250_port *up,
struct omap8250_priv *priv)
{
u8 old_scr;
old_scr = serial_in(up, UART_OMAP_SCR);
if (old_scr == priv->scr)
return;
/*
* The manual recommends not to enable the DMA mode selector in the SCR
* (instead of the FCR) register _and_ selecting the DMA mode as one
* register write because this may lead to malfunction.
*/
if (priv->scr & OMAP_UART_SCR_DMAMODE_MASK)
serial_out(up, UART_OMAP_SCR,
priv->scr & ~OMAP_UART_SCR_DMAMODE_MASK);
serial_out(up, UART_OMAP_SCR, priv->scr);
}
static void omap8250_update_mdr1(struct uart_8250_port *up,
struct omap8250_priv *priv)
{
if (priv->habit & UART_ERRATA_i202_MDR1_ACCESS)
omap_8250_mdr1_errataset(up, priv);
else
serial_out(up, UART_OMAP_MDR1, priv->mdr1);
}
static void omap8250_restore_regs(struct uart_8250_port *up)
{
struct omap8250_priv *priv = up->port.private_data;
struct uart_8250_dma *dma = up->dma;
if (dma && dma->tx_running) {
/*
* TCSANOW requests the change to occur immediately however if
* we have a TX-DMA operation in progress then it has been
* observed that it might stall and never complete. Therefore we
* delay DMA completes to prevent this hang from happen.
*/
priv->delayed_restore = 1;
return;
}
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_out(up, UART_EFR, UART_EFR_ECB);
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
serial8250_out_MCR(up, UART_MCR_TCRTLR);
serial_out(up, UART_FCR, up->fcr);
omap8250_update_scr(up, priv);
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_RESTORE(16) |
OMAP_UART_TCR_HALT(52));
serial_out(up, UART_TI752_TLR,
TRIGGER_TLR_MASK(priv->tx_trigger) << UART_TI752_TLR_TX |
TRIGGER_TLR_MASK(priv->rx_trigger) << UART_TI752_TLR_RX);
serial_out(up, UART_LCR, 0);
/* drop TCR + TLR access, we setup XON/XOFF later */
serial8250_out_MCR(up, up->mcr);
serial_out(up, UART_IER, up->ier);
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_dl_write(up, priv->quot);
serial_out(up, UART_EFR, priv->efr);
/* Configure flow control */
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_out(up, UART_XON1, priv->xon);
serial_out(up, UART_XOFF1, priv->xoff);
serial_out(up, UART_LCR, up->lcr);
omap8250_update_mdr1(up, priv);
up->port.ops->set_mctrl(&up->port, up->port.mctrl);
}
/*
* OMAP can use "CLK / (16 or 13) / div" for baud rate. And then we have have
* some differences in how we want to handle flow control.
*/
static void omap_8250_set_termios(struct uart_port *port,
struct ktermios *termios,
struct ktermios *old)
{
struct uart_8250_port *up = up_to_u8250p(port);
struct omap8250_priv *priv = up->port.private_data;
unsigned char cval = 0;
unsigned int baud;
cval = UART_LCR_WLEN(tty_get_char_size(termios->c_cflag));
if (termios->c_cflag & CSTOPB)
cval |= UART_LCR_STOP;
if (termios->c_cflag & PARENB)
cval |= UART_LCR_PARITY;
if (!(termios->c_cflag & PARODD))
cval |= UART_LCR_EPAR;
if (termios->c_cflag & CMSPAR)
cval |= UART_LCR_SPAR;
/*
* Ask the core to calculate the divisor for us.
*/
baud = uart_get_baud_rate(port, termios, old,
port->uartclk / 16 / UART_DIV_MAX,
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
port->uartclk / 13);
omap_8250_get_divisor(port, baud, priv);
/*
* Ok, we're now changing the port state. Do it with
* interrupts disabled.
*/
pm_runtime_get_sync(port->dev);
spin_lock_irq(&port->lock);
/*
* Update the per-port timeout.
*/
uart_update_timeout(port, termios->c_cflag, baud);
up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
if (termios->c_iflag & INPCK)
up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
if (termios->c_iflag & (IGNBRK | PARMRK))
up->port.read_status_mask |= UART_LSR_BI;
/*
* Characters to ignore
*/
up->port.ignore_status_mask = 0;
if (termios->c_iflag & IGNPAR)
up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
if (termios->c_iflag & IGNBRK) {
up->port.ignore_status_mask |= UART_LSR_BI;
/*
* If we're ignoring parity and break indicators,
* ignore overruns too (for real raw support).
*/
if (termios->c_iflag & IGNPAR)
up->port.ignore_status_mask |= UART_LSR_OE;
}
/*
* ignore all characters if CREAD is not set
*/
if ((termios->c_cflag & CREAD) == 0)
up->port.ignore_status_mask |= UART_LSR_DR;
/*
* Modem status interrupts
*/
up->ier &= ~UART_IER_MSI;
if (UART_ENABLE_MS(&up->port, termios->c_cflag))
up->ier |= UART_IER_MSI;
up->lcr = cval;
/* Up to here it was mostly serial8250_do_set_termios() */
/*
* We enable TRIG_GRANU for RX and TX and additionally we set
* SCR_TX_EMPTY bit. The result is the following:
* - RX_TRIGGER amount of bytes in the FIFO will cause an interrupt.
* - less than RX_TRIGGER number of bytes will also cause an interrupt
* once the UART decides that there no new bytes arriving.
* - Once THRE is enabled, the interrupt will be fired once the FIFO is
* empty - the trigger level is ignored here.
*
* Once DMA is enabled:
* - UART will assert the TX DMA line once there is room for TX_TRIGGER
* bytes in the TX FIFO. On each assert the DMA engine will move
* TX_TRIGGER bytes into the FIFO.
* - UART will assert the RX DMA line once there are RX_TRIGGER bytes in
* the FIFO and move RX_TRIGGER bytes.
* This is because threshold and trigger values are the same.
*/
up->fcr = UART_FCR_ENABLE_FIFO;
up->fcr |= TRIGGER_FCR_MASK(priv->tx_trigger) << OMAP_UART_FCR_TX_TRIG;
up->fcr |= TRIGGER_FCR_MASK(priv->rx_trigger) << OMAP_UART_FCR_RX_TRIG;
priv->scr = OMAP_UART_SCR_RX_TRIG_GRANU1_MASK | OMAP_UART_SCR_TX_EMPTY |
OMAP_UART_SCR_TX_TRIG_GRANU1_MASK;
if (up->dma)
priv->scr |= OMAP_UART_SCR_DMAMODE_1 |
OMAP_UART_SCR_DMAMODE_CTL;
priv->xon = termios->c_cc[VSTART];
priv->xoff = termios->c_cc[VSTOP];
priv->efr = 0;
up->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS | UPSTAT_AUTOXOFF);
if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW &&
!mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_RTS) &&
!mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_CTS)) {
/* Enable AUTOCTS (autoRTS is enabled when RTS is raised) */
up->port.status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS;
priv->efr |= UART_EFR_CTS;
} else if (up->port.flags & UPF_SOFT_FLOW) {
/*
* OMAP rx s/w flow control is borked; the transmitter remains
* stuck off even if rx flow control is subsequently disabled
*/
/*
* IXOFF Flag:
* Enable XON/XOFF flow control on output.
* Transmit XON1, XOFF1
*/
if (termios->c_iflag & IXOFF) {
up->port.status |= UPSTAT_AUTOXOFF;
priv->efr |= OMAP_UART_SW_TX;
}
omap8250_restore_regs(up);
spin_unlock_irq(&up->port.lock);
pm_runtime_mark_last_busy(port->dev);
pm_runtime_put_autosuspend(port->dev);
/* calculate wakeup latency constraint */
priv->calc_latency = USEC_PER_SEC * 64 * 8 / baud;
priv->latency = priv->calc_latency;
schedule_work(&priv->qos_work);
/* Don't rewrite B0 */
if (tty_termios_baud_rate(termios))
tty_termios_encode_baud_rate(termios, baud, baud);
}
/* same as 8250 except that we may have extra flow bits set in EFR */
static void omap_8250_pm(struct uart_port *port, unsigned int state,
unsigned int oldstate)
{
struct uart_8250_port *up = up_to_u8250p(port);
u8 efr;
pm_runtime_get_sync(port->dev);
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
efr = serial_in(up, UART_EFR);
serial_out(up, UART_EFR, efr | UART_EFR_ECB);
serial_out(up, UART_LCR, 0);
serial_out(up, UART_IER, (state != 0) ? UART_IERX_SLEEP : 0);
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
serial_out(up, UART_EFR, efr);
serial_out(up, UART_LCR, 0);
pm_runtime_mark_last_busy(port->dev);
pm_runtime_put_autosuspend(port->dev);
}
static void omap_serial_fill_features_erratas(struct uart_8250_port *up,
struct omap8250_priv *priv)
{
static const struct soc_device_attribute k3_soc_devices[] = {
{ .family = "AM65X", },
{ .family = "J721E", .revision = "SR1.0" },
{ /* sentinel */ }
};
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
u32 mvr, scheme;
u16 revision, major, minor;
mvr = uart_read(up, UART_OMAP_MVER);
/* Check revision register scheme */
scheme = mvr >> OMAP_UART_MVR_SCHEME_SHIFT;
switch (scheme) {
case 0: /* Legacy Scheme: OMAP2/3 */
/* MINOR_REV[0:4], MAJOR_REV[4:7] */
major = (mvr & OMAP_UART_LEGACY_MVR_MAJ_MASK) >>
OMAP_UART_LEGACY_MVR_MAJ_SHIFT;
minor = (mvr & OMAP_UART_LEGACY_MVR_MIN_MASK);
break;
case 1:
/* New Scheme: OMAP4+ */
/* MINOR_REV[0:5], MAJOR_REV[8:10] */
major = (mvr & OMAP_UART_MVR_MAJ_MASK) >>
OMAP_UART_MVR_MAJ_SHIFT;
minor = (mvr & OMAP_UART_MVR_MIN_MASK);
break;
default:
dev_warn(up->port.dev,
"Unknown revision, defaulting to highest\n");
/* highest possible revision */
major = 0xff;
minor = 0xff;
}
/* normalize revision for the driver */
revision = UART_BUILD_REVISION(major, minor);
switch (revision) {
case OMAP_UART_REV_46:
priv->habit |= UART_ERRATA_i202_MDR1_ACCESS;
break;
case OMAP_UART_REV_52:
priv->habit |= UART_ERRATA_i202_MDR1_ACCESS |
OMAP_UART_WER_HAS_TX_WAKEUP;
break;
case OMAP_UART_REV_63:
priv->habit |= UART_ERRATA_i202_MDR1_ACCESS |
OMAP_UART_WER_HAS_TX_WAKEUP;
break;
default:
break;
}
/*
* AM65x SR1.0, AM65x SR2.0 and J721e SR1.0 don't
* don't have RHR_IT_DIS bit in IER2 register. So drop to flag
* to enable errata workaround.
*/
if (soc_device_match(k3_soc_devices))
priv->habit &= ~UART_HAS_RHR_IT_DIS;
}
static void omap8250_uart_qos_work(struct work_struct *work)
{
struct omap8250_priv *priv;
priv = container_of(work, struct omap8250_priv, qos_work);
cpu_latency_qos_update_request(&priv->pm_qos_request, priv->latency);
Sebastian Andrzej Siewior
committed
#ifdef CONFIG_SERIAL_8250_DMA
static int omap_8250_dma_handle_irq(struct uart_port *port);
#endif
static irqreturn_t omap8250_irq(int irq, void *dev_id)
{
struct uart_port *port = dev_id;
struct omap8250_priv *priv = port->private_data;
Sebastian Andrzej Siewior
committed
struct uart_8250_port *up = up_to_u8250p(port);
unsigned int iir, lsr;
Sebastian Andrzej Siewior
committed
int ret;
#ifdef CONFIG_SERIAL_8250_DMA
if (up->dma) {
ret = omap_8250_dma_handle_irq(port);
return IRQ_RETVAL(ret);
}
#endif
serial8250_rpm_get(up);
lsr = serial_port_in(port, UART_LSR);
Sebastian Andrzej Siewior
committed
iir = serial_port_in(port, UART_IIR);
ret = serial8250_handle_irq(port, iir);
/*
* On K3 SoCs, it is observed that RX TIMEOUT is signalled after
* FIFO has been drained, in which case a dummy read of RX FIFO
* is required to clear RX TIMEOUT condition.
*/
if (priv->habit & UART_RX_TIMEOUT_QUIRK &&
(iir & UART_IIR_RX_TIMEOUT) == UART_IIR_RX_TIMEOUT &&
serial_port_in(port, UART_OMAP_RX_LVL) == 0) {
serial_port_in(port, UART_RX);
}
/* Stop processing interrupts on input overrun */
if ((lsr & UART_LSR_OE) && up->overrun_backoff_time_ms > 0) {
unsigned long delay;
up->ier = port->serial_in(port, UART_IER);
if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) {
port->ops->stop_rx(port);
} else {
/* Keep restarting the timer until
* the input overrun subsides.
*/
cancel_delayed_work(&up->overrun_backoff);
}
delay = msecs_to_jiffies(up->overrun_backoff_time_ms);
schedule_delayed_work(&up->overrun_backoff, delay);
}
Sebastian Andrzej Siewior
committed
serial8250_rpm_put(up);
return IRQ_RETVAL(ret);
}
static int omap_8250_startup(struct uart_port *port)
{
Sebastian Andrzej Siewior
committed
struct uart_8250_port *up = up_to_u8250p(port);
struct omap8250_priv *priv = port->private_data;
int ret;
if (priv->wakeirq) {
ret = dev_pm_set_dedicated_wake_irq(port->dev, priv->wakeirq);
if (ret)
return ret;
}
pm_runtime_get_sync(port->dev);
Sebastian Andrzej Siewior
committed
up->mcr = 0;
serial_out(up, UART_FCR, UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
serial_out(up, UART_LCR, UART_LCR_WLEN8);
up->lsr_saved_flags = 0;
up->msr_saved_flags = 0;
/* Disable DMA for console UART */
if (uart_console(port))
up->dma = NULL;
Sebastian Andrzej Siewior
committed
if (up->dma) {
ret = serial8250_request_dma(up);
if (ret) {
dev_warn_ratelimited(port->dev,
"failed to request DMA\n");
up->dma = NULL;
}
}
ret = request_irq(port->irq, omap8250_irq, IRQF_SHARED,
dev_name(port->dev), port);
if (ret < 0)
Sebastian Andrzej Siewior
committed
up->ier = UART_IER_RLSI | UART_IER_RDI;
serial_out(up, UART_IER, up->ier);
#ifdef CONFIG_PM
up->capabilities |= UART_CAP_RPM;
#endif
/* Enable module level wake up */
priv->wer = OMAP_UART_WER_MOD_WKUP;
if (priv->habit & OMAP_UART_WER_HAS_TX_WAKEUP)
priv->wer |= OMAP_UART_TX_WAKEUP_EN;
serial_out(up, UART_OMAP_WER, priv->wer);
if (up->dma && !(priv->habit & UART_HAS_EFR2))
up->dma->rx_dma(up);
pm_runtime_mark_last_busy(port->dev);
pm_runtime_put_autosuspend(port->dev);
return 0;
err:
pm_runtime_mark_last_busy(port->dev);
pm_runtime_put_autosuspend(port->dev);
dev_pm_clear_wake_irq(port->dev);
return ret;
}
static void omap_8250_shutdown(struct uart_port *port)
{
Sebastian Andrzej Siewior
committed
struct uart_8250_port *up = up_to_u8250p(port);
struct omap8250_priv *priv = port->private_data;
flush_work(&priv->qos_work);
omap_8250_rx_dma_flush(up);
pm_runtime_get_sync(port->dev);
serial_out(up, UART_OMAP_WER, 0);
if (priv->habit & UART_HAS_EFR2)
serial_out(up, UART_OMAP_EFR2, 0x0);
Sebastian Andrzej Siewior
committed
up->ier = 0;
serial_out(up, UART_IER, 0);
if (up->dma)
serial8250_release_dma(up);
/*
* Disable break condition and FIFOs
*/
if (up->lcr & UART_LCR_SBC)
serial_out(up, UART_LCR, up->lcr & ~UART_LCR_SBC);
serial_out(up, UART_FCR, UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
pm_runtime_mark_last_busy(port->dev);
pm_runtime_put_autosuspend(port->dev);
Sebastian Andrzej Siewior
committed
free_irq(port->irq, port);
dev_pm_clear_wake_irq(port->dev);
}
static void omap_8250_throttle(struct uart_port *port)
{
struct omap8250_priv *priv = port->private_data;
unsigned long flags;
pm_runtime_get_sync(port->dev);
spin_lock_irqsave(&port->lock, flags);
port->ops->stop_rx(port);
priv->throttled = true;
spin_unlock_irqrestore(&port->lock, flags);
pm_runtime_mark_last_busy(port->dev);
pm_runtime_put_autosuspend(port->dev);
}
static void omap_8250_unthrottle(struct uart_port *port)
{
struct omap8250_priv *priv = port->private_data;
struct uart_8250_port *up = up_to_u8250p(port);
unsigned long flags;
pm_runtime_get_sync(port->dev);
spin_lock_irqsave(&port->lock, flags);
priv->throttled = false;
if (up->dma)
up->dma->rx_dma(up);
up->ier |= UART_IER_RLSI | UART_IER_RDI;
port->read_status_mask |= UART_LSR_DR;
serial_out(up, UART_IER, up->ier);
spin_unlock_irqrestore(&port->lock, flags);
pm_runtime_mark_last_busy(port->dev);
pm_runtime_put_autosuspend(port->dev);
}
#ifdef CONFIG_SERIAL_8250_DMA
static int omap_8250_rx_dma(struct uart_8250_port *p);
/* Must be called while priv->rx_dma_lock is held */
static void __dma_rx_do_complete(struct uart_8250_port *p)
{
struct uart_8250_dma *dma = p->dma;
struct tty_port *tty_port = &p->port.state->port;
struct omap8250_priv *priv = p->port.private_data;
Vignesh Raghavendra
committed
struct dma_chan *rxchan = dma->rxchan;
dma_cookie_t cookie;
struct dma_tx_state state;
int count;
int ret;
u32 reg;
goto out;
Vignesh Raghavendra
committed
cookie = dma->rx_cookie;
dma->rx_running = 0;
/* Re-enable RX FIFO interrupt now that transfer is complete */
if (priv->habit & UART_HAS_RHR_IT_DIS) {
reg = serial_in(p, UART_OMAP_IER2);
reg &= ~UART_OMAP_IER2_RHR_IT_DIS;
serial_out(p, UART_OMAP_IER2, UART_OMAP_IER2_RHR_IT_DIS);
}
Vignesh Raghavendra
committed
dmaengine_tx_status(rxchan, cookie, &state);
Vignesh Raghavendra
committed
count = dma->rx_size - state.residue + state.in_flight_bytes;
if (count < dma->rx_size) {
dmaengine_terminate_async(rxchan);
/*
* Poll for teardown to complete which guarantees in
* flight data is drained.
*/
if (state.in_flight_bytes) {
int poll_count = 25;
Vignesh Raghavendra
committed
while (dmaengine_tx_status(rxchan, cookie, NULL) &&
poll_count--)
cpu_relax();
Vignesh Raghavendra
committed
dev_err(p->port.dev, "teardown incomplete\n");
}
}
Vignesh Raghavendra
committed
if (!count)
goto out;
ret = tty_insert_flip_string(tty_port, dma->rx_buf, count);
p->port.icount.rx += ret;
p->port.icount.buf_overrun += count - ret;
out:
tty_flip_buffer_push(tty_port);
}
static void __dma_rx_complete(void *param)
{
struct uart_8250_port *p = param;
struct omap8250_priv *priv = p->port.private_data;
struct uart_8250_dma *dma = p->dma;
struct dma_tx_state state;
unsigned long flags;
spin_lock_irqsave(&p->port.lock, flags);
/*
* If the tx status is not DMA_COMPLETE, then this is a delayed
* completion callback. A previous RX timeout flush would have
* already pushed the data, so exit.
*/
if (dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state) !=
DMA_COMPLETE) {
spin_unlock_irqrestore(&p->port.lock, flags);
return;
}
__dma_rx_do_complete(p);
if (!priv->throttled) {
p->ier |= UART_IER_RLSI | UART_IER_RDI;
serial_out(p, UART_IER, p->ier);
if (!(priv->habit & UART_HAS_EFR2))
omap_8250_rx_dma(p);
}
spin_unlock_irqrestore(&p->port.lock, flags);
static void omap_8250_rx_dma_flush(struct uart_8250_port *p)
{
struct omap8250_priv *priv = p->port.private_data;
struct uart_8250_dma *dma = p->dma;
struct dma_tx_state state;
Sebastian Andrzej Siewior
committed
int ret;
spin_lock_irqsave(&priv->rx_dma_lock, flags);
if (!dma->rx_running) {
spin_unlock_irqrestore(&priv->rx_dma_lock, flags);
return;
}
ret = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
if (ret == DMA_IN_PROGRESS) {
ret = dmaengine_pause(dma->rxchan);
if (WARN_ON_ONCE(ret))
priv->rx_dma_broken = true;
}
__dma_rx_do_complete(p);
spin_unlock_irqrestore(&priv->rx_dma_lock, flags);
static int omap_8250_rx_dma(struct uart_8250_port *p)
struct omap8250_priv *priv = p->port.private_data;
struct uart_8250_dma *dma = p->dma;
struct dma_async_tx_descriptor *desc;
u32 reg;
Sebastian Andrzej Siewior
committed
if (priv->rx_dma_broken)
return -EINVAL;
spin_lock_irqsave(&priv->rx_dma_lock, flags);
if (dma->rx_running) {
enum dma_status state;
state = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, NULL);
if (state == DMA_COMPLETE) {
/*
* Disable RX interrupts to allow RX DMA completion
* callback to run.
*/
p->ier &= ~(UART_IER_RLSI | UART_IER_RDI);
serial_out(p, UART_IER, p->ier);
}
desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
dma->rx_size, DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) {
err = -EBUSY;
goto out;
}
dma->rx_running = 1;
desc->callback = __dma_rx_complete;
desc->callback_param = p;
dma->rx_cookie = dmaengine_submit(desc);
/*
* Disable RX FIFO interrupt while RX DMA is enabled, else
* spurious interrupt may be raised when data is in the RX FIFO
* but is yet to be drained by DMA.
*/
if (priv->habit & UART_HAS_RHR_IT_DIS) {
reg = serial_in(p, UART_OMAP_IER2);
reg |= UART_OMAP_IER2_RHR_IT_DIS;
serial_out(p, UART_OMAP_IER2, UART_OMAP_IER2_RHR_IT_DIS);
}
dma_async_issue_pending(dma->rxchan);
out:
spin_unlock_irqrestore(&priv->rx_dma_lock, flags);
return err;
static int omap_8250_tx_dma(struct uart_8250_port *p);
static void omap_8250_dma_tx_complete(void *param)
{
struct uart_8250_port *p = param;
struct uart_8250_dma *dma = p->dma;
struct circ_buf *xmit = &p->port.state->xmit;
unsigned long flags;
bool en_thri = false;
struct omap8250_priv *priv = p->port.private_data;
dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr,
UART_XMIT_SIZE, DMA_TO_DEVICE);
spin_lock_irqsave(&p->port.lock, flags);
dma->tx_running = 0;
xmit->tail += dma->tx_size;
xmit->tail &= UART_XMIT_SIZE - 1;
p->port.icount.tx += dma->tx_size;
if (priv->delayed_restore) {
priv->delayed_restore = 0;
omap8250_restore_regs(p);
}
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(&p->port);
if (!uart_circ_empty(xmit) && !uart_tx_stopped(&p->port)) {
int ret;