]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.1
authorSasha Levin <sashal@kernel.org>
Wed, 21 Jun 2023 16:39:42 +0000 (12:39 -0400)
committerSasha Levin <sashal@kernel.org>
Wed, 21 Jun 2023 16:39:42 +0000 (12:39 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.1/ata-libata-scsi-avoid-deadlock-on-rescan-after-devic.patch [new file with mode: 0644]
queue-6.1/drm-amd-display-add-wrapper-to-call-planes-and-strea.patch [new file with mode: 0644]
queue-6.1/drm-amd-display-fix-the-system-hang-while-disable-ps.patch [new file with mode: 0644]
queue-6.1/drm-amd-display-use-dc_update_planes_and_stream.patch [new file with mode: 0644]
queue-6.1/series [new file with mode: 0644]
queue-6.1/tty-serial-fsl_lpuart-make-rx_watermark-configurable.patch [new file with mode: 0644]
queue-6.1/tty-serial-fsl_lpuart-reduce-rx-watermark-to-0-on-ls.patch [new file with mode: 0644]

diff --git a/queue-6.1/ata-libata-scsi-avoid-deadlock-on-rescan-after-devic.patch b/queue-6.1/ata-libata-scsi-avoid-deadlock-on-rescan-after-devic.patch
new file mode 100644 (file)
index 0000000..631b711
--- /dev/null
@@ -0,0 +1,143 @@
+From 27cab9fa2cdee6d12a88e50075a1ad6778c4be29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 17:18:53 +0900
+Subject: ata: libata-scsi: Avoid deadlock on rescan after device resume
+
+From: Damien Le Moal <dlemoal@kernel.org>
+
+[ Upstream commit 6aa0365a3c8512587fffd42fe438768709ddef8e ]
+
+When an ATA port is resumed from sleep, the port is reset and a power
+management request issued to libata EH to reset the port and rescanning
+the device(s) attached to the port. Device rescanning is done by
+scheduling an ata_scsi_dev_rescan() work, which will execute
+scsi_rescan_device().
+
+However, scsi_rescan_device() takes the generic device lock, which is
+also taken by dpm_resume() when the SCSI device is resumed as well. If
+a device rescan execution starts before the completion of the SCSI
+device resume, the rcu locking used to refresh the cached VPD pages of
+the device, combined with the generic device locking from
+scsi_rescan_device() and from dpm_resume() can cause a deadlock.
+
+Avoid this situation by changing struct ata_port scsi_rescan_task to be
+a delayed work instead of a simple work_struct. ata_scsi_dev_rescan() is
+modified to check if the SCSI device associated with the ATA device that
+must be rescanned is not suspended. If the SCSI device is still
+suspended, ata_scsi_dev_rescan() returns early and reschedule itself for
+execution after an arbitrary delay of 5ms.
+
+Reported-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Reported-by: Joe Breuer <linux-kernel@jmbreuer.net>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217530
+Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management")
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Tested-by: Joe Breuer <linux-kernel@jmbreuer.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/libata-core.c |  3 ++-
+ drivers/ata/libata-eh.c   |  2 +-
+ drivers/ata/libata-scsi.c | 22 +++++++++++++++++++++-
+ include/linux/libata.h    |  2 +-
+ 4 files changed, 25 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index a5ea144722fa3..0ba0c3d1613f1 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -5313,7 +5313,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
+       mutex_init(&ap->scsi_scan_mutex);
+       INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug);
+-      INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
++      INIT_DELAYED_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
+       INIT_LIST_HEAD(&ap->eh_done_q);
+       init_waitqueue_head(&ap->eh_wait_q);
+       init_completion(&ap->park_req_pending);
+@@ -5919,6 +5919,7 @@ static void ata_port_detach(struct ata_port *ap)
+       WARN_ON(!(ap->pflags & ATA_PFLAG_UNLOADED));
+       cancel_delayed_work_sync(&ap->hotplug_task);
++      cancel_delayed_work_sync(&ap->scsi_rescan_task);
+  skip_eh:
+       /* clean up zpodd on port removal */
+diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
+index 08e11bc312c28..a3ae5fc2a42fc 100644
+--- a/drivers/ata/libata-eh.c
++++ b/drivers/ata/libata-eh.c
+@@ -2973,7 +2973,7 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
+                       ehc->i.flags |= ATA_EHI_SETMODE;
+                       /* schedule the scsi_rescan_device() here */
+-                      schedule_work(&(ap->scsi_rescan_task));
++                      schedule_delayed_work(&ap->scsi_rescan_task, 0);
+               } else if (dev->class == ATA_DEV_UNKNOWN &&
+                          ehc->tries[dev->devno] &&
+                          ata_class_enabled(ehc->classes[dev->devno])) {
+diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
+index 39e1ff9b686b9..9c0052d28078a 100644
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -4601,10 +4601,11 @@ int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
+ void ata_scsi_dev_rescan(struct work_struct *work)
+ {
+       struct ata_port *ap =
+-              container_of(work, struct ata_port, scsi_rescan_task);
++              container_of(work, struct ata_port, scsi_rescan_task.work);
+       struct ata_link *link;
+       struct ata_device *dev;
+       unsigned long flags;
++      bool delay_rescan = false;
+       mutex_lock(&ap->scsi_scan_mutex);
+       spin_lock_irqsave(ap->lock, flags);
+@@ -4618,6 +4619,21 @@ void ata_scsi_dev_rescan(struct work_struct *work)
+                       if (scsi_device_get(sdev))
+                               continue;
++                      /*
++                       * If the rescan work was scheduled because of a resume
++                       * event, the port is already fully resumed, but the
++                       * SCSI device may not yet be fully resumed. In such
++                       * case, executing scsi_rescan_device() may cause a
++                       * deadlock with the PM code on device_lock(). Prevent
++                       * this by giving up and retrying rescan after a short
++                       * delay.
++                       */
++                      delay_rescan = sdev->sdev_gendev.power.is_suspended;
++                      if (delay_rescan) {
++                              scsi_device_put(sdev);
++                              break;
++                      }
++
+                       spin_unlock_irqrestore(ap->lock, flags);
+                       scsi_rescan_device(&(sdev->sdev_gendev));
+                       scsi_device_put(sdev);
+@@ -4627,4 +4643,8 @@ void ata_scsi_dev_rescan(struct work_struct *work)
+       spin_unlock_irqrestore(ap->lock, flags);
+       mutex_unlock(&ap->scsi_scan_mutex);
++
++      if (delay_rescan)
++              schedule_delayed_work(&ap->scsi_rescan_task,
++                                    msecs_to_jiffies(5));
+ }
+diff --git a/include/linux/libata.h b/include/linux/libata.h
+index fe990176e6ee9..9713f4d8f15f4 100644
+--- a/include/linux/libata.h
++++ b/include/linux/libata.h
+@@ -834,7 +834,7 @@ struct ata_port {
+       struct mutex            scsi_scan_mutex;
+       struct delayed_work     hotplug_task;
+-      struct work_struct      scsi_rescan_task;
++      struct delayed_work     scsi_rescan_task;
+       unsigned int            hsm_task_state;
+-- 
+2.39.2
+
diff --git a/queue-6.1/drm-amd-display-add-wrapper-to-call-planes-and-strea.patch b/queue-6.1/drm-amd-display-add-wrapper-to-call-planes-and-strea.patch
new file mode 100644 (file)
index 0000000..0e68cb6
--- /dev/null
@@ -0,0 +1,107 @@
+From 4643e048dfd25c91d15772d37f62acc642bd0060 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Feb 2023 11:36:08 -0700
+Subject: drm/amd/display: Add wrapper to call planes and stream update
+
+From: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+
+[ Upstream commit 81f743a08f3b214638aa389e252ae5e6c3592e7c ]
+
+[Why & How]
+This commit is part of a sequence of changes that replaces the commit
+sequence used in the DC with a new one. As a result of this transition,
+we moved some specific parts from the commit sequence and brought them
+to amdgpu_dm. This commit adds a wrapper inside DM that enable our
+drivers to do any necessary preparation or change before we offload the
+plane/stream update to DC.
+
+Reviewed-by: Harry Wentland <Harry.Wentland@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: ea2062dd1f03 ("drm/amd/display: fix the system hang while disable PSR")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 51 +++++++++++++++----
+ 1 file changed, 41 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index a7bc57529e6c9..91f074f4f262c 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -348,6 +348,35 @@ static inline bool is_dc_timing_adjust_needed(struct dm_crtc_state *old_state,
+               return false;
+ }
++/**
++ * update_planes_and_stream_adapter() - Send planes to be updated in DC
++ *
++ * DC has a generic way to update planes and stream via
++ * dc_update_planes_and_stream function; however, DM might need some
++ * adjustments and preparation before calling it. This function is a wrapper
++ * for the dc_update_planes_and_stream that does any required configuration
++ * before passing control to DC.
++ */
++static inline bool update_planes_and_stream_adapter(struct dc *dc,
++                                                  int update_type,
++                                                  int planes_count,
++                                                  struct dc_stream_state *stream,
++                                                  struct dc_stream_update *stream_update,
++                                                  struct dc_surface_update *array_of_surface_update)
++{
++      /*
++       * Previous frame finished and HW is ready for optimization.
++       */
++      if (update_type == UPDATE_TYPE_FAST)
++              dc_post_update_surfaces_to_stream(dc);
++
++      return dc_update_planes_and_stream(dc,
++                                         array_of_surface_update,
++                                         planes_count,
++                                         stream,
++                                         stream_update);
++}
++
+ /**
+  * dm_pflip_high_irq() - Handle pageflip interrupt
+  * @interrupt_params: ignored
+@@ -2633,11 +2662,12 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state,
+                               true;
+               }
+-              dc_update_planes_and_stream(dm->dc,
+-                      bundle->surface_updates,
+-                      dc_state->stream_status->plane_count,
+-                      dc_state->streams[k],
+-                      &bundle->stream_update);
++              update_planes_and_stream_adapter(dm->dc,
++                                       UPDATE_TYPE_FULL,
++                                       dc_state->stream_status->plane_count,
++                                       dc_state->streams[k],
++                                       &bundle->stream_update,
++                                       bundle->surface_updates);
+       }
+ cleanup:
+@@ -7889,11 +7919,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+                               acrtc_state->stream->link->psr_settings.psr_allow_active)
+                       amdgpu_dm_psr_disable(acrtc_state->stream);
+-              dc_update_planes_and_stream(dm->dc,
+-                                          bundle->surface_updates,
+-                                          planes_count,
+-                                          acrtc_state->stream,
+-                                          &bundle->stream_update);
++              update_planes_and_stream_adapter(dm->dc,
++                                       acrtc_state->update_type,
++                                       planes_count,
++                                       acrtc_state->stream,
++                                       &bundle->stream_update,
++                                       bundle->surface_updates);
+               /**
+                * Enable or disable the interrupts on the backend.
+-- 
+2.39.2
+
diff --git a/queue-6.1/drm-amd-display-fix-the-system-hang-while-disable-ps.patch b/queue-6.1/drm-amd-display-fix-the-system-hang-while-disable-ps.patch
new file mode 100644 (file)
index 0000000..ce35d03
--- /dev/null
@@ -0,0 +1,61 @@
+From 4f8cdc5fed65ebd746232fac1a98a98be8f684d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 May 2023 18:00:09 +0800
+Subject: drm/amd/display: fix the system hang while disable PSR
+
+From: Tom Chung <chiahsuan.chung@amd.com>
+
+[ Upstream commit ea2062dd1f0384ae1b136d333ee4ced15bedae38 ]
+
+[Why]
+When the PSR enabled. If you try to adjust the timing parameters,
+it may cause system hang. Because the timing mismatch with the
+DMCUB settings.
+
+[How]
+Disable the PSR before adjusting timing parameters.
+
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Acked-by: Stylon Wang <stylon.wang@amd.com>
+Signed-off-by: Tom Chung <chiahsuan.chung@amd.com>
+Reviewed-by: Wayne Lin <Wayne.Lin@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 91f074f4f262c..91c308cf27eb2 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -7902,6 +7902,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+               if (acrtc_state->abm_level != dm_old_crtc_state->abm_level)
+                       bundle->stream_update.abm_level = &acrtc_state->abm_level;
++              mutex_lock(&dm->dc_lock);
++              if ((acrtc_state->update_type > UPDATE_TYPE_FAST) &&
++                              acrtc_state->stream->link->psr_settings.psr_allow_active)
++                      amdgpu_dm_psr_disable(acrtc_state->stream);
++              mutex_unlock(&dm->dc_lock);
++
+               /*
+                * If FreeSync state on the stream has changed then we need to
+                * re-adjust the min/max bounds now that DC doesn't handle this
+@@ -7915,10 +7921,6 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+                       spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags);
+               }
+               mutex_lock(&dm->dc_lock);
+-              if ((acrtc_state->update_type > UPDATE_TYPE_FAST) &&
+-                              acrtc_state->stream->link->psr_settings.psr_allow_active)
+-                      amdgpu_dm_psr_disable(acrtc_state->stream);
+-
+               update_planes_and_stream_adapter(dm->dc,
+                                        acrtc_state->update_type,
+                                        planes_count,
+-- 
+2.39.2
+
diff --git a/queue-6.1/drm-amd-display-use-dc_update_planes_and_stream.patch b/queue-6.1/drm-amd-display-use-dc_update_planes_and_stream.patch
new file mode 100644 (file)
index 0000000..447e58e
--- /dev/null
@@ -0,0 +1,87 @@
+From 64f7536f7557f7c03a70c90464cbfea220c87ee6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Oct 2022 16:40:55 -0400
+Subject: drm/amd/display: Use dc_update_planes_and_stream
+
+From: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+
+[ Upstream commit f7511289821ffccc07579406d6ab520aa11049f5 ]
+
+[Why & How]
+The old dc_commit_updates_for_stream lacks manipulation for many corner
+cases where the DC feature requires special attention; as a result, it
+starts to show its limitation (e.g., the SubVP feature is not supported
+by it, among other cases). To modernize and unify our internal API, this
+commit replaces the old dc_commit_updates_for_stream with
+dc_update_planes_and_stream, which has more features.
+
+Reviewed-by: Harry Wentland <Harry.Wentland@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: ea2062dd1f03 ("drm/amd/display: fix the system hang while disable PSR")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 30 +++++++++----------
+ 1 file changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 53687de6c0530..a7bc57529e6c9 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -2632,10 +2632,12 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state,
+                       bundle->surface_updates[m].surface->force_full_update =
+                               true;
+               }
+-              dc_commit_updates_for_stream(
+-                      dm->dc, bundle->surface_updates,
++
++              dc_update_planes_and_stream(dm->dc,
++                      bundle->surface_updates,
+                       dc_state->stream_status->plane_count,
+-                      dc_state->streams[k], &bundle->stream_update, dc_state);
++                      dc_state->streams[k],
++                      &bundle->stream_update);
+       }
+ cleanup:
+@@ -7887,12 +7889,11 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+                               acrtc_state->stream->link->psr_settings.psr_allow_active)
+                       amdgpu_dm_psr_disable(acrtc_state->stream);
+-              dc_commit_updates_for_stream(dm->dc,
+-                                                   bundle->surface_updates,
+-                                                   planes_count,
+-                                                   acrtc_state->stream,
+-                                                   &bundle->stream_update,
+-                                                   dc_state);
++              dc_update_planes_and_stream(dm->dc,
++                                          bundle->surface_updates,
++                                          planes_count,
++                                          acrtc_state->stream,
++                                          &bundle->stream_update);
+               /**
+                * Enable or disable the interrupts on the backend.
+@@ -8334,12 +8335,11 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+               mutex_lock(&dm->dc_lock);
+-              dc_commit_updates_for_stream(dm->dc,
+-                                                   dummy_updates,
+-                                                   status->plane_count,
+-                                                   dm_new_crtc_state->stream,
+-                                                   &stream_update,
+-                                                   dc_state);
++              dc_update_planes_and_stream(dm->dc,
++                                          dummy_updates,
++                                          status->plane_count,
++                                          dm_new_crtc_state->stream,
++                                          &stream_update);
+               mutex_unlock(&dm->dc_lock);
+       }
+-- 
+2.39.2
+
diff --git a/queue-6.1/series b/queue-6.1/series
new file mode 100644 (file)
index 0000000..c212c16
--- /dev/null
@@ -0,0 +1,6 @@
+drm-amd-display-use-dc_update_planes_and_stream.patch
+drm-amd-display-add-wrapper-to-call-planes-and-strea.patch
+drm-amd-display-fix-the-system-hang-while-disable-ps.patch
+tty-serial-fsl_lpuart-make-rx_watermark-configurable.patch
+tty-serial-fsl_lpuart-reduce-rx-watermark-to-0-on-ls.patch
+ata-libata-scsi-avoid-deadlock-on-rescan-after-devic.patch
diff --git a/queue-6.1/tty-serial-fsl_lpuart-make-rx_watermark-configurable.patch b/queue-6.1/tty-serial-fsl_lpuart-make-rx_watermark-configurable.patch
new file mode 100644 (file)
index 0000000..db32b91
--- /dev/null
@@ -0,0 +1,111 @@
+From 188f738da662b7eee811bf53bec71cd8a543bc18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Jan 2023 14:44:44 +0800
+Subject: tty: serial: fsl_lpuart: make rx_watermark configurable for different
+ platforms
+
+From: Sherry Sun <sherry.sun@nxp.com>
+
+[ Upstream commit 34ebb26f12a84b744f43c5c4869516f122a2dfaa ]
+
+Add rx_watermark parameter for struct lpuart_port to make the receive
+watermark configurable for different platforms.
+No function changed.
+
+Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
+Link: https://lore.kernel.org/r/20230130064449.9564-2-sherry.sun@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a82c3df955f8 ("tty: serial: fsl_lpuart: reduce RX watermark to 0 on LS1028A")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/fsl_lpuart.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
+index dc7ac1ddbca5e..82066f17bdfb1 100644
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -257,6 +257,7 @@ struct lpuart_port {
+       unsigned int            txfifo_size;
+       unsigned int            rxfifo_size;
++      u8                      rx_watermark;
+       bool                    lpuart_dma_tx_use;
+       bool                    lpuart_dma_rx_use;
+       struct dma_chan         *dma_tx_chan;
+@@ -283,38 +284,45 @@ struct lpuart_soc_data {
+       enum lpuart_type devtype;
+       char iotype;
+       u8 reg_off;
++      u8 rx_watermark;
+ };
+ static const struct lpuart_soc_data vf_data = {
+       .devtype = VF610_LPUART,
+       .iotype = UPIO_MEM,
++      .rx_watermark = 1,
+ };
+ static const struct lpuart_soc_data ls1021a_data = {
+       .devtype = LS1021A_LPUART,
+       .iotype = UPIO_MEM32BE,
++      .rx_watermark = 1,
+ };
+ static const struct lpuart_soc_data ls1028a_data = {
+       .devtype = LS1028A_LPUART,
+       .iotype = UPIO_MEM32,
++      .rx_watermark = 1,
+ };
+ static struct lpuart_soc_data imx7ulp_data = {
+       .devtype = IMX7ULP_LPUART,
+       .iotype = UPIO_MEM32,
+       .reg_off = IMX_REG_OFF,
++      .rx_watermark = 1,
+ };
+ static struct lpuart_soc_data imx8qxp_data = {
+       .devtype = IMX8QXP_LPUART,
+       .iotype = UPIO_MEM32,
+       .reg_off = IMX_REG_OFF,
++      .rx_watermark = 1,
+ };
+ static struct lpuart_soc_data imxrt1050_data = {
+       .devtype = IMXRT1050_LPUART,
+       .iotype = UPIO_MEM32,
+       .reg_off = IMX_REG_OFF,
++      .rx_watermark = 1,
+ };
+ static const struct of_device_id lpuart_dt_ids[] = {
+@@ -1533,7 +1541,7 @@ static void lpuart_setup_watermark(struct lpuart_port *sport)
+       }
+       writeb(0, sport->port.membase + UARTTWFIFO);
+-      writeb(1, sport->port.membase + UARTRWFIFO);
++      writeb(sport->rx_watermark, sport->port.membase + UARTRWFIFO);
+       /* Restore cr2 */
+       writeb(cr2_saved, sport->port.membase + UARTCR2);
+@@ -1568,7 +1576,8 @@ static void lpuart32_setup_watermark(struct lpuart_port *sport)
+       lpuart32_write(&sport->port, val, UARTFIFO);
+       /* set the watermark */
+-      val = (0x1 << UARTWATER_RXWATER_OFF) | (0x0 << UARTWATER_TXWATER_OFF);
++      val = (sport->rx_watermark << UARTWATER_RXWATER_OFF) |
++            (0x0 << UARTWATER_TXWATER_OFF);
+       lpuart32_write(&sport->port, val, UARTWATER);
+       /* Restore cr2 */
+@@ -2714,6 +2723,7 @@ static int lpuart_probe(struct platform_device *pdev)
+       sport->port.dev = &pdev->dev;
+       sport->port.type = PORT_LPUART;
+       sport->devtype = sdata->devtype;
++      sport->rx_watermark = sdata->rx_watermark;
+       ret = platform_get_irq(pdev, 0);
+       if (ret < 0)
+               return ret;
+-- 
+2.39.2
+
diff --git a/queue-6.1/tty-serial-fsl_lpuart-reduce-rx-watermark-to-0-on-ls.patch b/queue-6.1/tty-serial-fsl_lpuart-reduce-rx-watermark-to-0-on-ls.patch
new file mode 100644 (file)
index 0000000..d106b49
--- /dev/null
@@ -0,0 +1,46 @@
+From aba04d59fa845ed313893f76f1bed54852391059 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jun 2023 14:13:34 +0200
+Subject: tty: serial: fsl_lpuart: reduce RX watermark to 0 on LS1028A
+
+From: Robert Hodaszi <robert.hodaszi@digi.com>
+
+[ Upstream commit a82c3df955f8c1c726e4976527aa6ae924a67dd9 ]
+
+LS1028A is using DMA with LPUART. Having RX watermark set to 1, means
+DMA transactions are started only after receiving the second character.
+
+On other platforms with newer LPUART IP, Receiver Idle Empty function
+initiates the DMA request after the receiver is idling for 4 characters.
+But this feature is missing on LS1028A, which is causing a 1-character
+delay in the RX direction on this platform.
+
+Set RX watermark to 0 to initiate RX DMA after each character.
+
+Link: https://lore.kernel.org/linux-serial/20230607103459.1222426-1-robert.hodaszi@digi.com/
+Fixes: 9ad9df844754 ("tty: serial: fsl_lpuart: Fix the wrong RXWATER setting for rx dma case")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Robert Hodaszi <robert.hodaszi@digi.com>
+Message-ID: <20230609121334.1878626-1-robert.hodaszi@digi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/fsl_lpuart.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
+index 82066f17bdfb1..1093c74b52840 100644
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -302,7 +302,7 @@ static const struct lpuart_soc_data ls1021a_data = {
+ static const struct lpuart_soc_data ls1028a_data = {
+       .devtype = LS1028A_LPUART,
+       .iotype = UPIO_MEM32,
+-      .rx_watermark = 1,
++      .rx_watermark = 0,
+ };
+ static struct lpuart_soc_data imx7ulp_data = {
+-- 
+2.39.2
+