usb-renesas_usbhs-fix-use-after-free-in-isr-during-device-removal.patch
usb-mdc800-handle-signal-and-read-racing.patch
usb-image-mdc800-kill-download-urb-on-timeout.patch
+time-add-kernel-doc-in-time.c.patch
+time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch
--- /dev/null
+From b7d9fa4ee9490fd2f3e497fe4fa152cf19e85511 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Jul 2023 22:24:05 -0700
+Subject: time: add kernel-doc in time.c
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 67b3f564cb1e769ef8e45835129a4866152fcfdb ]
+
+Add kernel-doc for all APIs that do not already have it.
+
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: John Stultz <jstultz@google.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Stephen Boyd <sboyd@kernel.org>
+Cc: Jonathan Corbet <corbet@lwn.net>
+Cc: linux-doc@vger.kernel.org
+Acked-by: John Stultz <jstultz@google.com>
+Signed-off-by: Jonathan Corbet <corbet@lwn.net>
+Link: https://lore.kernel.org/r/20230704052405.5089-3-rdunlap@infradead.org
+Stable-dep-of: 755a648e78f1 ("time/jiffies: Mark jiffies_64_to_clock_t() notrace")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/time.c | 169 ++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 158 insertions(+), 11 deletions(-)
+
+diff --git a/kernel/time/time.c b/kernel/time/time.c
+index 483f8a3e24d0c..6f81aead1856d 100644
+--- a/kernel/time/time.c
++++ b/kernel/time/time.c
+@@ -365,11 +365,14 @@ SYSCALL_DEFINE1(adjtimex_time32, struct old_timex32 __user *, utp)
+ }
+ #endif
+
+-/*
+- * Convert jiffies to milliseconds and back.
++/**
++ * jiffies_to_msecs - Convert jiffies to milliseconds
++ * @j: jiffies value
+ *
+ * Avoid unnecessary multiplications/divisions in the
+- * two most common HZ cases:
++ * two most common HZ cases.
++ *
++ * Return: milliseconds value
+ */
+ unsigned int jiffies_to_msecs(const unsigned long j)
+ {
+@@ -388,6 +391,12 @@ unsigned int jiffies_to_msecs(const unsigned long j)
+ }
+ EXPORT_SYMBOL(jiffies_to_msecs);
+
++/**
++ * jiffies_to_usecs - Convert jiffies to microseconds
++ * @j: jiffies value
++ *
++ * Return: microseconds value
++ */
+ unsigned int jiffies_to_usecs(const unsigned long j)
+ {
+ /*
+@@ -408,8 +417,15 @@ unsigned int jiffies_to_usecs(const unsigned long j)
+ }
+ EXPORT_SYMBOL(jiffies_to_usecs);
+
+-/*
++/**
+ * mktime64 - Converts date to seconds.
++ * @year0: year to convert
++ * @mon0: month to convert
++ * @day: day to convert
++ * @hour: hour to convert
++ * @min: minute to convert
++ * @sec: second to convert
++ *
+ * Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+ * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
+ * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
+@@ -427,6 +443,8 @@ EXPORT_SYMBOL(jiffies_to_usecs);
+ *
+ * An encoding of midnight at the end of the day as 24:00:00 - ie. midnight
+ * tomorrow - (allowable under ISO 8601) is supported.
++ *
++ * Return: seconds since the epoch time for the given input date
+ */
+ time64_t mktime64(const unsigned int year0, const unsigned int mon0,
+ const unsigned int day, const unsigned int hour,
+@@ -471,8 +489,7 @@ EXPORT_SYMBOL(ns_to_kernel_old_timeval);
+ * Set seconds and nanoseconds field of a timespec variable and
+ * normalize to the timespec storage format
+ *
+- * Note: The tv_nsec part is always in the range of
+- * 0 <= tv_nsec < NSEC_PER_SEC
++ * Note: The tv_nsec part is always in the range of 0 <= tv_nsec < NSEC_PER_SEC.
+ * For negative values only the tv_sec field is negative !
+ */
+ void set_normalized_timespec64(struct timespec64 *ts, time64_t sec, s64 nsec)
+@@ -501,7 +518,7 @@ EXPORT_SYMBOL(set_normalized_timespec64);
+ * ns_to_timespec64 - Convert nanoseconds to timespec64
+ * @nsec: the nanoseconds value to be converted
+ *
+- * Returns the timespec64 representation of the nsec parameter.
++ * Return: the timespec64 representation of the nsec parameter.
+ */
+ struct timespec64 ns_to_timespec64(const s64 nsec)
+ {
+@@ -548,6 +565,8 @@ EXPORT_SYMBOL(ns_to_timespec64);
+ * runtime.
+ * the _msecs_to_jiffies helpers are the HZ dependent conversion
+ * routines found in include/linux/jiffies.h
++ *
++ * Return: jiffies value
+ */
+ unsigned long __msecs_to_jiffies(const unsigned int m)
+ {
+@@ -560,6 +579,12 @@ unsigned long __msecs_to_jiffies(const unsigned int m)
+ }
+ EXPORT_SYMBOL(__msecs_to_jiffies);
+
++/**
++ * __usecs_to_jiffies: - convert microseconds to jiffies
++ * @u: time in milliseconds
++ *
++ * Return: jiffies value
++ */
+ unsigned long __usecs_to_jiffies(const unsigned int u)
+ {
+ if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET))
+@@ -568,7 +593,10 @@ unsigned long __usecs_to_jiffies(const unsigned int u)
+ }
+ EXPORT_SYMBOL(__usecs_to_jiffies);
+
+-/*
++/**
++ * timespec64_to_jiffies - convert a timespec64 value to jiffies
++ * @value: pointer to &struct timespec64
++ *
+ * The TICK_NSEC - 1 rounds up the value to the next resolution. Note
+ * that a remainder subtract here would not do the right thing as the
+ * resolution values don't fall on second boundries. I.e. the line:
+@@ -582,8 +610,9 @@ EXPORT_SYMBOL(__usecs_to_jiffies);
+ *
+ * The >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC) converts the scaled nsec
+ * value to a scaled second value.
++ *
++ * Return: jiffies value
+ */
+-
+ unsigned long
+ timespec64_to_jiffies(const struct timespec64 *value)
+ {
+@@ -601,6 +630,11 @@ timespec64_to_jiffies(const struct timespec64 *value)
+ }
+ EXPORT_SYMBOL(timespec64_to_jiffies);
+
++/**
++ * jiffies_to_timespec64 - convert jiffies value to &struct timespec64
++ * @jiffies: jiffies value
++ * @value: pointer to &struct timespec64
++ */
+ void
+ jiffies_to_timespec64(const unsigned long jiffies, struct timespec64 *value)
+ {
+@@ -618,6 +652,13 @@ EXPORT_SYMBOL(jiffies_to_timespec64);
+ /*
+ * Convert jiffies/jiffies_64 to clock_t and back.
+ */
++
++/**
++ * jiffies_to_clock_t - Convert jiffies to clock_t
++ * @x: jiffies value
++ *
++ * Return: jiffies converted to clock_t (CLOCKS_PER_SEC)
++ */
+ clock_t jiffies_to_clock_t(unsigned long x)
+ {
+ #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
+@@ -632,6 +673,12 @@ clock_t jiffies_to_clock_t(unsigned long x)
+ }
+ EXPORT_SYMBOL(jiffies_to_clock_t);
+
++/**
++ * clock_t_to_jiffies - Convert clock_t to jiffies
++ * @x: clock_t value
++ *
++ * Return: clock_t value converted to jiffies
++ */
+ unsigned long clock_t_to_jiffies(unsigned long x)
+ {
+ #if (HZ % USER_HZ)==0
+@@ -649,6 +696,12 @@ unsigned long clock_t_to_jiffies(unsigned long x)
+ }
+ EXPORT_SYMBOL(clock_t_to_jiffies);
+
++/**
++ * jiffies_64_to_clock_t - Convert jiffies_64 to clock_t
++ * @x: jiffies_64 value
++ *
++ * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC)
++ */
+ u64 jiffies_64_to_clock_t(u64 x)
+ {
+ #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
+@@ -671,6 +724,12 @@ u64 jiffies_64_to_clock_t(u64 x)
+ }
+ EXPORT_SYMBOL(jiffies_64_to_clock_t);
+
++/**
++ * nsec_to_clock_t - Convert nsec value to clock_t
++ * @x: nsec value
++ *
++ * Return: nsec value converted to 64-bit "clock_t" (CLOCKS_PER_SEC)
++ */
+ u64 nsec_to_clock_t(u64 x)
+ {
+ #if (NSEC_PER_SEC % USER_HZ) == 0
+@@ -687,6 +746,12 @@ u64 nsec_to_clock_t(u64 x)
+ #endif
+ }
+
++/**
++ * jiffies64_to_nsecs - Convert jiffies64 to nanoseconds
++ * @j: jiffies64 value
++ *
++ * Return: nanoseconds value
++ */
+ u64 jiffies64_to_nsecs(u64 j)
+ {
+ #if !(NSEC_PER_SEC % HZ)
+@@ -697,6 +762,12 @@ u64 jiffies64_to_nsecs(u64 j)
+ }
+ EXPORT_SYMBOL(jiffies64_to_nsecs);
+
++/**
++ * jiffies64_to_msecs - Convert jiffies64 to milliseconds
++ * @j: jiffies64 value
++ *
++ * Return: milliseconds value
++ */
+ u64 jiffies64_to_msecs(const u64 j)
+ {
+ #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
+@@ -719,6 +790,8 @@ EXPORT_SYMBOL(jiffies64_to_msecs);
+ * note:
+ * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512)
+ * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years
++ *
++ * Return: nsecs converted to jiffies64 value
+ */
+ u64 nsecs_to_jiffies64(u64 n)
+ {
+@@ -750,6 +823,8 @@ EXPORT_SYMBOL(nsecs_to_jiffies64);
+ * note:
+ * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512)
+ * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years
++ *
++ * Return: nsecs converted to jiffies value
+ */
+ unsigned long nsecs_to_jiffies(u64 n)
+ {
+@@ -757,10 +832,16 @@ unsigned long nsecs_to_jiffies(u64 n)
+ }
+ EXPORT_SYMBOL_GPL(nsecs_to_jiffies);
+
+-/*
+- * Add two timespec64 values and do a safety check for overflow.
++/**
++ * timespec64_add_safe - Add two timespec64 values and do a safety check
++ * for overflow.
++ * @lhs: first (left) timespec64 to add
++ * @rhs: second (right) timespec64 to add
++ *
+ * It's assumed that both values are valid (>= 0).
+ * And, each timespec64 is in normalized form.
++ *
++ * Return: sum of @lhs + @rhs
+ */
+ struct timespec64 timespec64_add_safe(const struct timespec64 lhs,
+ const struct timespec64 rhs)
+@@ -778,6 +859,15 @@ struct timespec64 timespec64_add_safe(const struct timespec64 lhs,
+ return res;
+ }
+
++/**
++ * get_timespec64 - get user's time value into kernel space
++ * @ts: destination &struct timespec64
++ * @uts: user's time value as &struct __kernel_timespec
++ *
++ * Handles compat or 32-bit modes.
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int get_timespec64(struct timespec64 *ts,
+ const struct __kernel_timespec __user *uts)
+ {
+@@ -801,6 +891,14 @@ int get_timespec64(struct timespec64 *ts,
+ }
+ EXPORT_SYMBOL_GPL(get_timespec64);
+
++/**
++ * put_timespec64 - convert timespec64 value to __kernel_timespec format and
++ * copy the latter to userspace
++ * @ts: input &struct timespec64
++ * @uts: user's &struct __kernel_timespec
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int put_timespec64(const struct timespec64 *ts,
+ struct __kernel_timespec __user *uts)
+ {
+@@ -839,6 +937,15 @@ static int __put_old_timespec32(const struct timespec64 *ts64,
+ return copy_to_user(cts, &ts, sizeof(ts)) ? -EFAULT : 0;
+ }
+
++/**
++ * get_old_timespec32 - get user's old-format time value into kernel space
++ * @ts: destination &struct timespec64
++ * @uts: user's old-format time value (&struct old_timespec32)
++ *
++ * Handles X86_X32_ABI compatibility conversion.
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int get_old_timespec32(struct timespec64 *ts, const void __user *uts)
+ {
+ if (COMPAT_USE_64BIT_TIME)
+@@ -848,6 +955,16 @@ int get_old_timespec32(struct timespec64 *ts, const void __user *uts)
+ }
+ EXPORT_SYMBOL_GPL(get_old_timespec32);
+
++/**
++ * put_old_timespec32 - convert timespec64 value to &struct old_timespec32 and
++ * copy the latter to userspace
++ * @ts: input &struct timespec64
++ * @uts: user's &struct old_timespec32
++ *
++ * Handles X86_X32_ABI compatibility conversion.
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int put_old_timespec32(const struct timespec64 *ts, void __user *uts)
+ {
+ if (COMPAT_USE_64BIT_TIME)
+@@ -857,6 +974,13 @@ int put_old_timespec32(const struct timespec64 *ts, void __user *uts)
+ }
+ EXPORT_SYMBOL_GPL(put_old_timespec32);
+
++/**
++ * get_itimerspec64 - get user's &struct __kernel_itimerspec into kernel space
++ * @it: destination &struct itimerspec64
++ * @uit: user's &struct __kernel_itimerspec
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int get_itimerspec64(struct itimerspec64 *it,
+ const struct __kernel_itimerspec __user *uit)
+ {
+@@ -872,6 +996,14 @@ int get_itimerspec64(struct itimerspec64 *it,
+ }
+ EXPORT_SYMBOL_GPL(get_itimerspec64);
+
++/**
++ * put_itimerspec64 - convert &struct itimerspec64 to __kernel_itimerspec format
++ * and copy the latter to userspace
++ * @it: input &struct itimerspec64
++ * @uit: user's &struct __kernel_itimerspec
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int put_itimerspec64(const struct itimerspec64 *it,
+ struct __kernel_itimerspec __user *uit)
+ {
+@@ -887,6 +1019,13 @@ int put_itimerspec64(const struct itimerspec64 *it,
+ }
+ EXPORT_SYMBOL_GPL(put_itimerspec64);
+
++/**
++ * get_old_itimerspec32 - get user's &struct old_itimerspec32 into kernel space
++ * @its: destination &struct itimerspec64
++ * @uits: user's &struct old_itimerspec32
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int get_old_itimerspec32(struct itimerspec64 *its,
+ const struct old_itimerspec32 __user *uits)
+ {
+@@ -898,6 +1037,14 @@ int get_old_itimerspec32(struct itimerspec64 *its,
+ }
+ EXPORT_SYMBOL_GPL(get_old_itimerspec32);
+
++/**
++ * put_old_itimerspec32 - convert &struct itimerspec64 to &struct
++ * old_itimerspec32 and copy the latter to userspace
++ * @its: input &struct itimerspec64
++ * @uits: user's &struct old_itimerspec32
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int put_old_itimerspec32(const struct itimerspec64 *its,
+ struct old_itimerspec32 __user *uits)
+ {
+--
+2.51.0
+
--- /dev/null
+From e767072424f5c63930f90b4555a940e34b050b41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Mar 2026 21:24:03 -0500
+Subject: time/jiffies: Mark jiffies_64_to_clock_t() notrace
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 755a648e78f12574482d4698d877375793867fa1 ]
+
+The trace_clock_jiffies() function that handles the "uptime" clock for
+tracing calls jiffies_64_to_clock_t(). This causes the function tracer to
+constantly recurse when the tracing clock is set to "uptime". Mark it
+notrace to prevent unnecessary recursion when using the "uptime" clock.
+
+Fixes: 58d4e21e50ff3 ("tracing: Fix wraparound problems in "uptime" trace clock")
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Link: https://patch.msgid.link/20260306212403.72270bb2@robin
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/time.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/time/time.c b/kernel/time/time.c
+index 6f81aead1856d..37c381607f372 100644
+--- a/kernel/time/time.c
++++ b/kernel/time/time.c
+@@ -702,7 +702,7 @@ EXPORT_SYMBOL(clock_t_to_jiffies);
+ *
+ * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC)
+ */
+-u64 jiffies_64_to_clock_t(u64 x)
++notrace u64 jiffies_64_to_clock_t(u64 x)
+ {
+ #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
+ # if HZ < USER_HZ
+--
+2.51.0
+
usb-renesas_usbhs-fix-use-after-free-in-isr-during-device-removal.patch
usb-mdc800-handle-signal-and-read-racing.patch
usb-image-mdc800-kill-download-urb-on-timeout.patch
+time-add-kernel-doc-in-time.c.patch
+time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch
--- /dev/null
+From fbcc7f534a757bff38652e9a2a0165b8aa78ad4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Jul 2023 22:24:05 -0700
+Subject: time: add kernel-doc in time.c
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 67b3f564cb1e769ef8e45835129a4866152fcfdb ]
+
+Add kernel-doc for all APIs that do not already have it.
+
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: John Stultz <jstultz@google.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Stephen Boyd <sboyd@kernel.org>
+Cc: Jonathan Corbet <corbet@lwn.net>
+Cc: linux-doc@vger.kernel.org
+Acked-by: John Stultz <jstultz@google.com>
+Signed-off-by: Jonathan Corbet <corbet@lwn.net>
+Link: https://lore.kernel.org/r/20230704052405.5089-3-rdunlap@infradead.org
+Stable-dep-of: 755a648e78f1 ("time/jiffies: Mark jiffies_64_to_clock_t() notrace")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/time.c | 169 ++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 158 insertions(+), 11 deletions(-)
+
+diff --git a/kernel/time/time.c b/kernel/time/time.c
+index a7fce68465a38..50390158e9d97 100644
+--- a/kernel/time/time.c
++++ b/kernel/time/time.c
+@@ -365,11 +365,14 @@ SYSCALL_DEFINE1(adjtimex_time32, struct old_timex32 __user *, utp)
+ }
+ #endif
+
+-/*
+- * Convert jiffies to milliseconds and back.
++/**
++ * jiffies_to_msecs - Convert jiffies to milliseconds
++ * @j: jiffies value
+ *
+ * Avoid unnecessary multiplications/divisions in the
+- * two most common HZ cases:
++ * two most common HZ cases.
++ *
++ * Return: milliseconds value
+ */
+ unsigned int jiffies_to_msecs(const unsigned long j)
+ {
+@@ -388,6 +391,12 @@ unsigned int jiffies_to_msecs(const unsigned long j)
+ }
+ EXPORT_SYMBOL(jiffies_to_msecs);
+
++/**
++ * jiffies_to_usecs - Convert jiffies to microseconds
++ * @j: jiffies value
++ *
++ * Return: microseconds value
++ */
+ unsigned int jiffies_to_usecs(const unsigned long j)
+ {
+ /*
+@@ -408,8 +417,15 @@ unsigned int jiffies_to_usecs(const unsigned long j)
+ }
+ EXPORT_SYMBOL(jiffies_to_usecs);
+
+-/*
++/**
+ * mktime64 - Converts date to seconds.
++ * @year0: year to convert
++ * @mon0: month to convert
++ * @day: day to convert
++ * @hour: hour to convert
++ * @min: minute to convert
++ * @sec: second to convert
++ *
+ * Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+ * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
+ * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
+@@ -427,6 +443,8 @@ EXPORT_SYMBOL(jiffies_to_usecs);
+ *
+ * An encoding of midnight at the end of the day as 24:00:00 - ie. midnight
+ * tomorrow - (allowable under ISO 8601) is supported.
++ *
++ * Return: seconds since the epoch time for the given input date
+ */
+ time64_t mktime64(const unsigned int year0, const unsigned int mon0,
+ const unsigned int day, const unsigned int hour,
+@@ -471,8 +489,7 @@ EXPORT_SYMBOL(ns_to_kernel_old_timeval);
+ * Set seconds and nanoseconds field of a timespec variable and
+ * normalize to the timespec storage format
+ *
+- * Note: The tv_nsec part is always in the range of
+- * 0 <= tv_nsec < NSEC_PER_SEC
++ * Note: The tv_nsec part is always in the range of 0 <= tv_nsec < NSEC_PER_SEC.
+ * For negative values only the tv_sec field is negative !
+ */
+ void set_normalized_timespec64(struct timespec64 *ts, time64_t sec, s64 nsec)
+@@ -501,7 +518,7 @@ EXPORT_SYMBOL(set_normalized_timespec64);
+ * ns_to_timespec64 - Convert nanoseconds to timespec64
+ * @nsec: the nanoseconds value to be converted
+ *
+- * Returns the timespec64 representation of the nsec parameter.
++ * Return: the timespec64 representation of the nsec parameter.
+ */
+ struct timespec64 ns_to_timespec64(const s64 nsec)
+ {
+@@ -548,6 +565,8 @@ EXPORT_SYMBOL(ns_to_timespec64);
+ * runtime.
+ * the _msecs_to_jiffies helpers are the HZ dependent conversion
+ * routines found in include/linux/jiffies.h
++ *
++ * Return: jiffies value
+ */
+ unsigned long __msecs_to_jiffies(const unsigned int m)
+ {
+@@ -560,6 +579,12 @@ unsigned long __msecs_to_jiffies(const unsigned int m)
+ }
+ EXPORT_SYMBOL(__msecs_to_jiffies);
+
++/**
++ * __usecs_to_jiffies: - convert microseconds to jiffies
++ * @u: time in milliseconds
++ *
++ * Return: jiffies value
++ */
+ unsigned long __usecs_to_jiffies(const unsigned int u)
+ {
+ if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET))
+@@ -568,7 +593,10 @@ unsigned long __usecs_to_jiffies(const unsigned int u)
+ }
+ EXPORT_SYMBOL(__usecs_to_jiffies);
+
+-/*
++/**
++ * timespec64_to_jiffies - convert a timespec64 value to jiffies
++ * @value: pointer to &struct timespec64
++ *
+ * The TICK_NSEC - 1 rounds up the value to the next resolution. Note
+ * that a remainder subtract here would not do the right thing as the
+ * resolution values don't fall on second boundaries. I.e. the line:
+@@ -582,8 +610,9 @@ EXPORT_SYMBOL(__usecs_to_jiffies);
+ *
+ * The >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC) converts the scaled nsec
+ * value to a scaled second value.
++ *
++ * Return: jiffies value
+ */
+-
+ unsigned long
+ timespec64_to_jiffies(const struct timespec64 *value)
+ {
+@@ -601,6 +630,11 @@ timespec64_to_jiffies(const struct timespec64 *value)
+ }
+ EXPORT_SYMBOL(timespec64_to_jiffies);
+
++/**
++ * jiffies_to_timespec64 - convert jiffies value to &struct timespec64
++ * @jiffies: jiffies value
++ * @value: pointer to &struct timespec64
++ */
+ void
+ jiffies_to_timespec64(const unsigned long jiffies, struct timespec64 *value)
+ {
+@@ -618,6 +652,13 @@ EXPORT_SYMBOL(jiffies_to_timespec64);
+ /*
+ * Convert jiffies/jiffies_64 to clock_t and back.
+ */
++
++/**
++ * jiffies_to_clock_t - Convert jiffies to clock_t
++ * @x: jiffies value
++ *
++ * Return: jiffies converted to clock_t (CLOCKS_PER_SEC)
++ */
+ clock_t jiffies_to_clock_t(unsigned long x)
+ {
+ #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
+@@ -632,6 +673,12 @@ clock_t jiffies_to_clock_t(unsigned long x)
+ }
+ EXPORT_SYMBOL(jiffies_to_clock_t);
+
++/**
++ * clock_t_to_jiffies - Convert clock_t to jiffies
++ * @x: clock_t value
++ *
++ * Return: clock_t value converted to jiffies
++ */
+ unsigned long clock_t_to_jiffies(unsigned long x)
+ {
+ #if (HZ % USER_HZ)==0
+@@ -649,6 +696,12 @@ unsigned long clock_t_to_jiffies(unsigned long x)
+ }
+ EXPORT_SYMBOL(clock_t_to_jiffies);
+
++/**
++ * jiffies_64_to_clock_t - Convert jiffies_64 to clock_t
++ * @x: jiffies_64 value
++ *
++ * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC)
++ */
+ u64 jiffies_64_to_clock_t(u64 x)
+ {
+ #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
+@@ -671,6 +724,12 @@ u64 jiffies_64_to_clock_t(u64 x)
+ }
+ EXPORT_SYMBOL(jiffies_64_to_clock_t);
+
++/**
++ * nsec_to_clock_t - Convert nsec value to clock_t
++ * @x: nsec value
++ *
++ * Return: nsec value converted to 64-bit "clock_t" (CLOCKS_PER_SEC)
++ */
+ u64 nsec_to_clock_t(u64 x)
+ {
+ #if (NSEC_PER_SEC % USER_HZ) == 0
+@@ -687,6 +746,12 @@ u64 nsec_to_clock_t(u64 x)
+ #endif
+ }
+
++/**
++ * jiffies64_to_nsecs - Convert jiffies64 to nanoseconds
++ * @j: jiffies64 value
++ *
++ * Return: nanoseconds value
++ */
+ u64 jiffies64_to_nsecs(u64 j)
+ {
+ #if !(NSEC_PER_SEC % HZ)
+@@ -697,6 +762,12 @@ u64 jiffies64_to_nsecs(u64 j)
+ }
+ EXPORT_SYMBOL(jiffies64_to_nsecs);
+
++/**
++ * jiffies64_to_msecs - Convert jiffies64 to milliseconds
++ * @j: jiffies64 value
++ *
++ * Return: milliseconds value
++ */
+ u64 jiffies64_to_msecs(const u64 j)
+ {
+ #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
+@@ -719,6 +790,8 @@ EXPORT_SYMBOL(jiffies64_to_msecs);
+ * note:
+ * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512)
+ * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years
++ *
++ * Return: nsecs converted to jiffies64 value
+ */
+ u64 nsecs_to_jiffies64(u64 n)
+ {
+@@ -750,6 +823,8 @@ EXPORT_SYMBOL(nsecs_to_jiffies64);
+ * note:
+ * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512)
+ * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years
++ *
++ * Return: nsecs converted to jiffies value
+ */
+ unsigned long nsecs_to_jiffies(u64 n)
+ {
+@@ -757,10 +832,16 @@ unsigned long nsecs_to_jiffies(u64 n)
+ }
+ EXPORT_SYMBOL_GPL(nsecs_to_jiffies);
+
+-/*
+- * Add two timespec64 values and do a safety check for overflow.
++/**
++ * timespec64_add_safe - Add two timespec64 values and do a safety check
++ * for overflow.
++ * @lhs: first (left) timespec64 to add
++ * @rhs: second (right) timespec64 to add
++ *
+ * It's assumed that both values are valid (>= 0).
+ * And, each timespec64 is in normalized form.
++ *
++ * Return: sum of @lhs + @rhs
+ */
+ struct timespec64 timespec64_add_safe(const struct timespec64 lhs,
+ const struct timespec64 rhs)
+@@ -778,6 +859,15 @@ struct timespec64 timespec64_add_safe(const struct timespec64 lhs,
+ return res;
+ }
+
++/**
++ * get_timespec64 - get user's time value into kernel space
++ * @ts: destination &struct timespec64
++ * @uts: user's time value as &struct __kernel_timespec
++ *
++ * Handles compat or 32-bit modes.
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int get_timespec64(struct timespec64 *ts,
+ const struct __kernel_timespec __user *uts)
+ {
+@@ -801,6 +891,14 @@ int get_timespec64(struct timespec64 *ts,
+ }
+ EXPORT_SYMBOL_GPL(get_timespec64);
+
++/**
++ * put_timespec64 - convert timespec64 value to __kernel_timespec format and
++ * copy the latter to userspace
++ * @ts: input &struct timespec64
++ * @uts: user's &struct __kernel_timespec
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int put_timespec64(const struct timespec64 *ts,
+ struct __kernel_timespec __user *uts)
+ {
+@@ -839,6 +937,15 @@ static int __put_old_timespec32(const struct timespec64 *ts64,
+ return copy_to_user(cts, &ts, sizeof(ts)) ? -EFAULT : 0;
+ }
+
++/**
++ * get_old_timespec32 - get user's old-format time value into kernel space
++ * @ts: destination &struct timespec64
++ * @uts: user's old-format time value (&struct old_timespec32)
++ *
++ * Handles X86_X32_ABI compatibility conversion.
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int get_old_timespec32(struct timespec64 *ts, const void __user *uts)
+ {
+ if (COMPAT_USE_64BIT_TIME)
+@@ -848,6 +955,16 @@ int get_old_timespec32(struct timespec64 *ts, const void __user *uts)
+ }
+ EXPORT_SYMBOL_GPL(get_old_timespec32);
+
++/**
++ * put_old_timespec32 - convert timespec64 value to &struct old_timespec32 and
++ * copy the latter to userspace
++ * @ts: input &struct timespec64
++ * @uts: user's &struct old_timespec32
++ *
++ * Handles X86_X32_ABI compatibility conversion.
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int put_old_timespec32(const struct timespec64 *ts, void __user *uts)
+ {
+ if (COMPAT_USE_64BIT_TIME)
+@@ -857,6 +974,13 @@ int put_old_timespec32(const struct timespec64 *ts, void __user *uts)
+ }
+ EXPORT_SYMBOL_GPL(put_old_timespec32);
+
++/**
++ * get_itimerspec64 - get user's &struct __kernel_itimerspec into kernel space
++ * @it: destination &struct itimerspec64
++ * @uit: user's &struct __kernel_itimerspec
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int get_itimerspec64(struct itimerspec64 *it,
+ const struct __kernel_itimerspec __user *uit)
+ {
+@@ -872,6 +996,14 @@ int get_itimerspec64(struct itimerspec64 *it,
+ }
+ EXPORT_SYMBOL_GPL(get_itimerspec64);
+
++/**
++ * put_itimerspec64 - convert &struct itimerspec64 to __kernel_itimerspec format
++ * and copy the latter to userspace
++ * @it: input &struct itimerspec64
++ * @uit: user's &struct __kernel_itimerspec
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int put_itimerspec64(const struct itimerspec64 *it,
+ struct __kernel_itimerspec __user *uit)
+ {
+@@ -887,6 +1019,13 @@ int put_itimerspec64(const struct itimerspec64 *it,
+ }
+ EXPORT_SYMBOL_GPL(put_itimerspec64);
+
++/**
++ * get_old_itimerspec32 - get user's &struct old_itimerspec32 into kernel space
++ * @its: destination &struct itimerspec64
++ * @uits: user's &struct old_itimerspec32
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int get_old_itimerspec32(struct itimerspec64 *its,
+ const struct old_itimerspec32 __user *uits)
+ {
+@@ -898,6 +1037,14 @@ int get_old_itimerspec32(struct itimerspec64 *its,
+ }
+ EXPORT_SYMBOL_GPL(get_old_itimerspec32);
+
++/**
++ * put_old_itimerspec32 - convert &struct itimerspec64 to &struct
++ * old_itimerspec32 and copy the latter to userspace
++ * @its: input &struct itimerspec64
++ * @uits: user's &struct old_itimerspec32
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int put_old_itimerspec32(const struct itimerspec64 *its,
+ struct old_itimerspec32 __user *uits)
+ {
+--
+2.51.0
+
--- /dev/null
+From 90b489eacdab0834bb3dd356b255f7968f9743a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Mar 2026 21:24:03 -0500
+Subject: time/jiffies: Mark jiffies_64_to_clock_t() notrace
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 755a648e78f12574482d4698d877375793867fa1 ]
+
+The trace_clock_jiffies() function that handles the "uptime" clock for
+tracing calls jiffies_64_to_clock_t(). This causes the function tracer to
+constantly recurse when the tracing clock is set to "uptime". Mark it
+notrace to prevent unnecessary recursion when using the "uptime" clock.
+
+Fixes: 58d4e21e50ff3 ("tracing: Fix wraparound problems in "uptime" trace clock")
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Link: https://patch.msgid.link/20260306212403.72270bb2@robin
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/time.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/time/time.c b/kernel/time/time.c
+index 50390158e9d97..df582f24f0d7b 100644
+--- a/kernel/time/time.c
++++ b/kernel/time/time.c
+@@ -702,7 +702,7 @@ EXPORT_SYMBOL(clock_t_to_jiffies);
+ *
+ * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC)
+ */
+-u64 jiffies_64_to_clock_t(u64 x)
++notrace u64 jiffies_64_to_clock_t(u64 x)
+ {
+ #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
+ # if HZ < USER_HZ
+--
+2.51.0
+
usb-renesas_usbhs-fix-use-after-free-in-isr-during-device-removal.patch
usb-mdc800-handle-signal-and-read-racing.patch
usb-image-mdc800-kill-download-urb-on-timeout.patch
+time-add-kernel-doc-in-time.c.patch
+time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch
--- /dev/null
+From 9b44ed67dac711f5e7213dce50865713666a26d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Jul 2023 22:24:05 -0700
+Subject: time: add kernel-doc in time.c
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 67b3f564cb1e769ef8e45835129a4866152fcfdb ]
+
+Add kernel-doc for all APIs that do not already have it.
+
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: John Stultz <jstultz@google.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Stephen Boyd <sboyd@kernel.org>
+Cc: Jonathan Corbet <corbet@lwn.net>
+Cc: linux-doc@vger.kernel.org
+Acked-by: John Stultz <jstultz@google.com>
+Signed-off-by: Jonathan Corbet <corbet@lwn.net>
+Link: https://lore.kernel.org/r/20230704052405.5089-3-rdunlap@infradead.org
+Stable-dep-of: 755a648e78f1 ("time/jiffies: Mark jiffies_64_to_clock_t() notrace")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/time.c | 169 ++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 158 insertions(+), 11 deletions(-)
+
+diff --git a/kernel/time/time.c b/kernel/time/time.c
+index a92c7f3277ad6..be42ace51255c 100644
+--- a/kernel/time/time.c
++++ b/kernel/time/time.c
+@@ -365,11 +365,14 @@ SYSCALL_DEFINE1(adjtimex_time32, struct old_timex32 __user *, utp)
+ }
+ #endif
+
+-/*
+- * Convert jiffies to milliseconds and back.
++/**
++ * jiffies_to_msecs - Convert jiffies to milliseconds
++ * @j: jiffies value
+ *
+ * Avoid unnecessary multiplications/divisions in the
+- * two most common HZ cases:
++ * two most common HZ cases.
++ *
++ * Return: milliseconds value
+ */
+ unsigned int jiffies_to_msecs(const unsigned long j)
+ {
+@@ -388,6 +391,12 @@ unsigned int jiffies_to_msecs(const unsigned long j)
+ }
+ EXPORT_SYMBOL(jiffies_to_msecs);
+
++/**
++ * jiffies_to_usecs - Convert jiffies to microseconds
++ * @j: jiffies value
++ *
++ * Return: microseconds value
++ */
+ unsigned int jiffies_to_usecs(const unsigned long j)
+ {
+ /*
+@@ -408,8 +417,15 @@ unsigned int jiffies_to_usecs(const unsigned long j)
+ }
+ EXPORT_SYMBOL(jiffies_to_usecs);
+
+-/*
++/**
+ * mktime64 - Converts date to seconds.
++ * @year0: year to convert
++ * @mon0: month to convert
++ * @day: day to convert
++ * @hour: hour to convert
++ * @min: minute to convert
++ * @sec: second to convert
++ *
+ * Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+ * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
+ * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
+@@ -427,6 +443,8 @@ EXPORT_SYMBOL(jiffies_to_usecs);
+ *
+ * An encoding of midnight at the end of the day as 24:00:00 - ie. midnight
+ * tomorrow - (allowable under ISO 8601) is supported.
++ *
++ * Return: seconds since the epoch time for the given input date
+ */
+ time64_t mktime64(const unsigned int year0, const unsigned int mon0,
+ const unsigned int day, const unsigned int hour,
+@@ -471,8 +489,7 @@ EXPORT_SYMBOL(ns_to_kernel_old_timeval);
+ * Set seconds and nanoseconds field of a timespec variable and
+ * normalize to the timespec storage format
+ *
+- * Note: The tv_nsec part is always in the range of
+- * 0 <= tv_nsec < NSEC_PER_SEC
++ * Note: The tv_nsec part is always in the range of 0 <= tv_nsec < NSEC_PER_SEC.
+ * For negative values only the tv_sec field is negative !
+ */
+ void set_normalized_timespec64(struct timespec64 *ts, time64_t sec, s64 nsec)
+@@ -501,7 +518,7 @@ EXPORT_SYMBOL(set_normalized_timespec64);
+ * ns_to_timespec64 - Convert nanoseconds to timespec64
+ * @nsec: the nanoseconds value to be converted
+ *
+- * Returns the timespec64 representation of the nsec parameter.
++ * Return: the timespec64 representation of the nsec parameter.
+ */
+ struct timespec64 ns_to_timespec64(s64 nsec)
+ {
+@@ -548,6 +565,8 @@ EXPORT_SYMBOL(ns_to_timespec64);
+ * runtime.
+ * the _msecs_to_jiffies helpers are the HZ dependent conversion
+ * routines found in include/linux/jiffies.h
++ *
++ * Return: jiffies value
+ */
+ unsigned long __msecs_to_jiffies(const unsigned int m)
+ {
+@@ -560,6 +579,12 @@ unsigned long __msecs_to_jiffies(const unsigned int m)
+ }
+ EXPORT_SYMBOL(__msecs_to_jiffies);
+
++/**
++ * __usecs_to_jiffies: - convert microseconds to jiffies
++ * @u: time in milliseconds
++ *
++ * Return: jiffies value
++ */
+ unsigned long __usecs_to_jiffies(const unsigned int u)
+ {
+ if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET))
+@@ -568,7 +593,10 @@ unsigned long __usecs_to_jiffies(const unsigned int u)
+ }
+ EXPORT_SYMBOL(__usecs_to_jiffies);
+
+-/*
++/**
++ * timespec64_to_jiffies - convert a timespec64 value to jiffies
++ * @value: pointer to &struct timespec64
++ *
+ * The TICK_NSEC - 1 rounds up the value to the next resolution. Note
+ * that a remainder subtract here would not do the right thing as the
+ * resolution values don't fall on second boundaries. I.e. the line:
+@@ -582,8 +610,9 @@ EXPORT_SYMBOL(__usecs_to_jiffies);
+ *
+ * The >> (NSEC_JIFFIE_SC - SEC_JIFFIE_SC) converts the scaled nsec
+ * value to a scaled second value.
++ *
++ * Return: jiffies value
+ */
+-
+ unsigned long
+ timespec64_to_jiffies(const struct timespec64 *value)
+ {
+@@ -601,6 +630,11 @@ timespec64_to_jiffies(const struct timespec64 *value)
+ }
+ EXPORT_SYMBOL(timespec64_to_jiffies);
+
++/**
++ * jiffies_to_timespec64 - convert jiffies value to &struct timespec64
++ * @jiffies: jiffies value
++ * @value: pointer to &struct timespec64
++ */
+ void
+ jiffies_to_timespec64(const unsigned long jiffies, struct timespec64 *value)
+ {
+@@ -618,6 +652,13 @@ EXPORT_SYMBOL(jiffies_to_timespec64);
+ /*
+ * Convert jiffies/jiffies_64 to clock_t and back.
+ */
++
++/**
++ * jiffies_to_clock_t - Convert jiffies to clock_t
++ * @x: jiffies value
++ *
++ * Return: jiffies converted to clock_t (CLOCKS_PER_SEC)
++ */
+ clock_t jiffies_to_clock_t(unsigned long x)
+ {
+ #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
+@@ -632,6 +673,12 @@ clock_t jiffies_to_clock_t(unsigned long x)
+ }
+ EXPORT_SYMBOL(jiffies_to_clock_t);
+
++/**
++ * clock_t_to_jiffies - Convert clock_t to jiffies
++ * @x: clock_t value
++ *
++ * Return: clock_t value converted to jiffies
++ */
+ unsigned long clock_t_to_jiffies(unsigned long x)
+ {
+ #if (HZ % USER_HZ)==0
+@@ -649,6 +696,12 @@ unsigned long clock_t_to_jiffies(unsigned long x)
+ }
+ EXPORT_SYMBOL(clock_t_to_jiffies);
+
++/**
++ * jiffies_64_to_clock_t - Convert jiffies_64 to clock_t
++ * @x: jiffies_64 value
++ *
++ * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC)
++ */
+ u64 jiffies_64_to_clock_t(u64 x)
+ {
+ #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
+@@ -671,6 +724,12 @@ u64 jiffies_64_to_clock_t(u64 x)
+ }
+ EXPORT_SYMBOL(jiffies_64_to_clock_t);
+
++/**
++ * nsec_to_clock_t - Convert nsec value to clock_t
++ * @x: nsec value
++ *
++ * Return: nsec value converted to 64-bit "clock_t" (CLOCKS_PER_SEC)
++ */
+ u64 nsec_to_clock_t(u64 x)
+ {
+ #if (NSEC_PER_SEC % USER_HZ) == 0
+@@ -687,6 +746,12 @@ u64 nsec_to_clock_t(u64 x)
+ #endif
+ }
+
++/**
++ * jiffies64_to_nsecs - Convert jiffies64 to nanoseconds
++ * @j: jiffies64 value
++ *
++ * Return: nanoseconds value
++ */
+ u64 jiffies64_to_nsecs(u64 j)
+ {
+ #if !(NSEC_PER_SEC % HZ)
+@@ -697,6 +762,12 @@ u64 jiffies64_to_nsecs(u64 j)
+ }
+ EXPORT_SYMBOL(jiffies64_to_nsecs);
+
++/**
++ * jiffies64_to_msecs - Convert jiffies64 to milliseconds
++ * @j: jiffies64 value
++ *
++ * Return: milliseconds value
++ */
+ u64 jiffies64_to_msecs(const u64 j)
+ {
+ #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
+@@ -719,6 +790,8 @@ EXPORT_SYMBOL(jiffies64_to_msecs);
+ * note:
+ * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512)
+ * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years
++ *
++ * Return: nsecs converted to jiffies64 value
+ */
+ u64 nsecs_to_jiffies64(u64 n)
+ {
+@@ -750,6 +823,8 @@ EXPORT_SYMBOL(nsecs_to_jiffies64);
+ * note:
+ * NSEC_PER_SEC = 10^9 = (5^9 * 2^9) = (1953125 * 512)
+ * ULLONG_MAX ns = 18446744073.709551615 secs = about 584 years
++ *
++ * Return: nsecs converted to jiffies value
+ */
+ unsigned long nsecs_to_jiffies(u64 n)
+ {
+@@ -757,10 +832,16 @@ unsigned long nsecs_to_jiffies(u64 n)
+ }
+ EXPORT_SYMBOL_GPL(nsecs_to_jiffies);
+
+-/*
+- * Add two timespec64 values and do a safety check for overflow.
++/**
++ * timespec64_add_safe - Add two timespec64 values and do a safety check
++ * for overflow.
++ * @lhs: first (left) timespec64 to add
++ * @rhs: second (right) timespec64 to add
++ *
+ * It's assumed that both values are valid (>= 0).
+ * And, each timespec64 is in normalized form.
++ *
++ * Return: sum of @lhs + @rhs
+ */
+ struct timespec64 timespec64_add_safe(const struct timespec64 lhs,
+ const struct timespec64 rhs)
+@@ -778,6 +859,15 @@ struct timespec64 timespec64_add_safe(const struct timespec64 lhs,
+ return res;
+ }
+
++/**
++ * get_timespec64 - get user's time value into kernel space
++ * @ts: destination &struct timespec64
++ * @uts: user's time value as &struct __kernel_timespec
++ *
++ * Handles compat or 32-bit modes.
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int get_timespec64(struct timespec64 *ts,
+ const struct __kernel_timespec __user *uts)
+ {
+@@ -801,6 +891,14 @@ int get_timespec64(struct timespec64 *ts,
+ }
+ EXPORT_SYMBOL_GPL(get_timespec64);
+
++/**
++ * put_timespec64 - convert timespec64 value to __kernel_timespec format and
++ * copy the latter to userspace
++ * @ts: input &struct timespec64
++ * @uts: user's &struct __kernel_timespec
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int put_timespec64(const struct timespec64 *ts,
+ struct __kernel_timespec __user *uts)
+ {
+@@ -839,6 +937,15 @@ static int __put_old_timespec32(const struct timespec64 *ts64,
+ return copy_to_user(cts, &ts, sizeof(ts)) ? -EFAULT : 0;
+ }
+
++/**
++ * get_old_timespec32 - get user's old-format time value into kernel space
++ * @ts: destination &struct timespec64
++ * @uts: user's old-format time value (&struct old_timespec32)
++ *
++ * Handles X86_X32_ABI compatibility conversion.
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int get_old_timespec32(struct timespec64 *ts, const void __user *uts)
+ {
+ if (COMPAT_USE_64BIT_TIME)
+@@ -848,6 +955,16 @@ int get_old_timespec32(struct timespec64 *ts, const void __user *uts)
+ }
+ EXPORT_SYMBOL_GPL(get_old_timespec32);
+
++/**
++ * put_old_timespec32 - convert timespec64 value to &struct old_timespec32 and
++ * copy the latter to userspace
++ * @ts: input &struct timespec64
++ * @uts: user's &struct old_timespec32
++ *
++ * Handles X86_X32_ABI compatibility conversion.
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int put_old_timespec32(const struct timespec64 *ts, void __user *uts)
+ {
+ if (COMPAT_USE_64BIT_TIME)
+@@ -857,6 +974,13 @@ int put_old_timespec32(const struct timespec64 *ts, void __user *uts)
+ }
+ EXPORT_SYMBOL_GPL(put_old_timespec32);
+
++/**
++ * get_itimerspec64 - get user's &struct __kernel_itimerspec into kernel space
++ * @it: destination &struct itimerspec64
++ * @uit: user's &struct __kernel_itimerspec
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int get_itimerspec64(struct itimerspec64 *it,
+ const struct __kernel_itimerspec __user *uit)
+ {
+@@ -872,6 +996,14 @@ int get_itimerspec64(struct itimerspec64 *it,
+ }
+ EXPORT_SYMBOL_GPL(get_itimerspec64);
+
++/**
++ * put_itimerspec64 - convert &struct itimerspec64 to __kernel_itimerspec format
++ * and copy the latter to userspace
++ * @it: input &struct itimerspec64
++ * @uit: user's &struct __kernel_itimerspec
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int put_itimerspec64(const struct itimerspec64 *it,
+ struct __kernel_itimerspec __user *uit)
+ {
+@@ -887,6 +1019,13 @@ int put_itimerspec64(const struct itimerspec64 *it,
+ }
+ EXPORT_SYMBOL_GPL(put_itimerspec64);
+
++/**
++ * get_old_itimerspec32 - get user's &struct old_itimerspec32 into kernel space
++ * @its: destination &struct itimerspec64
++ * @uits: user's &struct old_itimerspec32
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int get_old_itimerspec32(struct itimerspec64 *its,
+ const struct old_itimerspec32 __user *uits)
+ {
+@@ -898,6 +1037,14 @@ int get_old_itimerspec32(struct itimerspec64 *its,
+ }
+ EXPORT_SYMBOL_GPL(get_old_itimerspec32);
+
++/**
++ * put_old_itimerspec32 - convert &struct itimerspec64 to &struct
++ * old_itimerspec32 and copy the latter to userspace
++ * @its: input &struct itimerspec64
++ * @uits: user's &struct old_itimerspec32
++ *
++ * Return: %0 on success or negative errno on error
++ */
+ int put_old_itimerspec32(const struct itimerspec64 *its,
+ struct old_itimerspec32 __user *uits)
+ {
+--
+2.51.0
+
--- /dev/null
+From 83db8f72edc589ac56fb6cf6766cf9b16ec7af6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Mar 2026 21:24:03 -0500
+Subject: time/jiffies: Mark jiffies_64_to_clock_t() notrace
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 755a648e78f12574482d4698d877375793867fa1 ]
+
+The trace_clock_jiffies() function that handles the "uptime" clock for
+tracing calls jiffies_64_to_clock_t(). This causes the function tracer to
+constantly recurse when the tracing clock is set to "uptime". Mark it
+notrace to prevent unnecessary recursion when using the "uptime" clock.
+
+Fixes: 58d4e21e50ff3 ("tracing: Fix wraparound problems in "uptime" trace clock")
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Link: https://patch.msgid.link/20260306212403.72270bb2@robin
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/time.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/time/time.c b/kernel/time/time.c
+index be42ace51255c..170f1f8a0046c 100644
+--- a/kernel/time/time.c
++++ b/kernel/time/time.c
+@@ -702,7 +702,7 @@ EXPORT_SYMBOL(clock_t_to_jiffies);
+ *
+ * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC)
+ */
+-u64 jiffies_64_to_clock_t(u64 x)
++notrace u64 jiffies_64_to_clock_t(u64 x)
+ {
+ #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
+ # if HZ < USER_HZ
+--
+2.51.0
+
--- /dev/null
+From 3938f1902c2ae4fb37d304152b5902f8ec74014e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Sep 2025 08:54:12 -0700
+Subject: Fix CC_HAS_ASM_GOTO_OUTPUT on non-x86 architectures
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+[ Upstream commit fde0ab43b9a30d08817adc5402b69fec83a61cb8 ]
+
+There's a silly problem with the CC_HAS_ASM_GOTO_OUTPUT test: even with
+a working compiler it will fail on some architectures simply because it
+uses the mnemonic "jmp" for testing the inline asm.
+
+And as reported by Geert, not all architectures use that mnemonic, so
+the test fails spuriously on such platforms (including arm and riscv,
+but also several other architectures).
+
+This issue avoided any obvious test failures because the build still
+works thanks to falling back on the old non-asm-goto code, which just
+generates worse code.
+
+Just use an empty asm statement instead.
+
+Reported-and-tested-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Suggested-by: Peter Zijlstra <peterz@infradead.org>
+Fixes: e2ffa15b9baa ("kbuild: Disable CC_HAS_ASM_GOTO_OUTPUT on clang < 17")
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ init/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/init/Kconfig b/init/Kconfig
+index 1a39330252c59..f4b91b1857bf8 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -107,7 +107,7 @@ config CC_HAS_ASM_GOTO_OUTPUT
+ # Detect basic support
+ depends on $(success,echo 'int foo(int x) { asm goto ("": "=r"(x) ::: bar); return x; bar: return 0; }' | $(CC) -x c - -c -o /dev/null)
+ # Detect clang (< v17) scoped label issues
+- depends on $(success,echo 'void b(void **);void* c(void);int f(void){{asm goto("jmp %l0"::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b)))=c();{asm goto("jmp %l0"::::l1);return 2;l1:return 3;}}' | $(CC) -x c - -c -o /dev/null)
++ depends on $(success,echo 'void b(void **);void* c(void);int f(void){{asm goto(""::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b)))=c();{asm goto(""::::l1);return 2;l1:return 3;}}' | $(CC) -x c - -c -o /dev/null)
+
+ config CC_HAS_ASM_GOTO_TIED_OUTPUT
+ depends on CC_HAS_ASM_GOTO_OUTPUT
+--
+2.51.0
+
--- /dev/null
+From d450c1368162d802a8c3fda3b939600d8275c1ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 14:00:48 +0800
+Subject: i3c: dw-i3c-master: Set SIR_REJECT in DAT on device attach and
+ reattach
+
+From: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
+
+[ Upstream commit f311a05784634febd299f03476b80f3f18489767 ]
+
+The DesignWare I3C master controller ACKs IBIs as soon as a valid
+Device Address Table (DAT) entry is present. This can create a race
+between device attachment (after DAA) and the point where the client
+driver enables IBIs via i3c_device_enable_ibi().
+
+Set DEV_ADDR_TABLE_SIR_REJECT in the DAT entry during
+attach_i3c_dev() and reattach_i3c_dev() so that IBIs are rejected
+by default. The bit is managed thereafter by the existing
+dw_i3c_master_set_sir_enabled() function, which clears it in
+enable_ibi() after ENEC is issued, and restores it in disable_ibi()
+after DISEC.
+
+Fixes: 1dd728f5d4d4 ("i3c: master: Add driver for Synopsys DesignWare IP")
+Signed-off-by: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/53f5b8cbdd8af789ec38b95b02873f32f9182dd6.1770962368.git.adrianhoyin.ng@altera.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i3c/master/dw-i3c-master.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
+index 4c019c746f231..e0853a6bde0a4 100644
+--- a/drivers/i3c/master/dw-i3c-master.c
++++ b/drivers/i3c/master/dw-i3c-master.c
+@@ -1013,7 +1013,7 @@ static int dw_i3c_master_reattach_i3c_dev(struct i3c_dev_desc *dev,
+ master->free_pos &= ~BIT(pos);
+ }
+
+- writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr),
++ writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr) | DEV_ADDR_TABLE_SIR_REJECT,
+ master->regs +
+ DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
+
+@@ -1042,7 +1042,7 @@ static int dw_i3c_master_attach_i3c_dev(struct i3c_dev_desc *dev)
+ master->free_pos &= ~BIT(pos);
+ i3c_dev_set_master_data(dev, data);
+
+- writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr),
++ writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr) | DEV_ADDR_TABLE_SIR_REJECT,
+ master->regs +
+ DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
+
+--
+2.51.0
+
--- /dev/null
+From 5246feb2235fdc49f04bc2309ca3ca92b25bf7fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Sep 2025 15:21:51 +0200
+Subject: kbuild: Disable CC_HAS_ASM_GOTO_OUTPUT on clang < 17
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit e2ffa15b9baa447e444d654ffd47123ba6443ae4 ]
+
+clang < 17 fails to use scope local labels with CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y:
+
+ {
+ __label__ local_lbl;
+ ...
+ unsafe_get_user(uval, uaddr, local_lbl);
+ ...
+ return 0;
+ local_lbl:
+ return -EFAULT;
+ }
+
+when two such scopes exist in the same function:
+
+ error: cannot jump from this asm goto statement to one of its possible targets
+
+There are other failure scenarios. Shuffling code around slightly makes it
+worse and fail even with one instance.
+
+That issue prevents using local labels for a cleanup based user access
+mechanism.
+
+After failed attempts to provide a simple enough test case for the 'depends
+on' test in Kconfig, the initial cure was to mark ASM goto broken on clang
+versions < 17 to get this road block out of the way.
+
+But Nathan pointed out that this is a known clang issue and indeed affects
+clang < version 17 in combination with cleanup(). It's not even required to
+use local labels for that.
+
+The clang issue tracker has a small enough test case, which can be used as
+a test in the 'depends on' section of CC_HAS_ASM_GOTO_OUTPUT:
+
+void bar(void **);
+void* baz(void);
+
+int foo (void) {
+ {
+ asm goto("jmp %l0"::::l0);
+ return 0;
+l0:
+ return 1;
+ }
+ void *x __attribute__((cleanup(bar))) = baz();
+ {
+ asm goto("jmp %l0"::::l1);
+ return 42;
+l1:
+ return 0xff;
+ }
+}
+
+Add another dependency to config CC_HAS_ASM_GOTO_OUTPUT for it and use the
+clang issue tracker test case for detection by condensing it to obfuscated
+C-code contest format. This reliably catches the problem on clang < 17 and
+did not show any issues on the non broken GCC versions.
+
+That test might be sufficient to catch all issues and therefore could
+replace the existing test, but keeping that around does no harm either.
+
+Thanks to Nathan for pointing to the relevant clang issue!
+
+Suggested-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Reviewed-by: Nathan Chancellor <nathan@kernel.org>
+Link: https://github.com/ClangBuiltLinux/linux/issues/1886
+Link: https://github.com/llvm/llvm-project/commit/f023f5cdb2e6c19026f04a15b5a935c041835d14
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ init/Kconfig | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/init/Kconfig b/init/Kconfig
+index 219ccdb0af732..1a39330252c59 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -104,7 +104,10 @@ config GCC_ASM_GOTO_OUTPUT_BROKEN
+ config CC_HAS_ASM_GOTO_OUTPUT
+ def_bool y
+ depends on !GCC_ASM_GOTO_OUTPUT_BROKEN
++ # Detect basic support
+ depends on $(success,echo 'int foo(int x) { asm goto ("": "=r"(x) ::: bar); return x; bar: return 0; }' | $(CC) -x c - -c -o /dev/null)
++ # Detect clang (< v17) scoped label issues
++ depends on $(success,echo 'void b(void **);void* c(void);int f(void){{asm goto("jmp %l0"::::l0);return 0;l0:return 1;}void *x __attribute__((cleanup(b)))=c();{asm goto("jmp %l0"::::l1);return 2;l1:return 3;}}' | $(CC) -x c - -c -o /dev/null)
+
+ config CC_HAS_ASM_GOTO_TIED_OUTPUT
+ depends on CC_HAS_ASM_GOTO_OUTPUT
+--
+2.51.0
+
--- /dev/null
+From 7ecd0f88688ba719967c2a0fbfbc8b0eee993ff6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Oct 2024 10:18:19 +0800
+Subject: scsi: hisi_sas: Add time interval between two H2D FIS following soft
+ reset spec
+
+From: Xingui Yang <yangxingui@huawei.com>
+
+[ Upstream commit 3c62791322e42d1afd65acfdb5b3a371bde21ede ]
+
+Spec says at least 5us between two H2D FIS when do soft reset, but be
+generous and sleep for about 1ms.
+
+Signed-off-by: Xingui Yang <yangxingui@huawei.com>
+Link: https://lore.kernel.org/r/20241008021822.2617339-11-liyihang9@huawei.com
+Reviewed-by: Yihang Li <liyihang9@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: 8ddc0c269165 ("scsi: hisi_sas: Fix NULL pointer exception during user_scan()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index d9500b7306905..43d2ca4c6605f 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1341,6 +1341,7 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device)
+ }
+
+ if (rc == TMF_RESP_FUNC_COMPLETE) {
++ usleep_range(900, 1000);
+ ata_for_each_link(link, ap, EDGE) {
+ int pmp = sata_srst_pmp(link);
+
+--
+2.51.0
+
--- /dev/null
+From 259eb44cacf8a15d3a3c2a0838ddc93b2212d42e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Mar 2026 14:40:39 +0800
+Subject: scsi: hisi_sas: Fix NULL pointer exception during user_scan()
+
+From: Xingui Yang <yangxingui@huawei.com>
+
+[ Upstream commit 8ddc0c26916574395447ebf4cff684314f6873a9 ]
+
+user_scan() invokes updated sas_user_scan() for channel 0, and if
+successful, iteratively scans remaining channels (1 to shost->max_channel)
+via scsi_scan_host_selected() in commit 37c4e72b0651 ("scsi: Fix
+sas_user_scan() to handle wildcard and multi-channel scans"). However,
+hisi_sas supports only one channel, and the current value of max_channel is
+1. sas_user_scan() for channel 1 will trigger the following NULL pointer
+exception:
+
+[ 441.554662] Unable to handle kernel NULL pointer dereference at virtual address 00000000000008b0
+[ 441.554699] Mem abort info:
+[ 441.554710] ESR = 0x0000000096000004
+[ 441.554718] EC = 0x25: DABT (current EL), IL = 32 bits
+[ 441.554723] SET = 0, FnV = 0
+[ 441.554726] EA = 0, S1PTW = 0
+[ 441.554730] FSC = 0x04: level 0 translation fault
+[ 441.554735] Data abort info:
+[ 441.554737] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
+[ 441.554742] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
+[ 441.554747] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+[ 441.554752] user pgtable: 4k pages, 48-bit VAs, pgdp=00000828377a6000
+[ 441.554757] [00000000000008b0] pgd=0000000000000000, p4d=0000000000000000
+[ 441.554769] Internal error: Oops: 0000000096000004 [#1] SMP
+[ 441.629589] Modules linked in: arm_spe_pmu arm_smmuv3_pmu tpm_tis_spi hisi_uncore_sllc_pmu hisi_uncore_pa_pmu hisi_uncore_l3c_pmu hisi_uncore_hha_pmu hisi_uncore_ddrc_pmu hisi_uncore_cpa_pmu hns3_pmu hisi_ptt hisi_pcie_pmu tpm_tis_core spidev spi_hisi_sfc_v3xx hisi_uncore_pmu spi_dw_mmio fuse hclge hclge_common hisi_sec2 hisi_hpre hisi_zip hisi_qm hns3 hisi_sas_v3_hw sm3_ce sbsa_gwdt hnae3 hisi_sas_main uacce hisi_dma i2c_hisi dm_mirror dm_region_hash dm_log dm_mod
+[ 441.670819] CPU: 46 UID: 0 PID: 6994 Comm: bash Kdump: loaded Not tainted 7.0.0-rc2+ #84 PREEMPT
+[ 441.691327] pstate: 81400009 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
+[ 441.698277] pc : sas_find_dev_by_rphy+0x44/0x118
+[ 441.702896] lr : sas_find_dev_by_rphy+0x3c/0x118
+[ 441.707502] sp : ffff80009abbba40
+[ 441.710805] x29: ffff80009abbba40 x28: ffff082819a40008 x27: ffff082810c37c08
+[ 441.717930] x26: ffff082810c37c28 x25: ffff082819a40290 x24: ffff082810c37c00
+[ 441.725054] x23: 0000000000000000 x22: 0000000000000001 x21: ffff082819a40000
+[ 441.732179] x20: ffff082819a40290 x19: 0000000000000000 x18: 0000000000000020
+[ 441.739304] x17: 0000000000000000 x16: ffffb5dad6bda690 x15: 00000000ffffffff
+[ 441.746428] x14: ffff082814c3b26c x13: 00000000ffffffff x12: ffff082814c3b26a
+[ 441.753553] x11: 00000000000000c0 x10: 000000000000003a x9 : ffffb5dad5ea94f4
+[ 441.760678] x8 : 000000000000003a x7 : ffff80009abbbab0 x6 : 0000000000000030
+[ 441.767802] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
+[ 441.774926] x2 : ffff08280f35a300 x1 : ffffb5dad7127180 x0 : 0000000000000000
+[ 441.782053] Call trace:
+[ 441.784488] sas_find_dev_by_rphy+0x44/0x118 (P)
+[ 441.789095] sas_target_alloc+0x24/0xb0
+[ 441.792920] scsi_alloc_target+0x290/0x330
+[ 441.797010] __scsi_scan_target+0x88/0x258
+[ 441.801096] scsi_scan_channel+0x74/0xb8
+[ 441.805008] scsi_scan_host_selected+0x170/0x188
+[ 441.809615] sas_user_scan+0xfc/0x148
+[ 441.813267] store_scan+0x10c/0x180
+[ 441.816743] dev_attr_store+0x20/0x40
+[ 441.820398] sysfs_kf_write+0x84/0xa8
+[ 441.824054] kernfs_fop_write_iter+0x130/0x1c8
+[ 441.828487] vfs_write+0x2c0/0x370
+[ 441.831880] ksys_write+0x74/0x118
+[ 441.835271] __arm64_sys_write+0x24/0x38
+[ 441.839182] invoke_syscall+0x50/0x120
+[ 441.842919] el0_svc_common.constprop.0+0xc8/0xf0
+[ 441.847611] do_el0_svc+0x24/0x38
+[ 441.850913] el0_svc+0x38/0x158
+[ 441.854043] el0t_64_sync_handler+0xa0/0xe8
+[ 441.858214] el0t_64_sync+0x1ac/0x1b0
+[ 441.861865] Code: aa1303e0 97ff70a8 34ffff80 d10a4273 (f9445a75)
+[ 441.867946] ---[ end trace 0000000000000000 ]---
+
+Therefore, set max_channel to 0.
+
+Fixes: e21fe3a52692 ("scsi: hisi_sas: add initialisation for v3 pci-based controller")
+Signed-off-by: Xingui Yang <yangxingui@huawei.com>
+Signed-off-by: Yihang Li <liyihang9@huawei.com>
+Link: https://patch.msgid.link/20260305064039.4096775-1-liyihang9@huawei.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +-
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 71d12b94ba5be..236e23620f21d 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -2544,7 +2544,7 @@ int hisi_sas_probe(struct platform_device *pdev,
+ shost->transportt = hisi_sas_stt;
+ shost->max_id = HISI_SAS_MAX_DEVICES;
+ shost->max_lun = ~0;
+- shost->max_channel = 1;
++ shost->max_channel = 0;
+ shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN;
+ if (hisi_hba->hw->slot_index_alloc) {
+ shost->can_queue = HISI_SAS_MAX_COMMANDS;
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index cf0df9b405b24..e958b588d078f 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -4959,7 +4959,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ shost->transportt = hisi_sas_stt;
+ shost->max_id = HISI_SAS_MAX_DEVICES;
+ shost->max_lun = ~0;
+- shost->max_channel = 1;
++ shost->max_channel = 0;
+ shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN;
+ shost->can_queue = HISI_SAS_UNRESERVED_IPTT;
+ shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT;
+--
+2.51.0
+
--- /dev/null
+From 020bbd183a44da003ef27d8902484b0854a92ae3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 16:08:42 +0800
+Subject: scsi: hisi_sas: Use macro instead of magic number
+
+From: Yihang Li <liyihang9@huawei.com>
+
+[ Upstream commit 4ca7fe99fc8485fcd04b367f37dc7a48f1355419 ]
+
+The hisi_sas driver has a large number of magic numbers which makes for
+unfriendly code reading. Use macro definitions instead.
+
+Signed-off-by: Yihang Li <liyihang9@huawei.com>
+Link: https://lore.kernel.org/r/20250414080845.1220997-2-liyihang9@huawei.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: 8ddc0c269165 ("scsi: hisi_sas: Fix NULL pointer exception during user_scan()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 43 +++--
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 41 +++--
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 244 ++++++++++++++++---------
+ 3 files changed, 213 insertions(+), 115 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index 010479a354eee..3311f9b9eca6a 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -46,6 +46,13 @@
+ #define HISI_SAS_IOST_ITCT_CACHE_DW_SZ 10
+ #define HISI_SAS_FIFO_DATA_DW_SIZE 32
+
++#define HISI_SAS_REG_MEM_SIZE 4
++#define HISI_SAS_MAX_CDB_LEN 16
++#define HISI_SAS_BLK_QUEUE_DEPTH 64
++
++#define BYTE_TO_DW 4
++#define BYTE_TO_DDW 8
++
+ #define HISI_SAS_STATUS_BUF_SZ (sizeof(struct hisi_sas_status_buffer))
+ #define HISI_SAS_COMMAND_TABLE_SZ (sizeof(union hisi_sas_command_table))
+
+@@ -92,6 +99,8 @@
+
+ #define HISI_SAS_WAIT_PHYUP_TIMEOUT (30 * HZ)
+ #define HISI_SAS_CLEAR_ITCT_TIMEOUT (20 * HZ)
++#define HISI_SAS_DELAY_FOR_PHY_DISABLE 100
++#define NAME_BUF_SIZE 256
+
+ struct hisi_hba;
+
+@@ -167,6 +176,8 @@ struct hisi_sas_debugfs_fifo {
+ u32 rd_data[HISI_SAS_FIFO_DATA_DW_SIZE];
+ };
+
++#define FRAME_RCVD_BUF 32
++#define SAS_PHY_RESV_SIZE 2
+ struct hisi_sas_phy {
+ struct work_struct works[HISI_PHYES_NUM];
+ struct hisi_hba *hisi_hba;
+@@ -178,10 +189,10 @@ struct hisi_sas_phy {
+ spinlock_t lock;
+ u64 port_id; /* from hw */
+ u64 frame_rcvd_size;
+- u8 frame_rcvd[32];
++ u8 frame_rcvd[FRAME_RCVD_BUF];
+ u8 phy_attached;
+ u8 in_reset;
+- u8 reserved[2];
++ u8 reserved[SAS_PHY_RESV_SIZE];
+ u32 phy_type;
+ u32 code_violation_err_count;
+ enum sas_linkrate minimum_linkrate;
+@@ -348,6 +359,7 @@ struct hisi_sas_hw {
+ };
+
+ #define HISI_SAS_MAX_DEBUGFS_DUMP (50)
++#define HISI_SAS_DEFAULT_DEBUGFS_DUMP 1
+
+ struct hisi_sas_debugfs_cq {
+ struct hisi_sas_cq *cq;
+@@ -527,12 +539,13 @@ struct hisi_sas_cmd_hdr {
+ __le64 dif_prd_table_addr;
+ };
+
++#define ITCT_RESV_DDW 12
+ struct hisi_sas_itct {
+ __le64 qw0;
+ __le64 sas_addr;
+ __le64 qw2;
+ __le64 qw3;
+- __le64 qw4_15[12];
++ __le64 qw4_15[ITCT_RESV_DDW];
+ };
+
+ struct hisi_sas_iost {
+@@ -542,22 +555,26 @@ struct hisi_sas_iost {
+ __le64 qw3;
+ };
+
++#define ERROR_RECORD_BUF_DW 4
+ struct hisi_sas_err_record {
+- u32 data[4];
++ u32 data[ERROR_RECORD_BUF_DW];
+ };
+
++#define FIS_RESV_DW 3
+ struct hisi_sas_initial_fis {
+ struct hisi_sas_err_record err_record;
+ struct dev_to_host_fis fis;
+- u32 rsvd[3];
++ u32 rsvd[FIS_RESV_DW];
+ };
+
++#define BREAKPOINT_DATA_SIZE 128
+ struct hisi_sas_breakpoint {
+- u8 data[128];
++ u8 data[BREAKPOINT_DATA_SIZE];
+ };
+
++#define BREAKPOINT_TAG_NUM 32
+ struct hisi_sas_sata_breakpoint {
+- struct hisi_sas_breakpoint tag[32];
++ struct hisi_sas_breakpoint tag[BREAKPOINT_TAG_NUM];
+ };
+
+ struct hisi_sas_sge {
+@@ -568,13 +585,15 @@ struct hisi_sas_sge {
+ __le32 data_off;
+ };
+
++#define SMP_CMD_TABLE_SIZE 44
+ struct hisi_sas_command_table_smp {
+- u8 bytes[44];
++ u8 bytes[SMP_CMD_TABLE_SIZE];
+ };
+
++#define DUMMY_BUF_SIZE 12
+ struct hisi_sas_command_table_stp {
+ struct host_to_dev_fis command_fis;
+- u8 dummy[12];
++ u8 dummy[DUMMY_BUF_SIZE];
+ u8 atapi_cdb[ATAPI_CDB_LEN];
+ };
+
+@@ -588,12 +607,13 @@ struct hisi_sas_sge_dif_page {
+ struct hisi_sas_sge sge[HISI_SAS_SGE_DIF_PAGE_CNT];
+ } __aligned(16);
+
++#define PROT_BUF_SIZE 7
+ struct hisi_sas_command_table_ssp {
+ struct ssp_frame_hdr hdr;
+ union {
+ struct {
+ struct ssp_command_iu task;
+- u32 prot[7];
++ u32 prot[PROT_BUF_SIZE];
+ };
+ struct ssp_tmf_iu ssp_task;
+ struct xfer_rdy_iu xfer_rdy;
+@@ -607,9 +627,10 @@ union hisi_sas_command_table {
+ struct hisi_sas_command_table_stp stp;
+ } __aligned(16);
+
++#define IU_BUF_SIZE 1024
+ struct hisi_sas_status_buffer {
+ struct hisi_sas_err_record err;
+- u8 iu[1024];
++ u8 iu[IU_BUF_SIZE];
+ } __aligned(16);
+
+ struct hisi_sas_slot_buf_table {
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 43d2ca4c6605f..71d12b94ba5be 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -7,6 +7,16 @@
+ #include "hisi_sas.h"
+ #define DRV_NAME "hisi_sas"
+
++#define LINK_RATE_BIT_MASK 2
++#define FIS_BUF_SIZE 20
++#define WAIT_CMD_COMPLETE_DELAY 100
++#define WAIT_CMD_COMPLETE_TMROUT 5000
++#define DELAY_FOR_LINK_READY 2000
++#define BLK_CNT_OPTIMIZE_MARK 64
++#define HZ_TO_MHZ 1000000
++#define DELAY_FOR_SOFTRESET_MAX 1000
++#define DELAY_FOR_SOFTRESET_MIN 900
++
+ #define DEV_IS_GONE(dev) \
+ ((!dev) || (dev->dev_type == SAS_PHY_UNUSED))
+
+@@ -127,7 +137,7 @@ u8 hisi_sas_get_prog_phy_linkrate_mask(enum sas_linkrate max)
+
+ max -= SAS_LINK_RATE_1_5_GBPS;
+ for (i = 0; i <= max; i++)
+- rate |= 1 << (i * 2);
++ rate |= 1 << (i * LINK_RATE_BIT_MASK);
+ return rate;
+ }
+ EXPORT_SYMBOL_GPL(hisi_sas_get_prog_phy_linkrate_mask);
+@@ -877,7 +887,7 @@ int hisi_sas_device_configure(struct scsi_device *sdev,
+ if (ret)
+ return ret;
+ if (!dev_is_sata(dev))
+- sas_change_queue_depth(sdev, 64);
++ sas_change_queue_depth(sdev, HISI_SAS_BLK_QUEUE_DEPTH);
+
+ return 0;
+ }
+@@ -1239,7 +1249,7 @@ static int hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no,
+ sas_phy->phy->minimum_linkrate = min;
+
+ hisi_sas_phy_enable(hisi_hba, phy_no, 0);
+- msleep(100);
++ msleep(HISI_SAS_DELAY_FOR_PHY_DISABLE);
+ hisi_hba->hw->phy_set_linkrate(hisi_hba, phy_no, &_r);
+ hisi_sas_phy_enable(hisi_hba, phy_no, 1);
+
+@@ -1269,7 +1279,7 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func,
+
+ case PHY_FUNC_LINK_RESET:
+ hisi_sas_phy_enable(hisi_hba, phy_no, 0);
+- msleep(100);
++ msleep(HISI_SAS_DELAY_FOR_PHY_DISABLE);
+ hisi_sas_phy_enable(hisi_hba, phy_no, 1);
+ break;
+
+@@ -1324,7 +1334,7 @@ static void hisi_sas_fill_ata_reset_cmd(struct ata_device *dev,
+
+ static int hisi_sas_softreset_ata_disk(struct domain_device *device)
+ {
+- u8 fis[20] = {0};
++ u8 fis[FIS_BUF_SIZE] = {0};
+ struct ata_port *ap = device->sata_dev.ap;
+ struct ata_link *link;
+ int rc = TMF_RESP_FUNC_FAILED;
+@@ -1341,7 +1351,7 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device)
+ }
+
+ if (rc == TMF_RESP_FUNC_COMPLETE) {
+- usleep_range(900, 1000);
++ usleep_range(DELAY_FOR_SOFTRESET_MIN, DELAY_FOR_SOFTRESET_MAX);
+ ata_for_each_link(link, ap, EDGE) {
+ int pmp = sata_srst_pmp(link);
+
+@@ -1460,7 +1470,7 @@ static void hisi_sas_send_ata_reset_each_phy(struct hisi_hba *hisi_hba,
+ struct device *dev = hisi_hba->dev;
+ int rc = TMF_RESP_FUNC_FAILED;
+ struct ata_link *link;
+- u8 fis[20] = {0};
++ u8 fis[FIS_BUF_SIZE] = {0};
+ int i;
+
+ for (i = 0; i < hisi_hba->n_phy; i++) {
+@@ -1527,7 +1537,9 @@ void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba)
+ hisi_hba->phy_state = hisi_hba->hw->get_phys_state(hisi_hba);
+
+ scsi_block_requests(shost);
+- hisi_hba->hw->wait_cmds_complete_timeout(hisi_hba, 100, 5000);
++ hisi_hba->hw->wait_cmds_complete_timeout(hisi_hba,
++ WAIT_CMD_COMPLETE_DELAY,
++ WAIT_CMD_COMPLETE_TMROUT);
+
+ /*
+ * hisi_hba->timer is only used for v1/v2 hw, and check hw->sht
+@@ -1828,7 +1840,7 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device)
+ rc = ata_wait_after_reset(link, jiffies + HISI_SAS_WAIT_PHYUP_TIMEOUT,
+ smp_ata_check_ready_type);
+ } else {
+- msleep(2000);
++ msleep(DELAY_FOR_LINK_READY);
+ }
+
+ return rc;
+@@ -2243,12 +2255,14 @@ int hisi_sas_alloc(struct hisi_hba *hisi_hba)
+ goto err_out;
+
+ /* roundup to avoid overly large block size */
+- max_command_entries_ru = roundup(max_command_entries, 64);
++ max_command_entries_ru = roundup(max_command_entries,
++ BLK_CNT_OPTIMIZE_MARK);
+ if (hisi_hba->prot_mask & HISI_SAS_DIX_PROT_MASK)
+ sz_slot_buf_ru = sizeof(struct hisi_sas_slot_dif_buf_table);
+ else
+ sz_slot_buf_ru = sizeof(struct hisi_sas_slot_buf_table);
+- sz_slot_buf_ru = roundup(sz_slot_buf_ru, 64);
++
++ sz_slot_buf_ru = roundup(sz_slot_buf_ru, BLK_CNT_OPTIMIZE_MARK);
+ s = max(lcm(max_command_entries_ru, sz_slot_buf_ru), PAGE_SIZE);
+ blk_cnt = (max_command_entries_ru * sz_slot_buf_ru) / s;
+ slots_per_blk = s / sz_slot_buf_ru;
+@@ -2413,7 +2427,8 @@ int hisi_sas_get_fw_info(struct hisi_hba *hisi_hba)
+ if (IS_ERR(refclk))
+ dev_dbg(dev, "no ref clk property\n");
+ else
+- hisi_hba->refclk_frequency_mhz = clk_get_rate(refclk) / 1000000;
++ hisi_hba->refclk_frequency_mhz = clk_get_rate(refclk) /
++ HZ_TO_MHZ;
+
+ if (device_property_read_u32(dev, "phy-count", &hisi_hba->n_phy)) {
+ dev_err(dev, "could not get property phy-count\n");
+@@ -2530,7 +2545,7 @@ int hisi_sas_probe(struct platform_device *pdev,
+ shost->max_id = HISI_SAS_MAX_DEVICES;
+ shost->max_lun = ~0;
+ shost->max_channel = 1;
+- shost->max_cmd_len = 16;
++ shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN;
+ if (hisi_hba->hw->slot_index_alloc) {
+ shost->can_queue = HISI_SAS_MAX_COMMANDS;
+ shost->cmd_per_lun = HISI_SAS_MAX_COMMANDS;
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 2b04556681a1a..cf0df9b405b24 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -465,6 +465,12 @@
+ #define ITCT_HDR_RTOLT_OFF 48
+ #define ITCT_HDR_RTOLT_MSK (0xffffULL << ITCT_HDR_RTOLT_OFF)
+
++/*debugfs*/
++#define TWO_PARA_PER_LINE 2
++#define FOUR_PARA_PER_LINE 4
++#define DUMP_BUF_SIZE 8
++#define BIST_BUF_SIZE 16
++
+ struct hisi_sas_protect_iu_v3_hw {
+ u32 dw0;
+ u32 lbrtcv;
+@@ -535,6 +541,43 @@ struct hisi_sas_err_record_v3 {
+
+ #define BASE_VECTORS_V3_HW 16
+ #define MIN_AFFINE_VECTORS_V3_HW (BASE_VECTORS_V3_HW + 1)
++#define IRQ_PHY_UP_DOWN_INDEX 1
++#define IRQ_CHL_INDEX 2
++#define IRQ_AXI_INDEX 11
++
++#define DELAY_FOR_RESET_HW 100
++#define HDR_SG_MOD 0x2
++#define LUN_SIZE 8
++#define ATTR_PRIO_REGION 9
++#define CDB_REGION 12
++#define PRIO_OFF 3
++#define TMF_REGION 10
++#define TAG_MSB 12
++#define TAG_LSB 13
++#define SMP_FRAME_TYPE 2
++#define SMP_CRC_SIZE 4
++#define HDR_TAG_OFF 3
++#define HOST_NO_OFF 6
++#define PHY_NO_OFF 7
++#define IDENTIFY_REG_READ 6
++#define LINK_RESET_TIMEOUT_OFF 4
++#define DECIMALISM_FLAG 10
++#define WAIT_RETRY 100
++#define WAIT_TMROUT 5000
++
++#define ID_DWORD0_INDEX 0
++#define ID_DWORD1_INDEX 1
++#define ID_DWORD2_INDEX 2
++#define ID_DWORD3_INDEX 3
++#define ID_DWORD4_INDEX 4
++#define ID_DWORD5_INDEX 5
++#define TICKS_BIT_INDEX 24
++#define COUNT_BIT_INDEX 8
++
++#define PORT_REG_LENGTH 0x100
++#define GLOBAL_REG_LENGTH 0x800
++#define AXI_REG_LENGTH 0x61
++#define RAS_REG_LENGTH 0x10
+
+ #define CHNL_INT_STS_MSK 0xeeeeeeee
+ #define CHNL_INT_STS_PHY_MSK 0xe
+@@ -807,17 +850,17 @@ static void config_id_frame_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
+ identify_buffer = (u32 *)(&identify_frame);
+
+ hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD0,
+- __swab32(identify_buffer[0]));
++ __swab32(identify_buffer[ID_DWORD0_INDEX]));
+ hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD1,
+- __swab32(identify_buffer[1]));
++ __swab32(identify_buffer[ID_DWORD1_INDEX]));
+ hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD2,
+- __swab32(identify_buffer[2]));
++ __swab32(identify_buffer[ID_DWORD2_INDEX]));
+ hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD3,
+- __swab32(identify_buffer[3]));
++ __swab32(identify_buffer[ID_DWORD3_INDEX]));
+ hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD4,
+- __swab32(identify_buffer[4]));
++ __swab32(identify_buffer[ID_DWORD4_INDEX]));
+ hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD5,
+- __swab32(identify_buffer[5]));
++ __swab32(identify_buffer[ID_DWORD5_INDEX]));
+ }
+
+ static void setup_itct_v3_hw(struct hisi_hba *hisi_hba,
+@@ -937,7 +980,7 @@ static int reset_hw_v3_hw(struct hisi_hba *hisi_hba)
+
+ /* Disable all of the PHYs */
+ hisi_sas_stop_phys(hisi_hba);
+- udelay(50);
++ udelay(HISI_SAS_DELAY_FOR_PHY_DISABLE);
+
+ /* Ensure axi bus idle */
+ ret = hisi_sas_read32_poll_timeout(AXI_CFG, val, !val,
+@@ -977,7 +1020,7 @@ static int hw_init_v3_hw(struct hisi_hba *hisi_hba)
+ return rc;
+ }
+
+- msleep(100);
++ msleep(DELAY_FOR_RESET_HW);
+ init_reg_v3_hw(hisi_hba);
+
+ if (guid_parse("D5918B4B-37AE-4E10-A99F-E5E8A6EF4C1F", &guid)) {
+@@ -1026,7 +1069,7 @@ static void disable_phy_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
+ cfg &= ~PHY_CFG_ENA_MSK;
+ hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg);
+
+- mdelay(50);
++ mdelay(HISI_SAS_DELAY_FOR_PHY_DISABLE);
+
+ state = hisi_sas_read32(hisi_hba, PHY_STATE);
+ if (state & BIT(phy_no)) {
+@@ -1062,7 +1105,7 @@ static void phy_hard_reset_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
+ hisi_sas_phy_write32(hisi_hba, phy_no, TXID_AUTO,
+ txid_auto | TX_HARDRST_MSK);
+ }
+- msleep(100);
++ msleep(HISI_SAS_DELAY_FOR_PHY_DISABLE);
+ hisi_sas_phy_enable(hisi_hba, phy_no, 1);
+ }
+
+@@ -1107,7 +1150,8 @@ static int get_wideport_bitmap_v3_hw(struct hisi_hba *hisi_hba, int port_id)
+
+ for (i = 0; i < hisi_hba->n_phy; i++)
+ if (phy_state & BIT(i))
+- if (((phy_port_num_ma >> (i * 4)) & 0xf) == port_id)
++ if (((phy_port_num_ma >> (i * HISI_SAS_REG_MEM_SIZE)) & 0xf) ==
++ port_id)
+ bitmap |= BIT(i);
+
+ return bitmap;
+@@ -1305,9 +1349,9 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
+ dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF;
+
+ dw2 = (((sizeof(struct ssp_command_iu) + sizeof(struct ssp_frame_hdr)
+- + 3) / 4) << CMD_HDR_CFL_OFF) |
+- ((HISI_SAS_MAX_SSP_RESP_SZ / 4) << CMD_HDR_MRFL_OFF) |
+- (2 << CMD_HDR_SG_MOD_OFF);
++ + 3) / BYTE_TO_DW) << CMD_HDR_CFL_OFF) |
++ ((HISI_SAS_MAX_SSP_RESP_SZ / BYTE_TO_DW) << CMD_HDR_MRFL_OFF) |
++ (HDR_SG_MOD << CMD_HDR_SG_MOD_OFF);
+ hdr->dw2 = cpu_to_le32(dw2);
+ hdr->transfer_tags = cpu_to_le32(slot->idx);
+
+@@ -1327,18 +1371,19 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
+ buf_cmd = hisi_sas_cmd_hdr_addr_mem(slot) +
+ sizeof(struct ssp_frame_hdr);
+
+- memcpy(buf_cmd, &task->ssp_task.LUN, 8);
++ memcpy(buf_cmd, &task->ssp_task.LUN, LUN_SIZE);
+ if (!tmf) {
+- buf_cmd[9] = ssp_task->task_attr;
+- memcpy(buf_cmd + 12, scsi_cmnd->cmnd, scsi_cmnd->cmd_len);
++ buf_cmd[ATTR_PRIO_REGION] = ssp_task->task_attr;
++ memcpy(buf_cmd + CDB_REGION, scsi_cmnd->cmnd,
++ scsi_cmnd->cmd_len);
+ } else {
+- buf_cmd[10] = tmf->tmf;
++ buf_cmd[TMF_REGION] = tmf->tmf;
+ switch (tmf->tmf) {
+ case TMF_ABORT_TASK:
+ case TMF_QUERY_TASK:
+- buf_cmd[12] =
++ buf_cmd[TAG_MSB] =
+ (tmf->tag_of_task_to_be_managed >> 8) & 0xff;
+- buf_cmd[13] =
++ buf_cmd[TAG_LSB] =
+ tmf->tag_of_task_to_be_managed & 0xff;
+ break;
+ default:
+@@ -1371,7 +1416,8 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
+ unsigned int interval = scsi_prot_interval(scsi_cmnd);
+ unsigned int ilog2_interval = ilog2(interval);
+
+- len = (task->total_xfer_len >> ilog2_interval) * 8;
++ len = (task->total_xfer_len >> ilog2_interval) *
++ BYTE_TO_DDW;
+ }
+ }
+
+@@ -1391,6 +1437,7 @@ static void prep_smp_v3_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_device *sas_dev = device->lldd_dev;
+ dma_addr_t req_dma_addr;
+ unsigned int req_len;
++ u32 cfl;
+
+ /* req */
+ sg_req = &task->smp_task.smp_req;
+@@ -1401,7 +1448,7 @@ static void prep_smp_v3_hw(struct hisi_hba *hisi_hba,
+ /* dw0 */
+ hdr->dw0 = cpu_to_le32((port->id << CMD_HDR_PORT_OFF) |
+ (1 << CMD_HDR_PRIORITY_OFF) | /* high pri */
+- (2 << CMD_HDR_CMD_OFF)); /* smp */
++ (SMP_FRAME_TYPE << CMD_HDR_CMD_OFF)); /* smp */
+
+ /* map itct entry */
+ hdr->dw1 = cpu_to_le32((sas_dev->device_id << CMD_HDR_DEV_ID_OFF) |
+@@ -1409,8 +1456,9 @@ static void prep_smp_v3_hw(struct hisi_hba *hisi_hba,
+ (DIR_NO_DATA << CMD_HDR_DIR_OFF));
+
+ /* dw2 */
+- hdr->dw2 = cpu_to_le32((((req_len - 4) / 4) << CMD_HDR_CFL_OFF) |
+- (HISI_SAS_MAX_SMP_RESP_SZ / 4 <<
++ cfl = (req_len - SMP_CRC_SIZE) / BYTE_TO_DW;
++ hdr->dw2 = cpu_to_le32((cfl << CMD_HDR_CFL_OFF) |
++ (HISI_SAS_MAX_SMP_RESP_SZ / BYTE_TO_DW <<
+ CMD_HDR_MRFL_OFF));
+
+ hdr->transfer_tags = cpu_to_le32(slot->idx << CMD_HDR_IPTT_OFF);
+@@ -1477,12 +1525,13 @@ static void prep_ata_v3_hw(struct hisi_hba *hisi_hba,
+ struct ata_queued_cmd *qc = task->uldd_task;
+
+ hdr_tag = qc->tag;
+- task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3);
++ task->ata_task.fis.sector_count |=
++ (u8)(hdr_tag << HDR_TAG_OFF);
+ dw2 |= hdr_tag << CMD_HDR_NCQ_TAG_OFF;
+ }
+
+- dw2 |= (HISI_SAS_MAX_STP_RESP_SZ / 4) << CMD_HDR_CFL_OFF |
+- 2 << CMD_HDR_SG_MOD_OFF;
++ dw2 |= (HISI_SAS_MAX_STP_RESP_SZ / BYTE_TO_DW) << CMD_HDR_CFL_OFF |
++ HDR_SG_MOD << CMD_HDR_SG_MOD_OFF;
+ hdr->dw2 = cpu_to_le32(dw2);
+
+ /* dw3 */
+@@ -1542,9 +1591,9 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+ hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1);
+
+ port_id = hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA);
+- port_id = (port_id >> (4 * phy_no)) & 0xf;
++ port_id = (port_id >> (HISI_SAS_REG_MEM_SIZE * phy_no)) & 0xf;
+ link_rate = hisi_sas_read32(hisi_hba, PHY_CONN_RATE);
+- link_rate = (link_rate >> (phy_no * 4)) & 0xf;
++ link_rate = (link_rate >> (phy_no * HISI_SAS_REG_MEM_SIZE)) & 0xf;
+
+ if (port_id == 0xf) {
+ dev_err(dev, "phyup: phy%d invalid portid\n", phy_no);
+@@ -1577,8 +1626,8 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+
+ sas_phy->oob_mode = SATA_OOB_MODE;
+ attached_sas_addr[0] = 0x50;
+- attached_sas_addr[6] = shost->host_no;
+- attached_sas_addr[7] = phy_no;
++ attached_sas_addr[HOST_NO_OFF] = shost->host_no;
++ attached_sas_addr[PHY_NO_OFF] = phy_no;
+ memcpy(sas_phy->attached_sas_addr,
+ attached_sas_addr,
+ SAS_ADDR_SIZE);
+@@ -1594,7 +1643,7 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+ (struct sas_identify_frame *)frame_rcvd;
+
+ dev_info(dev, "phyup: phy%d link_rate=%d\n", phy_no, link_rate);
+- for (i = 0; i < 6; i++) {
++ for (i = 0; i < IDENTIFY_REG_READ; i++) {
+ u32 idaf = hisi_sas_phy_read32(hisi_hba, phy_no,
+ RX_IDAF_DWORD0 + (i * 4));
+ frame_rcvd[i] = __swab32(idaf);
+@@ -1864,7 +1913,7 @@ static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
+
+ dev_warn(dev, "phy%d stp link timeout (0x%x)\n",
+ phy_no, reg_value);
+- if (reg_value & BIT(4))
++ if (reg_value & BIT(LINK_RESET_TIMEOUT_OFF))
+ hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET);
+ }
+
+@@ -2581,7 +2630,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
+ struct pci_dev *pdev = hisi_hba->pci_dev;
+ int rc, i;
+
+- rc = devm_request_irq(dev, pci_irq_vector(pdev, 1),
++ rc = devm_request_irq(dev, pci_irq_vector(pdev, IRQ_PHY_UP_DOWN_INDEX),
+ int_phy_up_down_bcast_v3_hw, 0,
+ DRV_NAME " phy", hisi_hba);
+ if (rc) {
+@@ -2589,7 +2638,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
+ return -ENOENT;
+ }
+
+- rc = devm_request_irq(dev, pci_irq_vector(pdev, 2),
++ rc = devm_request_irq(dev, pci_irq_vector(pdev, IRQ_CHL_INDEX),
+ int_chnl_int_v3_hw, 0,
+ DRV_NAME " channel", hisi_hba);
+ if (rc) {
+@@ -2597,7 +2646,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
+ return -ENOENT;
+ }
+
+- rc = devm_request_irq(dev, pci_irq_vector(pdev, 11),
++ rc = devm_request_irq(dev, pci_irq_vector(pdev, IRQ_AXI_INDEX),
+ fatal_axi_int_v3_hw, 0,
+ DRV_NAME " fatal", hisi_hba);
+ if (rc) {
+@@ -2610,7 +2659,8 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
+
+ for (i = 0; i < hisi_hba->cq_nvecs; i++) {
+ struct hisi_sas_cq *cq = &hisi_hba->cq[i];
+- int nr = hisi_sas_intr_conv ? 16 : 16 + i;
++ int nr = hisi_sas_intr_conv ? BASE_VECTORS_V3_HW :
++ BASE_VECTORS_V3_HW + i;
+ unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED :
+ IRQF_ONESHOT;
+
+@@ -2668,14 +2718,14 @@ static void interrupt_disable_v3_hw(struct hisi_hba *hisi_hba)
+ struct pci_dev *pdev = hisi_hba->pci_dev;
+ int i;
+
+- synchronize_irq(pci_irq_vector(pdev, 1));
+- synchronize_irq(pci_irq_vector(pdev, 2));
+- synchronize_irq(pci_irq_vector(pdev, 11));
++ synchronize_irq(pci_irq_vector(pdev, IRQ_PHY_UP_DOWN_INDEX));
++ synchronize_irq(pci_irq_vector(pdev, IRQ_CHL_INDEX));
++ synchronize_irq(pci_irq_vector(pdev, IRQ_AXI_INDEX));
+ for (i = 0; i < hisi_hba->queue_count; i++)
+ hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0x1);
+
+ for (i = 0; i < hisi_hba->cq_nvecs; i++)
+- synchronize_irq(pci_irq_vector(pdev, i + 16));
++ synchronize_irq(pci_irq_vector(pdev, i + BASE_VECTORS_V3_HW));
+
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xffffffff);
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xffffffff);
+@@ -2707,7 +2757,7 @@ static int disable_host_v3_hw(struct hisi_hba *hisi_hba)
+
+ hisi_sas_stop_phys(hisi_hba);
+
+- mdelay(10);
++ mdelay(HISI_SAS_DELAY_FOR_PHY_DISABLE);
+
+ reg_val = hisi_sas_read32(hisi_hba, AXI_MASTER_CFG_BASE +
+ AM_CTRL_GLOBAL);
+@@ -2843,13 +2893,13 @@ static ssize_t intr_coal_ticks_v3_hw_store(struct device *dev,
+ u32 intr_coal_ticks;
+ int ret;
+
+- ret = kstrtou32(buf, 10, &intr_coal_ticks);
++ ret = kstrtou32(buf, DECIMALISM_FLAG, &intr_coal_ticks);
+ if (ret) {
+ dev_err(dev, "Input data of interrupt coalesce unmatch\n");
+ return -EINVAL;
+ }
+
+- if (intr_coal_ticks >= BIT(24)) {
++ if (intr_coal_ticks >= BIT(TICKS_BIT_INDEX)) {
+ dev_err(dev, "intr_coal_ticks must be less than 2^24!\n");
+ return -EINVAL;
+ }
+@@ -2882,13 +2932,13 @@ static ssize_t intr_coal_count_v3_hw_store(struct device *dev,
+ u32 intr_coal_count;
+ int ret;
+
+- ret = kstrtou32(buf, 10, &intr_coal_count);
++ ret = kstrtou32(buf, DECIMALISM_FLAG, &intr_coal_count);
+ if (ret) {
+ dev_err(dev, "Input data of interrupt coalesce unmatch\n");
+ return -EINVAL;
+ }
+
+- if (intr_coal_count >= BIT(8)) {
++ if (intr_coal_count >= BIT(COUNT_BIT_INDEX)) {
+ dev_err(dev, "intr_coal_count must be less than 2^8!\n");
+ return -EINVAL;
+ }
+@@ -3020,7 +3070,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_port_reg_lu[] = {
+
+ static const struct hisi_sas_debugfs_reg debugfs_port_reg = {
+ .lu = debugfs_port_reg_lu,
+- .count = 0x100,
++ .count = PORT_REG_LENGTH,
+ .base_off = PORT_BASE,
+ };
+
+@@ -3094,7 +3144,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_global_reg_lu[] = {
+
+ static const struct hisi_sas_debugfs_reg debugfs_global_reg = {
+ .lu = debugfs_global_reg_lu,
+- .count = 0x800,
++ .count = GLOBAL_REG_LENGTH,
+ };
+
+ static const struct hisi_sas_debugfs_reg_lu debugfs_axi_reg_lu[] = {
+@@ -3107,7 +3157,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_axi_reg_lu[] = {
+
+ static const struct hisi_sas_debugfs_reg debugfs_axi_reg = {
+ .lu = debugfs_axi_reg_lu,
+- .count = 0x61,
++ .count = AXI_REG_LENGTH,
+ .base_off = AXI_MASTER_CFG_BASE,
+ };
+
+@@ -3124,7 +3174,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_ras_reg_lu[] = {
+
+ static const struct hisi_sas_debugfs_reg debugfs_ras_reg = {
+ .lu = debugfs_ras_reg_lu,
+- .count = 0x10,
++ .count = RAS_REG_LENGTH,
+ .base_off = RAS_BASE,
+ };
+
+@@ -3133,7 +3183,7 @@ static void debugfs_snapshot_prepare_v3_hw(struct hisi_hba *hisi_hba)
+ struct Scsi_Host *shost = hisi_hba->shost;
+
+ scsi_block_requests(shost);
+- wait_cmds_complete_timeout_v3_hw(hisi_hba, 100, 5000);
++ wait_cmds_complete_timeout_v3_hw(hisi_hba, WAIT_RETRY, WAIT_TMROUT);
+
+ set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
+ hisi_sas_sync_cqs(hisi_hba);
+@@ -3174,7 +3224,7 @@ static void read_iost_itct_cache_v3_hw(struct hisi_hba *hisi_hba,
+ return;
+ }
+
+- memset(buf, 0, cache_dw_size * 4);
++ memset(buf, 0, cache_dw_size * BYTE_TO_DW);
+ buf[0] = val;
+
+ for (i = 1; i < cache_dw_size; i++)
+@@ -3221,7 +3271,7 @@ static void hisi_sas_bist_test_restore_v3_hw(struct hisi_hba *hisi_hba)
+ reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, PROG_PHY_LINK_RATE);
+ /* init OOB link rate as 1.5 Gbits */
+ reg_val &= ~CFG_PROG_OOB_PHY_LINK_RATE_MSK;
+- reg_val |= (0x8 << CFG_PROG_OOB_PHY_LINK_RATE_OFF);
++ reg_val |= (SAS_LINK_RATE_1_5_GBPS << CFG_PROG_OOB_PHY_LINK_RATE_OFF);
+ hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, reg_val);
+
+ /* enable PHY */
+@@ -3230,6 +3280,9 @@ static void hisi_sas_bist_test_restore_v3_hw(struct hisi_hba *hisi_hba)
+
+ #define SAS_PHY_BIST_CODE_INIT 0x1
+ #define SAS_PHY_BIST_CODE1_INIT 0X80
++#define SAS_PHY_BIST_INIT_DELAY 100
++#define SAS_PHY_BIST_LOOP_TEST_0 1
++#define SAS_PHY_BIST_LOOP_TEST_1 2
+ static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable)
+ {
+ u32 reg_val, mode_tmp;
+@@ -3248,7 +3301,8 @@ static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable)
+ ffe[FFE_SATA_1_5_GBPS], ffe[FFE_SATA_3_0_GBPS],
+ ffe[FFE_SATA_6_0_GBPS], fix_code[FIXED_CODE],
+ fix_code[FIXED_CODE_1]);
+- mode_tmp = path_mode ? 2 : 1;
++ mode_tmp = path_mode ? SAS_PHY_BIST_LOOP_TEST_1 :
++ SAS_PHY_BIST_LOOP_TEST_0;
+ if (enable) {
+ /* some preparations before bist test */
+ hisi_sas_bist_test_prep_v3_hw(hisi_hba);
+@@ -3291,13 +3345,13 @@ static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable)
+ SAS_PHY_BIST_CODE1_INIT);
+ }
+
+- mdelay(100);
++ mdelay(SAS_PHY_BIST_INIT_DELAY);
+ reg_val |= (CFG_RX_BIST_EN_MSK | CFG_TX_BIST_EN_MSK);
+ hisi_sas_phy_write32(hisi_hba, phy_no, SAS_PHY_BIST_CTRL,
+ reg_val);
+
+ /* clear error bit */
+- mdelay(100);
++ mdelay(SAS_PHY_BIST_INIT_DELAY);
+ hisi_sas_phy_read32(hisi_hba, phy_no, SAS_BIST_ERR_CNT);
+ } else {
+ /* disable bist test and recover it */
+@@ -3473,7 +3527,7 @@ static void debugfs_snapshot_port_reg_v3_hw(struct hisi_hba *hisi_hba)
+ for (phy_cnt = 0; phy_cnt < hisi_hba->n_phy; phy_cnt++) {
+ databuf = hisi_hba->debugfs_port_reg[dump_index][phy_cnt].data;
+ for (i = 0; i < port->count; i++, databuf++) {
+- offset = port->base_off + 4 * i;
++ offset = port->base_off + HISI_SAS_REG_MEM_SIZE * i;
+ *databuf = hisi_sas_phy_read32(hisi_hba, phy_cnt,
+ offset);
+ }
+@@ -3487,7 +3541,8 @@ static void debugfs_snapshot_global_reg_v3_hw(struct hisi_hba *hisi_hba)
+ int i;
+
+ for (i = 0; i < debugfs_global_reg.count; i++, databuf++)
+- *databuf = hisi_sas_read32(hisi_hba, 4 * i);
++ *databuf = hisi_sas_read32(hisi_hba,
++ HISI_SAS_REG_MEM_SIZE * i);
+ }
+
+ static void debugfs_snapshot_axi_reg_v3_hw(struct hisi_hba *hisi_hba)
+@@ -3498,7 +3553,9 @@ static void debugfs_snapshot_axi_reg_v3_hw(struct hisi_hba *hisi_hba)
+ int i;
+
+ for (i = 0; i < axi->count; i++, databuf++)
+- *databuf = hisi_sas_read32(hisi_hba, 4 * i + axi->base_off);
++ *databuf = hisi_sas_read32(hisi_hba,
++ HISI_SAS_REG_MEM_SIZE * i +
++ axi->base_off);
+ }
+
+ static void debugfs_snapshot_ras_reg_v3_hw(struct hisi_hba *hisi_hba)
+@@ -3509,7 +3566,9 @@ static void debugfs_snapshot_ras_reg_v3_hw(struct hisi_hba *hisi_hba)
+ int i;
+
+ for (i = 0; i < ras->count; i++, databuf++)
+- *databuf = hisi_sas_read32(hisi_hba, 4 * i + ras->base_off);
++ *databuf = hisi_sas_read32(hisi_hba,
++ HISI_SAS_REG_MEM_SIZE * i +
++ ras->base_off);
+ }
+
+ static void debugfs_snapshot_itct_reg_v3_hw(struct hisi_hba *hisi_hba)
+@@ -3572,7 +3631,7 @@ static void debugfs_print_reg_v3_hw(u32 *regs_val, struct seq_file *s,
+ int i;
+
+ for (i = 0; i < reg->count; i++) {
+- int off = i * 4;
++ int off = i * HISI_SAS_REG_MEM_SIZE;
+ const char *name;
+
+ name = debugfs_to_reg_name_v3_hw(off, reg->base_off,
+@@ -3650,9 +3709,9 @@ static void debugfs_show_row_64_v3_hw(struct seq_file *s, int index,
+
+ /* completion header size not fixed per HW version */
+ seq_printf(s, "index %04d:\n\t", index);
+- for (i = 1; i <= sz / 8; i++, ptr++) {
++ for (i = 1; i <= sz / BYTE_TO_DDW; i++, ptr++) {
+ seq_printf(s, " 0x%016llx", le64_to_cpu(*ptr));
+- if (!(i % 2))
++ if (!(i % TWO_PARA_PER_LINE))
+ seq_puts(s, "\n\t");
+ }
+
+@@ -3666,9 +3725,9 @@ static void debugfs_show_row_32_v3_hw(struct seq_file *s, int index,
+
+ /* completion header size not fixed per HW version */
+ seq_printf(s, "index %04d:\n\t", index);
+- for (i = 1; i <= sz / 4; i++, ptr++) {
++ for (i = 1; i <= sz / BYTE_TO_DW; i++, ptr++) {
+ seq_printf(s, " 0x%08x", le32_to_cpu(*ptr));
+- if (!(i % 4))
++ if (!(i % FOUR_PARA_PER_LINE))
+ seq_puts(s, "\n\t");
+ }
+ seq_puts(s, "\n");
+@@ -3753,7 +3812,7 @@ static int debugfs_iost_cache_v3_hw_show(struct seq_file *s, void *p)
+ struct hisi_sas_debugfs_iost_cache *debugfs_iost_cache = s->private;
+ struct hisi_sas_iost_itct_cache *iost_cache =
+ debugfs_iost_cache->cache;
+- u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4;
++ u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * BYTE_TO_DW;
+ int i, tab_idx;
+ __le64 *iost;
+
+@@ -3801,7 +3860,7 @@ static int debugfs_itct_cache_v3_hw_show(struct seq_file *s, void *p)
+ struct hisi_sas_debugfs_itct_cache *debugfs_itct_cache = s->private;
+ struct hisi_sas_iost_itct_cache *itct_cache =
+ debugfs_itct_cache->cache;
+- u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4;
++ u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * BYTE_TO_DW;
+ int i, tab_idx;
+ __le64 *itct;
+
+@@ -3830,12 +3889,12 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index)
+ u64 *debugfs_timestamp;
+ struct dentry *dump_dentry;
+ struct dentry *dentry;
+- char name[256];
++ char name[NAME_BUF_SIZE];
+ int p;
+ int c;
+ int d;
+
+- snprintf(name, 256, "%d", index);
++ snprintf(name, NAME_BUF_SIZE, "%d", index);
+
+ dump_dentry = debugfs_create_dir(name, hisi_hba->debugfs_dump_dentry);
+
+@@ -3851,7 +3910,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index)
+ /* Create port dir and files */
+ dentry = debugfs_create_dir("port", dump_dentry);
+ for (p = 0; p < hisi_hba->n_phy; p++) {
+- snprintf(name, 256, "%d", p);
++ snprintf(name, NAME_BUF_SIZE, "%d", p);
+
+ debugfs_create_file(name, 0400, dentry,
+ &hisi_hba->debugfs_port_reg[index][p],
+@@ -3861,7 +3920,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index)
+ /* Create CQ dir and files */
+ dentry = debugfs_create_dir("cq", dump_dentry);
+ for (c = 0; c < hisi_hba->queue_count; c++) {
+- snprintf(name, 256, "%d", c);
++ snprintf(name, NAME_BUF_SIZE, "%d", c);
+
+ debugfs_create_file(name, 0400, dentry,
+ &hisi_hba->debugfs_cq[index][c],
+@@ -3871,7 +3930,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index)
+ /* Create DQ dir and files */
+ dentry = debugfs_create_dir("dq", dump_dentry);
+ for (d = 0; d < hisi_hba->queue_count; d++) {
+- snprintf(name, 256, "%d", d);
++ snprintf(name, NAME_BUF_SIZE, "%d", d);
+
+ debugfs_create_file(name, 0400, dentry,
+ &hisi_hba->debugfs_dq[index][d],
+@@ -3908,9 +3967,9 @@ static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file,
+ size_t count, loff_t *ppos)
+ {
+ struct hisi_hba *hisi_hba = file->f_inode->i_private;
+- char buf[8];
++ char buf[DUMP_BUF_SIZE];
+
+- if (count > 8)
++ if (count > DUMP_BUF_SIZE)
+ return -EFAULT;
+
+ if (copy_from_user(buf, user_buf, count))
+@@ -3974,7 +4033,7 @@ static ssize_t debugfs_bist_linkrate_v3_hw_write(struct file *filp,
+ {
+ struct seq_file *m = filp->private_data;
+ struct hisi_hba *hisi_hba = m->private;
+- char kbuf[16] = {}, *pkbuf;
++ char kbuf[BIST_BUF_SIZE] = {}, *pkbuf;
+ bool found = false;
+ int i;
+
+@@ -3991,7 +4050,7 @@ static ssize_t debugfs_bist_linkrate_v3_hw_write(struct file *filp,
+
+ for (i = 0; i < ARRAY_SIZE(debugfs_loop_linkrate_v3_hw); i++) {
+ if (!strncmp(debugfs_loop_linkrate_v3_hw[i].name,
+- pkbuf, 16)) {
++ pkbuf, BIST_BUF_SIZE)) {
+ hisi_hba->debugfs_bist_linkrate =
+ debugfs_loop_linkrate_v3_hw[i].value;
+ found = true;
+@@ -4049,7 +4108,7 @@ static ssize_t debugfs_bist_code_mode_v3_hw_write(struct file *filp,
+ {
+ struct seq_file *m = filp->private_data;
+ struct hisi_hba *hisi_hba = m->private;
+- char kbuf[16] = {}, *pkbuf;
++ char kbuf[BIST_BUF_SIZE] = {}, *pkbuf;
+ bool found = false;
+ int i;
+
+@@ -4066,7 +4125,7 @@ static ssize_t debugfs_bist_code_mode_v3_hw_write(struct file *filp,
+
+ for (i = 0; i < ARRAY_SIZE(debugfs_loop_code_mode_v3_hw); i++) {
+ if (!strncmp(debugfs_loop_code_mode_v3_hw[i].name,
+- pkbuf, 16)) {
++ pkbuf, BIST_BUF_SIZE)) {
+ hisi_hba->debugfs_bist_code_mode =
+ debugfs_loop_code_mode_v3_hw[i].value;
+ found = true;
+@@ -4181,7 +4240,7 @@ static ssize_t debugfs_bist_mode_v3_hw_write(struct file *filp,
+ {
+ struct seq_file *m = filp->private_data;
+ struct hisi_hba *hisi_hba = m->private;
+- char kbuf[16] = {}, *pkbuf;
++ char kbuf[BIST_BUF_SIZE] = {}, *pkbuf;
+ bool found = false;
+ int i;
+
+@@ -4197,7 +4256,8 @@ static ssize_t debugfs_bist_mode_v3_hw_write(struct file *filp,
+ pkbuf = strstrip(kbuf);
+
+ for (i = 0; i < ARRAY_SIZE(debugfs_loop_modes_v3_hw); i++) {
+- if (!strncmp(debugfs_loop_modes_v3_hw[i].name, pkbuf, 16)) {
++ if (!strncmp(debugfs_loop_modes_v3_hw[i].name, pkbuf,
++ BIST_BUF_SIZE)) {
+ hisi_hba->debugfs_bist_mode =
+ debugfs_loop_modes_v3_hw[i].value;
+ found = true;
+@@ -4476,8 +4536,9 @@ static int debugfs_fifo_data_v3_hw_show(struct seq_file *s, void *p)
+
+ debugfs_read_fifo_data_v3_hw(phy);
+
+- debugfs_show_row_32_v3_hw(s, 0, HISI_SAS_FIFO_DATA_DW_SIZE * 4,
+- (__le32 *)phy->fifo.rd_data);
++ debugfs_show_row_32_v3_hw(s, 0,
++ HISI_SAS_FIFO_DATA_DW_SIZE * HISI_SAS_REG_MEM_SIZE,
++ phy->fifo.rd_data);
+
+ return 0;
+ }
+@@ -4609,14 +4670,14 @@ static int debugfs_alloc_v3_hw(struct hisi_hba *hisi_hba, int dump_index)
+ struct hisi_sas_debugfs_regs *regs =
+ &hisi_hba->debugfs_regs[dump_index][r];
+
+- sz = debugfs_reg_array_v3_hw[r]->count * 4;
++ sz = debugfs_reg_array_v3_hw[r]->count * HISI_SAS_REG_MEM_SIZE;
+ regs->data = devm_kmalloc(dev, sz, GFP_KERNEL);
+ if (!regs->data)
+ goto fail;
+ regs->hisi_hba = hisi_hba;
+ }
+
+- sz = debugfs_port_reg.count * 4;
++ sz = debugfs_port_reg.count * HISI_SAS_REG_MEM_SIZE;
+ for (p = 0; p < hisi_hba->n_phy; p++) {
+ struct hisi_sas_debugfs_port *port =
+ &hisi_hba->debugfs_port_reg[dump_index][p];
+@@ -4726,11 +4787,11 @@ static void debugfs_phy_down_cnt_init_v3_hw(struct hisi_hba *hisi_hba)
+ {
+ struct dentry *dir = debugfs_create_dir("phy_down_cnt",
+ hisi_hba->debugfs_dir);
+- char name[16];
++ char name[NAME_BUF_SIZE];
+ int phy_no;
+
+ for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) {
+- snprintf(name, 16, "%d", phy_no);
++ snprintf(name, NAME_BUF_SIZE, "%d", phy_no);
+ debugfs_create_file(name, 0600, dir,
+ &hisi_hba->phy[phy_no],
+ &debugfs_phy_down_cnt_v3_hw_fops);
+@@ -4899,7 +4960,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ shost->max_id = HISI_SAS_MAX_DEVICES;
+ shost->max_lun = ~0;
+ shost->max_channel = 1;
+- shost->max_cmd_len = 16;
++ shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN;
+ shost->can_queue = HISI_SAS_UNRESERVED_IPTT;
+ shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT;
+ if (hisi_hba->iopoll_q_cnt)
+@@ -4981,12 +5042,13 @@ hisi_sas_v3_destroy_irqs(struct pci_dev *pdev, struct hisi_hba *hisi_hba)
+ {
+ int i;
+
+- devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 1), hisi_hba);
+- devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 2), hisi_hba);
+- devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 11), hisi_hba);
++ devm_free_irq(&pdev->dev, pci_irq_vector(pdev, IRQ_PHY_UP_DOWN_INDEX), hisi_hba);
++ devm_free_irq(&pdev->dev, pci_irq_vector(pdev, IRQ_CHL_INDEX), hisi_hba);
++ devm_free_irq(&pdev->dev, pci_irq_vector(pdev, IRQ_AXI_INDEX), hisi_hba);
+ for (i = 0; i < hisi_hba->cq_nvecs; i++) {
+ struct hisi_sas_cq *cq = &hisi_hba->cq[i];
+- int nr = hisi_sas_intr_conv ? 16 : 16 + i;
++ int nr = hisi_sas_intr_conv ? BASE_VECTORS_V3_HW :
++ BASE_VECTORS_V3_HW + i;
+
+ devm_free_irq(&pdev->dev, pci_irq_vector(pdev, nr), cq);
+ }
+--
+2.51.0
+
--- /dev/null
+From 1d37a98c22d1a1c00652376f5420f8dcc5b0eaa9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 7 Mar 2026 11:51:28 +0800
+Subject: scsi: ufs: core: Fix SError in ufshcd_rtc_work() during UFS suspend
+
+From: Wang Shuaiwei <wangshuaiwei1@xiaomi.com>
+
+[ Upstream commit b0bd84c39289ef6a6c3827dd52c875659291970a ]
+
+In __ufshcd_wl_suspend(), cancel_delayed_work_sync() is called to cancel
+the UFS RTC work, but it is placed after ufshcd_vops_suspend(hba, pm_op,
+POST_CHANGE). This creates a race condition where ufshcd_rtc_work() can
+still be running while ufshcd_vops_suspend() is executing. When
+UFSHCD_CAP_CLK_GATING is not supported, the condition
+!hba->clk_gating.active_reqs is always true, causing ufshcd_update_rtc()
+to be executed. Since ufshcd_vops_suspend() typically performs clock
+gating operations, executing ufshcd_update_rtc() at that moment triggers
+an SError. The kernel panic trace is as follows:
+
+Kernel panic - not syncing: Asynchronous SError Interrupt
+Call trace:
+ dump_backtrace+0xec/0x128
+ show_stack+0x18/0x28
+ dump_stack_lvl+0x40/0xa0
+ dump_stack+0x18/0x24
+ panic+0x148/0x374
+ nmi_panic+0x3c/0x8c
+ arm64_serror_panic+0x64/0x8c
+ do_serror+0xc4/0xc8
+ el1h_64_error_handler+0x34/0x4c
+ el1h_64_error+0x68/0x6c
+ el1_interrupt+0x20/0x58
+ el1h_64_irq_handler+0x18/0x24
+ el1h_64_irq+0x68/0x6c
+ ktime_get+0xc4/0x12c
+ ufshcd_mcq_sq_stop+0x4c/0xec
+ ufshcd_mcq_sq_cleanup+0x64/0x1dc
+ ufshcd_clear_cmd+0x38/0x134
+ ufshcd_issue_dev_cmd+0x298/0x4d0
+ ufshcd_exec_dev_cmd+0x1a4/0x1c4
+ ufshcd_query_attr+0xbc/0x19c
+ ufshcd_rtc_work+0x10c/0x1c8
+ process_scheduled_works+0x1c4/0x45c
+ worker_thread+0x32c/0x3e8
+ kthread+0x120/0x1d8
+ ret_from_fork+0x10/0x20
+
+Fix this by moving cancel_delayed_work_sync() before the call to
+ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE), ensuring the UFS RTC work is
+fully completed or cancelled at that point.
+
+Cc: Bean Huo <beanhuo@iokpp.de>
+Fixes: 6bf999e0eb41 ("scsi: ufs: core: Add UFS RTC support")
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Wang Shuaiwei <wangshuaiwei1@xiaomi.com>
+Link: https://patch.msgid.link/20260307035128.3419687-1-wangshuaiwei1@xiaomi.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/core/ufshcd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
+index ea6e7c18e35cd..22d3cb0ddbcaa 100644
+--- a/drivers/ufs/core/ufshcd.c
++++ b/drivers/ufs/core/ufshcd.c
+@@ -9813,6 +9813,7 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
+ }
+
+ flush_work(&hba->eeh_work);
++ cancel_delayed_work_sync(&hba->ufs_rtc_update_work);
+
+ ret = ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE);
+ if (ret)
+@@ -9867,7 +9868,6 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
+ if (ret)
+ goto set_link_active;
+
+- cancel_delayed_work_sync(&hba->ufs_rtc_update_work);
+ goto out;
+
+ set_link_active:
+--
+2.51.0
+
usb-mdc800-handle-signal-and-read-racing.patch
usb-image-mdc800-kill-download-urb-on-timeout.patch
rust-kbuild-allow-unused_features.patch
+time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch
+i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch
+scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch
+scsi-hisi_sas-add-time-interval-between-two-h2d-fis-.patch
+scsi-hisi_sas-use-macro-instead-of-magic-number.patch
+scsi-hisi_sas-fix-null-pointer-exception-during-user.patch
+kbuild-disable-cc_has_asm_goto_output-on-clang-17.patch
+fix-cc_has_asm_goto_output-on-non-x86-architectures.patch
--- /dev/null
+From c9eb9faac6ea2dd1e0e60b23e2a46f552dafcd10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Mar 2026 21:24:03 -0500
+Subject: time/jiffies: Mark jiffies_64_to_clock_t() notrace
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 755a648e78f12574482d4698d877375793867fa1 ]
+
+The trace_clock_jiffies() function that handles the "uptime" clock for
+tracing calls jiffies_64_to_clock_t(). This causes the function tracer to
+constantly recurse when the tracing clock is set to "uptime". Mark it
+notrace to prevent unnecessary recursion when using the "uptime" clock.
+
+Fixes: 58d4e21e50ff3 ("tracing: Fix wraparound problems in "uptime" trace clock")
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Link: https://patch.msgid.link/20260306212403.72270bb2@robin
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/time.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/time/time.c b/kernel/time/time.c
+index 1ad88e97b4ebc..da7e8a02a0964 100644
+--- a/kernel/time/time.c
++++ b/kernel/time/time.c
+@@ -702,7 +702,7 @@ EXPORT_SYMBOL(clock_t_to_jiffies);
+ *
+ * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC)
+ */
+-u64 jiffies_64_to_clock_t(u64 x)
++notrace u64 jiffies_64_to_clock_t(u64 x)
+ {
+ #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
+ # if HZ < USER_HZ
+--
+2.51.0
+
--- /dev/null
+From be346e0a68c71fc84da0b592b91f3ed1f82d9d59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 Feb 2026 02:33:45 +1030
+Subject: ALSA: usb-audio: Improve Focusrite sample rate filtering
+
+From: Geoffrey D. Bennett <g@b4.vu>
+
+[ Upstream commit 24d2d3c5f94007a5a0554065ab7349bb69e28bcb ]
+
+Replace the bLength == 10 max_rate check in
+focusrite_valid_sample_rate() with filtering that also examines the
+bmControls VAL_ALT_SETTINGS bit.
+
+When VAL_ALT_SETTINGS is readable, the device uses strict
+per-altsetting rate filtering (only the highest rate pair for that
+altsetting is valid). When it is not readable, all rates up to
+max_rate are valid.
+
+For devices without the bLength == 10 Format Type descriptor extension
+but with VAL_ALT_SETTINGS readable and multiple altsettings (only seen
+in Scarlett 18i8 3rd Gen playback), fall back to the Focusrite
+convention: alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz.
+
+This produces correct rate tables for all tested Focusrite devices
+(all Scarlett 2nd, 3rd, and 4th Gen, Clarett+, and Vocaster) using
+only USB descriptors, allowing QUIRK_FLAG_VALIDATE_RATES to be removed
+for Focusrite in the next commit.
+
+Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/7e18c1f393a6ecb6fc75dd867a2c4dbe135e3e22.1771594828.git.g@b4.vu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/format.c | 70 ++++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 65 insertions(+), 5 deletions(-)
+
+diff --git a/sound/usb/format.c b/sound/usb/format.c
+index ec95a063beb10..53b5dc5453b78 100644
+--- a/sound/usb/format.c
++++ b/sound/usb/format.c
+@@ -302,17 +302,48 @@ static bool s1810c_valid_sample_rate(struct audioformat *fp,
+ }
+
+ /*
+- * Many Focusrite devices supports a limited set of sampling rates per
+- * altsetting. Maximum rate is exposed in the last 4 bytes of Format Type
+- * descriptor which has a non-standard bLength = 10.
++ * Focusrite devices use rate pairs: 44100/48000, 88200/96000, and
++ * 176400/192000. Return true if rate is in the pair for max_rate.
++ */
++static bool focusrite_rate_pair(unsigned int rate,
++ unsigned int max_rate)
++{
++ switch (max_rate) {
++ case 48000: return rate == 44100 || rate == 48000;
++ case 96000: return rate == 88200 || rate == 96000;
++ case 192000: return rate == 176400 || rate == 192000;
++ default: return true;
++ }
++}
++
++/*
++ * Focusrite devices report all supported rates in a single clock
++ * source but only a subset is valid per altsetting.
++ *
++ * Detection uses two descriptor features:
++ *
++ * 1. Format Type descriptor bLength == 10: non-standard extension
++ * with max sample rate in bytes 6..9.
++ *
++ * 2. bmControls VAL_ALT_SETTINGS readable bit: when set, the device
++ * only supports the highest rate pair for that altsetting, and when
++ * clear, all rates up to max_rate are valid.
++ *
++ * For devices without the bLength == 10 extension but with
++ * VAL_ALT_SETTINGS readable and multiple altsettings (only seen in
++ * Scarlett 18i8 3rd Gen playback), fall back to the Focusrite
++ * convention: alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz.
+ */
+ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
+ struct audioformat *fp,
+ unsigned int rate)
+ {
++ struct usb_interface *iface;
+ struct usb_host_interface *alts;
++ struct uac2_as_header_descriptor *as;
+ unsigned char *fmt;
+ unsigned int max_rate;
++ bool val_alt;
+
+ alts = snd_usb_get_host_interface(chip, fp->iface, fp->altsetting);
+ if (!alts)
+@@ -323,9 +354,21 @@ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
+ if (!fmt)
+ return true;
+
++ as = snd_usb_find_csint_desc(alts->extra, alts->extralen,
++ NULL, UAC_AS_GENERAL);
++ if (!as)
++ return true;
++
++ val_alt = uac_v2v3_control_is_readable(as->bmControls,
++ UAC2_AS_VAL_ALT_SETTINGS);
++
+ if (fmt[0] == 10) { /* bLength */
+ max_rate = combine_quad(&fmt[6]);
+
++ if (val_alt)
++ return focusrite_rate_pair(rate, max_rate);
++
++ /* No val_alt: rates fall through from higher */
+ switch (max_rate) {
+ case 192000:
+ if (rate == 176400 || rate == 192000)
+@@ -341,12 +384,29 @@ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
+ usb_audio_info(chip,
+ "%u:%d : unexpected max rate: %u\n",
+ fp->iface, fp->altsetting, max_rate);
+-
+ return true;
+ }
+ }
+
+- return true;
++ if (!val_alt)
++ return true;
++
++ /* Multi-altsetting device with val_alt but no max_rate
++ * in the format descriptor. Use Focusrite convention:
++ * alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz.
++ */
++ iface = usb_ifnum_to_if(chip->dev, fp->iface);
++ if (!iface || iface->num_altsetting <= 2)
++ return true;
++
++ switch (fp->altsetting) {
++ case 1: max_rate = 48000; break;
++ case 2: max_rate = 96000; break;
++ case 3: max_rate = 192000; break;
++ default: return true;
++ }
++
++ return focusrite_rate_pair(rate, max_rate);
+ }
+
+ /*
+--
+2.51.0
+
--- /dev/null
+From ce114ab0f21499a962658c9de10b46f231236276 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 14:00:48 +0800
+Subject: i3c: dw-i3c-master: Set SIR_REJECT in DAT on device attach and
+ reattach
+
+From: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
+
+[ Upstream commit f311a05784634febd299f03476b80f3f18489767 ]
+
+The DesignWare I3C master controller ACKs IBIs as soon as a valid
+Device Address Table (DAT) entry is present. This can create a race
+between device attachment (after DAA) and the point where the client
+driver enables IBIs via i3c_device_enable_ibi().
+
+Set DEV_ADDR_TABLE_SIR_REJECT in the DAT entry during
+attach_i3c_dev() and reattach_i3c_dev() so that IBIs are rejected
+by default. The bit is managed thereafter by the existing
+dw_i3c_master_set_sir_enabled() function, which clears it in
+enable_ibi() after ENEC is issued, and restores it in disable_ibi()
+after DISEC.
+
+Fixes: 1dd728f5d4d4 ("i3c: master: Add driver for Synopsys DesignWare IP")
+Signed-off-by: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/53f5b8cbdd8af789ec38b95b02873f32f9182dd6.1770962368.git.adrianhoyin.ng@altera.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i3c/master/dw-i3c-master.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
+index c06595cb74010..41ddac1d49d5e 100644
+--- a/drivers/i3c/master/dw-i3c-master.c
++++ b/drivers/i3c/master/dw-i3c-master.c
+@@ -1005,7 +1005,7 @@ static int dw_i3c_master_reattach_i3c_dev(struct i3c_dev_desc *dev,
+ master->free_pos &= ~BIT(pos);
+ }
+
+- writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr),
++ writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr) | DEV_ADDR_TABLE_SIR_REJECT,
+ master->regs +
+ DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
+
+@@ -1034,7 +1034,7 @@ static int dw_i3c_master_attach_i3c_dev(struct i3c_dev_desc *dev)
+ master->free_pos &= ~BIT(pos);
+ i3c_dev_set_master_data(dev, data);
+
+- writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr),
++ writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr) | DEV_ADDR_TABLE_SIR_REJECT,
+ master->regs +
+ DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
+
+--
+2.51.0
+
--- /dev/null
+From f55428b73ee65e49b9eff30d6c2bbdc7b79ab6c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Mar 2026 15:40:45 +0100
+Subject: powerpc, perf: Check that current->mm is alive before getting user
+ callchain
+
+From: Viktor Malik <vmalik@redhat.com>
+
+[ Upstream commit e9bbfb4bfa86c6b5515b868d6982ac60505d7e39 ]
+
+It may happen that mm is already released, which leads to kernel panic.
+This adds the NULL check for current->mm, similarly to
+commit 20afc60f892d ("x86, perf: Check that current->mm is alive before getting user callchain").
+
+I was getting this panic when running a profiling BPF program
+(profile.py from bcc-tools):
+
+ [26215.051935] Kernel attempted to read user page (588) - exploit attempt? (uid: 0)
+ [26215.051950] BUG: Kernel NULL pointer dereference on read at 0x00000588
+ [26215.051952] Faulting instruction address: 0xc00000000020fac0
+ [26215.051957] Oops: Kernel access of bad area, sig: 11 [#1]
+ [...]
+ [26215.052049] Call Trace:
+ [26215.052050] [c000000061da6d30] [c00000000020fc10] perf_callchain_user_64+0x2d0/0x490 (unreliable)
+ [26215.052054] [c000000061da6dc0] [c00000000020f92c] perf_callchain_user+0x1c/0x30
+ [26215.052057] [c000000061da6de0] [c0000000005ab2a0] get_perf_callchain+0x100/0x360
+ [26215.052063] [c000000061da6e70] [c000000000573bc8] bpf_get_stackid+0x88/0xf0
+ [26215.052067] [c000000061da6ea0] [c008000000042258] bpf_prog_16d4ab9ab662f669_do_perf_event+0xf8/0x274
+ [...]
+
+In addition, move storing the top-level stack entry to generic
+perf_callchain_user to make sure the top-evel entry is always captured,
+even if current->mm is NULL.
+
+Fixes: 20002ded4d93 ("perf_counter: powerpc: Add callchain support")
+Signed-off-by: Viktor Malik <vmalik@redhat.com>
+Tested-by: Qiao Zhao <qzhao@redhat.com>
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Reviewed-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
+[Maddy: fixed message to avoid checkpatch format style error]
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20260309144045.169427-1-vmalik@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/perf/callchain.c | 5 +++++
+ arch/powerpc/perf/callchain_32.c | 1 -
+ arch/powerpc/perf/callchain_64.c | 1 -
+ 3 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
+index 26aa26482c9ac..992cc5c982144 100644
+--- a/arch/powerpc/perf/callchain.c
++++ b/arch/powerpc/perf/callchain.c
+@@ -103,6 +103,11 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re
+ void
+ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
+ {
++ perf_callchain_store(entry, perf_arch_instruction_pointer(regs));
++
++ if (!current->mm)
++ return;
++
+ if (!is_32bit_task())
+ perf_callchain_user_64(entry, regs);
+ else
+diff --git a/arch/powerpc/perf/callchain_32.c b/arch/powerpc/perf/callchain_32.c
+index ddcc2d8aa64a5..0de21c5d272c2 100644
+--- a/arch/powerpc/perf/callchain_32.c
++++ b/arch/powerpc/perf/callchain_32.c
+@@ -142,7 +142,6 @@ void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
+ next_ip = perf_arch_instruction_pointer(regs);
+ lr = regs->link;
+ sp = regs->gpr[1];
+- perf_callchain_store(entry, next_ip);
+
+ while (entry->nr < entry->max_stack) {
+ fp = (unsigned int __user *) (unsigned long) sp;
+diff --git a/arch/powerpc/perf/callchain_64.c b/arch/powerpc/perf/callchain_64.c
+index 115d1c105e8a8..30fb61c5f0cb0 100644
+--- a/arch/powerpc/perf/callchain_64.c
++++ b/arch/powerpc/perf/callchain_64.c
+@@ -77,7 +77,6 @@ void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
+ next_ip = perf_arch_instruction_pointer(regs);
+ lr = regs->link;
+ sp = regs->gpr[1];
+- perf_callchain_store(entry, next_ip);
+
+ while (entry->nr < entry->max_stack) {
+ fp = (unsigned long __user *) sp;
+--
+2.51.0
+
--- /dev/null
+From 0fa858029bf19e72107c0ce74dbe84c0a53ec026 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Mar 2026 14:40:39 +0800
+Subject: scsi: hisi_sas: Fix NULL pointer exception during user_scan()
+
+From: Xingui Yang <yangxingui@huawei.com>
+
+[ Upstream commit 8ddc0c26916574395447ebf4cff684314f6873a9 ]
+
+user_scan() invokes updated sas_user_scan() for channel 0, and if
+successful, iteratively scans remaining channels (1 to shost->max_channel)
+via scsi_scan_host_selected() in commit 37c4e72b0651 ("scsi: Fix
+sas_user_scan() to handle wildcard and multi-channel scans"). However,
+hisi_sas supports only one channel, and the current value of max_channel is
+1. sas_user_scan() for channel 1 will trigger the following NULL pointer
+exception:
+
+[ 441.554662] Unable to handle kernel NULL pointer dereference at virtual address 00000000000008b0
+[ 441.554699] Mem abort info:
+[ 441.554710] ESR = 0x0000000096000004
+[ 441.554718] EC = 0x25: DABT (current EL), IL = 32 bits
+[ 441.554723] SET = 0, FnV = 0
+[ 441.554726] EA = 0, S1PTW = 0
+[ 441.554730] FSC = 0x04: level 0 translation fault
+[ 441.554735] Data abort info:
+[ 441.554737] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
+[ 441.554742] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
+[ 441.554747] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+[ 441.554752] user pgtable: 4k pages, 48-bit VAs, pgdp=00000828377a6000
+[ 441.554757] [00000000000008b0] pgd=0000000000000000, p4d=0000000000000000
+[ 441.554769] Internal error: Oops: 0000000096000004 [#1] SMP
+[ 441.629589] Modules linked in: arm_spe_pmu arm_smmuv3_pmu tpm_tis_spi hisi_uncore_sllc_pmu hisi_uncore_pa_pmu hisi_uncore_l3c_pmu hisi_uncore_hha_pmu hisi_uncore_ddrc_pmu hisi_uncore_cpa_pmu hns3_pmu hisi_ptt hisi_pcie_pmu tpm_tis_core spidev spi_hisi_sfc_v3xx hisi_uncore_pmu spi_dw_mmio fuse hclge hclge_common hisi_sec2 hisi_hpre hisi_zip hisi_qm hns3 hisi_sas_v3_hw sm3_ce sbsa_gwdt hnae3 hisi_sas_main uacce hisi_dma i2c_hisi dm_mirror dm_region_hash dm_log dm_mod
+[ 441.670819] CPU: 46 UID: 0 PID: 6994 Comm: bash Kdump: loaded Not tainted 7.0.0-rc2+ #84 PREEMPT
+[ 441.691327] pstate: 81400009 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
+[ 441.698277] pc : sas_find_dev_by_rphy+0x44/0x118
+[ 441.702896] lr : sas_find_dev_by_rphy+0x3c/0x118
+[ 441.707502] sp : ffff80009abbba40
+[ 441.710805] x29: ffff80009abbba40 x28: ffff082819a40008 x27: ffff082810c37c08
+[ 441.717930] x26: ffff082810c37c28 x25: ffff082819a40290 x24: ffff082810c37c00
+[ 441.725054] x23: 0000000000000000 x22: 0000000000000001 x21: ffff082819a40000
+[ 441.732179] x20: ffff082819a40290 x19: 0000000000000000 x18: 0000000000000020
+[ 441.739304] x17: 0000000000000000 x16: ffffb5dad6bda690 x15: 00000000ffffffff
+[ 441.746428] x14: ffff082814c3b26c x13: 00000000ffffffff x12: ffff082814c3b26a
+[ 441.753553] x11: 00000000000000c0 x10: 000000000000003a x9 : ffffb5dad5ea94f4
+[ 441.760678] x8 : 000000000000003a x7 : ffff80009abbbab0 x6 : 0000000000000030
+[ 441.767802] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
+[ 441.774926] x2 : ffff08280f35a300 x1 : ffffb5dad7127180 x0 : 0000000000000000
+[ 441.782053] Call trace:
+[ 441.784488] sas_find_dev_by_rphy+0x44/0x118 (P)
+[ 441.789095] sas_target_alloc+0x24/0xb0
+[ 441.792920] scsi_alloc_target+0x290/0x330
+[ 441.797010] __scsi_scan_target+0x88/0x258
+[ 441.801096] scsi_scan_channel+0x74/0xb8
+[ 441.805008] scsi_scan_host_selected+0x170/0x188
+[ 441.809615] sas_user_scan+0xfc/0x148
+[ 441.813267] store_scan+0x10c/0x180
+[ 441.816743] dev_attr_store+0x20/0x40
+[ 441.820398] sysfs_kf_write+0x84/0xa8
+[ 441.824054] kernfs_fop_write_iter+0x130/0x1c8
+[ 441.828487] vfs_write+0x2c0/0x370
+[ 441.831880] ksys_write+0x74/0x118
+[ 441.835271] __arm64_sys_write+0x24/0x38
+[ 441.839182] invoke_syscall+0x50/0x120
+[ 441.842919] el0_svc_common.constprop.0+0xc8/0xf0
+[ 441.847611] do_el0_svc+0x24/0x38
+[ 441.850913] el0_svc+0x38/0x158
+[ 441.854043] el0t_64_sync_handler+0xa0/0xe8
+[ 441.858214] el0t_64_sync+0x1ac/0x1b0
+[ 441.861865] Code: aa1303e0 97ff70a8 34ffff80 d10a4273 (f9445a75)
+[ 441.867946] ---[ end trace 0000000000000000 ]---
+
+Therefore, set max_channel to 0.
+
+Fixes: e21fe3a52692 ("scsi: hisi_sas: add initialisation for v3 pci-based controller")
+Signed-off-by: Xingui Yang <yangxingui@huawei.com>
+Signed-off-by: Yihang Li <liyihang9@huawei.com>
+Link: https://patch.msgid.link/20260305064039.4096775-1-liyihang9@huawei.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +-
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 30a9c66126513..c2b082f1252c3 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -2578,7 +2578,7 @@ int hisi_sas_probe(struct platform_device *pdev,
+ shost->transportt = hisi_sas_stt;
+ shost->max_id = HISI_SAS_MAX_DEVICES;
+ shost->max_lun = ~0;
+- shost->max_channel = 1;
++ shost->max_channel = 0;
+ shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN;
+ if (hisi_hba->hw->slot_index_alloc) {
+ shost->can_queue = HISI_SAS_MAX_COMMANDS;
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 2f9e01717ef38..f69efc6494b8e 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -4993,7 +4993,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ shost->transportt = hisi_sas_stt;
+ shost->max_id = HISI_SAS_MAX_DEVICES;
+ shost->max_lun = ~0;
+- shost->max_channel = 1;
++ shost->max_channel = 0;
+ shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN;
+ shost->can_queue = HISI_SAS_UNRESERVED_IPTT;
+ shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT;
+--
+2.51.0
+
--- /dev/null
+From b74eb1f39aa1d3bcc48c5c76844fcf59fcdd56b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 7 Mar 2026 11:51:28 +0800
+Subject: scsi: ufs: core: Fix SError in ufshcd_rtc_work() during UFS suspend
+
+From: Wang Shuaiwei <wangshuaiwei1@xiaomi.com>
+
+[ Upstream commit b0bd84c39289ef6a6c3827dd52c875659291970a ]
+
+In __ufshcd_wl_suspend(), cancel_delayed_work_sync() is called to cancel
+the UFS RTC work, but it is placed after ufshcd_vops_suspend(hba, pm_op,
+POST_CHANGE). This creates a race condition where ufshcd_rtc_work() can
+still be running while ufshcd_vops_suspend() is executing. When
+UFSHCD_CAP_CLK_GATING is not supported, the condition
+!hba->clk_gating.active_reqs is always true, causing ufshcd_update_rtc()
+to be executed. Since ufshcd_vops_suspend() typically performs clock
+gating operations, executing ufshcd_update_rtc() at that moment triggers
+an SError. The kernel panic trace is as follows:
+
+Kernel panic - not syncing: Asynchronous SError Interrupt
+Call trace:
+ dump_backtrace+0xec/0x128
+ show_stack+0x18/0x28
+ dump_stack_lvl+0x40/0xa0
+ dump_stack+0x18/0x24
+ panic+0x148/0x374
+ nmi_panic+0x3c/0x8c
+ arm64_serror_panic+0x64/0x8c
+ do_serror+0xc4/0xc8
+ el1h_64_error_handler+0x34/0x4c
+ el1h_64_error+0x68/0x6c
+ el1_interrupt+0x20/0x58
+ el1h_64_irq_handler+0x18/0x24
+ el1h_64_irq+0x68/0x6c
+ ktime_get+0xc4/0x12c
+ ufshcd_mcq_sq_stop+0x4c/0xec
+ ufshcd_mcq_sq_cleanup+0x64/0x1dc
+ ufshcd_clear_cmd+0x38/0x134
+ ufshcd_issue_dev_cmd+0x298/0x4d0
+ ufshcd_exec_dev_cmd+0x1a4/0x1c4
+ ufshcd_query_attr+0xbc/0x19c
+ ufshcd_rtc_work+0x10c/0x1c8
+ process_scheduled_works+0x1c4/0x45c
+ worker_thread+0x32c/0x3e8
+ kthread+0x120/0x1d8
+ ret_from_fork+0x10/0x20
+
+Fix this by moving cancel_delayed_work_sync() before the call to
+ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE), ensuring the UFS RTC work is
+fully completed or cancelled at that point.
+
+Cc: Bean Huo <beanhuo@iokpp.de>
+Fixes: 6bf999e0eb41 ("scsi: ufs: core: Add UFS RTC support")
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Wang Shuaiwei <wangshuaiwei1@xiaomi.com>
+Link: https://patch.msgid.link/20260307035128.3419687-1-wangshuaiwei1@xiaomi.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/core/ufshcd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
+index fe1425ea6718f..5371f173e28b9 100644
+--- a/drivers/ufs/core/ufshcd.c
++++ b/drivers/ufs/core/ufshcd.c
+@@ -9925,6 +9925,7 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
+ }
+
+ flush_work(&hba->eeh_work);
++ cancel_delayed_work_sync(&hba->ufs_rtc_update_work);
+
+ ret = ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE);
+ if (ret)
+@@ -9979,7 +9980,6 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
+ if (ret)
+ goto set_link_active;
+
+- cancel_delayed_work_sync(&hba->ufs_rtc_update_work);
+ goto out;
+
+ set_link_active:
+--
+2.51.0
+
revert-usb-gadget-f_ncm-align-net_device-lifecycle-with-bind-unbind.patch
revert-usb-gadget-u_ether-add-gether_opts-for-config-caching.patch
usb-gadget-f_ncm-fix-net_device-lifecycle-with-device_move.patch
+alsa-usb-audio-improve-focusrite-sample-rate-filteri.patch
+time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch
+i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch
+powerpc-perf-check-that-current-mm-is-alive-before-g.patch
+scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch
+scsi-hisi_sas-fix-null-pointer-exception-during-user.patch
--- /dev/null
+From b35d9dd7d18c6e1460331e2dec2f88f9572f49be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Mar 2026 21:24:03 -0500
+Subject: time/jiffies: Mark jiffies_64_to_clock_t() notrace
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 755a648e78f12574482d4698d877375793867fa1 ]
+
+The trace_clock_jiffies() function that handles the "uptime" clock for
+tracing calls jiffies_64_to_clock_t(). This causes the function tracer to
+constantly recurse when the tracing clock is set to "uptime". Mark it
+notrace to prevent unnecessary recursion when using the "uptime" clock.
+
+Fixes: 58d4e21e50ff3 ("tracing: Fix wraparound problems in "uptime" trace clock")
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Link: https://patch.msgid.link/20260306212403.72270bb2@robin
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/time.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/time/time.c b/kernel/time/time.c
+index 0ba8e3c50d625..155cf7def9146 100644
+--- a/kernel/time/time.c
++++ b/kernel/time/time.c
+@@ -702,7 +702,7 @@ EXPORT_SYMBOL(clock_t_to_jiffies);
+ *
+ * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC)
+ */
+-u64 jiffies_64_to_clock_t(u64 x)
++notrace u64 jiffies_64_to_clock_t(u64 x)
+ {
+ #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
+ # if HZ < USER_HZ
+--
+2.51.0
+
--- /dev/null
+From 46ec6adcab5355d772539dcda12710e3c217b7d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 Feb 2026 02:33:45 +1030
+Subject: ALSA: usb-audio: Improve Focusrite sample rate filtering
+
+From: Geoffrey D. Bennett <g@b4.vu>
+
+[ Upstream commit 24d2d3c5f94007a5a0554065ab7349bb69e28bcb ]
+
+Replace the bLength == 10 max_rate check in
+focusrite_valid_sample_rate() with filtering that also examines the
+bmControls VAL_ALT_SETTINGS bit.
+
+When VAL_ALT_SETTINGS is readable, the device uses strict
+per-altsetting rate filtering (only the highest rate pair for that
+altsetting is valid). When it is not readable, all rates up to
+max_rate are valid.
+
+For devices without the bLength == 10 Format Type descriptor extension
+but with VAL_ALT_SETTINGS readable and multiple altsettings (only seen
+in Scarlett 18i8 3rd Gen playback), fall back to the Focusrite
+convention: alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz.
+
+This produces correct rate tables for all tested Focusrite devices
+(all Scarlett 2nd, 3rd, and 4th Gen, Clarett+, and Vocaster) using
+only USB descriptors, allowing QUIRK_FLAG_VALIDATE_RATES to be removed
+for Focusrite in the next commit.
+
+Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/7e18c1f393a6ecb6fc75dd867a2c4dbe135e3e22.1771594828.git.g@b4.vu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/format.c | 70 ++++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 65 insertions(+), 5 deletions(-)
+
+diff --git a/sound/usb/format.c b/sound/usb/format.c
+index 64cfe4a9d8cdf..1207c507882ad 100644
+--- a/sound/usb/format.c
++++ b/sound/usb/format.c
+@@ -305,17 +305,48 @@ static bool s1810c_valid_sample_rate(struct audioformat *fp,
+ }
+
+ /*
+- * Many Focusrite devices supports a limited set of sampling rates per
+- * altsetting. Maximum rate is exposed in the last 4 bytes of Format Type
+- * descriptor which has a non-standard bLength = 10.
++ * Focusrite devices use rate pairs: 44100/48000, 88200/96000, and
++ * 176400/192000. Return true if rate is in the pair for max_rate.
++ */
++static bool focusrite_rate_pair(unsigned int rate,
++ unsigned int max_rate)
++{
++ switch (max_rate) {
++ case 48000: return rate == 44100 || rate == 48000;
++ case 96000: return rate == 88200 || rate == 96000;
++ case 192000: return rate == 176400 || rate == 192000;
++ default: return true;
++ }
++}
++
++/*
++ * Focusrite devices report all supported rates in a single clock
++ * source but only a subset is valid per altsetting.
++ *
++ * Detection uses two descriptor features:
++ *
++ * 1. Format Type descriptor bLength == 10: non-standard extension
++ * with max sample rate in bytes 6..9.
++ *
++ * 2. bmControls VAL_ALT_SETTINGS readable bit: when set, the device
++ * only supports the highest rate pair for that altsetting, and when
++ * clear, all rates up to max_rate are valid.
++ *
++ * For devices without the bLength == 10 extension but with
++ * VAL_ALT_SETTINGS readable and multiple altsettings (only seen in
++ * Scarlett 18i8 3rd Gen playback), fall back to the Focusrite
++ * convention: alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz.
+ */
+ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
+ struct audioformat *fp,
+ unsigned int rate)
+ {
++ struct usb_interface *iface;
+ struct usb_host_interface *alts;
++ struct uac2_as_header_descriptor *as;
+ unsigned char *fmt;
+ unsigned int max_rate;
++ bool val_alt;
+
+ alts = snd_usb_get_host_interface(chip, fp->iface, fp->altsetting);
+ if (!alts)
+@@ -326,9 +357,21 @@ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
+ if (!fmt)
+ return true;
+
++ as = snd_usb_find_csint_desc(alts->extra, alts->extralen,
++ NULL, UAC_AS_GENERAL);
++ if (!as)
++ return true;
++
++ val_alt = uac_v2v3_control_is_readable(as->bmControls,
++ UAC2_AS_VAL_ALT_SETTINGS);
++
+ if (fmt[0] == 10) { /* bLength */
+ max_rate = combine_quad(&fmt[6]);
+
++ if (val_alt)
++ return focusrite_rate_pair(rate, max_rate);
++
++ /* No val_alt: rates fall through from higher */
+ switch (max_rate) {
+ case 192000:
+ if (rate == 176400 || rate == 192000)
+@@ -344,12 +387,29 @@ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
+ usb_audio_info(chip,
+ "%u:%d : unexpected max rate: %u\n",
+ fp->iface, fp->altsetting, max_rate);
+-
+ return true;
+ }
+ }
+
+- return true;
++ if (!val_alt)
++ return true;
++
++ /* Multi-altsetting device with val_alt but no max_rate
++ * in the format descriptor. Use Focusrite convention:
++ * alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz.
++ */
++ iface = usb_ifnum_to_if(chip->dev, fp->iface);
++ if (!iface || iface->num_altsetting <= 2)
++ return true;
++
++ switch (fp->altsetting) {
++ case 1: max_rate = 48000; break;
++ case 2: max_rate = 96000; break;
++ case 3: max_rate = 192000; break;
++ default: return true;
++ }
++
++ return focusrite_rate_pair(rate, max_rate);
+ }
+
+ /*
+--
+2.51.0
+
--- /dev/null
+From 8a6c793c597555a97c6110094c13f2b20c502e17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 14:00:48 +0800
+Subject: i3c: dw-i3c-master: Set SIR_REJECT in DAT on device attach and
+ reattach
+
+From: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
+
+[ Upstream commit f311a05784634febd299f03476b80f3f18489767 ]
+
+The DesignWare I3C master controller ACKs IBIs as soon as a valid
+Device Address Table (DAT) entry is present. This can create a race
+between device attachment (after DAA) and the point where the client
+driver enables IBIs via i3c_device_enable_ibi().
+
+Set DEV_ADDR_TABLE_SIR_REJECT in the DAT entry during
+attach_i3c_dev() and reattach_i3c_dev() so that IBIs are rejected
+by default. The bit is managed thereafter by the existing
+dw_i3c_master_set_sir_enabled() function, which clears it in
+enable_ibi() after ENEC is issued, and restores it in disable_ibi()
+after DISEC.
+
+Fixes: 1dd728f5d4d4 ("i3c: master: Add driver for Synopsys DesignWare IP")
+Signed-off-by: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/53f5b8cbdd8af789ec38b95b02873f32f9182dd6.1770962368.git.adrianhoyin.ng@altera.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i3c/master/dw-i3c-master.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
+index 4033bc16677ff..f9b981abd10c5 100644
+--- a/drivers/i3c/master/dw-i3c-master.c
++++ b/drivers/i3c/master/dw-i3c-master.c
+@@ -1010,7 +1010,7 @@ static int dw_i3c_master_reattach_i3c_dev(struct i3c_dev_desc *dev,
+ master->free_pos &= ~BIT(pos);
+ }
+
+- writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr),
++ writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr) | DEV_ADDR_TABLE_SIR_REJECT,
+ master->regs +
+ DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
+
+@@ -1039,7 +1039,7 @@ static int dw_i3c_master_attach_i3c_dev(struct i3c_dev_desc *dev)
+ master->free_pos &= ~BIT(pos);
+ i3c_dev_set_master_data(dev, data);
+
+- writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr),
++ writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr) | DEV_ADDR_TABLE_SIR_REJECT,
+ master->regs +
+ DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
+
+--
+2.51.0
+
--- /dev/null
+From be9314253d9c7bb0f74022f63e0bcecbcc4e0688 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Mar 2026 14:16:00 +0800
+Subject: irqchip/riscv-aplic: Do not clear ACPI dependencies on probe failure
+
+From: Jessica Liu <liu.xuemei1@zte.com.cn>
+
+[ Upstream commit 620b6ded72a7f0f77be6ec44d0462bb85729ab7a ]
+
+aplic_probe() calls acpi_dev_clear_dependencies() unconditionally at the
+end, even when the preceding setup (MSI or direct mode) has failed. This is
+incorrect because if the device failed to probe, it should not be
+considered as active and should not clear dependencies for other devices
+waiting on it.
+
+Fix this by returning immediately when the setup fails, skipping the ACPI
+dependency cleanup. Also, explicitly return 0 on success instead of relying
+on the value of 'rc' to make the success path clear.
+
+Fixes: 5122e380c23b ("irqchip/riscv-aplic: Add ACPI support")
+Signed-off-by: Jessica Liu <liu.xuemei1@zte.com.cn>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Link: https://patch.msgid.link/20260310141600411Fu8H8-GXOOgKISU48Tjgx@zte.com.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-riscv-aplic-main.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
+index 4495ca26abf57..8775f188ea4fc 100644
+--- a/drivers/irqchip/irq-riscv-aplic-main.c
++++ b/drivers/irqchip/irq-riscv-aplic-main.c
+@@ -372,18 +372,21 @@ static int aplic_probe(struct platform_device *pdev)
+ rc = aplic_msi_setup(dev, regs);
+ else
+ rc = aplic_direct_setup(dev, regs);
+- if (rc)
++
++ if (rc) {
+ dev_err_probe(dev, rc, "failed to setup APLIC in %s mode\n",
+ msi_mode ? "MSI" : "direct");
+- else
+- register_syscore(&aplic_syscore);
++ return rc;
++ }
++
++ register_syscore(&aplic_syscore);
+
+ #ifdef CONFIG_ACPI
+ if (!acpi_disabled)
+ acpi_dev_clear_dependencies(ACPI_COMPANION(dev));
+ #endif
+
+- return rc;
++ return 0;
+ }
+
+ static const struct of_device_id aplic_match[] = {
+--
+2.51.0
+
--- /dev/null
+From c120aae874b512314c1113a31e45124fbccbc0b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 14:07:41 +0800
+Subject: irqchip/riscv-aplic: Preserve APLIC states across suspend/resume
+
+From: Nick Hu <nick.hu@sifive.com>
+
+[ Upstream commit 95a8ddde36601d0a645475fb080ed118db59c8c3 ]
+
+The APLIC states might be reset when the platform enters a low power
+state, but the register states are not being preserved and restored,
+which prevents interrupt delivery after the platform resumes.
+Solve this by adding a syscore ops and a power management notifier to
+preserve and restore the APLIC states on suspend and resume.
+
+[ tglx: Folded the build fix provided by Geert ]
+
+Signed-off-by: Nick Hu <nick.hu@sifive.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
+Reviewed-by: Cyan Yang <cyan.yang@sifive.com>
+Reviewed-by: Nutty Liu <liujingqi@lanxincomputing.com>
+Reviewed-by: Anup Patel <anup@brainfault.org>
+Link: https://patch.msgid.link/20251202-preserve-aplic-imsic-v3-2-1844fbf1fe92@sifive.com
+Stable-dep-of: 620b6ded72a7 ("irqchip/riscv-aplic: Do not clear ACPI dependencies on probe failure")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-riscv-aplic-direct.c | 10 ++
+ drivers/irqchip/irq-riscv-aplic-main.c | 170 ++++++++++++++++++++++-
+ drivers/irqchip/irq-riscv-aplic-main.h | 19 +++
+ 3 files changed, 198 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/irqchip/irq-riscv-aplic-direct.c b/drivers/irqchip/irq-riscv-aplic-direct.c
+index c2a75bf3d20c6..5a9650225dd80 100644
+--- a/drivers/irqchip/irq-riscv-aplic-direct.c
++++ b/drivers/irqchip/irq-riscv-aplic-direct.c
+@@ -8,6 +8,7 @@
+ #include <linux/bitfield.h>
+ #include <linux/bitops.h>
+ #include <linux/cpu.h>
++#include <linux/cpumask.h>
+ #include <linux/interrupt.h>
+ #include <linux/irqchip.h>
+ #include <linux/irqchip/chained_irq.h>
+@@ -171,6 +172,15 @@ static void aplic_idc_set_delivery(struct aplic_idc *idc, bool en)
+ writel(de, idc->regs + APLIC_IDC_IDELIVERY);
+ }
+
++void aplic_direct_restore_states(struct aplic_priv *priv)
++{
++ struct aplic_direct *direct = container_of(priv, struct aplic_direct, priv);
++ int cpu;
++
++ for_each_cpu(cpu, &direct->lmask)
++ aplic_idc_set_delivery(per_cpu_ptr(&aplic_idcs, cpu), true);
++}
++
+ static int aplic_direct_dying_cpu(unsigned int cpu)
+ {
+ if (aplic_direct_parent_irq)
+diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
+index 93e7c51f944ab..4495ca26abf57 100644
+--- a/drivers/irqchip/irq-riscv-aplic-main.c
++++ b/drivers/irqchip/irq-riscv-aplic-main.c
+@@ -12,10 +12,169 @@
+ #include <linux/of.h>
+ #include <linux/of_irq.h>
+ #include <linux/platform_device.h>
++#include <linux/pm_domain.h>
++#include <linux/pm_runtime.h>
+ #include <linux/printk.h>
++#include <linux/syscore_ops.h>
+
+ #include "irq-riscv-aplic-main.h"
+
++static LIST_HEAD(aplics);
++
++static void aplic_restore_states(struct aplic_priv *priv)
++{
++ struct aplic_saved_regs *saved_regs = &priv->saved_hw_regs;
++ struct aplic_src_ctrl *srcs;
++ void __iomem *regs;
++ u32 nr_irqs, i;
++
++ regs = priv->regs;
++ writel(saved_regs->domaincfg, regs + APLIC_DOMAINCFG);
++#ifdef CONFIG_RISCV_M_MODE
++ writel(saved_regs->msiaddr, regs + APLIC_xMSICFGADDR);
++ writel(saved_regs->msiaddrh, regs + APLIC_xMSICFGADDRH);
++#endif
++ /*
++ * The sourcecfg[i] has to be restored prior to the target[i], interrupt-pending and
++ * interrupt-enable bits. The AIA specification states that "Whenever interrupt source i is
++ * inactive in an interrupt domain, the corresponding interrupt-pending and interrupt-enable
++ * bits within the domain are read-only zeros, and register target[i] is also read-only
++ * zero."
++ */
++ nr_irqs = priv->nr_irqs;
++ for (i = 0; i < nr_irqs; i++) {
++ srcs = &priv->saved_hw_regs.srcs[i];
++ writel(srcs->sourcecfg, regs + APLIC_SOURCECFG_BASE + i * sizeof(u32));
++ writel(srcs->target, regs + APLIC_TARGET_BASE + i * sizeof(u32));
++ }
++
++ for (i = 0; i <= nr_irqs; i += 32) {
++ srcs = &priv->saved_hw_regs.srcs[i];
++ writel(-1U, regs + APLIC_CLRIE_BASE + (i / 32) * sizeof(u32));
++ writel(srcs->ie, regs + APLIC_SETIE_BASE + (i / 32) * sizeof(u32));
++
++ /* Re-trigger the interrupts if it forwards interrupts to target harts by MSIs */
++ if (!priv->nr_idcs)
++ writel(readl(regs + APLIC_CLRIP_BASE + (i / 32) * sizeof(u32)),
++ regs + APLIC_SETIP_BASE + (i / 32) * sizeof(u32));
++ }
++
++ if (priv->nr_idcs)
++ aplic_direct_restore_states(priv);
++}
++
++static void aplic_save_states(struct aplic_priv *priv)
++{
++ struct aplic_src_ctrl *srcs;
++ void __iomem *regs;
++ u32 i, nr_irqs;
++
++ regs = priv->regs;
++ nr_irqs = priv->nr_irqs;
++ /* The valid interrupt source IDs range from 1 to N, where N is priv->nr_irqs */
++ for (i = 0; i < nr_irqs; i++) {
++ srcs = &priv->saved_hw_regs.srcs[i];
++ srcs->target = readl(regs + APLIC_TARGET_BASE + i * sizeof(u32));
++
++ if (i % 32)
++ continue;
++
++ srcs->ie = readl(regs + APLIC_SETIE_BASE + (i / 32) * sizeof(u32));
++ }
++
++ /* Save the nr_irqs bit if needed */
++ if (!(nr_irqs % 32)) {
++ srcs = &priv->saved_hw_regs.srcs[nr_irqs];
++ srcs->ie = readl(regs + APLIC_SETIE_BASE + (nr_irqs / 32) * sizeof(u32));
++ }
++}
++
++static int aplic_syscore_suspend(void *data)
++{
++ struct aplic_priv *priv;
++
++ list_for_each_entry(priv, &aplics, head)
++ aplic_save_states(priv);
++
++ return 0;
++}
++
++static void aplic_syscore_resume(void *data)
++{
++ struct aplic_priv *priv;
++
++ list_for_each_entry(priv, &aplics, head)
++ aplic_restore_states(priv);
++}
++
++static struct syscore_ops aplic_syscore_ops = {
++ .suspend = aplic_syscore_suspend,
++ .resume = aplic_syscore_resume,
++};
++
++static struct syscore aplic_syscore = {
++ .ops = &aplic_syscore_ops,
++};
++
++static int aplic_pm_notifier(struct notifier_block *nb, unsigned long action, void *data)
++{
++ struct aplic_priv *priv = container_of(nb, struct aplic_priv, genpd_nb);
++
++ switch (action) {
++ case GENPD_NOTIFY_PRE_OFF:
++ aplic_save_states(priv);
++ break;
++ case GENPD_NOTIFY_ON:
++ aplic_restore_states(priv);
++ break;
++ default:
++ break;
++ }
++
++ return 0;
++}
++
++static void aplic_pm_remove(void *data)
++{
++ struct aplic_priv *priv = data;
++ struct device *dev = priv->dev;
++
++ list_del(&priv->head);
++ if (dev->pm_domain)
++ dev_pm_genpd_remove_notifier(dev);
++}
++
++static int aplic_pm_add(struct device *dev, struct aplic_priv *priv)
++{
++ struct aplic_src_ctrl *srcs;
++ int ret;
++
++ srcs = devm_kzalloc(dev, (priv->nr_irqs + 1) * sizeof(*srcs), GFP_KERNEL);
++ if (!srcs)
++ return -ENOMEM;
++
++ priv->saved_hw_regs.srcs = srcs;
++ list_add(&priv->head, &aplics);
++ if (dev->pm_domain) {
++ priv->genpd_nb.notifier_call = aplic_pm_notifier;
++ ret = dev_pm_genpd_add_notifier(dev, &priv->genpd_nb);
++ if (ret)
++ goto remove_head;
++
++ ret = devm_pm_runtime_enable(dev);
++ if (ret)
++ goto remove_notifier;
++ }
++
++ return devm_add_action_or_reset(dev, aplic_pm_remove, priv);
++
++remove_notifier:
++ dev_pm_genpd_remove_notifier(dev);
++remove_head:
++ list_del(&priv->head);
++ return ret;
++}
++
+ void aplic_irq_unmask(struct irq_data *d)
+ {
+ struct aplic_priv *priv = irq_data_get_irq_chip_data(d);
+@@ -60,6 +219,8 @@ int aplic_irq_set_type(struct irq_data *d, unsigned int type)
+ sourcecfg += (d->hwirq - 1) * sizeof(u32);
+ writel(val, sourcecfg);
+
++ priv->saved_hw_regs.srcs[d->hwirq - 1].sourcecfg = val;
++
+ return 0;
+ }
+
+@@ -82,6 +243,7 @@ int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base,
+
+ void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode)
+ {
++ struct aplic_saved_regs *saved_regs = &priv->saved_hw_regs;
+ u32 val;
+ #ifdef CONFIG_RISCV_M_MODE
+ u32 valh;
+@@ -95,6 +257,8 @@ void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode)
+ valh |= FIELD_PREP(APLIC_xMSICFGADDRH_HHXS, priv->msicfg.hhxs);
+ writel(val, priv->regs + APLIC_xMSICFGADDR);
+ writel(valh, priv->regs + APLIC_xMSICFGADDRH);
++ saved_regs->msiaddr = val;
++ saved_regs->msiaddrh = valh;
+ }
+ #endif
+
+@@ -106,6 +270,8 @@ void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode)
+ writel(val, priv->regs + APLIC_DOMAINCFG);
+ if (readl(priv->regs + APLIC_DOMAINCFG) != val)
+ dev_warn(priv->dev, "unable to write 0x%x in domaincfg\n", val);
++
++ saved_regs->domaincfg = val;
+ }
+
+ static void aplic_init_hw_irqs(struct aplic_priv *priv)
+@@ -176,7 +342,7 @@ int aplic_setup_priv(struct aplic_priv *priv, struct device *dev, void __iomem *
+ /* Setup initial state APLIC interrupts */
+ aplic_init_hw_irqs(priv);
+
+- return 0;
++ return aplic_pm_add(dev, priv);
+ }
+
+ static int aplic_probe(struct platform_device *pdev)
+@@ -209,6 +375,8 @@ static int aplic_probe(struct platform_device *pdev)
+ if (rc)
+ dev_err_probe(dev, rc, "failed to setup APLIC in %s mode\n",
+ msi_mode ? "MSI" : "direct");
++ else
++ register_syscore(&aplic_syscore);
+
+ #ifdef CONFIG_ACPI
+ if (!acpi_disabled)
+diff --git a/drivers/irqchip/irq-riscv-aplic-main.h b/drivers/irqchip/irq-riscv-aplic-main.h
+index b0ad8cde69b13..2d8ad7138541a 100644
+--- a/drivers/irqchip/irq-riscv-aplic-main.h
++++ b/drivers/irqchip/irq-riscv-aplic-main.h
+@@ -23,7 +23,25 @@ struct aplic_msicfg {
+ u32 lhxw;
+ };
+
++struct aplic_src_ctrl {
++ u32 sourcecfg;
++ u32 target;
++ u32 ie;
++};
++
++struct aplic_saved_regs {
++ u32 domaincfg;
++#ifdef CONFIG_RISCV_M_MODE
++ u32 msiaddr;
++ u32 msiaddrh;
++#endif
++ struct aplic_src_ctrl *srcs;
++};
++
+ struct aplic_priv {
++ struct list_head head;
++ struct notifier_block genpd_nb;
++ struct aplic_saved_regs saved_hw_regs;
+ struct device *dev;
+ u32 gsi_base;
+ u32 nr_irqs;
+@@ -40,6 +58,7 @@ int aplic_irqdomain_translate(struct irq_fwspec *fwspec, u32 gsi_base,
+ unsigned long *hwirq, unsigned int *type);
+ void aplic_init_hw_global(struct aplic_priv *priv, bool msi_mode);
+ int aplic_setup_priv(struct aplic_priv *priv, struct device *dev, void __iomem *regs);
++void aplic_direct_restore_states(struct aplic_priv *priv);
+ int aplic_direct_setup(struct device *dev, void __iomem *regs);
+ #ifdef CONFIG_RISCV_APLIC_MSI
+ int aplic_msi_setup(struct device *dev, void __iomem *regs);
+--
+2.51.0
+
--- /dev/null
+From 02d1c38f978b50cc6d5bec66825dd931f9177fcc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Mar 2026 14:17:31 +0800
+Subject: irqchip/riscv-aplic: Register syscore operations only once
+
+From: Jessica Liu <liu.xuemei1@zte.com.cn>
+
+[ Upstream commit b330fbfd34d7624bec62b99ad88dba2614326a19 ]
+
+Since commit 95a8ddde3660 ("irqchip/riscv-aplic: Preserve APLIC
+states across suspend/resume"), when multiple NUMA nodes exist
+and AIA is not configured as "none", aplic_probe() is called
+multiple times. This leads to register_syscore(&aplic_syscore)
+being invoked repeatedly, causing the following Oops:
+
+ list_add double add: new=ffffffffb91461f0, prev=ffffffffb91461f0, next=ffffffffb915c408.
+ [<ffffffffb7b5c8ca>] __list_add_valid_or_report+0x60/0xc0
+ [<ffffffffb7cc3236>] register_syscore+0x3e/0x70
+ [<ffffffffb7b8d61c>] aplic_probe+0xc6/0x112
+
+Fix this by registering syscore operations only once, using a static
+variable aplic_syscore_registered to track registration.
+
+[ tglx: Trim backtrace properly ]
+
+Fixes: 95a8ddde3660 ("irqchip/riscv-aplic: Preserve APLIC states across suspend/resume")
+Signed-off-by: Jessica Liu <liu.xuemei1@zte.com.cn>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Link: https://patch.msgid.link/20260310141731145xMwLsyvXl9Gw-m6A4VRYj@zte.com.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-riscv-aplic-main.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c
+index 8775f188ea4fc..9f53979b69625 100644
+--- a/drivers/irqchip/irq-riscv-aplic-main.c
++++ b/drivers/irqchip/irq-riscv-aplic-main.c
+@@ -116,6 +116,16 @@ static struct syscore aplic_syscore = {
+ .ops = &aplic_syscore_ops,
+ };
+
++static bool aplic_syscore_registered __ro_after_init;
++
++static void aplic_syscore_init(void)
++{
++ if (!aplic_syscore_registered) {
++ register_syscore(&aplic_syscore);
++ aplic_syscore_registered = true;
++ }
++}
++
+ static int aplic_pm_notifier(struct notifier_block *nb, unsigned long action, void *data)
+ {
+ struct aplic_priv *priv = container_of(nb, struct aplic_priv, genpd_nb);
+@@ -379,7 +389,7 @@ static int aplic_probe(struct platform_device *pdev)
+ return rc;
+ }
+
+- register_syscore(&aplic_syscore);
++ aplic_syscore_init();
+
+ #ifdef CONFIG_ACPI
+ if (!acpi_disabled)
+--
+2.51.0
+
--- /dev/null
+From eb7be45480144dea4b2bb966847ad5c90b2c8918 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Mar 2026 10:28:14 -0800
+Subject: objtool: Fix another stack overflow in validate_branch()
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit 9a73f085dc91980ab7fcc5e9716f4449424b3b59 ]
+
+The insn state is getting saved on the stack twice for each recursive
+iteration. No need for that, once is enough.
+
+Fixes the following reported stack overflow:
+
+ drivers/scsi/qla2xxx/qla_dbg.o: error: SIGSEGV: objtool stack overflow!
+ Segmentation fault
+
+Fixes: 70589843b36f ("objtool: Add option to trace function validation")
+Reported-by: Arnd Bergmann <arnd@arndb.de>
+Closes: https://lore.kernel.org/90956545-2066-46e3-b547-10c884582eb0@app.fastmail.com
+Link: https://patch.msgid.link/8b97f62d083457f3b0a29a424275f7957dd3372f.1772821683.git.jpoimboe@kernel.org
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/objtool/check.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index 37ec0d757e9b1..eba35bb8c0bdf 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -3694,7 +3694,7 @@ static void checksum_update_insn(struct objtool_file *file, struct symbol *func,
+ static int validate_branch(struct objtool_file *file, struct symbol *func,
+ struct instruction *insn, struct insn_state state);
+ static int do_validate_branch(struct objtool_file *file, struct symbol *func,
+- struct instruction *insn, struct insn_state state);
++ struct instruction *insn, struct insn_state *state);
+
+ static int validate_insn(struct objtool_file *file, struct symbol *func,
+ struct instruction *insn, struct insn_state *statep,
+@@ -3959,7 +3959,7 @@ static int validate_insn(struct objtool_file *file, struct symbol *func,
+ * tools/objtool/Documentation/objtool.txt.
+ */
+ static int do_validate_branch(struct objtool_file *file, struct symbol *func,
+- struct instruction *insn, struct insn_state state)
++ struct instruction *insn, struct insn_state *state)
+ {
+ struct instruction *next_insn, *prev_insn = NULL;
+ bool dead_end;
+@@ -3990,7 +3990,7 @@ static int do_validate_branch(struct objtool_file *file, struct symbol *func,
+ return 1;
+ }
+
+- ret = validate_insn(file, func, insn, &state, prev_insn, next_insn,
++ ret = validate_insn(file, func, insn, state, prev_insn, next_insn,
+ &dead_end);
+
+ if (!insn->trace) {
+@@ -4001,7 +4001,7 @@ static int do_validate_branch(struct objtool_file *file, struct symbol *func,
+ }
+
+ if (!dead_end && !next_insn) {
+- if (state.cfi.cfa.base == CFI_UNDEFINED)
++ if (state->cfi.cfa.base == CFI_UNDEFINED)
+ return 0;
+ if (file->ignore_unreachables)
+ return 0;
+@@ -4026,7 +4026,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
+ int ret;
+
+ trace_depth_inc();
+- ret = do_validate_branch(file, func, insn, state);
++ ret = do_validate_branch(file, func, insn, &state);
+ trace_depth_dec();
+
+ return ret;
+--
+2.51.0
+
--- /dev/null
+From 80c5fd8ce09e6154b9494ed6cfc984253eee1871 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Mar 2026 19:31:20 -0800
+Subject: objtool: Fix data alignment in elf_add_data()
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit 356e4b2f5b80f757965f3f4d0219c81fca91b6f2 ]
+
+Any data added to a section needs to be aligned in accordance with the
+section's sh_addralign value. Particularly strings added to a .str1.8
+section. Otherwise you may get some funky strings.
+
+Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files")
+Link: https://patch.msgid.link/d962fc0ca24fa0825cca8dad71932dccdd9312a9.1772681234.git.jpoimboe@kernel.org
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/objtool/elf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
+index 2c02c7b492658..3da90686350d7 100644
+--- a/tools/objtool/elf.c
++++ b/tools/objtool/elf.c
+@@ -1375,7 +1375,7 @@ void *elf_add_data(struct elf *elf, struct section *sec, const void *data, size_
+ memcpy(sec->data->d_buf, data, size);
+
+ sec->data->d_size = size;
+- sec->data->d_align = 1;
++ sec->data->d_align = sec->sh.sh_addralign;
+
+ offset = ALIGN(sec->sh.sh_size, sec->sh.sh_addralign);
+ sec->sh.sh_size = offset + size;
+--
+2.51.0
+
--- /dev/null
+From 40168c3f0a3ab2aab1b2ec8e0c51ce4307cfcec9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 13:50:09 -0800
+Subject: objtool/klp: Fix detection of corrupt static branch/call entries
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit f9fb44b0ecefc1f218db56661ed66d4e8d67317d ]
+
+Patching a function which references a static key living in a kernel
+module is unsupported due to ordering issues inherent to late module
+patching:
+
+ 1) Load a livepatch module which has a __jump_table entry which needs
+ a klp reloc to reference static key K which lives in module M.
+
+ 2) The __jump_table klp reloc does *not* get resolved because module M
+ is not yet loaded.
+
+ 3) jump_label_add_module() corrupts memory (or causes a panic) when
+ dereferencing the uninitialized pointer to key K.
+
+validate_special_section_klp_reloc() intends to prevent that from ever
+happening by catching it at build time. However, it incorrectly assumes
+the special section entry's reloc symbol references have already been
+converted from section symbols to object symbols, causing the validation
+to miss corruption in extracted static branch/call table entries.
+
+Make sure the references have been properly converted before doing the
+validation.
+
+Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files")
+Reported-by: Song Liu <song@kernel.org>
+Reviewed-and-tested-by: Song Liu <song@kernel.org>
+Link: https://patch.msgid.link/124ad747b751df0df1725eff89de8332e3fb26d6.1770759954.git.jpoimboe@kernel.org
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/objtool/klp-diff.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
+index 9f1f4011eb9cd..d94632e809558 100644
+--- a/tools/objtool/klp-diff.c
++++ b/tools/objtool/klp-diff.c
+@@ -1364,6 +1364,9 @@ static int validate_special_section_klp_reloc(struct elfs *e, struct symbol *sym
+ const char *sym_modname;
+ struct export *export;
+
++ if (convert_reloc_sym(e->patched, reloc))
++ continue;
++
+ /* Static branch/call keys are always STT_OBJECT */
+ if (reloc->sym->type != STT_OBJECT) {
+
+--
+2.51.0
+
--- /dev/null
+From 0c151a5aca7c98c8ac34bd5e3fa6ee4408646a57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Mar 2026 15:40:45 +0100
+Subject: powerpc, perf: Check that current->mm is alive before getting user
+ callchain
+
+From: Viktor Malik <vmalik@redhat.com>
+
+[ Upstream commit e9bbfb4bfa86c6b5515b868d6982ac60505d7e39 ]
+
+It may happen that mm is already released, which leads to kernel panic.
+This adds the NULL check for current->mm, similarly to
+commit 20afc60f892d ("x86, perf: Check that current->mm is alive before getting user callchain").
+
+I was getting this panic when running a profiling BPF program
+(profile.py from bcc-tools):
+
+ [26215.051935] Kernel attempted to read user page (588) - exploit attempt? (uid: 0)
+ [26215.051950] BUG: Kernel NULL pointer dereference on read at 0x00000588
+ [26215.051952] Faulting instruction address: 0xc00000000020fac0
+ [26215.051957] Oops: Kernel access of bad area, sig: 11 [#1]
+ [...]
+ [26215.052049] Call Trace:
+ [26215.052050] [c000000061da6d30] [c00000000020fc10] perf_callchain_user_64+0x2d0/0x490 (unreliable)
+ [26215.052054] [c000000061da6dc0] [c00000000020f92c] perf_callchain_user+0x1c/0x30
+ [26215.052057] [c000000061da6de0] [c0000000005ab2a0] get_perf_callchain+0x100/0x360
+ [26215.052063] [c000000061da6e70] [c000000000573bc8] bpf_get_stackid+0x88/0xf0
+ [26215.052067] [c000000061da6ea0] [c008000000042258] bpf_prog_16d4ab9ab662f669_do_perf_event+0xf8/0x274
+ [...]
+
+In addition, move storing the top-level stack entry to generic
+perf_callchain_user to make sure the top-evel entry is always captured,
+even if current->mm is NULL.
+
+Fixes: 20002ded4d93 ("perf_counter: powerpc: Add callchain support")
+Signed-off-by: Viktor Malik <vmalik@redhat.com>
+Tested-by: Qiao Zhao <qzhao@redhat.com>
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Reviewed-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
+[Maddy: fixed message to avoid checkpatch format style error]
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20260309144045.169427-1-vmalik@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/perf/callchain.c | 5 +++++
+ arch/powerpc/perf/callchain_32.c | 1 -
+ arch/powerpc/perf/callchain_64.c | 1 -
+ 3 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
+index 26aa26482c9ac..992cc5c982144 100644
+--- a/arch/powerpc/perf/callchain.c
++++ b/arch/powerpc/perf/callchain.c
+@@ -103,6 +103,11 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re
+ void
+ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
+ {
++ perf_callchain_store(entry, perf_arch_instruction_pointer(regs));
++
++ if (!current->mm)
++ return;
++
+ if (!is_32bit_task())
+ perf_callchain_user_64(entry, regs);
+ else
+diff --git a/arch/powerpc/perf/callchain_32.c b/arch/powerpc/perf/callchain_32.c
+index ddcc2d8aa64a5..0de21c5d272c2 100644
+--- a/arch/powerpc/perf/callchain_32.c
++++ b/arch/powerpc/perf/callchain_32.c
+@@ -142,7 +142,6 @@ void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
+ next_ip = perf_arch_instruction_pointer(regs);
+ lr = regs->link;
+ sp = regs->gpr[1];
+- perf_callchain_store(entry, next_ip);
+
+ while (entry->nr < entry->max_stack) {
+ fp = (unsigned int __user *) (unsigned long) sp;
+diff --git a/arch/powerpc/perf/callchain_64.c b/arch/powerpc/perf/callchain_64.c
+index 115d1c105e8a8..30fb61c5f0cb0 100644
+--- a/arch/powerpc/perf/callchain_64.c
++++ b/arch/powerpc/perf/callchain_64.c
+@@ -77,7 +77,6 @@ void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
+ next_ip = perf_arch_instruction_pointer(regs);
+ lr = regs->link;
+ sp = regs->gpr[1];
+- perf_callchain_store(entry, next_ip);
+
+ while (entry->nr < entry->max_stack) {
+ fp = (unsigned long __user *) sp;
+--
+2.51.0
+
--- /dev/null
+From 798ce24d9929b6c81d2623a47aee25034c6dfd5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Mar 2026 21:29:09 +0100
+Subject: sched/mmcid: Avoid full tasklist walks
+
+From: Thomas Gleixner <tglx@kernel.org>
+
+[ Upstream commit 192d852129b1b7c4f0ddbab95d0de1efd5ee1405 ]
+
+Chasing vfork()'ed tasks on a CID ownership mode switch requires a full
+task list walk, which is obviously expensive on large systems.
+
+Avoid that by keeping a list of tasks using a mm MMCID entity in mm::mm_cid
+and walk this list instead. This removes the proven to be flaky counting
+logic and avoids a full task list walk in the case of vfork()'ed tasks.
+
+Fixes: fbd0e71dc370 ("sched/mmcid: Provide CID ownership mode fixup functions")
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Tested-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260310202526.183824481@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/rseq_types.h | 6 ++++-
+ kernel/fork.c | 1 +
+ kernel/sched/core.c | 54 +++++++++-----------------------------
+ 3 files changed, 18 insertions(+), 43 deletions(-)
+
+diff --git a/include/linux/rseq_types.h b/include/linux/rseq_types.h
+index ef0811379c540..a612959c5b17f 100644
+--- a/include/linux/rseq_types.h
++++ b/include/linux/rseq_types.h
+@@ -103,10 +103,12 @@ struct rseq_data { };
+ * @active: MM CID is active for the task
+ * @cid: The CID associated to the task either permanently or
+ * borrowed from the CPU
++ * @node: Queued in the per MM MMCID list
+ */
+ struct sched_mm_cid {
+ unsigned int active;
+ unsigned int cid;
++ struct hlist_node node;
+ };
+
+ /**
+@@ -127,6 +129,7 @@ struct mm_cid_pcpu {
+ * @work: Regular work to handle the affinity mode change case
+ * @lock: Spinlock to protect against affinity setting which can't take @mutex
+ * @mutex: Mutex to serialize forks and exits related to this mm
++ * @user_list: List of the MM CID users of a MM
+ * @nr_cpus_allowed: The number of CPUs in the per MM allowed CPUs map. The map
+ * is growth only.
+ * @users: The number of tasks sharing this MM. Separate from mm::mm_users
+@@ -147,13 +150,14 @@ struct mm_mm_cid {
+
+ raw_spinlock_t lock;
+ struct mutex mutex;
++ struct hlist_head user_list;
+
+ /* Low frequency modified */
+ unsigned int nr_cpus_allowed;
+ unsigned int users;
+ unsigned int pcpu_thrs;
+ unsigned int update_deferred;
+-}____cacheline_aligned_in_smp;
++} ____cacheline_aligned;
+ #else /* CONFIG_SCHED_MM_CID */
+ struct mm_mm_cid { };
+ struct sched_mm_cid { };
+diff --git a/kernel/fork.c b/kernel/fork.c
+index 2d79096e0fecb..5b45887435dcc 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -999,6 +999,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
+ #ifdef CONFIG_SCHED_MM_CID
+ tsk->mm_cid.cid = MM_CID_UNSET;
+ tsk->mm_cid.active = 0;
++ INIT_HLIST_NODE(&tsk->mm_cid.node);
+ #endif
+ return tsk;
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index c80076fcd78f2..011fe1b2ae911 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -10568,13 +10568,10 @@ static inline void mm_cid_transit_to_cpu(struct task_struct *t, struct mm_cid_pc
+ }
+ }
+
+-static bool mm_cid_fixup_task_to_cpu(struct task_struct *t, struct mm_struct *mm)
++static void mm_cid_fixup_task_to_cpu(struct task_struct *t, struct mm_struct *mm)
+ {
+ /* Remote access to mm::mm_cid::pcpu requires rq_lock */
+ guard(task_rq_lock)(t);
+- /* If the task is not active it is not in the users count */
+- if (!t->mm_cid.active)
+- return false;
+ if (cid_on_task(t->mm_cid.cid)) {
+ /* If running on the CPU, put the CID in transit mode, otherwise drop it */
+ if (task_rq(t)->curr == t)
+@@ -10582,51 +10579,21 @@ static bool mm_cid_fixup_task_to_cpu(struct task_struct *t, struct mm_struct *mm
+ else
+ mm_unset_cid_on_task(t);
+ }
+- return true;
+ }
+
+-static void mm_cid_do_fixup_tasks_to_cpus(struct mm_struct *mm)
++static void mm_cid_fixup_tasks_to_cpus(void)
+ {
+- struct task_struct *p, *t;
+- unsigned int users;
+-
+- /*
+- * This can obviously race with a concurrent affinity change, which
+- * increases the number of allowed CPUs for this mm, but that does
+- * not affect the mode and only changes the CID constraints. A
+- * possible switch back to per task mode happens either in the
+- * deferred handler function or in the next fork()/exit().
+- *
+- * The caller has already transferred so remove it from the users
+- * count. The incoming task is already visible and has mm_cid.active,
+- * but has task::mm_cid::cid == UNSET. Still it needs to be accounted
+- * for. Concurrent fork()s might add more threads, but all of them have
+- * task::mm_cid::active = 0, so they don't affect the accounting here.
+- */
+- users = mm->mm_cid.users - 1;
+-
+- guard(rcu)();
+- for_other_threads(current, t) {
+- if (mm_cid_fixup_task_to_cpu(t, mm))
+- users--;
+- }
++ struct mm_struct *mm = current->mm;
++ struct task_struct *t;
+
+- if (!users)
+- return;
++ lockdep_assert_held(&mm->mm_cid.mutex);
+
+- /* Happens only for VM_CLONE processes. */
+- for_each_process_thread(p, t) {
+- if (t == current || t->mm != mm)
+- continue;
+- mm_cid_fixup_task_to_cpu(t, mm);
++ hlist_for_each_entry(t, &mm->mm_cid.user_list, mm_cid.node) {
++ /* Current has already transferred before invoking the fixup. */
++ if (t != current)
++ mm_cid_fixup_task_to_cpu(t, mm);
+ }
+-}
+-
+-static void mm_cid_fixup_tasks_to_cpus(void)
+-{
+- struct mm_struct *mm = current->mm;
+
+- mm_cid_do_fixup_tasks_to_cpus(mm);
+ mm_cid_complete_transit(mm, MM_CID_ONCPU);
+ }
+
+@@ -10635,6 +10602,7 @@ static bool sched_mm_cid_add_user(struct task_struct *t, struct mm_struct *mm)
+ lockdep_assert_held(&mm->mm_cid.lock);
+
+ t->mm_cid.active = 1;
++ hlist_add_head(&t->mm_cid.node, &mm->mm_cid.user_list);
+ mm->mm_cid.users++;
+ return mm_update_max_cids(mm);
+ }
+@@ -10692,6 +10660,7 @@ static bool sched_mm_cid_remove_user(struct task_struct *t)
+ /* Clear the transition bit */
+ t->mm_cid.cid = cid_from_transit_cid(t->mm_cid.cid);
+ mm_unset_cid_on_task(t);
++ hlist_del_init(&t->mm_cid.node);
+ t->mm->mm_cid.users--;
+ return mm_update_max_cids(t->mm);
+ }
+@@ -10834,6 +10803,7 @@ void mm_init_cid(struct mm_struct *mm, struct task_struct *p)
+ mutex_init(&mm->mm_cid.mutex);
+ mm->mm_cid.irq_work = IRQ_WORK_INIT_HARD(mm_cid_irq_work);
+ INIT_WORK(&mm->mm_cid.work, mm_cid_work_fn);
++ INIT_HLIST_HEAD(&mm->mm_cid.user_list);
+ cpumask_copy(mm_cpus_allowed(mm), &p->cpus_mask);
+ bitmap_zero(mm_cidmask(mm), num_possible_cpus());
+ }
+--
+2.51.0
+
--- /dev/null
+From 674b0ac7110459b7f7f4c6e400f630828336872e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Mar 2026 21:28:58 +0100
+Subject: sched/mmcid: Handle vfork()/CLONE_VM correctly
+
+From: Thomas Gleixner <tglx@kernel.org>
+
+[ Upstream commit 28b5a1395036d6c7a6c8034d85ad3d7d365f192c ]
+
+Matthieu and Jiri reported stalls where a task endlessly loops in
+mm_get_cid() when scheduling in.
+
+It turned out that the logic which handles vfork()'ed tasks is broken. It
+is invoked when the number of tasks associated to a process is smaller than
+the number of MMCID users. It then walks the task list to find the
+vfork()'ed task, but accounts all the already processed tasks as well.
+
+If that double processing brings the number of to be handled tasks to 0,
+the walk stops and the vfork()'ed task's CID is not fixed up. As a
+consequence a subsequent schedule in fails to acquire a (transitional) CID
+and the machine stalls.
+
+Cure this by removing the accounting condition and make the fixup always
+walk the full task list if it could not find the exact number of users in
+the process' thread list.
+
+Fixes: fbd0e71dc370 ("sched/mmcid: Provide CID ownership mode fixup functions")
+Closes: https://lore.kernel.org/b24ffcb3-09d5-4e48-9070-0b69bc654281@kernel.org
+Reported-by: Matthieu Baerts <matttbe@kernel.org>
+Reported-by: Jiri Slaby <jirislaby@kernel.org>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Tested-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260310202526.048657665@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/core.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index ca6e6e4b17eaf..24d607c78f119 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -10618,10 +10618,7 @@ static void mm_cid_do_fixup_tasks_to_cpus(struct mm_struct *mm)
+ for_each_process_thread(p, t) {
+ if (t == current || t->mm != mm)
+ continue;
+- if (mm_cid_fixup_task_to_cpu(t, mm)) {
+- if (--users == 0)
+- return;
+- }
++ mm_cid_fixup_task_to_cpu(t, mm);
+ }
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 1b9ebba6db21b21e5cecb13b667a01680849d673 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Mar 2026 21:28:53 +0100
+Subject: sched/mmcid: Prevent CID stalls due to concurrent forks
+
+From: Thomas Gleixner <tglx@kernel.org>
+
+[ Upstream commit b2e48c429ec54715d16fefa719dd2fbded2e65be ]
+
+A newly forked task is accounted as MMCID user before the task is visible
+in the process' thread list and the global task list. This creates the
+following problem:
+
+ CPU1 CPU2
+ fork()
+ sched_mm_cid_fork(tnew1)
+ tnew1->mm.mm_cid_users++;
+ tnew1->mm_cid.cid = getcid()
+-> preemption
+ fork()
+ sched_mm_cid_fork(tnew2)
+ tnew2->mm.mm_cid_users++;
+ // Reaches the per CPU threshold
+ mm_cid_fixup_tasks_to_cpus()
+ for_each_other(current, p)
+ ....
+
+As tnew1 is not visible yet, this fails to fix up the already allocated CID
+of tnew1. As a consequence a subsequent schedule in might fail to acquire a
+(transitional) CID and the machine stalls.
+
+Move the invocation of sched_mm_cid_fork() after the new task becomes
+visible in the thread and the task list to prevent this.
+
+This also makes it symmetrical vs. exit() where the task is removed as CID
+user before the task is removed from the thread and task lists.
+
+Fixes: fbd0e71dc370 ("sched/mmcid: Provide CID ownership mode fixup functions")
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Tested-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260310202525.969061974@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/sched.h | 2 --
+ kernel/fork.c | 2 --
+ kernel/sched/core.c | 22 +++++++++++++++-------
+ 3 files changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index eb1c4c347a5cf..0719862970a28 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -2313,7 +2313,6 @@ static __always_inline void alloc_tag_restore(struct alloc_tag *tag, struct allo
+ #ifdef CONFIG_SCHED_MM_CID
+ void sched_mm_cid_before_execve(struct task_struct *t);
+ void sched_mm_cid_after_execve(struct task_struct *t);
+-void sched_mm_cid_fork(struct task_struct *t);
+ void sched_mm_cid_exit(struct task_struct *t);
+ static __always_inline int task_mm_cid(struct task_struct *t)
+ {
+@@ -2322,7 +2321,6 @@ static __always_inline int task_mm_cid(struct task_struct *t)
+ #else
+ static inline void sched_mm_cid_before_execve(struct task_struct *t) { }
+ static inline void sched_mm_cid_after_execve(struct task_struct *t) { }
+-static inline void sched_mm_cid_fork(struct task_struct *t) { }
+ static inline void sched_mm_cid_exit(struct task_struct *t) { }
+ static __always_inline int task_mm_cid(struct task_struct *t)
+ {
+diff --git a/kernel/fork.c b/kernel/fork.c
+index 68ccbaea7398a..2d79096e0fecb 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -1585,7 +1585,6 @@ static int copy_mm(u64 clone_flags, struct task_struct *tsk)
+
+ tsk->mm = mm;
+ tsk->active_mm = mm;
+- sched_mm_cid_fork(tsk);
+ return 0;
+ }
+
+@@ -2496,7 +2495,6 @@ __latent_entropy struct task_struct *copy_process(
+ exit_nsproxy_namespaces(p);
+ bad_fork_cleanup_mm:
+ if (p->mm) {
+- sched_mm_cid_exit(p);
+ mm_clear_owner(p->mm, p);
+ mmput(p->mm);
+ }
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index dbf4e32a063f7..ca6e6e4b17eaf 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -4708,8 +4708,11 @@ void sched_cancel_fork(struct task_struct *p)
+ scx_cancel_fork(p);
+ }
+
++static void sched_mm_cid_fork(struct task_struct *t);
++
+ void sched_post_fork(struct task_struct *p)
+ {
++ sched_mm_cid_fork(p);
+ uclamp_post_fork(p);
+ scx_post_fork(p);
+ }
+@@ -10594,12 +10597,13 @@ static void mm_cid_do_fixup_tasks_to_cpus(struct mm_struct *mm)
+ * possible switch back to per task mode happens either in the
+ * deferred handler function or in the next fork()/exit().
+ *
+- * The caller has already transferred. The newly incoming task is
+- * already accounted for, but not yet visible.
++ * The caller has already transferred so remove it from the users
++ * count. The incoming task is already visible and has mm_cid.active,
++ * but has task::mm_cid::cid == UNSET. Still it needs to be accounted
++ * for. Concurrent fork()s might add more threads, but all of them have
++ * task::mm_cid::active = 0, so they don't affect the accounting here.
+ */
+- users = mm->mm_cid.users - 2;
+- if (!users)
+- return;
++ users = mm->mm_cid.users - 1;
+
+ guard(rcu)();
+ for_other_threads(current, t) {
+@@ -10636,12 +10640,15 @@ static bool sched_mm_cid_add_user(struct task_struct *t, struct mm_struct *mm)
+ return mm_update_max_cids(mm);
+ }
+
+-void sched_mm_cid_fork(struct task_struct *t)
++static void sched_mm_cid_fork(struct task_struct *t)
+ {
+ struct mm_struct *mm = t->mm;
+ bool percpu;
+
+- WARN_ON_ONCE(!mm || t->mm_cid.cid != MM_CID_UNSET);
++ if (!mm)
++ return;
++
++ WARN_ON_ONCE(t->mm_cid.cid != MM_CID_UNSET);
+
+ guard(mutex)(&mm->mm_cid.mutex);
+ scoped_guard(raw_spinlock_irq, &mm->mm_cid.lock) {
+@@ -10833,6 +10840,7 @@ void mm_init_cid(struct mm_struct *mm, struct task_struct *p)
+ }
+ #else /* CONFIG_SCHED_MM_CID */
+ static inline void mm_update_cpus_allowed(struct mm_struct *mm, const struct cpumask *affmsk) { }
++static inline void sched_mm_cid_fork(struct task_struct *t) { }
+ #endif /* !CONFIG_SCHED_MM_CID */
+
+ static DEFINE_PER_CPU(struct sched_change_ctx, sched_change_ctx);
+--
+2.51.0
+
--- /dev/null
+From 44bbf4781d379165568fe9e618f11ecd83f7a546 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Mar 2026 21:29:04 +0100
+Subject: sched/mmcid: Remove pointless preempt guard
+
+From: Thomas Gleixner <tglx@kernel.org>
+
+[ Upstream commit 7574ac6e49789ddee1b1be9b2afb42b4a1b4b1f4 ]
+
+This is a leftover from the early versions of this function where it could
+be invoked without mm::mm_cid::lock held.
+
+Remove it and add lockdep asserts instead.
+
+Fixes: 653fda7ae73d ("sched/mmcid: Switch over to the new mechanism")
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Tested-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260310202526.116363613@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/core.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 24d607c78f119..c80076fcd78f2 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -10632,6 +10632,8 @@ static void mm_cid_fixup_tasks_to_cpus(void)
+
+ static bool sched_mm_cid_add_user(struct task_struct *t, struct mm_struct *mm)
+ {
++ lockdep_assert_held(&mm->mm_cid.lock);
++
+ t->mm_cid.active = 1;
+ mm->mm_cid.users++;
+ return mm_update_max_cids(mm);
+@@ -10684,12 +10686,12 @@ static void sched_mm_cid_fork(struct task_struct *t)
+
+ static bool sched_mm_cid_remove_user(struct task_struct *t)
+ {
++ lockdep_assert_held(&t->mm->mm_cid.lock);
++
+ t->mm_cid.active = 0;
+- scoped_guard(preempt) {
+- /* Clear the transition bit */
+- t->mm_cid.cid = cid_from_transit_cid(t->mm_cid.cid);
+- mm_unset_cid_on_task(t);
+- }
++ /* Clear the transition bit */
++ t->mm_cid.cid = cid_from_transit_cid(t->mm_cid.cid);
++ mm_unset_cid_on_task(t);
+ t->mm->mm_cid.users--;
+ return mm_update_max_cids(t->mm);
+ }
+--
+2.51.0
+
--- /dev/null
+From 759717aaef23f60a28ead15ab487ddcf07dd0f87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Mar 2026 14:40:39 +0800
+Subject: scsi: hisi_sas: Fix NULL pointer exception during user_scan()
+
+From: Xingui Yang <yangxingui@huawei.com>
+
+[ Upstream commit 8ddc0c26916574395447ebf4cff684314f6873a9 ]
+
+user_scan() invokes updated sas_user_scan() for channel 0, and if
+successful, iteratively scans remaining channels (1 to shost->max_channel)
+via scsi_scan_host_selected() in commit 37c4e72b0651 ("scsi: Fix
+sas_user_scan() to handle wildcard and multi-channel scans"). However,
+hisi_sas supports only one channel, and the current value of max_channel is
+1. sas_user_scan() for channel 1 will trigger the following NULL pointer
+exception:
+
+[ 441.554662] Unable to handle kernel NULL pointer dereference at virtual address 00000000000008b0
+[ 441.554699] Mem abort info:
+[ 441.554710] ESR = 0x0000000096000004
+[ 441.554718] EC = 0x25: DABT (current EL), IL = 32 bits
+[ 441.554723] SET = 0, FnV = 0
+[ 441.554726] EA = 0, S1PTW = 0
+[ 441.554730] FSC = 0x04: level 0 translation fault
+[ 441.554735] Data abort info:
+[ 441.554737] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
+[ 441.554742] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
+[ 441.554747] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+[ 441.554752] user pgtable: 4k pages, 48-bit VAs, pgdp=00000828377a6000
+[ 441.554757] [00000000000008b0] pgd=0000000000000000, p4d=0000000000000000
+[ 441.554769] Internal error: Oops: 0000000096000004 [#1] SMP
+[ 441.629589] Modules linked in: arm_spe_pmu arm_smmuv3_pmu tpm_tis_spi hisi_uncore_sllc_pmu hisi_uncore_pa_pmu hisi_uncore_l3c_pmu hisi_uncore_hha_pmu hisi_uncore_ddrc_pmu hisi_uncore_cpa_pmu hns3_pmu hisi_ptt hisi_pcie_pmu tpm_tis_core spidev spi_hisi_sfc_v3xx hisi_uncore_pmu spi_dw_mmio fuse hclge hclge_common hisi_sec2 hisi_hpre hisi_zip hisi_qm hns3 hisi_sas_v3_hw sm3_ce sbsa_gwdt hnae3 hisi_sas_main uacce hisi_dma i2c_hisi dm_mirror dm_region_hash dm_log dm_mod
+[ 441.670819] CPU: 46 UID: 0 PID: 6994 Comm: bash Kdump: loaded Not tainted 7.0.0-rc2+ #84 PREEMPT
+[ 441.691327] pstate: 81400009 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
+[ 441.698277] pc : sas_find_dev_by_rphy+0x44/0x118
+[ 441.702896] lr : sas_find_dev_by_rphy+0x3c/0x118
+[ 441.707502] sp : ffff80009abbba40
+[ 441.710805] x29: ffff80009abbba40 x28: ffff082819a40008 x27: ffff082810c37c08
+[ 441.717930] x26: ffff082810c37c28 x25: ffff082819a40290 x24: ffff082810c37c00
+[ 441.725054] x23: 0000000000000000 x22: 0000000000000001 x21: ffff082819a40000
+[ 441.732179] x20: ffff082819a40290 x19: 0000000000000000 x18: 0000000000000020
+[ 441.739304] x17: 0000000000000000 x16: ffffb5dad6bda690 x15: 00000000ffffffff
+[ 441.746428] x14: ffff082814c3b26c x13: 00000000ffffffff x12: ffff082814c3b26a
+[ 441.753553] x11: 00000000000000c0 x10: 000000000000003a x9 : ffffb5dad5ea94f4
+[ 441.760678] x8 : 000000000000003a x7 : ffff80009abbbab0 x6 : 0000000000000030
+[ 441.767802] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
+[ 441.774926] x2 : ffff08280f35a300 x1 : ffffb5dad7127180 x0 : 0000000000000000
+[ 441.782053] Call trace:
+[ 441.784488] sas_find_dev_by_rphy+0x44/0x118 (P)
+[ 441.789095] sas_target_alloc+0x24/0xb0
+[ 441.792920] scsi_alloc_target+0x290/0x330
+[ 441.797010] __scsi_scan_target+0x88/0x258
+[ 441.801096] scsi_scan_channel+0x74/0xb8
+[ 441.805008] scsi_scan_host_selected+0x170/0x188
+[ 441.809615] sas_user_scan+0xfc/0x148
+[ 441.813267] store_scan+0x10c/0x180
+[ 441.816743] dev_attr_store+0x20/0x40
+[ 441.820398] sysfs_kf_write+0x84/0xa8
+[ 441.824054] kernfs_fop_write_iter+0x130/0x1c8
+[ 441.828487] vfs_write+0x2c0/0x370
+[ 441.831880] ksys_write+0x74/0x118
+[ 441.835271] __arm64_sys_write+0x24/0x38
+[ 441.839182] invoke_syscall+0x50/0x120
+[ 441.842919] el0_svc_common.constprop.0+0xc8/0xf0
+[ 441.847611] do_el0_svc+0x24/0x38
+[ 441.850913] el0_svc+0x38/0x158
+[ 441.854043] el0t_64_sync_handler+0xa0/0xe8
+[ 441.858214] el0t_64_sync+0x1ac/0x1b0
+[ 441.861865] Code: aa1303e0 97ff70a8 34ffff80 d10a4273 (f9445a75)
+[ 441.867946] ---[ end trace 0000000000000000 ]---
+
+Therefore, set max_channel to 0.
+
+Fixes: e21fe3a52692 ("scsi: hisi_sas: add initialisation for v3 pci-based controller")
+Signed-off-by: Xingui Yang <yangxingui@huawei.com>
+Signed-off-by: Yihang Li <liyihang9@huawei.com>
+Link: https://patch.msgid.link/20260305064039.4096775-1-liyihang9@huawei.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +-
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 30a9c66126513..c2b082f1252c3 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -2578,7 +2578,7 @@ int hisi_sas_probe(struct platform_device *pdev,
+ shost->transportt = hisi_sas_stt;
+ shost->max_id = HISI_SAS_MAX_DEVICES;
+ shost->max_lun = ~0;
+- shost->max_channel = 1;
++ shost->max_channel = 0;
+ shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN;
+ if (hisi_hba->hw->slot_index_alloc) {
+ shost->can_queue = HISI_SAS_MAX_COMMANDS;
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 2f9e01717ef38..f69efc6494b8e 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -4993,7 +4993,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ shost->transportt = hisi_sas_stt;
+ shost->max_id = HISI_SAS_MAX_DEVICES;
+ shost->max_lun = ~0;
+- shost->max_channel = 1;
++ shost->max_channel = 0;
+ shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN;
+ shost->can_queue = HISI_SAS_UNRESERVED_IPTT;
+ shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT;
+--
+2.51.0
+
--- /dev/null
+From 20de38ca93d783dda287fb818ee11630fea0a525 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 11:08:22 +0100
+Subject: scsi: qla2xxx: Completely fix fcport double free
+
+From: Vladimir Riabchun <ferr.lambarginio@gmail.com>
+
+[ Upstream commit c0b7da13a04bd70ef6070bfb9ea85f582294560a ]
+
+In qla24xx_els_dcmd_iocb() sp->free is set to qla2x00_els_dcmd_sp_free().
+When an error happens, this function is called by qla2x00_sp_release(),
+when kref_put() releases the first and the last reference.
+
+qla2x00_els_dcmd_sp_free() frees fcport by calling qla2x00_free_fcport().
+Doing it one more time after kref_put() is a bad idea.
+
+Fixes: 82f522ae0d97 ("scsi: qla2xxx: Fix double free of fcport")
+Fixes: 4895009c4bb7 ("scsi: qla2xxx: Prevent command send on chip reset")
+Signed-off-by: Vladimir Riabchun <ferr.lambarginio@gmail.com>
+Signed-off-by: Farhat Abbas <fabbas@cloudlinux.com>
+Link: https://patch.msgid.link/aYsDln9NFQQsPDgg@vova-pc
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_iocb.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
+index 3224044f17753..0de015de7eb59 100644
+--- a/drivers/scsi/qla2xxx/qla_iocb.c
++++ b/drivers/scsi/qla2xxx/qla_iocb.c
+@@ -2751,7 +2751,6 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
+ if (!elsio->u.els_logo.els_logo_pyld) {
+ /* ref: INIT */
+ kref_put(&sp->cmd_kref, qla2x00_sp_release);
+- qla2x00_free_fcport(fcport);
+ return QLA_FUNCTION_FAILED;
+ }
+
+@@ -2776,7 +2775,6 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
+ if (rval != QLA_SUCCESS) {
+ /* ref: INIT */
+ kref_put(&sp->cmd_kref, qla2x00_sp_release);
+- qla2x00_free_fcport(fcport);
+ return QLA_FUNCTION_FAILED;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From c7725982793d91ef11a541d604b9f1e9cc98c334 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 7 Mar 2026 11:51:28 +0800
+Subject: scsi: ufs: core: Fix SError in ufshcd_rtc_work() during UFS suspend
+
+From: Wang Shuaiwei <wangshuaiwei1@xiaomi.com>
+
+[ Upstream commit b0bd84c39289ef6a6c3827dd52c875659291970a ]
+
+In __ufshcd_wl_suspend(), cancel_delayed_work_sync() is called to cancel
+the UFS RTC work, but it is placed after ufshcd_vops_suspend(hba, pm_op,
+POST_CHANGE). This creates a race condition where ufshcd_rtc_work() can
+still be running while ufshcd_vops_suspend() is executing. When
+UFSHCD_CAP_CLK_GATING is not supported, the condition
+!hba->clk_gating.active_reqs is always true, causing ufshcd_update_rtc()
+to be executed. Since ufshcd_vops_suspend() typically performs clock
+gating operations, executing ufshcd_update_rtc() at that moment triggers
+an SError. The kernel panic trace is as follows:
+
+Kernel panic - not syncing: Asynchronous SError Interrupt
+Call trace:
+ dump_backtrace+0xec/0x128
+ show_stack+0x18/0x28
+ dump_stack_lvl+0x40/0xa0
+ dump_stack+0x18/0x24
+ panic+0x148/0x374
+ nmi_panic+0x3c/0x8c
+ arm64_serror_panic+0x64/0x8c
+ do_serror+0xc4/0xc8
+ el1h_64_error_handler+0x34/0x4c
+ el1h_64_error+0x68/0x6c
+ el1_interrupt+0x20/0x58
+ el1h_64_irq_handler+0x18/0x24
+ el1h_64_irq+0x68/0x6c
+ ktime_get+0xc4/0x12c
+ ufshcd_mcq_sq_stop+0x4c/0xec
+ ufshcd_mcq_sq_cleanup+0x64/0x1dc
+ ufshcd_clear_cmd+0x38/0x134
+ ufshcd_issue_dev_cmd+0x298/0x4d0
+ ufshcd_exec_dev_cmd+0x1a4/0x1c4
+ ufshcd_query_attr+0xbc/0x19c
+ ufshcd_rtc_work+0x10c/0x1c8
+ process_scheduled_works+0x1c4/0x45c
+ worker_thread+0x32c/0x3e8
+ kthread+0x120/0x1d8
+ ret_from_fork+0x10/0x20
+
+Fix this by moving cancel_delayed_work_sync() before the call to
+ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE), ensuring the UFS RTC work is
+fully completed or cancelled at that point.
+
+Cc: Bean Huo <beanhuo@iokpp.de>
+Fixes: 6bf999e0eb41 ("scsi: ufs: core: Add UFS RTC support")
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Wang Shuaiwei <wangshuaiwei1@xiaomi.com>
+Link: https://patch.msgid.link/20260307035128.3419687-1-wangshuaiwei1@xiaomi.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/core/ufshcd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
+index 2048ebc86590e..5038b8428fc30 100644
+--- a/drivers/ufs/core/ufshcd.c
++++ b/drivers/ufs/core/ufshcd.c
+@@ -10061,6 +10061,7 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
+ }
+
+ flush_work(&hba->eeh_work);
++ cancel_delayed_work_sync(&hba->ufs_rtc_update_work);
+
+ ret = ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE);
+ if (ret)
+@@ -10115,7 +10116,6 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
+ if (ret)
+ goto set_link_active;
+
+- cancel_delayed_work_sync(&hba->ufs_rtc_update_work);
+ goto out;
+
+ set_link_active:
+--
+2.51.0
+
revert-usb-gadget-f_ncm-align-net_device-lifecycle-with-bind-unbind.patch
revert-usb-gadget-u_ether-add-gether_opts-for-config-caching.patch
usb-gadget-f_ncm-fix-net_device-lifecycle-with-device_move.patch
+alsa-usb-audio-improve-focusrite-sample-rate-filteri.patch
+objtool-klp-fix-detection-of-corrupt-static-branch-c.patch
+objtool-fix-data-alignment-in-elf_add_data.patch
+objtool-fix-another-stack-overflow-in-validate_branc.patch
+irqchip-riscv-aplic-preserve-aplic-states-across-sus.patch
+irqchip-riscv-aplic-do-not-clear-acpi-dependencies-o.patch
+irqchip-riscv-aplic-register-syscore-operations-only.patch
+time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch
+sched-mmcid-prevent-cid-stalls-due-to-concurrent-for.patch
+sched-mmcid-handle-vfork-clone_vm-correctly.patch
+sched-mmcid-remove-pointless-preempt-guard.patch
+sched-mmcid-avoid-full-tasklist-walks.patch
+i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch
+powerpc-perf-check-that-current-mm-is-alive-before-g.patch
+scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch
+scsi-qla2xxx-completely-fix-fcport-double-free.patch
+scsi-hisi_sas-fix-null-pointer-exception-during-user.patch
--- /dev/null
+From 3d9f364df7dadaac18f32ea60836afd8ed7945e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Mar 2026 21:24:03 -0500
+Subject: time/jiffies: Mark jiffies_64_to_clock_t() notrace
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 755a648e78f12574482d4698d877375793867fa1 ]
+
+The trace_clock_jiffies() function that handles the "uptime" clock for
+tracing calls jiffies_64_to_clock_t(). This causes the function tracer to
+constantly recurse when the tracing clock is set to "uptime". Mark it
+notrace to prevent unnecessary recursion when using the "uptime" clock.
+
+Fixes: 58d4e21e50ff3 ("tracing: Fix wraparound problems in "uptime" trace clock")
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Link: https://patch.msgid.link/20260306212403.72270bb2@robin
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/time.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/time/time.c b/kernel/time/time.c
+index 0ba8e3c50d625..155cf7def9146 100644
+--- a/kernel/time/time.c
++++ b/kernel/time/time.c
+@@ -702,7 +702,7 @@ EXPORT_SYMBOL(clock_t_to_jiffies);
+ *
+ * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC)
+ */
+-u64 jiffies_64_to_clock_t(u64 x)
++notrace u64 jiffies_64_to_clock_t(u64 x)
+ {
+ #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
+ # if HZ < USER_HZ
+--
+2.51.0
+
--- /dev/null
+From d571c940d9021d45c44da3fd30f312acbe3f9f0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 14:00:48 +0800
+Subject: i3c: dw-i3c-master: Set SIR_REJECT in DAT on device attach and
+ reattach
+
+From: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
+
+[ Upstream commit f311a05784634febd299f03476b80f3f18489767 ]
+
+The DesignWare I3C master controller ACKs IBIs as soon as a valid
+Device Address Table (DAT) entry is present. This can create a race
+between device attachment (after DAA) and the point where the client
+driver enables IBIs via i3c_device_enable_ibi().
+
+Set DEV_ADDR_TABLE_SIR_REJECT in the DAT entry during
+attach_i3c_dev() and reattach_i3c_dev() so that IBIs are rejected
+by default. The bit is managed thereafter by the existing
+dw_i3c_master_set_sir_enabled() function, which clears it in
+enable_ibi() after ENEC is issued, and restores it in disable_ibi()
+after DISEC.
+
+Fixes: 1dd728f5d4d4 ("i3c: master: Add driver for Synopsys DesignWare IP")
+Signed-off-by: Adrian Ng Ho Yin <adrianhoyin.ng@altera.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/53f5b8cbdd8af789ec38b95b02873f32f9182dd6.1770962368.git.adrianhoyin.ng@altera.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i3c/master/dw-i3c-master.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
+index cee2805fccd0f..ccb521bcb73e3 100644
+--- a/drivers/i3c/master/dw-i3c-master.c
++++ b/drivers/i3c/master/dw-i3c-master.c
+@@ -941,7 +941,7 @@ static int dw_i3c_master_reattach_i3c_dev(struct i3c_dev_desc *dev,
+ master->free_pos &= ~BIT(pos);
+ }
+
+- writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr),
++ writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr) | DEV_ADDR_TABLE_SIR_REJECT,
+ master->regs +
+ DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
+
+@@ -970,7 +970,7 @@ static int dw_i3c_master_attach_i3c_dev(struct i3c_dev_desc *dev)
+ master->free_pos &= ~BIT(pos);
+ i3c_dev_set_master_data(dev, data);
+
+- writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr),
++ writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr) | DEV_ADDR_TABLE_SIR_REJECT,
+ master->regs +
+ DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
+
+--
+2.51.0
+
--- /dev/null
+From ea20d3e808eef3d31db19c43b9e59ac8fd21ddcd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Oct 2024 10:18:19 +0800
+Subject: scsi: hisi_sas: Add time interval between two H2D FIS following soft
+ reset spec
+
+From: Xingui Yang <yangxingui@huawei.com>
+
+[ Upstream commit 3c62791322e42d1afd65acfdb5b3a371bde21ede ]
+
+Spec says at least 5us between two H2D FIS when do soft reset, but be
+generous and sleep for about 1ms.
+
+Signed-off-by: Xingui Yang <yangxingui@huawei.com>
+Link: https://lore.kernel.org/r/20241008021822.2617339-11-liyihang9@huawei.com
+Reviewed-by: Yihang Li <liyihang9@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: 8ddc0c269165 ("scsi: hisi_sas: Fix NULL pointer exception during user_scan()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 3ad58250bf6b2..17189703454a2 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1340,6 +1340,7 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device)
+ }
+
+ if (rc == TMF_RESP_FUNC_COMPLETE) {
++ usleep_range(900, 1000);
+ ata_for_each_link(link, ap, EDGE) {
+ int pmp = sata_srst_pmp(link);
+
+--
+2.51.0
+
--- /dev/null
+From a5ef8fb404ef6cae13e0f16e704e1d4442860bfe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Mar 2026 14:40:39 +0800
+Subject: scsi: hisi_sas: Fix NULL pointer exception during user_scan()
+
+From: Xingui Yang <yangxingui@huawei.com>
+
+[ Upstream commit 8ddc0c26916574395447ebf4cff684314f6873a9 ]
+
+user_scan() invokes updated sas_user_scan() for channel 0, and if
+successful, iteratively scans remaining channels (1 to shost->max_channel)
+via scsi_scan_host_selected() in commit 37c4e72b0651 ("scsi: Fix
+sas_user_scan() to handle wildcard and multi-channel scans"). However,
+hisi_sas supports only one channel, and the current value of max_channel is
+1. sas_user_scan() for channel 1 will trigger the following NULL pointer
+exception:
+
+[ 441.554662] Unable to handle kernel NULL pointer dereference at virtual address 00000000000008b0
+[ 441.554699] Mem abort info:
+[ 441.554710] ESR = 0x0000000096000004
+[ 441.554718] EC = 0x25: DABT (current EL), IL = 32 bits
+[ 441.554723] SET = 0, FnV = 0
+[ 441.554726] EA = 0, S1PTW = 0
+[ 441.554730] FSC = 0x04: level 0 translation fault
+[ 441.554735] Data abort info:
+[ 441.554737] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
+[ 441.554742] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
+[ 441.554747] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+[ 441.554752] user pgtable: 4k pages, 48-bit VAs, pgdp=00000828377a6000
+[ 441.554757] [00000000000008b0] pgd=0000000000000000, p4d=0000000000000000
+[ 441.554769] Internal error: Oops: 0000000096000004 [#1] SMP
+[ 441.629589] Modules linked in: arm_spe_pmu arm_smmuv3_pmu tpm_tis_spi hisi_uncore_sllc_pmu hisi_uncore_pa_pmu hisi_uncore_l3c_pmu hisi_uncore_hha_pmu hisi_uncore_ddrc_pmu hisi_uncore_cpa_pmu hns3_pmu hisi_ptt hisi_pcie_pmu tpm_tis_core spidev spi_hisi_sfc_v3xx hisi_uncore_pmu spi_dw_mmio fuse hclge hclge_common hisi_sec2 hisi_hpre hisi_zip hisi_qm hns3 hisi_sas_v3_hw sm3_ce sbsa_gwdt hnae3 hisi_sas_main uacce hisi_dma i2c_hisi dm_mirror dm_region_hash dm_log dm_mod
+[ 441.670819] CPU: 46 UID: 0 PID: 6994 Comm: bash Kdump: loaded Not tainted 7.0.0-rc2+ #84 PREEMPT
+[ 441.691327] pstate: 81400009 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
+[ 441.698277] pc : sas_find_dev_by_rphy+0x44/0x118
+[ 441.702896] lr : sas_find_dev_by_rphy+0x3c/0x118
+[ 441.707502] sp : ffff80009abbba40
+[ 441.710805] x29: ffff80009abbba40 x28: ffff082819a40008 x27: ffff082810c37c08
+[ 441.717930] x26: ffff082810c37c28 x25: ffff082819a40290 x24: ffff082810c37c00
+[ 441.725054] x23: 0000000000000000 x22: 0000000000000001 x21: ffff082819a40000
+[ 441.732179] x20: ffff082819a40290 x19: 0000000000000000 x18: 0000000000000020
+[ 441.739304] x17: 0000000000000000 x16: ffffb5dad6bda690 x15: 00000000ffffffff
+[ 441.746428] x14: ffff082814c3b26c x13: 00000000ffffffff x12: ffff082814c3b26a
+[ 441.753553] x11: 00000000000000c0 x10: 000000000000003a x9 : ffffb5dad5ea94f4
+[ 441.760678] x8 : 000000000000003a x7 : ffff80009abbbab0 x6 : 0000000000000030
+[ 441.767802] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
+[ 441.774926] x2 : ffff08280f35a300 x1 : ffffb5dad7127180 x0 : 0000000000000000
+[ 441.782053] Call trace:
+[ 441.784488] sas_find_dev_by_rphy+0x44/0x118 (P)
+[ 441.789095] sas_target_alloc+0x24/0xb0
+[ 441.792920] scsi_alloc_target+0x290/0x330
+[ 441.797010] __scsi_scan_target+0x88/0x258
+[ 441.801096] scsi_scan_channel+0x74/0xb8
+[ 441.805008] scsi_scan_host_selected+0x170/0x188
+[ 441.809615] sas_user_scan+0xfc/0x148
+[ 441.813267] store_scan+0x10c/0x180
+[ 441.816743] dev_attr_store+0x20/0x40
+[ 441.820398] sysfs_kf_write+0x84/0xa8
+[ 441.824054] kernfs_fop_write_iter+0x130/0x1c8
+[ 441.828487] vfs_write+0x2c0/0x370
+[ 441.831880] ksys_write+0x74/0x118
+[ 441.835271] __arm64_sys_write+0x24/0x38
+[ 441.839182] invoke_syscall+0x50/0x120
+[ 441.842919] el0_svc_common.constprop.0+0xc8/0xf0
+[ 441.847611] do_el0_svc+0x24/0x38
+[ 441.850913] el0_svc+0x38/0x158
+[ 441.854043] el0t_64_sync_handler+0xa0/0xe8
+[ 441.858214] el0t_64_sync+0x1ac/0x1b0
+[ 441.861865] Code: aa1303e0 97ff70a8 34ffff80 d10a4273 (f9445a75)
+[ 441.867946] ---[ end trace 0000000000000000 ]---
+
+Therefore, set max_channel to 0.
+
+Fixes: e21fe3a52692 ("scsi: hisi_sas: add initialisation for v3 pci-based controller")
+Signed-off-by: Xingui Yang <yangxingui@huawei.com>
+Signed-off-by: Yihang Li <liyihang9@huawei.com>
+Link: https://patch.msgid.link/20260305064039.4096775-1-liyihang9@huawei.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +-
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 0a52e7ba504cb..578f7c6117d3d 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -2537,7 +2537,7 @@ int hisi_sas_probe(struct platform_device *pdev,
+ shost->transportt = hisi_sas_stt;
+ shost->max_id = HISI_SAS_MAX_DEVICES;
+ shost->max_lun = ~0;
+- shost->max_channel = 1;
++ shost->max_channel = 0;
+ shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN;
+ if (hisi_hba->hw->slot_index_alloc) {
+ shost->can_queue = HISI_SAS_MAX_COMMANDS;
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index e8f5a8023a1af..7075dde4584db 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -5087,7 +5087,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ shost->transportt = hisi_sas_stt;
+ shost->max_id = HISI_SAS_MAX_DEVICES;
+ shost->max_lun = ~0;
+- shost->max_channel = 1;
++ shost->max_channel = 0;
+ shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN;
+ shost->can_queue = HISI_SAS_UNRESERVED_IPTT;
+ shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT;
+--
+2.51.0
+
--- /dev/null
+From 4f804a36ff98dc07f27a806ca9cab80f706adcbe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Apr 2025 16:08:42 +0800
+Subject: scsi: hisi_sas: Use macro instead of magic number
+
+From: Yihang Li <liyihang9@huawei.com>
+
+[ Upstream commit 4ca7fe99fc8485fcd04b367f37dc7a48f1355419 ]
+
+The hisi_sas driver has a large number of magic numbers which makes for
+unfriendly code reading. Use macro definitions instead.
+
+Signed-off-by: Yihang Li <liyihang9@huawei.com>
+Link: https://lore.kernel.org/r/20250414080845.1220997-2-liyihang9@huawei.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: 8ddc0c269165 ("scsi: hisi_sas: Fix NULL pointer exception during user_scan()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 43 +++--
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 41 +++--
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 244 ++++++++++++++++---------
+ 3 files changed, 213 insertions(+), 115 deletions(-)
+
+diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
+index 1e4550156b735..4e905c9bec28e 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -47,6 +47,13 @@
+ #define HISI_SAS_IOST_ITCT_CACHE_DW_SZ 10
+ #define HISI_SAS_FIFO_DATA_DW_SIZE 32
+
++#define HISI_SAS_REG_MEM_SIZE 4
++#define HISI_SAS_MAX_CDB_LEN 16
++#define HISI_SAS_BLK_QUEUE_DEPTH 64
++
++#define BYTE_TO_DW 4
++#define BYTE_TO_DDW 8
++
+ #define HISI_SAS_STATUS_BUF_SZ (sizeof(struct hisi_sas_status_buffer))
+ #define HISI_SAS_COMMAND_TABLE_SZ (sizeof(union hisi_sas_command_table))
+
+@@ -93,6 +100,8 @@
+
+ #define HISI_SAS_WAIT_PHYUP_TIMEOUT (30 * HZ)
+ #define HISI_SAS_CLEAR_ITCT_TIMEOUT (20 * HZ)
++#define HISI_SAS_DELAY_FOR_PHY_DISABLE 100
++#define NAME_BUF_SIZE 256
+
+ struct hisi_hba;
+
+@@ -168,6 +177,8 @@ struct hisi_sas_debugfs_fifo {
+ u32 rd_data[HISI_SAS_FIFO_DATA_DW_SIZE];
+ };
+
++#define FRAME_RCVD_BUF 32
++#define SAS_PHY_RESV_SIZE 2
+ struct hisi_sas_phy {
+ struct work_struct works[HISI_PHYES_NUM];
+ struct hisi_hba *hisi_hba;
+@@ -179,10 +190,10 @@ struct hisi_sas_phy {
+ spinlock_t lock;
+ u64 port_id; /* from hw */
+ u64 frame_rcvd_size;
+- u8 frame_rcvd[32];
++ u8 frame_rcvd[FRAME_RCVD_BUF];
+ u8 phy_attached;
+ u8 in_reset;
+- u8 reserved[2];
++ u8 reserved[SAS_PHY_RESV_SIZE];
+ u32 phy_type;
+ u32 code_violation_err_count;
+ enum sas_linkrate minimum_linkrate;
+@@ -349,6 +360,7 @@ struct hisi_sas_hw {
+ };
+
+ #define HISI_SAS_MAX_DEBUGFS_DUMP (50)
++#define HISI_SAS_DEFAULT_DEBUGFS_DUMP 1
+
+ struct hisi_sas_debugfs_cq {
+ struct hisi_sas_cq *cq;
+@@ -528,12 +540,13 @@ struct hisi_sas_cmd_hdr {
+ __le64 dif_prd_table_addr;
+ };
+
++#define ITCT_RESV_DDW 12
+ struct hisi_sas_itct {
+ __le64 qw0;
+ __le64 sas_addr;
+ __le64 qw2;
+ __le64 qw3;
+- __le64 qw4_15[12];
++ __le64 qw4_15[ITCT_RESV_DDW];
+ };
+
+ struct hisi_sas_iost {
+@@ -543,22 +556,26 @@ struct hisi_sas_iost {
+ __le64 qw3;
+ };
+
++#define ERROR_RECORD_BUF_DW 4
+ struct hisi_sas_err_record {
+- u32 data[4];
++ u32 data[ERROR_RECORD_BUF_DW];
+ };
+
++#define FIS_RESV_DW 3
+ struct hisi_sas_initial_fis {
+ struct hisi_sas_err_record err_record;
+ struct dev_to_host_fis fis;
+- u32 rsvd[3];
++ u32 rsvd[FIS_RESV_DW];
+ };
+
++#define BREAKPOINT_DATA_SIZE 128
+ struct hisi_sas_breakpoint {
+- u8 data[128];
++ u8 data[BREAKPOINT_DATA_SIZE];
+ };
+
++#define BREAKPOINT_TAG_NUM 32
+ struct hisi_sas_sata_breakpoint {
+- struct hisi_sas_breakpoint tag[32];
++ struct hisi_sas_breakpoint tag[BREAKPOINT_TAG_NUM];
+ };
+
+ struct hisi_sas_sge {
+@@ -569,13 +586,15 @@ struct hisi_sas_sge {
+ __le32 data_off;
+ };
+
++#define SMP_CMD_TABLE_SIZE 44
+ struct hisi_sas_command_table_smp {
+- u8 bytes[44];
++ u8 bytes[SMP_CMD_TABLE_SIZE];
+ };
+
++#define DUMMY_BUF_SIZE 12
+ struct hisi_sas_command_table_stp {
+ struct host_to_dev_fis command_fis;
+- u8 dummy[12];
++ u8 dummy[DUMMY_BUF_SIZE];
+ u8 atapi_cdb[ATAPI_CDB_LEN];
+ };
+
+@@ -589,12 +608,13 @@ struct hisi_sas_sge_dif_page {
+ struct hisi_sas_sge sge[HISI_SAS_SGE_DIF_PAGE_CNT];
+ } __aligned(16);
+
++#define PROT_BUF_SIZE 7
+ struct hisi_sas_command_table_ssp {
+ struct ssp_frame_hdr hdr;
+ union {
+ struct {
+ struct ssp_command_iu task;
+- u32 prot[7];
++ u32 prot[PROT_BUF_SIZE];
+ };
+ struct ssp_tmf_iu ssp_task;
+ struct xfer_rdy_iu xfer_rdy;
+@@ -608,9 +628,10 @@ union hisi_sas_command_table {
+ struct hisi_sas_command_table_stp stp;
+ } __aligned(16);
+
++#define IU_BUF_SIZE 1024
+ struct hisi_sas_status_buffer {
+ struct hisi_sas_err_record err;
+- u8 iu[1024];
++ u8 iu[IU_BUF_SIZE];
+ } __aligned(16);
+
+ struct hisi_sas_slot_buf_table {
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 17189703454a2..0a52e7ba504cb 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -7,6 +7,16 @@
+ #include "hisi_sas.h"
+ #define DRV_NAME "hisi_sas"
+
++#define LINK_RATE_BIT_MASK 2
++#define FIS_BUF_SIZE 20
++#define WAIT_CMD_COMPLETE_DELAY 100
++#define WAIT_CMD_COMPLETE_TMROUT 5000
++#define DELAY_FOR_LINK_READY 2000
++#define BLK_CNT_OPTIMIZE_MARK 64
++#define HZ_TO_MHZ 1000000
++#define DELAY_FOR_SOFTRESET_MAX 1000
++#define DELAY_FOR_SOFTRESET_MIN 900
++
+ #define DEV_IS_GONE(dev) \
+ ((!dev) || (dev->dev_type == SAS_PHY_UNUSED))
+
+@@ -127,7 +137,7 @@ u8 hisi_sas_get_prog_phy_linkrate_mask(enum sas_linkrate max)
+
+ max -= SAS_LINK_RATE_1_5_GBPS;
+ for (i = 0; i <= max; i++)
+- rate |= 1 << (i * 2);
++ rate |= 1 << (i * LINK_RATE_BIT_MASK);
+ return rate;
+ }
+ EXPORT_SYMBOL_GPL(hisi_sas_get_prog_phy_linkrate_mask);
+@@ -876,7 +886,7 @@ int hisi_sas_slave_configure(struct scsi_device *sdev)
+ if (ret)
+ return ret;
+ if (!dev_is_sata(dev))
+- sas_change_queue_depth(sdev, 64);
++ sas_change_queue_depth(sdev, HISI_SAS_BLK_QUEUE_DEPTH);
+
+ return 0;
+ }
+@@ -1238,7 +1248,7 @@ static int hisi_sas_phy_set_linkrate(struct hisi_hba *hisi_hba, int phy_no,
+ sas_phy->phy->minimum_linkrate = min;
+
+ hisi_sas_phy_enable(hisi_hba, phy_no, 0);
+- msleep(100);
++ msleep(HISI_SAS_DELAY_FOR_PHY_DISABLE);
+ hisi_hba->hw->phy_set_linkrate(hisi_hba, phy_no, &_r);
+ hisi_sas_phy_enable(hisi_hba, phy_no, 1);
+
+@@ -1268,7 +1278,7 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func,
+
+ case PHY_FUNC_LINK_RESET:
+ hisi_sas_phy_enable(hisi_hba, phy_no, 0);
+- msleep(100);
++ msleep(HISI_SAS_DELAY_FOR_PHY_DISABLE);
+ hisi_sas_phy_enable(hisi_hba, phy_no, 1);
+ break;
+
+@@ -1323,7 +1333,7 @@ static void hisi_sas_fill_ata_reset_cmd(struct ata_device *dev,
+
+ static int hisi_sas_softreset_ata_disk(struct domain_device *device)
+ {
+- u8 fis[20] = {0};
++ u8 fis[FIS_BUF_SIZE] = {0};
+ struct ata_port *ap = device->sata_dev.ap;
+ struct ata_link *link;
+ int rc = TMF_RESP_FUNC_FAILED;
+@@ -1340,7 +1350,7 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device)
+ }
+
+ if (rc == TMF_RESP_FUNC_COMPLETE) {
+- usleep_range(900, 1000);
++ usleep_range(DELAY_FOR_SOFTRESET_MIN, DELAY_FOR_SOFTRESET_MAX);
+ ata_for_each_link(link, ap, EDGE) {
+ int pmp = sata_srst_pmp(link);
+
+@@ -1459,7 +1469,7 @@ static void hisi_sas_send_ata_reset_each_phy(struct hisi_hba *hisi_hba,
+ struct device *dev = hisi_hba->dev;
+ int rc = TMF_RESP_FUNC_FAILED;
+ struct ata_link *link;
+- u8 fis[20] = {0};
++ u8 fis[FIS_BUF_SIZE] = {0};
+ int i;
+
+ for (i = 0; i < hisi_hba->n_phy; i++) {
+@@ -1526,7 +1536,9 @@ void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba)
+ hisi_hba->phy_state = hisi_hba->hw->get_phys_state(hisi_hba);
+
+ scsi_block_requests(shost);
+- hisi_hba->hw->wait_cmds_complete_timeout(hisi_hba, 100, 5000);
++ hisi_hba->hw->wait_cmds_complete_timeout(hisi_hba,
++ WAIT_CMD_COMPLETE_DELAY,
++ WAIT_CMD_COMPLETE_TMROUT);
+
+ del_timer_sync(&hisi_hba->timer);
+
+@@ -1822,7 +1834,7 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device)
+ rc = ata_wait_after_reset(link, jiffies + HISI_SAS_WAIT_PHYUP_TIMEOUT,
+ smp_ata_check_ready_type);
+ } else {
+- msleep(2000);
++ msleep(DELAY_FOR_LINK_READY);
+ }
+
+ return rc;
+@@ -2237,12 +2249,14 @@ int hisi_sas_alloc(struct hisi_hba *hisi_hba)
+ goto err_out;
+
+ /* roundup to avoid overly large block size */
+- max_command_entries_ru = roundup(max_command_entries, 64);
++ max_command_entries_ru = roundup(max_command_entries,
++ BLK_CNT_OPTIMIZE_MARK);
+ if (hisi_hba->prot_mask & HISI_SAS_DIX_PROT_MASK)
+ sz_slot_buf_ru = sizeof(struct hisi_sas_slot_dif_buf_table);
+ else
+ sz_slot_buf_ru = sizeof(struct hisi_sas_slot_buf_table);
+- sz_slot_buf_ru = roundup(sz_slot_buf_ru, 64);
++
++ sz_slot_buf_ru = roundup(sz_slot_buf_ru, BLK_CNT_OPTIMIZE_MARK);
+ s = max(lcm(max_command_entries_ru, sz_slot_buf_ru), PAGE_SIZE);
+ blk_cnt = (max_command_entries_ru * sz_slot_buf_ru) / s;
+ slots_per_blk = s / sz_slot_buf_ru;
+@@ -2406,7 +2420,8 @@ int hisi_sas_get_fw_info(struct hisi_hba *hisi_hba)
+ if (IS_ERR(refclk))
+ dev_dbg(dev, "no ref clk property\n");
+ else
+- hisi_hba->refclk_frequency_mhz = clk_get_rate(refclk) / 1000000;
++ hisi_hba->refclk_frequency_mhz = clk_get_rate(refclk) /
++ HZ_TO_MHZ;
+
+ if (device_property_read_u32(dev, "phy-count", &hisi_hba->n_phy)) {
+ dev_err(dev, "could not get property phy-count\n");
+@@ -2523,7 +2538,7 @@ int hisi_sas_probe(struct platform_device *pdev,
+ shost->max_id = HISI_SAS_MAX_DEVICES;
+ shost->max_lun = ~0;
+ shost->max_channel = 1;
+- shost->max_cmd_len = 16;
++ shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN;
+ if (hisi_hba->hw->slot_index_alloc) {
+ shost->can_queue = HISI_SAS_MAX_COMMANDS;
+ shost->cmd_per_lun = HISI_SAS_MAX_COMMANDS;
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+index 596b5426d9953..e8f5a8023a1af 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -465,6 +465,12 @@
+ #define ITCT_HDR_RTOLT_OFF 48
+ #define ITCT_HDR_RTOLT_MSK (0xffffULL << ITCT_HDR_RTOLT_OFF)
+
++/*debugfs*/
++#define TWO_PARA_PER_LINE 2
++#define FOUR_PARA_PER_LINE 4
++#define DUMP_BUF_SIZE 8
++#define BIST_BUF_SIZE 16
++
+ struct hisi_sas_protect_iu_v3_hw {
+ u32 dw0;
+ u32 lbrtcv;
+@@ -535,6 +541,43 @@ struct hisi_sas_err_record_v3 {
+
+ #define BASE_VECTORS_V3_HW 16
+ #define MIN_AFFINE_VECTORS_V3_HW (BASE_VECTORS_V3_HW + 1)
++#define IRQ_PHY_UP_DOWN_INDEX 1
++#define IRQ_CHL_INDEX 2
++#define IRQ_AXI_INDEX 11
++
++#define DELAY_FOR_RESET_HW 100
++#define HDR_SG_MOD 0x2
++#define LUN_SIZE 8
++#define ATTR_PRIO_REGION 9
++#define CDB_REGION 12
++#define PRIO_OFF 3
++#define TMF_REGION 10
++#define TAG_MSB 12
++#define TAG_LSB 13
++#define SMP_FRAME_TYPE 2
++#define SMP_CRC_SIZE 4
++#define HDR_TAG_OFF 3
++#define HOST_NO_OFF 6
++#define PHY_NO_OFF 7
++#define IDENTIFY_REG_READ 6
++#define LINK_RESET_TIMEOUT_OFF 4
++#define DECIMALISM_FLAG 10
++#define WAIT_RETRY 100
++#define WAIT_TMROUT 5000
++
++#define ID_DWORD0_INDEX 0
++#define ID_DWORD1_INDEX 1
++#define ID_DWORD2_INDEX 2
++#define ID_DWORD3_INDEX 3
++#define ID_DWORD4_INDEX 4
++#define ID_DWORD5_INDEX 5
++#define TICKS_BIT_INDEX 24
++#define COUNT_BIT_INDEX 8
++
++#define PORT_REG_LENGTH 0x100
++#define GLOBAL_REG_LENGTH 0x800
++#define AXI_REG_LENGTH 0x61
++#define RAS_REG_LENGTH 0x10
+
+ #define CHNL_INT_STS_MSK 0xeeeeeeee
+ #define CHNL_INT_STS_PHY_MSK 0xe
+@@ -807,17 +850,17 @@ static void config_id_frame_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
+ identify_buffer = (u32 *)(&identify_frame);
+
+ hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD0,
+- __swab32(identify_buffer[0]));
++ __swab32(identify_buffer[ID_DWORD0_INDEX]));
+ hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD1,
+- __swab32(identify_buffer[1]));
++ __swab32(identify_buffer[ID_DWORD1_INDEX]));
+ hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD2,
+- __swab32(identify_buffer[2]));
++ __swab32(identify_buffer[ID_DWORD2_INDEX]));
+ hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD3,
+- __swab32(identify_buffer[3]));
++ __swab32(identify_buffer[ID_DWORD3_INDEX]));
+ hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD4,
+- __swab32(identify_buffer[4]));
++ __swab32(identify_buffer[ID_DWORD4_INDEX]));
+ hisi_sas_phy_write32(hisi_hba, phy_no, TX_ID_DWORD5,
+- __swab32(identify_buffer[5]));
++ __swab32(identify_buffer[ID_DWORD5_INDEX]));
+ }
+
+ static void setup_itct_v3_hw(struct hisi_hba *hisi_hba,
+@@ -937,7 +980,7 @@ static int reset_hw_v3_hw(struct hisi_hba *hisi_hba)
+
+ /* Disable all of the PHYs */
+ hisi_sas_stop_phys(hisi_hba);
+- udelay(50);
++ udelay(HISI_SAS_DELAY_FOR_PHY_DISABLE);
+
+ /* Ensure axi bus idle */
+ ret = hisi_sas_read32_poll_timeout(AXI_CFG, val, !val,
+@@ -977,7 +1020,7 @@ static int hw_init_v3_hw(struct hisi_hba *hisi_hba)
+ return rc;
+ }
+
+- msleep(100);
++ msleep(DELAY_FOR_RESET_HW);
+ init_reg_v3_hw(hisi_hba);
+
+ if (guid_parse("D5918B4B-37AE-4E10-A99F-E5E8A6EF4C1F", &guid)) {
+@@ -1026,7 +1069,7 @@ static void disable_phy_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
+ cfg &= ~PHY_CFG_ENA_MSK;
+ hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg);
+
+- mdelay(50);
++ mdelay(HISI_SAS_DELAY_FOR_PHY_DISABLE);
+
+ state = hisi_sas_read32(hisi_hba, PHY_STATE);
+ if (state & BIT(phy_no)) {
+@@ -1062,7 +1105,7 @@ static void phy_hard_reset_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
+ hisi_sas_phy_write32(hisi_hba, phy_no, TXID_AUTO,
+ txid_auto | TX_HARDRST_MSK);
+ }
+- msleep(100);
++ msleep(HISI_SAS_DELAY_FOR_PHY_DISABLE);
+ hisi_sas_phy_enable(hisi_hba, phy_no, 1);
+ }
+
+@@ -1107,7 +1150,8 @@ static int get_wideport_bitmap_v3_hw(struct hisi_hba *hisi_hba, int port_id)
+
+ for (i = 0; i < hisi_hba->n_phy; i++)
+ if (phy_state & BIT(i))
+- if (((phy_port_num_ma >> (i * 4)) & 0xf) == port_id)
++ if (((phy_port_num_ma >> (i * HISI_SAS_REG_MEM_SIZE)) & 0xf) ==
++ port_id)
+ bitmap |= BIT(i);
+
+ return bitmap;
+@@ -1305,9 +1349,9 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
+ dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF;
+
+ dw2 = (((sizeof(struct ssp_command_iu) + sizeof(struct ssp_frame_hdr)
+- + 3) / 4) << CMD_HDR_CFL_OFF) |
+- ((HISI_SAS_MAX_SSP_RESP_SZ / 4) << CMD_HDR_MRFL_OFF) |
+- (2 << CMD_HDR_SG_MOD_OFF);
++ + 3) / BYTE_TO_DW) << CMD_HDR_CFL_OFF) |
++ ((HISI_SAS_MAX_SSP_RESP_SZ / BYTE_TO_DW) << CMD_HDR_MRFL_OFF) |
++ (HDR_SG_MOD << CMD_HDR_SG_MOD_OFF);
+ hdr->dw2 = cpu_to_le32(dw2);
+ hdr->transfer_tags = cpu_to_le32(slot->idx);
+
+@@ -1327,18 +1371,19 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
+ buf_cmd = hisi_sas_cmd_hdr_addr_mem(slot) +
+ sizeof(struct ssp_frame_hdr);
+
+- memcpy(buf_cmd, &task->ssp_task.LUN, 8);
++ memcpy(buf_cmd, &task->ssp_task.LUN, LUN_SIZE);
+ if (!tmf) {
+- buf_cmd[9] = ssp_task->task_attr;
+- memcpy(buf_cmd + 12, scsi_cmnd->cmnd, scsi_cmnd->cmd_len);
++ buf_cmd[ATTR_PRIO_REGION] = ssp_task->task_attr;
++ memcpy(buf_cmd + CDB_REGION, scsi_cmnd->cmnd,
++ scsi_cmnd->cmd_len);
+ } else {
+- buf_cmd[10] = tmf->tmf;
++ buf_cmd[TMF_REGION] = tmf->tmf;
+ switch (tmf->tmf) {
+ case TMF_ABORT_TASK:
+ case TMF_QUERY_TASK:
+- buf_cmd[12] =
++ buf_cmd[TAG_MSB] =
+ (tmf->tag_of_task_to_be_managed >> 8) & 0xff;
+- buf_cmd[13] =
++ buf_cmd[TAG_LSB] =
+ tmf->tag_of_task_to_be_managed & 0xff;
+ break;
+ default:
+@@ -1371,7 +1416,8 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
+ unsigned int interval = scsi_prot_interval(scsi_cmnd);
+ unsigned int ilog2_interval = ilog2(interval);
+
+- len = (task->total_xfer_len >> ilog2_interval) * 8;
++ len = (task->total_xfer_len >> ilog2_interval) *
++ BYTE_TO_DDW;
+ }
+ }
+
+@@ -1391,6 +1437,7 @@ static void prep_smp_v3_hw(struct hisi_hba *hisi_hba,
+ struct hisi_sas_device *sas_dev = device->lldd_dev;
+ dma_addr_t req_dma_addr;
+ unsigned int req_len;
++ u32 cfl;
+
+ /* req */
+ sg_req = &task->smp_task.smp_req;
+@@ -1401,7 +1448,7 @@ static void prep_smp_v3_hw(struct hisi_hba *hisi_hba,
+ /* dw0 */
+ hdr->dw0 = cpu_to_le32((port->id << CMD_HDR_PORT_OFF) |
+ (1 << CMD_HDR_PRIORITY_OFF) | /* high pri */
+- (2 << CMD_HDR_CMD_OFF)); /* smp */
++ (SMP_FRAME_TYPE << CMD_HDR_CMD_OFF)); /* smp */
+
+ /* map itct entry */
+ hdr->dw1 = cpu_to_le32((sas_dev->device_id << CMD_HDR_DEV_ID_OFF) |
+@@ -1409,8 +1456,9 @@ static void prep_smp_v3_hw(struct hisi_hba *hisi_hba,
+ (DIR_NO_DATA << CMD_HDR_DIR_OFF));
+
+ /* dw2 */
+- hdr->dw2 = cpu_to_le32((((req_len - 4) / 4) << CMD_HDR_CFL_OFF) |
+- (HISI_SAS_MAX_SMP_RESP_SZ / 4 <<
++ cfl = (req_len - SMP_CRC_SIZE) / BYTE_TO_DW;
++ hdr->dw2 = cpu_to_le32((cfl << CMD_HDR_CFL_OFF) |
++ (HISI_SAS_MAX_SMP_RESP_SZ / BYTE_TO_DW <<
+ CMD_HDR_MRFL_OFF));
+
+ hdr->transfer_tags = cpu_to_le32(slot->idx << CMD_HDR_IPTT_OFF);
+@@ -1477,12 +1525,13 @@ static void prep_ata_v3_hw(struct hisi_hba *hisi_hba,
+ struct ata_queued_cmd *qc = task->uldd_task;
+
+ hdr_tag = qc->tag;
+- task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3);
++ task->ata_task.fis.sector_count |=
++ (u8)(hdr_tag << HDR_TAG_OFF);
+ dw2 |= hdr_tag << CMD_HDR_NCQ_TAG_OFF;
+ }
+
+- dw2 |= (HISI_SAS_MAX_STP_RESP_SZ / 4) << CMD_HDR_CFL_OFF |
+- 2 << CMD_HDR_SG_MOD_OFF;
++ dw2 |= (HISI_SAS_MAX_STP_RESP_SZ / BYTE_TO_DW) << CMD_HDR_CFL_OFF |
++ HDR_SG_MOD << CMD_HDR_SG_MOD_OFF;
+ hdr->dw2 = cpu_to_le32(dw2);
+
+ /* dw3 */
+@@ -1542,9 +1591,9 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+ hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1);
+
+ port_id = hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA);
+- port_id = (port_id >> (4 * phy_no)) & 0xf;
++ port_id = (port_id >> (HISI_SAS_REG_MEM_SIZE * phy_no)) & 0xf;
+ link_rate = hisi_sas_read32(hisi_hba, PHY_CONN_RATE);
+- link_rate = (link_rate >> (phy_no * 4)) & 0xf;
++ link_rate = (link_rate >> (phy_no * HISI_SAS_REG_MEM_SIZE)) & 0xf;
+
+ if (port_id == 0xf) {
+ dev_err(dev, "phyup: phy%d invalid portid\n", phy_no);
+@@ -1577,8 +1626,8 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+
+ sas_phy->oob_mode = SATA_OOB_MODE;
+ attached_sas_addr[0] = 0x50;
+- attached_sas_addr[6] = shost->host_no;
+- attached_sas_addr[7] = phy_no;
++ attached_sas_addr[HOST_NO_OFF] = shost->host_no;
++ attached_sas_addr[PHY_NO_OFF] = phy_no;
+ memcpy(sas_phy->attached_sas_addr,
+ attached_sas_addr,
+ SAS_ADDR_SIZE);
+@@ -1594,7 +1643,7 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+ (struct sas_identify_frame *)frame_rcvd;
+
+ dev_info(dev, "phyup: phy%d link_rate=%d\n", phy_no, link_rate);
+- for (i = 0; i < 6; i++) {
++ for (i = 0; i < IDENTIFY_REG_READ; i++) {
+ u32 idaf = hisi_sas_phy_read32(hisi_hba, phy_no,
+ RX_IDAF_DWORD0 + (i * 4));
+ frame_rcvd[i] = __swab32(idaf);
+@@ -1864,7 +1913,7 @@ static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
+
+ dev_warn(dev, "phy%d stp link timeout (0x%x)\n",
+ phy_no, reg_value);
+- if (reg_value & BIT(4))
++ if (reg_value & BIT(LINK_RESET_TIMEOUT_OFF))
+ hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET);
+ }
+
+@@ -2581,7 +2630,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
+ struct pci_dev *pdev = hisi_hba->pci_dev;
+ int rc, i;
+
+- rc = devm_request_irq(dev, pci_irq_vector(pdev, 1),
++ rc = devm_request_irq(dev, pci_irq_vector(pdev, IRQ_PHY_UP_DOWN_INDEX),
+ int_phy_up_down_bcast_v3_hw, 0,
+ DRV_NAME " phy", hisi_hba);
+ if (rc) {
+@@ -2589,7 +2638,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
+ return -ENOENT;
+ }
+
+- rc = devm_request_irq(dev, pci_irq_vector(pdev, 2),
++ rc = devm_request_irq(dev, pci_irq_vector(pdev, IRQ_CHL_INDEX),
+ int_chnl_int_v3_hw, 0,
+ DRV_NAME " channel", hisi_hba);
+ if (rc) {
+@@ -2597,7 +2646,7 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
+ return -ENOENT;
+ }
+
+- rc = devm_request_irq(dev, pci_irq_vector(pdev, 11),
++ rc = devm_request_irq(dev, pci_irq_vector(pdev, IRQ_AXI_INDEX),
+ fatal_axi_int_v3_hw, 0,
+ DRV_NAME " fatal", hisi_hba);
+ if (rc) {
+@@ -2610,7 +2659,8 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
+
+ for (i = 0; i < hisi_hba->cq_nvecs; i++) {
+ struct hisi_sas_cq *cq = &hisi_hba->cq[i];
+- int nr = hisi_sas_intr_conv ? 16 : 16 + i;
++ int nr = hisi_sas_intr_conv ? BASE_VECTORS_V3_HW :
++ BASE_VECTORS_V3_HW + i;
+ unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED :
+ IRQF_ONESHOT;
+
+@@ -2668,14 +2718,14 @@ static void interrupt_disable_v3_hw(struct hisi_hba *hisi_hba)
+ struct pci_dev *pdev = hisi_hba->pci_dev;
+ int i;
+
+- synchronize_irq(pci_irq_vector(pdev, 1));
+- synchronize_irq(pci_irq_vector(pdev, 2));
+- synchronize_irq(pci_irq_vector(pdev, 11));
++ synchronize_irq(pci_irq_vector(pdev, IRQ_PHY_UP_DOWN_INDEX));
++ synchronize_irq(pci_irq_vector(pdev, IRQ_CHL_INDEX));
++ synchronize_irq(pci_irq_vector(pdev, IRQ_AXI_INDEX));
+ for (i = 0; i < hisi_hba->queue_count; i++)
+ hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK + 0x4 * i, 0x1);
+
+ for (i = 0; i < hisi_hba->cq_nvecs; i++)
+- synchronize_irq(pci_irq_vector(pdev, i + 16));
++ synchronize_irq(pci_irq_vector(pdev, i + BASE_VECTORS_V3_HW));
+
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xffffffff);
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xffffffff);
+@@ -2707,7 +2757,7 @@ static int disable_host_v3_hw(struct hisi_hba *hisi_hba)
+
+ hisi_sas_stop_phys(hisi_hba);
+
+- mdelay(10);
++ mdelay(HISI_SAS_DELAY_FOR_PHY_DISABLE);
+
+ reg_val = hisi_sas_read32(hisi_hba, AXI_MASTER_CFG_BASE +
+ AM_CTRL_GLOBAL);
+@@ -2843,13 +2893,13 @@ static ssize_t intr_coal_ticks_v3_hw_store(struct device *dev,
+ u32 intr_coal_ticks;
+ int ret;
+
+- ret = kstrtou32(buf, 10, &intr_coal_ticks);
++ ret = kstrtou32(buf, DECIMALISM_FLAG, &intr_coal_ticks);
+ if (ret) {
+ dev_err(dev, "Input data of interrupt coalesce unmatch\n");
+ return -EINVAL;
+ }
+
+- if (intr_coal_ticks >= BIT(24)) {
++ if (intr_coal_ticks >= BIT(TICKS_BIT_INDEX)) {
+ dev_err(dev, "intr_coal_ticks must be less than 2^24!\n");
+ return -EINVAL;
+ }
+@@ -2882,13 +2932,13 @@ static ssize_t intr_coal_count_v3_hw_store(struct device *dev,
+ u32 intr_coal_count;
+ int ret;
+
+- ret = kstrtou32(buf, 10, &intr_coal_count);
++ ret = kstrtou32(buf, DECIMALISM_FLAG, &intr_coal_count);
+ if (ret) {
+ dev_err(dev, "Input data of interrupt coalesce unmatch\n");
+ return -EINVAL;
+ }
+
+- if (intr_coal_count >= BIT(8)) {
++ if (intr_coal_count >= BIT(COUNT_BIT_INDEX)) {
+ dev_err(dev, "intr_coal_count must be less than 2^8!\n");
+ return -EINVAL;
+ }
+@@ -3014,7 +3064,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_port_reg_lu[] = {
+
+ static const struct hisi_sas_debugfs_reg debugfs_port_reg = {
+ .lu = debugfs_port_reg_lu,
+- .count = 0x100,
++ .count = PORT_REG_LENGTH,
+ .base_off = PORT_BASE,
+ };
+
+@@ -3088,7 +3138,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_global_reg_lu[] = {
+
+ static const struct hisi_sas_debugfs_reg debugfs_global_reg = {
+ .lu = debugfs_global_reg_lu,
+- .count = 0x800,
++ .count = GLOBAL_REG_LENGTH,
+ };
+
+ static const struct hisi_sas_debugfs_reg_lu debugfs_axi_reg_lu[] = {
+@@ -3101,7 +3151,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_axi_reg_lu[] = {
+
+ static const struct hisi_sas_debugfs_reg debugfs_axi_reg = {
+ .lu = debugfs_axi_reg_lu,
+- .count = 0x61,
++ .count = AXI_REG_LENGTH,
+ .base_off = AXI_MASTER_CFG_BASE,
+ };
+
+@@ -3118,7 +3168,7 @@ static const struct hisi_sas_debugfs_reg_lu debugfs_ras_reg_lu[] = {
+
+ static const struct hisi_sas_debugfs_reg debugfs_ras_reg = {
+ .lu = debugfs_ras_reg_lu,
+- .count = 0x10,
++ .count = RAS_REG_LENGTH,
+ .base_off = RAS_BASE,
+ };
+
+@@ -3127,7 +3177,7 @@ static void debugfs_snapshot_prepare_v3_hw(struct hisi_hba *hisi_hba)
+ struct Scsi_Host *shost = hisi_hba->shost;
+
+ scsi_block_requests(shost);
+- wait_cmds_complete_timeout_v3_hw(hisi_hba, 100, 5000);
++ wait_cmds_complete_timeout_v3_hw(hisi_hba, WAIT_RETRY, WAIT_TMROUT);
+
+ set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
+ hisi_sas_sync_cqs(hisi_hba);
+@@ -3168,7 +3218,7 @@ static void read_iost_itct_cache_v3_hw(struct hisi_hba *hisi_hba,
+ return;
+ }
+
+- memset(buf, 0, cache_dw_size * 4);
++ memset(buf, 0, cache_dw_size * BYTE_TO_DW);
+ buf[0] = val;
+
+ for (i = 1; i < cache_dw_size; i++)
+@@ -3215,7 +3265,7 @@ static void hisi_sas_bist_test_restore_v3_hw(struct hisi_hba *hisi_hba)
+ reg_val = hisi_sas_phy_read32(hisi_hba, phy_no, PROG_PHY_LINK_RATE);
+ /* init OOB link rate as 1.5 Gbits */
+ reg_val &= ~CFG_PROG_OOB_PHY_LINK_RATE_MSK;
+- reg_val |= (0x8 << CFG_PROG_OOB_PHY_LINK_RATE_OFF);
++ reg_val |= (SAS_LINK_RATE_1_5_GBPS << CFG_PROG_OOB_PHY_LINK_RATE_OFF);
+ hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, reg_val);
+
+ /* enable PHY */
+@@ -3224,6 +3274,9 @@ static void hisi_sas_bist_test_restore_v3_hw(struct hisi_hba *hisi_hba)
+
+ #define SAS_PHY_BIST_CODE_INIT 0x1
+ #define SAS_PHY_BIST_CODE1_INIT 0X80
++#define SAS_PHY_BIST_INIT_DELAY 100
++#define SAS_PHY_BIST_LOOP_TEST_0 1
++#define SAS_PHY_BIST_LOOP_TEST_1 2
+ static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable)
+ {
+ u32 reg_val, mode_tmp;
+@@ -3242,7 +3295,8 @@ static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable)
+ ffe[FFE_SATA_1_5_GBPS], ffe[FFE_SATA_3_0_GBPS],
+ ffe[FFE_SATA_6_0_GBPS], fix_code[FIXED_CODE],
+ fix_code[FIXED_CODE_1]);
+- mode_tmp = path_mode ? 2 : 1;
++ mode_tmp = path_mode ? SAS_PHY_BIST_LOOP_TEST_1 :
++ SAS_PHY_BIST_LOOP_TEST_0;
+ if (enable) {
+ /* some preparations before bist test */
+ hisi_sas_bist_test_prep_v3_hw(hisi_hba);
+@@ -3285,13 +3339,13 @@ static int debugfs_set_bist_v3_hw(struct hisi_hba *hisi_hba, bool enable)
+ SAS_PHY_BIST_CODE1_INIT);
+ }
+
+- mdelay(100);
++ mdelay(SAS_PHY_BIST_INIT_DELAY);
+ reg_val |= (CFG_RX_BIST_EN_MSK | CFG_TX_BIST_EN_MSK);
+ hisi_sas_phy_write32(hisi_hba, phy_no, SAS_PHY_BIST_CTRL,
+ reg_val);
+
+ /* clear error bit */
+- mdelay(100);
++ mdelay(SAS_PHY_BIST_INIT_DELAY);
+ hisi_sas_phy_read32(hisi_hba, phy_no, SAS_BIST_ERR_CNT);
+ } else {
+ /* disable bist test and recover it */
+@@ -3482,7 +3536,7 @@ static void debugfs_snapshot_port_reg_v3_hw(struct hisi_hba *hisi_hba)
+ for (phy_cnt = 0; phy_cnt < hisi_hba->n_phy; phy_cnt++) {
+ databuf = hisi_hba->debugfs_port_reg[dump_index][phy_cnt].data;
+ for (i = 0; i < port->count; i++, databuf++) {
+- offset = port->base_off + 4 * i;
++ offset = port->base_off + HISI_SAS_REG_MEM_SIZE * i;
+ *databuf = hisi_sas_phy_read32(hisi_hba, phy_cnt,
+ offset);
+ }
+@@ -3496,7 +3550,8 @@ static void debugfs_snapshot_global_reg_v3_hw(struct hisi_hba *hisi_hba)
+ int i;
+
+ for (i = 0; i < debugfs_global_reg.count; i++, databuf++)
+- *databuf = hisi_sas_read32(hisi_hba, 4 * i);
++ *databuf = hisi_sas_read32(hisi_hba,
++ HISI_SAS_REG_MEM_SIZE * i);
+ }
+
+ static void debugfs_snapshot_axi_reg_v3_hw(struct hisi_hba *hisi_hba)
+@@ -3507,7 +3562,9 @@ static void debugfs_snapshot_axi_reg_v3_hw(struct hisi_hba *hisi_hba)
+ int i;
+
+ for (i = 0; i < axi->count; i++, databuf++)
+- *databuf = hisi_sas_read32(hisi_hba, 4 * i + axi->base_off);
++ *databuf = hisi_sas_read32(hisi_hba,
++ HISI_SAS_REG_MEM_SIZE * i +
++ axi->base_off);
+ }
+
+ static void debugfs_snapshot_ras_reg_v3_hw(struct hisi_hba *hisi_hba)
+@@ -3518,7 +3575,9 @@ static void debugfs_snapshot_ras_reg_v3_hw(struct hisi_hba *hisi_hba)
+ int i;
+
+ for (i = 0; i < ras->count; i++, databuf++)
+- *databuf = hisi_sas_read32(hisi_hba, 4 * i + ras->base_off);
++ *databuf = hisi_sas_read32(hisi_hba,
++ HISI_SAS_REG_MEM_SIZE * i +
++ ras->base_off);
+ }
+
+ static void debugfs_snapshot_itct_reg_v3_hw(struct hisi_hba *hisi_hba)
+@@ -3581,7 +3640,7 @@ static void debugfs_print_reg_v3_hw(u32 *regs_val, struct seq_file *s,
+ int i;
+
+ for (i = 0; i < reg->count; i++) {
+- int off = i * 4;
++ int off = i * HISI_SAS_REG_MEM_SIZE;
+ const char *name;
+
+ name = debugfs_to_reg_name_v3_hw(off, reg->base_off,
+@@ -3659,9 +3718,9 @@ static void debugfs_show_row_64_v3_hw(struct seq_file *s, int index,
+
+ /* completion header size not fixed per HW version */
+ seq_printf(s, "index %04d:\n\t", index);
+- for (i = 1; i <= sz / 8; i++, ptr++) {
++ for (i = 1; i <= sz / BYTE_TO_DDW; i++, ptr++) {
+ seq_printf(s, " 0x%016llx", le64_to_cpu(*ptr));
+- if (!(i % 2))
++ if (!(i % TWO_PARA_PER_LINE))
+ seq_puts(s, "\n\t");
+ }
+
+@@ -3675,9 +3734,9 @@ static void debugfs_show_row_32_v3_hw(struct seq_file *s, int index,
+
+ /* completion header size not fixed per HW version */
+ seq_printf(s, "index %04d:\n\t", index);
+- for (i = 1; i <= sz / 4; i++, ptr++) {
++ for (i = 1; i <= sz / BYTE_TO_DW; i++, ptr++) {
+ seq_printf(s, " 0x%08x", le32_to_cpu(*ptr));
+- if (!(i % 4))
++ if (!(i % FOUR_PARA_PER_LINE))
+ seq_puts(s, "\n\t");
+ }
+ seq_puts(s, "\n");
+@@ -3762,7 +3821,7 @@ static int debugfs_iost_cache_v3_hw_show(struct seq_file *s, void *p)
+ struct hisi_sas_debugfs_iost_cache *debugfs_iost_cache = s->private;
+ struct hisi_sas_iost_itct_cache *iost_cache =
+ debugfs_iost_cache->cache;
+- u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4;
++ u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * BYTE_TO_DW;
+ int i, tab_idx;
+ __le64 *iost;
+
+@@ -3810,7 +3869,7 @@ static int debugfs_itct_cache_v3_hw_show(struct seq_file *s, void *p)
+ struct hisi_sas_debugfs_itct_cache *debugfs_itct_cache = s->private;
+ struct hisi_sas_iost_itct_cache *itct_cache =
+ debugfs_itct_cache->cache;
+- u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4;
++ u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * BYTE_TO_DW;
+ int i, tab_idx;
+ __le64 *itct;
+
+@@ -3839,12 +3898,12 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index)
+ u64 *debugfs_timestamp;
+ struct dentry *dump_dentry;
+ struct dentry *dentry;
+- char name[256];
++ char name[NAME_BUF_SIZE];
+ int p;
+ int c;
+ int d;
+
+- snprintf(name, 256, "%d", index);
++ snprintf(name, NAME_BUF_SIZE, "%d", index);
+
+ dump_dentry = debugfs_create_dir(name, hisi_hba->debugfs_dump_dentry);
+
+@@ -3860,7 +3919,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index)
+ /* Create port dir and files */
+ dentry = debugfs_create_dir("port", dump_dentry);
+ for (p = 0; p < hisi_hba->n_phy; p++) {
+- snprintf(name, 256, "%d", p);
++ snprintf(name, NAME_BUF_SIZE, "%d", p);
+
+ debugfs_create_file(name, 0400, dentry,
+ &hisi_hba->debugfs_port_reg[index][p],
+@@ -3870,7 +3929,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index)
+ /* Create CQ dir and files */
+ dentry = debugfs_create_dir("cq", dump_dentry);
+ for (c = 0; c < hisi_hba->queue_count; c++) {
+- snprintf(name, 256, "%d", c);
++ snprintf(name, NAME_BUF_SIZE, "%d", c);
+
+ debugfs_create_file(name, 0400, dentry,
+ &hisi_hba->debugfs_cq[index][c],
+@@ -3880,7 +3939,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index)
+ /* Create DQ dir and files */
+ dentry = debugfs_create_dir("dq", dump_dentry);
+ for (d = 0; d < hisi_hba->queue_count; d++) {
+- snprintf(name, 256, "%d", d);
++ snprintf(name, NAME_BUF_SIZE, "%d", d);
+
+ debugfs_create_file(name, 0400, dentry,
+ &hisi_hba->debugfs_dq[index][d],
+@@ -3917,9 +3976,9 @@ static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file,
+ size_t count, loff_t *ppos)
+ {
+ struct hisi_hba *hisi_hba = file->f_inode->i_private;
+- char buf[8];
++ char buf[DUMP_BUF_SIZE];
+
+- if (count > 8)
++ if (count > DUMP_BUF_SIZE)
+ return -EFAULT;
+
+ if (copy_from_user(buf, user_buf, count))
+@@ -3983,7 +4042,7 @@ static ssize_t debugfs_bist_linkrate_v3_hw_write(struct file *filp,
+ {
+ struct seq_file *m = filp->private_data;
+ struct hisi_hba *hisi_hba = m->private;
+- char kbuf[16] = {}, *pkbuf;
++ char kbuf[BIST_BUF_SIZE] = {}, *pkbuf;
+ bool found = false;
+ int i;
+
+@@ -4000,7 +4059,7 @@ static ssize_t debugfs_bist_linkrate_v3_hw_write(struct file *filp,
+
+ for (i = 0; i < ARRAY_SIZE(debugfs_loop_linkrate_v3_hw); i++) {
+ if (!strncmp(debugfs_loop_linkrate_v3_hw[i].name,
+- pkbuf, 16)) {
++ pkbuf, BIST_BUF_SIZE)) {
+ hisi_hba->debugfs_bist_linkrate =
+ debugfs_loop_linkrate_v3_hw[i].value;
+ found = true;
+@@ -4073,7 +4132,7 @@ static ssize_t debugfs_bist_code_mode_v3_hw_write(struct file *filp,
+ {
+ struct seq_file *m = filp->private_data;
+ struct hisi_hba *hisi_hba = m->private;
+- char kbuf[16] = {}, *pkbuf;
++ char kbuf[BIST_BUF_SIZE] = {}, *pkbuf;
+ bool found = false;
+ int i;
+
+@@ -4090,7 +4149,7 @@ static ssize_t debugfs_bist_code_mode_v3_hw_write(struct file *filp,
+
+ for (i = 0; i < ARRAY_SIZE(debugfs_loop_code_mode_v3_hw); i++) {
+ if (!strncmp(debugfs_loop_code_mode_v3_hw[i].name,
+- pkbuf, 16)) {
++ pkbuf, BIST_BUF_SIZE)) {
+ hisi_hba->debugfs_bist_code_mode =
+ debugfs_loop_code_mode_v3_hw[i].value;
+ found = true;
+@@ -4250,7 +4309,7 @@ static ssize_t debugfs_bist_mode_v3_hw_write(struct file *filp,
+ {
+ struct seq_file *m = filp->private_data;
+ struct hisi_hba *hisi_hba = m->private;
+- char kbuf[16] = {}, *pkbuf;
++ char kbuf[BIST_BUF_SIZE] = {}, *pkbuf;
+ bool found = false;
+ int i;
+
+@@ -4266,7 +4325,8 @@ static ssize_t debugfs_bist_mode_v3_hw_write(struct file *filp,
+ pkbuf = strstrip(kbuf);
+
+ for (i = 0; i < ARRAY_SIZE(debugfs_loop_modes_v3_hw); i++) {
+- if (!strncmp(debugfs_loop_modes_v3_hw[i].name, pkbuf, 16)) {
++ if (!strncmp(debugfs_loop_modes_v3_hw[i].name, pkbuf,
++ BIST_BUF_SIZE)) {
+ hisi_hba->debugfs_bist_mode =
+ debugfs_loop_modes_v3_hw[i].value;
+ found = true;
+@@ -4604,8 +4664,9 @@ static int debugfs_fifo_data_v3_hw_show(struct seq_file *s, void *p)
+
+ debugfs_read_fifo_data_v3_hw(phy);
+
+- debugfs_show_row_32_v3_hw(s, 0, HISI_SAS_FIFO_DATA_DW_SIZE * 4,
+- (__le32 *)phy->fifo.rd_data);
++ debugfs_show_row_32_v3_hw(s, 0,
++ HISI_SAS_FIFO_DATA_DW_SIZE * HISI_SAS_REG_MEM_SIZE,
++ phy->fifo.rd_data);
+
+ return 0;
+ }
+@@ -4737,14 +4798,14 @@ static int debugfs_alloc_v3_hw(struct hisi_hba *hisi_hba, int dump_index)
+ struct hisi_sas_debugfs_regs *regs =
+ &hisi_hba->debugfs_regs[dump_index][r];
+
+- sz = debugfs_reg_array_v3_hw[r]->count * 4;
++ sz = debugfs_reg_array_v3_hw[r]->count * HISI_SAS_REG_MEM_SIZE;
+ regs->data = devm_kmalloc(dev, sz, GFP_KERNEL);
+ if (!regs->data)
+ goto fail;
+ regs->hisi_hba = hisi_hba;
+ }
+
+- sz = debugfs_port_reg.count * 4;
++ sz = debugfs_port_reg.count * HISI_SAS_REG_MEM_SIZE;
+ for (p = 0; p < hisi_hba->n_phy; p++) {
+ struct hisi_sas_debugfs_port *port =
+ &hisi_hba->debugfs_port_reg[dump_index][p];
+@@ -4854,11 +4915,11 @@ static void debugfs_phy_down_cnt_init_v3_hw(struct hisi_hba *hisi_hba)
+ {
+ struct dentry *dir = debugfs_create_dir("phy_down_cnt",
+ hisi_hba->debugfs_dir);
+- char name[16];
++ char name[NAME_BUF_SIZE];
+ int phy_no;
+
+ for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) {
+- snprintf(name, 16, "%d", phy_no);
++ snprintf(name, NAME_BUF_SIZE, "%d", phy_no);
+ debugfs_create_file(name, 0600, dir,
+ &hisi_hba->phy[phy_no],
+ &debugfs_phy_down_cnt_v3_hw_fops);
+@@ -5027,7 +5088,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ shost->max_id = HISI_SAS_MAX_DEVICES;
+ shost->max_lun = ~0;
+ shost->max_channel = 1;
+- shost->max_cmd_len = 16;
++ shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN;
+ shost->can_queue = HISI_SAS_UNRESERVED_IPTT;
+ shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT;
+ if (hisi_hba->iopoll_q_cnt)
+@@ -5108,12 +5169,13 @@ hisi_sas_v3_destroy_irqs(struct pci_dev *pdev, struct hisi_hba *hisi_hba)
+ {
+ int i;
+
+- devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 1), hisi_hba);
+- devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 2), hisi_hba);
+- devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 11), hisi_hba);
++ devm_free_irq(&pdev->dev, pci_irq_vector(pdev, IRQ_PHY_UP_DOWN_INDEX), hisi_hba);
++ devm_free_irq(&pdev->dev, pci_irq_vector(pdev, IRQ_CHL_INDEX), hisi_hba);
++ devm_free_irq(&pdev->dev, pci_irq_vector(pdev, IRQ_AXI_INDEX), hisi_hba);
+ for (i = 0; i < hisi_hba->cq_nvecs; i++) {
+ struct hisi_sas_cq *cq = &hisi_hba->cq[i];
+- int nr = hisi_sas_intr_conv ? 16 : 16 + i;
++ int nr = hisi_sas_intr_conv ? BASE_VECTORS_V3_HW :
++ BASE_VECTORS_V3_HW + i;
+
+ devm_free_irq(&pdev->dev, pci_irq_vector(pdev, nr), cq);
+ }
+--
+2.51.0
+
--- /dev/null
+From 64d98e7f0c51c57e674f411bc62f2157463da830 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 7 Mar 2026 11:51:28 +0800
+Subject: scsi: ufs: core: Fix SError in ufshcd_rtc_work() during UFS suspend
+
+From: Wang Shuaiwei <wangshuaiwei1@xiaomi.com>
+
+[ Upstream commit b0bd84c39289ef6a6c3827dd52c875659291970a ]
+
+In __ufshcd_wl_suspend(), cancel_delayed_work_sync() is called to cancel
+the UFS RTC work, but it is placed after ufshcd_vops_suspend(hba, pm_op,
+POST_CHANGE). This creates a race condition where ufshcd_rtc_work() can
+still be running while ufshcd_vops_suspend() is executing. When
+UFSHCD_CAP_CLK_GATING is not supported, the condition
+!hba->clk_gating.active_reqs is always true, causing ufshcd_update_rtc()
+to be executed. Since ufshcd_vops_suspend() typically performs clock
+gating operations, executing ufshcd_update_rtc() at that moment triggers
+an SError. The kernel panic trace is as follows:
+
+Kernel panic - not syncing: Asynchronous SError Interrupt
+Call trace:
+ dump_backtrace+0xec/0x128
+ show_stack+0x18/0x28
+ dump_stack_lvl+0x40/0xa0
+ dump_stack+0x18/0x24
+ panic+0x148/0x374
+ nmi_panic+0x3c/0x8c
+ arm64_serror_panic+0x64/0x8c
+ do_serror+0xc4/0xc8
+ el1h_64_error_handler+0x34/0x4c
+ el1h_64_error+0x68/0x6c
+ el1_interrupt+0x20/0x58
+ el1h_64_irq_handler+0x18/0x24
+ el1h_64_irq+0x68/0x6c
+ ktime_get+0xc4/0x12c
+ ufshcd_mcq_sq_stop+0x4c/0xec
+ ufshcd_mcq_sq_cleanup+0x64/0x1dc
+ ufshcd_clear_cmd+0x38/0x134
+ ufshcd_issue_dev_cmd+0x298/0x4d0
+ ufshcd_exec_dev_cmd+0x1a4/0x1c4
+ ufshcd_query_attr+0xbc/0x19c
+ ufshcd_rtc_work+0x10c/0x1c8
+ process_scheduled_works+0x1c4/0x45c
+ worker_thread+0x32c/0x3e8
+ kthread+0x120/0x1d8
+ ret_from_fork+0x10/0x20
+
+Fix this by moving cancel_delayed_work_sync() before the call to
+ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE), ensuring the UFS RTC work is
+fully completed or cancelled at that point.
+
+Cc: Bean Huo <beanhuo@iokpp.de>
+Fixes: 6bf999e0eb41 ("scsi: ufs: core: Add UFS RTC support")
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Wang Shuaiwei <wangshuaiwei1@xiaomi.com>
+Link: https://patch.msgid.link/20260307035128.3419687-1-wangshuaiwei1@xiaomi.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/core/ufshcd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
+index d109a0c8f75ff..2dcb0146c17e3 100644
+--- a/drivers/ufs/core/ufshcd.c
++++ b/drivers/ufs/core/ufshcd.c
+@@ -9882,6 +9882,7 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
+ }
+
+ flush_work(&hba->eeh_work);
++ cancel_delayed_work_sync(&hba->ufs_rtc_update_work);
+
+ ret = ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE);
+ if (ret)
+@@ -9936,7 +9937,6 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
+ if (ret)
+ goto set_link_active;
+
+- cancel_delayed_work_sync(&hba->ufs_rtc_update_work);
+ goto out;
+
+ set_link_active:
+--
+2.51.0
+
usb-renesas_usbhs-fix-use-after-free-in-isr-during-device-removal.patch
usb-mdc800-handle-signal-and-read-racing.patch
usb-image-mdc800-kill-download-urb-on-timeout.patch
+time-jiffies-mark-jiffies_64_to_clock_t-notrace.patch
+i3c-dw-i3c-master-set-sir_reject-in-dat-on-device-at.patch
+scsi-ufs-core-fix-serror-in-ufshcd_rtc_work-during-u.patch
+scsi-hisi_sas-add-time-interval-between-two-h2d-fis-.patch
+scsi-hisi_sas-use-macro-instead-of-magic-number.patch
+scsi-hisi_sas-fix-null-pointer-exception-during-user.patch
--- /dev/null
+From 2592d03504af1e88ed820de84a571e5e45997605 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Mar 2026 21:24:03 -0500
+Subject: time/jiffies: Mark jiffies_64_to_clock_t() notrace
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 755a648e78f12574482d4698d877375793867fa1 ]
+
+The trace_clock_jiffies() function that handles the "uptime" clock for
+tracing calls jiffies_64_to_clock_t(). This causes the function tracer to
+constantly recurse when the tracing clock is set to "uptime". Mark it
+notrace to prevent unnecessary recursion when using the "uptime" clock.
+
+Fixes: 58d4e21e50ff3 ("tracing: Fix wraparound problems in "uptime" trace clock")
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Link: https://patch.msgid.link/20260306212403.72270bb2@robin
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/time.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/time/time.c b/kernel/time/time.c
+index 1ad88e97b4ebc..da7e8a02a0964 100644
+--- a/kernel/time/time.c
++++ b/kernel/time/time.c
+@@ -702,7 +702,7 @@ EXPORT_SYMBOL(clock_t_to_jiffies);
+ *
+ * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC)
+ */
+-u64 jiffies_64_to_clock_t(u64 x)
++notrace u64 jiffies_64_to_clock_t(u64 x)
+ {
+ #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0
+ # if HZ < USER_HZ
+--
+2.51.0
+