[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