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
commit
3e2e5e5550
File diff suppressed because it is too large
Load Diff
|
@ -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. */
|
||||
|
|
Loading…
Reference in New Issue