]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.12
authorSasha Levin <sashal@kernel.org>
Sat, 8 Mar 2025 14:08:42 +0000 (09:08 -0500)
committerSasha Levin <sashal@kernel.org>
Sat, 8 Mar 2025 14:08:42 +0000 (09:08 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.12/btrfs-fix-data-overwriting-bug-during-buffered-write.patch [new file with mode: 0644]
queue-6.12/cifs-remove-symlink-member-from-cifs_open_info_data-.patch [new file with mode: 0644]
queue-6.12/drm-i915-dsi-convert-to-struct-intel_display.patch [new file with mode: 0644]
queue-6.12/drm-i915-dsi-use-trans_ddi_func_ctl-s-own-port-width.patch [new file with mode: 0644]
queue-6.12/gpio-vf610-add-locking-to-gpio-direction-functions.patch [new file with mode: 0644]
queue-6.12/gpio-vf610-use-generic-device_get_match_data.patch [new file with mode: 0644]
queue-6.12/series
queue-6.12/smb311-failure-to-open-files-of-length-1040-when-mou.patch [new file with mode: 0644]

diff --git a/queue-6.12/btrfs-fix-data-overwriting-bug-during-buffered-write.patch b/queue-6.12/btrfs-fix-data-overwriting-bug-during-buffered-write.patch
new file mode 100644 (file)
index 0000000..df7f61e
--- /dev/null
@@ -0,0 +1,149 @@
+From 6226abdef75084708ec8ed2a2af6d774f6d227b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Feb 2025 09:06:33 +1030
+Subject: btrfs: fix data overwriting bug during buffered write when block size
+ < page size
+
+From: Qu Wenruo <wqu@suse.com>
+
+[ Upstream commit efa11fd269c139e29b71ec21bc9c9c0063fde40d ]
+
+[BUG]
+When running generic/418 with a btrfs whose block size < page size
+(subpage cases), it always fails.
+
+And the following minimal reproducer is more than enough to trigger it
+reliably:
+
+workload()
+{
+        mkfs.btrfs -s 4k -f $dev > /dev/null
+        dmesg -C
+        mount $dev $mnt
+        $fsstree_dir/src/dio-invalidate-cache -r -b 4096 -n 3 -i 1 -f $mnt/diotest
+        ret=$?
+        umount $mnt
+        stop_trace
+        if [ $ret -ne 0 ]; then
+                fail
+        fi
+}
+
+for (( i = 0; i < 1024; i++)); do
+        echo "=== $i/$runtime ==="
+        workload
+done
+
+[CAUSE]
+With extra trace printk added to the following functions:
+- btrfs_buffered_write()
+  * Which folio is touched
+  * The file offset (start) where the buffered write is at
+  * How many bytes are copied
+  * The content of the write (the first 2 bytes)
+
+- submit_one_sector()
+  * Which folio is touched
+  * The position inside the folio
+  * The content of the page cache (the first 2 bytes)
+
+- pagecache_isize_extended()
+  * The parameters of the function itself
+  * The parameters of the folio_zero_range()
+
+Which are enough to show the problem:
+
+  22.158114: btrfs_buffered_write: folio pos=0 start=0 copied=4096 content=0x0101
+  22.158161: submit_one_sector: r/i=5/257 folio=0 pos=0 content=0x0101
+  22.158609: btrfs_buffered_write: folio pos=0 start=4096 copied=4096 content=0x0101
+  22.158634: btrfs_buffered_write: folio pos=0 start=8192 copied=4096 content=0x0101
+  22.158650: pagecache_isize_extended: folio=0 from=4096 to=8192 bsize=4096 zero off=4096 len=8192
+  22.158682: submit_one_sector: r/i=5/257 folio=0 pos=4096 content=0x0000
+  22.158686: submit_one_sector: r/i=5/257 folio=0 pos=8192 content=0x0101
+
+The tool dio-invalidate-cache will start 3 threads, each doing a buffered
+write with 0x01 at offset 0, 4096 and 8192, do a fsync, then do a direct read,
+and compare the read buffer with the write buffer.
+
+Note that all 3 btrfs_buffered_write() are writing the correct 0x01 into
+the page cache.
+
+But at submit_one_sector(), at file offset 4096, the content is zeroed
+out, by pagecache_isize_extended().
+
+The race happens like this:
+ Thread A is writing into range [4K, 8K).
+ Thread B is writing into range [8K, 12k).
+
+               Thread A              |         Thread B
+-------------------------------------+------------------------------------
+btrfs_buffered_write()               | btrfs_buffered_write()
+|- old_isize = 4K;                   | |- old_isize = 4096;
+|- btrfs_inode_lock()                | |
+|- write into folio range [4K, 8K)   | |
+|- pagecache_isize_extended()        | |
+|  extend isize from 4096 to 8192    | |
+|  no folio_zero_range() called      | |
+|- btrfs_inode_lock()                | |
+                                     | |- btrfs_inode_lock()
+                                    | |- write into folio range [8K, 12K)
+                                    | |- pagecache_isize_extended()
+                                    | |  calling folio_zero_range(4K, 8K)
+                                    | |  This is caused by the old_isize is
+                                    | |  grabbed too early, without any
+                                    | |  inode lock.
+                                    | |- btrfs_inode_unlock()
+
+The @old_isize is grabbed without inode lock, causing race between two
+buffered write threads and making pagecache_isize_extended() to zero
+range which is still containing cached data.
+
+And this is only affecting subpage btrfs, because for regular blocksize
+== page size case, the function pagecache_isize_extended() will do
+nothing if the block size >= page size.
+
+[FIX]
+Grab the old i_size while holding the inode lock.
+This means each buffered write thread will have a stable view of the
+old inode size, thus avoid the above race.
+
+CC: stable@vger.kernel.org # 5.15+
+Fixes: 5e8b9ef30392 ("btrfs: move pos increment and pagecache extension to btrfs_buffered_write")
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/file.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
+index 848cb2c3d9dde..78c4a3765002e 100644
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -1200,7 +1200,7 @@ ssize_t btrfs_buffered_write(struct kiocb *iocb, struct iov_iter *i)
+       ssize_t ret;
+       bool only_release_metadata = false;
+       bool force_page_uptodate = false;
+-      loff_t old_isize = i_size_read(inode);
++      loff_t old_isize;
+       unsigned int ilock_flags = 0;
+       const bool nowait = (iocb->ki_flags & IOCB_NOWAIT);
+       unsigned int bdp_flags = (nowait ? BDP_ASYNC : 0);
+@@ -1212,6 +1212,13 @@ ssize_t btrfs_buffered_write(struct kiocb *iocb, struct iov_iter *i)
+       if (ret < 0)
+               return ret;
++      /*
++       * We can only trust the isize with inode lock held, or it can race with
++       * other buffered writes and cause incorrect call of
++       * pagecache_isize_extended() to overwrite existing data.
++       */
++      old_isize = i_size_read(inode);
++
+       ret = generic_write_checks(iocb, i);
+       if (ret <= 0)
+               goto out;
+-- 
+2.39.5
+
diff --git a/queue-6.12/cifs-remove-symlink-member-from-cifs_open_info_data-.patch b/queue-6.12/cifs-remove-symlink-member-from-cifs_open_info_data-.patch
new file mode 100644 (file)
index 0000000..b4f928d
--- /dev/null
@@ -0,0 +1,82 @@
+From a85a6faca69142a7fddbd0fd0eba6377fdf0f705 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Dec 2024 14:50:38 +0100
+Subject: cifs: Remove symlink member from cifs_open_info_data union
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit 65c49767dd4fc058673f9259fda1772fd398eaa7 ]
+
+Member 'symlink' is part of the union in struct cifs_open_info_data. Its
+value is assigned on few places, but is always read through another union
+member 'reparse_point'. So to make code more readable, always use only
+'reparse_point' member and drop whole union structure. No function change.
+
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Acked-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 9df23801c83d ("smb311: failure to open files of length 1040 when mounting with SMB3.1.1 POSIX extensions")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/cifsglob.h | 5 +----
+ fs/smb/client/inode.c    | 2 +-
+ fs/smb/client/smb1ops.c  | 4 ++--
+ 3 files changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
+index 05274121e46f0..0979feb30bedb 100644
+--- a/fs/smb/client/cifsglob.h
++++ b/fs/smb/client/cifsglob.h
+@@ -209,10 +209,7 @@ struct cifs_cred {
+ struct cifs_open_info_data {
+       bool adjust_tz;
+-      union {
+-              bool reparse_point;
+-              bool symlink;
+-      };
++      bool reparse_point;
+       struct {
+               /* ioctl response buffer */
+               struct {
+diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
+index e11e67af760f4..a3f0835e12be3 100644
+--- a/fs/smb/client/inode.c
++++ b/fs/smb/client/inode.c
+@@ -968,7 +968,7 @@ cifs_get_file_info(struct file *filp)
+               /* TODO: add support to query reparse tag */
+               data.adjust_tz = false;
+               if (data.symlink_target) {
+-                      data.symlink = true;
++                      data.reparse_point = true;
+                       data.reparse.tag = IO_REPARSE_TAG_SYMLINK;
+               }
+               path = build_path_from_dentry(dentry, page);
+diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
+index c70f4961c4eb7..bd791aa54681f 100644
+--- a/fs/smb/client/smb1ops.c
++++ b/fs/smb/client/smb1ops.c
+@@ -551,7 +551,7 @@ static int cifs_query_path_info(const unsigned int xid,
+       int rc;
+       FILE_ALL_INFO fi = {};
+-      data->symlink = false;
++      data->reparse_point = false;
+       data->adjust_tz = false;
+       /* could do find first instead but this returns more info */
+@@ -592,7 +592,7 @@ static int cifs_query_path_info(const unsigned int xid,
+               /* Need to check if this is a symbolic link or not */
+               tmprc = CIFS_open(xid, &oparms, &oplock, NULL);
+               if (tmprc == -EOPNOTSUPP)
+-                      data->symlink = true;
++                      data->reparse_point = true;
+               else if (tmprc == 0)
+                       CIFSSMBClose(xid, tcon, fid.netfid);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.12/drm-i915-dsi-convert-to-struct-intel_display.patch b/queue-6.12/drm-i915-dsi-convert-to-struct-intel_display.patch
new file mode 100644 (file)
index 0000000..79edcbf
--- /dev/null
@@ -0,0 +1,1424 @@
+From 20bdb739beee60e20ffda6cadec8638ade0344f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Oct 2024 22:07:29 +0200
+Subject: drm/i915/dsi: convert to struct intel_display
+
+From: Jani Nikula <jani.nikula@intel.com>
+
+[ Upstream commit 7c05c58c15d49b75eefaa24154cce771f1db955b ]
+
+struct intel_display will replace struct drm_i915_private as the main
+device pointer for display code. Switch ICL DSI code over to it.
+
+Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/f62a3616ef15e02cf19c5d041656fc6e09b37f6a.1730146000.git.jani.nikula@intel.com
+Stable-dep-of: 879f70382ff3 ("drm/i915/dsi: Use TRANS_DDI_FUNC_CTL's own port width macro")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/icl_dsi.c   | 444 ++++++++++++-----------
+ drivers/gpu/drm/i915/display/icl_dsi.h   |   4 +-
+ drivers/gpu/drm/i915/display/intel_ddi.c |   2 +-
+ 3 files changed, 227 insertions(+), 223 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
+index 293efc1f841df..e2a88e5a97479 100644
+--- a/drivers/gpu/drm/i915/display/icl_dsi.c
++++ b/drivers/gpu/drm/i915/display/icl_dsi.c
+@@ -50,38 +50,38 @@
+ #include "skl_scaler.h"
+ #include "skl_universal_plane.h"
+-static int header_credits_available(struct drm_i915_private *dev_priv,
++static int header_credits_available(struct intel_display *display,
+                                   enum transcoder dsi_trans)
+ {
+-      return (intel_de_read(dev_priv, DSI_CMD_TXCTL(dsi_trans)) & FREE_HEADER_CREDIT_MASK)
++      return (intel_de_read(display, DSI_CMD_TXCTL(dsi_trans)) & FREE_HEADER_CREDIT_MASK)
+               >> FREE_HEADER_CREDIT_SHIFT;
+ }
+-static int payload_credits_available(struct drm_i915_private *dev_priv,
++static int payload_credits_available(struct intel_display *display,
+                                    enum transcoder dsi_trans)
+ {
+-      return (intel_de_read(dev_priv, DSI_CMD_TXCTL(dsi_trans)) & FREE_PLOAD_CREDIT_MASK)
++      return (intel_de_read(display, DSI_CMD_TXCTL(dsi_trans)) & FREE_PLOAD_CREDIT_MASK)
+               >> FREE_PLOAD_CREDIT_SHIFT;
+ }
+-static bool wait_for_header_credits(struct drm_i915_private *dev_priv,
++static bool wait_for_header_credits(struct intel_display *display,
+                                   enum transcoder dsi_trans, int hdr_credit)
+ {
+-      if (wait_for_us(header_credits_available(dev_priv, dsi_trans) >=
++      if (wait_for_us(header_credits_available(display, dsi_trans) >=
+                       hdr_credit, 100)) {
+-              drm_err(&dev_priv->drm, "DSI header credits not released\n");
++              drm_err(display->drm, "DSI header credits not released\n");
+               return false;
+       }
+       return true;
+ }
+-static bool wait_for_payload_credits(struct drm_i915_private *dev_priv,
++static bool wait_for_payload_credits(struct intel_display *display,
+                                    enum transcoder dsi_trans, int payld_credit)
+ {
+-      if (wait_for_us(payload_credits_available(dev_priv, dsi_trans) >=
++      if (wait_for_us(payload_credits_available(display, dsi_trans) >=
+                       payld_credit, 100)) {
+-              drm_err(&dev_priv->drm, "DSI payload credits not released\n");
++              drm_err(display->drm, "DSI payload credits not released\n");
+               return false;
+       }
+@@ -98,7 +98,7 @@ static enum transcoder dsi_port_to_transcoder(enum port port)
+ static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       struct mipi_dsi_device *dsi;
+       enum port port;
+@@ -108,8 +108,8 @@ static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder)
+       /* wait for header/payload credits to be released */
+       for_each_dsi_port(port, intel_dsi->ports) {
+               dsi_trans = dsi_port_to_transcoder(port);
+-              wait_for_header_credits(dev_priv, dsi_trans, MAX_HEADER_CREDIT);
+-              wait_for_payload_credits(dev_priv, dsi_trans, MAX_PLOAD_CREDIT);
++              wait_for_header_credits(display, dsi_trans, MAX_HEADER_CREDIT);
++              wait_for_payload_credits(display, dsi_trans, MAX_PLOAD_CREDIT);
+       }
+       /* send nop DCS command */
+@@ -119,22 +119,22 @@ static void wait_for_cmds_dispatched_to_panel(struct intel_encoder *encoder)
+               dsi->channel = 0;
+               ret = mipi_dsi_dcs_nop(dsi);
+               if (ret < 0)
+-                      drm_err(&dev_priv->drm,
++                      drm_err(display->drm,
+                               "error sending DCS NOP command\n");
+       }
+       /* wait for header credits to be released */
+       for_each_dsi_port(port, intel_dsi->ports) {
+               dsi_trans = dsi_port_to_transcoder(port);
+-              wait_for_header_credits(dev_priv, dsi_trans, MAX_HEADER_CREDIT);
++              wait_for_header_credits(display, dsi_trans, MAX_HEADER_CREDIT);
+       }
+       /* wait for LP TX in progress bit to be cleared */
+       for_each_dsi_port(port, intel_dsi->ports) {
+               dsi_trans = dsi_port_to_transcoder(port);
+-              if (wait_for_us(!(intel_de_read(dev_priv, DSI_LP_MSG(dsi_trans)) &
++              if (wait_for_us(!(intel_de_read(display, DSI_LP_MSG(dsi_trans)) &
+                                 LPTX_IN_PROGRESS), 20))
+-                      drm_err(&dev_priv->drm, "LPTX bit not cleared\n");
++                      drm_err(display->drm, "LPTX bit not cleared\n");
+       }
+ }
+@@ -142,7 +142,7 @@ static int dsi_send_pkt_payld(struct intel_dsi_host *host,
+                             const struct mipi_dsi_packet *packet)
+ {
+       struct intel_dsi *intel_dsi = host->intel_dsi;
+-      struct drm_i915_private *i915 = to_i915(intel_dsi->base.base.dev);
++      struct intel_display *display = to_intel_display(&intel_dsi->base);
+       enum transcoder dsi_trans = dsi_port_to_transcoder(host->port);
+       const u8 *data = packet->payload;
+       u32 len = packet->payload_length;
+@@ -150,20 +150,20 @@ static int dsi_send_pkt_payld(struct intel_dsi_host *host,
+       /* payload queue can accept *256 bytes*, check limit */
+       if (len > MAX_PLOAD_CREDIT * 4) {
+-              drm_err(&i915->drm, "payload size exceeds max queue limit\n");
++              drm_err(display->drm, "payload size exceeds max queue limit\n");
+               return -EINVAL;
+       }
+       for (i = 0; i < len; i += 4) {
+               u32 tmp = 0;
+-              if (!wait_for_payload_credits(i915, dsi_trans, 1))
++              if (!wait_for_payload_credits(display, dsi_trans, 1))
+                       return -EBUSY;
+               for (j = 0; j < min_t(u32, len - i, 4); j++)
+                       tmp |= *data++ << 8 * j;
+-              intel_de_write(i915, DSI_CMD_TXPYLD(dsi_trans), tmp);
++              intel_de_write(display, DSI_CMD_TXPYLD(dsi_trans), tmp);
+       }
+       return 0;
+@@ -174,14 +174,14 @@ static int dsi_send_pkt_hdr(struct intel_dsi_host *host,
+                           bool enable_lpdt)
+ {
+       struct intel_dsi *intel_dsi = host->intel_dsi;
+-      struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
++      struct intel_display *display = to_intel_display(&intel_dsi->base);
+       enum transcoder dsi_trans = dsi_port_to_transcoder(host->port);
+       u32 tmp;
+-      if (!wait_for_header_credits(dev_priv, dsi_trans, 1))
++      if (!wait_for_header_credits(display, dsi_trans, 1))
+               return -EBUSY;
+-      tmp = intel_de_read(dev_priv, DSI_CMD_TXHDR(dsi_trans));
++      tmp = intel_de_read(display, DSI_CMD_TXHDR(dsi_trans));
+       if (packet->payload)
+               tmp |= PAYLOAD_PRESENT;
+@@ -200,15 +200,14 @@ static int dsi_send_pkt_hdr(struct intel_dsi_host *host,
+       tmp |= ((packet->header[0] & DT_MASK) << DT_SHIFT);
+       tmp |= (packet->header[1] << PARAM_WC_LOWER_SHIFT);
+       tmp |= (packet->header[2] << PARAM_WC_UPPER_SHIFT);
+-      intel_de_write(dev_priv, DSI_CMD_TXHDR(dsi_trans), tmp);
++      intel_de_write(display, DSI_CMD_TXHDR(dsi_trans), tmp);
+       return 0;
+ }
+ void icl_dsi_frame_update(struct intel_crtc_state *crtc_state)
+ {
+-      struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+-      struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
++      struct intel_display *display = to_intel_display(crtc_state);
+       u32 mode_flags;
+       enum port port;
+@@ -226,12 +225,13 @@ void icl_dsi_frame_update(struct intel_crtc_state *crtc_state)
+       else
+               return;
+-      intel_de_rmw(dev_priv, DSI_CMD_FRMCTL(port), 0, DSI_FRAME_UPDATE_REQUEST);
++      intel_de_rmw(display, DSI_CMD_FRMCTL(port), 0,
++                   DSI_FRAME_UPDATE_REQUEST);
+ }
+ static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       enum phy phy;
+       u32 tmp, mask, val;
+@@ -245,31 +245,31 @@ static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder)
+               mask = SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK;
+               val = SCALING_MODE_SEL(0x2) | TAP2_DISABLE | TAP3_DISABLE |
+                     RTERM_SELECT(0x6);
+-              tmp = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy));
++              tmp = intel_de_read(display, ICL_PORT_TX_DW5_LN(0, phy));
+               tmp &= ~mask;
+               tmp |= val;
+-              intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), tmp);
+-              intel_de_rmw(dev_priv, ICL_PORT_TX_DW5_AUX(phy), mask, val);
++              intel_de_write(display, ICL_PORT_TX_DW5_GRP(phy), tmp);
++              intel_de_rmw(display, ICL_PORT_TX_DW5_AUX(phy), mask, val);
+               mask = SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
+                      RCOMP_SCALAR_MASK;
+               val = SWING_SEL_UPPER(0x2) | SWING_SEL_LOWER(0x2) |
+                     RCOMP_SCALAR(0x98);
+-              tmp = intel_de_read(dev_priv, ICL_PORT_TX_DW2_LN(0, phy));
++              tmp = intel_de_read(display, ICL_PORT_TX_DW2_LN(0, phy));
+               tmp &= ~mask;
+               tmp |= val;
+-              intel_de_write(dev_priv, ICL_PORT_TX_DW2_GRP(phy), tmp);
+-              intel_de_rmw(dev_priv, ICL_PORT_TX_DW2_AUX(phy), mask, val);
++              intel_de_write(display, ICL_PORT_TX_DW2_GRP(phy), tmp);
++              intel_de_rmw(display, ICL_PORT_TX_DW2_AUX(phy), mask, val);
+               mask = POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
+                      CURSOR_COEFF_MASK;
+               val = POST_CURSOR_1(0x0) | POST_CURSOR_2(0x0) |
+                     CURSOR_COEFF(0x3f);
+-              intel_de_rmw(dev_priv, ICL_PORT_TX_DW4_AUX(phy), mask, val);
++              intel_de_rmw(display, ICL_PORT_TX_DW4_AUX(phy), mask, val);
+               /* Bspec: must not use GRP register for write */
+               for (lane = 0; lane <= 3; lane++)
+-                      intel_de_rmw(dev_priv, ICL_PORT_TX_DW4_LN(lane, phy),
++                      intel_de_rmw(display, ICL_PORT_TX_DW4_LN(lane, phy),
+                                    mask, val);
+       }
+ }
+@@ -277,13 +277,13 @@ static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder)
+ static void configure_dual_link_mode(struct intel_encoder *encoder,
+                                    const struct intel_crtc_state *pipe_config)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
+       u32 dss_ctl1;
+       /* FIXME: Move all DSS handling to intel_vdsc.c */
+-      if (DISPLAY_VER(dev_priv) >= 12) {
++      if (DISPLAY_VER(display) >= 12) {
+               struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
+               dss_ctl1_reg = ICL_PIPE_DSS_CTL1(crtc->pipe);
+@@ -293,7 +293,7 @@ static void configure_dual_link_mode(struct intel_encoder *encoder,
+               dss_ctl2_reg = DSS_CTL2;
+       }
+-      dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg);
++      dss_ctl1 = intel_de_read(display, dss_ctl1_reg);
+       dss_ctl1 |= SPLITTER_ENABLE;
+       dss_ctl1 &= ~OVERLAP_PIXELS_MASK;
+       dss_ctl1 |= OVERLAP_PIXELS(intel_dsi->pixel_overlap);
+@@ -308,19 +308,19 @@ static void configure_dual_link_mode(struct intel_encoder *encoder,
+               dl_buffer_depth = hactive / 2 + intel_dsi->pixel_overlap;
+               if (dl_buffer_depth > MAX_DL_BUFFER_TARGET_DEPTH)
+-                      drm_err(&dev_priv->drm,
++                      drm_err(display->drm,
+                               "DL buffer depth exceed max value\n");
+               dss_ctl1 &= ~LEFT_DL_BUF_TARGET_DEPTH_MASK;
+               dss_ctl1 |= LEFT_DL_BUF_TARGET_DEPTH(dl_buffer_depth);
+-              intel_de_rmw(dev_priv, dss_ctl2_reg, RIGHT_DL_BUF_TARGET_DEPTH_MASK,
++              intel_de_rmw(display, dss_ctl2_reg, RIGHT_DL_BUF_TARGET_DEPTH_MASK,
+                            RIGHT_DL_BUF_TARGET_DEPTH(dl_buffer_depth));
+       } else {
+               /* Interleave */
+               dss_ctl1 |= DUAL_LINK_MODE_INTERLEAVE;
+       }
+-      intel_de_write(dev_priv, dss_ctl1_reg, dss_ctl1);
++      intel_de_write(display, dss_ctl1_reg, dss_ctl1);
+ }
+ /* aka DSI 8X clock */
+@@ -341,6 +341,7 @@ static int afe_clk(struct intel_encoder *encoder,
+ static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder,
+                                         const struct intel_crtc_state *crtc_state)
+ {
++      struct intel_display *display = to_intel_display(encoder);
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       enum port port;
+@@ -360,33 +361,34 @@ static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder,
+       }
+       for_each_dsi_port(port, intel_dsi->ports) {
+-              intel_de_write(dev_priv, ICL_DSI_ESC_CLK_DIV(port),
++              intel_de_write(display, ICL_DSI_ESC_CLK_DIV(port),
+                              esc_clk_div_m & ICL_ESC_CLK_DIV_MASK);
+-              intel_de_posting_read(dev_priv, ICL_DSI_ESC_CLK_DIV(port));
++              intel_de_posting_read(display, ICL_DSI_ESC_CLK_DIV(port));
+       }
+       for_each_dsi_port(port, intel_dsi->ports) {
+-              intel_de_write(dev_priv, ICL_DPHY_ESC_CLK_DIV(port),
++              intel_de_write(display, ICL_DPHY_ESC_CLK_DIV(port),
+                              esc_clk_div_m & ICL_ESC_CLK_DIV_MASK);
+-              intel_de_posting_read(dev_priv, ICL_DPHY_ESC_CLK_DIV(port));
++              intel_de_posting_read(display, ICL_DPHY_ESC_CLK_DIV(port));
+       }
+       if (IS_ALDERLAKE_S(dev_priv) || IS_ALDERLAKE_P(dev_priv)) {
+               for_each_dsi_port(port, intel_dsi->ports) {
+-                      intel_de_write(dev_priv, ADL_MIPIO_DW(port, 8),
++                      intel_de_write(display, ADL_MIPIO_DW(port, 8),
+                                      esc_clk_div_m_phy & TX_ESC_CLK_DIV_PHY);
+-                      intel_de_posting_read(dev_priv, ADL_MIPIO_DW(port, 8));
++                      intel_de_posting_read(display, ADL_MIPIO_DW(port, 8));
+               }
+       }
+ }
+-static void get_dsi_io_power_domains(struct drm_i915_private *dev_priv,
+-                                   struct intel_dsi *intel_dsi)
++static void get_dsi_io_power_domains(struct intel_dsi *intel_dsi)
+ {
++      struct intel_display *display = to_intel_display(&intel_dsi->base);
++      struct drm_i915_private *dev_priv = to_i915(display->drm);
+       enum port port;
+       for_each_dsi_port(port, intel_dsi->ports) {
+-              drm_WARN_ON(&dev_priv->drm, intel_dsi->io_wakeref[port]);
++              drm_WARN_ON(display->drm, intel_dsi->io_wakeref[port]);
+               intel_dsi->io_wakeref[port] =
+                       intel_display_power_get(dev_priv,
+                                               port == PORT_A ?
+@@ -397,15 +399,15 @@ static void get_dsi_io_power_domains(struct drm_i915_private *dev_priv,
+ static void gen11_dsi_enable_io_power(struct intel_encoder *encoder)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       enum port port;
+       for_each_dsi_port(port, intel_dsi->ports)
+-              intel_de_rmw(dev_priv, ICL_DSI_IO_MODECTL(port),
++              intel_de_rmw(display, ICL_DSI_IO_MODECTL(port),
+                            0, COMBO_PHY_MODE_DSI);
+-      get_dsi_io_power_domains(dev_priv, intel_dsi);
++      get_dsi_io_power_domains(intel_dsi);
+ }
+ static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder)
+@@ -421,6 +423,7 @@ static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder)
+ static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder)
+ {
++      struct intel_display *display = to_intel_display(encoder);
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       enum phy phy;
+@@ -429,32 +432,33 @@ static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder)
+       /* Step 4b(i) set loadgen select for transmit and aux lanes */
+       for_each_dsi_phy(phy, intel_dsi->phys) {
+-              intel_de_rmw(dev_priv, ICL_PORT_TX_DW4_AUX(phy), LOADGEN_SELECT, 0);
++              intel_de_rmw(display, ICL_PORT_TX_DW4_AUX(phy),
++                           LOADGEN_SELECT, 0);
+               for (lane = 0; lane <= 3; lane++)
+-                      intel_de_rmw(dev_priv, ICL_PORT_TX_DW4_LN(lane, phy),
++                      intel_de_rmw(display, ICL_PORT_TX_DW4_LN(lane, phy),
+                                    LOADGEN_SELECT, lane != 2 ? LOADGEN_SELECT : 0);
+       }
+       /* Step 4b(ii) set latency optimization for transmit and aux lanes */
+       for_each_dsi_phy(phy, intel_dsi->phys) {
+-              intel_de_rmw(dev_priv, ICL_PORT_TX_DW2_AUX(phy),
++              intel_de_rmw(display, ICL_PORT_TX_DW2_AUX(phy),
+                            FRC_LATENCY_OPTIM_MASK, FRC_LATENCY_OPTIM_VAL(0x5));
+-              tmp = intel_de_read(dev_priv, ICL_PORT_TX_DW2_LN(0, phy));
++              tmp = intel_de_read(display, ICL_PORT_TX_DW2_LN(0, phy));
+               tmp &= ~FRC_LATENCY_OPTIM_MASK;
+               tmp |= FRC_LATENCY_OPTIM_VAL(0x5);
+-              intel_de_write(dev_priv, ICL_PORT_TX_DW2_GRP(phy), tmp);
++              intel_de_write(display, ICL_PORT_TX_DW2_GRP(phy), tmp);
+               /* For EHL, TGL, set latency optimization for PCS_DW1 lanes */
+               if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv) ||
+-                  (DISPLAY_VER(dev_priv) >= 12)) {
+-                      intel_de_rmw(dev_priv, ICL_PORT_PCS_DW1_AUX(phy),
++                  (DISPLAY_VER(display) >= 12)) {
++                      intel_de_rmw(display, ICL_PORT_PCS_DW1_AUX(phy),
+                                    LATENCY_OPTIM_MASK, LATENCY_OPTIM_VAL(0));
+-                      tmp = intel_de_read(dev_priv,
++                      tmp = intel_de_read(display,
+                                           ICL_PORT_PCS_DW1_LN(0, phy));
+                       tmp &= ~LATENCY_OPTIM_MASK;
+                       tmp |= LATENCY_OPTIM_VAL(0x1);
+-                      intel_de_write(dev_priv, ICL_PORT_PCS_DW1_GRP(phy),
++                      intel_de_write(display, ICL_PORT_PCS_DW1_GRP(phy),
+                                      tmp);
+               }
+       }
+@@ -463,17 +467,17 @@ static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder)
+ static void gen11_dsi_voltage_swing_program_seq(struct intel_encoder *encoder)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       u32 tmp;
+       enum phy phy;
+       /* clear common keeper enable bit */
+       for_each_dsi_phy(phy, intel_dsi->phys) {
+-              tmp = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN(0, phy));
++              tmp = intel_de_read(display, ICL_PORT_PCS_DW1_LN(0, phy));
+               tmp &= ~COMMON_KEEPER_EN;
+-              intel_de_write(dev_priv, ICL_PORT_PCS_DW1_GRP(phy), tmp);
+-              intel_de_rmw(dev_priv, ICL_PORT_PCS_DW1_AUX(phy), COMMON_KEEPER_EN, 0);
++              intel_de_write(display, ICL_PORT_PCS_DW1_GRP(phy), tmp);
++              intel_de_rmw(display, ICL_PORT_PCS_DW1_AUX(phy), COMMON_KEEPER_EN, 0);
+       }
+       /*
+@@ -482,14 +486,15 @@ static void gen11_dsi_voltage_swing_program_seq(struct intel_encoder *encoder)
+        * as part of lane phy sequence configuration
+        */
+       for_each_dsi_phy(phy, intel_dsi->phys)
+-              intel_de_rmw(dev_priv, ICL_PORT_CL_DW5(phy), 0, SUS_CLOCK_CONFIG);
++              intel_de_rmw(display, ICL_PORT_CL_DW5(phy), 0,
++                           SUS_CLOCK_CONFIG);
+       /* Clear training enable to change swing values */
+       for_each_dsi_phy(phy, intel_dsi->phys) {
+-              tmp = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy));
++              tmp = intel_de_read(display, ICL_PORT_TX_DW5_LN(0, phy));
+               tmp &= ~TX_TRAINING_EN;
+-              intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), tmp);
+-              intel_de_rmw(dev_priv, ICL_PORT_TX_DW5_AUX(phy), TX_TRAINING_EN, 0);
++              intel_de_write(display, ICL_PORT_TX_DW5_GRP(phy), tmp);
++              intel_de_rmw(display, ICL_PORT_TX_DW5_AUX(phy), TX_TRAINING_EN, 0);
+       }
+       /* Program swing and de-emphasis */
+@@ -497,26 +502,26 @@ static void gen11_dsi_voltage_swing_program_seq(struct intel_encoder *encoder)
+       /* Set training enable to trigger update */
+       for_each_dsi_phy(phy, intel_dsi->phys) {
+-              tmp = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy));
++              tmp = intel_de_read(display, ICL_PORT_TX_DW5_LN(0, phy));
+               tmp |= TX_TRAINING_EN;
+-              intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), tmp);
+-              intel_de_rmw(dev_priv, ICL_PORT_TX_DW5_AUX(phy), 0, TX_TRAINING_EN);
++              intel_de_write(display, ICL_PORT_TX_DW5_GRP(phy), tmp);
++              intel_de_rmw(display, ICL_PORT_TX_DW5_AUX(phy), 0, TX_TRAINING_EN);
+       }
+ }
+ static void gen11_dsi_enable_ddi_buffer(struct intel_encoder *encoder)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       enum port port;
+       for_each_dsi_port(port, intel_dsi->ports) {
+-              intel_de_rmw(dev_priv, DDI_BUF_CTL(port), 0, DDI_BUF_CTL_ENABLE);
++              intel_de_rmw(display, DDI_BUF_CTL(port), 0, DDI_BUF_CTL_ENABLE);
+-              if (wait_for_us(!(intel_de_read(dev_priv, DDI_BUF_CTL(port)) &
++              if (wait_for_us(!(intel_de_read(display, DDI_BUF_CTL(port)) &
+                                 DDI_BUF_IS_IDLE),
+                                 500))
+-                      drm_err(&dev_priv->drm, "DDI port:%c buffer idle\n",
++                      drm_err(display->drm, "DDI port:%c buffer idle\n",
+                               port_name(port));
+       }
+ }
+@@ -525,6 +530,7 @@ static void
+ gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder,
+                            const struct intel_crtc_state *crtc_state)
+ {
++      struct intel_display *display = to_intel_display(encoder);
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       enum port port;
+@@ -532,12 +538,12 @@ gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder,
+       /* Program DPHY clock lanes timings */
+       for_each_dsi_port(port, intel_dsi->ports)
+-              intel_de_write(dev_priv, DPHY_CLK_TIMING_PARAM(port),
++              intel_de_write(display, DPHY_CLK_TIMING_PARAM(port),
+                              intel_dsi->dphy_reg);
+       /* Program DPHY data lanes timings */
+       for_each_dsi_port(port, intel_dsi->ports)
+-              intel_de_write(dev_priv, DPHY_DATA_TIMING_PARAM(port),
++              intel_de_write(display, DPHY_DATA_TIMING_PARAM(port),
+                              intel_dsi->dphy_data_lane_reg);
+       /*
+@@ -546,10 +552,10 @@ gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder,
+        * a value '0' inside TA_PARAM_REGISTERS otherwise
+        * leave all fields at HW default values.
+        */
+-      if (DISPLAY_VER(dev_priv) == 11) {
++      if (DISPLAY_VER(display) == 11) {
+               if (afe_clk(encoder, crtc_state) <= 800000) {
+                       for_each_dsi_port(port, intel_dsi->ports)
+-                              intel_de_rmw(dev_priv, DPHY_TA_TIMING_PARAM(port),
++                              intel_de_rmw(display, DPHY_TA_TIMING_PARAM(port),
+                                            TA_SURE_MASK,
+                                            TA_SURE_OVERRIDE | TA_SURE(0));
+               }
+@@ -557,7 +563,7 @@ gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder,
+       if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) {
+               for_each_dsi_phy(phy, intel_dsi->phys)
+-                      intel_de_rmw(dev_priv, ICL_DPHY_CHKN(phy),
++                      intel_de_rmw(display, ICL_DPHY_CHKN(phy),
+                                    0, ICL_DPHY_CHKN_AFE_OVER_PPI_STRAP);
+       }
+ }
+@@ -566,30 +572,30 @@ static void
+ gen11_dsi_setup_timings(struct intel_encoder *encoder,
+                       const struct intel_crtc_state *crtc_state)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       enum port port;
+       /* Program T-INIT master registers */
+       for_each_dsi_port(port, intel_dsi->ports)
+-              intel_de_rmw(dev_priv, ICL_DSI_T_INIT_MASTER(port),
++              intel_de_rmw(display, ICL_DSI_T_INIT_MASTER(port),
+                            DSI_T_INIT_MASTER_MASK, intel_dsi->init_count);
+       /* shadow register inside display core */
+       for_each_dsi_port(port, intel_dsi->ports)
+-              intel_de_write(dev_priv, DSI_CLK_TIMING_PARAM(port),
++              intel_de_write(display, DSI_CLK_TIMING_PARAM(port),
+                              intel_dsi->dphy_reg);
+       /* shadow register inside display core */
+       for_each_dsi_port(port, intel_dsi->ports)
+-              intel_de_write(dev_priv, DSI_DATA_TIMING_PARAM(port),
++              intel_de_write(display, DSI_DATA_TIMING_PARAM(port),
+                              intel_dsi->dphy_data_lane_reg);
+       /* shadow register inside display core */
+-      if (DISPLAY_VER(dev_priv) == 11) {
++      if (DISPLAY_VER(display) == 11) {
+               if (afe_clk(encoder, crtc_state) <= 800000) {
+                       for_each_dsi_port(port, intel_dsi->ports) {
+-                              intel_de_rmw(dev_priv, DSI_TA_TIMING_PARAM(port),
++                              intel_de_rmw(display, DSI_TA_TIMING_PARAM(port),
+                                            TA_SURE_MASK,
+                                            TA_SURE_OVERRIDE | TA_SURE(0));
+                       }
+@@ -599,45 +605,45 @@ gen11_dsi_setup_timings(struct intel_encoder *encoder,
+ static void gen11_dsi_gate_clocks(struct intel_encoder *encoder)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       u32 tmp;
+       enum phy phy;
+-      mutex_lock(&dev_priv->display.dpll.lock);
+-      tmp = intel_de_read(dev_priv, ICL_DPCLKA_CFGCR0);
++      mutex_lock(&display->dpll.lock);
++      tmp = intel_de_read(display, ICL_DPCLKA_CFGCR0);
+       for_each_dsi_phy(phy, intel_dsi->phys)
+               tmp |= ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
+-      intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, tmp);
+-      mutex_unlock(&dev_priv->display.dpll.lock);
++      intel_de_write(display, ICL_DPCLKA_CFGCR0, tmp);
++      mutex_unlock(&display->dpll.lock);
+ }
+ static void gen11_dsi_ungate_clocks(struct intel_encoder *encoder)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       u32 tmp;
+       enum phy phy;
+-      mutex_lock(&dev_priv->display.dpll.lock);
+-      tmp = intel_de_read(dev_priv, ICL_DPCLKA_CFGCR0);
++      mutex_lock(&display->dpll.lock);
++      tmp = intel_de_read(display, ICL_DPCLKA_CFGCR0);
+       for_each_dsi_phy(phy, intel_dsi->phys)
+               tmp &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
+-      intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, tmp);
+-      mutex_unlock(&dev_priv->display.dpll.lock);
++      intel_de_write(display, ICL_DPCLKA_CFGCR0, tmp);
++      mutex_unlock(&display->dpll.lock);
+ }
+ static bool gen11_dsi_is_clock_enabled(struct intel_encoder *encoder)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       bool clock_enabled = false;
+       enum phy phy;
+       u32 tmp;
+-      tmp = intel_de_read(dev_priv, ICL_DPCLKA_CFGCR0);
++      tmp = intel_de_read(display, ICL_DPCLKA_CFGCR0);
+       for_each_dsi_phy(phy, intel_dsi->phys) {
+               if (!(tmp & ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)))
+@@ -650,36 +656,36 @@ static bool gen11_dsi_is_clock_enabled(struct intel_encoder *encoder)
+ static void gen11_dsi_map_pll(struct intel_encoder *encoder,
+                             const struct intel_crtc_state *crtc_state)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       struct intel_shared_dpll *pll = crtc_state->shared_dpll;
+       enum phy phy;
+       u32 val;
+-      mutex_lock(&dev_priv->display.dpll.lock);
++      mutex_lock(&display->dpll.lock);
+-      val = intel_de_read(dev_priv, ICL_DPCLKA_CFGCR0);
++      val = intel_de_read(display, ICL_DPCLKA_CFGCR0);
+       for_each_dsi_phy(phy, intel_dsi->phys) {
+               val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
+               val |= ICL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy);
+       }
+-      intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, val);
++      intel_de_write(display, ICL_DPCLKA_CFGCR0, val);
+       for_each_dsi_phy(phy, intel_dsi->phys) {
+               val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
+       }
+-      intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, val);
++      intel_de_write(display, ICL_DPCLKA_CFGCR0, val);
+-      intel_de_posting_read(dev_priv, ICL_DPCLKA_CFGCR0);
++      intel_de_posting_read(display, ICL_DPCLKA_CFGCR0);
+-      mutex_unlock(&dev_priv->display.dpll.lock);
++      mutex_unlock(&display->dpll.lock);
+ }
+ static void
+ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
+                              const struct intel_crtc_state *pipe_config)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
+       enum pipe pipe = crtc->pipe;
+@@ -689,7 +695,7 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
+       for_each_dsi_port(port, intel_dsi->ports) {
+               dsi_trans = dsi_port_to_transcoder(port);
+-              tmp = intel_de_read(dev_priv, DSI_TRANS_FUNC_CONF(dsi_trans));
++              tmp = intel_de_read(display, DSI_TRANS_FUNC_CONF(dsi_trans));
+               if (intel_dsi->eotp_pkt)
+                       tmp &= ~EOTP_DISABLED;
+@@ -745,7 +751,7 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
+                       }
+               }
+-              if (DISPLAY_VER(dev_priv) >= 12) {
++              if (DISPLAY_VER(display) >= 12) {
+                       if (is_vid_mode(intel_dsi))
+                               tmp |= BLANKING_PACKET_ENABLE;
+               }
+@@ -778,15 +784,15 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
+                       tmp |= TE_SOURCE_GPIO;
+               }
+-              intel_de_write(dev_priv, DSI_TRANS_FUNC_CONF(dsi_trans), tmp);
++              intel_de_write(display, DSI_TRANS_FUNC_CONF(dsi_trans), tmp);
+       }
+       /* enable port sync mode if dual link */
+       if (intel_dsi->dual_link) {
+               for_each_dsi_port(port, intel_dsi->ports) {
+                       dsi_trans = dsi_port_to_transcoder(port);
+-                      intel_de_rmw(dev_priv,
+-                                   TRANS_DDI_FUNC_CTL2(dev_priv, dsi_trans),
++                      intel_de_rmw(display,
++                                   TRANS_DDI_FUNC_CTL2(display, dsi_trans),
+                                    0, PORT_SYNC_MODE_ENABLE);
+               }
+@@ -798,8 +804,8 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
+               dsi_trans = dsi_port_to_transcoder(port);
+               /* select data lane width */
+-              tmp = intel_de_read(dev_priv,
+-                                  TRANS_DDI_FUNC_CTL(dev_priv, dsi_trans));
++              tmp = intel_de_read(display,
++                                  TRANS_DDI_FUNC_CTL(display, dsi_trans));
+               tmp &= ~DDI_PORT_WIDTH_MASK;
+               tmp |= DDI_PORT_WIDTH(intel_dsi->lane_count);
+@@ -825,16 +831,16 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
+               /* enable DDI buffer */
+               tmp |= TRANS_DDI_FUNC_ENABLE;
+-              intel_de_write(dev_priv,
+-                             TRANS_DDI_FUNC_CTL(dev_priv, dsi_trans), tmp);
++              intel_de_write(display,
++                             TRANS_DDI_FUNC_CTL(display, dsi_trans), tmp);
+       }
+       /* wait for link ready */
+       for_each_dsi_port(port, intel_dsi->ports) {
+               dsi_trans = dsi_port_to_transcoder(port);
+-              if (wait_for_us((intel_de_read(dev_priv, DSI_TRANS_FUNC_CONF(dsi_trans)) &
++              if (wait_for_us((intel_de_read(display, DSI_TRANS_FUNC_CONF(dsi_trans)) &
+                                LINK_READY), 2500))
+-                      drm_err(&dev_priv->drm, "DSI link not ready\n");
++                      drm_err(display->drm, "DSI link not ready\n");
+       }
+ }
+@@ -842,7 +848,7 @@ static void
+ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
+                                const struct intel_crtc_state *crtc_state)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       const struct drm_display_mode *adjusted_mode =
+               &crtc_state->hw.adjusted_mode;
+@@ -909,17 +915,17 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
+       /* minimum hactive as per bspec: 256 pixels */
+       if (adjusted_mode->crtc_hdisplay < 256)
+-              drm_err(&dev_priv->drm, "hactive is less then 256 pixels\n");
++              drm_err(display->drm, "hactive is less then 256 pixels\n");
+       /* if RGB666 format, then hactive must be multiple of 4 pixels */
+       if (intel_dsi->pixel_format == MIPI_DSI_FMT_RGB666 && hactive % 4 != 0)
+-              drm_err(&dev_priv->drm,
++              drm_err(display->drm,
+                       "hactive pixels are not multiple of 4\n");
+       /* program TRANS_HTOTAL register */
+       for_each_dsi_port(port, intel_dsi->ports) {
+               dsi_trans = dsi_port_to_transcoder(port);
+-              intel_de_write(dev_priv, TRANS_HTOTAL(dev_priv, dsi_trans),
++              intel_de_write(display, TRANS_HTOTAL(display, dsi_trans),
+                              HACTIVE(hactive - 1) | HTOTAL(htotal - 1));
+       }
+@@ -928,12 +934,12 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
+               if (intel_dsi->video_mode == NON_BURST_SYNC_PULSE) {
+                       /* BSPEC: hsync size should be atleast 16 pixels */
+                       if (hsync_size < 16)
+-                              drm_err(&dev_priv->drm,
++                              drm_err(display->drm,
+                                       "hsync size < 16 pixels\n");
+               }
+               if (hback_porch < 16)
+-                      drm_err(&dev_priv->drm, "hback porch < 16 pixels\n");
++                      drm_err(display->drm, "hback porch < 16 pixels\n");
+               if (intel_dsi->dual_link) {
+                       hsync_start /= 2;
+@@ -942,8 +948,8 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
+               for_each_dsi_port(port, intel_dsi->ports) {
+                       dsi_trans = dsi_port_to_transcoder(port);
+-                      intel_de_write(dev_priv,
+-                                     TRANS_HSYNC(dev_priv, dsi_trans),
++                      intel_de_write(display,
++                                     TRANS_HSYNC(display, dsi_trans),
+                                      HSYNC_START(hsync_start - 1) | HSYNC_END(hsync_end - 1));
+               }
+       }
+@@ -957,22 +963,22 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
+                * struct drm_display_mode.
+                * For interlace mode: program required pixel minus 2
+                */
+-              intel_de_write(dev_priv, TRANS_VTOTAL(dev_priv, dsi_trans),
++              intel_de_write(display, TRANS_VTOTAL(display, dsi_trans),
+                              VACTIVE(vactive - 1) | VTOTAL(vtotal - 1));
+       }
+       if (vsync_end < vsync_start || vsync_end > vtotal)
+-              drm_err(&dev_priv->drm, "Invalid vsync_end value\n");
++              drm_err(display->drm, "Invalid vsync_end value\n");
+       if (vsync_start < vactive)
+-              drm_err(&dev_priv->drm, "vsync_start less than vactive\n");
++              drm_err(display->drm, "vsync_start less than vactive\n");
+       /* program TRANS_VSYNC register for video mode only */
+       if (is_vid_mode(intel_dsi)) {
+               for_each_dsi_port(port, intel_dsi->ports) {
+                       dsi_trans = dsi_port_to_transcoder(port);
+-                      intel_de_write(dev_priv,
+-                                     TRANS_VSYNC(dev_priv, dsi_trans),
++                      intel_de_write(display,
++                                     TRANS_VSYNC(display, dsi_trans),
+                                      VSYNC_START(vsync_start - 1) | VSYNC_END(vsync_end - 1));
+               }
+       }
+@@ -986,8 +992,8 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
+       if (is_vid_mode(intel_dsi)) {
+               for_each_dsi_port(port, intel_dsi->ports) {
+                       dsi_trans = dsi_port_to_transcoder(port);
+-                      intel_de_write(dev_priv,
+-                                     TRANS_VSYNCSHIFT(dev_priv, dsi_trans),
++                      intel_de_write(display,
++                                     TRANS_VSYNCSHIFT(display, dsi_trans),
+                                      vsync_shift);
+               }
+       }
+@@ -998,11 +1004,11 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
+        * FIXME get rid of these local hacks and do it right,
+        * this will not handle eg. delayed vblank correctly.
+        */
+-      if (DISPLAY_VER(dev_priv) >= 12) {
++      if (DISPLAY_VER(display) >= 12) {
+               for_each_dsi_port(port, intel_dsi->ports) {
+                       dsi_trans = dsi_port_to_transcoder(port);
+-                      intel_de_write(dev_priv,
+-                                     TRANS_VBLANK(dev_priv, dsi_trans),
++                      intel_de_write(display,
++                                     TRANS_VBLANK(display, dsi_trans),
+                                      VBLANK_START(vactive - 1) | VBLANK_END(vtotal - 1));
+               }
+       }
+@@ -1010,20 +1016,20 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
+ static void gen11_dsi_enable_transcoder(struct intel_encoder *encoder)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       enum port port;
+       enum transcoder dsi_trans;
+       for_each_dsi_port(port, intel_dsi->ports) {
+               dsi_trans = dsi_port_to_transcoder(port);
+-              intel_de_rmw(dev_priv, TRANSCONF(dev_priv, dsi_trans), 0,
++              intel_de_rmw(display, TRANSCONF(display, dsi_trans), 0,
+                            TRANSCONF_ENABLE);
+               /* wait for transcoder to be enabled */
+-              if (intel_de_wait_for_set(dev_priv, TRANSCONF(dev_priv, dsi_trans),
++              if (intel_de_wait_for_set(display, TRANSCONF(display, dsi_trans),
+                                         TRANSCONF_STATE_ENABLE, 10))
+-                      drm_err(&dev_priv->drm,
++                      drm_err(display->drm,
+                               "DSI transcoder not enabled\n");
+       }
+ }
+@@ -1031,7 +1037,7 @@ static void gen11_dsi_enable_transcoder(struct intel_encoder *encoder)
+ static void gen11_dsi_setup_timeouts(struct intel_encoder *encoder,
+                                    const struct intel_crtc_state *crtc_state)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       enum port port;
+       enum transcoder dsi_trans;
+@@ -1055,21 +1061,21 @@ static void gen11_dsi_setup_timeouts(struct intel_encoder *encoder,
+               dsi_trans = dsi_port_to_transcoder(port);
+               /* program hst_tx_timeout */
+-              intel_de_rmw(dev_priv, DSI_HSTX_TO(dsi_trans),
++              intel_de_rmw(display, DSI_HSTX_TO(dsi_trans),
+                            HSTX_TIMEOUT_VALUE_MASK,
+                            HSTX_TIMEOUT_VALUE(hs_tx_timeout));
+               /* FIXME: DSI_CALIB_TO */
+               /* program lp_rx_host timeout */
+-              intel_de_rmw(dev_priv, DSI_LPRX_HOST_TO(dsi_trans),
++              intel_de_rmw(display, DSI_LPRX_HOST_TO(dsi_trans),
+                            LPRX_TIMEOUT_VALUE_MASK,
+                            LPRX_TIMEOUT_VALUE(lp_rx_timeout));
+               /* FIXME: DSI_PWAIT_TO */
+               /* program turn around timeout */
+-              intel_de_rmw(dev_priv, DSI_TA_TO(dsi_trans),
++              intel_de_rmw(display, DSI_TA_TO(dsi_trans),
+                            TA_TIMEOUT_VALUE_MASK,
+                            TA_TIMEOUT_VALUE(ta_timeout));
+       }
+@@ -1078,7 +1084,7 @@ static void gen11_dsi_setup_timeouts(struct intel_encoder *encoder,
+ static void gen11_dsi_config_util_pin(struct intel_encoder *encoder,
+                                     bool enable)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       u32 tmp;
+@@ -1090,7 +1096,7 @@ static void gen11_dsi_config_util_pin(struct intel_encoder *encoder,
+       if (is_vid_mode(intel_dsi) || (intel_dsi->ports & BIT(PORT_B)))
+               return;
+-      tmp = intel_de_read(dev_priv, UTIL_PIN_CTL);
++      tmp = intel_de_read(display, UTIL_PIN_CTL);
+       if (enable) {
+               tmp |= UTIL_PIN_DIRECTION_INPUT;
+@@ -1098,7 +1104,7 @@ static void gen11_dsi_config_util_pin(struct intel_encoder *encoder,
+       } else {
+               tmp &= ~UTIL_PIN_ENABLE;
+       }
+-      intel_de_write(dev_priv, UTIL_PIN_CTL, tmp);
++      intel_de_write(display, UTIL_PIN_CTL, tmp);
+ }
+ static void
+@@ -1136,7 +1142,7 @@ gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder,
+ static void gen11_dsi_powerup_panel(struct intel_encoder *encoder)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       struct mipi_dsi_device *dsi;
+       enum port port;
+@@ -1152,14 +1158,14 @@ static void gen11_dsi_powerup_panel(struct intel_encoder *encoder)
+                * FIXME: This uses the number of DW's currently in the payload
+                * receive queue. This is probably not what we want here.
+                */
+-              tmp = intel_de_read(dev_priv, DSI_CMD_RXCTL(dsi_trans));
++              tmp = intel_de_read(display, DSI_CMD_RXCTL(dsi_trans));
+               tmp &= NUMBER_RX_PLOAD_DW_MASK;
+               /* multiply "Number Rx Payload DW" by 4 to get max value */
+               tmp = tmp * 4;
+               dsi = intel_dsi->dsi_hosts[port]->device;
+               ret = mipi_dsi_set_maximum_return_packet_size(dsi, tmp);
+               if (ret < 0)
+-                      drm_err(&dev_priv->drm,
++                      drm_err(display->drm,
+                               "error setting max return pkt size%d\n", tmp);
+       }
+@@ -1219,10 +1225,10 @@ static void gen11_dsi_pre_enable(struct intel_atomic_state *state,
+ static void icl_apply_kvmr_pipe_a_wa(struct intel_encoder *encoder,
+                                    enum pipe pipe, bool enable)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+-      if (DISPLAY_VER(dev_priv) == 11 && pipe == PIPE_B)
+-              intel_de_rmw(dev_priv, CHICKEN_PAR1_1,
++      if (DISPLAY_VER(display) == 11 && pipe == PIPE_B)
++              intel_de_rmw(display, CHICKEN_PAR1_1,
+                            IGNORE_KVMR_PIPE_A,
+                            enable ? IGNORE_KVMR_PIPE_A : 0);
+ }
+@@ -1235,13 +1241,13 @@ static void icl_apply_kvmr_pipe_a_wa(struct intel_encoder *encoder,
+  */
+ static void adlp_set_lp_hs_wakeup_gb(struct intel_encoder *encoder)
+ {
+-      struct drm_i915_private *i915 = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       enum port port;
+-      if (DISPLAY_VER(i915) == 13) {
++      if (DISPLAY_VER(display) == 13) {
+               for_each_dsi_port(port, intel_dsi->ports)
+-                      intel_de_rmw(i915, TGL_DSI_CHKN_REG(port),
++                      intel_de_rmw(display, TGL_DSI_CHKN_REG(port),
+                                    TGL_DSI_CHKN_LSHS_GB_MASK,
+                                    TGL_DSI_CHKN_LSHS_GB(4));
+       }
+@@ -1275,7 +1281,7 @@ static void gen11_dsi_enable(struct intel_atomic_state *state,
+ static void gen11_dsi_disable_transcoder(struct intel_encoder *encoder)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       enum port port;
+       enum transcoder dsi_trans;
+@@ -1284,13 +1290,13 @@ static void gen11_dsi_disable_transcoder(struct intel_encoder *encoder)
+               dsi_trans = dsi_port_to_transcoder(port);
+               /* disable transcoder */
+-              intel_de_rmw(dev_priv, TRANSCONF(dev_priv, dsi_trans),
++              intel_de_rmw(display, TRANSCONF(display, dsi_trans),
+                            TRANSCONF_ENABLE, 0);
+               /* wait for transcoder to be disabled */
+-              if (intel_de_wait_for_clear(dev_priv, TRANSCONF(dev_priv, dsi_trans),
++              if (intel_de_wait_for_clear(display, TRANSCONF(display, dsi_trans),
+                                           TRANSCONF_STATE_ENABLE, 50))
+-                      drm_err(&dev_priv->drm,
++                      drm_err(display->drm,
+                               "DSI trancoder not disabled\n");
+       }
+ }
+@@ -1307,7 +1313,7 @@ static void gen11_dsi_powerdown_panel(struct intel_encoder *encoder)
+ static void gen11_dsi_deconfigure_trancoder(struct intel_encoder *encoder)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       enum port port;
+       enum transcoder dsi_trans;
+@@ -1316,29 +1322,29 @@ static void gen11_dsi_deconfigure_trancoder(struct intel_encoder *encoder)
+       /* disable periodic update mode */
+       if (is_cmd_mode(intel_dsi)) {
+               for_each_dsi_port(port, intel_dsi->ports)
+-                      intel_de_rmw(dev_priv, DSI_CMD_FRMCTL(port),
++                      intel_de_rmw(display, DSI_CMD_FRMCTL(port),
+                                    DSI_PERIODIC_FRAME_UPDATE_ENABLE, 0);
+       }
+       /* put dsi link in ULPS */
+       for_each_dsi_port(port, intel_dsi->ports) {
+               dsi_trans = dsi_port_to_transcoder(port);
+-              tmp = intel_de_read(dev_priv, DSI_LP_MSG(dsi_trans));
++              tmp = intel_de_read(display, DSI_LP_MSG(dsi_trans));
+               tmp |= LINK_ENTER_ULPS;
+               tmp &= ~LINK_ULPS_TYPE_LP11;
+-              intel_de_write(dev_priv, DSI_LP_MSG(dsi_trans), tmp);
++              intel_de_write(display, DSI_LP_MSG(dsi_trans), tmp);
+-              if (wait_for_us((intel_de_read(dev_priv, DSI_LP_MSG(dsi_trans)) &
++              if (wait_for_us((intel_de_read(display, DSI_LP_MSG(dsi_trans)) &
+                                LINK_IN_ULPS),
+                               10))
+-                      drm_err(&dev_priv->drm, "DSI link not in ULPS\n");
++                      drm_err(display->drm, "DSI link not in ULPS\n");
+       }
+       /* disable ddi function */
+       for_each_dsi_port(port, intel_dsi->ports) {
+               dsi_trans = dsi_port_to_transcoder(port);
+-              intel_de_rmw(dev_priv,
+-                           TRANS_DDI_FUNC_CTL(dev_priv, dsi_trans),
++              intel_de_rmw(display,
++                           TRANS_DDI_FUNC_CTL(display, dsi_trans),
+                            TRANS_DDI_FUNC_ENABLE, 0);
+       }
+@@ -1346,8 +1352,8 @@ static void gen11_dsi_deconfigure_trancoder(struct intel_encoder *encoder)
+       if (intel_dsi->dual_link) {
+               for_each_dsi_port(port, intel_dsi->ports) {
+                       dsi_trans = dsi_port_to_transcoder(port);
+-                      intel_de_rmw(dev_priv,
+-                                   TRANS_DDI_FUNC_CTL2(dev_priv, dsi_trans),
++                      intel_de_rmw(display,
++                                   TRANS_DDI_FUNC_CTL2(display, dsi_trans),
+                                    PORT_SYNC_MODE_ENABLE, 0);
+               }
+       }
+@@ -1355,18 +1361,18 @@ static void gen11_dsi_deconfigure_trancoder(struct intel_encoder *encoder)
+ static void gen11_dsi_disable_port(struct intel_encoder *encoder)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       enum port port;
+       gen11_dsi_ungate_clocks(encoder);
+       for_each_dsi_port(port, intel_dsi->ports) {
+-              intel_de_rmw(dev_priv, DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE, 0);
++              intel_de_rmw(display, DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE, 0);
+-              if (wait_for_us((intel_de_read(dev_priv, DDI_BUF_CTL(port)) &
++              if (wait_for_us((intel_de_read(display, DDI_BUF_CTL(port)) &
+                                DDI_BUF_IS_IDLE),
+                                8))
+-                      drm_err(&dev_priv->drm,
++                      drm_err(display->drm,
+                               "DDI port:%c buffer not idle\n",
+                               port_name(port));
+       }
+@@ -1375,6 +1381,7 @@ static void gen11_dsi_disable_port(struct intel_encoder *encoder)
+ static void gen11_dsi_disable_io_power(struct intel_encoder *encoder)
+ {
++      struct intel_display *display = to_intel_display(encoder);
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       enum port port;
+@@ -1392,7 +1399,7 @@ static void gen11_dsi_disable_io_power(struct intel_encoder *encoder)
+       /* set mode to DDI */
+       for_each_dsi_port(port, intel_dsi->ports)
+-              intel_de_rmw(dev_priv, ICL_DSI_IO_MODECTL(port),
++              intel_de_rmw(display, ICL_DSI_IO_MODECTL(port),
+                            COMBO_PHY_MODE_DSI, 0);
+ }
+@@ -1504,8 +1511,7 @@ static void gen11_dsi_get_timings(struct intel_encoder *encoder,
+ static bool gen11_dsi_is_periodic_cmd_mode(struct intel_dsi *intel_dsi)
+ {
+-      struct drm_device *dev = intel_dsi->base.base.dev;
+-      struct drm_i915_private *dev_priv = to_i915(dev);
++      struct intel_display *display = to_intel_display(&intel_dsi->base);
+       enum transcoder dsi_trans;
+       u32 val;
+@@ -1514,7 +1520,7 @@ static bool gen11_dsi_is_periodic_cmd_mode(struct intel_dsi *intel_dsi)
+       else
+               dsi_trans = TRANSCODER_DSI_0;
+-      val = intel_de_read(dev_priv, DSI_TRANS_FUNC_CONF(dsi_trans));
++      val = intel_de_read(display, DSI_TRANS_FUNC_CONF(dsi_trans));
+       return (val & DSI_PERIODIC_FRAME_UPDATE_ENABLE);
+ }
+@@ -1557,7 +1563,7 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
+ static void gen11_dsi_sync_state(struct intel_encoder *encoder,
+                                const struct intel_crtc_state *crtc_state)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_crtc *intel_crtc;
+       enum pipe pipe;
+@@ -1568,9 +1574,9 @@ static void gen11_dsi_sync_state(struct intel_encoder *encoder,
+       pipe = intel_crtc->pipe;
+       /* wa verify 1409054076:icl,jsl,ehl */
+-      if (DISPLAY_VER(dev_priv) == 11 && pipe == PIPE_B &&
+-          !(intel_de_read(dev_priv, CHICKEN_PAR1_1) & IGNORE_KVMR_PIPE_A))
+-              drm_dbg_kms(&dev_priv->drm,
++      if (DISPLAY_VER(display) == 11 && pipe == PIPE_B &&
++          !(intel_de_read(display, CHICKEN_PAR1_1) & IGNORE_KVMR_PIPE_A))
++              drm_dbg_kms(display->drm,
+                           "[ENCODER:%d:%s] BIOS left IGNORE_KVMR_PIPE_A cleared with pipe B enabled\n",
+                           encoder->base.base.id,
+                           encoder->base.name);
+@@ -1579,9 +1585,9 @@ static void gen11_dsi_sync_state(struct intel_encoder *encoder,
+ static int gen11_dsi_dsc_compute_config(struct intel_encoder *encoder,
+                                       struct intel_crtc_state *crtc_state)
+ {
+-      struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
+-      int dsc_max_bpc = DISPLAY_VER(dev_priv) >= 12 ? 12 : 10;
++      int dsc_max_bpc = DISPLAY_VER(display) >= 12 ? 12 : 10;
+       bool use_dsc;
+       int ret;
+@@ -1606,12 +1612,12 @@ static int gen11_dsi_dsc_compute_config(struct intel_encoder *encoder,
+               return ret;
+       /* DSI specific sanity checks on the common code */
+-      drm_WARN_ON(&dev_priv->drm, vdsc_cfg->vbr_enable);
+-      drm_WARN_ON(&dev_priv->drm, vdsc_cfg->simple_422);
+-      drm_WARN_ON(&dev_priv->drm,
++      drm_WARN_ON(display->drm, vdsc_cfg->vbr_enable);
++      drm_WARN_ON(display->drm, vdsc_cfg->simple_422);
++      drm_WARN_ON(display->drm,
+                   vdsc_cfg->pic_width % vdsc_cfg->slice_width);
+-      drm_WARN_ON(&dev_priv->drm, vdsc_cfg->slice_height < 8);
+-      drm_WARN_ON(&dev_priv->drm,
++      drm_WARN_ON(display->drm, vdsc_cfg->slice_height < 8);
++      drm_WARN_ON(display->drm,
+                   vdsc_cfg->pic_height % vdsc_cfg->slice_height);
+       ret = drm_dsc_compute_rc_parameters(vdsc_cfg);
+@@ -1627,7 +1633,7 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder,
+                                   struct intel_crtc_state *pipe_config,
+                                   struct drm_connector_state *conn_state)
+ {
+-      struct drm_i915_private *i915 = to_i915(encoder->base.dev);
++      struct intel_display *display = to_intel_display(encoder);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       struct intel_connector *intel_connector = intel_dsi->attached_connector;
+       struct drm_display_mode *adjusted_mode =
+@@ -1661,7 +1667,7 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder,
+       pipe_config->clock_set = true;
+       if (gen11_dsi_dsc_compute_config(encoder, pipe_config))
+-              drm_dbg_kms(&i915->drm, "Attempting to use DSC failed\n");
++              drm_dbg_kms(display->drm, "Attempting to use DSC failed\n");
+       pipe_config->port_clock = afe_clk(encoder, pipe_config) / 5;
+@@ -1679,15 +1685,13 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder,
+ static void gen11_dsi_get_power_domains(struct intel_encoder *encoder,
+                                       struct intel_crtc_state *crtc_state)
+ {
+-      struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+-
+-      get_dsi_io_power_domains(i915,
+-                               enc_to_intel_dsi(encoder));
++      get_dsi_io_power_domains(enc_to_intel_dsi(encoder));
+ }
+ static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder,
+                                  enum pipe *pipe)
+ {
++      struct intel_display *display = to_intel_display(encoder);
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+       enum transcoder dsi_trans;
+@@ -1703,8 +1707,8 @@ static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder,
+       for_each_dsi_port(port, intel_dsi->ports) {
+               dsi_trans = dsi_port_to_transcoder(port);
+-              tmp = intel_de_read(dev_priv,
+-                                  TRANS_DDI_FUNC_CTL(dev_priv, dsi_trans));
++              tmp = intel_de_read(display,
++                                  TRANS_DDI_FUNC_CTL(display, dsi_trans));
+               switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
+               case TRANS_DDI_EDP_INPUT_A_ON:
+                       *pipe = PIPE_A;
+@@ -1719,11 +1723,11 @@ static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder,
+                       *pipe = PIPE_D;
+                       break;
+               default:
+-                      drm_err(&dev_priv->drm, "Invalid PIPE input\n");
++                      drm_err(display->drm, "Invalid PIPE input\n");
+                       goto out;
+               }
+-              tmp = intel_de_read(dev_priv, TRANSCONF(dev_priv, dsi_trans));
++              tmp = intel_de_read(display, TRANSCONF(display, dsi_trans));
+               ret = tmp & TRANSCONF_ENABLE;
+       }
+ out:
+@@ -1833,8 +1837,7 @@ static const struct mipi_dsi_host_ops gen11_dsi_host_ops = {
+ static void icl_dphy_param_init(struct intel_dsi *intel_dsi)
+ {
+-      struct drm_device *dev = intel_dsi->base.base.dev;
+-      struct drm_i915_private *dev_priv = to_i915(dev);
++      struct intel_display *display = to_intel_display(&intel_dsi->base);
+       struct intel_connector *connector = intel_dsi->attached_connector;
+       struct mipi_config *mipi_config = connector->panel.vbt.dsi.config;
+       u32 tlpx_ns;
+@@ -1858,7 +1861,7 @@ static void icl_dphy_param_init(struct intel_dsi *intel_dsi)
+        */
+       prepare_cnt = DIV_ROUND_UP(ths_prepare_ns * 4, tlpx_ns);
+       if (prepare_cnt > ICL_PREPARE_CNT_MAX) {
+-              drm_dbg_kms(&dev_priv->drm, "prepare_cnt out of range (%d)\n",
++              drm_dbg_kms(display->drm, "prepare_cnt out of range (%d)\n",
+                           prepare_cnt);
+               prepare_cnt = ICL_PREPARE_CNT_MAX;
+       }
+@@ -1867,7 +1870,7 @@ static void icl_dphy_param_init(struct intel_dsi *intel_dsi)
+       clk_zero_cnt = DIV_ROUND_UP(mipi_config->tclk_prepare_clkzero -
+                                   ths_prepare_ns, tlpx_ns);
+       if (clk_zero_cnt > ICL_CLK_ZERO_CNT_MAX) {
+-              drm_dbg_kms(&dev_priv->drm,
++              drm_dbg_kms(display->drm,
+                           "clk_zero_cnt out of range (%d)\n", clk_zero_cnt);
+               clk_zero_cnt = ICL_CLK_ZERO_CNT_MAX;
+       }
+@@ -1875,7 +1878,7 @@ static void icl_dphy_param_init(struct intel_dsi *intel_dsi)
+       /* trail cnt in escape clocks*/
+       trail_cnt = DIV_ROUND_UP(tclk_trail_ns, tlpx_ns);
+       if (trail_cnt > ICL_TRAIL_CNT_MAX) {
+-              drm_dbg_kms(&dev_priv->drm, "trail_cnt out of range (%d)\n",
++              drm_dbg_kms(display->drm, "trail_cnt out of range (%d)\n",
+                           trail_cnt);
+               trail_cnt = ICL_TRAIL_CNT_MAX;
+       }
+@@ -1883,7 +1886,7 @@ static void icl_dphy_param_init(struct intel_dsi *intel_dsi)
+       /* tclk pre count in escape clocks */
+       tclk_pre_cnt = DIV_ROUND_UP(mipi_config->tclk_pre, tlpx_ns);
+       if (tclk_pre_cnt > ICL_TCLK_PRE_CNT_MAX) {
+-              drm_dbg_kms(&dev_priv->drm,
++              drm_dbg_kms(display->drm,
+                           "tclk_pre_cnt out of range (%d)\n", tclk_pre_cnt);
+               tclk_pre_cnt = ICL_TCLK_PRE_CNT_MAX;
+       }
+@@ -1892,7 +1895,7 @@ static void icl_dphy_param_init(struct intel_dsi *intel_dsi)
+       hs_zero_cnt = DIV_ROUND_UP(mipi_config->ths_prepare_hszero -
+                                  ths_prepare_ns, tlpx_ns);
+       if (hs_zero_cnt > ICL_HS_ZERO_CNT_MAX) {
+-              drm_dbg_kms(&dev_priv->drm, "hs_zero_cnt out of range (%d)\n",
++              drm_dbg_kms(display->drm, "hs_zero_cnt out of range (%d)\n",
+                           hs_zero_cnt);
+               hs_zero_cnt = ICL_HS_ZERO_CNT_MAX;
+       }
+@@ -1900,7 +1903,7 @@ static void icl_dphy_param_init(struct intel_dsi *intel_dsi)
+       /* hs exit zero cnt in escape clocks */
+       exit_zero_cnt = DIV_ROUND_UP(mipi_config->ths_exit, tlpx_ns);
+       if (exit_zero_cnt > ICL_EXIT_ZERO_CNT_MAX) {
+-              drm_dbg_kms(&dev_priv->drm,
++              drm_dbg_kms(display->drm,
+                           "exit_zero_cnt out of range (%d)\n",
+                           exit_zero_cnt);
+               exit_zero_cnt = ICL_EXIT_ZERO_CNT_MAX;
+@@ -1942,10 +1945,9 @@ static void icl_dsi_add_properties(struct intel_connector *connector)
+                                                      fixed_mode->vdisplay);
+ }
+-void icl_dsi_init(struct drm_i915_private *dev_priv,
++void icl_dsi_init(struct intel_display *display,
+                 const struct intel_bios_encoder_data *devdata)
+ {
+-      struct intel_display *display = &dev_priv->display;
+       struct intel_dsi *intel_dsi;
+       struct intel_encoder *encoder;
+       struct intel_connector *intel_connector;
+@@ -1973,7 +1975,8 @@ void icl_dsi_init(struct drm_i915_private *dev_priv,
+       encoder->devdata = devdata;
+       /* register DSI encoder with DRM subsystem */
+-      drm_encoder_init(&dev_priv->drm, &encoder->base, &gen11_dsi_encoder_funcs,
++      drm_encoder_init(display->drm, &encoder->base,
++                       &gen11_dsi_encoder_funcs,
+                        DRM_MODE_ENCODER_DSI, "DSI %c", port_name(port));
+       encoder->pre_pll_enable = gen11_dsi_pre_pll_enable;
+@@ -1998,7 +2001,8 @@ void icl_dsi_init(struct drm_i915_private *dev_priv,
+       encoder->shutdown = intel_dsi_shutdown;
+       /* register DSI connector with DRM subsystem */
+-      drm_connector_init(&dev_priv->drm, connector, &gen11_dsi_connector_funcs,
++      drm_connector_init(display->drm, connector,
++                         &gen11_dsi_connector_funcs,
+                          DRM_MODE_CONNECTOR_DSI);
+       drm_connector_helper_add(connector, &gen11_dsi_connector_helper_funcs);
+       connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+@@ -2011,12 +2015,12 @@ void icl_dsi_init(struct drm_i915_private *dev_priv,
+       intel_bios_init_panel_late(display, &intel_connector->panel, encoder->devdata, NULL);
+-      mutex_lock(&dev_priv->drm.mode_config.mutex);
++      mutex_lock(&display->drm->mode_config.mutex);
+       intel_panel_add_vbt_lfp_fixed_mode(intel_connector);
+-      mutex_unlock(&dev_priv->drm.mode_config.mutex);
++      mutex_unlock(&display->drm->mode_config.mutex);
+       if (!intel_panel_preferred_fixed_mode(intel_connector)) {
+-              drm_err(&dev_priv->drm, "DSI fixed mode info missing\n");
++              drm_err(display->drm, "DSI fixed mode info missing\n");
+               goto err;
+       }
+@@ -2029,10 +2033,10 @@ void icl_dsi_init(struct drm_i915_private *dev_priv,
+       else
+               intel_dsi->ports = BIT(port);
+-      if (drm_WARN_ON(&dev_priv->drm, intel_connector->panel.vbt.dsi.bl_ports & ~intel_dsi->ports))
++      if (drm_WARN_ON(display->drm, intel_connector->panel.vbt.dsi.bl_ports & ~intel_dsi->ports))
+               intel_connector->panel.vbt.dsi.bl_ports &= intel_dsi->ports;
+-      if (drm_WARN_ON(&dev_priv->drm, intel_connector->panel.vbt.dsi.cabc_ports & ~intel_dsi->ports))
++      if (drm_WARN_ON(display->drm, intel_connector->panel.vbt.dsi.cabc_ports & ~intel_dsi->ports))
+               intel_connector->panel.vbt.dsi.cabc_ports &= intel_dsi->ports;
+       for_each_dsi_port(port, intel_dsi->ports) {
+@@ -2046,7 +2050,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv,
+       }
+       if (!intel_dsi_vbt_init(intel_dsi, MIPI_DSI_GENERIC_PANEL_ID)) {
+-              drm_dbg_kms(&dev_priv->drm, "no device found\n");
++              drm_dbg_kms(display->drm, "no device found\n");
+               goto err;
+       }
+diff --git a/drivers/gpu/drm/i915/display/icl_dsi.h b/drivers/gpu/drm/i915/display/icl_dsi.h
+index 43fa7d72eeb18..099fc50e35b41 100644
+--- a/drivers/gpu/drm/i915/display/icl_dsi.h
++++ b/drivers/gpu/drm/i915/display/icl_dsi.h
+@@ -6,11 +6,11 @@
+ #ifndef __ICL_DSI_H__
+ #define __ICL_DSI_H__
+-struct drm_i915_private;
+ struct intel_bios_encoder_data;
+ struct intel_crtc_state;
++struct intel_display;
+-void icl_dsi_init(struct drm_i915_private *dev_priv,
++void icl_dsi_init(struct intel_display *display,
+                 const struct intel_bios_encoder_data *devdata);
+ void icl_dsi_frame_update(struct intel_crtc_state *crtc_state);
+diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
+index 2f1d9ce87ceb0..34dee523f0b61 100644
+--- a/drivers/gpu/drm/i915/display/intel_ddi.c
++++ b/drivers/gpu/drm/i915/display/intel_ddi.c
+@@ -4888,7 +4888,7 @@ void intel_ddi_init(struct intel_display *display,
+               if (!assert_has_icl_dsi(dev_priv))
+                       return;
+-              icl_dsi_init(dev_priv, devdata);
++              icl_dsi_init(display, devdata);
+               return;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.12/drm-i915-dsi-use-trans_ddi_func_ctl-s-own-port-width.patch b/queue-6.12/drm-i915-dsi-use-trans_ddi_func_ctl-s-own-port-width.patch
new file mode 100644 (file)
index 0000000..7b011c8
--- /dev/null
@@ -0,0 +1,44 @@
+From a95787a96a9d4d7320053cfa41e1fcde3a49955b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 16:19:51 +0200
+Subject: drm/i915/dsi: Use TRANS_DDI_FUNC_CTL's own port width macro
+
+From: Imre Deak <imre.deak@intel.com>
+
+[ Upstream commit 879f70382ff3e92fc854589ada3453e3f5f5b601 ]
+
+The format of the port width field in the DDI_BUF_CTL and the
+TRANS_DDI_FUNC_CTL registers are different starting with MTL, where the
+x3 lane mode for HDMI FRL has a different encoding in the two registers.
+To account for this use the TRANS_DDI_FUNC_CTL's own port width macro.
+
+Cc: <stable@vger.kernel.org> # v6.5+
+Fixes: b66a8abaa48a ("drm/i915/display/mtl: Fill port width in DDI_BUF_/TRANS_DDI_FUNC_/PORT_BUF_CTL for HDMI")
+Reviewed-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Imre Deak <imre.deak@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250214142001.552916-2-imre.deak@intel.com
+(cherry picked from commit 76120b3a304aec28fef4910204b81a12db8974da)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/icl_dsi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
+index e2a88e5a97479..4e95b8eda23f7 100644
+--- a/drivers/gpu/drm/i915/display/icl_dsi.c
++++ b/drivers/gpu/drm/i915/display/icl_dsi.c
+@@ -806,8 +806,8 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
+               /* select data lane width */
+               tmp = intel_de_read(display,
+                                   TRANS_DDI_FUNC_CTL(display, dsi_trans));
+-              tmp &= ~DDI_PORT_WIDTH_MASK;
+-              tmp |= DDI_PORT_WIDTH(intel_dsi->lane_count);
++              tmp &= ~TRANS_DDI_PORT_WIDTH_MASK;
++              tmp |= TRANS_DDI_PORT_WIDTH(intel_dsi->lane_count);
+               /* select input pipe */
+               tmp &= ~TRANS_DDI_EDP_INPUT_MASK;
+-- 
+2.39.5
+
diff --git a/queue-6.12/gpio-vf610-add-locking-to-gpio-direction-functions.patch b/queue-6.12/gpio-vf610-add-locking-to-gpio-direction-functions.patch
new file mode 100644 (file)
index 0000000..30caab2
--- /dev/null
@@ -0,0 +1,71 @@
+From d8ee40d18b024446cd9f94a57ae9eb43c6054501 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 10:16:43 +0100
+Subject: gpio: vf610: add locking to gpio direction functions
+
+From: Johan Korsnes <johan.korsnes@remarkable.no>
+
+[ Upstream commit 4e667a1968099c6deadee2313ecd648f8f0a8956 ]
+
+Add locking to `vf610_gpio_direction_input|output()` functions. Without
+this locking, a race condition exists between concurrent calls to these
+functions, potentially leading to incorrect GPIO direction settings.
+
+To verify the correctness of this fix, a `trylock` patch was applied,
+where after a couple of reboots the race was confirmed. I.e., one user
+had to wait before acquiring the lock. With this patch the race has not
+been encountered. It's worth mentioning that any type of debugging
+(printing, tracing, etc.) would "resolve"/hide the issue.
+
+Fixes: 659d8a62311f ("gpio: vf610: add imx7ulp support")
+Signed-off-by: Johan Korsnes <johan.korsnes@remarkable.no>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Reviewed-by: Haibo Chen <haibo.chen@nxp.com>
+Cc: Bartosz Golaszewski <brgl@bgdev.pl>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20250217091643.679644-1-johan.korsnes@remarkable.no
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-vf610.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c
+index c4f34a347cb6e..c36a9dbccd4dd 100644
+--- a/drivers/gpio/gpio-vf610.c
++++ b/drivers/gpio/gpio-vf610.c
+@@ -36,6 +36,7 @@ struct vf610_gpio_port {
+       struct clk *clk_port;
+       struct clk *clk_gpio;
+       int irq;
++      spinlock_t lock; /* protect gpio direction registers */
+ };
+ #define GPIO_PDOR             0x00
+@@ -124,6 +125,7 @@ static int vf610_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
+       u32 val;
+       if (port->sdata->have_paddr) {
++              guard(spinlock_irqsave)(&port->lock);
+               val = vf610_gpio_readl(port->gpio_base + GPIO_PDDR);
+               val &= ~mask;
+               vf610_gpio_writel(val, port->gpio_base + GPIO_PDDR);
+@@ -142,6 +144,7 @@ static int vf610_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio
+       vf610_gpio_set(chip, gpio, value);
+       if (port->sdata->have_paddr) {
++              guard(spinlock_irqsave)(&port->lock);
+               val = vf610_gpio_readl(port->gpio_base + GPIO_PDDR);
+               val |= mask;
+               vf610_gpio_writel(val, port->gpio_base + GPIO_PDDR);
+@@ -297,6 +300,7 @@ static int vf610_gpio_probe(struct platform_device *pdev)
+               return -ENOMEM;
+       port->sdata = device_get_match_data(dev);
++      spin_lock_init(&port->lock);
+       dual_base = port->sdata->have_dual_base;
+-- 
+2.39.5
+
diff --git a/queue-6.12/gpio-vf610-use-generic-device_get_match_data.patch b/queue-6.12/gpio-vf610-use-generic-device_get_match_data.patch
new file mode 100644 (file)
index 0000000..2905d03
--- /dev/null
@@ -0,0 +1,52 @@
+From e8d970b9443ecafb5c6becd9d61a0c122a7955f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Oct 2024 12:25:49 +0200
+Subject: gpio: vf610: use generic device_get_match_data()
+
+From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+
+[ Upstream commit 1b35c124f961b355dafb1906c591191bd0b37417 ]
+
+There's no need to use the OF-specific variant to get the match data.
+Switch to using device_get_match_data() and with that remove the of.h
+include. Also remove of_irq.h as none of its interfaces is used here and
+order the includes in alphabetical order.
+
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20241007102549.34926-1-brgl@bgdev.pl
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Stable-dep-of: 4e667a196809 ("gpio: vf610: add locking to gpio direction functions")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-vf610.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c
+index 27eff741fe9a2..c4f34a347cb6e 100644
+--- a/drivers/gpio/gpio-vf610.c
++++ b/drivers/gpio/gpio-vf610.c
+@@ -15,10 +15,9 @@
+ #include <linux/io.h>
+ #include <linux/ioport.h>
+ #include <linux/irq.h>
+-#include <linux/platform_device.h>
+-#include <linux/of.h>
+-#include <linux/of_irq.h>
+ #include <linux/pinctrl/consumer.h>
++#include <linux/platform_device.h>
++#include <linux/property.h>
+ #define VF610_GPIO_PER_PORT           32
+@@ -297,7 +296,7 @@ static int vf610_gpio_probe(struct platform_device *pdev)
+       if (!port)
+               return -ENOMEM;
+-      port->sdata = of_device_get_match_data(dev);
++      port->sdata = device_get_match_data(dev);
+       dual_base = port->sdata->have_dual_base;
+-- 
+2.39.5
+
index b65c7ec462ca5fcdf309fd7dbbc21ed5fbc5dd94..12dd45fc7bbda6f5e2bc43d7c735d986897f7f86 100644 (file)
@@ -1 +1,8 @@
 rust-block-fix-formatting-in-gendisk-doc.patch
+drm-i915-dsi-convert-to-struct-intel_display.patch
+drm-i915-dsi-use-trans_ddi_func_ctl-s-own-port-width.patch
+gpio-vf610-use-generic-device_get_match_data.patch
+gpio-vf610-add-locking-to-gpio-direction-functions.patch
+cifs-remove-symlink-member-from-cifs_open_info_data-.patch
+smb311-failure-to-open-files-of-length-1040-when-mou.patch
+btrfs-fix-data-overwriting-bug-during-buffered-write.patch
diff --git a/queue-6.12/smb311-failure-to-open-files-of-length-1040-when-mou.patch b/queue-6.12/smb311-failure-to-open-files-of-length-1040-when-mou.patch
new file mode 100644 (file)
index 0000000..45b0a46
--- /dev/null
@@ -0,0 +1,147 @@
+From 2be2de86617879c89c524920e55a32100b11c369 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Feb 2025 22:17:54 -0600
+Subject: smb311: failure to open files of length 1040 when mounting with
+ SMB3.1.1 POSIX extensions
+
+From: Steve French <stfrench@microsoft.com>
+
+[ Upstream commit 9df23801c83d3e12b4c09be39d37d2be385e52f9 ]
+
+If a file size has bits 0x410 = ATTR_DIRECTORY | ATTR_REPARSE set
+then during queryinfo (stat) the file is regarded as a directory
+and subsequent opens can fail. A simple test example is trying
+to open any file 1040 bytes long when mounting with "posix"
+(SMB3.1.1 POSIX/Linux Extensions).
+
+The cause of this bug is that Attributes field in smb2_file_all_info
+struct occupies the same place that EndOfFile field in
+smb311_posix_qinfo, and sometimes the latter struct is incorrectly
+processed as if it was the first one.
+
+Reported-by: Oleh Nykyforchyn <oleh.nyk@gmail.com>
+Tested-by: Oleh Nykyforchyn <oleh.nyk@gmail.com>
+Acked-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/cifsglob.h  |  1 +
+ fs/smb/client/reparse.h   | 28 ++++++++++++++++++++++------
+ fs/smb/client/smb2inode.c |  4 ++++
+ fs/smb/client/smb2ops.c   |  3 ++-
+ 4 files changed, 29 insertions(+), 7 deletions(-)
+
+diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
+index 0979feb30bedb..b630beb757a44 100644
+--- a/fs/smb/client/cifsglob.h
++++ b/fs/smb/client/cifsglob.h
+@@ -210,6 +210,7 @@ struct cifs_cred {
+ struct cifs_open_info_data {
+       bool adjust_tz;
+       bool reparse_point;
++      bool contains_posix_file_info;
+       struct {
+               /* ioctl response buffer */
+               struct {
+diff --git a/fs/smb/client/reparse.h b/fs/smb/client/reparse.h
+index ff05b0e75c928..f080f92cb1e74 100644
+--- a/fs/smb/client/reparse.h
++++ b/fs/smb/client/reparse.h
+@@ -97,14 +97,30 @@ static inline bool reparse_inode_match(struct inode *inode,
+ static inline bool cifs_open_data_reparse(struct cifs_open_info_data *data)
+ {
+-      struct smb2_file_all_info *fi = &data->fi;
+-      u32 attrs = le32_to_cpu(fi->Attributes);
++      u32 attrs;
+       bool ret;
+-      ret = data->reparse_point || (attrs & ATTR_REPARSE);
+-      if (ret)
+-              attrs |= ATTR_REPARSE;
+-      fi->Attributes = cpu_to_le32(attrs);
++      if (data->contains_posix_file_info) {
++              struct smb311_posix_qinfo *fi = &data->posix_fi;
++
++              attrs = le32_to_cpu(fi->DosAttributes);
++              if (data->reparse_point) {
++                      attrs |= ATTR_REPARSE;
++                      fi->DosAttributes = cpu_to_le32(attrs);
++              }
++
++      } else {
++              struct smb2_file_all_info *fi = &data->fi;
++
++              attrs = le32_to_cpu(fi->Attributes);
++              if (data->reparse_point) {
++                      attrs |= ATTR_REPARSE;
++                      fi->Attributes = cpu_to_le32(attrs);
++              }
++      }
++
++      ret = attrs & ATTR_REPARSE;
++
+       return ret;
+ }
+diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c
+index 7dfd3eb3847b3..6048b3fed3e78 100644
+--- a/fs/smb/client/smb2inode.c
++++ b/fs/smb/client/smb2inode.c
+@@ -648,6 +648,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+               switch (cmds[i]) {
+               case SMB2_OP_QUERY_INFO:
+                       idata = in_iov[i].iov_base;
++                      idata->contains_posix_file_info = false;
+                       if (rc == 0 && cfile && cfile->symlink_target) {
+                               idata->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL);
+                               if (!idata->symlink_target)
+@@ -671,6 +672,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+                       break;
+               case SMB2_OP_POSIX_QUERY_INFO:
+                       idata = in_iov[i].iov_base;
++                      idata->contains_posix_file_info = true;
+                       if (rc == 0 && cfile && cfile->symlink_target) {
+                               idata->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL);
+                               if (!idata->symlink_target)
+@@ -768,6 +770,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+                               idata = in_iov[i].iov_base;
+                               idata->reparse.io.iov = *iov;
+                               idata->reparse.io.buftype = resp_buftype[i + 1];
++                              idata->contains_posix_file_info = false; /* BB VERIFY */
+                               rbuf = reparse_buf_ptr(iov);
+                               if (IS_ERR(rbuf)) {
+                                       rc = PTR_ERR(rbuf);
+@@ -789,6 +792,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+               case SMB2_OP_QUERY_WSL_EA:
+                       if (!rc) {
+                               idata = in_iov[i].iov_base;
++                              idata->contains_posix_file_info = false;
+                               qi_rsp = rsp_iov[i + 1].iov_base;
+                               data[0] = (u8 *)qi_rsp + le16_to_cpu(qi_rsp->OutputBufferOffset);
+                               size[0] = le32_to_cpu(qi_rsp->OutputBufferLength);
+diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
+index e8da63d29a28f..516be8c0b2a9b 100644
+--- a/fs/smb/client/smb2ops.c
++++ b/fs/smb/client/smb2ops.c
+@@ -1001,6 +1001,7 @@ static int smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
+               if (!data->symlink_target)
+                       return -ENOMEM;
+       }
++      data->contains_posix_file_info = false;
+       return SMB2_query_info(xid, tcon, fid->persistent_fid, fid->volatile_fid, &data->fi);
+ }
+@@ -5177,7 +5178,7 @@ int __cifs_sfu_make_node(unsigned int xid, struct inode *inode,
+                            FILE_CREATE, CREATE_NOT_DIR |
+                            CREATE_OPTION_SPECIAL, ACL_NO_MODE);
+       oparms.fid = &fid;
+-
++      idata.contains_posix_file_info = false;
+       rc = server->ops->open(xid, &oparms, &oplock, &idata);
+       if (rc)
+               goto out;
+-- 
+2.39.5
+