[RFC 11/12] powerpc/powernv: Rework OPAL console write to remove conditional locking

From: Ritesh Harjani (IBM)

Date: Sun Sep 27 2026 - 10:36:02 EST


Clang's context analysis reports:
opal.c:454:7: error: spinlock 'opal_write_lock' is not held on every path through here [-Werror,-Wthread-safety-analysis]
opal.c:493:3: error: releasing spinlock 'opal_write_lock' that was not held [-Werror,-Wthread-safety-analysis]

This patch rework the OPAL console write function to remove this
conditional locking to fix the reported build errors while enabling
Clang context analysis. We could have marked __context_unsafe(),
but this anyways simplifies the locking a bit.

Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@xxxxxxxxx>
---
arch/powerpc/platforms/powernv/opal.c | 30 ++++++++++++++++++---------
1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 1946dbdc9fa1..aea83c4be76d 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -438,19 +438,13 @@ ssize_t opal_get_chars(uint32_t vtermno, u8 *buf, size_t count)
return 0;
}

-static ssize_t __opal_put_chars(uint32_t vtermno, const u8 *data,
- size_t total_len, bool atomic)
+static ssize_t __opal_put_chars_unlocked(uint32_t vtermno, const u8 *data,
+ size_t total_len, bool atomic)
{
- unsigned long flags = 0 /* shut up gcc */;
ssize_t written;
__be64 olen;
s64 rc;

- if (!opal.entry)
- return -ENODEV;
-
- if (atomic)
- spin_lock_irqsave(&opal_write_lock, flags);
rc = opal_console_write_buffer_space(vtermno, &olen);
if (rc || be64_to_cpu(olen) < total_len) {
/* Closed -> drop characters */
@@ -489,10 +483,26 @@ static ssize_t __opal_put_chars(uint32_t vtermno, const u8 *data,
}

out:
- if (atomic)
+ return written;
+}
+
+static ssize_t __opal_put_chars(uint32_t vtermno, const u8 *data,
+ size_t total_len, bool atomic)
+{
+ unsigned long flags = 0;
+ ssize_t written;
+
+ if (!opal.entry)
+ return -ENODEV;
+
+ if (atomic) {
+ spin_lock_irqsave(&opal_write_lock, flags);
+ written = __opal_put_chars_unlocked(vtermno, data, total_len, true);
spin_unlock_irqrestore(&opal_write_lock, flags);
+ return written;
+ }

- return written;
+ return __opal_put_chars_unlocked(vtermno, data, total_len, false);
}

ssize_t opal_put_chars(uint32_t vtermno, const u8 *data, size_t total_len)
--
2.39.5