[linux-yocto] [[PATCH 1/1] 8250: dw: Support all baudrates on baytrail

chong.yi.chai at intel.com chong.yi.chai at intel.com
Wed Mar 30 20:16:14 PDT 2016


From: "Chai, Chong Yi" <chong.yi.chai at intel.com>

---
 ...8250_dw-Support-all-baudrates-on-baytrail.patch | 152 ++++++++++++++++++
 ...ot-using-UART-RTS-override-with-Auto-Flow.patch |  61 ++++++++
 features/soc/baytrail/baytrail.scc                 |   8 +
 ...-Override-the-DCD-and-DSR-pin-status-for-.patch | 160 +++++++++++++++++++
 ...50-don-t-use-slave_id-of-dma_slave_config.patch | 169 +++++++++++++++++++++
 ..._core-handle_irq-returns-1-only-if-data-w.patch | 102 +++++++++++++
 ..._dw-mask-UART-TX-completion-intr-in-byt_s.patch |  72 +++++++++
 ..._pci-mask-UART-TX-completion-intr-in-byt_.patch |  47 ++++++
 ..._pci-remove-rts_n-override-from-Baytrail-.patch |  52 +++++++
 9 files changed, 823 insertions(+)
 create mode 100644 features/soc/baytrail/8250_dw-Support-all-baudrates-on-baytrail.patch
 create mode 100644 features/soc/baytrail/ACPI-LPSS-not-using-UART-RTS-override-with-Auto-Flow.patch
 create mode 100644 features/soc/baytrail/serial-8250-Override-the-DCD-and-DSR-pin-status-for-.patch
 create mode 100644 features/soc/baytrail/serial-8250-don-t-use-slave_id-of-dma_slave_config.patch
 create mode 100644 features/soc/baytrail/serial-8250_core-handle_irq-returns-1-only-if-data-w.patch
 create mode 100644 features/soc/baytrail/serial-8250_dw-mask-UART-TX-completion-intr-in-byt_s.patch
 create mode 100644 features/soc/baytrail/serial-8250_pci-mask-UART-TX-completion-intr-in-byt_.patch
 create mode 100644 features/soc/baytrail/serial-8250_pci-remove-rts_n-override-from-Baytrail-.patch

diff --git a/features/soc/baytrail/8250_dw-Support-all-baudrates-on-baytrail.patch b/features/soc/baytrail/8250_dw-Support-all-baudrates-on-baytrail.patch
new file mode 100644
index 0000000..6ae4ad1
--- /dev/null
+++ b/features/soc/baytrail/8250_dw-Support-all-baudrates-on-baytrail.patch
@@ -0,0 +1,152 @@
+From 64e266106919e60a491248aa26ecbc5daf7a100d Mon Sep 17 00:00:00 2001
+From: Loic Poulain <loic.poulain at intel.com>
+Date: Thu, 24 Apr 2014 11:46:14 +0200
+Subject: [PATCH 005/164] 8250_dw: Support all baudrates on baytrail
+
+In the same manner as 8250_pci, 8250_dw needs some
+baytrail specific quirks to be used. The reference
+clock needs to be adjusted before divided in order
+to have the minimum error rate on the baudrate.
+
+The specific byt set termios function is stored in
+the driver_data field of the acpi device id via the
+dw8250_acpi_desc structure.
+
+Remove the uartclk field which is no longer delivered
+as driver data.
+
+Signed-off-by: Loic Poulain <loic.poulain at intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+(cherry picked from commit c439c33d85e252d3b2b454ab7ba38b62d6e0a830)
+
+Signed-off-by: Maurice Petallo <mauricex.r.petallo at intel.com>
+---
+ drivers/tty/serial/8250/8250_dw.c |   81 +++++++++++++++++++++++++++++++++++--
+ 1 files changed, 77 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
+index ed31135..51b307a 100644
+--- a/drivers/tty/serial/8250/8250_dw.c
++++ b/drivers/tty/serial/8250/8250_dw.c
+@@ -63,6 +63,70 @@ struct dw8250_data { 
+ 	bool			no_ucv;
+ };
+ 
++struct dw8250_acpi_desc {
++	void (*set_termios)(struct uart_port *p, struct ktermios *termios,
++			    struct ktermios *old);
++};
++
++#define BYT_PRV_CLK			0x800
++#define BYT_PRV_CLK_EN			(1 << 0)
++#define BYT_PRV_CLK_M_VAL_SHIFT		1
++#define BYT_PRV_CLK_N_VAL_SHIFT		16
++#define BYT_PRV_CLK_UPDATE		(1 << 31)
++
++static void byt_set_termios(struct uart_port *p, struct ktermios *termios,
++			    struct ktermios *old)
++{
++	unsigned int baud = tty_termios_baud_rate(termios);
++	unsigned int m, n;
++	u32 reg;
++
++	/*
++	* For baud rates 0.5M, 1M, 1.5M, 2M, 2.5M, 3M, 3.5M and 4M the
++	* dividers must be adjusted.
++	*
++	* uartclk = (m / n) * 100 MHz, where m <= n
++	*/
++	switch (baud) {
++	case 500000:
++	case 1000000:
++	case 2000000:
++	case 4000000:
++		m = 64;
++		n = 100;
++		p->uartclk = 64000000;
++		break;
++	case 3500000:
++		m = 56;
++		n = 100;
++		p->uartclk = 56000000;
++		break;
++	case 1500000:
++	case 3000000:
++		m = 48;
++		n = 100;
++		p->uartclk = 48000000;
++		break;
++	case 2500000:
++		m = 40;
++		n = 100;
++		p->uartclk = 40000000;
++		break;
++	default:
++		m = 2304;
++		n = 3125;
++		p->uartclk = 73728000;
++	}
++
++	/* Reset the clock */
++	reg = (m << BYT_PRV_CLK_M_VAL_SHIFT) | (n << BYT_PRV_CLK_N_VAL_SHIFT);
++	writel(reg, p->membase + BYT_PRV_CLK);
++	reg |= BYT_PRV_CLK_EN | BYT_PRV_CLK_UPDATE;
++	writel(reg, p->membase + BYT_PRV_CLK);
++
++	serial8250_do_set_termios(p, termios, old);
++}
++
+ static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value)
+ {
+ 	struct dw8250_data *d = p->private_data;
+@@ -301,6 +365,7 @@ static int dw8250_probe_acpi(struct uart_8250_port *up,
+ {
+ 	const struct acpi_device_id *id;
+ 	struct uart_port *p = &up->port;
++	struct dw8250_acpi_desc *acpi_desc;
+ 
+ 	dw8250_setup_port(up);
+ 
+@@ -313,14 +378,18 @@ static int dw8250_probe_acpi(struct uart_8250_port *up,
+ 	p->serial_out = dw8250_serial_out32;
+ 	p->regshift = 2;
+ 
+-	if (!p->uartclk)
+-		p->uartclk = (unsigned int)id->driver_data;
+-
+ 	up->dma = &data->dma;
+ 
+ 	up->dma->rxconf.src_maxburst = p->fifosize / 4;
+ 	up->dma->txconf.dst_maxburst = p->fifosize / 4;
+ 
++	acpi_desc = (struct dw8250_acpi_desc *)id->driver_data;
++	if (!acpi_desc)
++		return 0;
++
++	if (acpi_desc->set_termios)
++		p->set_termios = acpi_desc->set_termios;
++
+ 	return 0;
+ }
+ 
+@@ -471,12 +540,16 @@ static const struct of_device_id dw8250_of_match[] = {
+ };
+ MODULE_DEVICE_TABLE(of, dw8250_of_match);
+ 
++static struct dw8250_acpi_desc byt_8250_desc = {
++	.set_termios = byt_set_termios,
++};
++
+ static const struct acpi_device_id dw8250_acpi_match[] = {
+ 	{ "INT33C4", 0 },
+ 	{ "INT33C5", 0 },
+ 	{ "INT3434", 0 },
+ 	{ "INT3435", 0 },
+-	{ "80860F0A", 0 },
++	{ "80860F0A", (kernel_ulong_t)&byt_8250_desc},
+ 	{ },
+ };
+ MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match);
+-- 
+1.7.7.6
+
diff --git a/features/soc/baytrail/ACPI-LPSS-not-using-UART-RTS-override-with-Auto-Flow.patch b/features/soc/baytrail/ACPI-LPSS-not-using-UART-RTS-override-with-Auto-Flow.patch
new file mode 100644
index 0000000..593fe89
--- /dev/null
+++ b/features/soc/baytrail/ACPI-LPSS-not-using-UART-RTS-override-with-Auto-Flow.patch
@@ -0,0 +1,61 @@
+From 0f5aad449f79758fa69474b23918c053d31d82e5 Mon Sep 17 00:00:00 2001
+From: Heikki Krogerus <heikki.krogerus at linux.intel.com>
+Date: Thu, 11 Sep 2014 15:19:33 +0300
+Subject: [PATCH 029/164] ACPI / LPSS: not using UART RTS override with Auto
+ Flow Control
+
+Adding a check for UART Auto Flow Control feature and only
+enabling the RTS override when it's not supported. RTS
+override is not needed when Auto Flow Control is used and
+they shouldn't be used together.
+
+Signed-off-by: Heikki Krogerus <heikki.krogerus at linux.intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+(cherry picked from commit 1f47a77c4e4951f141bf20fe7f7c5d9438ea1663)
+
+Signed-off-by: Maurice Petallo <mauricex.r.petallo at intel.com>
+---
+ drivers/acpi/acpi_lpss.c |   22 +++++++++++++++-------
+ 1 files changed, 15 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
+index 8c2bae9..7e038be 100644
+--- a/drivers/acpi/acpi_lpss.c
++++ b/drivers/acpi/acpi_lpss.c
+@@ -67,18 +67,26 @@ struct lpss_private_data {
+ 	const struct lpss_device_desc *dev_desc;
+ };
+ 
++/* UART Component Parameter Register */
++#define LPSS_UART_CPR			0xF4
++#define LPSS_UART_CPR_AFCE		BIT(4)
++
+ static void lpss_uart_setup(struct lpss_private_data *pdata)
+ {
+ 	unsigned int offset;
+-	u32 reg;
++	u32 val;
+ 
+ 	offset = pdata->dev_desc->prv_offset + LPSS_TX_INT;
+-	reg = readl(pdata->mmio_base + offset);
+-	writel(reg | LPSS_TX_INT_MASK, pdata->mmio_base + offset);
+-
+-	offset = pdata->dev_desc->prv_offset + LPSS_GENERAL;
+-	reg = readl(pdata->mmio_base + offset);
+-	writel(reg | LPSS_GENERAL_UART_RTS_OVRD, pdata->mmio_base + offset);
++	val = readl(pdata->mmio_base + offset);
++	writel(val | LPSS_TX_INT_MASK, pdata->mmio_base + offset);
++
++	val = readl(pdata->mmio_base + LPSS_UART_CPR);
++	if (!(val & LPSS_UART_CPR_AFCE)) {
++		offset = pdata->dev_desc->prv_offset + LPSS_GENERAL;
++		val = readl(pdata->mmio_base + offset);
++		val |= LPSS_GENERAL_UART_RTS_OVRD;
++		writel(val, pdata->mmio_base + offset);
++	}
+ }
+ 
+ static struct lpss_device_desc lpt_dev_desc = {
+-- 
+1.7.7.6
+
diff --git a/features/soc/baytrail/baytrail.scc b/features/soc/baytrail/baytrail.scc
index 03a22d0..da9f3d5 100644
--- a/features/soc/baytrail/baytrail.scc
+++ b/features/soc/baytrail/baytrail.scc
@@ -54,3 +54,11 @@ patch dmaengine-dw-apply-both-HS-interfaces-and-remove-sla.patch
 patch dmaengine-dw-introduce-generic-filter-function.patch
 patch dmaengine-dw-move-clock-operations-to-platform.c.patch
 patch dmaengine-dw-fix-checkpatch.pl-warnings.patch
+patch 8250_dw-Support-all-baudrates-on-baytrail.patch
+patch serial-8250_pci-remove-rts_n-override-from-Baytrail-.patch
+patch ACPI-LPSS-not-using-UART-RTS-override-with-Auto-Flow.patch
+patch serial-8250-don-t-use-slave_id-of-dma_slave_config.patch
+patch serial-8250_pci-mask-UART-TX-completion-intr-in-byt_.patch
+patch serial-8250_dw-mask-UART-TX-completion-intr-in-byt_s.patch
+patch serial-8250_core-handle_irq-returns-1-only-if-data-w.patch
+patch serial-8250-Override-the-DCD-and-DSR-pin-status-for-.patch
diff --git a/features/soc/baytrail/serial-8250-Override-the-DCD-and-DSR-pin-status-for-.patch b/features/soc/baytrail/serial-8250-Override-the-DCD-and-DSR-pin-status-for-.patch
new file mode 100644
index 0000000..4fe8489
--- /dev/null
+++ b/features/soc/baytrail/serial-8250-Override-the-DCD-and-DSR-pin-status-for-.patch
@@ -0,0 +1,160 @@
+From 2e7bc2916641e92b13f9e5371cd56bd774b1ea43 Mon Sep 17 00:00:00 2001
+From: Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad at intel.com>
+Date: Wed, 3 Jun 2015 11:43:35 +0800
+Subject: [PATCH 112/164] serial: 8250: Override the DCD and DSR pin status
+ for Bay Trail
+
+Bay Trail UART port does not support DCD and DSR. The driver
+should indicate that the signal is permanently active.
+
+Signed-off-by: Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad at intel.com>
+---
+ drivers/tty/serial/8250/8250_core.c |   12 +++++++++++-
+ drivers/tty/serial/8250/8250_dw.c   |   16 ++++++++++++++++
+ drivers/tty/serial/8250/8250_pci.c  |   12 ++++++++++++
+ include/linux/serial_8250.h         |    1 +
+ include/linux/serial_core.h         |    1 +
+ 5 files changed, 41 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
+index 0841186..8edf57d 100644
+--- a/drivers/tty/serial/8250/8250_core.c
++++ b/drivers/tty/serial/8250/8250_core.c
+@@ -1811,7 +1811,7 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
+ 	return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0;
+ }
+ 
+-static unsigned int serial8250_get_mctrl(struct uart_port *port)
++unsigned int serial8250_do_get_mctrl(struct uart_port *port)
+ {
+ 	struct uart_8250_port *up =
+ 		container_of(port, struct uart_8250_port, port);
+@@ -1831,6 +1831,14 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port)
+ 		ret |= TIOCM_CTS;
+ 	return ret;
+ }
++EXPORT_SYMBOL_GPL(serial8250_do_get_mctrl);
++
++static unsigned int serial8250_get_mctrl(struct uart_port *port)
++{
++	if (port->get_mctrl)
++		return port->get_mctrl(port);
++	return serial8250_do_get_mctrl(port);
++}
+ 
+ static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
+ {
+@@ -3307,6 +3315,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
+ 		/*  Possibly override set_termios call */
+ 		if (up->port.set_termios)
+ 			uart->port.set_termios = up->port.set_termios;
++		if (up->port.get_mctrl)
++			uart->port.get_mctrl = up->port.get_mctrl;
+ 		if (up->port.pm)
+ 			uart->port.pm = up->port.pm;
+ 		if (up->port.handle_break)
+diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
+index e9ee1a1..a98b0b8 100644
+--- a/drivers/tty/serial/8250/8250_dw.c
++++ b/drivers/tty/serial/8250/8250_dw.c
+@@ -65,6 +65,7 @@ struct dw8250_data {
+ struct dw8250_acpi_desc {
+ 	void (*set_termios)(struct uart_port *p, struct ktermios *termios,
+ 			    struct ktermios *old);
++	unsigned int (*get_mctrl)(struct uart_port *port);
+ };
+ 
+ #define BYT_PRV_CLK			0x800
+@@ -132,6 +133,17 @@ static void byt_set_termios(struct uart_port *p, struct ktermios *termios,
+ 	serial8250_do_set_termios(p, termios, old);
+ }
+ 
++static unsigned int
++byt_get_mctrl(struct uart_port *port)
++{
++	unsigned int ret = serial8250_do_get_mctrl(port);
++
++	/* Override the status of DCD and DSR */
++	ret = ret | TIOCM_CAR | TIOCM_DSR;
++
++	return ret;
++}
++
+ static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value)
+ {
+ 	struct dw8250_data *d = p->private_data;
+@@ -370,6 +382,9 @@ static int dw8250_probe_acpi(struct uart_8250_port *up,
+ 	if (acpi_desc->set_termios)
+ 		p->set_termios = acpi_desc->set_termios;
+ 
++	if (acpi_desc->get_mctrl)
++		p->get_mctrl = acpi_desc->get_mctrl;
++
+ 	return 0;
+ }
+ 
+@@ -517,6 +532,7 @@ MODULE_DEVICE_TABLE(of, dw8250_of_match);
+ 
+ static struct dw8250_acpi_desc byt_8250_desc = {
+ 	.set_termios = byt_set_termios,
++	.get_mctrl = byt_get_mctrl,
+ };
+ 
+ static const struct acpi_device_id dw8250_acpi_match[] = {
+diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
+index e8a5a70..ef3f4b0 100644
+--- a/drivers/tty/serial/8250/8250_pci.c
++++ b/drivers/tty/serial/8250/8250_pci.c
+@@ -1409,6 +1409,17 @@ static bool byt_dma_filter(struct dma_chan *chan, void *param)
+ 	return true;
+ }
+ 
++static unsigned int
++byt_get_mctrl(struct uart_port *port)
++{
++	unsigned int ret = serial8250_do_get_mctrl(port);
++
++	/* Override the status of DCD and DSR */
++	ret = ret | TIOCM_CAR | TIOCM_DSR;
++
++	return ret;
++}
++
+ static int
+ byt_serial_setup(struct serial_private *priv,
+ 		 const struct pciserial_board *board,
+@@ -1469,6 +1480,7 @@ byt_serial_setup(struct serial_private *priv,
+ 	port->port.type = PORT_16550A;
+ 	port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE);
+ 	port->port.set_termios = byt_set_termios;
++	port->port.get_mctrl = byt_get_mctrl;
+ 	port->port.fifosize = 64;
+ 	port->tx_loadsz = 64;
+ 	port->dma = dma;
+diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
+index af47a8a..4a4ba49 100644
+--- a/include/linux/serial_8250.h
++++ b/include/linux/serial_8250.h
+@@ -116,6 +116,7 @@ extern void serial8250_do_set_termios(struct uart_port *port,
+ 		struct ktermios *termios, struct ktermios *old);
+ extern void serial8250_do_pm(struct uart_port *port, unsigned int state,
+ 			     unsigned int oldstate);
++extern unsigned int serial8250_do_get_mctrl(struct uart_port *port);
+ extern int fsl8250_handle_irq(struct uart_port *port);
+ int serial8250_handle_irq(struct uart_port *port, unsigned int iir);
+ unsigned char serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr);
+diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
+index f729be9..a2ed15c 100644
+--- a/include/linux/serial_core.h
++++ b/include/linux/serial_core.h
+@@ -122,6 +122,7 @@ struct uart_port {
+ 	void			(*set_termios)(struct uart_port *,
+ 				               struct ktermios *new,
+ 				               struct ktermios *old);
++	unsigned int		(*get_mctrl)(struct uart_port *);
+ 	int			(*handle_irq)(struct uart_port *);
+ 	void			(*pm)(struct uart_port *, unsigned int state,
+ 				      unsigned int old);
+-- 
+1.7.7.6
+
diff --git a/features/soc/baytrail/serial-8250-don-t-use-slave_id-of-dma_slave_config.patch b/features/soc/baytrail/serial-8250-don-t-use-slave_id-of-dma_slave_config.patch
new file mode 100644
index 0000000..1bedc03
--- /dev/null
+++ b/features/soc/baytrail/serial-8250-don-t-use-slave_id-of-dma_slave_config.patch
@@ -0,0 +1,169 @@
+From 59bedc088759eb10039f8882c9be097e3b0d84a3 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
+Date: Tue, 19 Aug 2014 20:29:22 +0300
+Subject: [PATCH 040/164] serial: 8250: don't use slave_id of dma_slave_config
+
+That field has been deprecated in favour of getting the necessary information
+from ACPI or DT.
+
+However, we still need to deal systems that are PCI only (no ACPI to back up)
+like Intel Bay Trail. In order to support such systems, we explicitly bind
+setup() to the appropriate DMA filter function and its corresponding parameter.
+Then when serial8250_request_dma() doesn't find the channel via ACPI or DT, it
+falls back to use the given filter function.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
+Acked-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+Signed-off-by: Vinod Koul <vinod.koul at intel.com>
+(cherry picked from commit 9a1870ce812e13091c21af36d4dc1cd29077966d)
+Signed-off-by: Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad at intel.com>
+---
+ drivers/tty/serial/8250/8250.h     |    6 ++--
+ drivers/tty/serial/8250/8250_dw.c  |    7 +----
+ drivers/tty/serial/8250/8250_pci.c |   51 ++++++++++++++++++++++++++++--------
+ 3 files changed, 44 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
+index 1ebf853..488ec04 100644
+--- a/drivers/tty/serial/8250/8250.h
++++ b/drivers/tty/serial/8250/8250.h
+@@ -15,13 +15,13 @@
+ #include <linux/dmaengine.h>
+ 
+ struct uart_8250_dma {
++	/* Filter function */
+ 	dma_filter_fn		fn;
++
++	/* Parameter to the filter function */
+ 	void			*rx_param;
+ 	void			*tx_param;
+ 
+-	int			rx_chan_id;
+-	int			tx_chan_id;
+-
+ 	struct dma_slave_config	rxconf;
+ 	struct dma_slave_config	txconf;
+ 
+diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
+index 51b307a..56e1102 100644
+--- a/drivers/tty/serial/8250/8250_dw.c
++++ b/drivers/tty/serial/8250/8250_dw.c
+@@ -244,10 +244,7 @@ dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)
+ 
+ static bool dw8250_dma_filter(struct dma_chan *chan, void *param)
+ {
+-	struct dw8250_data *data = param;
+-
+-	return chan->chan_id == data->dma.tx_chan_id ||
+-	       chan->chan_id == data->dma.rx_chan_id;
++	return false;
+ }
+ 
+ static void dw8250_setup_port(struct uart_8250_port *up)
+@@ -408,8 +405,6 @@ static int dw8250_probe(struct platform_device *pdev)
+ 		uart.port.uartclk = clk_get_rate(data->clk);
+ 	}
+ 
+-	data->dma.rx_chan_id = -1;
+-	data->dma.tx_chan_id = -1;
+ 	data->dma.rx_param = data;
+ 	data->dma.tx_param = data;
+ 	data->dma.fn = dw8250_dma_filter;
+diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
+index bc68ca2..1557c73 100644
+--- a/drivers/tty/serial/8250/8250_pci.c
++++ b/drivers/tty/serial/8250/8250_pci.c
+@@ -25,6 +25,9 @@
+ #include <asm/byteorder.h>
+ #include <asm/io.h>
+ 
++#include <linux/dmaengine.h>
++#include <linux/platform_data/dma-dw.h>
++
+ #include "8250.h"
+ 
+ /*
+@@ -1393,7 +1396,13 @@ byt_set_termios(struct uart_port *p, struct ktermios *termios,
+ 
+ static bool byt_dma_filter(struct dma_chan *chan, void *param)
+ {
+-	return chan->chan_id == *(int *)param;
++	struct dw_dma_slave *dws = param;
++
++	if (dws->dma_dev != chan->device->dev)
++		return false;
++
++	chan->private = dws;
++	return true;
+ }
+ 
+ static int
+@@ -1401,35 +1410,55 @@ byt_serial_setup(struct serial_private *priv,
+ 		 const struct pciserial_board *board,
+ 		 struct uart_8250_port *port, int idx)
+ {
++	struct pci_dev *pdev = priv->dev;
++	struct device *dev = port->port.dev;
+ 	struct uart_8250_dma *dma;
++	struct dw_dma_slave *tx_param, *rx_param;
++	struct pci_dev *dma_dev;
+ 	int ret;
+ 
+-	dma = devm_kzalloc(port->port.dev, sizeof(*dma), GFP_KERNEL);
++	dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
+ 	if (!dma)
+ 		return -ENOMEM;
+ 
+-	switch (priv->dev->device) {
++	tx_param = devm_kzalloc(dev, sizeof(*tx_param), GFP_KERNEL);
++	if (!tx_param)
++		return -ENOMEM;
++
++	rx_param = devm_kzalloc(dev, sizeof(*rx_param), GFP_KERNEL);
++	if (!rx_param)
++		return -ENOMEM;
++
++	switch (pdev->device) {
+ 	case PCI_DEVICE_ID_INTEL_BYT_UART1:
+-		dma->rx_chan_id = 3;
+-		dma->tx_chan_id = 2;
++		rx_param->src_id = 3;
++		tx_param->dst_id = 2;
+ 		break;
+ 	case PCI_DEVICE_ID_INTEL_BYT_UART2:
+-		dma->rx_chan_id = 5;
+-		dma->tx_chan_id = 4;
++		rx_param->src_id = 5;
++		tx_param->dst_id = 4;
+ 		break;
+ 	default:
+ 		return -EINVAL;
+ 	}
+ 
+-	dma->rxconf.slave_id = dma->rx_chan_id;
++	rx_param->src_master = 1;
++	rx_param->dst_master = 0;
++
+ 	dma->rxconf.src_maxburst = 16;
+ 
+-	dma->txconf.slave_id = dma->tx_chan_id;
++	tx_param->src_master = 1;
++	tx_param->dst_master = 0;
++
+ 	dma->txconf.dst_maxburst = 16;
+ 
++	dma_dev = pci_get_slot(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 0));
++	rx_param->dma_dev = &dma_dev->dev;
++	tx_param->dma_dev = &dma_dev->dev;
++
+ 	dma->fn = byt_dma_filter;
+-	dma->rx_param = &dma->rx_chan_id;
+-	dma->tx_param = &dma->tx_chan_id;
++	dma->rx_param = rx_param;
++	dma->tx_param = tx_param;
+ 
+ 	ret = pci_default_setup(priv, board, port, idx);
+ 	port->port.iotype = UPIO_MEM;
+-- 
+1.7.7.6
+
diff --git a/features/soc/baytrail/serial-8250_core-handle_irq-returns-1-only-if-data-w.patch b/features/soc/baytrail/serial-8250_core-handle_irq-returns-1-only-if-data-w.patch
new file mode 100644
index 0000000..52eee24
--- /dev/null
+++ b/features/soc/baytrail/serial-8250_core-handle_irq-returns-1-only-if-data-w.patch
@@ -0,0 +1,102 @@
+From 63eaecae36397cf51a8f9a2f366a1af7843b9052 Mon Sep 17 00:00:00 2001
+From: Maurice Petallo <mauricex.r.petallo at intel.com>
+Date: Thu, 16 Apr 2015 14:03:47 +0800
+Subject: [PATCH 096/164] serial: 8250_core: handle_irq returns 1 only if data
+ was processed
+
+There are cases when the serial8250 interrupt routine is being called
+but there are really no data to process (IIR bit 3:0 is 0x1, UART_IIR_NO_INT).
+The good thing is, the routine just ignores it and returns back
+immediately.
+
+There are also cases when the routine handles only rx-related interrupts.
+When FIFO is enabled and THRE is disabled, LSR_THRE (LSR bit 5) will
+indicate that TX FIFO is empty which is correct since the port, in this
+case, is configured only for receiving. But, in the driver code, this will
+cause the function serial8250_handle_irq() to call serial8250_tx_chars()
+which only ends up returning from:
+
+if (uart_circ_empty(xmit))
+{
+	__stop_tx(up); return;
+}
+
+serial8250_handle_irq() returns 1 and the serial8250_interrupt() will then
+continue executing the do-while loop which keeps on trying and trying to
+process data even when there's actually nothing to transfer. This will
+result to serial8250 driver saying:
+
+"serial8250: too much work for irq..."
+
+This patch will allow serial8250_handle_irq() to return 1 only when there's
+actually some data that was processed. Otherwise, the routine ignores it just
+like how UART_IIR_NO_INT is being handled. Also, we add an extra check before
+calling serial8250_tx_chars() inside serial8250_handle_irq() to see
+whether there are data to be transmitted and the tx is not stopped.
+
+Signed-off-by: Maurice Petallo <mauricex.r.petallo at intel.com>
+Signed-off-by: Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad at intel.com>
+---
+ drivers/tty/serial/8250/8250_core.c |   25 +++++++++++++++++++++----
+ 1 files changed, 21 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
+index 612dfc7..0841186 100644
+--- a/drivers/tty/serial/8250/8250_core.c
++++ b/drivers/tty/serial/8250/8250_core.c
+@@ -1467,6 +1467,17 @@ void serial8250_tx_chars(struct uart_8250_port *up)
+ }
+ EXPORT_SYMBOL_GPL(serial8250_tx_chars);
+ 
++static int tx_data_ready(struct uart_8250_port *up)
++{
++	struct uart_port *port = &up->port;
++	struct circ_buf *xmit = &port->state->xmit;
++
++	if (uart_circ_empty(xmit) || uart_tx_stopped(port))
++		return 0;
++	else
++		return 1;
++}
++
+ unsigned int serial8250_modem_status(struct uart_8250_port *up)
+ {
+ 	struct uart_port *port = &up->port;
+@@ -1501,10 +1512,10 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
+ 	unsigned long flags;
+ 	struct uart_8250_port *up =
+ 		container_of(port, struct uart_8250_port, port);
+-	int dma_err = 0;
++	int dma_err = 0, handled = 0;
+ 
+ 	if (iir & UART_IIR_NO_INT)
+-		return 0;
++		return handled;
+ 
+ 	spin_lock_irqsave(&port->lock, flags);
+ 
+@@ -1518,13 +1529,19 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
+ 
+ 		if (!up->dma || dma_err)
+ 			status = serial8250_rx_chars(up, status);
++
++		handled = 1;
+ 	}
+ 	serial8250_modem_status(up);
+-	if (!up->dma && (status & UART_LSR_THRE))
++
++	if (!up->dma && (status & UART_LSR_THRE) &&
++	    tx_data_ready(up)) {
+ 		serial8250_tx_chars(up);
++		handled = 1;
++	}
+ 
+ 	spin_unlock_irqrestore(&port->lock, flags);
+-	return 1;
++	return handled;
+ }
+ EXPORT_SYMBOL_GPL(serial8250_handle_irq);
+ 
+-- 
+1.7.7.6
+
diff --git a/features/soc/baytrail/serial-8250_dw-mask-UART-TX-completion-intr-in-byt_s.patch b/features/soc/baytrail/serial-8250_dw-mask-UART-TX-completion-intr-in-byt_s.patch
new file mode 100644
index 0000000..bb135ab
--- /dev/null
+++ b/features/soc/baytrail/serial-8250_dw-mask-UART-TX-completion-intr-in-byt_s.patch
@@ -0,0 +1,72 @@
+From 86aae7e10a7abd226a49c7d010a1e1cb2716e9d6 Mon Sep 17 00:00:00 2001
+From: Maurice Petallo <mauricex.r.petallo at intel.com>
+Date: Wed, 4 Feb 2015 16:10:01 +0800
+Subject: [PATCH 044/164] serial: 8250_dw: mask UART TX completion intr in
+ byt_set_termios
+
+The code masking for TX completion interrupt was added by commit
+"06d8641 ACPI / LPSS: mask the UART TX completion interrupt".
+At that time, this code executes during initialization. Regression
+test on power management suspend/resume reveals the need for this
+bit to be masked again during controller resume. So, instead of
+doing the mask during Baytrail LPSS initialization, put it in
+byt_set_termios in the 8250 platform device code to make sure that
+the bit is properly set even on the event of system suspend/resume.
+
+Signed-off-by: Maurice Petallo <mauricex.r.petallo at intel.com>
+---
+ drivers/acpi/acpi_lpss.c          |    6 ------
+ drivers/tty/serial/8250/8250_dw.c |    6 ++++++
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
+index 7e038be..974b28b 100644
+--- a/drivers/acpi/acpi_lpss.c
++++ b/drivers/acpi/acpi_lpss.c
+@@ -33,8 +33,6 @@ ACPI_MODULE_NAME("acpi_lpss");
+ #define LPSS_GENERAL_UART_RTS_OVRD	BIT(3)
+ #define LPSS_SW_LTR			0x10
+ #define LPSS_AUTO_LTR			0x14
+-#define LPSS_TX_INT			0x20
+-#define LPSS_TX_INT_MASK		BIT(1)
+ 
+ struct lpss_shared_clock {
+ 	const char *name;
+@@ -76,10 +74,6 @@ static void lpss_uart_setup(struct lpss_private_data *pdata)
+ 	unsigned int offset;
+ 	u32 val;
+ 
+-	offset = pdata->dev_desc->prv_offset + LPSS_TX_INT;
+-	val = readl(pdata->mmio_base + offset);
+-	writel(val | LPSS_TX_INT_MASK, pdata->mmio_base + offset);
+-
+ 	val = readl(pdata->mmio_base + LPSS_UART_CPR);
+ 	if (!(val & LPSS_UART_CPR_AFCE)) {
+ 		offset = pdata->dev_desc->prv_offset + LPSS_GENERAL;
+diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
+index 56e1102..e9ee1a1 100644
+--- a/drivers/tty/serial/8250/8250_dw.c
++++ b/drivers/tty/serial/8250/8250_dw.c
+@@ -72,6 +72,8 @@ struct dw8250_acpi_desc {
+ #define BYT_PRV_CLK_M_VAL_SHIFT		1
+ #define BYT_PRV_CLK_N_VAL_SHIFT		16
+ #define BYT_PRV_CLK_UPDATE		(1 << 31)
++#define LPSS_TX_INT			0x820
++#define LPSS_TX_INT_MASK		BIT(1)
+ 
+ static void byt_set_termios(struct uart_port *p, struct ktermios *termios,
+ 			    struct ktermios *old)
+@@ -123,6 +125,10 @@ static void byt_set_termios(struct uart_port *p, struct ktermios *termios,
+ 	reg |= BYT_PRV_CLK_EN | BYT_PRV_CLK_UPDATE;
+ 	writel(reg, p->membase + BYT_PRV_CLK);
+ 
++	/* Disable Tx counter interrupts */
++	reg = readl(p->membase + LPSS_TX_INT);
++	writel(reg | LPSS_TX_INT_MASK, p->membase + LPSS_TX_INT);
++
+ 	serial8250_do_set_termios(p, termios, old);
+ }
+ 
+-- 
+1.7.7.6
+
diff --git a/features/soc/baytrail/serial-8250_pci-mask-UART-TX-completion-intr-in-byt_.patch b/features/soc/baytrail/serial-8250_pci-mask-UART-TX-completion-intr-in-byt_.patch
new file mode 100644
index 0000000..810917e
--- /dev/null
+++ b/features/soc/baytrail/serial-8250_pci-mask-UART-TX-completion-intr-in-byt_.patch
@@ -0,0 +1,47 @@
+From 7f9de179994f63aff637a87565b30f75be1be297 Mon Sep 17 00:00:00 2001
+From: Maurice Petallo <mauricex.r.petallo at intel.com>
+Date: Wed, 4 Feb 2015 14:56:46 +0800
+Subject: [PATCH 043/164] serial: 8250_pci: mask UART TX completion intr in
+ byt_set_termios
+
+The code masking for TX completion interrupt was added as part of
+enabling Intel Baytrail UART. At that time, this code executes
+during initialization. Regression test on power management
+suspend/resume reveals the need for this bit to be masked again
+during controller resume. So, instead of doing the mask during
+initialization, put it in byt_set_termios to make sure that the
+bit is properly set even on the event of system suspend/resume.
+
+Signed-off-by: Maurice Petallo <mauricex.r.petallo at intel.com>
+---
+ drivers/tty/serial/8250/8250_pci.c |    7 ++++---
+ 1 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
+index 1557c73..e8a5a70 100644
+--- a/drivers/tty/serial/8250/8250_pci.c
++++ b/drivers/tty/serial/8250/8250_pci.c
+@@ -1391,6 +1391,10 @@ byt_set_termios(struct uart_port *p, struct ktermios *termios,
+ 	reg |= BYT_PRV_CLK_EN | BYT_PRV_CLK_UPDATE;
+ 	writel(reg, p->membase + BYT_PRV_CLK);
+ 
++	/* Disable Tx counter interrupts */
++	reg = readl(p->membase + BYT_TX_OVF_INT);
++	writel(reg | BYT_TX_OVF_INT_MASK, p->membase + BYT_TX_OVF_INT);
++
+ 	serial8250_do_set_termios(p, termios, old);
+ }
+ 
+@@ -1470,9 +1474,6 @@ byt_serial_setup(struct serial_private *priv,
+ 	port->dma = dma;
+ 	port->capabilities = UART_CAP_FIFO | UART_CAP_AFE;
+ 
+-	/* Disable Tx counter interrupts */
+-	writel(BYT_TX_OVF_INT_MASK, port->port.membase + BYT_TX_OVF_INT);
+-
+ 	return ret;
+ }
+ 
+-- 
+1.7.7.6
+
diff --git a/features/soc/baytrail/serial-8250_pci-remove-rts_n-override-from-Baytrail-.patch b/features/soc/baytrail/serial-8250_pci-remove-rts_n-override-from-Baytrail-.patch
new file mode 100644
index 0000000..2f8fdd0
--- /dev/null
+++ b/features/soc/baytrail/serial-8250_pci-remove-rts_n-override-from-Baytrail-.patch
@@ -0,0 +1,52 @@
+From b33e3755a177f99d928cddedcd1466fb65ef38cc Mon Sep 17 00:00:00 2001
+From: Heikki Krogerus <heikki.krogerus at linux.intel.com>
+Date: Thu, 11 Sep 2014 15:26:12 +0300
+Subject: [PATCH 028/164] serial: 8250_pci: remove rts_n override from
+ Baytrail quirk
+
+It should not be used together with Auto Flow Control, and
+Auto Flow Control is always enabled on Baytrail.
+
+Signed-off-by: Heikki Krogerus <heikki.krogerus at linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+(cherry picked from commit 716e115cd7f75e3ab717f467432fd4b8cd23ee2c)
+
+Signed-off-by: Maurice Petallo <mauricex.r.petallo at intel.com>
+---
+ drivers/tty/serial/8250/8250_pci.c |   13 -------------
+ 1 files changed, 0 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
+index 5892eab..bc68ca2 100644
+--- a/drivers/tty/serial/8250/8250_pci.c
++++ b/drivers/tty/serial/8250/8250_pci.c
+@@ -1355,9 +1355,6 @@ ce4100_serial_setup(struct serial_private *priv,
+ #define BYT_PRV_CLK_N_VAL_SHIFT		16
+ #define BYT_PRV_CLK_UPDATE		(1 << 31)
+ 
+-#define BYT_GENERAL_REG			0x808
+-#define BYT_GENERAL_DIS_RTS_N_OVERRIDE	(1 << 3)
+-
+ #define BYT_TX_OVF_INT			0x820
+ #define BYT_TX_OVF_INT_MASK		(1 << 1)
+ 
+@@ -1391,16 +1388,6 @@ byt_set_termios(struct uart_port *p, struct ktermios *termios,
+ 	reg |= BYT_PRV_CLK_EN | BYT_PRV_CLK_UPDATE;
+ 	writel(reg, p->membase + BYT_PRV_CLK);
+ 
+-	/*
+-	 * If auto-handshake mechanism is not enabled,
+-	 * disable rts_n override
+-	 */
+-	reg = readl(p->membase + BYT_GENERAL_REG);
+-	reg &= ~BYT_GENERAL_DIS_RTS_N_OVERRIDE;
+-	if (termios->c_cflag & CRTSCTS)
+-		reg |= BYT_GENERAL_DIS_RTS_N_OVERRIDE;
+-	writel(reg, p->membase + BYT_GENERAL_REG);
+-
+ 	serial8250_do_set_termios(p, termios, old);
+ }
+ 
+-- 
+1.7.7.6
+
-- 
1.9.1



More information about the linux-yocto mailing list