From: Sasha Levin Date: Sat, 8 Mar 2025 14:08:42 +0000 (-0500) Subject: Fixes for 6.12 X-Git-Tag: v6.6.82~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e2a1302c141be84117c47101c6fb83ee55f5ba70;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.12 Signed-off-by: Sasha Levin --- 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 index 0000000000..df7f61e6a6 --- /dev/null +++ b/queue-6.12/btrfs-fix-data-overwriting-bug-during-buffered-write.patch @@ -0,0 +1,149 @@ +From 6226abdef75084708ec8ed2a2af6d774f6d227b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Qu Wenruo +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..b4f928d49f --- /dev/null +++ b/queue-6.12/cifs-remove-symlink-member-from-cifs_open_info_data-.patch @@ -0,0 +1,82 @@ +From a85a6faca69142a7fddbd0fd0eba6377fdf0f705 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Acked-by: Paulo Alcantara (Red Hat) +Signed-off-by: Steve French +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 +--- + 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 index 0000000000..79edcbf35b --- /dev/null +++ b/queue-6.12/drm-i915-dsi-convert-to-struct-intel_display.patch @@ -0,0 +1,1424 @@ +From 20bdb739beee60e20ffda6cadec8638ade0344f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Oct 2024 22:07:29 +0200 +Subject: drm/i915/dsi: convert to struct intel_display + +From: Jani Nikula + +[ 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 +Signed-off-by: Jani Nikula +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 +--- + 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 index 0000000000..7b011c842e --- /dev/null +++ b/queue-6.12/drm-i915-dsi-use-trans_ddi_func_ctl-s-own-port-width.patch @@ -0,0 +1,44 @@ +From a95787a96a9d4d7320053cfa41e1fcde3a49955b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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: # 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 +Signed-off-by: Imre Deak +Link: https://patchwork.freedesktop.org/patch/msgid/20250214142001.552916-2-imre.deak@intel.com +(cherry picked from commit 76120b3a304aec28fef4910204b81a12db8974da) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..30caab297b --- /dev/null +++ b/queue-6.12/gpio-vf610-add-locking-to-gpio-direction-functions.patch @@ -0,0 +1,71 @@ +From d8ee40d18b024446cd9f94a57ae9eb43c6054501 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 10:16:43 +0100 +Subject: gpio: vf610: add locking to gpio direction functions + +From: Johan Korsnes + +[ 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 +Reviewed-by: Linus Walleij +Reviewed-by: Haibo Chen +Cc: Bartosz Golaszewski +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20250217091643.679644-1-johan.korsnes@remarkable.no +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + 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 index 0000000000..2905d03161 --- /dev/null +++ b/queue-6.12/gpio-vf610-use-generic-device_get_match_data.patch @@ -0,0 +1,52 @@ +From e8d970b9443ecafb5c6becd9d61a0c122a7955f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Oct 2024 12:25:49 +0200 +Subject: gpio: vf610: use generic device_get_match_data() + +From: Bartosz Golaszewski + +[ 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 +Link: https://lore.kernel.org/r/20241007102549.34926-1-brgl@bgdev.pl +Signed-off-by: Bartosz Golaszewski +Stable-dep-of: 4e667a196809 ("gpio: vf610: add locking to gpio direction functions") +Signed-off-by: Sasha Levin +--- + 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 + #include + #include +-#include +-#include +-#include + #include ++#include ++#include + + #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 + diff --git a/queue-6.12/series b/queue-6.12/series index b65c7ec462..12dd45fc7b 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -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 index 0000000000..45b0a465aa --- /dev/null +++ b/queue-6.12/smb311-failure-to-open-files-of-length-1040-when-mou.patch @@ -0,0 +1,147 @@ +From 2be2de86617879c89c524920e55a32100b11c369 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Tested-by: Oleh Nykyforchyn +Acked-by: Paulo Alcantara (Red Hat) +Cc: stable@vger.kernel.org +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + 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 +