]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
fixes for 4.19
authorSasha Levin <sashal@kernel.org>
Thu, 27 Feb 2020 03:38:57 +0000 (22:38 -0500)
committerSasha Levin <sashal@kernel.org>
Thu, 27 Feb 2020 03:38:57 +0000 (22:38 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.19/drm-nouveau-kms-gv100-re-set-lut-after-clearing-for-.patch [new file with mode: 0644]
queue-4.19/lib-stackdepot-fix-outdated-comments.patch [new file with mode: 0644]
queue-4.19/lib-stackdepot.c-fix-global-out-of-bounds-in-stack_s.patch [new file with mode: 0644]
queue-4.19/series
queue-4.19/tty-serial-qcom_geni_serial-fix-rx-cancel-command-fa.patch [new file with mode: 0644]
queue-4.19/tty-serial-qcom_geni_serial-fix-uart-hang.patch [new file with mode: 0644]
queue-4.19/tty-serial-qcom_geni_serial-remove-interrupt-storm.patch [new file with mode: 0644]
queue-4.19/tty-serial-qcom_geni_serial-remove-set_rfr_wm-and-re.patch [new file with mode: 0644]
queue-4.19/tty-serial-qcom_geni_serial-remove-use-of-_relaxed-a.patch [new file with mode: 0644]
queue-4.19/tty-serial-qcom_geni_serial-remove-xfer_mode-variabl.patch [new file with mode: 0644]

diff --git a/queue-4.19/drm-nouveau-kms-gv100-re-set-lut-after-clearing-for-.patch b/queue-4.19/drm-nouveau-kms-gv100-re-set-lut-after-clearing-for-.patch
new file mode 100644 (file)
index 0000000..8c9780e
--- /dev/null
@@ -0,0 +1,47 @@
+From d30c79f4862ca4fa07daa0f767519d79c27ffab8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Feb 2020 18:11:49 -0500
+Subject: drm/nouveau/kms/gv100-: Re-set LUT after clearing for modesets
+
+From: Lyude Paul <lyude@redhat.com>
+
+[ Upstream commit f287d3d19769b1d22cba4e51fa0487f2697713c9 ]
+
+While certain modeset operations on gv100+ need us to temporarily
+disable the LUT, we make the mistake of sometimes neglecting to
+reprogram the LUT after such modesets. In particular, moving a head from
+one encoder to another seems to trigger this quite often. GV100+ is very
+picky about having a LUT in most scenarios, so this causes the display
+engine to hang with the following error code:
+
+disp: chid 1 stat 00005080 reason 5 [INVALID_STATE] mthd 0200 data
+00000001 code 0000002d)
+
+So, fix this by always re-programming the LUT if we're clearing it in a
+state where the wndw is still visible, and has a XLUT handle programmed.
+
+Signed-off-by: Lyude Paul <lyude@redhat.com>
+Fixes: facaed62b4cb ("drm/nouveau/kms/gv100: initial support")
+Cc: <stable@vger.kernel.org> # v4.18+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/nouveau/dispnv50/wndw.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
+index b3db4553098d5..d343ae66c64fe 100644
+--- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c
++++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
+@@ -405,6 +405,8 @@ nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state)
+               asyw->clr.ntfy = armw->ntfy.handle != 0;
+               asyw->clr.sema = armw->sema.handle != 0;
+               asyw->clr.xlut = armw->xlut.handle != 0;
++              if (asyw->clr.xlut && asyw->visible)
++                      asyw->set.xlut = asyw->xlut.handle != 0;
+               if (wndw->func->image_clr)
+                       asyw->clr.image = armw->image.handle[0] != 0;
+       }
+-- 
+2.20.1
+
diff --git a/queue-4.19/lib-stackdepot-fix-outdated-comments.patch b/queue-4.19/lib-stackdepot-fix-outdated-comments.patch
new file mode 100644 (file)
index 0000000..587e601
--- /dev/null
@@ -0,0 +1,47 @@
+From 844d3e76628130384370c6ffa0c2db3da374bce4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Aug 2019 19:32:46 +0800
+Subject: lib/stackdepot: Fix outdated comments
+
+From: Miles Chen <miles.chen@mediatek.com>
+
+[ Upstream commit ee050dc83bc326ad5ef8ee93bca344819371e7a5 ]
+
+Replace "depot_save_stack" with "stack_depot_save" in code comments because
+depot_save_stack() was replaced in commit c0cfc337264c ("lib/stackdepot:
+Provide functions which operate on plain storage arrays") and removed in
+commit 56d8f079c51a ("lib/stackdepot: Remove obsolete functions")
+
+Signed-off-by: Miles Chen <miles.chen@mediatek.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lkml.kernel.org/r/20190815113246.18478-1-miles.chen@mediatek.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/stackdepot.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/lib/stackdepot.c b/lib/stackdepot.c
+index e513459a5601a..c5e06c43228f9 100644
+--- a/lib/stackdepot.c
++++ b/lib/stackdepot.c
+@@ -96,7 +96,7 @@ static bool init_stack_slab(void **prealloc)
+               stack_slabs[depot_index + 1] = *prealloc;
+               /*
+                * This smp_store_release pairs with smp_load_acquire() from
+-               * |next_slab_inited| above and in depot_save_stack().
++               * |next_slab_inited| above and in stack_depot_save().
+                */
+               smp_store_release(&next_slab_inited, 1);
+       }
+@@ -123,7 +123,7 @@ static struct stack_record *depot_alloc_stack(unsigned long *entries, int size,
+               depot_offset = 0;
+               /*
+                * smp_store_release() here pairs with smp_load_acquire() from
+-               * |next_slab_inited| in depot_save_stack() and
++               * |next_slab_inited| in stack_depot_save() and
+                * init_stack_slab().
+                */
+               if (depot_index + 1 < STACK_ALLOC_MAX_SLABS)
+-- 
+2.20.1
+
diff --git a/queue-4.19/lib-stackdepot.c-fix-global-out-of-bounds-in-stack_s.patch b/queue-4.19/lib-stackdepot.c-fix-global-out-of-bounds-in-stack_s.patch
new file mode 100644 (file)
index 0000000..74b9aa5
--- /dev/null
@@ -0,0 +1,62 @@
+From d33350b62bd2427b787999177442685a31e5ffbc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Feb 2020 20:04:30 -0800
+Subject: lib/stackdepot.c: fix global out-of-bounds in stack_slabs
+
+From: Alexander Potapenko <glider@google.com>
+
+[ Upstream commit 305e519ce48e935702c32241f07d393c3c8fed3e ]
+
+Walter Wu has reported a potential case in which init_stack_slab() is
+called after stack_slabs[STACK_ALLOC_MAX_SLABS - 1] has already been
+initialized.  In that case init_stack_slab() will overwrite
+stack_slabs[STACK_ALLOC_MAX_SLABS], which may result in a memory
+corruption.
+
+Link: http://lkml.kernel.org/r/20200218102950.260263-1-glider@google.com
+Fixes: cd11016e5f521 ("mm, kasan: stackdepot implementation. Enable stackdepot for SLAB")
+Signed-off-by: Alexander Potapenko <glider@google.com>
+Reported-by: Walter Wu <walter-zh.wu@mediatek.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: Matthias Brugger <matthias.bgg@gmail.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Kate Stewart <kstewart@linuxfoundation.org>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/stackdepot.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/lib/stackdepot.c b/lib/stackdepot.c
+index c5e06c43228f9..34c71973932e0 100644
+--- a/lib/stackdepot.c
++++ b/lib/stackdepot.c
+@@ -92,15 +92,19 @@ static bool init_stack_slab(void **prealloc)
+               return true;
+       if (stack_slabs[depot_index] == NULL) {
+               stack_slabs[depot_index] = *prealloc;
++              *prealloc = NULL;
+       } else {
+-              stack_slabs[depot_index + 1] = *prealloc;
++              /* If this is the last depot slab, do not touch the next one. */
++              if (depot_index + 1 < STACK_ALLOC_MAX_SLABS) {
++                      stack_slabs[depot_index + 1] = *prealloc;
++                      *prealloc = NULL;
++              }
+               /*
+                * This smp_store_release pairs with smp_load_acquire() from
+                * |next_slab_inited| above and in stack_depot_save().
+                */
+               smp_store_release(&next_slab_inited, 1);
+       }
+-      *prealloc = NULL;
+       return true;
+ }
+-- 
+2.20.1
+
index aca69c2707b89845e829f557304ed377ac7c7920..e1fc745538cb9f6e216027427d5dcd9c271af8dc 100644 (file)
@@ -51,3 +51,12 @@ drm-amdgpu-soc15-fix-xclk-for-raven.patch
 xhci-apply-xhci_pme_stuck_quirk-to-intel-comet-lake-platforms.patch
 kvm-nvmx-don-t-emulate-instructions-in-guest-mode.patch
 kvm-x86-don-t-notify-userspace-ioapic-on-edge-triggered-interrupt-eoi.patch
+tty-serial-qcom_geni_serial-fix-uart-hang.patch
+tty-serial-qcom_geni_serial-remove-interrupt-storm.patch
+tty-serial-qcom_geni_serial-remove-use-of-_relaxed-a.patch
+tty-serial-qcom_geni_serial-remove-set_rfr_wm-and-re.patch
+tty-serial-qcom_geni_serial-remove-xfer_mode-variabl.patch
+tty-serial-qcom_geni_serial-fix-rx-cancel-command-fa.patch
+lib-stackdepot-fix-outdated-comments.patch
+lib-stackdepot.c-fix-global-out-of-bounds-in-stack_s.patch
+drm-nouveau-kms-gv100-re-set-lut-after-clearing-for-.patch
diff --git a/queue-4.19/tty-serial-qcom_geni_serial-fix-rx-cancel-command-fa.patch b/queue-4.19/tty-serial-qcom_geni_serial-fix-rx-cancel-command-fa.patch
new file mode 100644 (file)
index 0000000..40da618
--- /dev/null
@@ -0,0 +1,73 @@
+From 7eea30d0b1fac7b3dfefdcec64a22c3ad8305c2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Feb 2020 15:43:02 +0530
+Subject: tty: serial: qcom_geni_serial: Fix RX cancel command failure
+
+From: satya priya <skakit@codeaurora.org>
+
+[ Upstream commit 679aac5ead2f18d223554a52b543e1195e181811 ]
+
+RX cancel command fails when BT is switched on and off multiple times.
+
+To handle this, poll for the cancel bit in SE_GENI_S_IRQ_STATUS register
+instead of SE_GENI_S_CMD_CTRL_REG.
+
+As per the HPG update, handle the RX last bit after cancel command
+and flush out the RX FIFO buffer.
+
+Signed-off-by: satya priya <skakit@codeaurora.org>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/1581415982-8793-1-git-send-email-skakit@codeaurora.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/qcom_geni_serial.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
+index 4182129925dec..4458419f053b6 100644
+--- a/drivers/tty/serial/qcom_geni_serial.c
++++ b/drivers/tty/serial/qcom_geni_serial.c
+@@ -121,6 +121,7 @@ static int handle_rx_console(struct uart_port *uport, u32 bytes, bool drop);
+ static int handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop);
+ static unsigned int qcom_geni_serial_tx_empty(struct uart_port *port);
+ static void qcom_geni_serial_stop_rx(struct uart_port *uport);
++static void qcom_geni_serial_handle_rx(struct uart_port *uport, bool drop);
+ static const unsigned long root_freq[] = {7372800, 14745600, 19200000, 29491200,
+                                       32000000, 48000000, 64000000, 80000000,
+@@ -614,7 +615,7 @@ static void qcom_geni_serial_stop_rx(struct uart_port *uport)
+       u32 irq_en;
+       u32 status;
+       struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
+-      u32 irq_clear = S_CMD_DONE_EN;
++      u32 s_irq_status;
+       irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN);
+       irq_en &= ~(S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN);
+@@ -630,10 +631,19 @@ static void qcom_geni_serial_stop_rx(struct uart_port *uport)
+               return;
+       geni_se_cancel_s_cmd(&port->se);
+-      qcom_geni_serial_poll_bit(uport, SE_GENI_S_CMD_CTRL_REG,
+-                                      S_GENI_CMD_CANCEL, false);
++      qcom_geni_serial_poll_bit(uport, SE_GENI_S_IRQ_STATUS,
++                                      S_CMD_CANCEL_EN, true);
++      /*
++       * If timeout occurs secondary engine remains active
++       * and Abort sequence is executed.
++       */
++      s_irq_status = readl(uport->membase + SE_GENI_S_IRQ_STATUS);
++      /* Flush the Rx buffer */
++      if (s_irq_status & S_RX_FIFO_LAST_EN)
++              qcom_geni_serial_handle_rx(uport, true);
++      writel(s_irq_status, uport->membase + SE_GENI_S_IRQ_CLEAR);
++
+       status = readl(uport->membase + SE_GENI_STATUS);
+-      writel(irq_clear, uport->membase + SE_GENI_S_IRQ_CLEAR);
+       if (status & S_GENI_CMD_ACTIVE)
+               qcom_geni_serial_abort_rx(uport);
+ }
+-- 
+2.20.1
+
diff --git a/queue-4.19/tty-serial-qcom_geni_serial-fix-uart-hang.patch b/queue-4.19/tty-serial-qcom_geni_serial-fix-uart-hang.patch
new file mode 100644 (file)
index 0000000..4b327df
--- /dev/null
@@ -0,0 +1,52 @@
+From 2ace7701fd5a438f01b6791feae7659db882d598 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Dec 2018 12:33:53 -0800
+Subject: tty: serial: qcom_geni_serial: Fix UART hang
+
+From: Ryan Case <ryandcase@chromium.org>
+
+[ Upstream commit 663abb1a7a7ff8fea9ab0145463de7fcff823755 ]
+
+If a serial console write occured while a UART transmit command was
+waiting for a done signal then no further data would be sent until
+something new kicked the system into gear. If there is already data
+waiting in the circular buffer we must re-enable the tx watermark so we
+receive the expected interrupts.
+
+Signed-off-by: Ryan Case <ryandcase@chromium.org>
+Reviewed-by: Evan Green <evgreen@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/qcom_geni_serial.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
+index b3f7d1a1e97f8..2003dfcace5d8 100644
+--- a/drivers/tty/serial/qcom_geni_serial.c
++++ b/drivers/tty/serial/qcom_geni_serial.c
+@@ -438,6 +438,7 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
+       bool locked = true;
+       unsigned long flags;
+       u32 geni_status;
++      u32 irq_en;
+       WARN_ON(co->index < 0 || co->index >= GENI_UART_CONS_PORTS);
+@@ -472,6 +473,13 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
+                * has been sent, in which case we need to look for done first.
+                */
+               qcom_geni_serial_poll_tx_done(uport);
++
++              if (uart_circ_chars_pending(&uport->state->xmit)) {
++                      irq_en = readl_relaxed(uport->membase +
++                                      SE_GENI_M_IRQ_EN);
++                      writel_relaxed(irq_en | M_TX_FIFO_WATERMARK_EN,
++                                      uport->membase + SE_GENI_M_IRQ_EN);
++              }
+       }
+       __qcom_geni_serial_console_write(uport, s, count);
+-- 
+2.20.1
+
diff --git a/queue-4.19/tty-serial-qcom_geni_serial-remove-interrupt-storm.patch b/queue-4.19/tty-serial-qcom_geni_serial-remove-interrupt-storm.patch
new file mode 100644 (file)
index 0000000..053e92e
--- /dev/null
@@ -0,0 +1,87 @@
+From 22dfafadabd283123339e705d9cffde1bb0b0f1c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Dec 2018 11:43:20 -0800
+Subject: tty: serial: qcom_geni_serial: Remove interrupt storm
+
+From: Ryan Case <ryandcase@chromium.org>
+
+[ Upstream commit 64a428077758383518c258641e81d57fcd454792 ]
+
+Disable M_TX_FIFO_WATERMARK_EN after we've sent all data for a given
+transaction so we don't continue to receive a flurry of free space
+interrupts while waiting for the M_CMD_DONE notification. Re-enable the
+watermark when establishing the next transaction.
+
+Also clear the watermark interrupt after filling the FIFO so we do not
+receive notification again prior to actually having free space.
+
+Signed-off-by: Ryan Case <ryandcase@chromium.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Tested-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/qcom_geni_serial.c | 25 +++++++++++++++++++++++--
+ 1 file changed, 23 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
+index 2003dfcace5d8..743d877e7ff94 100644
+--- a/drivers/tty/serial/qcom_geni_serial.c
++++ b/drivers/tty/serial/qcom_geni_serial.c
+@@ -727,6 +727,7 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
+       size_t pending;
+       int i;
+       u32 status;
++      u32 irq_en;
+       unsigned int chunk;
+       int tail;
+@@ -755,6 +756,11 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
+       if (!port->tx_remaining) {
+               qcom_geni_serial_setup_tx(uport, pending);
+               port->tx_remaining = pending;
++
++              irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
++              if (!(irq_en & M_TX_FIFO_WATERMARK_EN))
++                      writel_relaxed(irq_en | M_TX_FIFO_WATERMARK_EN,
++                                      uport->membase + SE_GENI_M_IRQ_EN);
+       }
+       remaining = chunk;
+@@ -778,7 +784,23 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
+       }
+       xmit->tail = tail & (UART_XMIT_SIZE - 1);
++
++      /*
++       * The tx fifo watermark is level triggered and latched. Though we had
++       * cleared it in qcom_geni_serial_isr it will have already reasserted
++       * so we must clear it again here after our writes.
++       */
++      writel_relaxed(M_TX_FIFO_WATERMARK_EN,
++                      uport->membase + SE_GENI_M_IRQ_CLEAR);
++
+ out_write_wakeup:
++      if (!port->tx_remaining) {
++              irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
++              if (irq_en & M_TX_FIFO_WATERMARK_EN)
++                      writel_relaxed(irq_en & ~M_TX_FIFO_WATERMARK_EN,
++                                      uport->membase + SE_GENI_M_IRQ_EN);
++      }
++
+       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+               uart_write_wakeup(uport);
+ }
+@@ -814,8 +836,7 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
+               tty_insert_flip_char(tport, 0, TTY_OVERRUN);
+       }
+-      if (m_irq_status & (M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN) &&
+-          m_irq_en & (M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN))
++      if (m_irq_status & m_irq_en & (M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN))
+               qcom_geni_serial_handle_tx(uport, m_irq_status & M_CMD_DONE_EN,
+                                       geni_status & M_GENI_CMD_ACTIVE);
+-- 
+2.20.1
+
diff --git a/queue-4.19/tty-serial-qcom_geni_serial-remove-set_rfr_wm-and-re.patch b/queue-4.19/tty-serial-qcom_geni_serial-remove-set_rfr_wm-and-re.patch
new file mode 100644 (file)
index 0000000..b000654
--- /dev/null
@@ -0,0 +1,103 @@
+From 6fc1e94a14a9d40db946de3b6f813220bfe7360f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jan 2019 17:58:36 -0800
+Subject: tty: serial: qcom_geni_serial: Remove set_rfr_wm() and related
+ variables
+
+From: Ryan Case <ryandcase@chromium.org>
+
+[ Upstream commit a85fb9ce1fab34a3216fd4d769fede643dbc68d4 ]
+
+The variables of tx_wm and rx_wm were set to the same define value in
+all cases, never updated, and the define was sometimes used
+interchangably. Remove the variables/function and use the fixed value.
+
+Signed-off-by: Ryan Case <ryandcase@chromium.org>
+Reviewed-by: Evan Green <evgreen@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/qcom_geni_serial.c | 25 ++++---------------------
+ 1 file changed, 4 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
+index 4824869a4080d..080fa1d1ecbfd 100644
+--- a/drivers/tty/serial/qcom_geni_serial.c
++++ b/drivers/tty/serial/qcom_geni_serial.c
+@@ -85,7 +85,7 @@
+ #define DEF_FIFO_DEPTH_WORDS  16
+ #define DEF_TX_WM             2
+ #define DEF_FIFO_WIDTH_BITS   32
+-#define UART_CONSOLE_RX_WM    2
++#define UART_RX_WM            2
+ #define MAX_LOOPBACK_CFG      3
+ #ifdef CONFIG_CONSOLE_POLL
+@@ -101,9 +101,6 @@ struct qcom_geni_serial_port {
+       u32 tx_fifo_depth;
+       u32 tx_fifo_width;
+       u32 rx_fifo_depth;
+-      u32 tx_wm;
+-      u32 rx_wm;
+-      u32 rx_rfr;
+       enum geni_se_xfer_mode xfer_mode;
+       bool setup;
+       int (*handle_rx)(struct uart_port *uport, u32 bytes, bool drop);
+@@ -361,9 +358,7 @@ static int qcom_geni_serial_get_char(struct uart_port *uport)
+ static void qcom_geni_serial_poll_put_char(struct uart_port *uport,
+                                                       unsigned char c)
+ {
+-      struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
+-
+-      writel(port->tx_wm, uport->membase + SE_GENI_TX_WATERMARK_REG);
++      writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG);
+       qcom_geni_serial_setup_tx(uport, 1);
+       WARN_ON(!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
+                                               M_TX_FIFO_WATERMARK_EN, true));
+@@ -571,7 +566,7 @@ static void qcom_geni_serial_start_tx(struct uart_port *uport)
+               irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+               irq_en |= M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN;
+-              writel(port->tx_wm, uport->membase +
++              writel(DEF_TX_WM, uport->membase +
+                                               SE_GENI_TX_WATERMARK_REG);
+               writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
+       }
+@@ -840,17 +835,6 @@ static void get_tx_fifo_size(struct qcom_geni_serial_port *port)
+               (port->tx_fifo_depth * port->tx_fifo_width) / BITS_PER_BYTE;
+ }
+-static void set_rfr_wm(struct qcom_geni_serial_port *port)
+-{
+-      /*
+-       * Set RFR (Flow off) to FIFO_DEPTH - 2.
+-       * RX WM level at 10% RX_FIFO_DEPTH.
+-       * TX WM level at 10% TX_FIFO_DEPTH.
+-       */
+-      port->rx_rfr = port->rx_fifo_depth - 2;
+-      port->rx_wm = UART_CONSOLE_RX_WM;
+-      port->tx_wm = DEF_TX_WM;
+-}
+ static void qcom_geni_serial_shutdown(struct uart_port *uport)
+ {
+@@ -889,7 +873,6 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
+       get_tx_fifo_size(port);
+-      set_rfr_wm(port);
+       writel(rxstale, uport->membase + SE_UART_RX_STALE_CNT);
+       /*
+        * Make an unconditional cancel on the main sequencer to reset
+@@ -902,7 +885,7 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
+                                               false, true, false);
+       geni_se_config_packing(&port->se, BITS_PER_BYTE, port->rx_bytes_pw,
+                                               false, false, true);
+-      geni_se_init(&port->se, port->rx_wm, port->rx_rfr);
++      geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2);
+       geni_se_select_mode(&port->se, port->xfer_mode);
+       if (!uart_console(uport)) {
+               port->rx_fifo = devm_kcalloc(uport->dev,
+-- 
+2.20.1
+
diff --git a/queue-4.19/tty-serial-qcom_geni_serial-remove-use-of-_relaxed-a.patch b/queue-4.19/tty-serial-qcom_geni_serial-remove-use-of-_relaxed-a.patch
new file mode 100644 (file)
index 0000000..9e4bd6a
--- /dev/null
@@ -0,0 +1,474 @@
+From e3c77259e810cda9504699e6beb8e77259bf0332 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jan 2019 17:58:35 -0800
+Subject: tty: serial: qcom_geni_serial: Remove use of *_relaxed() and mb()
+
+From: Ryan Case <ryandcase@chromium.org>
+
+[ Upstream commit 9e06d55f7b856bfaf82036b50072600b21e52d20 ]
+
+A frequent side comment has been to remove the use of writel_relaxed,
+readl_relaxed, and mb. This reduces driver complexity and the _relaxed
+variants were not known to provide any noticeable performance benefit.
+
+Signed-off-by: Ryan Case <ryandcase@chromium.org>
+Reviewed-by: Evan Green <evgreen@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/qcom_geni_serial.c | 191 +++++++++++---------------
+ 1 file changed, 80 insertions(+), 111 deletions(-)
+
+diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
+index 743d877e7ff94..4824869a4080d 100644
+--- a/drivers/tty/serial/qcom_geni_serial.c
++++ b/drivers/tty/serial/qcom_geni_serial.c
+@@ -226,7 +226,7 @@ static unsigned int qcom_geni_serial_get_mctrl(struct uart_port *uport)
+       if (uart_console(uport)) {
+               mctrl |= TIOCM_CTS;
+       } else {
+-              geni_ios = readl_relaxed(uport->membase + SE_GENI_IOS);
++              geni_ios = readl(uport->membase + SE_GENI_IOS);
+               if (!(geni_ios & IO2_DATA_IN))
+                       mctrl |= TIOCM_CTS;
+       }
+@@ -244,7 +244,7 @@ static void qcom_geni_serial_set_mctrl(struct uart_port *uport,
+       if (!(mctrl & TIOCM_RTS))
+               uart_manual_rfr = UART_MANUAL_RFR_EN | UART_RFR_NOT_READY;
+-      writel_relaxed(uart_manual_rfr, uport->membase + SE_UART_MANUAL_RFR);
++      writel(uart_manual_rfr, uport->membase + SE_UART_MANUAL_RFR);
+ }
+ static const char *qcom_geni_serial_get_type(struct uart_port *uport)
+@@ -273,9 +273,6 @@ static bool qcom_geni_serial_poll_bit(struct uart_port *uport,
+       unsigned int fifo_bits;
+       unsigned long timeout_us = 20000;
+-      /* Ensure polling is not re-ordered before the prior writes/reads */
+-      mb();
+-
+       if (uport->private_data) {
+               port = to_dev_port(uport, uport);
+               baud = port->baud;
+@@ -295,7 +292,7 @@ static bool qcom_geni_serial_poll_bit(struct uart_port *uport,
+        */
+       timeout_us = DIV_ROUND_UP(timeout_us, 10) * 10;
+       while (timeout_us) {
+-              reg = readl_relaxed(uport->membase + offset);
++              reg = readl(uport->membase + offset);
+               if ((bool)(reg & field) == set)
+                       return true;
+               udelay(10);
+@@ -308,7 +305,7 @@ static void qcom_geni_serial_setup_tx(struct uart_port *uport, u32 xmit_size)
+ {
+       u32 m_cmd;
+-      writel_relaxed(xmit_size, uport->membase + SE_UART_TX_TRANS_LEN);
++      writel(xmit_size, uport->membase + SE_UART_TX_TRANS_LEN);
+       m_cmd = UART_START_TX << M_OPCODE_SHFT;
+       writel(m_cmd, uport->membase + SE_GENI_M_CMD0);
+ }
+@@ -321,13 +318,13 @@ static void qcom_geni_serial_poll_tx_done(struct uart_port *uport)
+       done = qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
+                                               M_CMD_DONE_EN, true);
+       if (!done) {
+-              writel_relaxed(M_GENI_CMD_ABORT, uport->membase +
++              writel(M_GENI_CMD_ABORT, uport->membase +
+                                               SE_GENI_M_CMD_CTRL_REG);
+               irq_clear |= M_CMD_ABORT_EN;
+               qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
+                                                       M_CMD_ABORT_EN, true);
+       }
+-      writel_relaxed(irq_clear, uport->membase + SE_GENI_M_IRQ_CLEAR);
++      writel(irq_clear, uport->membase + SE_GENI_M_IRQ_CLEAR);
+ }
+ static void qcom_geni_serial_abort_rx(struct uart_port *uport)
+@@ -337,8 +334,8 @@ static void qcom_geni_serial_abort_rx(struct uart_port *uport)
+       writel(S_GENI_CMD_ABORT, uport->membase + SE_GENI_S_CMD_CTRL_REG);
+       qcom_geni_serial_poll_bit(uport, SE_GENI_S_CMD_CTRL_REG,
+                                       S_GENI_CMD_ABORT, false);
+-      writel_relaxed(irq_clear, uport->membase + SE_GENI_S_IRQ_CLEAR);
+-      writel_relaxed(FORCE_DEFAULT, uport->membase + GENI_FORCE_DEFAULT_REG);
++      writel(irq_clear, uport->membase + SE_GENI_S_IRQ_CLEAR);
++      writel(FORCE_DEFAULT, uport->membase + GENI_FORCE_DEFAULT_REG);
+ }
+ #ifdef CONFIG_CONSOLE_POLL
+@@ -347,19 +344,13 @@ static int qcom_geni_serial_get_char(struct uart_port *uport)
+       u32 rx_fifo;
+       u32 status;
+-      status = readl_relaxed(uport->membase + SE_GENI_M_IRQ_STATUS);
+-      writel_relaxed(status, uport->membase + SE_GENI_M_IRQ_CLEAR);
+-
+-      status = readl_relaxed(uport->membase + SE_GENI_S_IRQ_STATUS);
+-      writel_relaxed(status, uport->membase + SE_GENI_S_IRQ_CLEAR);
++      status = readl(uport->membase + SE_GENI_M_IRQ_STATUS);
++      writel(status, uport->membase + SE_GENI_M_IRQ_CLEAR);
+-      /*
+-       * Ensure the writes to clear interrupts is not re-ordered after
+-       * reading the data.
+-       */
+-      mb();
++      status = readl(uport->membase + SE_GENI_S_IRQ_STATUS);
++      writel(status, uport->membase + SE_GENI_S_IRQ_CLEAR);
+-      status = readl_relaxed(uport->membase + SE_GENI_RX_FIFO_STATUS);
++      status = readl(uport->membase + SE_GENI_RX_FIFO_STATUS);
+       if (!(status & RX_FIFO_WC_MSK))
+               return NO_POLL_CHAR;
+@@ -372,13 +363,12 @@ static void qcom_geni_serial_poll_put_char(struct uart_port *uport,
+ {
+       struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
+-      writel_relaxed(port->tx_wm, uport->membase + SE_GENI_TX_WATERMARK_REG);
++      writel(port->tx_wm, uport->membase + SE_GENI_TX_WATERMARK_REG);
+       qcom_geni_serial_setup_tx(uport, 1);
+       WARN_ON(!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
+                                               M_TX_FIFO_WATERMARK_EN, true));
+-      writel_relaxed(c, uport->membase + SE_GENI_TX_FIFOn);
+-      writel_relaxed(M_TX_FIFO_WATERMARK_EN, uport->membase +
+-                                                      SE_GENI_M_IRQ_CLEAR);
++      writel(c, uport->membase + SE_GENI_TX_FIFOn);
++      writel(M_TX_FIFO_WATERMARK_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
+       qcom_geni_serial_poll_tx_done(uport);
+ }
+ #endif
+@@ -386,7 +376,7 @@ static void qcom_geni_serial_poll_put_char(struct uart_port *uport,
+ #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE
+ static void qcom_geni_serial_wr_char(struct uart_port *uport, int ch)
+ {
+-      writel_relaxed(ch, uport->membase + SE_GENI_TX_FIFOn);
++      writel(ch, uport->membase + SE_GENI_TX_FIFOn);
+ }
+ static void
+@@ -405,7 +395,7 @@ __qcom_geni_serial_console_write(struct uart_port *uport, const char *s,
+                       bytes_to_send++;
+       }
+-      writel_relaxed(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG);
++      writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG);
+       qcom_geni_serial_setup_tx(uport, bytes_to_send);
+       for (i = 0; i < count; ) {
+               size_t chars_to_write = 0;
+@@ -423,7 +413,7 @@ __qcom_geni_serial_console_write(struct uart_port *uport, const char *s,
+               chars_to_write = min_t(size_t, count - i, avail / 2);
+               uart_console_write(uport, s + i, chars_to_write,
+                                               qcom_geni_serial_wr_char);
+-              writel_relaxed(M_TX_FIFO_WATERMARK_EN, uport->membase +
++              writel(M_TX_FIFO_WATERMARK_EN, uport->membase +
+                                                       SE_GENI_M_IRQ_CLEAR);
+               i += chars_to_write;
+       }
+@@ -452,7 +442,7 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
+       else
+               spin_lock_irqsave(&uport->lock, flags);
+-      geni_status = readl_relaxed(uport->membase + SE_GENI_STATUS);
++      geni_status = readl(uport->membase + SE_GENI_STATUS);
+       /* Cancel the current write to log the fault */
+       if (!locked) {
+@@ -462,11 +452,10 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
+                       geni_se_abort_m_cmd(&port->se);
+                       qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
+                                                       M_CMD_ABORT_EN, true);
+-                      writel_relaxed(M_CMD_ABORT_EN, uport->membase +
++                      writel(M_CMD_ABORT_EN, uport->membase +
+                                                       SE_GENI_M_IRQ_CLEAR);
+               }
+-              writel_relaxed(M_CMD_CANCEL_EN, uport->membase +
+-                                                      SE_GENI_M_IRQ_CLEAR);
++              writel(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
+       } else if ((geni_status & M_GENI_CMD_ACTIVE) && !port->tx_remaining) {
+               /*
+                * It seems we can't interrupt existing transfers if all data
+@@ -475,9 +464,8 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
+               qcom_geni_serial_poll_tx_done(uport);
+               if (uart_circ_chars_pending(&uport->state->xmit)) {
+-                      irq_en = readl_relaxed(uport->membase +
+-                                      SE_GENI_M_IRQ_EN);
+-                      writel_relaxed(irq_en | M_TX_FIFO_WATERMARK_EN,
++                      irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
++                      writel(irq_en | M_TX_FIFO_WATERMARK_EN,
+                                       uport->membase + SE_GENI_M_IRQ_EN);
+               }
+       }
+@@ -580,12 +568,12 @@ static void qcom_geni_serial_start_tx(struct uart_port *uport)
+               if (!qcom_geni_serial_tx_empty(uport))
+                       return;
+-              irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
++              irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+               irq_en |= M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN;
+-              writel_relaxed(port->tx_wm, uport->membase +
++              writel(port->tx_wm, uport->membase +
+                                               SE_GENI_TX_WATERMARK_REG);
+-              writel_relaxed(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
++              writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
+       }
+ }
+@@ -595,35 +583,28 @@ static void qcom_geni_serial_stop_tx(struct uart_port *uport)
+       u32 status;
+       struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
+-      irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
++      irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+       irq_en &= ~M_CMD_DONE_EN;
+       if (port->xfer_mode == GENI_SE_FIFO) {
+               irq_en &= ~M_TX_FIFO_WATERMARK_EN;
+-              writel_relaxed(0, uport->membase +
++              writel(0, uport->membase +
+                                    SE_GENI_TX_WATERMARK_REG);
+       }
+-      writel_relaxed(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
+-      status = readl_relaxed(uport->membase + SE_GENI_STATUS);
++      writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
++      status = readl(uport->membase + SE_GENI_STATUS);
+       /* Possible stop tx is called multiple times. */
+       if (!(status & M_GENI_CMD_ACTIVE))
+               return;
+-      /*
+-       * Ensure cancel command write is not re-ordered before checking
+-       * the status of the Primary Sequencer.
+-       */
+-      mb();
+-
+       geni_se_cancel_m_cmd(&port->se);
+       if (!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
+                                               M_CMD_CANCEL_EN, true)) {
+               geni_se_abort_m_cmd(&port->se);
+               qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS,
+                                               M_CMD_ABORT_EN, true);
+-              writel_relaxed(M_CMD_ABORT_EN, uport->membase +
+-                                                      SE_GENI_M_IRQ_CLEAR);
++              writel(M_CMD_ABORT_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
+       }
+-      writel_relaxed(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
++      writel(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR);
+ }
+ static void qcom_geni_serial_start_rx(struct uart_port *uport)
+@@ -632,26 +613,20 @@ static void qcom_geni_serial_start_rx(struct uart_port *uport)
+       u32 status;
+       struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
+-      status = readl_relaxed(uport->membase + SE_GENI_STATUS);
++      status = readl(uport->membase + SE_GENI_STATUS);
+       if (status & S_GENI_CMD_ACTIVE)
+               qcom_geni_serial_stop_rx(uport);
+-      /*
+-       * Ensure setup command write is not re-ordered before checking
+-       * the status of the Secondary Sequencer.
+-       */
+-      mb();
+-
+       geni_se_setup_s_cmd(&port->se, UART_START_READ, 0);
+       if (port->xfer_mode == GENI_SE_FIFO) {
+-              irq_en = readl_relaxed(uport->membase + SE_GENI_S_IRQ_EN);
++              irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN);
+               irq_en |= S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN;
+-              writel_relaxed(irq_en, uport->membase + SE_GENI_S_IRQ_EN);
++              writel(irq_en, uport->membase + SE_GENI_S_IRQ_EN);
+-              irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
++              irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+               irq_en |= M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN;
+-              writel_relaxed(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
++              writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
+       }
+ }
+@@ -663,31 +638,25 @@ static void qcom_geni_serial_stop_rx(struct uart_port *uport)
+       u32 irq_clear = S_CMD_DONE_EN;
+       if (port->xfer_mode == GENI_SE_FIFO) {
+-              irq_en = readl_relaxed(uport->membase + SE_GENI_S_IRQ_EN);
++              irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN);
+               irq_en &= ~(S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN);
+-              writel_relaxed(irq_en, uport->membase + SE_GENI_S_IRQ_EN);
++              writel(irq_en, uport->membase + SE_GENI_S_IRQ_EN);
+-              irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
++              irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+               irq_en &= ~(M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
+-              writel_relaxed(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
++              writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
+       }
+-      status = readl_relaxed(uport->membase + SE_GENI_STATUS);
++      status = readl(uport->membase + SE_GENI_STATUS);
+       /* Possible stop rx is called multiple times. */
+       if (!(status & S_GENI_CMD_ACTIVE))
+               return;
+-      /*
+-       * Ensure cancel command write is not re-ordered before checking
+-       * the status of the Secondary Sequencer.
+-       */
+-      mb();
+-
+       geni_se_cancel_s_cmd(&port->se);
+       qcom_geni_serial_poll_bit(uport, SE_GENI_S_CMD_CTRL_REG,
+                                       S_GENI_CMD_CANCEL, false);
+-      status = readl_relaxed(uport->membase + SE_GENI_STATUS);
+-      writel_relaxed(irq_clear, uport->membase + SE_GENI_S_IRQ_CLEAR);
++      status = readl(uport->membase + SE_GENI_STATUS);
++      writel(irq_clear, uport->membase + SE_GENI_S_IRQ_CLEAR);
+       if (status & S_GENI_CMD_ACTIVE)
+               qcom_geni_serial_abort_rx(uport);
+ }
+@@ -701,7 +670,7 @@ static void qcom_geni_serial_handle_rx(struct uart_port *uport, bool drop)
+       u32 total_bytes;
+       struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
+-      status = readl_relaxed(uport->membase + SE_GENI_RX_FIFO_STATUS);
++      status = readl(uport->membase + SE_GENI_RX_FIFO_STATUS);
+       word_cnt = status & RX_FIFO_WC_MSK;
+       last_word_partial = status & RX_LAST;
+       last_word_byte_cnt = (status & RX_LAST_BYTE_VALID_MSK) >>
+@@ -731,7 +700,7 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
+       unsigned int chunk;
+       int tail;
+-      status = readl_relaxed(uport->membase + SE_GENI_TX_FIFO_STATUS);
++      status = readl(uport->membase + SE_GENI_TX_FIFO_STATUS);
+       /* Complete the current tx command before taking newly added data */
+       if (active)
+@@ -757,9 +726,9 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
+               qcom_geni_serial_setup_tx(uport, pending);
+               port->tx_remaining = pending;
+-              irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
++              irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+               if (!(irq_en & M_TX_FIFO_WATERMARK_EN))
+-                      writel_relaxed(irq_en | M_TX_FIFO_WATERMARK_EN,
++                      writel(irq_en | M_TX_FIFO_WATERMARK_EN,
+                                       uport->membase + SE_GENI_M_IRQ_EN);
+       }
+@@ -790,14 +759,14 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
+        * cleared it in qcom_geni_serial_isr it will have already reasserted
+        * so we must clear it again here after our writes.
+        */
+-      writel_relaxed(M_TX_FIFO_WATERMARK_EN,
++      writel(M_TX_FIFO_WATERMARK_EN,
+                       uport->membase + SE_GENI_M_IRQ_CLEAR);
+ out_write_wakeup:
+       if (!port->tx_remaining) {
+-              irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
++              irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+               if (irq_en & M_TX_FIFO_WATERMARK_EN)
+-                      writel_relaxed(irq_en & ~M_TX_FIFO_WATERMARK_EN,
++                      writel(irq_en & ~M_TX_FIFO_WATERMARK_EN,
+                                       uport->membase + SE_GENI_M_IRQ_EN);
+       }
+@@ -821,12 +790,12 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
+               return IRQ_NONE;
+       spin_lock_irqsave(&uport->lock, flags);
+-      m_irq_status = readl_relaxed(uport->membase + SE_GENI_M_IRQ_STATUS);
+-      s_irq_status = readl_relaxed(uport->membase + SE_GENI_S_IRQ_STATUS);
+-      geni_status = readl_relaxed(uport->membase + SE_GENI_STATUS);
+-      m_irq_en = readl_relaxed(uport->membase + SE_GENI_M_IRQ_EN);
+-      writel_relaxed(m_irq_status, uport->membase + SE_GENI_M_IRQ_CLEAR);
+-      writel_relaxed(s_irq_status, uport->membase + SE_GENI_S_IRQ_CLEAR);
++      m_irq_status = readl(uport->membase + SE_GENI_M_IRQ_STATUS);
++      s_irq_status = readl(uport->membase + SE_GENI_S_IRQ_STATUS);
++      geni_status = readl(uport->membase + SE_GENI_STATUS);
++      m_irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
++      writel(m_irq_status, uport->membase + SE_GENI_M_IRQ_CLEAR);
++      writel(s_irq_status, uport->membase + SE_GENI_S_IRQ_CLEAR);
+       if (WARN_ON(m_irq_status & M_ILLEGAL_CMD_EN))
+               goto out_unlock;
+@@ -921,7 +890,7 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
+       get_tx_fifo_size(port);
+       set_rfr_wm(port);
+-      writel_relaxed(rxstale, uport->membase + SE_UART_RX_STALE_CNT);
++      writel(rxstale, uport->membase + SE_UART_RX_STALE_CNT);
+       /*
+        * Make an unconditional cancel on the main sequencer to reset
+        * it else we could end up in data loss scenarios.
+@@ -1025,10 +994,10 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
+       ser_clk_cfg |= clk_div << CLK_DIV_SHFT;
+       /* parity */
+-      tx_trans_cfg = readl_relaxed(uport->membase + SE_UART_TX_TRANS_CFG);
+-      tx_parity_cfg = readl_relaxed(uport->membase + SE_UART_TX_PARITY_CFG);
+-      rx_trans_cfg = readl_relaxed(uport->membase + SE_UART_RX_TRANS_CFG);
+-      rx_parity_cfg = readl_relaxed(uport->membase + SE_UART_RX_PARITY_CFG);
++      tx_trans_cfg = readl(uport->membase + SE_UART_TX_TRANS_CFG);
++      tx_parity_cfg = readl(uport->membase + SE_UART_TX_PARITY_CFG);
++      rx_trans_cfg = readl(uport->membase + SE_UART_RX_TRANS_CFG);
++      rx_parity_cfg = readl(uport->membase + SE_UART_RX_PARITY_CFG);
+       if (termios->c_cflag & PARENB) {
+               tx_trans_cfg |= UART_TX_PAR_EN;
+               rx_trans_cfg |= UART_RX_PAR_EN;
+@@ -1084,17 +1053,17 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
+               uart_update_timeout(uport, termios->c_cflag, baud);
+       if (!uart_console(uport))
+-              writel_relaxed(port->loopback,
++              writel(port->loopback,
+                               uport->membase + SE_UART_LOOPBACK_CFG);
+-      writel_relaxed(tx_trans_cfg, uport->membase + SE_UART_TX_TRANS_CFG);
+-      writel_relaxed(tx_parity_cfg, uport->membase + SE_UART_TX_PARITY_CFG);
+-      writel_relaxed(rx_trans_cfg, uport->membase + SE_UART_RX_TRANS_CFG);
+-      writel_relaxed(rx_parity_cfg, uport->membase + SE_UART_RX_PARITY_CFG);
+-      writel_relaxed(bits_per_char, uport->membase + SE_UART_TX_WORD_LEN);
+-      writel_relaxed(bits_per_char, uport->membase + SE_UART_RX_WORD_LEN);
+-      writel_relaxed(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN);
+-      writel_relaxed(ser_clk_cfg, uport->membase + GENI_SER_M_CLK_CFG);
+-      writel_relaxed(ser_clk_cfg, uport->membase + GENI_SER_S_CLK_CFG);
++      writel(tx_trans_cfg, uport->membase + SE_UART_TX_TRANS_CFG);
++      writel(tx_parity_cfg, uport->membase + SE_UART_TX_PARITY_CFG);
++      writel(rx_trans_cfg, uport->membase + SE_UART_RX_TRANS_CFG);
++      writel(rx_parity_cfg, uport->membase + SE_UART_RX_PARITY_CFG);
++      writel(bits_per_char, uport->membase + SE_UART_TX_WORD_LEN);
++      writel(bits_per_char, uport->membase + SE_UART_RX_WORD_LEN);
++      writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN);
++      writel(ser_clk_cfg, uport->membase + GENI_SER_M_CLK_CFG);
++      writel(ser_clk_cfg, uport->membase + GENI_SER_S_CLK_CFG);
+ out_restart_rx:
+       qcom_geni_serial_start_rx(uport);
+ }
+@@ -1185,13 +1154,13 @@ static int __init qcom_geni_serial_earlycon_setup(struct earlycon_device *dev,
+       geni_se_init(&se, DEF_FIFO_DEPTH_WORDS / 2, DEF_FIFO_DEPTH_WORDS - 2);
+       geni_se_select_mode(&se, GENI_SE_FIFO);
+-      writel_relaxed(tx_trans_cfg, uport->membase + SE_UART_TX_TRANS_CFG);
+-      writel_relaxed(tx_parity_cfg, uport->membase + SE_UART_TX_PARITY_CFG);
+-      writel_relaxed(rx_trans_cfg, uport->membase + SE_UART_RX_TRANS_CFG);
+-      writel_relaxed(rx_parity_cfg, uport->membase + SE_UART_RX_PARITY_CFG);
+-      writel_relaxed(bits_per_char, uport->membase + SE_UART_TX_WORD_LEN);
+-      writel_relaxed(bits_per_char, uport->membase + SE_UART_RX_WORD_LEN);
+-      writel_relaxed(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN);
++      writel(tx_trans_cfg, uport->membase + SE_UART_TX_TRANS_CFG);
++      writel(tx_parity_cfg, uport->membase + SE_UART_TX_PARITY_CFG);
++      writel(rx_trans_cfg, uport->membase + SE_UART_RX_TRANS_CFG);
++      writel(rx_parity_cfg, uport->membase + SE_UART_RX_PARITY_CFG);
++      writel(bits_per_char, uport->membase + SE_UART_TX_WORD_LEN);
++      writel(bits_per_char, uport->membase + SE_UART_RX_WORD_LEN);
++      writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN);
+       dev->con->write = qcom_geni_serial_earlycon_write;
+       dev->con->setup = NULL;
+-- 
+2.20.1
+
diff --git a/queue-4.19/tty-serial-qcom_geni_serial-remove-xfer_mode-variabl.patch b/queue-4.19/tty-serial-qcom_geni_serial-remove-xfer_mode-variabl.patch
new file mode 100644 (file)
index 0000000..e774ddc
--- /dev/null
@@ -0,0 +1,151 @@
+From 916215111278a6268997e8e4f05354cea4412d1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Jan 2019 17:58:37 -0800
+Subject: tty: serial: qcom_geni_serial: Remove xfer_mode variable
+
+From: Ryan Case <ryandcase@chromium.org>
+
+[ Upstream commit bdc05a8a3f822ca0662464055f902faf760da6be ]
+
+The driver only supports FIFO mode so setting and checking this variable
+is unnecessary. If DMA support is ever added then such checks can be
+introduced.
+
+Signed-off-by: Ryan Case <ryandcase@chromium.org>
+Reviewed-by: Evan Green <evgreen@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/qcom_geni_serial.c | 67 ++++++++++-----------------
+ 1 file changed, 24 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
+index 080fa1d1ecbfd..4182129925dec 100644
+--- a/drivers/tty/serial/qcom_geni_serial.c
++++ b/drivers/tty/serial/qcom_geni_serial.c
+@@ -101,7 +101,6 @@ struct qcom_geni_serial_port {
+       u32 tx_fifo_depth;
+       u32 tx_fifo_width;
+       u32 rx_fifo_depth;
+-      enum geni_se_xfer_mode xfer_mode;
+       bool setup;
+       int (*handle_rx)(struct uart_port *uport, u32 bytes, bool drop);
+       unsigned int baud;
+@@ -547,29 +546,20 @@ static int handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop)
+ static void qcom_geni_serial_start_tx(struct uart_port *uport)
+ {
+       u32 irq_en;
+-      struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
+       u32 status;
+-      if (port->xfer_mode == GENI_SE_FIFO) {
+-              /*
+-               * readl ensures reading & writing of IRQ_EN register
+-               * is not re-ordered before checking the status of the
+-               * Serial Engine.
+-               */
+-              status = readl(uport->membase + SE_GENI_STATUS);
+-              if (status & M_GENI_CMD_ACTIVE)
+-                      return;
++      status = readl(uport->membase + SE_GENI_STATUS);
++      if (status & M_GENI_CMD_ACTIVE)
++              return;
+-              if (!qcom_geni_serial_tx_empty(uport))
+-                      return;
++      if (!qcom_geni_serial_tx_empty(uport))
++              return;
+-              irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+-              irq_en |= M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN;
++      irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
++      irq_en |= M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN;
+-              writel(DEF_TX_WM, uport->membase +
+-                                              SE_GENI_TX_WATERMARK_REG);
+-              writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
+-      }
++      writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG);
++      writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
+ }
+ static void qcom_geni_serial_stop_tx(struct uart_port *uport)
+@@ -579,12 +569,8 @@ static void qcom_geni_serial_stop_tx(struct uart_port *uport)
+       struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
+       irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+-      irq_en &= ~M_CMD_DONE_EN;
+-      if (port->xfer_mode == GENI_SE_FIFO) {
+-              irq_en &= ~M_TX_FIFO_WATERMARK_EN;
+-              writel(0, uport->membase +
+-                                   SE_GENI_TX_WATERMARK_REG);
+-      }
++      irq_en &= ~(M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN);
++      writel(0, uport->membase + SE_GENI_TX_WATERMARK_REG);
+       writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
+       status = readl(uport->membase + SE_GENI_STATUS);
+       /* Possible stop tx is called multiple times. */
+@@ -614,15 +600,13 @@ static void qcom_geni_serial_start_rx(struct uart_port *uport)
+       geni_se_setup_s_cmd(&port->se, UART_START_READ, 0);
+-      if (port->xfer_mode == GENI_SE_FIFO) {
+-              irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN);
+-              irq_en |= S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN;
+-              writel(irq_en, uport->membase + SE_GENI_S_IRQ_EN);
++      irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN);
++      irq_en |= S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN;
++      writel(irq_en, uport->membase + SE_GENI_S_IRQ_EN);
+-              irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+-              irq_en |= M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN;
+-              writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
+-      }
++      irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
++      irq_en |= M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN;
++      writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
+ }
+ static void qcom_geni_serial_stop_rx(struct uart_port *uport)
+@@ -632,15 +616,13 @@ static void qcom_geni_serial_stop_rx(struct uart_port *uport)
+       struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
+       u32 irq_clear = S_CMD_DONE_EN;
+-      if (port->xfer_mode == GENI_SE_FIFO) {
+-              irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN);
+-              irq_en &= ~(S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN);
+-              writel(irq_en, uport->membase + SE_GENI_S_IRQ_EN);
++      irq_en = readl(uport->membase + SE_GENI_S_IRQ_EN);
++      irq_en &= ~(S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN);
++      writel(irq_en, uport->membase + SE_GENI_S_IRQ_EN);
+-              irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+-              irq_en &= ~(M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
+-              writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
+-      }
++      irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
++      irq_en &= ~(M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
++      writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
+       status = readl(uport->membase + SE_GENI_STATUS);
+       /* Possible stop rx is called multiple times. */
+@@ -878,7 +860,6 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
+        * Make an unconditional cancel on the main sequencer to reset
+        * it else we could end up in data loss scenarios.
+        */
+-      port->xfer_mode = GENI_SE_FIFO;
+       if (uart_console(uport))
+               qcom_geni_serial_poll_tx_done(uport);
+       geni_se_config_packing(&port->se, BITS_PER_BYTE, port->tx_bytes_pw,
+@@ -886,7 +867,7 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
+       geni_se_config_packing(&port->se, BITS_PER_BYTE, port->rx_bytes_pw,
+                                               false, false, true);
+       geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2);
+-      geni_se_select_mode(&port->se, port->xfer_mode);
++      geni_se_select_mode(&port->se, GENI_SE_FIFO);
+       if (!uart_console(uport)) {
+               port->rx_fifo = devm_kcalloc(uport->dev,
+                       port->rx_fifo_depth, sizeof(u32), GFP_KERNEL);
+-- 
+2.20.1
+