--- /dev/null
+From 6030d4306f4dfb8ecf9a711dbbbc29a3e3f86d98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Aug 2024 12:04:59 +0200
+Subject: ALSA: hda/tas2781: Use correct endian conversion
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit 829e2a23121fb36ee30ea5145c2a85199f68e2c8 ]
+
+The data conversion is done rather by a wrong function. We convert to
+BE32, not from BE32. Although the end result must be same, this was
+complained by the compiler.
+
+Fix the code again and align with another similar function
+tas2563_apply_calib() that does already right.
+
+Fixes: 3beddef84d90 ("ALSA: hda/tas2781: fix wrong calibrated data order")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202408141630.DiDUB8Z4-lkp@intel.com/
+Link: https://patch.msgid.link/20240814100500.1944-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/tas2781_hda_i2c.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2c.c
+index 1d4b044b78410..9e88d39eac1e2 100644
+--- a/sound/pci/hda/tas2781_hda_i2c.c
++++ b/sound/pci/hda/tas2781_hda_i2c.c
+@@ -527,8 +527,8 @@ static void tas2781_apply_calib(struct tasdevice_priv *tas_priv)
+
+ for (i = 0; i < tas_priv->ndev; i++) {
+ for (j = 0; j < CALIB_MAX; j++) {
+- data = get_unaligned_be32(
+- &tas_priv->cali_data.data[offset]);
++ data = cpu_to_be32(
++ *(uint32_t *)&tas_priv->cali_data.data[offset]);
+ rc = tasdevice_dev_bulk_write(tas_priv, i,
+ TASDEVICE_REG(0, page_array[j], rgno_array[j]),
+ (unsigned char *)&data, 4);
+--
+2.43.0
+
--- /dev/null
+From 73ca5c8a33f52f8068f04f18ba1fc903e7871326 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 May 2024 10:01:08 +0100
+Subject: cifs: Add a tracepoint to track credits involved in R/W requests
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 519be989717c5bffaed1dc14a439e3872cb4bb8d ]
+
+Add a tracepoint to track the credit changes and server in_flight value
+involved in the lifetime of a R/W request, logging it against the
+request/subreq debugging ID. This requires the debugging IDs to be
+recorded in the cifs_credits struct.
+
+The tracepoint can be enabled with:
+
+ echo 1 >/sys/kernel/debug/tracing/events/cifs/smb3_rw_credits/enable
+
+Also add a three-state flag to struct cifs_credits to note if we're
+interested in determining when the in_flight contribution ends and, if so,
+to track whether we've decremented the contribution yet.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
+cc: Jeff Layton <jlayton@kernel.org>
+cc: linux-cifs@vger.kernel.org
+cc: netfs@lists.linux.dev
+cc: linux-fsdevel@vger.kernel.org
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 74c2ab6d653b ("smb/client: avoid possible NULL dereference in cifs_free_subrequest()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/cifsglob.h | 17 +++++++-----
+ fs/smb/client/file.c | 32 ++++++++++++++++++++++-
+ fs/smb/client/smb1ops.c | 2 +-
+ fs/smb/client/smb2ops.c | 42 ++++++++++++++++++++++++++----
+ fs/smb/client/smb2pdu.c | 40 +++++++++++++++++++++++++---
+ fs/smb/client/trace.h | 55 ++++++++++++++++++++++++++++++++++++++-
+ fs/smb/client/transport.c | 8 +++---
+ 7 files changed, 173 insertions(+), 23 deletions(-)
+
+diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
+index d4bcc7da700c6..0a271b9fbc622 100644
+--- a/fs/smb/client/cifsglob.h
++++ b/fs/smb/client/cifsglob.h
+@@ -290,7 +290,7 @@ struct smb_version_operations {
+ int (*check_receive)(struct mid_q_entry *, struct TCP_Server_Info *,
+ bool);
+ void (*add_credits)(struct TCP_Server_Info *server,
+- const struct cifs_credits *credits,
++ struct cifs_credits *credits,
+ const int optype);
+ void (*set_credits)(struct TCP_Server_Info *, const int);
+ int * (*get_credits_field)(struct TCP_Server_Info *, const int);
+@@ -550,8 +550,8 @@ struct smb_version_operations {
+ size_t *, struct cifs_credits *);
+ /* adjust previously taken mtu credits to request size */
+ int (*adjust_credits)(struct TCP_Server_Info *server,
+- struct cifs_credits *credits,
+- const unsigned int payload_size);
++ struct cifs_io_subrequest *subreq,
++ unsigned int /*enum smb3_rw_credits_trace*/ trace);
+ /* check if we need to issue closedir */
+ bool (*dir_needs_close)(struct cifsFileInfo *);
+ long (*fallocate)(struct file *, struct cifs_tcon *, int, loff_t,
+@@ -848,6 +848,9 @@ static inline void cifs_server_unlock(struct TCP_Server_Info *server)
+ struct cifs_credits {
+ unsigned int value;
+ unsigned int instance;
++ unsigned int in_flight_check;
++ unsigned int rreq_debug_id;
++ unsigned int rreq_debug_index;
+ };
+
+ static inline unsigned int
+@@ -873,7 +876,7 @@ has_credits(struct TCP_Server_Info *server, int *credits, int num_credits)
+ }
+
+ static inline void
+-add_credits(struct TCP_Server_Info *server, const struct cifs_credits *credits,
++add_credits(struct TCP_Server_Info *server, struct cifs_credits *credits,
+ const int optype)
+ {
+ server->ops->add_credits(server, credits, optype);
+@@ -897,11 +900,11 @@ set_credits(struct TCP_Server_Info *server, const int val)
+ }
+
+ static inline int
+-adjust_credits(struct TCP_Server_Info *server, struct cifs_credits *credits,
+- const unsigned int payload_size)
++adjust_credits(struct TCP_Server_Info *server, struct cifs_io_subrequest *subreq,
++ unsigned int /* enum smb3_rw_credits_trace */ trace)
+ {
+ return server->ops->adjust_credits ?
+- server->ops->adjust_credits(server, credits, payload_size) : 0;
++ server->ops->adjust_credits(server, subreq, trace) : 0;
+ }
+
+ static inline __le64
+diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
+index 9e4f4e67768b9..b413cfef05422 100644
+--- a/fs/smb/client/file.c
++++ b/fs/smb/client/file.c
+@@ -80,6 +80,16 @@ static void cifs_prepare_write(struct netfs_io_subrequest *subreq)
+ return netfs_prepare_write_failed(subreq);
+ }
+
++ wdata->credits.rreq_debug_id = subreq->rreq->debug_id;
++ wdata->credits.rreq_debug_index = subreq->debug_index;
++ wdata->credits.in_flight_check = 1;
++ trace_smb3_rw_credits(wdata->rreq->debug_id,
++ wdata->subreq.debug_index,
++ wdata->credits.value,
++ server->credits, server->in_flight,
++ wdata->credits.value,
++ cifs_trace_rw_credits_write_prepare);
++
+ #ifdef CONFIG_CIFS_SMB_DIRECT
+ if (server->smbd_conn)
+ subreq->max_nr_segs = server->smbd_conn->max_frmr_depth;
+@@ -101,7 +111,7 @@ static void cifs_issue_write(struct netfs_io_subrequest *subreq)
+ goto fail;
+ }
+
+- rc = adjust_credits(wdata->server, &wdata->credits, wdata->subreq.len);
++ rc = adjust_credits(wdata->server, wdata, cifs_trace_rw_credits_issue_write_adjust);
+ if (rc)
+ goto fail;
+
+@@ -163,7 +173,18 @@ static bool cifs_clamp_length(struct netfs_io_subrequest *subreq)
+ return false;
+ }
+
++ rdata->credits.in_flight_check = 1;
++ rdata->credits.rreq_debug_id = rreq->debug_id;
++ rdata->credits.rreq_debug_index = subreq->debug_index;
++
++ trace_smb3_rw_credits(rdata->rreq->debug_id,
++ rdata->subreq.debug_index,
++ rdata->credits.value,
++ server->credits, server->in_flight, 0,
++ cifs_trace_rw_credits_read_submit);
++
+ subreq->len = min_t(size_t, subreq->len, rsize);
++
+ #ifdef CONFIG_CIFS_SMB_DIRECT
+ if (server->smbd_conn)
+ subreq->max_nr_segs = server->smbd_conn->max_frmr_depth;
+@@ -295,6 +316,15 @@ static void cifs_free_subrequest(struct netfs_io_subrequest *subreq)
+ #endif
+ }
+
++ if (rdata->credits.value != 0)
++ trace_smb3_rw_credits(rdata->rreq->debug_id,
++ rdata->subreq.debug_index,
++ rdata->credits.value,
++ rdata->server ? rdata->server->credits : 0,
++ rdata->server ? rdata->server->in_flight : 0,
++ -rdata->credits.value,
++ cifs_trace_rw_credits_free_subreq);
++
+ add_credits_and_wake_if(rdata->server, &rdata->credits, 0);
+ if (rdata->have_xid)
+ free_xid(rdata->xid);
+diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
+index 212ec6f66ec65..e1f2feb56f45f 100644
+--- a/fs/smb/client/smb1ops.c
++++ b/fs/smb/client/smb1ops.c
+@@ -108,7 +108,7 @@ cifs_find_mid(struct TCP_Server_Info *server, char *buffer)
+
+ static void
+ cifs_add_credits(struct TCP_Server_Info *server,
+- const struct cifs_credits *credits, const int optype)
++ struct cifs_credits *credits, const int optype)
+ {
+ spin_lock(&server->req_lock);
+ server->credits += credits->value;
+diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
+index c8e536540895a..7fe59235f0901 100644
+--- a/fs/smb/client/smb2ops.c
++++ b/fs/smb/client/smb2ops.c
+@@ -66,7 +66,7 @@ change_conf(struct TCP_Server_Info *server)
+
+ static void
+ smb2_add_credits(struct TCP_Server_Info *server,
+- const struct cifs_credits *credits, const int optype)
++ struct cifs_credits *credits, const int optype)
+ {
+ int *val, rc = -1;
+ int scredits, in_flight;
+@@ -94,7 +94,21 @@ smb2_add_credits(struct TCP_Server_Info *server,
+ server->conn_id, server->hostname, *val,
+ add, server->in_flight);
+ }
+- WARN_ON_ONCE(server->in_flight == 0);
++ if (credits->in_flight_check > 1) {
++ pr_warn_once("rreq R=%08x[%x] Credits not in flight\n",
++ credits->rreq_debug_id, credits->rreq_debug_index);
++ } else {
++ credits->in_flight_check = 2;
++ }
++ if (WARN_ON_ONCE(server->in_flight == 0)) {
++ pr_warn_once("rreq R=%08x[%x] Zero in_flight\n",
++ credits->rreq_debug_id, credits->rreq_debug_index);
++ trace_smb3_rw_credits(credits->rreq_debug_id,
++ credits->rreq_debug_index,
++ credits->value,
++ server->credits, server->in_flight, 0,
++ cifs_trace_rw_credits_zero_in_flight);
++ }
+ server->in_flight--;
+ if (server->in_flight == 0 &&
+ ((optype & CIFS_OP_MASK) != CIFS_NEG_OP) &&
+@@ -283,16 +297,23 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, size_t size,
+
+ static int
+ smb2_adjust_credits(struct TCP_Server_Info *server,
+- struct cifs_credits *credits,
+- const unsigned int payload_size)
++ struct cifs_io_subrequest *subreq,
++ unsigned int /*enum smb3_rw_credits_trace*/ trace)
+ {
+- int new_val = DIV_ROUND_UP(payload_size, SMB2_MAX_BUFFER_SIZE);
++ struct cifs_credits *credits = &subreq->credits;
++ int new_val = DIV_ROUND_UP(subreq->subreq.len, SMB2_MAX_BUFFER_SIZE);
+ int scredits, in_flight;
+
+ if (!credits->value || credits->value == new_val)
+ return 0;
+
+ if (credits->value < new_val) {
++ trace_smb3_rw_credits(subreq->rreq->debug_id,
++ subreq->subreq.debug_index,
++ credits->value,
++ server->credits, server->in_flight,
++ new_val - credits->value,
++ cifs_trace_rw_credits_no_adjust_up);
+ trace_smb3_too_many_credits(server->CurrentMid,
+ server->conn_id, server->hostname, 0, credits->value - new_val, 0);
+ cifs_server_dbg(VFS, "request has less credits (%d) than required (%d)",
+@@ -308,6 +329,12 @@ smb2_adjust_credits(struct TCP_Server_Info *server,
+ in_flight = server->in_flight;
+ spin_unlock(&server->req_lock);
+
++ trace_smb3_rw_credits(subreq->rreq->debug_id,
++ subreq->subreq.debug_index,
++ credits->value,
++ server->credits, server->in_flight,
++ new_val - credits->value,
++ cifs_trace_rw_credits_old_session);
+ trace_smb3_reconnect_detected(server->CurrentMid,
+ server->conn_id, server->hostname, scredits,
+ credits->value - new_val, in_flight);
+@@ -316,6 +343,11 @@ smb2_adjust_credits(struct TCP_Server_Info *server,
+ return -EAGAIN;
+ }
+
++ trace_smb3_rw_credits(subreq->rreq->debug_id,
++ subreq->subreq.debug_index,
++ credits->value,
++ server->credits, server->in_flight,
++ new_val - credits->value, trace);
+ server->credits += credits->value - new_val;
+ scredits = server->credits;
+ in_flight = server->in_flight;
+diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
+index 896147ba6660e..4cd5c33be2a1a 100644
+--- a/fs/smb/client/smb2pdu.c
++++ b/fs/smb/client/smb2pdu.c
+@@ -4505,8 +4505,15 @@ smb2_readv_callback(struct mid_q_entry *mid)
+ struct TCP_Server_Info *server = rdata->server;
+ struct smb2_hdr *shdr =
+ (struct smb2_hdr *)rdata->iov[0].iov_base;
+- struct cifs_credits credits = { .value = 0, .instance = 0 };
++ struct cifs_credits credits = {
++ .value = 0,
++ .instance = 0,
++ .rreq_debug_id = rdata->rreq->debug_id,
++ .rreq_debug_index = rdata->subreq.debug_index,
++ };
+ struct smb_rqst rqst = { .rq_iov = &rdata->iov[1], .rq_nvec = 1 };
++ unsigned int rreq_debug_id = rdata->rreq->debug_id;
++ unsigned int subreq_debug_index = rdata->subreq.debug_index;
+
+ if (rdata->got_bytes) {
+ rqst.rq_iter = rdata->subreq.io_iter;
+@@ -4590,10 +4597,16 @@ smb2_readv_callback(struct mid_q_entry *mid)
+ if (rdata->subreq.start < rdata->subreq.rreq->i_size)
+ rdata->result = 0;
+ }
++ trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, rdata->credits.value,
++ server->credits, server->in_flight,
++ 0, cifs_trace_rw_credits_read_response_clear);
+ rdata->credits.value = 0;
+ INIT_WORK(&rdata->subreq.work, smb2_readv_worker);
+ queue_work(cifsiod_wq, &rdata->subreq.work);
+ release_mid(mid);
++ trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0,
++ server->credits, server->in_flight,
++ credits.value, cifs_trace_rw_credits_read_response_add);
+ add_credits(server, &credits, 0);
+ }
+
+@@ -4650,7 +4663,7 @@ smb2_async_readv(struct cifs_io_subrequest *rdata)
+ min_t(int, server->max_credits -
+ server->credits, credit_request));
+
+- rc = adjust_credits(server, &rdata->credits, rdata->subreq.len);
++ rc = adjust_credits(server, rdata, cifs_trace_rw_credits_call_readv_adjust);
+ if (rc)
+ goto async_readv_out;
+
+@@ -4769,7 +4782,14 @@ smb2_writev_callback(struct mid_q_entry *mid)
+ struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
+ struct TCP_Server_Info *server = wdata->server;
+ struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf;
+- struct cifs_credits credits = { .value = 0, .instance = 0 };
++ struct cifs_credits credits = {
++ .value = 0,
++ .instance = 0,
++ .rreq_debug_id = wdata->rreq->debug_id,
++ .rreq_debug_index = wdata->subreq.debug_index,
++ };
++ unsigned int rreq_debug_id = wdata->rreq->debug_id;
++ unsigned int subreq_debug_index = wdata->subreq.debug_index;
+ ssize_t result = 0;
+ size_t written;
+
+@@ -4840,9 +4860,15 @@ smb2_writev_callback(struct mid_q_entry *mid)
+ tcon->tid, tcon->ses->Suid,
+ wdata->subreq.start, wdata->subreq.len);
+
++ trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, wdata->credits.value,
++ server->credits, server->in_flight,
++ 0, cifs_trace_rw_credits_write_response_clear);
+ wdata->credits.value = 0;
+ cifs_write_subrequest_terminated(wdata, result ?: written, true);
+ release_mid(mid);
++ trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0,
++ server->credits, server->in_flight,
++ credits.value, cifs_trace_rw_credits_write_response_add);
+ add_credits(server, &credits, 0);
+ }
+
+@@ -4972,7 +4998,7 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
+ min_t(int, server->max_credits -
+ server->credits, credit_request));
+
+- rc = adjust_credits(server, &wdata->credits, io_parms->length);
++ rc = adjust_credits(server, wdata, cifs_trace_rw_credits_call_writev_adjust);
+ if (rc)
+ goto async_writev_out;
+
+@@ -4997,6 +5023,12 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
+ cifs_small_buf_release(req);
+ out:
+ if (rc) {
++ trace_smb3_rw_credits(wdata->rreq->debug_id,
++ wdata->subreq.debug_index,
++ wdata->credits.value,
++ server->credits, server->in_flight,
++ -(int)wdata->credits.value,
++ cifs_trace_rw_credits_write_response_clear);
+ add_credits_and_wake_if(wdata->server, &wdata->credits, 0);
+ cifs_write_subrequest_terminated(wdata, rc, true);
+ }
+diff --git a/fs/smb/client/trace.h b/fs/smb/client/trace.h
+index 36d47ce596317..36d5295c2a6f9 100644
+--- a/fs/smb/client/trace.h
++++ b/fs/smb/client/trace.h
+@@ -20,6 +20,22 @@
+ /*
+ * Specify enums for tracing information.
+ */
++#define smb3_rw_credits_traces \
++ EM(cifs_trace_rw_credits_call_readv_adjust, "rd-call-adj") \
++ EM(cifs_trace_rw_credits_call_writev_adjust, "wr-call-adj") \
++ EM(cifs_trace_rw_credits_free_subreq, "free-subreq") \
++ EM(cifs_trace_rw_credits_issue_read_adjust, "rd-issu-adj") \
++ EM(cifs_trace_rw_credits_issue_write_adjust, "wr-issu-adj") \
++ EM(cifs_trace_rw_credits_no_adjust_up, "no-adj-up ") \
++ EM(cifs_trace_rw_credits_old_session, "old-session") \
++ EM(cifs_trace_rw_credits_read_response_add, "rd-resp-add") \
++ EM(cifs_trace_rw_credits_read_response_clear, "rd-resp-clr") \
++ EM(cifs_trace_rw_credits_read_submit, "rd-submit ") \
++ EM(cifs_trace_rw_credits_write_prepare, "wr-prepare ") \
++ EM(cifs_trace_rw_credits_write_response_add, "wr-resp-add") \
++ EM(cifs_trace_rw_credits_write_response_clear, "wr-resp-clr") \
++ E_(cifs_trace_rw_credits_zero_in_flight, "ZERO-IN-FLT")
++
+ #define smb3_tcon_ref_traces \
+ EM(netfs_trace_tcon_ref_dec_dfs_refer, "DEC DfsRef") \
+ EM(netfs_trace_tcon_ref_free, "FRE ") \
+@@ -59,7 +75,8 @@
+ #define EM(a, b) a,
+ #define E_(a, b) a
+
+-enum smb3_tcon_ref_trace { smb3_tcon_ref_traces } __mode(byte);
++enum smb3_rw_credits_trace { smb3_rw_credits_traces } __mode(byte);
++enum smb3_tcon_ref_trace { smb3_tcon_ref_traces } __mode(byte);
+
+ #undef EM
+ #undef E_
+@@ -71,6 +88,7 @@ enum smb3_tcon_ref_trace { smb3_tcon_ref_traces } __mode(byte);
+ #define EM(a, b) TRACE_DEFINE_ENUM(a);
+ #define E_(a, b) TRACE_DEFINE_ENUM(a);
+
++smb3_rw_credits_traces;
+ smb3_tcon_ref_traces;
+
+ #undef EM
+@@ -1316,6 +1334,41 @@ TRACE_EVENT(smb3_tcon_ref,
+ __entry->ref)
+ );
+
++TRACE_EVENT(smb3_rw_credits,
++ TP_PROTO(unsigned int rreq_debug_id,
++ unsigned int subreq_debug_index,
++ unsigned int subreq_credits,
++ unsigned int server_credits,
++ int server_in_flight,
++ int credit_change,
++ enum smb3_rw_credits_trace trace),
++ TP_ARGS(rreq_debug_id, subreq_debug_index, subreq_credits,
++ server_credits, server_in_flight, credit_change, trace),
++ TP_STRUCT__entry(
++ __field(unsigned int, rreq_debug_id)
++ __field(unsigned int, subreq_debug_index)
++ __field(unsigned int, subreq_credits)
++ __field(unsigned int, server_credits)
++ __field(int, in_flight)
++ __field(int, credit_change)
++ __field(enum smb3_rw_credits_trace, trace)
++ ),
++ TP_fast_assign(
++ __entry->rreq_debug_id = rreq_debug_id;
++ __entry->subreq_debug_index = subreq_debug_index;
++ __entry->subreq_credits = subreq_credits;
++ __entry->server_credits = server_credits;
++ __entry->in_flight = server_in_flight;
++ __entry->credit_change = credit_change;
++ __entry->trace = trace;
++ ),
++ TP_printk("R=%08x[%x] %s cred=%u chg=%d pool=%u ifl=%d",
++ __entry->rreq_debug_id, __entry->subreq_debug_index,
++ __print_symbolic(__entry->trace, smb3_rw_credits_traces),
++ __entry->subreq_credits, __entry->credit_change,
++ __entry->server_credits, __entry->in_flight)
++ );
++
+
+ #undef EM
+ #undef E_
+diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
+index 012b9bd069952..adfe0d0587010 100644
+--- a/fs/smb/client/transport.c
++++ b/fs/smb/client/transport.c
+@@ -988,10 +988,10 @@ static void
+ cifs_compound_callback(struct mid_q_entry *mid)
+ {
+ struct TCP_Server_Info *server = mid->server;
+- struct cifs_credits credits;
+-
+- credits.value = server->ops->get_credits(mid);
+- credits.instance = server->reconnect_instance;
++ struct cifs_credits credits = {
++ .value = server->ops->get_credits(mid),
++ .instance = server->reconnect_instance,
++ };
+
+ add_credits(server, &credits, mid->optype);
+
+--
+2.43.0
+
--- /dev/null
+From b79c7bdeec796b5a7117ca1f4c949bf70591d793 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Aug 2024 12:38:51 +0200
+Subject: dm suspend: return -ERESTARTSYS instead of -EINTR
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+[ Upstream commit 1e1fd567d32fcf7544c6e09e0e5bc6c650da6e23 ]
+
+This commit changes device mapper, so that it returns -ERESTARTSYS
+instead of -EINTR when it is interrupted by a signal (so that the ioctl
+can be restarted).
+
+The manpage signal(7) says that the ioctl function should be restarted if
+the signal was handled with SA_RESTART.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 13037d6a6f62a..6e15ac4e0845c 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -2594,7 +2594,7 @@ static int dm_wait_for_bios_completion(struct mapped_device *md, unsigned int ta
+ break;
+
+ if (signal_pending_state(task_state, current)) {
+- r = -EINTR;
++ r = -ERESTARTSYS;
+ break;
+ }
+
+@@ -2619,7 +2619,7 @@ static int dm_wait_for_completion(struct mapped_device *md, unsigned int task_st
+ break;
+
+ if (signal_pending_state(task_state, current)) {
+- r = -EINTR;
++ r = -ERESTARTSYS;
+ break;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 0db55dc7f29d49fdbbfc9d15ccd77d837f04b80f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Aug 2024 14:46:44 +0200
+Subject: platform/surface: aggregator: Fix warning when controller is
+ destroyed in probe
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maximilian Luz <luzmaximilian@gmail.com>
+
+[ Upstream commit bc923d594db21bee0ead128eb4bb78f7e77467a4 ]
+
+There is a small window in ssam_serial_hub_probe() where the controller
+is initialized but has not been started yet. Specifically, between
+ssam_controller_init() and ssam_controller_start(). Any failure in this
+window, for example caused by a failure of serdev_device_open(),
+currently results in an incorrect warning being emitted.
+
+In particular, any failure in this window results in the controller
+being destroyed via ssam_controller_destroy(). This function checks the
+state of the controller and, in an attempt to validate that the
+controller has been cleanly shut down before we try and deallocate any
+resources, emits a warning if that state is not SSAM_CONTROLLER_STOPPED.
+
+However, since we have only just initialized the controller and have not
+yet started it, its state is SSAM_CONTROLLER_INITIALIZED. Note that this
+is the only point at which the controller has this state, as it will
+change after we start the controller with ssam_controller_start() and
+never revert back. Further, at this point no communication has taken
+place and the sender and receiver threads have not been started yet (and
+we may not even have an open serdev device either).
+
+Therefore, it is perfectly safe to call ssam_controller_destroy() with a
+state of SSAM_CONTROLLER_INITIALIZED. This, however, means that the
+warning currently being emitted is incorrect. Fix it by extending the
+check.
+
+Fixes: c167b9c7e3d6 ("platform/surface: Add Surface Aggregator subsystem")
+Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
+Link: https://lore.kernel.org/r/20240811124645.246016-1-luzmaximilian@gmail.com
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/surface/aggregator/controller.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/platform/surface/aggregator/controller.c b/drivers/platform/surface/aggregator/controller.c
+index 7fc602e01487d..7e89f547999b2 100644
+--- a/drivers/platform/surface/aggregator/controller.c
++++ b/drivers/platform/surface/aggregator/controller.c
+@@ -1354,7 +1354,8 @@ void ssam_controller_destroy(struct ssam_controller *ctrl)
+ if (ctrl->state == SSAM_CONTROLLER_UNINITIALIZED)
+ return;
+
+- WARN_ON(ctrl->state != SSAM_CONTROLLER_STOPPED);
++ WARN_ON(ctrl->state != SSAM_CONTROLLER_STOPPED &&
++ ctrl->state != SSAM_CONTROLLER_INITIALIZED);
+
+ /*
+ * Note: New events could still have been received after the previous
+--
+2.43.0
+
arm64-fix-kasan-random-tag-seed-initialization.patch
block-fix-lockdep-warning-in-blk_mq_mark_tag_wait.patch
drm-amd-display-don-t-register-panel_power_savings-on-oled-panels.patch
+thermal-gov_bang_bang-drop-unnecessary-cooling-devic.patch
+thermal-gov_bang_bang-split-bang_bang_control.patch
+thermal-gov_bang_bang-add-.manage-callback.patch
+thermal-gov_bang_bang-use-governor_data-to-reduce-ov.patch
+cifs-add-a-tracepoint-to-track-credits-involved-in-r.patch
+smb-client-avoid-possible-null-dereference-in-cifs_f.patch
+dm-suspend-return-erestartsys-instead-of-eintr.patch
+wifi-ath12k-use-128-bytes-aligned-iova-in-transmit-p.patch
+platform-surface-aggregator-fix-warning-when-control.patch
+alsa-hda-tas2781-use-correct-endian-conversion.patch
--- /dev/null
+From 91ee85fb8eaf49b895086f7bb4ce80df52e5911d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Aug 2024 20:23:32 +0800
+Subject: smb/client: avoid possible NULL dereference in cifs_free_subrequest()
+
+From: Su Hui <suhui@nfschina.com>
+
+[ Upstream commit 74c2ab6d653b4c2354df65a7f7f2df1925a40a51 ]
+
+Clang static checker (scan-build) warning:
+ cifsglob.h:line 890, column 3
+ Access to field 'ops' results in a dereference of a null pointer.
+
+Commit 519be989717c ("cifs: Add a tracepoint to track credits involved in
+R/W requests") adds a check for 'rdata->server', and let clang throw this
+warning about NULL dereference.
+
+When 'rdata->credits.value != 0 && rdata->server == NULL' happens,
+add_credits_and_wake_if() will call rdata->server->ops->add_credits().
+This will cause NULL dereference problem. Add a check for 'rdata->server'
+to avoid NULL dereference.
+
+Cc: stable@vger.kernel.org
+Fixes: 69c3c023af25 ("cifs: Implement netfslib hooks")
+Reviewed-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Su Hui <suhui@nfschina.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/file.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
+index b413cfef05422..1fc66bcf49eb4 100644
+--- a/fs/smb/client/file.c
++++ b/fs/smb/client/file.c
+@@ -316,7 +316,7 @@ static void cifs_free_subrequest(struct netfs_io_subrequest *subreq)
+ #endif
+ }
+
+- if (rdata->credits.value != 0)
++ if (rdata->credits.value != 0) {
+ trace_smb3_rw_credits(rdata->rreq->debug_id,
+ rdata->subreq.debug_index,
+ rdata->credits.value,
+@@ -324,8 +324,12 @@ static void cifs_free_subrequest(struct netfs_io_subrequest *subreq)
+ rdata->server ? rdata->server->in_flight : 0,
+ -rdata->credits.value,
+ cifs_trace_rw_credits_free_subreq);
++ if (rdata->server)
++ add_credits_and_wake_if(rdata->server, &rdata->credits, 0);
++ else
++ rdata->credits.value = 0;
++ }
+
+- add_credits_and_wake_if(rdata->server, &rdata->credits, 0);
+ if (rdata->have_xid)
+ free_xid(rdata->xid);
+ }
+--
+2.43.0
+
--- /dev/null
+From 71c567b10c8c1606f37f0a28cf80e03a27cd4008 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Aug 2024 16:27:33 +0200
+Subject: thermal: gov_bang_bang: Add .manage() callback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 5f64b4a1ab1b0412446d42e1fc2964c2cdb60b27 ]
+
+After recent changes, the Bang-bang governor may not adjust the
+initial configuration of cooling devices to the actual situation.
+
+Namely, if a cooling device bound to a certain trip point starts in
+the "on" state and the thermal zone temperature is below the threshold
+of that trip point, the trip point may never be crossed on the way up
+in which case the state of the cooling device will never be adjusted
+because the thermal core will never invoke the governor's
+.trip_crossed() callback. [Note that there is no issue if the zone
+temperature is at the trip threshold or above it to start with because
+.trip_crossed() will be invoked then to indicate the start of thermal
+mitigation for the given trip.]
+
+To address this, add a .manage() callback to the Bang-bang governor
+and use it to ensure that all of the thermal instances managed by the
+governor have been initialized properly and the states of all of the
+cooling devices involved have been adjusted to the current zone
+temperature as appropriate.
+
+Fixes: 530c932bdf75 ("thermal: gov_bang_bang: Use .trip_crossed() instead of .throttle()")
+Link: https://lore.kernel.org/linux-pm/1bfbbae5-42b0-4c7d-9544-e98855715294@piie.net/
+Cc: 6.10+ <stable@vger.kernel.org> # 6.10+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Peter Kästle <peter@piie.net>
+Reviewed-by: Zhang Rui <rui.zhang@intel.com>
+Link: https://patch.msgid.link/8419356.T7Z3S40VBb@rjwysocki.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/gov_bang_bang.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/drivers/thermal/gov_bang_bang.c b/drivers/thermal/gov_bang_bang.c
+index 87cff3ea77a9d..bc55e0698bfa8 100644
+--- a/drivers/thermal/gov_bang_bang.c
++++ b/drivers/thermal/gov_bang_bang.c
+@@ -26,6 +26,7 @@ static void bang_bang_set_instance_target(struct thermal_instance *instance,
+ * when the trip is crossed on the way down.
+ */
+ instance->target = target;
++ instance->initialized = true;
+
+ dev_dbg(&instance->cdev->device, "target=%ld\n", instance->target);
+
+@@ -80,8 +81,37 @@ static void bang_bang_control(struct thermal_zone_device *tz,
+ }
+ }
+
++static void bang_bang_manage(struct thermal_zone_device *tz)
++{
++ const struct thermal_trip_desc *td;
++ struct thermal_instance *instance;
++
++ for_each_trip_desc(tz, td) {
++ const struct thermal_trip *trip = &td->trip;
++
++ if (tz->temperature >= td->threshold ||
++ trip->temperature == THERMAL_TEMP_INVALID ||
++ trip->type == THERMAL_TRIP_CRITICAL ||
++ trip->type == THERMAL_TRIP_HOT)
++ continue;
++
++ /*
++ * If the initial cooling device state is "on", but the zone
++ * temperature is not above the trip point, the core will not
++ * call bang_bang_control() until the zone temperature reaches
++ * the trip point temperature which may be never. In those
++ * cases, set the initial state of the cooling device to 0.
++ */
++ list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
++ if (!instance->initialized && instance->trip == trip)
++ bang_bang_set_instance_target(instance, 0);
++ }
++ }
++}
++
+ static struct thermal_governor thermal_gov_bang_bang = {
+ .name = "bang_bang",
+ .trip_crossed = bang_bang_control,
++ .manage = bang_bang_manage,
+ };
+ THERMAL_GOVERNOR_DECLARE(thermal_gov_bang_bang);
+--
+2.43.0
+
--- /dev/null
+From 7f264d9ef29607f68e28313a85b02df8c6e36811 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 May 2024 18:54:01 +0200
+Subject: thermal: gov_bang_bang: Drop unnecessary cooling device target state
+ checks
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 2c637af8a74d9a2a52ee5456a75dd29c8cb52da5 ]
+
+Some cooling device target state checks in bang_bang_control()
+done before setting the new target state are not necessary after
+recent changes, so drop them.
+
+Also avoid updating the target state before checking it for
+unexpected values.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: 84248e35d9b6 ("thermal: gov_bang_bang: Split bang_bang_control()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/gov_bang_bang.c | 14 +++-----------
+ 1 file changed, 3 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/thermal/gov_bang_bang.c b/drivers/thermal/gov_bang_bang.c
+index 2a6a651e9d921..b9474c6af72b5 100644
+--- a/drivers/thermal/gov_bang_bang.c
++++ b/drivers/thermal/gov_bang_bang.c
+@@ -57,24 +57,16 @@ static void bang_bang_control(struct thermal_zone_device *tz,
+ if (instance->trip != trip)
+ continue;
+
+- if (instance->target == THERMAL_NO_TARGET)
+- instance->target = 0;
+-
+- if (instance->target != 0 && instance->target != 1) {
++ if (instance->target != 0 && instance->target != 1 &&
++ instance->target != THERMAL_NO_TARGET)
+ pr_debug("Unexpected state %ld of thermal instance %s in bang-bang\n",
+ instance->target, instance->name);
+
+- instance->target = 1;
+- }
+-
+ /*
+ * Enable the fan when the trip is crossed on the way up and
+ * disable it when the trip is crossed on the way down.
+ */
+- if (instance->target == 0 && crossed_up)
+- instance->target = 1;
+- else if (instance->target == 1 && !crossed_up)
+- instance->target = 0;
++ instance->target = crossed_up;
+
+ dev_dbg(&instance->cdev->device, "target=%ld\n", instance->target);
+
+--
+2.43.0
+
--- /dev/null
+From f9f2d2275908b83d8127e718a2698e1fcec4a888 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Aug 2024 16:26:42 +0200
+Subject: thermal: gov_bang_bang: Split bang_bang_control()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 84248e35d9b60e03df7276627e4e91fbaf80f73d ]
+
+Move the setting of the thermal instance target state from
+bang_bang_control() into a separate function that will be also called
+in a different place going forward.
+
+No intentional functional impact.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Peter Kästle <peter@piie.net>
+Reviewed-by: Zhang Rui <rui.zhang@intel.com>
+Cc: 6.10+ <stable@vger.kernel.org> # 6.10+
+Link: https://patch.msgid.link/3313587.aeNJFYEL58@rjwysocki.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/gov_bang_bang.c | 42 ++++++++++++++++++---------------
+ 1 file changed, 23 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/thermal/gov_bang_bang.c b/drivers/thermal/gov_bang_bang.c
+index b9474c6af72b5..87cff3ea77a9d 100644
+--- a/drivers/thermal/gov_bang_bang.c
++++ b/drivers/thermal/gov_bang_bang.c
+@@ -13,6 +13,27 @@
+
+ #include "thermal_core.h"
+
++static void bang_bang_set_instance_target(struct thermal_instance *instance,
++ unsigned int target)
++{
++ if (instance->target != 0 && instance->target != 1 &&
++ instance->target != THERMAL_NO_TARGET)
++ pr_debug("Unexpected state %ld of thermal instance %s in bang-bang\n",
++ instance->target, instance->name);
++
++ /*
++ * Enable the fan when the trip is crossed on the way up and disable it
++ * when the trip is crossed on the way down.
++ */
++ instance->target = target;
++
++ dev_dbg(&instance->cdev->device, "target=%ld\n", instance->target);
++
++ mutex_lock(&instance->cdev->lock);
++ __thermal_cdev_update(instance->cdev);
++ mutex_unlock(&instance->cdev->lock);
++}
++
+ /**
+ * bang_bang_control - controls devices associated with the given zone
+ * @tz: thermal_zone_device
+@@ -54,25 +75,8 @@ static void bang_bang_control(struct thermal_zone_device *tz,
+ tz->temperature, trip->hysteresis);
+
+ list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
+- if (instance->trip != trip)
+- continue;
+-
+- if (instance->target != 0 && instance->target != 1 &&
+- instance->target != THERMAL_NO_TARGET)
+- pr_debug("Unexpected state %ld of thermal instance %s in bang-bang\n",
+- instance->target, instance->name);
+-
+- /*
+- * Enable the fan when the trip is crossed on the way up and
+- * disable it when the trip is crossed on the way down.
+- */
+- instance->target = crossed_up;
+-
+- dev_dbg(&instance->cdev->device, "target=%ld\n", instance->target);
+-
+- mutex_lock(&instance->cdev->lock);
+- __thermal_cdev_update(instance->cdev);
+- mutex_unlock(&instance->cdev->lock);
++ if (instance->trip == trip)
++ bang_bang_set_instance_target(instance, crossed_up);
+ }
+ }
+
+--
+2.43.0
+
--- /dev/null
+From a2255a4d4ad531959dcd058dccf6b6048bbed71d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Aug 2024 16:29:11 +0200
+Subject: thermal: gov_bang_bang: Use governor_data to reduce overhead
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 6e6f58a170ea98e44075b761f2da42a5aec47dfb ]
+
+After running once, the for_each_trip_desc() loop in
+bang_bang_manage() is pure needless overhead because it is not going to
+make any changes unless a new cooling device has been bound to one of
+the trips in the thermal zone or the system is resuming from sleep.
+
+For this reason, make bang_bang_manage() set governor_data for the
+thermal zone and check it upfront to decide whether or not it needs to
+do anything.
+
+However, governor_data needs to be reset in some cases to let
+bang_bang_manage() know that it should walk the trips again, so add an
+.update_tz() callback to the governor and make the core additionally
+invoke it during system resume.
+
+To avoid affecting the other users of that callback unnecessarily, add
+a special notification reason for system resume, THERMAL_TZ_RESUME, and
+also pass it to __thermal_zone_device_update() called during system
+resume for consistency.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Peter Kästle <peter@piie.net>
+Reviewed-by: Zhang Rui <rui.zhang@intel.com>
+Cc: 6.10+ <stable@vger.kernel.org> # 6.10+
+Link: https://patch.msgid.link/2285575.iZASKD2KPV@rjwysocki.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/gov_bang_bang.c | 18 ++++++++++++++++++
+ drivers/thermal/thermal_core.c | 3 ++-
+ include/linux/thermal.h | 1 +
+ 3 files changed, 21 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/gov_bang_bang.c b/drivers/thermal/gov_bang_bang.c
+index bc55e0698bfa8..daed67d19efb8 100644
+--- a/drivers/thermal/gov_bang_bang.c
++++ b/drivers/thermal/gov_bang_bang.c
+@@ -86,6 +86,10 @@ static void bang_bang_manage(struct thermal_zone_device *tz)
+ const struct thermal_trip_desc *td;
+ struct thermal_instance *instance;
+
++ /* If the code below has run already, nothing needs to be done. */
++ if (tz->governor_data)
++ return;
++
+ for_each_trip_desc(tz, td) {
+ const struct thermal_trip *trip = &td->trip;
+
+@@ -107,11 +111,25 @@ static void bang_bang_manage(struct thermal_zone_device *tz)
+ bang_bang_set_instance_target(instance, 0);
+ }
+ }
++
++ tz->governor_data = (void *)true;
++}
++
++static void bang_bang_update_tz(struct thermal_zone_device *tz,
++ enum thermal_notify_event reason)
++{
++ /*
++ * Let bang_bang_manage() know that it needs to walk trips after binding
++ * a new cdev and after system resume.
++ */
++ if (reason == THERMAL_TZ_BIND_CDEV || reason == THERMAL_TZ_RESUME)
++ tz->governor_data = NULL;
+ }
+
+ static struct thermal_governor thermal_gov_bang_bang = {
+ .name = "bang_bang",
+ .trip_crossed = bang_bang_control,
+ .manage = bang_bang_manage,
++ .update_tz = bang_bang_update_tz,
+ };
+ THERMAL_GOVERNOR_DECLARE(thermal_gov_bang_bang);
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index f2d31bc48f529..b8d889ef4fa5e 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -1715,7 +1715,8 @@ static void thermal_zone_device_resume(struct work_struct *work)
+ tz->suspended = false;
+
+ thermal_zone_device_init(tz);
+- __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
++ thermal_governor_update_tz(tz, THERMAL_TZ_RESUME);
++ __thermal_zone_device_update(tz, THERMAL_TZ_RESUME);
+
+ complete(&tz->resume);
+ tz->resuming = false;
+diff --git a/include/linux/thermal.h b/include/linux/thermal.h
+index f1155c0439c4b..13f88317b81bf 100644
+--- a/include/linux/thermal.h
++++ b/include/linux/thermal.h
+@@ -55,6 +55,7 @@ enum thermal_notify_event {
+ THERMAL_TZ_BIND_CDEV, /* Cooling dev is bind to the thermal zone */
+ THERMAL_TZ_UNBIND_CDEV, /* Cooling dev is unbind from the thermal zone */
+ THERMAL_INSTANCE_WEIGHT_CHANGED, /* Thermal instance weight changed */
++ THERMAL_TZ_RESUME, /* Thermal zone is resuming after system sleep */
+ };
+
+ /**
+--
+2.43.0
+
--- /dev/null
+From cfd305d3c703c0982a9172fb5c2f63dd320c5a3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Aug 2024 18:04:07 +0300
+Subject: wifi: ath12k: use 128 bytes aligned iova in transmit path for WCN7850
+
+From: Baochen Qiang <quic_bqiang@quicinc.com>
+
+[ Upstream commit 38055789d15155109b41602ad719d770af507030 ]
+
+In transmit path, it is likely that the iova is not aligned to PCIe TLP
+max payload size, which is 128 for WCN7850. Normally in such cases hardware
+is expected to split the packet into several parts in a manner such that
+they, other than the first one, have aligned iova. However due to hardware
+limitations, WCN7850 does not behave like that properly with some specific
+unaligned iova in transmit path. This easily results in target hang in a
+KPI transmit test: packet send/receive failure, WMI command send timeout
+etc. Also fatal error seen in PCIe level:
+
+ ...
+ Capabilities: ...
+ ...
+ DevSta: ... FatalErr+ ...
+ ...
+ ...
+
+Work around this by manually moving/reallocating payload buffer such that
+we can map it to a 128 bytes aligned iova. The moving requires sufficient
+head room or tail room in skb: for the former we can do ourselves a favor
+by asking some extra bytes when registering with mac80211, while for the
+latter we can do nothing.
+
+Moving/reallocating buffer consumes additional CPU cycles, but the good news
+is that an aligned iova increases PCIe efficiency. In my tests on some X86
+platforms the KPI results are almost consistent.
+
+Since this is seen only with WCN7850, add a new hardware parameter to
+differentiate from others.
+
+Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
+
+Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
+Cc: <stable@vger.kernel.org>
+Tested-by: Mark Pearson <mpearson-lenovo@squebb.ca>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://patch.msgid.link/20240715023814.20242-1-quic_bqiang@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath12k/dp_tx.c | 72 +++++++++++++++++++++++++
+ drivers/net/wireless/ath/ath12k/hw.c | 6 +++
+ drivers/net/wireless/ath/ath12k/hw.h | 4 ++
+ drivers/net/wireless/ath/ath12k/mac.c | 1 +
+ 4 files changed, 83 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c
+index a7c7a868c14ce..fca9f7e510b41 100644
+--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
++++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
+@@ -124,6 +124,60 @@ static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab,
+ HAL_TX_MSDU_EXT_INFO1_ENCRYPT_TYPE);
+ }
+
++static void ath12k_dp_tx_move_payload(struct sk_buff *skb,
++ unsigned long delta,
++ bool head)
++{
++ unsigned long len = skb->len;
++
++ if (head) {
++ skb_push(skb, delta);
++ memmove(skb->data, skb->data + delta, len);
++ skb_trim(skb, len);
++ } else {
++ skb_put(skb, delta);
++ memmove(skb->data + delta, skb->data, len);
++ skb_pull(skb, delta);
++ }
++}
++
++static int ath12k_dp_tx_align_payload(struct ath12k_base *ab,
++ struct sk_buff **pskb)
++{
++ u32 iova_mask = ab->hw_params->iova_mask;
++ unsigned long offset, delta1, delta2;
++ struct sk_buff *skb2, *skb = *pskb;
++ unsigned int headroom = skb_headroom(skb);
++ int tailroom = skb_tailroom(skb);
++ int ret = 0;
++
++ offset = (unsigned long)skb->data & iova_mask;
++ delta1 = offset;
++ delta2 = iova_mask - offset + 1;
++
++ if (headroom >= delta1) {
++ ath12k_dp_tx_move_payload(skb, delta1, true);
++ } else if (tailroom >= delta2) {
++ ath12k_dp_tx_move_payload(skb, delta2, false);
++ } else {
++ skb2 = skb_realloc_headroom(skb, iova_mask);
++ if (!skb2) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ dev_kfree_skb_any(skb);
++
++ offset = (unsigned long)skb2->data & iova_mask;
++ if (offset)
++ ath12k_dp_tx_move_payload(skb2, offset, true);
++ *pskb = skb2;
++ }
++
++out:
++ return ret;
++}
++
+ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
+ struct sk_buff *skb)
+ {
+@@ -145,6 +199,7 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
+ u8 ring_selector, ring_map = 0;
+ bool tcl_ring_retry;
+ bool msdu_ext_desc = false;
++ u32 iova_mask = ab->hw_params->iova_mask;
+
+ if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))
+ return -ESHUTDOWN;
+@@ -240,6 +295,23 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
+ goto fail_remove_tx_buf;
+ }
+
++ if (iova_mask &&
++ (unsigned long)skb->data & iova_mask) {
++ ret = ath12k_dp_tx_align_payload(ab, &skb);
++ if (ret) {
++ ath12k_warn(ab, "failed to align TX buffer %d\n", ret);
++ /* don't bail out, give original buffer
++ * a chance even unaligned.
++ */
++ goto map;
++ }
++
++ /* hdr is pointing to a wrong place after alignment,
++ * so refresh it for later use.
++ */
++ hdr = (void *)skb->data;
++ }
++map:
+ ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE);
+ if (dma_mapping_error(ab->dev, ti.paddr)) {
+ atomic_inc(&ab->soc_stats.tx_err.misc_fail);
+diff --git a/drivers/net/wireless/ath/ath12k/hw.c b/drivers/net/wireless/ath/ath12k/hw.c
+index bff8cf97a18c6..2a92147d15fa1 100644
+--- a/drivers/net/wireless/ath/ath12k/hw.c
++++ b/drivers/net/wireless/ath/ath12k/hw.c
+@@ -922,6 +922,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
+ .supports_sta_ps = false,
+
+ .acpi_guid = NULL,
++
++ .iova_mask = 0,
+ },
+ {
+ .name = "wcn7850 hw2.0",
+@@ -997,6 +999,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
+ .supports_sta_ps = true,
+
+ .acpi_guid = &wcn7850_uuid,
++
++ .iova_mask = ATH12K_PCIE_MAX_PAYLOAD_SIZE - 1,
+ },
+ {
+ .name = "qcn9274 hw2.0",
+@@ -1067,6 +1071,8 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
+ .supports_sta_ps = false,
+
+ .acpi_guid = NULL,
++
++ .iova_mask = 0,
+ },
+ };
+
+diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h
+index 2a314cfc8cb84..400bda17e02f6 100644
+--- a/drivers/net/wireless/ath/ath12k/hw.h
++++ b/drivers/net/wireless/ath/ath12k/hw.h
+@@ -96,6 +96,8 @@
+ #define ATH12K_M3_FILE "m3.bin"
+ #define ATH12K_REGDB_FILE_NAME "regdb.bin"
+
++#define ATH12K_PCIE_MAX_PAYLOAD_SIZE 128
++
+ enum ath12k_hw_rate_cck {
+ ATH12K_HW_RATE_CCK_LP_11M = 0,
+ ATH12K_HW_RATE_CCK_LP_5_5M,
+@@ -214,6 +216,8 @@ struct ath12k_hw_params {
+ bool supports_sta_ps;
+
+ const guid_t *acpi_guid;
++
++ u32 iova_mask;
+ };
+
+ struct ath12k_hw_ops {
+diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
+index ead37a4e002a2..8474e25d2ac64 100644
+--- a/drivers/net/wireless/ath/ath12k/mac.c
++++ b/drivers/net/wireless/ath/ath12k/mac.c
+@@ -8737,6 +8737,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
+
+ hw->vif_data_size = sizeof(struct ath12k_vif);
+ hw->sta_data_size = sizeof(struct ath12k_sta);
++ hw->extra_tx_headroom = ab->hw_params->iova_mask;
+
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_STA_TX_PWR);
+--
+2.43.0
+