1
0
Fork 0

Merge branch 'uart/next' into next

* uart/next: (18 commits)
  MLK-22971 serial: imx: disable UCR4_OREN in .stop_rx()
  tty: serial: lpuart: add LS1028A support
  serial: fsl_lpuart: enable two stop bits
  tty: serial: lpuart: enable wakeup source for lpuart
  MLK-17133-02 tty: serial: lpuart: add runtime pm support
  ...
5.4-rM2-2.2.x-imx-squashed
Dong Aisheng 2019-12-02 18:05:30 +08:00
commit 3e2e5e5550
2 changed files with 660 additions and 152 deletions

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,7 @@
#include <linux/delay.h>
#include <linux/pinctrl/consumer.h>
#include <linux/rational.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_device.h>
@ -33,6 +34,8 @@
#include <linux/dma-mapping.h>
#include <asm/irq.h>
#include <linux/busfreq-imx.h>
#include <linux/pm_qos.h>
#include <linux/platform_data/serial-imx.h>
#include <linux/platform_data/dma-imx.h>
@ -177,6 +180,7 @@
#define DRIVER_NAME "IMX-uart"
#define UART_NR 8
#define IMX_MODULE_MAX_CLK_RATE 80000000
/* i.MX21 type uart runs on all i.mx except i.MX1 and i.MX6q */
enum imx_uart_type {
@ -226,6 +230,8 @@ struct imx_port {
unsigned int dma_tx_nents;
unsigned int saved_reg[10];
bool context_saved;
struct pm_qos_request pm_qos_req;
};
struct imx_port_ucrs {
@ -463,18 +469,21 @@ static void imx_uart_stop_tx(struct uart_port *port)
static void imx_uart_stop_rx(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
u32 ucr1, ucr2;
u32 ucr1, ucr2, ucr4;
ucr1 = imx_uart_readl(sport, UCR1);
ucr2 = imx_uart_readl(sport, UCR2);
ucr4 = imx_uart_readl(sport, UCR4);
if (sport->dma_is_enabled) {
ucr1 &= ~(UCR1_RXDMAEN | UCR1_ATDMAEN);
} else {
ucr1 &= ~UCR1_RRDYEN;
ucr2 &= ~UCR2_ATEN;
ucr4 &= ~UCR4_OREN;
}
imx_uart_writel(sport, ucr1, UCR1);
imx_uart_writel(sport, ucr4, UCR4);
ucr2 &= ~UCR2_RXEN;
imx_uart_writel(sport, ucr2, UCR2);
@ -1222,6 +1231,9 @@ static void imx_uart_dma_exit(struct imx_port *sport)
dma_release_channel(sport->dma_chan_tx);
sport->dma_chan_tx = NULL;
}
pm_qos_remove_request(&sport->pm_qos_req);
release_bus_freq(BUS_FREQ_HIGH);
}
static int imx_uart_dma_init(struct imx_port *sport)
@ -1230,6 +1242,10 @@ static int imx_uart_dma_init(struct imx_port *sport)
struct device *dev = sport->port.dev;
int ret;
/* request high bus for DMA mode */
request_bus_freq(BUS_FREQ_HIGH);
pm_qos_add_request(&sport->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 0);
/* Prepare for RX : */
sport->dma_chan_rx = dma_request_slave_channel(dev, "rx");
if (!sport->dma_chan_rx) {
@ -1314,11 +1330,19 @@ static void imx_uart_disable_dma(struct imx_port *sport)
static int imx_uart_startup(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
struct tty_port *tty_port = &sport->port.state->port;
int retval, i;
unsigned long flags;
int dma_is_inited = 0;
u32 ucr1, ucr2, ucr4;
/* some modem may need reset */
if (!tty_port_suspended(tty_port)) {
retval = device_reset(sport->port.dev);
if (retval && retval != -ENOENT)
return retval;
}
retval = clk_prepare_enable(sport->clk_per);
if (retval)
return retval;
@ -2255,6 +2279,14 @@ static int imx_uart_probe(struct platform_device *pdev)
return ret;
}
sport->port.uartclk = clk_get_rate(sport->clk_per);
if (sport->port.uartclk > IMX_MODULE_MAX_CLK_RATE) {
ret = clk_set_rate(sport->clk_per, IMX_MODULE_MAX_CLK_RATE);
if (ret < 0) {
dev_err(&pdev->dev, "clk_set_rate() failed\n");
return ret;
}
}
sport->port.uartclk = clk_get_rate(sport->clk_per);
/* For register access, we only need to enable the ipg clock. */