Linux MIPS Architecture development
 help / color / mirror / Atom feed
* [PATCH v5 3/7] locking: Add contended_release tracepoint to sleepable locks
From: Dmitry Ilvokhin @ 2026-04-16 15:05 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long,
	Thomas Bogendoerfer, Juergen Gross, Ajay Kaher, Alexey Makhalov,
	Broadcom internal kernel review list, Thomas Gleixner,
	Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers
  Cc: linux-kernel, linux-mips, virtualization, linux-arch, linux-mm,
	linux-trace-kernel, kernel-team, Paul E. McKenney,
	Dmitry Ilvokhin
In-Reply-To: <cover.1776350944.git.d@ilvokhin.com>

Add the contended_release trace event. This tracepoint fires on the
holder side when a contended lock is released, complementing the
existing contention_begin/contention_end tracepoints which fire on the
waiter side.

This enables correlating lock hold time under contention with waiter
events by lock address.

Add trace_contended_release() calls to the slowpath unlock paths of
sleepable locks: mutex, rtmutex, semaphore, rwsem, percpu-rwsem, and
RT-specific rwbase locks.

Where possible, trace_contended_release() fires before the lock is
released and before the waiter is woken. For some lock types, the
tracepoint fires after the release but before the wake. Making the
placement consistent across all lock types is not worth the added
complexity.

For reader/writer locks, the tracepoint fires for every reader releasing
while a writer is waiting, not only for the last reader.

Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
---
 include/trace/events/lock.h   | 17 +++++++++++++++++
 kernel/locking/mutex.c        |  4 ++++
 kernel/locking/percpu-rwsem.c | 11 +++++++++++
 kernel/locking/rtmutex.c      |  1 +
 kernel/locking/rwbase_rt.c    |  6 ++++++
 kernel/locking/rwsem.c        | 10 ++++++++--
 kernel/locking/semaphore.c    |  4 ++++
 7 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/include/trace/events/lock.h b/include/trace/events/lock.h
index da978f2afb45..1ded869cd619 100644
--- a/include/trace/events/lock.h
+++ b/include/trace/events/lock.h
@@ -137,6 +137,23 @@ TRACE_EVENT(contention_end,
 	TP_printk("%p (ret=%d)", __entry->lock_addr, __entry->ret)
 );
 
+TRACE_EVENT(contended_release,
+
+	TP_PROTO(void *lock),
+
+	TP_ARGS(lock),
+
+	TP_STRUCT__entry(
+		__field(void *, lock_addr)
+	),
+
+	TP_fast_assign(
+		__entry->lock_addr = lock;
+	),
+
+	TP_printk("%p", __entry->lock_addr)
+);
+
 #endif /* _TRACE_LOCK_H */
 
 /* This part must be outside protection */
diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c
index 427187ff02db..6c2c9312eb8f 100644
--- a/kernel/locking/mutex.c
+++ b/kernel/locking/mutex.c
@@ -997,6 +997,9 @@ static noinline void __sched __mutex_unlock_slowpath(struct mutex *lock, unsigne
 		wake_q_add(&wake_q, next);
 	}
 
+	if (trace_contended_release_enabled() && waiter)
+		trace_contended_release(lock);
+
 	if (owner & MUTEX_FLAG_HANDOFF)
 		__mutex_handoff(lock, next);
 
@@ -1194,6 +1197,7 @@ EXPORT_SYMBOL(ww_mutex_lock_interruptible);
 
 EXPORT_TRACEPOINT_SYMBOL_GPL(contention_begin);
 EXPORT_TRACEPOINT_SYMBOL_GPL(contention_end);
+EXPORT_TRACEPOINT_SYMBOL_GPL(contended_release);
 
 /**
  * atomic_dec_and_mutex_lock - return holding mutex if we dec to 0
diff --git a/kernel/locking/percpu-rwsem.c b/kernel/locking/percpu-rwsem.c
index f3ee7a0d6047..46b5903989b8 100644
--- a/kernel/locking/percpu-rwsem.c
+++ b/kernel/locking/percpu-rwsem.c
@@ -263,6 +263,9 @@ void percpu_up_write(struct percpu_rw_semaphore *sem)
 {
 	rwsem_release(&sem->dep_map, _RET_IP_);
 
+	if (trace_contended_release_enabled() && wq_has_sleeper(&sem->waiters))
+		trace_contended_release(sem);
+
 	/*
 	 * Signal the writer is done, no fast path yet.
 	 *
@@ -292,6 +295,14 @@ EXPORT_SYMBOL_GPL(percpu_up_write);
 void __percpu_up_read(struct percpu_rw_semaphore *sem)
 {
 	lockdep_assert_preemption_disabled();
+	/*
+	 * After percpu_up_write() completes, rcu_sync_is_idle() can still
+	 * return false during the grace period, forcing readers into this
+	 * slowpath. Only trace when a writer is actually waiting for
+	 * readers to drain.
+	 */
+	if (trace_contended_release_enabled() && rcuwait_active(&sem->writer))
+		trace_contended_release(sem);
 	/*
 	 * slowpath; reader will only ever wake a single blocked
 	 * writer.
diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
index ccaba6148b61..3db8a840b4e8 100644
--- a/kernel/locking/rtmutex.c
+++ b/kernel/locking/rtmutex.c
@@ -1466,6 +1466,7 @@ static void __sched rt_mutex_slowunlock(struct rt_mutex_base *lock)
 		raw_spin_lock_irqsave(&lock->wait_lock, flags);
 	}
 
+	trace_contended_release(lock);
 	/*
 	 * The wakeup next waiter path does not suffer from the above
 	 * race. See the comments there.
diff --git a/kernel/locking/rwbase_rt.c b/kernel/locking/rwbase_rt.c
index 82e078c0665a..74da5601018f 100644
--- a/kernel/locking/rwbase_rt.c
+++ b/kernel/locking/rwbase_rt.c
@@ -174,6 +174,8 @@ static void __sched __rwbase_read_unlock(struct rwbase_rt *rwb,
 static __always_inline void rwbase_read_unlock(struct rwbase_rt *rwb,
 					       unsigned int state)
 {
+	if (trace_contended_release_enabled() && rt_mutex_owner(&rwb->rtmutex))
+		trace_contended_release(rwb);
 	/*
 	 * rwb->readers can only hit 0 when a writer is waiting for the
 	 * active readers to leave the critical section.
@@ -205,6 +207,8 @@ static inline void rwbase_write_unlock(struct rwbase_rt *rwb)
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&rtm->wait_lock, flags);
+	if (trace_contended_release_enabled() && rt_mutex_has_waiters(rtm))
+		trace_contended_release(rwb);
 	__rwbase_write_unlock(rwb, WRITER_BIAS, flags);
 }
 
@@ -214,6 +218,8 @@ static inline void rwbase_write_downgrade(struct rwbase_rt *rwb)
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&rtm->wait_lock, flags);
+	if (trace_contended_release_enabled() && rt_mutex_has_waiters(rtm))
+		trace_contended_release(rwb);
 	/* Release it and account current as reader */
 	__rwbase_write_unlock(rwb, WRITER_BIAS - 1, flags);
 }
diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c
index bf647097369c..602d5fd3c91a 100644
--- a/kernel/locking/rwsem.c
+++ b/kernel/locking/rwsem.c
@@ -1387,6 +1387,8 @@ static inline void __up_read(struct rw_semaphore *sem)
 	rwsem_clear_reader_owned(sem);
 	tmp = atomic_long_add_return_release(-RWSEM_READER_BIAS, &sem->count);
 	DEBUG_RWSEMS_WARN_ON(tmp < 0, sem);
+	if (trace_contended_release_enabled() && (tmp & RWSEM_FLAG_WAITERS))
+		trace_contended_release(sem);
 	if (unlikely((tmp & (RWSEM_LOCK_MASK|RWSEM_FLAG_WAITERS)) ==
 		      RWSEM_FLAG_WAITERS)) {
 		clear_nonspinnable(sem);
@@ -1413,8 +1415,10 @@ static inline void __up_write(struct rw_semaphore *sem)
 	preempt_disable();
 	rwsem_clear_owner(sem);
 	tmp = atomic_long_fetch_add_release(-RWSEM_WRITER_LOCKED, &sem->count);
-	if (unlikely(tmp & RWSEM_FLAG_WAITERS))
+	if (unlikely(tmp & RWSEM_FLAG_WAITERS)) {
+		trace_contended_release(sem);
 		rwsem_wake(sem);
+	}
 	preempt_enable();
 }
 
@@ -1437,8 +1441,10 @@ static inline void __downgrade_write(struct rw_semaphore *sem)
 	tmp = atomic_long_fetch_add_release(
 		-RWSEM_WRITER_LOCKED+RWSEM_READER_BIAS, &sem->count);
 	rwsem_set_reader_owned(sem);
-	if (tmp & RWSEM_FLAG_WAITERS)
+	if (tmp & RWSEM_FLAG_WAITERS) {
+		trace_contended_release(sem);
 		rwsem_downgrade_wake(sem);
+	}
 	preempt_enable();
 }
 
diff --git a/kernel/locking/semaphore.c b/kernel/locking/semaphore.c
index 74d41433ba13..35ac3498dca5 100644
--- a/kernel/locking/semaphore.c
+++ b/kernel/locking/semaphore.c
@@ -230,6 +230,10 @@ void __sched up(struct semaphore *sem)
 		sem->count++;
 	else
 		__up(sem, &wake_q);
+
+	if (trace_contended_release_enabled() && !wake_q_empty(&wake_q))
+		trace_contended_release(sem);
+
 	raw_spin_unlock_irqrestore(&sem->lock, flags);
 	if (!wake_q_empty(&wake_q))
 		wake_up_q(&wake_q);
-- 
2.52.0


^ permalink raw reply related

* [PATCH v5 2/7] locking/percpu-rwsem: Extract __percpu_up_read()
From: Dmitry Ilvokhin @ 2026-04-16 15:05 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long,
	Thomas Bogendoerfer, Juergen Gross, Ajay Kaher, Alexey Makhalov,
	Broadcom internal kernel review list, Thomas Gleixner,
	Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers
  Cc: linux-kernel, linux-mips, virtualization, linux-arch, linux-mm,
	linux-trace-kernel, kernel-team, Paul E. McKenney,
	Dmitry Ilvokhin, Usama Arif
In-Reply-To: <cover.1776350944.git.d@ilvokhin.com>

Move the percpu_up_read() slowpath out of the inline function into a new
__percpu_up_read() to avoid binary size increase from adding a
tracepoint to an inlined function.

Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
Acked-by: Usama Arif <usama.arif@linux.dev>
---
 include/linux/percpu-rwsem.h  | 15 +++------------
 kernel/locking/percpu-rwsem.c | 18 ++++++++++++++++++
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/include/linux/percpu-rwsem.h b/include/linux/percpu-rwsem.h
index c8cb010d655e..39d5bf8e6562 100644
--- a/include/linux/percpu-rwsem.h
+++ b/include/linux/percpu-rwsem.h
@@ -107,6 +107,8 @@ static inline bool percpu_down_read_trylock(struct percpu_rw_semaphore *sem)
 	return ret;
 }
 
+extern void __percpu_up_read(struct percpu_rw_semaphore *sem);
+
 static inline void percpu_up_read(struct percpu_rw_semaphore *sem)
 {
 	rwsem_release(&sem->dep_map, _RET_IP_);
@@ -118,18 +120,7 @@ static inline void percpu_up_read(struct percpu_rw_semaphore *sem)
 	if (likely(rcu_sync_is_idle(&sem->rss))) {
 		this_cpu_dec(*sem->read_count);
 	} else {
-		/*
-		 * slowpath; reader will only ever wake a single blocked
-		 * writer.
-		 */
-		smp_mb(); /* B matches C */
-		/*
-		 * In other words, if they see our decrement (presumably to
-		 * aggregate zero, as that is the only time it matters) they
-		 * will also see our critical section.
-		 */
-		this_cpu_dec(*sem->read_count);
-		rcuwait_wake_up(&sem->writer);
+		__percpu_up_read(sem);
 	}
 	preempt_enable();
 }
diff --git a/kernel/locking/percpu-rwsem.c b/kernel/locking/percpu-rwsem.c
index ef234469baac..f3ee7a0d6047 100644
--- a/kernel/locking/percpu-rwsem.c
+++ b/kernel/locking/percpu-rwsem.c
@@ -288,3 +288,21 @@ void percpu_up_write(struct percpu_rw_semaphore *sem)
 	rcu_sync_exit(&sem->rss);
 }
 EXPORT_SYMBOL_GPL(percpu_up_write);
+
+void __percpu_up_read(struct percpu_rw_semaphore *sem)
+{
+	lockdep_assert_preemption_disabled();
+	/*
+	 * slowpath; reader will only ever wake a single blocked
+	 * writer.
+	 */
+	smp_mb(); /* B matches C */
+	/*
+	 * In other words, if they see our decrement (presumably to
+	 * aggregate zero, as that is the only time it matters) they
+	 * will also see our critical section.
+	 */
+	this_cpu_dec(*sem->read_count);
+	rcuwait_wake_up(&sem->writer);
+}
+EXPORT_SYMBOL_GPL(__percpu_up_read);
-- 
2.52.0


^ permalink raw reply related

* [PATCH v5 0/7] locking: contended_release tracepoint instrumentation
From: Dmitry Ilvokhin @ 2026-04-16 15:05 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long,
	Thomas Bogendoerfer, Juergen Gross, Ajay Kaher, Alexey Makhalov,
	Broadcom internal kernel review list, Thomas Gleixner,
	Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers
  Cc: linux-kernel, linux-mips, virtualization, linux-arch, linux-mm,
	linux-trace-kernel, kernel-team, Paul E. McKenney,
	Dmitry Ilvokhin

The existing contention_begin/contention_end tracepoints fire on the
waiter side. The lock holder's identity and stack can be captured at
contention_begin time (e.g. perf lock contention --lock-owner), but
this reflects the holder's state when a waiter arrives, not when the
lock is actually released.

This series adds a contended_release tracepoint that fires on the
holder side when a lock with waiters is released. This provides:

- Hold time estimation: when the holder's own acquisition was
  contended, its contention_end (acquisition) and contended_release
  can be correlated to measure how long the lock was held under
  contention.

- The holder's stack at release time, which may differ from what perf lock
  contention --lock-owner captures if the holder does significant work between
  the waiter's arrival and the unlock.

Note: for reader/writer locks, the tracepoint fires for every reader
releasing while a writer is waiting, not only for the last reader.

v4 -> v5:

- Split the combined spinning locks patch into separate qspinlock and                                                   
  qrwlock patches (Paul E. McKenney).                     
- Factor out __queued_read_unlock()/__queued_write_unlock() as a                                                        
  separate preparatory commit, mirroring the queued_spin_release()
  split (Paul E. McKenney).                                                                                             
- Updated binary size numbers for qspinlock-only change.
- Added Acked-by and Reviewed-by tags where appropriate.

v3 -> v4:

- Fix spurious events in __percpu_up_read(): guard with
  rcuwait_active(&sem->writer) to avoid tracing during the RCU grace
  period after a writer releases (Sashiko).
- Fix possible use-after-free in semaphore up(): move
  trace_contended_release() inside the sem->lock critical section
  (Sashiko).
- Fix build failure with CONFIG_PARAVIRT_SPINLOCKS=y: introduce
  queued_spin_release() as the arch-overridable unlock primitive,
  so queued_spin_unlock() can be a generic tracing wrapper. Convert
  x86 (paravirt) and MIPS overrides (Sashiko).
- Add EXPORT_TRACEPOINT_SYMBOL_GPL(contended_release) for module
  support (Sashiko).
- Split spinning locks patch: factor out queued_spin_release() as a
  separate preparatory commit (Sashiko).
- Make read unlock tracepoint behavior consistent across all
  reader/writer lock types: fire for every reader releasing while
  a writer is waiting (rwsem, rwbase_rt were previously last-reader
  only).

v2 -> v3:

- Added new patch: extend contended_release tracepoint to queued spinlocks
  and queued rwlocks (marked as RFC, requesting feedback). This is prompted by
  Matthew Wilcox's suggestion to try to come up with generic instrumentation,
  instead of instrumenting each "special" lock manually. See [1] for the
  discussion.
- Reworked tracepoint placement to fire before the lock is released and
  before the waiter is woken where possible, for consistency with
  spinning locks where there is no explicit wake (inspired by Usama Arif's
  suggestion).
- Remove unnecessary linux/sched.h include from trace/events/lock.h.

RFC -> v2:

- Add trace_contended_release_enabled() guard before waiter checks that
  exist only for the tracepoint (Steven Rostedt).
- Rename __percpu_up_read_slowpath() to __percpu_up_read() (Peter
  Zijlstra).
- Add extern for __percpu_up_read() (Peter Zijlstra).
- Squashed tracepoint introduction and usage commits (Masami Hiramatsu).

v4: https://lore.kernel.org/all/cover.1774536681.git.d@ilvokhin.com/
v3: https://lore.kernel.org/all/cover.1773858853.git.d@ilvokhin.com/
v2: https://lore.kernel.org/all/cover.1773164180.git.d@ilvokhin.com/
RFC: https://lore.kernel.org/all/cover.1772642407.git.d@ilvokhin.com/

[1]: https://lore.kernel.org/all/aa7G1nD7Rd9F4eBH@casper.infradead.org/

Dmitry Ilvokhin (7):
  tracing/lock: Remove unnecessary linux/sched.h include
  locking/percpu-rwsem: Extract __percpu_up_read()
  locking: Add contended_release tracepoint to sleepable locks
  locking: Factor out queued_spin_release()
  locking: Add contended_release tracepoint to qspinlock
  locking: Factor out __queued_read_unlock()/__queued_write_unlock()
  locking: Add contended_release tracepoint to qrwlock

 arch/mips/include/asm/spinlock.h         |  6 ++--
 arch/x86/include/asm/paravirt-spinlock.h |  6 ++--
 include/asm-generic/qrwlock.h            | 38 ++++++++++++++++++++++--
 include/asm-generic/qspinlock.h          | 33 ++++++++++++++++++--
 include/linux/percpu-rwsem.h             | 15 ++--------
 include/trace/events/lock.h              | 18 ++++++++++-
 kernel/locking/mutex.c                   |  4 +++
 kernel/locking/percpu-rwsem.c            | 29 ++++++++++++++++++
 kernel/locking/qrwlock.c                 | 16 ++++++++++
 kernel/locking/qspinlock.c               |  8 +++++
 kernel/locking/rtmutex.c                 |  1 +
 kernel/locking/rwbase_rt.c               |  6 ++++
 kernel/locking/rwsem.c                   | 10 +++++--
 kernel/locking/semaphore.c               |  4 +++
 14 files changed, 167 insertions(+), 27 deletions(-)

-- 
2.52.0


^ permalink raw reply

* [PATCH v5 1/7] tracing/lock: Remove unnecessary linux/sched.h include
From: Dmitry Ilvokhin @ 2026-04-16 15:05 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long,
	Thomas Bogendoerfer, Juergen Gross, Ajay Kaher, Alexey Makhalov,
	Broadcom internal kernel review list, Thomas Gleixner,
	Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers
  Cc: linux-kernel, linux-mips, virtualization, linux-arch, linux-mm,
	linux-trace-kernel, kernel-team, Paul E. McKenney,
	Dmitry Ilvokhin, Usama Arif
In-Reply-To: <cover.1776350944.git.d@ilvokhin.com>

None of the trace events in lock.h reference anything from
linux/sched.h. Remove the unnecessary include.

Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
Acked-by: Usama Arif <usama.arif@linux.dev>
---
 include/trace/events/lock.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/include/trace/events/lock.h b/include/trace/events/lock.h
index 8e89baa3775f..da978f2afb45 100644
--- a/include/trace/events/lock.h
+++ b/include/trace/events/lock.h
@@ -5,7 +5,6 @@
 #if !defined(_TRACE_LOCK_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_LOCK_H
 
-#include <linux/sched.h>
 #include <linux/tracepoint.h>
 
 /* flags for lock:contention_begin */
-- 
2.52.0


^ permalink raw reply related

* Re: [PATCH 01/61] Coccinelle: Prefer IS_ERR_OR_NULL over manual NULL check
From: Krzysztof Kozlowski @ 2026-04-16 12:30 UTC (permalink / raw)
  To: Philipp Hahn, amd-gfx, apparmor, bpf, ceph-devel, cocci, dm-devel,
	dri-devel, gfs2, intel-gfx, intel-wired-lan, iommu, kvm,
	linux-arm-kernel, linux-block, linux-bluetooth, linux-btrfs,
	linux-cifs, linux-clk, linux-erofs, linux-ext4, linux-fsdevel,
	linux-gpio, linux-hyperv, linux-input, linux-kernel, linux-leds,
	linux-media, linux-mips, linux-mm, linux-modules, linux-mtd,
	linux-nfs, linux-omap, linux-phy, linux-pm, linux-rockchip,
	linux-s390, linux-scsi, linux-sctp, linux-security-module,
	linux-sh, linux-sound, linux-stm32, linux-trace-kernel, linux-usb,
	linux-wireless, netdev, ntfs3, samba-technical, sched-ext,
	target-devel, tipc-discussion, v9fs
  Cc: Julia Lawall, Nicolas Palix
In-Reply-To: <20260310-b4-is_err_or_null-v1-1-bd63b656022d@avm.de>

On 10/03/2026 12:48, Philipp Hahn wrote:
> Find and convert uses of IS_ERR() plus NULL check to IS_ERR_OR_NULL().
> 
> There are several cases where `!ptr && WARN_ON[_ONCE](IS_ERR(ptr))` is
> used:
> - arch/x86/kernel/callthunks.c:215 WARN_ON_ONCE
> - drivers/clk/clk.c:4561 WARN_ON_ONCE
> - drivers/interconnect/core.c:793 WARN_ON
> - drivers/reset/core.c:718 WARN_ON
> The change is not 100% semantical equivalent as the warning will now
> also happen when the pointer is NULL.
> 
> To: Julia Lawall <Julia.Lawall@inria.fr>
> To: Nicolas Palix <nicolas.palix@imag.fr>
> Cc: cocci@inria.fr
> Cc: linux-kernel@vger.kernel.org
> 
> ---
> drivers/clocksource/mips-gic-timer.c:283 looks suspicious: ret != clk,
> but Daniel Lezcano verified it as cottect.
> 
> There are some cases where the checks are part of a larger expression:
> - mm/kmemleak.c:1095
> - mm/kmemleak.c:1155
> - mm/kmemleak.c:1173
> - mm/kmemleak.c:1290
> - mm/kmemleak.c:1328
> - mm/kmemleak.c:1241
> - mm/kmemleak.c:1310
> - mm/kmemleak.c:1258
> - net/netlink/af_netlink.c:2670
> Thanks to Julia Lawall for the help to also handle them.
> 
> Signed-off-by: Philipp Hahn <phahn-oss@avm.de>
> ---
>  scripts/coccinelle/api/is_err_or_null.cocci | 125 ++++++++++++++++++++++++++++
>  1 file changed, 125 insertions(+)
> 

Neither this, nor try from 2011, nor any future try should be accepted,
because it creates impression IS_ERR_OR_NULL is somehow okay. No, it is
not okay, it is a discouraged pattern leading to less readable and
maintainable code. We should not have therefore any tools suggesting
usage of IS_ERR_OR_NULL, because people will be converting poor code
into that, instead of fixing that poor code.

Best regards,
Krzysztof

^ permalink raw reply

* Re: [PATCH 55/61] interconnect: Prefer IS_ERR_OR_NULL over manual NULL check
From: Krzysztof Kozlowski @ 2026-04-16 12:24 UTC (permalink / raw)
  To: Philipp Hahn, amd-gfx, apparmor, bpf, ceph-devel, cocci, dm-devel,
	dri-devel, gfs2, intel-gfx, intel-wired-lan, iommu, kvm,
	linux-arm-kernel, linux-block, linux-bluetooth, linux-btrfs,
	linux-cifs, linux-clk, linux-erofs, linux-ext4, linux-fsdevel,
	linux-gpio, linux-hyperv, linux-input, linux-kernel, linux-leds,
	linux-media, linux-mips, linux-mm, linux-modules, linux-mtd,
	linux-nfs, linux-omap, linux-phy, linux-pm, linux-rockchip,
	linux-s390, linux-scsi, linux-sctp, linux-security-module,
	linux-sh, linux-sound, linux-stm32, linux-trace-kernel, linux-usb,
	linux-wireless, netdev, ntfs3, samba-technical, sched-ext,
	target-devel, tipc-discussion, v9fs
  Cc: Georgi Djakov
In-Reply-To: <20260310-b4-is_err_or_null-v1-55-bd63b656022d@avm.de>

On 10/03/2026 12:49, Philipp Hahn wrote:
> Prefer using IS_ERR_OR_NULL() over using IS_ERR() and a manual NULL
> check.
> 
> Semantich change: Previously the code only printed the warning on error,
> but not when the pointer was NULL. Now the warning is printed in both
> cases!

NAK, read the code

> 
> Change found with coccinelle.
> 
> To: Georgi Djakov <djakov@kernel.org>
> Cc: linux-pm@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Philipp Hahn <phahn-oss@avm.de>
> ---
>  drivers/interconnect/core.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c
> index 8569b78a18517b33abeafac091978b25cbc1acc7..22e92b30f73853d5bd2e05b4f52cb5aa22556468 100644
> --- a/drivers/interconnect/core.c
> +++ b/drivers/interconnect/core.c
> @@ -790,7 +790,7 @@ void icc_put(struct icc_path *path)
>  	size_t i;
>  	int ret;
>  
> -	if (!path || WARN_ON(IS_ERR(path)))
> +	if (WARN_ON(IS_ERR_OR_NULL(path)))

IS_ERR_OR_NULL is simply discouraged, but beside of code preference, you
just added bug here. This is clearly not equivalent and you emit warn on
perfectly valid case!

Best regards,
Krzysztof

^ permalink raw reply

* Re: [PATCH] iio: adc: ingenic-adc: use guard(mutex)(&lock) to handle synchronisation
From: Paul Cercueil @ 2026-04-16 10:08 UTC (permalink / raw)
  To: Felipe Ribeiro de Souza, jic23, dlechner, nuno.sa, andy
  Cc: Lucas Ivars Cadima Ciziks, linux-mips, linux-iio
In-Reply-To: <20260416011815.9140-1-felipers@ime.usp.br>

Hi Felipe,

Le mercredi 15 avril 2026 à 22:18 -0300, Felipe Ribeiro de Souza a
écrit :
> Replace mutex_lock(&lock) and mutex_unlock(&lock) calls with
> guard(mutex)(&lock) in functions ingenic_adc_set_adcmd,
> ingenic_adc_set_config, ingenic_adc_enable, ingenic_adc_capture
> and ingenic_adc_read_chan_info_raw.
> 
> This removes the need to call the unlock function, as the lock is
> automatically released when the function return or the scope exits
> for any other case.
> 
> Signed-off-by: Felipe Ribeiro de Souza <felipers@ime.usp.br>
> Co-developed-by: Lucas Ivars Cadima Ciziks <lucas@ciziks.com>
> Signed-off-by: Lucas Ivars Cadima Ciziks <lucas@ciziks.com>

I see a slight behaviour change in ingenic_adc_read_chan_info_raw()
where the mutex is now unlocked after the clk_disable(). I think that's
fine though. So:

Reviewed-by: Paul Cercueil <paul@crapouillou.net>

Cheers,
-Paul

> ---
>  drivers/iio/adc/ingenic-adc.c | 19 +++++++------------
>  1 file changed, 7 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/iio/adc/ingenic-adc.c b/drivers/iio/adc/ingenic-
> adc.c
> index 1e802c877..bb7abdcd8 100644
> --- a/drivers/iio/adc/ingenic-adc.c
> +++ b/drivers/iio/adc/ingenic-adc.c
> @@ -20,6 +20,7 @@
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
>  #include <linux/property.h>
> +#include <linux/cleanup.h>
>  
>  #define JZ_ADC_REG_ENABLE		0x00
>  #define JZ_ADC_REG_CFG			0x04
> @@ -115,7 +116,7 @@ static void ingenic_adc_set_adcmd(struct iio_dev
> *iio_dev, unsigned long mask)
>  {
>  	struct ingenic_adc *adc = iio_priv(iio_dev);
>  
> -	mutex_lock(&adc->lock);
> +	guard(mutex)(&adc->lock);
>  
>  	/* Init ADCMD */
>  	readl(adc->base + JZ_ADC_REG_ADCMD);
> @@ -162,8 +163,6 @@ static void ingenic_adc_set_adcmd(struct iio_dev
> *iio_dev, unsigned long mask)
>  
>  	/* We're done */
>  	writel(0, adc->base + JZ_ADC_REG_ADCMD);
> -
> -	mutex_unlock(&adc->lock);
>  }
>  
>  static void ingenic_adc_set_config(struct ingenic_adc *adc,
> @@ -172,13 +171,11 @@ static void ingenic_adc_set_config(struct
> ingenic_adc *adc,
>  {
>  	uint32_t cfg;
>  
> -	mutex_lock(&adc->lock);
> +	guard(mutex)(&adc->lock);
>  
>  	cfg = readl(adc->base + JZ_ADC_REG_CFG) & ~mask;
>  	cfg |= val;
>  	writel(cfg, adc->base + JZ_ADC_REG_CFG);
> -
> -	mutex_unlock(&adc->lock);
>  }
>  
>  static void ingenic_adc_enable_unlocked(struct ingenic_adc *adc,
> @@ -201,9 +198,8 @@ static void ingenic_adc_enable(struct ingenic_adc
> *adc,
>  			       int engine,
>  			       bool enabled)
>  {
> -	mutex_lock(&adc->lock);
> +	guard(mutex)(&adc->lock);
>  	ingenic_adc_enable_unlocked(adc, engine, enabled);
> -	mutex_unlock(&adc->lock);
>  }
>  
>  static int ingenic_adc_capture(struct ingenic_adc *adc,
> @@ -218,7 +214,7 @@ static int ingenic_adc_capture(struct ingenic_adc
> *adc,
>  	 * probably due to the switch of VREF. We must keep the lock
> here to
>  	 * avoid races with the buffer enable/disable functions.
>  	 */
> -	mutex_lock(&adc->lock);
> +	guard(mutex)(&adc->lock);
>  	cfg = readl(adc->base + JZ_ADC_REG_CFG);
>  	writel(cfg & ~JZ_ADC_REG_CFG_CMD_SEL, adc->base +
> JZ_ADC_REG_CFG);
>  
> @@ -229,7 +225,6 @@ static int ingenic_adc_capture(struct ingenic_adc
> *adc,
>  		ingenic_adc_enable_unlocked(adc, engine, false);
>  
>  	writel(cfg, adc->base + JZ_ADC_REG_CFG);
> -	mutex_unlock(&adc->lock);
>  
>  	return ret;
>  }
> @@ -643,7 +638,8 @@ static int ingenic_adc_read_chan_info_raw(struct
> iio_dev *iio_dev,
>  	}
>  
>  	/* We cannot sample the aux channels in parallel. */
> -	mutex_lock(&adc->aux_lock);
> +	guard(mutex)(&adc->lock);
> +
>  	if (adc->soc_data->has_aux_md && engine == 0) {
>  		switch (chan->channel) {
>  		case INGENIC_ADC_AUX0:
> @@ -677,7 +673,6 @@ static int ingenic_adc_read_chan_info_raw(struct
> iio_dev *iio_dev,
>  
>  	ret = IIO_VAL_INT;
>  out:
> -	mutex_unlock(&adc->aux_lock);
>  	clk_disable(adc->clk);
>  
>  	return ret;

^ permalink raw reply

* Re: [PATCH] mips: econet: add EN751627 SoC Kconfig entry
From: kpursoty @ 2026-04-16  7:20 UTC (permalink / raw)
  To: openwrt-devel@lists.openwrt.org
  Cc: linux-mips@vger.kernel.org, tsbogend@alpha.franken.de,
	cjd@cjdns.fr
In-Reply-To: <E5Pgm6Vp9MRV0KHJ_KOh8hEjTukhx1F2X5nlmbJeG-EW0j44NRslk1EuiB6AQt7zLQykmY_QzPU0haPtiH7Yb3fd7QhMFxWBxxx4_2684RA=@proton.me>

Thanks for your notes. Patch withdrawn.

On Wednesday, 15 April 2026 at 20:48, kpursoty@proton.me <kpursoty@proton.me> wrote:

>
> The EN751627 family (EN7516 DSL, EN7527 xPON) is a big-endian dual-core
> MIPS 1004Kc SoC (2 VPEs per core, NR_CPUS=4) used in DSL/WiFi gateway
> devices such as the ZyXEL EX3301-T0. It shares the MIPS GIC interrupt
> controller with EN7528 but is big-endian.
>
> Key differences from existing SoCs:
> - EN751221: BE, single-core 34Kc, custom INTC
> - EN7528:   LE, dual-core 1004Kc, MIPS GIC
> - EN751627: BE, dual-core 2-VPE 1004Kc, MIPS GIC
>
> The SMP plumbing (CM/CPC probe + CPS SMP ops) is shared with EN7528 and
> lives in patch 100 (device_tree_init). This patch adds only the Kconfig
> entry.
>
> Note: on EN751627, mips_cpc_probe() must be called before
> register_cps_smp_ops(). Without it, core 1 never comes online because
> write_gcr_co_reset_release(0) is insufficient on this SoC. This is
> different from EN7528 where CPC probe behaves identically. Both SoCs
> are covered by the shared #if in device_tree_init().
>
> Signed-off-by: Kervin Pursoty <kpursoty@proton.me>
> ---
>  arch/mips/econet/Kconfig | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
>
> diff --git a/arch/mips/econet/Kconfig b/arch/mips/econet/Kconfig
> --- a/arch/mips/econet/Kconfig
> +++ b/arch/mips/econet/Kconfig
> @@ -41,3 +41,28 @@ choice
>  		  The EN7528 family with dual-core MIPS 1004Kc.
>  		  Requires MIPS_RAW_APPENDED_DTB=y for boot.
> +
> +	config SOC_ECONET_EN751627
> +		bool "EN751627 family"
> +		select COMMON_CLK
> +		select CPU_BIG_ENDIAN
> +		select HAVE_PCI
> +		select IRQ_MIPS_CPU
> +		select MIPS_CM
> +		select MIPS_CPC
> +		select MIPS_CPS
> +		select MIPS_CPU_SCACHE
> +		select MIPS_GIC
> +		select MIPS_MT_SMP
> +		select PCI_DRIVERS_GENERIC
> +		select SMP
> +		select SMP_UP
> +		select SYS_SUPPORTS_HIGHMEM
> +		select SYS_SUPPORTS_MIPS_CPS
> +		select SYS_SUPPORTS_MULTITHREADING
> +		select SYS_SUPPORTS_SMP
> +		help
> +		  The EN751627 family (EN7516 DSL, EN7527 xPON) with big-endian
> +		  dual-core, 2-VPE-per-core MIPS 1004Kc and MIPS GIC. Used in
> +		  DSL+WiFi gateways. Requires MIPS_RAW_APPENDED_DTB=y for boot.
>  endchoice
>

^ permalink raw reply

* Re: [PATCH] serial: base: do not disable TX on hangup for console ports
From: kpursoty @ 2026-04-16  7:19 UTC (permalink / raw)
  To: linux-serial@vger.kernel.org, gregkh@linuxfoundation.org,
	jirislaby@kernel.org
  Cc: linux-kernel@vger.kernel.org, linux-mips@vger.kernel.org,
	tsbogend@alpha.franken.de
In-Reply-To: <1fpGAFo1KYyRDeGSGmaDWx6gXbV00C83qU_tep62Zu_cl9JfjpjWg8SKhw6z0owZ9eEMzXR2GnZ_U3V2PVi2R1fuGAmzgK43GYbWkCIBFf8=@proton.me>

Thanks for your notes. Patch withdrawn.

On Wednesday, 15 April 2026 at 09:01, kpursoty@proton.me <kpursoty@proton.me> wrote:

> serial_base_port_shutdown() calls serial_base_port_set_tx(false)
> unconditionally. When a TTY hangup occurs on a port that is also a
> registered kernel console, this permanently disables the console
> transmitter.
>
> uart_hangup() already guards against uart_change_pm(PM_OFF) for console
> ports (see the uart_console() check in uart_hangup()). Apply the same
> guard in serial_base_port_shutdown(): skip TX-disable if the port is a
> registered console.
>
> Without this fix, any path that calls uart_shutdown() on a console port
> - including TIOCSCTTY with force=1 (as used by init systems such as
> procd) - permanently silences all subsequent kernel console output.
>
> Signed-off-by: Kervin Pursoty <kpursoty@proton.me>
> ---
>  drivers/tty/serial/serial_port.c | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/tty/serial/serial_port.c b/drivers/tty/serial/serial_port.c
> --- a/drivers/tty/serial/serial_port.c
> +++ b/drivers/tty/serial/serial_port.c
> @@ -110,5 +110,14 @@
>  {
>  	struct serial_port_device *port_dev = port->port_dev;
>
> -	serial_base_port_set_tx(port, port_dev, false);
> +	/*
> +	 * Do not disable TX on a console port. When an init system calls
> +	 * TIOCSCTTY with force=1, the kernel hangs up the previous session,
> +	 * triggering uart_hangup() -> uart_shutdown() -> here. Stopping TX
> +	 * kills all kernel console output permanently.
> +	 * uart_hangup() already skips uart_change_pm(PM_OFF) for consoles
> +	 * via uart_console(); apply the same guard here.
> +	 */
> +	if (!uart_console(port))
> +		serial_base_port_set_tx(port, port_dev, false);
>  }
>
>  static DEFINE_RUNTIME_DEV_PM_OPS(serial_port_pm,
>

^ permalink raw reply

* Re: [PATCH v3 2/2] clocksource: timer-econet-en751221: fix IRQ ack storm on interrupt handler
From: kpursoty @ 2026-04-16  7:19 UTC (permalink / raw)
  To: linux-kernel@vger.kernel.org, daniel.lezcano@linaro.org,
	tglx@linutronix.de
  Cc: linux-mips@vger.kernel.org, tsbogend@alpha.franken.de,
	cjd@cjdns.fr, naseefkm@gmail.com
In-Reply-To: <bshyYDAvwv9SWN7CjLfkE_DUQGLMssyTLFOlDYgGNi-nZGbqFC8sMbm8fP3I2q3Zwxb_5FFlCKqbt0kvs7x8Q3DqjDI675GUFYQF08-CoeQ=@proton.me>

Thanks for your notes. Patch withdrawn.

On Wednesday, 15 April 2026 at 08:53, kpursoty@proton.me <kpursoty@proton.me> wrote:

> The interrupt handler acked by writing the current count back to compare:
>
>   iowrite32(ioread32(reg_count(cpu)), reg_compare(cpu));
>
> Since the interrupt fires when count >= compare, and the counter advances
> past the written value before the MMIO write reaches the peripheral, the
> condition re-asserts on the same bus cycle. This causes a tight IRQ storm
> on CPU0, stalling boot at T=62s (measured: boot never progresses past
> clockevents registration).
>
> The EcoNet GPL kernel (arch/mips/econet/time2.c, cputmr_timer_ack()) acks
> by writing the *next* deadline, which puts count < compare and clears the
> pending condition. Write U32_MAX (unreachable before set_next_event()
> programs the real deadline), consistent with cevt_dev_init() which also
> writes U32_MAX to park the compare register at init.
>
> Fixes: 3b4c33ac87d0 ("clocksource/drivers: Add EcoNet Timer HPT driver")
> Signed-off-by: Kervin Pursoty <kpursoty@proton.me>
> Tested-by: Caleb James DeLisle <cjd@cjdns.fr>
> ---
> v3: Add Tested-by from Caleb James DeLisle (tested on EN755221 hardware).
>     No code changes since v2.
>
>  drivers/clocksource/timer-econet-en751221.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clocksource/timer-econet-en751221.c b/drivers/clocksource/timer-econet-en751221.c
> --- a/drivers/clocksource/timer-econet-en751221.c
> +++ b/drivers/clocksource/timer-econet-en751221.c
> @@ -68,6 +68,10 @@ static irqreturn_t cevt_interrupt(int irq, void *dev_id)
>  	if (!cevt_is_pending(cpu))
>  		return IRQ_NONE;
>
> -	iowrite32(ioread32(reg_count(cpu)), reg_compare(cpu));
> +	/*
> +	 * Ack: write a future value so count < compare, clearing the pending
> +	 * condition. set_next_event() will program the real deadline.
> +	 */
> +	iowrite32(U32_MAX, reg_compare(cpu));
>  	dev->event_handler(dev);
>  	return IRQ_HANDLED;
>  }
>

^ permalink raw reply

* Re: [PATCH v3 1/2] clocksource: timer-econet-en751221: fix timer block mapping at boot
From: kpursoty @ 2026-04-16  7:19 UTC (permalink / raw)
  To: linux-kernel@vger.kernel.org, daniel.lezcano@linaro.org,
	tglx@linutronix.de
  Cc: linux-mips@vger.kernel.org, tsbogend@alpha.franken.de,
	cjd@cjdns.fr, naseefkm@gmail.com
In-Reply-To: <o_cMD_cD6PNolsucCVtoojfSsfFgjsNiEop7YJ_QW8jrX1aCkIF8Rhdk-8_DSCBU1WrKSjr9STxTuCjiRK8yJ6vDA4Q1Ck2BCgOzYaBqSEs=@proton.me>

Thanks for your notes. Patch withdrawn.

On Wednesday, 15 April 2026 at 08:53, kpursoty@proton.me <kpursoty@proton.me> wrote:

> timer_init() used DIV_ROUND_UP(num_possible_cpus(), 2) to determine how
> many register blocks to iomap. At early boot with VPE-based SMP, MIPS
> reports num_possible_cpus()=1 (VPEs not yet brought online), giving
> num_blocks=1. Only membase[0] is then mapped via of_iomap.
>
> The EN751627 SoC has 2 physical cores, each with 2 VPEs, giving NR_CPUS=4
> and two timer register blocks (one per core). Each block serves two VPEs:
> block 0 handles CPU0+CPU1 (core 0), block 1 handles CPU2+CPU3 (core 1).
> The block count is a silicon constant: DIV_ROUND_UP(NR_CPUS, 2) = 2.
>
> cevt_init() calls cevt_dev_init(i) for each possible CPU via
> for_each_possible_cpu(). On EN7528/EN751627 with 4 VPEs, NR_CPUS=4 so
> cevt_dev_init(2) is called. cevt_dev_init(2) writes to reg_compare(2)
> which dereferences membase[2>>1] = membase[1], which is NULL:
>
>   CPU 0 Unable to handle kernel paging request at virtual address 00000008
>   epc : iowrite32+0x4/0x10
>   ra  : cevt_dev_init+0x40/0x64
>
> Fix: replace the runtime calculation with ECONET_NUM_BLOCKS, which is
> DIV_ROUND_UP(NR_CPUS, 2) evaluated at compile time. This is the same
> expression used to declare the membase[] array, so the loop bound and
> array size are provably consistent. For NR_CPUS=4 this is always 2,
> correctly mapping both register blocks regardless of how many VPEs are
> visible at early boot.
>
> Fixes: 3b4c33ac87d0 ("clocksource/drivers: Add EcoNet Timer HPT driver")
> Signed-off-by: Kervin Pursoty <kpursoty@proton.me>
> Reviewed-by: Caleb James DeLisle <cjd@cjdns.fr>
> ---
> v3: No changes. Resent as v3 to keep version in sync with 2/2.
> v2: Add Reviewed-by from Caleb James DeLisle.
>
>  drivers/clocksource/timer-econet-en751221.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/clocksource/timer-econet-en751221.c b/drivers/clocksource/timer-econet-en751221.c
> --- a/drivers/clocksource/timer-econet-en751221.c
> +++ b/drivers/clocksource/timer-econet-en751221.c
> @@ -160,5 +160,4 @@ static u64 notrace sched_clock_read(void)
>  static int __init timer_init(struct device_node *np)
>  {
> -	int num_blocks = DIV_ROUND_UP(num_possible_cpus(), 2);
>  	struct clk *clk;
>  	int ret;
>
> @@ -172,5 +171,5 @@ static int __init timer_init(struct device_node *np)
>
>  	econet_timer.freq_hz = clk_get_rate(clk);
>
> -	for (int i = 0; i < num_blocks; i++) {
> +	for (int i = 0; i < ECONET_NUM_BLOCKS; i++) {
>  		econet_timer.membase[i] = of_iomap(np, i);
>  		if (!econet_timer.membase[i]) {
>  			pr_err("%pOFn: failed to map register [%d]\n", np, i);

^ permalink raw reply

* [PATCH] iio: adc: ingenic-adc: use guard(mutex)(&lock) to handle synchronisation
From: Felipe Ribeiro de Souza @ 2026-04-16  1:18 UTC (permalink / raw)
  To: paul, jic23, dlechner, nuno.sa, andy
  Cc: Felipe Ribeiro de Souza, Lucas Ivars Cadima Ciziks, linux-mips,
	linux-iio

Replace mutex_lock(&lock) and mutex_unlock(&lock) calls with
guard(mutex)(&lock) in functions ingenic_adc_set_adcmd,
ingenic_adc_set_config, ingenic_adc_enable, ingenic_adc_capture
and ingenic_adc_read_chan_info_raw.

This removes the need to call the unlock function, as the lock is
automatically released when the function return or the scope exits
for any other case.

Signed-off-by: Felipe Ribeiro de Souza <felipers@ime.usp.br>
Co-developed-by: Lucas Ivars Cadima Ciziks <lucas@ciziks.com>
Signed-off-by: Lucas Ivars Cadima Ciziks <lucas@ciziks.com>
---
 drivers/iio/adc/ingenic-adc.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/iio/adc/ingenic-adc.c b/drivers/iio/adc/ingenic-adc.c
index 1e802c877..bb7abdcd8 100644
--- a/drivers/iio/adc/ingenic-adc.c
+++ b/drivers/iio/adc/ingenic-adc.c
@@ -20,6 +20,7 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/property.h>
+#include <linux/cleanup.h>
 
 #define JZ_ADC_REG_ENABLE		0x00
 #define JZ_ADC_REG_CFG			0x04
@@ -115,7 +116,7 @@ static void ingenic_adc_set_adcmd(struct iio_dev *iio_dev, unsigned long mask)
 {
 	struct ingenic_adc *adc = iio_priv(iio_dev);
 
-	mutex_lock(&adc->lock);
+	guard(mutex)(&adc->lock);
 
 	/* Init ADCMD */
 	readl(adc->base + JZ_ADC_REG_ADCMD);
@@ -162,8 +163,6 @@ static void ingenic_adc_set_adcmd(struct iio_dev *iio_dev, unsigned long mask)
 
 	/* We're done */
 	writel(0, adc->base + JZ_ADC_REG_ADCMD);
-
-	mutex_unlock(&adc->lock);
 }
 
 static void ingenic_adc_set_config(struct ingenic_adc *adc,
@@ -172,13 +171,11 @@ static void ingenic_adc_set_config(struct ingenic_adc *adc,
 {
 	uint32_t cfg;
 
-	mutex_lock(&adc->lock);
+	guard(mutex)(&adc->lock);
 
 	cfg = readl(adc->base + JZ_ADC_REG_CFG) & ~mask;
 	cfg |= val;
 	writel(cfg, adc->base + JZ_ADC_REG_CFG);
-
-	mutex_unlock(&adc->lock);
 }
 
 static void ingenic_adc_enable_unlocked(struct ingenic_adc *adc,
@@ -201,9 +198,8 @@ static void ingenic_adc_enable(struct ingenic_adc *adc,
 			       int engine,
 			       bool enabled)
 {
-	mutex_lock(&adc->lock);
+	guard(mutex)(&adc->lock);
 	ingenic_adc_enable_unlocked(adc, engine, enabled);
-	mutex_unlock(&adc->lock);
 }
 
 static int ingenic_adc_capture(struct ingenic_adc *adc,
@@ -218,7 +214,7 @@ static int ingenic_adc_capture(struct ingenic_adc *adc,
 	 * probably due to the switch of VREF. We must keep the lock here to
 	 * avoid races with the buffer enable/disable functions.
 	 */
-	mutex_lock(&adc->lock);
+	guard(mutex)(&adc->lock);
 	cfg = readl(adc->base + JZ_ADC_REG_CFG);
 	writel(cfg & ~JZ_ADC_REG_CFG_CMD_SEL, adc->base + JZ_ADC_REG_CFG);
 
@@ -229,7 +225,6 @@ static int ingenic_adc_capture(struct ingenic_adc *adc,
 		ingenic_adc_enable_unlocked(adc, engine, false);
 
 	writel(cfg, adc->base + JZ_ADC_REG_CFG);
-	mutex_unlock(&adc->lock);
 
 	return ret;
 }
@@ -643,7 +638,8 @@ static int ingenic_adc_read_chan_info_raw(struct iio_dev *iio_dev,
 	}
 
 	/* We cannot sample the aux channels in parallel. */
-	mutex_lock(&adc->aux_lock);
+	guard(mutex)(&adc->lock);
+
 	if (adc->soc_data->has_aux_md && engine == 0) {
 		switch (chan->channel) {
 		case INGENIC_ADC_AUX0:
@@ -677,7 +673,6 @@ static int ingenic_adc_read_chan_info_raw(struct iio_dev *iio_dev,
 
 	ret = IIO_VAL_INT;
 out:
-	mutex_unlock(&adc->aux_lock);
 	clk_disable(adc->clk);
 
 	return ret;
-- 
2.43.0


^ permalink raw reply related

* [PATCH] mips: econet: add EN751627 SoC Kconfig entry
From: kpursoty @ 2026-04-15 19:48 UTC (permalink / raw)
  To: openwrt-devel@lists.openwrt.org
  Cc: linux-mips@vger.kernel.org, tsbogend@alpha.franken.de,
	cjd@cjdns.fr


The EN751627 family (EN7516 DSL, EN7527 xPON) is a big-endian dual-core
MIPS 1004Kc SoC (2 VPEs per core, NR_CPUS=4) used in DSL/WiFi gateway
devices such as the ZyXEL EX3301-T0. It shares the MIPS GIC interrupt
controller with EN7528 but is big-endian.

Key differences from existing SoCs:
- EN751221: BE, single-core 34Kc, custom INTC
- EN7528:   LE, dual-core 1004Kc, MIPS GIC
- EN751627: BE, dual-core 2-VPE 1004Kc, MIPS GIC

The SMP plumbing (CM/CPC probe + CPS SMP ops) is shared with EN7528 and
lives in patch 100 (device_tree_init). This patch adds only the Kconfig
entry.

Note: on EN751627, mips_cpc_probe() must be called before
register_cps_smp_ops(). Without it, core 1 never comes online because
write_gcr_co_reset_release(0) is insufficient on this SoC. This is
different from EN7528 where CPC probe behaves identically. Both SoCs
are covered by the shared #if in device_tree_init().

Signed-off-by: Kervin Pursoty <kpursoty@proton.me>
---
 arch/mips/econet/Kconfig | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/mips/econet/Kconfig b/arch/mips/econet/Kconfig
--- a/arch/mips/econet/Kconfig
+++ b/arch/mips/econet/Kconfig
@@ -41,3 +41,28 @@ choice
 		  The EN7528 family with dual-core MIPS 1004Kc.
 		  Requires MIPS_RAW_APPENDED_DTB=y for boot.
+
+	config SOC_ECONET_EN751627
+		bool "EN751627 family"
+		select COMMON_CLK
+		select CPU_BIG_ENDIAN
+		select HAVE_PCI
+		select IRQ_MIPS_CPU
+		select MIPS_CM
+		select MIPS_CPC
+		select MIPS_CPS
+		select MIPS_CPU_SCACHE
+		select MIPS_GIC
+		select MIPS_MT_SMP
+		select PCI_DRIVERS_GENERIC
+		select SMP
+		select SMP_UP
+		select SYS_SUPPORTS_HIGHMEM
+		select SYS_SUPPORTS_MIPS_CPS
+		select SYS_SUPPORTS_MULTITHREADING
+		select SYS_SUPPORTS_SMP
+		help
+		  The EN751627 family (EN7516 DSL, EN7527 xPON) with big-endian
+		  dual-core, 2-VPE-per-core MIPS 1004Kc and MIPS GIC. Used in
+		  DSL+WiFi gateways. Requires MIPS_RAW_APPENDED_DTB=y for boot.
 endchoice


^ permalink raw reply

* Re: [PATCH v4 5/5] locking: Add contended_release tracepoint to spinning locks
From: Dmitry Ilvokhin @ 2026-04-15 17:43 UTC (permalink / raw)
  To: Paul E. McKenney
  Cc: Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long,
	Thomas Bogendoerfer, Juergen Gross, Ajay Kaher, Alexey Makhalov,
	Broadcom internal kernel review list, Thomas Gleixner,
	Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, linux-kernel, linux-mips,
	virtualization, linux-arch, linux-mm, linux-trace-kernel,
	kernel-team
In-Reply-To: <8d98d9f4-ccab-4864-b406-d3eb684cab45@paulmck-laptop>

On Tue, Apr 14, 2026 at 04:20:26PM -0700, Paul E. McKenney wrote:

[...]

> > +static inline void queued_read_unlock(struct qrwlock *lock)
> > +{
> > +	/*
> > +	 * Trace and unlock are combined in the traced unlock variant so
> > +	 * the compiler does not need to preserve the lock pointer across
> > +	 * the function call, avoiding callee-saved register save/restore
> > +	 * on the hot path.
> > +	 */
> > +	if (tracepoint_enabled(contended_release)) {
> > +		queued_read_unlock_traced(lock);
> > +		return;
> > +	}
> > +
> > +	__queued_read_unlock(lock);
> > +}
> 
> Shouldn't this refactoring be its own separate patch, similar to 4/5?
> 
> That would probably clean up this diff a bit.
> 
> > +
> > +static __always_inline void __queued_write_unlock(struct qrwlock *lock)
> >  {
> >  	smp_store_release(&lock->wlocked, 0);
> >  }
> >  
> >  /**
> > - * queued_rwlock_is_contended - check if the lock is contended
> > + * queued_write_unlock - release write lock of a queued rwlock
> >   * @lock : Pointer to queued rwlock structure
> > - * Return: 1 if lock contended, 0 otherwise
> >   */
> > -static inline int queued_rwlock_is_contended(struct qrwlock *lock)
> > +static inline void queued_write_unlock(struct qrwlock *lock)
> >  {
> > -	return arch_spin_is_locked(&lock->wait_lock);
> > +	/* See comment in queued_read_unlock(). */
> > +	if (tracepoint_enabled(contended_release)) {
> > +		queued_write_unlock_traced(lock);
> > +		return;
> > +	}
> > +
> > +	__queued_write_unlock(lock);
> 
> And the same here, so one patch for interposing __queued_read_unlock()
> and another for interposing __queued_write_unlock().
> 
>

[...]

> And is it possible to have one patch for qspinlock and another for qrwlock?
> It *looks* like it should be.
> 
> 							Thanx, Paul
> 

Thanks for the suggestion, Paul.

I think separate commits for the read and write paths of qrwlock is a
bit too fine-grained, but I like the point about mixing refactoring with
instrumentation and keeping different lock types separate.

I'll split this commit into four.

    locking: Factor out __queued_read_unlock()/__queued_write_unlock()                                                    
    locking: Add contended_release tracepoint to qrwlock
    locking: Factor out queued_spin_release()                                                                             
    locking: Add contended_release tracepoint to qspinlock

^ permalink raw reply

* Re: [PATCH v2] staging: octeon: remove SPI, POW, PKO, and Helper typedef enums
From: Max @ 2026-04-15 14:54 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: gregkh, tsbogend, len.bao, yoelvisoliveros, linux-mips,
	linux-kernel, linux-staging
In-Reply-To: <ad-XuNMor_ORjyOt@stanley.mountain>

On Wed, Apr 15, 2026 at 8:50 AM Dan Carpenter <error27@gmail.com> wrote:
>
> I haven't looked at the conflict.  No idea.  Sorry.
>
> regards,
> dan carpenter
>

No worries, if you or anybody else can suggest a better name then I'd be happy
to send over a v3.

Best regards,
Maxwell

^ permalink raw reply

* Re: [PATCH v2] staging: octeon: remove SPI, POW, PKO, and Helper typedef enums
From: Dan Carpenter @ 2026-04-15 13:50 UTC (permalink / raw)
  To: Max
  Cc: gregkh, tsbogend, len.bao, yoelvisoliveros, linux-mips,
	linux-kernel, linux-staging
In-Reply-To: <CAKqfh0EEvEwF3QmgtNk2znsaamGFCc0muGjY3zsH6OogsZS8-Q@mail.gmail.com>

On Wed, Apr 15, 2026 at 08:31:10AM -0500, Max wrote:
> Hi Dan,
> 
> > Presumably the "_e" stands for enum?  Ugh.  No.  Don't do that.
> 
> This was because of a struct with the same name, provided there wasn't
> the "_e" suffix.
> Just curious, what name would you prefer over appending "_e"?

I haven't looked at the conflict.  No idea.  Sorry.

regards,
dan carpenter


^ permalink raw reply

* Re: [PATCH v2] staging: octeon: remove SPI, POW, PKO, and Helper typedef enums
From: Max @ 2026-04-15 13:31 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: gregkh, tsbogend, len.bao, yoelvisoliveros, linux-mips,
	linux-kernel, linux-staging
In-Reply-To: <ad-FcZeXsFlSPXQj@stanley.mountain>

Hi Dan,

> Presumably the "_e" stands for enum?  Ugh.  No.  Don't do that.

This was because of a struct with the same name, provided there wasn't
the "_e" suffix.
Just curious, what name would you prefer over appending "_e"?

Best regards,
Maxwell

On Wed, Apr 15, 2026 at 7:32 AM Dan Carpenter <error27@gmail.com> wrote:
>
> On Wed, Apr 15, 2026 at 07:29:39AM -0500, Maxwell Doose wrote:
> > This patch removes custom typedef enums and replaces them with standard
> > enums to address the "General code review and cleanup" task in TODO.
> >
> > The following enums are affected:
> >
> > - cvmx_spi_mode_t (now enum cvmx_spi_mode)
> > - cvmx_helper_interface_mode_t (now enum cvmx_helper_interface_mode_e)
>
> Presumably the "_e" stands for enum?  Ugh.  No.  Don't do that.
>
> regards,
> dan carpenter
>

^ permalink raw reply

* Re: [PATCH v2] staging: octeon: remove SPI, POW, PKO, and Helper typedef enums
From: Dan Carpenter @ 2026-04-15 12:32 UTC (permalink / raw)
  To: Maxwell Doose
  Cc: gregkh, tsbogend, len.bao, yoelvisoliveros, linux-mips,
	linux-kernel, linux-staging
In-Reply-To: <20260415122939.77847-1-m32285159@gmail.com>

On Wed, Apr 15, 2026 at 07:29:39AM -0500, Maxwell Doose wrote:
> This patch removes custom typedef enums and replaces them with standard
> enums to address the "General code review and cleanup" task in TODO.
> 
> The following enums are affected:
> 
> - cvmx_spi_mode_t (now enum cvmx_spi_mode)
> - cvmx_helper_interface_mode_t (now enum cvmx_helper_interface_mode_e)

Presumably the "_e" stands for enum?  Ugh.  No.  Don't do that.

regards,
dan carpenter


^ permalink raw reply

* [PATCH v2] staging: octeon: remove SPI, POW, PKO, and Helper typedef enums
From: Maxwell Doose @ 2026-04-15 12:29 UTC (permalink / raw)
  To: gregkh, tsbogend
  Cc: len.bao, yoelvisoliveros, linux-mips, linux-kernel, linux-staging

This patch removes custom typedef enums and replaces them with standard
enums to address the "General code review and cleanup" task in TODO.

The following enums are affected:

- cvmx_spi_mode_t (now enum cvmx_spi_mode)
- cvmx_helper_interface_mode_t (now enum cvmx_helper_interface_mode_e)
- cvmx_pow_wait_t (now enum cvmx_pow_wait)
- cvmx_pko_lock_t (now enum cvmx_pko_lock)
- cvmx_pko_status_t (now enum cvmx_pko_status)

This patch aligns the octeon codebase more closely with the Linux kernel
code style, and will address the "cleanup" task in TODO.

Signed-off-by: Maxwell Doose <m32285159@gmail.com>

---
v2:
 - Appended "_e" to enum cvmx_helper_interface_mode to prevent namespace
   collisions with a struct of the same name
 - Fixed errors that were indirect results of the namespace collisions

 .../executive/cvmx-helper-util.c              |  2 +-
 .../cavium-octeon/executive/cvmx-helper.c     |  8 ++---
 arch/mips/cavium-octeon/executive/cvmx-pko.c  |  6 ++--
 arch/mips/cavium-octeon/executive/cvmx-spi.c  | 16 ++++-----
 .../include/asm/octeon/cvmx-helper-util.h     |  2 +-
 arch/mips/include/asm/octeon/cvmx-helper.h    |  6 ++--
 arch/mips/include/asm/octeon/cvmx-pko.h       | 20 +++++------
 arch/mips/include/asm/octeon/cvmx-pow.h       | 12 +++----
 arch/mips/include/asm/octeon/cvmx-spi.h       | 32 ++++++++---------
 drivers/staging/octeon/ethernet.c             |  2 +-
 drivers/staging/octeon/octeon-ethernet.h      |  2 +-
 drivers/staging/octeon/octeon-stubs.h         | 36 +++++++++----------
 12 files changed, 72 insertions(+), 72 deletions(-)

diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-util.c b/arch/mips/cavium-octeon/executive/cvmx-helper-util.c
index 53b912745dbd..af09e2744e36 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-helper-util.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-util.c
@@ -52,7 +52,7 @@
  *
  * Returns String
  */
-const char *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t
+const char *cvmx_helper_interface_mode_to_string(enum cvmx_helper_interface_mode_e
 						 mode)
 {
 	switch (mode) {
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper.c b/arch/mips/cavium-octeon/executive/cvmx-helper.c
index 9abfc4bf9bd8..b7d037a94769 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-helper.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c
@@ -95,7 +95,7 @@ EXPORT_SYMBOL_GPL(cvmx_helper_ports_on_interface);
  * @INTERNAL
  * Return interface mode for CN68xx.
  */
-static cvmx_helper_interface_mode_t __cvmx_get_mode_cn68xx(int interface)
+static enum cvmx_helper_interface_mode_e __cvmx_get_mode_cn68xx(int interface)
 {
 	union cvmx_mio_qlmx_cfg qlm_cfg;
 	switch (interface) {
@@ -147,7 +147,7 @@ static cvmx_helper_interface_mode_t __cvmx_get_mode_cn68xx(int interface)
  * @INTERNAL
  * Return interface mode for an Octeon II
  */
-static cvmx_helper_interface_mode_t __cvmx_get_mode_octeon2(int interface)
+static enum cvmx_helper_interface_mode_e __cvmx_get_mode_octeon2(int interface)
 {
 	union cvmx_gmxx_inf_mode mode;
 
@@ -247,7 +247,7 @@ static cvmx_helper_interface_mode_t __cvmx_get_mode_octeon2(int interface)
  * @INTERNAL
  * Return interface mode for CN7XXX.
  */
-static cvmx_helper_interface_mode_t __cvmx_get_mode_cn7xxx(int interface)
+static enum cvmx_helper_interface_mode_e __cvmx_get_mode_cn7xxx(int interface)
 {
 	union cvmx_gmxx_inf_mode mode;
 
@@ -289,7 +289,7 @@ static cvmx_helper_interface_mode_t __cvmx_get_mode_cn7xxx(int interface)
  * Returns Mode of the interface. Unknown or unsupported interfaces return
  *	   DISABLED.
  */
-cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
+enum cvmx_helper_interface_mode_e cvmx_helper_interface_get_mode(int interface)
 {
 	union cvmx_gmxx_inf_mode mode;
 
diff --git a/arch/mips/cavium-octeon/executive/cvmx-pko.c b/arch/mips/cavium-octeon/executive/cvmx-pko.c
index 6e70b859a0ac..199746bc40de 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-pko.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-pko.c
@@ -120,7 +120,7 @@ static void __cvmx_pko_port_map_o68(void)
 {
 	int port;
 	int interface, index;
-	cvmx_helper_interface_mode_t mode;
+	enum cvmx_helper_interface_mode_e mode;
 	union cvmx_pko_mem_iport_ptrs config;
 
 	/*
@@ -323,11 +323,11 @@ EXPORT_SYMBOL_GPL(cvmx_pko_shutdown);
  *		     queues have higher priority than higher numbered queues.
  *		     There must be num_queues elements in the array.
  */
-cvmx_pko_status_t cvmx_pko_config_port(uint64_t port, uint64_t base_queue,
+enum cvmx_pko_status cvmx_pko_config_port(uint64_t port, uint64_t base_queue,
 				       uint64_t num_queues,
 				       const uint64_t priority[])
 {
-	cvmx_pko_status_t result_code;
+	enum cvmx_pko_status result_code;
 	uint64_t queue;
 	union cvmx_pko_mem_queue_ptrs config;
 	union cvmx_pko_reg_queue_ptrs1 config1;
diff --git a/arch/mips/cavium-octeon/executive/cvmx-spi.c b/arch/mips/cavium-octeon/executive/cvmx-spi.c
index eb9333e84a6b..b6c0b3fa73ad 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-spi.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-spi.c
@@ -102,7 +102,7 @@ void cvmx_spi_set_callbacks(cvmx_spi_callbacks_t *new_callbacks)
  *
  * Returns Zero on success, negative of failure.
  */
-int cvmx_spi_start_interface(int interface, cvmx_spi_mode_t mode, int timeout,
+int cvmx_spi_start_interface(int interface, enum cvmx_spi_mode mode, int timeout,
 			     int num_ports)
 {
 	int res = -1;
@@ -147,7 +147,7 @@ int cvmx_spi_start_interface(int interface, cvmx_spi_mode_t mode, int timeout,
  *
  * Returns Zero on success, negative of failure.
  */
-int cvmx_spi_restart_interface(int interface, cvmx_spi_mode_t mode, int timeout)
+int cvmx_spi_restart_interface(int interface, enum cvmx_spi_mode mode, int timeout)
 {
 	int res = -1;
 
@@ -192,7 +192,7 @@ EXPORT_SYMBOL_GPL(cvmx_spi_restart_interface);
  * Returns Zero on success, non-zero error code on failure (will cause
  * SPI initialization to abort)
  */
-int cvmx_spi_reset_cb(int interface, cvmx_spi_mode_t mode)
+int cvmx_spi_reset_cb(int interface, enum cvmx_spi_mode mode)
 {
 	union cvmx_spxx_dbg_deskew_ctl spxx_dbg_deskew_ctl;
 	union cvmx_spxx_clk_ctl spxx_clk_ctl;
@@ -308,7 +308,7 @@ int cvmx_spi_reset_cb(int interface, cvmx_spi_mode_t mode)
  * Returns Zero on success, non-zero error code on failure (will cause
  * SPI initialization to abort)
  */
-int cvmx_spi_calendar_setup_cb(int interface, cvmx_spi_mode_t mode,
+int cvmx_spi_calendar_setup_cb(int interface, enum cvmx_spi_mode mode,
 			       int num_ports)
 {
 	int port;
@@ -427,7 +427,7 @@ int cvmx_spi_calendar_setup_cb(int interface, cvmx_spi_mode_t mode,
  * Returns Zero on success, non-zero error code on failure (will cause
  * SPI initialization to abort)
  */
-int cvmx_spi_clock_detect_cb(int interface, cvmx_spi_mode_t mode, int timeout)
+int cvmx_spi_clock_detect_cb(int interface, enum cvmx_spi_mode mode, int timeout)
 {
 	int clock_transitions;
 	union cvmx_spxx_clk_stat stat;
@@ -505,7 +505,7 @@ int cvmx_spi_clock_detect_cb(int interface, cvmx_spi_mode_t mode, int timeout)
  * Returns Zero on success, non-zero error code on failure (will cause
  * SPI initialization to abort)
  */
-int cvmx_spi_training_cb(int interface, cvmx_spi_mode_t mode, int timeout)
+int cvmx_spi_training_cb(int interface, enum cvmx_spi_mode mode, int timeout)
 {
 	union cvmx_spxx_trn4_ctl spxx_trn4_ctl;
 	union cvmx_spxx_clk_stat stat;
@@ -574,7 +574,7 @@ int cvmx_spi_training_cb(int interface, cvmx_spi_mode_t mode, int timeout)
  * Returns Zero on success, non-zero error code on failure (will cause
  * SPI initialization to abort)
  */
-int cvmx_spi_calendar_sync_cb(int interface, cvmx_spi_mode_t mode, int timeout)
+int cvmx_spi_calendar_sync_cb(int interface, enum cvmx_spi_mode mode, int timeout)
 {
 	uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000;
 	if (mode & CVMX_SPI_MODE_RX_HALFPLEX) {
@@ -630,7 +630,7 @@ int cvmx_spi_calendar_sync_cb(int interface, cvmx_spi_mode_t mode, int timeout)
  * Returns Zero on success, non-zero error code on failure (will cause
  * SPI initialization to abort)
  */
-int cvmx_spi_interface_up_cb(int interface, cvmx_spi_mode_t mode)
+int cvmx_spi_interface_up_cb(int interface, enum cvmx_spi_mode mode)
 {
 	union cvmx_gmxx_rxx_frm_min gmxx_rxx_frm_min;
 	union cvmx_gmxx_rxx_frm_max gmxx_rxx_frm_max;
diff --git a/arch/mips/include/asm/octeon/cvmx-helper-util.h b/arch/mips/include/asm/octeon/cvmx-helper-util.h
index 97b27a07cfb0..239819102283 100644
--- a/arch/mips/include/asm/octeon/cvmx-helper-util.h
+++ b/arch/mips/include/asm/octeon/cvmx-helper-util.h
@@ -42,7 +42,7 @@
  * Returns String
  */
 extern const char
-    *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t mode);
+    *cvmx_helper_interface_mode_to_string(enum cvmx_helper_interface_mode_e mode);
 
 /**
  * Setup Random Early Drop to automatically begin dropping packets.
diff --git a/arch/mips/include/asm/octeon/cvmx-helper.h b/arch/mips/include/asm/octeon/cvmx-helper.h
index 0cddce35291b..2aa391a7b059 100644
--- a/arch/mips/include/asm/octeon/cvmx-helper.h
+++ b/arch/mips/include/asm/octeon/cvmx-helper.h
@@ -38,7 +38,7 @@
 #include <asm/octeon/cvmx-fpa.h>
 #include <asm/octeon/cvmx-wqe.h>
 
-typedef enum {
+enum cvmx_helper_interface_mode_e {
 	CVMX_HELPER_INTERFACE_MODE_DISABLED,
 	CVMX_HELPER_INTERFACE_MODE_RGMII,
 	CVMX_HELPER_INTERFACE_MODE_GMII,
@@ -49,7 +49,7 @@ typedef enum {
 	CVMX_HELPER_INTERFACE_MODE_PICMG,
 	CVMX_HELPER_INTERFACE_MODE_NPI,
 	CVMX_HELPER_INTERFACE_MODE_LOOP,
-} cvmx_helper_interface_mode_t;
+};
 
 union cvmx_helper_link_info {
 	uint64_t u64;
@@ -125,7 +125,7 @@ extern int cvmx_helper_get_number_of_interfaces(void);
  * Returns Mode of the interface. Unknown or unsupported interfaces return
  *	   DISABLED.
  */
-extern cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int
+extern enum cvmx_helper_interface_mode_e cvmx_helper_interface_get_mode(int
 								   interface);
 
 /**
diff --git a/arch/mips/include/asm/octeon/cvmx-pko.h b/arch/mips/include/asm/octeon/cvmx-pko.h
index f18a7f24daf8..a742c1d61d8f 100644
--- a/arch/mips/include/asm/octeon/cvmx-pko.h
+++ b/arch/mips/include/asm/octeon/cvmx-pko.h
@@ -80,7 +80,7 @@
 #define CVMX_PKO_ILLEGAL_QUEUE	0xFFFF
 #define CVMX_PKO_MAX_QUEUE_DEPTH 0
 
-typedef enum {
+enum cvmx_pko_status {
 	CVMX_PKO_SUCCESS,
 	CVMX_PKO_INVALID_PORT,
 	CVMX_PKO_INVALID_QUEUE,
@@ -88,12 +88,12 @@ typedef enum {
 	CVMX_PKO_NO_MEMORY,
 	CVMX_PKO_PORT_ALREADY_SETUP,
 	CVMX_PKO_CMD_QUEUE_INIT_ERROR
-} cvmx_pko_status_t;
+};
 
 /**
  * This enumeration represents the different locking modes supported by PKO.
  */
-typedef enum {
+enum cvmx_pko_lock {
 	/*
 	 * PKO doesn't do any locking. It is the responsibility of the
 	 * application to make sure that no other core is accessing
@@ -112,7 +112,7 @@ typedef enum {
 	 * ll/sc. This is the most portable locking mechanism.
 	 */
 	CVMX_PKO_LOCK_CMD_QUEUE = 2,
-} cvmx_pko_lock_t;
+};
 
 typedef struct {
 	uint32_t packets;
@@ -306,7 +306,7 @@ extern void cvmx_pko_shutdown(void);
  *		     of a value of 1. There must be num_queues elements in the
  *		     array.
  */
-extern cvmx_pko_status_t cvmx_pko_config_port(uint64_t port,
+extern enum cvmx_pko_status cvmx_pko_config_port(uint64_t port,
 					      uint64_t base_queue,
 					      uint64_t num_queues,
 					      const uint64_t priority[]);
@@ -374,7 +374,7 @@ static inline void cvmx_pko_doorbell(uint64_t port, uint64_t queue,
  */
 
 static inline void cvmx_pko_send_packet_prepare(uint64_t port, uint64_t queue,
-						cvmx_pko_lock_t use_locking)
+						enum cvmx_pko_lock use_locking)
 {
 	if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG) {
 		/*
@@ -414,12 +414,12 @@ static inline void cvmx_pko_send_packet_prepare(uint64_t port, uint64_t queue,
  * Returns: CVMX_PKO_SUCCESS on success, or error code on
  * failure of output
  */
-static inline cvmx_pko_status_t cvmx_pko_send_packet_finish(
+static inline enum cvmx_pko_status cvmx_pko_send_packet_finish(
 	uint64_t port,
 	uint64_t queue,
 	union cvmx_pko_command_word0 pko_command,
 	union cvmx_buf_ptr packet,
-	cvmx_pko_lock_t use_locking)
+	enum cvmx_pko_lock use_locking)
 {
 	cvmx_cmd_queue_result_t result;
 	if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
@@ -457,13 +457,13 @@ static inline cvmx_pko_status_t cvmx_pko_send_packet_finish(
  * Returns: CVMX_PKO_SUCCESS on success, or error code on
  * failure of output
  */
-static inline cvmx_pko_status_t cvmx_pko_send_packet_finish3(
+static inline enum cvmx_pko_status cvmx_pko_send_packet_finish3(
 	uint64_t port,
 	uint64_t queue,
 	union cvmx_pko_command_word0 pko_command,
 	union cvmx_buf_ptr packet,
 	uint64_t addr,
-	cvmx_pko_lock_t use_locking)
+	enum cvmx_pko_lock use_locking)
 {
 	cvmx_cmd_queue_result_t result;
 	if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
diff --git a/arch/mips/include/asm/octeon/cvmx-pow.h b/arch/mips/include/asm/octeon/cvmx-pow.h
index 21b4378244fa..409029809639 100644
--- a/arch/mips/include/asm/octeon/cvmx-pow.h
+++ b/arch/mips/include/asm/octeon/cvmx-pow.h
@@ -84,10 +84,10 @@ enum cvmx_pow_tag_type {
 /**
  * Wait flag values for pow functions.
  */
-typedef enum {
+enum cvmx_pow_wait {
 	CVMX_POW_WAIT = 1,
 	CVMX_POW_NO_WAIT = 0,
-} cvmx_pow_wait_t;
+};
 
 /**
  *  POW tag operations.	 These are used in the data stored to the POW.
@@ -1348,7 +1348,7 @@ static inline void cvmx_pow_tag_sw_wait(void)
  * Returns: the WQE pointer from POW. Returns NULL if no work
  * was available.
  */
-static inline struct cvmx_wqe *cvmx_pow_work_request_sync_nocheck(cvmx_pow_wait_t
+static inline struct cvmx_wqe *cvmx_pow_work_request_sync_nocheck(enum cvmx_pow_wait
 							     wait)
 {
 	cvmx_pow_load_addr_t ptr;
@@ -1382,7 +1382,7 @@ static inline struct cvmx_wqe *cvmx_pow_work_request_sync_nocheck(cvmx_pow_wait_
  * Returns: the WQE pointer from POW. Returns NULL if no work
  * was available.
  */
-static inline struct cvmx_wqe *cvmx_pow_work_request_sync(cvmx_pow_wait_t wait)
+static inline struct cvmx_wqe *cvmx_pow_work_request_sync(enum cvmx_pow_wait wait)
 {
 	if (CVMX_ENABLE_POW_CHECKS)
 		__cvmx_pow_warn_if_pending_switch(__func__);
@@ -1436,7 +1436,7 @@ static inline enum cvmx_pow_tag_type cvmx_pow_work_request_null_rd(void)
  *	  timeout), 0 to cause response to return immediately
  */
 static inline void cvmx_pow_work_request_async_nocheck(int scr_addr,
-						       cvmx_pow_wait_t wait)
+						       enum cvmx_pow_wait wait)
 {
 	cvmx_pow_iobdma_store_t data;
 
@@ -1465,7 +1465,7 @@ static inline void cvmx_pow_work_request_async_nocheck(int scr_addr,
  *		    timeout), 0 to cause response to return immediately
  */
 static inline void cvmx_pow_work_request_async(int scr_addr,
-					       cvmx_pow_wait_t wait)
+					       enum cvmx_pow_wait wait)
 {
 	if (CVMX_ENABLE_POW_CHECKS)
 		__cvmx_pow_warn_if_pending_switch(__func__);
diff --git a/arch/mips/include/asm/octeon/cvmx-spi.h b/arch/mips/include/asm/octeon/cvmx-spi.h
index d5038cc4b475..c9c8590e0a9a 100644
--- a/arch/mips/include/asm/octeon/cvmx-spi.h
+++ b/arch/mips/include/asm/octeon/cvmx-spi.h
@@ -36,35 +36,35 @@
 
 /* CSR typedefs have been moved to cvmx-csr-*.h */
 
-typedef enum {
+enum cvmx_spi_mode {
 	CVMX_SPI_MODE_UNKNOWN = 0,
 	CVMX_SPI_MODE_TX_HALFPLEX = 1,
 	CVMX_SPI_MODE_RX_HALFPLEX = 2,
 	CVMX_SPI_MODE_DUPLEX = 3
-} cvmx_spi_mode_t;
+};
 
 /** Callbacks structure to customize SPI4 initialization sequence */
 typedef struct {
     /** Called to reset SPI4 DLL */
-	int (*reset_cb) (int interface, cvmx_spi_mode_t mode);
+	int (*reset_cb) (int interface, enum cvmx_spi_mode mode);
 
     /** Called to setup calendar */
-	int (*calendar_setup_cb) (int interface, cvmx_spi_mode_t mode,
+	int (*calendar_setup_cb) (int interface, enum cvmx_spi_mode mode,
 				  int num_ports);
 
     /** Called for Tx and Rx clock detection */
-	int (*clock_detect_cb) (int interface, cvmx_spi_mode_t mode,
+	int (*clock_detect_cb) (int interface, enum cvmx_spi_mode mode,
 				int timeout);
 
     /** Called to perform link training */
-	int (*training_cb) (int interface, cvmx_spi_mode_t mode, int timeout);
+	int (*training_cb) (int interface, enum cvmx_spi_mode mode, int timeout);
 
     /** Called for calendar data synchronization */
-	int (*calendar_sync_cb) (int interface, cvmx_spi_mode_t mode,
+	int (*calendar_sync_cb) (int interface, enum cvmx_spi_mode mode,
 				 int timeout);
 
     /** Called when interface is up */
-	int (*interface_up_cb) (int interface, cvmx_spi_mode_t mode);
+	int (*interface_up_cb) (int interface, enum cvmx_spi_mode mode);
 
 } cvmx_spi_callbacks_t;
 
@@ -94,7 +94,7 @@ static inline int cvmx_spi_is_spi_interface(int interface)
  *
  * Returns Zero on success, negative of failure.
  */
-extern int cvmx_spi_start_interface(int interface, cvmx_spi_mode_t mode,
+extern int cvmx_spi_start_interface(int interface, enum cvmx_spi_mode mode,
 				    int timeout, int num_ports);
 
 /**
@@ -110,7 +110,7 @@ extern int cvmx_spi_start_interface(int interface, cvmx_spi_mode_t mode,
  * @timeout:   Timeout to wait for clock synchronization in seconds
  * Returns Zero on success, negative of failure.
  */
-extern int cvmx_spi_restart_interface(int interface, cvmx_spi_mode_t mode,
+extern int cvmx_spi_restart_interface(int interface, enum cvmx_spi_mode mode,
 				      int timeout);
 
 /**
@@ -180,7 +180,7 @@ extern void cvmx_spi_set_callbacks(cvmx_spi_callbacks_t *new_callbacks);
  * Returns Zero on success, non-zero error code on failure (will cause
  * SPI initialization to abort)
  */
-extern int cvmx_spi_reset_cb(int interface, cvmx_spi_mode_t mode);
+extern int cvmx_spi_reset_cb(int interface, enum cvmx_spi_mode mode);
 
 /**
  * Callback to setup calendar and miscellaneous settings before clock
@@ -197,7 +197,7 @@ extern int cvmx_spi_reset_cb(int interface, cvmx_spi_mode_t mode);
  * Returns Zero on success, non-zero error code on failure (will cause
  * SPI initialization to abort)
  */
-extern int cvmx_spi_calendar_setup_cb(int interface, cvmx_spi_mode_t mode,
+extern int cvmx_spi_calendar_setup_cb(int interface, enum cvmx_spi_mode mode,
 				      int num_ports);
 
 /**
@@ -214,7 +214,7 @@ extern int cvmx_spi_calendar_setup_cb(int interface, cvmx_spi_mode_t mode,
  * Returns Zero on success, non-zero error code on failure (will cause
  * SPI initialization to abort)
  */
-extern int cvmx_spi_clock_detect_cb(int interface, cvmx_spi_mode_t mode,
+extern int cvmx_spi_clock_detect_cb(int interface, enum cvmx_spi_mode mode,
 				    int timeout);
 
 /**
@@ -231,7 +231,7 @@ extern int cvmx_spi_clock_detect_cb(int interface, cvmx_spi_mode_t mode,
  * Returns Zero on success, non-zero error code on failure (will cause
  * SPI initialization to abort)
  */
-extern int cvmx_spi_training_cb(int interface, cvmx_spi_mode_t mode,
+extern int cvmx_spi_training_cb(int interface, enum cvmx_spi_mode mode,
 				int timeout);
 
 /**
@@ -248,7 +248,7 @@ extern int cvmx_spi_training_cb(int interface, cvmx_spi_mode_t mode,
  * Returns Zero on success, non-zero error code on failure (will cause
  * SPI initialization to abort)
  */
-extern int cvmx_spi_calendar_sync_cb(int interface, cvmx_spi_mode_t mode,
+extern int cvmx_spi_calendar_sync_cb(int interface, enum cvmx_spi_mode mode,
 				     int timeout);
 
 /**
@@ -264,6 +264,6 @@ extern int cvmx_spi_calendar_sync_cb(int interface, cvmx_spi_mode_t mode,
  * Returns Zero on success, non-zero error code on failure (will cause
  * SPI initialization to abort)
  */
-extern int cvmx_spi_interface_up_cb(int interface, cvmx_spi_mode_t mode);
+extern int cvmx_spi_interface_up_cb(int interface, enum cvmx_spi_mode mode);
 
 #endif /* __CVMX_SPI_H__ */
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index eadb74fc14c8..5a3fe651bc48 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -798,7 +798,7 @@ static int cvm_oct_probe(struct platform_device *pdev)
 
 	num_interfaces = cvmx_helper_get_number_of_interfaces();
 	for (interface = 0; interface < num_interfaces; interface++) {
-		cvmx_helper_interface_mode_t imode =
+		enum cvmx_helper_interface_mode_e imode =
 		    cvmx_helper_interface_get_mode(interface);
 		int num_ports = cvmx_helper_ports_on_interface(interface);
 		int port;
diff --git a/drivers/staging/octeon/octeon-ethernet.h b/drivers/staging/octeon/octeon-ethernet.h
index a6140705706f..d369c97c1332 100644
--- a/drivers/staging/octeon/octeon-ethernet.h
+++ b/drivers/staging/octeon/octeon-ethernet.h
@@ -57,7 +57,7 @@ struct octeon_ethernet {
 	struct net_device *netdev;
 	/*
 	 * Type of port. This is one of the enums in
-	 * cvmx_helper_interface_mode_t
+	 * cvmx_helper_interface_mode
 	 */
 	int imode;
 	/* PHY mode */
diff --git a/drivers/staging/octeon/octeon-stubs.h b/drivers/staging/octeon/octeon-stubs.h
index 291eaffd2543..e621cc6fcce4 100644
--- a/drivers/staging/octeon/octeon-stubs.h
+++ b/drivers/staging/octeon/octeon-stubs.h
@@ -215,14 +215,14 @@ enum cvmx_fau_op_size {
 	CVMX_FAU_OP_SIZE_64 = 3
 };
 
-typedef enum {
+enum cvmx_spi_mode {
 	CVMX_SPI_MODE_UNKNOWN = 0,
 	CVMX_SPI_MODE_TX_HALFPLEX = 1,
 	CVMX_SPI_MODE_RX_HALFPLEX = 2,
 	CVMX_SPI_MODE_DUPLEX = 3
-} cvmx_spi_mode_t;
+};
 
-typedef enum {
+enum cvmx_helper_interface_mode_e {
 	CVMX_HELPER_INTERFACE_MODE_DISABLED,
 	CVMX_HELPER_INTERFACE_MODE_RGMII,
 	CVMX_HELPER_INTERFACE_MODE_GMII,
@@ -233,20 +233,20 @@ typedef enum {
 	CVMX_HELPER_INTERFACE_MODE_PICMG,
 	CVMX_HELPER_INTERFACE_MODE_NPI,
 	CVMX_HELPER_INTERFACE_MODE_LOOP,
-} cvmx_helper_interface_mode_t;
+};
 
-typedef enum {
+enum cvmx_pow_wait {
 	CVMX_POW_WAIT = 1,
 	CVMX_POW_NO_WAIT = 0,
-} cvmx_pow_wait_t;
+};
 
-typedef enum {
+enum cvmx_pko_lock {
 	CVMX_PKO_LOCK_NONE = 0,
 	CVMX_PKO_LOCK_ATOMIC_TAG = 1,
 	CVMX_PKO_LOCK_CMD_QUEUE = 2,
-} cvmx_pko_lock_t;
+};
 
-typedef enum {
+enum cvmx_pko_status {
 	CVMX_PKO_SUCCESS,
 	CVMX_PKO_INVALID_PORT,
 	CVMX_PKO_INVALID_QUEUE,
@@ -254,7 +254,7 @@ typedef enum {
 	CVMX_PKO_NO_MEMORY,
 	CVMX_PKO_PORT_ALREADY_SETUP,
 	CVMX_PKO_CMD_QUEUE_INIT_ERROR
-} cvmx_pko_status_t;
+};
 
 enum cvmx_pow_tag_type {
 	CVMX_POW_TAG_TYPE_ORDERED   = 0L,
@@ -1267,7 +1267,7 @@ static inline void cvmx_pko_get_port_status(u64 port_num, u64 clear,
 					    cvmx_pko_port_status_t *status)
 { }
 
-static inline cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int
+static inline struct cvmx_helper_interface_mode cvmx_helper_interface_get_mode(int
 								   interface)
 {
 	return 0;
@@ -1344,11 +1344,11 @@ static inline unsigned int cvmx_get_core_num(void)
 }
 
 static inline void cvmx_pow_work_request_async_nocheck(int scr_addr,
-						       cvmx_pow_wait_t wait)
+						       enum cvmx_pow_wait wait)
 { }
 
 static inline void cvmx_pow_work_request_async(int scr_addr,
-					       cvmx_pow_wait_t wait)
+					       enum cvmx_pow_wait wait)
 { }
 
 static inline struct cvmx_wqe *cvmx_pow_work_response_async(int scr_addr)
@@ -1358,13 +1358,13 @@ static inline struct cvmx_wqe *cvmx_pow_work_response_async(int scr_addr)
 	return wqe;
 }
 
-static inline struct cvmx_wqe *cvmx_pow_work_request_sync(cvmx_pow_wait_t wait)
+static inline struct cvmx_wqe *cvmx_pow_work_request_sync(enum cvmx_pow_wait wait)
 {
 	return (void *)(unsigned long)wait;
 }
 
 static inline int cvmx_spi_restart_interface(int interface,
-					     cvmx_spi_mode_t mode, int timeout)
+					     enum cvmx_spi_mode mode, int timeout)
 {
 	return 0;
 }
@@ -1383,12 +1383,12 @@ static inline union cvmx_gmxx_rxx_rx_inbnd cvmx_spi4000_check_speed(int interfac
 }
 
 static inline void cvmx_pko_send_packet_prepare(u64 port, u64 queue,
-						cvmx_pko_lock_t use_locking)
+						enum cvmx_pko_lock use_locking)
 { }
 
-static inline cvmx_pko_status_t cvmx_pko_send_packet_finish(u64 port,
+static inline enum cvmx_pko_status cvmx_pko_send_packet_finish(u64 port,
 		u64 queue, union cvmx_pko_command_word0 pko_command,
-		union cvmx_buf_ptr packet, cvmx_pko_lock_t use_locking)
+		union cvmx_buf_ptr packet, enum cvmx_pko_lock use_locking)
 {
 	return 0;
 }
-- 
2.53.0


^ permalink raw reply related

* [PATCH] serial: base: do not disable TX on hangup for console ports
From: kpursoty @ 2026-04-15  8:01 UTC (permalink / raw)
  To: linux-serial@vger.kernel.org, gregkh@linuxfoundation.org,
	jirislaby@kernel.org
  Cc: linux-kernel@vger.kernel.org, linux-mips@vger.kernel.org,
	tsbogend@alpha.franken.de

serial_base_port_shutdown() calls serial_base_port_set_tx(false)
unconditionally. When a TTY hangup occurs on a port that is also a
registered kernel console, this permanently disables the console
transmitter.

uart_hangup() already guards against uart_change_pm(PM_OFF) for console
ports (see the uart_console() check in uart_hangup()). Apply the same
guard in serial_base_port_shutdown(): skip TX-disable if the port is a
registered console.

Without this fix, any path that calls uart_shutdown() on a console port
- including TIOCSCTTY with force=1 (as used by init systems such as
procd) - permanently silences all subsequent kernel console output.

Signed-off-by: Kervin Pursoty <kpursoty@proton.me>
---
 drivers/tty/serial/serial_port.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/serial_port.c b/drivers/tty/serial/serial_port.c
--- a/drivers/tty/serial/serial_port.c
+++ b/drivers/tty/serial/serial_port.c
@@ -110,5 +110,14 @@
 {
 	struct serial_port_device *port_dev = port->port_dev;

-	serial_base_port_set_tx(port, port_dev, false);
+	/*
+	 * Do not disable TX on a console port. When an init system calls
+	 * TIOCSCTTY with force=1, the kernel hangs up the previous session,
+	 * triggering uart_hangup() -> uart_shutdown() -> here. Stopping TX
+	 * kills all kernel console output permanently.
+	 * uart_hangup() already skips uart_change_pm(PM_OFF) for consoles
+	 * via uart_console(); apply the same guard here.
+	 */
+	if (!uart_console(port))
+		serial_base_port_set_tx(port, port_dev, false);
 }

 static DEFINE_RUNTIME_DEV_PM_OPS(serial_port_pm,


^ permalink raw reply

* [PATCH v3 2/2] clocksource: timer-econet-en751221: fix IRQ ack storm on interrupt handler
From: kpursoty @ 2026-04-15  7:53 UTC (permalink / raw)
  To: linux-kernel@vger.kernel.org, daniel.lezcano@linaro.org,
	tglx@linutronix.de
  Cc: linux-mips@vger.kernel.org, tsbogend@alpha.franken.de,
	cjd@cjdns.fr, naseefkm@gmail.com

The interrupt handler acked by writing the current count back to compare:

  iowrite32(ioread32(reg_count(cpu)), reg_compare(cpu));

Since the interrupt fires when count >= compare, and the counter advances
past the written value before the MMIO write reaches the peripheral, the
condition re-asserts on the same bus cycle. This causes a tight IRQ storm
on CPU0, stalling boot at T=62s (measured: boot never progresses past
clockevents registration).

The EcoNet GPL kernel (arch/mips/econet/time2.c, cputmr_timer_ack()) acks
by writing the *next* deadline, which puts count < compare and clears the
pending condition. Write U32_MAX (unreachable before set_next_event()
programs the real deadline), consistent with cevt_dev_init() which also
writes U32_MAX to park the compare register at init.

Fixes: 3b4c33ac87d0 ("clocksource/drivers: Add EcoNet Timer HPT driver")
Signed-off-by: Kervin Pursoty <kpursoty@proton.me>
Tested-by: Caleb James DeLisle <cjd@cjdns.fr>
---
v3: Add Tested-by from Caleb James DeLisle (tested on EN755221 hardware).
    No code changes since v2.

 drivers/clocksource/timer-econet-en751221.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/clocksource/timer-econet-en751221.c b/drivers/clocksource/timer-econet-en751221.c
--- a/drivers/clocksource/timer-econet-en751221.c
+++ b/drivers/clocksource/timer-econet-en751221.c
@@ -68,6 +68,10 @@ static irqreturn_t cevt_interrupt(int irq, void *dev_id)
 	if (!cevt_is_pending(cpu))
 		return IRQ_NONE;

-	iowrite32(ioread32(reg_count(cpu)), reg_compare(cpu));
+	/*
+	 * Ack: write a future value so count < compare, clearing the pending
+	 * condition. set_next_event() will program the real deadline.
+	 */
+	iowrite32(U32_MAX, reg_compare(cpu));
 	dev->event_handler(dev);
 	return IRQ_HANDLED;
 }


^ permalink raw reply

* [PATCH v3 1/2] clocksource: timer-econet-en751221: fix timer block mapping at boot
From: kpursoty @ 2026-04-15  7:53 UTC (permalink / raw)
  To: linux-kernel@vger.kernel.org, daniel.lezcano@linaro.org,
	tglx@linutronix.de
  Cc: linux-mips@vger.kernel.org, tsbogend@alpha.franken.de,
	cjd@cjdns.fr, naseefkm@gmail.com

timer_init() used DIV_ROUND_UP(num_possible_cpus(), 2) to determine how
many register blocks to iomap. At early boot with VPE-based SMP, MIPS
reports num_possible_cpus()=1 (VPEs not yet brought online), giving
num_blocks=1. Only membase[0] is then mapped via of_iomap.

The EN751627 SoC has 2 physical cores, each with 2 VPEs, giving NR_CPUS=4
and two timer register blocks (one per core). Each block serves two VPEs:
block 0 handles CPU0+CPU1 (core 0), block 1 handles CPU2+CPU3 (core 1).
The block count is a silicon constant: DIV_ROUND_UP(NR_CPUS, 2) = 2.

cevt_init() calls cevt_dev_init(i) for each possible CPU via
for_each_possible_cpu(). On EN7528/EN751627 with 4 VPEs, NR_CPUS=4 so
cevt_dev_init(2) is called. cevt_dev_init(2) writes to reg_compare(2)
which dereferences membase[2>>1] = membase[1], which is NULL:

  CPU 0 Unable to handle kernel paging request at virtual address 00000008
  epc : iowrite32+0x4/0x10
  ra  : cevt_dev_init+0x40/0x64

Fix: replace the runtime calculation with ECONET_NUM_BLOCKS, which is
DIV_ROUND_UP(NR_CPUS, 2) evaluated at compile time. This is the same
expression used to declare the membase[] array, so the loop bound and
array size are provably consistent. For NR_CPUS=4 this is always 2,
correctly mapping both register blocks regardless of how many VPEs are
visible at early boot.

Fixes: 3b4c33ac87d0 ("clocksource/drivers: Add EcoNet Timer HPT driver")
Signed-off-by: Kervin Pursoty <kpursoty@proton.me>
Reviewed-by: Caleb James DeLisle <cjd@cjdns.fr>
---
v3: No changes. Resent as v3 to keep version in sync with 2/2.
v2: Add Reviewed-by from Caleb James DeLisle.

 drivers/clocksource/timer-econet-en751221.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/clocksource/timer-econet-en751221.c b/drivers/clocksource/timer-econet-en751221.c
--- a/drivers/clocksource/timer-econet-en751221.c
+++ b/drivers/clocksource/timer-econet-en751221.c
@@ -160,5 +160,4 @@ static u64 notrace sched_clock_read(void)
 static int __init timer_init(struct device_node *np)
 {
-	int num_blocks = DIV_ROUND_UP(num_possible_cpus(), 2);
 	struct clk *clk;
 	int ret;

@@ -172,5 +171,5 @@ static int __init timer_init(struct device_node *np)

 	econet_timer.freq_hz = clk_get_rate(clk);

-	for (int i = 0; i < num_blocks; i++) {
+	for (int i = 0; i < ECONET_NUM_BLOCKS; i++) {
 		econet_timer.membase[i] = of_iomap(np, i);
 		if (!econet_timer.membase[i]) {
 			pr_err("%pOFn: failed to map register [%d]\n", np, i);

^ permalink raw reply

* Re: [PATCH] staging: octeon: remove SPI, POW, PKO, and Helper typedef enums
From: kernel test robot @ 2026-04-15  3:51 UTC (permalink / raw)
  To: Maxwell Doose, gregkh, tsbogend
  Cc: llvm, oe-kbuild-all, yoelvisoliveros, len.bao, linux-mips,
	linux-kernel, linux-staging
In-Reply-To: <20260412000226.2711800-1-m32285159@gmail.com>

Hi Maxwell,

kernel test robot noticed the following build errors:

[auto build test ERROR on staging/staging-testing]

url:    https://github.com/intel-lab-lkp/linux/commits/Maxwell-Doose/staging-octeon-remove-SPI-POW-PKO-and-Helper-typedef-enums/20260415-004127
base:   staging/staging-testing
patch link:    https://lore.kernel.org/r/20260412000226.2711800-1-m32285159%40gmail.com
patch subject: [PATCH] staging: octeon: remove SPI, POW, PKO, and Helper typedef enums
config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20260415/202604151159.fZkPsdWl-lkp@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260415/202604151159.fZkPsdWl-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202604151159.fZkPsdWl-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from drivers/staging/octeon/ethernet.c:23:
   In file included from drivers/staging/octeon/octeon-ethernet.h:41:
>> drivers/staging/octeon/octeon-stubs.h:1270:15: error: use of 'cvmx_helper_interface_mode' with tag type that does not match previous declaration
    1270 | static inline struct cvmx_helper_interface_mode cvmx_helper_interface_get_mode(int
         |               ^
   drivers/staging/octeon/octeon-stubs.h:225:6: note: previous use is here
     225 | enum cvmx_helper_interface_mode {
         |      ^
>> drivers/staging/octeon/octeon-stubs.h:1273:9: error: returning 'int' from a function with incompatible result type 'struct (unnamed struct at drivers/staging/octeon/octeon-stubs.h:1270:22)'
    1273 |         return 0;
         |                ^
   2 errors generated.


vim +/cvmx_helper_interface_mode +1270 drivers/staging/octeon/octeon-stubs.h

  1269	
> 1270	static inline struct cvmx_helper_interface_mode cvmx_helper_interface_get_mode(int
  1271									   interface)
  1272	{
> 1273		return 0;
  1274	}
  1275	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH] staging: octeon: remove SPI, POW, PKO, and Helper typedef enums
From: kernel test robot @ 2026-04-15  2:44 UTC (permalink / raw)
  To: Maxwell Doose, gregkh, tsbogend
  Cc: oe-kbuild-all, yoelvisoliveros, len.bao, linux-mips, linux-kernel,
	linux-staging
In-Reply-To: <20260412000226.2711800-1-m32285159@gmail.com>

Hi Maxwell,

kernel test robot noticed the following build warnings:

[auto build test WARNING on staging/staging-testing]

url:    https://github.com/intel-lab-lkp/linux/commits/Maxwell-Doose/staging-octeon-remove-SPI-POW-PKO-and-Helper-typedef-enums/20260415-004127
base:   staging/staging-testing
patch link:    https://lore.kernel.org/r/20260412000226.2711800-1-m32285159%40gmail.com
patch subject: [PATCH] staging: octeon: remove SPI, POW, PKO, and Helper typedef enums
config: nios2-allmodconfig (https://download.01.org/0day-ci/archive/20260415/202604151042.H0SJqN2r-lkp@intel.com/config)
compiler: nios2-linux-gcc (GCC) 11.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260415/202604151042.H0SJqN2r-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202604151042.H0SJqN2r-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from drivers/staging/octeon/octeon-ethernet.h:41,
                    from drivers/staging/octeon/ethernet.c:23:
   drivers/staging/octeon/octeon-stubs.h:1270:22: error: 'cvmx_helper_interface_mode' defined as wrong kind of tag
    1270 | static inline struct cvmx_helper_interface_mode cvmx_helper_interface_get_mode(int
         |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/staging/octeon/octeon-stubs.h:1270:49: error: return type is an incomplete type
    1270 | static inline struct cvmx_helper_interface_mode cvmx_helper_interface_get_mode(int
         |                                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/staging/octeon/octeon-stubs.h: In function 'cvmx_helper_interface_get_mode':
>> drivers/staging/octeon/octeon-stubs.h:1273:16: warning: 'return' with a value, in function returning void [-Wreturn-type]
    1273 |         return 0;
         |                ^
   drivers/staging/octeon/octeon-stubs.h:1270:49: note: declared here
    1270 | static inline struct cvmx_helper_interface_mode cvmx_helper_interface_get_mode(int
         |                                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/staging/octeon/ethernet.c: In function 'cvm_oct_common_change_mtu':
   drivers/staging/octeon/ethernet.c:252:14: error: void value not ignored as it ought to be
     252 |             (cvmx_helper_interface_get_mode(interface) !=
         |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/staging/octeon/ethernet.c: In function 'cvm_oct_common_set_multicast_list':
   drivers/staging/octeon/ethernet.c:298:14: error: void value not ignored as it ought to be
     298 |             (cvmx_helper_interface_get_mode(interface) !=
         |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/staging/octeon/ethernet.c: In function 'cvm_oct_set_mac_filter':
   drivers/staging/octeon/ethernet.c:350:14: error: void value not ignored as it ought to be
     350 |             (cvmx_helper_interface_get_mode(interface) !=
         |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/staging/octeon/ethernet.c: In function 'cvm_oct_probe':
   drivers/staging/octeon/ethernet.c:801:22: error: 'cvmx_helper_interface_mode' defined as wrong kind of tag
     801 |                 enum cvmx_helper_interface_mode imode =
         |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/staging/octeon/ethernet.c:801:22: error: variable 'imode' has initializer but incomplete type
   drivers/staging/octeon/ethernet.c:801:49: error: storage size of 'imode' isn't known
     801 |                 enum cvmx_helper_interface_mode imode =
         |                                                 ^~~~~
   drivers/staging/octeon/ethernet.c:801:49: warning: unused variable 'imode' [-Wunused-variable]
--
   In file included from drivers/staging/octeon/octeon-ethernet.h:41,
                    from drivers/staging/octeon/ethernet-mdio.c:15:
   drivers/staging/octeon/octeon-stubs.h:1270:22: error: 'cvmx_helper_interface_mode' defined as wrong kind of tag
    1270 | static inline struct cvmx_helper_interface_mode cvmx_helper_interface_get_mode(int
         |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/staging/octeon/octeon-stubs.h:1270:49: error: return type is an incomplete type
    1270 | static inline struct cvmx_helper_interface_mode cvmx_helper_interface_get_mode(int
         |                                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/staging/octeon/octeon-stubs.h: In function 'cvmx_helper_interface_get_mode':
>> drivers/staging/octeon/octeon-stubs.h:1273:16: warning: 'return' with a value, in function returning void [-Wreturn-type]
    1273 |         return 0;
         |                ^
   drivers/staging/octeon/octeon-stubs.h:1270:49: note: declared here
    1270 | static inline struct cvmx_helper_interface_mode cvmx_helper_interface_get_mode(int
         |                                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


vim +/return +1273 drivers/staging/octeon/octeon-stubs.h

422d97b8b05ed38 Chris Packham 2020-02-05  1269  
8912373dc44ef18 Maxwell Doose 2026-04-11 @1270  static inline struct cvmx_helper_interface_mode cvmx_helper_interface_get_mode(int
422d97b8b05ed38 Chris Packham 2020-02-05  1271  								   interface)
422d97b8b05ed38 Chris Packham 2020-02-05  1272  {
422d97b8b05ed38 Chris Packham 2020-02-05 @1273  	return 0;
422d97b8b05ed38 Chris Packham 2020-02-05  1274  }
422d97b8b05ed38 Chris Packham 2020-02-05  1275  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH] staging: octeon: remove SPI, POW, PKO, and Helper typedef enums
From: kernel test robot @ 2026-04-15  0:04 UTC (permalink / raw)
  To: Maxwell Doose, gregkh, tsbogend
  Cc: oe-kbuild-all, yoelvisoliveros, len.bao, linux-mips, linux-kernel,
	linux-staging
In-Reply-To: <20260412000226.2711800-1-m32285159@gmail.com>

Hi Maxwell,

kernel test robot noticed the following build errors:

[auto build test ERROR on staging/staging-testing]

url:    https://github.com/intel-lab-lkp/linux/commits/Maxwell-Doose/staging-octeon-remove-SPI-POW-PKO-and-Helper-typedef-enums/20260415-004127
base:   staging/staging-testing
patch link:    https://lore.kernel.org/r/20260412000226.2711800-1-m32285159%40gmail.com
patch subject: [PATCH] staging: octeon: remove SPI, POW, PKO, and Helper typedef enums
config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20260415/202604150717.26IAjbLy-lkp@intel.com/config)
compiler: sh4-linux-gcc (GCC) 15.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260415/202604150717.26IAjbLy-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202604150717.26IAjbLy-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

   In file included from drivers/staging/octeon/octeon-ethernet.h:41,
                    from drivers/staging/octeon/ethernet.c:23:
>> drivers/staging/octeon/octeon-stubs.h:1270:22: error: 'cvmx_helper_interface_mode' defined as wrong kind of tag
    1270 | static inline struct cvmx_helper_interface_mode cvmx_helper_interface_get_mode(int
         |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/staging/octeon/octeon-stubs.h:1270:49: error: return type is an incomplete type
    1270 | static inline struct cvmx_helper_interface_mode cvmx_helper_interface_get_mode(int
         |                                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/staging/octeon/octeon-stubs.h: In function 'cvmx_helper_interface_get_mode':
>> drivers/staging/octeon/octeon-stubs.h:1273:16: error: 'return' with a value, in function returning void [-Wreturn-mismatch]
    1273 |         return 0;
         |                ^
   drivers/staging/octeon/octeon-stubs.h:1270:49: note: declared here
    1270 | static inline struct cvmx_helper_interface_mode cvmx_helper_interface_get_mode(int
         |                                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/staging/octeon/ethernet.c: In function 'cvm_oct_common_change_mtu':
>> drivers/staging/octeon/ethernet.c:252:14: error: void value not ignored as it ought to be
     252 |             (cvmx_helper_interface_get_mode(interface) !=
         |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/staging/octeon/ethernet.c: In function 'cvm_oct_common_set_multicast_list':
   drivers/staging/octeon/ethernet.c:298:14: error: void value not ignored as it ought to be
     298 |             (cvmx_helper_interface_get_mode(interface) !=
         |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/staging/octeon/ethernet.c: In function 'cvm_oct_set_mac_filter':
   drivers/staging/octeon/ethernet.c:350:14: error: void value not ignored as it ought to be
     350 |             (cvmx_helper_interface_get_mode(interface) !=
         |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/staging/octeon/ethernet.c: In function 'cvm_oct_probe':
>> drivers/staging/octeon/ethernet.c:801:22: error: 'cvmx_helper_interface_mode' defined as wrong kind of tag
     801 |                 enum cvmx_helper_interface_mode imode =
         |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/staging/octeon/ethernet.c:802:21: error: variable 'imode' has initializer but incomplete type
     802 |                     cvmx_helper_interface_get_mode(interface);
         |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/staging/octeon/ethernet.c:801:49: error: storage size of 'imode' isn't known
     801 |                 enum cvmx_helper_interface_mode imode =
         |                                                 ^~~~~
>> drivers/staging/octeon/ethernet.c:801:49: warning: unused variable 'imode' [-Wunused-variable]
--
   In file included from drivers/staging/octeon/octeon-ethernet.h:41,
                    from drivers/staging/octeon/ethernet-mdio.c:15:
>> drivers/staging/octeon/octeon-stubs.h:1270:22: error: 'cvmx_helper_interface_mode' defined as wrong kind of tag
    1270 | static inline struct cvmx_helper_interface_mode cvmx_helper_interface_get_mode(int
         |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/staging/octeon/octeon-stubs.h:1270:49: error: return type is an incomplete type
    1270 | static inline struct cvmx_helper_interface_mode cvmx_helper_interface_get_mode(int
         |                                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/staging/octeon/octeon-stubs.h: In function 'cvmx_helper_interface_get_mode':
>> drivers/staging/octeon/octeon-stubs.h:1273:16: error: 'return' with a value, in function returning void [-Wreturn-mismatch]
    1273 |         return 0;
         |                ^
   drivers/staging/octeon/octeon-stubs.h:1270:49: note: declared here
    1270 | static inline struct cvmx_helper_interface_mode cvmx_helper_interface_get_mode(int
         |                                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


vim +/cvmx_helper_interface_mode +1270 drivers/staging/octeon/octeon-stubs.h

  1269	
> 1270	static inline struct cvmx_helper_interface_mode cvmx_helper_interface_get_mode(int
  1271									   interface)
  1272	{
> 1273		return 0;
  1274	}
  1275	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox