From: "Chai, Chong Yi" <chong.yi.c...@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.poul...@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.poul...@intel.com> +Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org> +(cherry picked from commit c439c33d85e252d3b2b454ab7ba38b62d6e0a830) + +Signed-off-by: Maurice Petallo <mauricex.r.peta...@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.kroge...@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.kroge...@linux.intel.com> +Signed-off-by: Rafael J. Wysocki <rafael.j.wyso...@intel.com> +(cherry picked from commit 1f47a77c4e4951f141bf20fe7f7c5d9438ea1663) + +Signed-off-by: Maurice Petallo <mauricex.r.peta...@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.moha...@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.moha...@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.shevche...@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.shevche...@linux.intel.com> +Acked-by: Greg Kroah-Hartman <gre...@linuxfoundation.org> +Signed-off-by: Vinod Koul <vinod.k...@intel.com> +(cherry picked from commit 9a1870ce812e13091c21af36d4dc1cd29077966d) +Signed-off-by: Wan Ahmad Zainie <wan.ahmad.zainie.wan.moha...@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.peta...@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.peta...@intel.com> +Signed-off-by: Wan Ahmad Zainie <wan.ahmad.zainie.wan.moha...@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.peta...@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.peta...@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.peta...@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.peta...@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.kroge...@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.kroge...@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org> +(cherry picked from commit 716e115cd7f75e3ab717f467432fd4b8cd23ee2c) + +Signed-off-by: Maurice Petallo <mauricex.r.peta...@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 -- _______________________________________________ linux-yocto mailing list linux-yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/linux-yocto