* Re: [PATCH] remoteproc: xlnx: check remote node state
From: Shah, Tanmay @ 2026-04-27 18:51 UTC (permalink / raw)
To: Mathieu Poirier, tanmay.shah
Cc: Padhi, Beleswar, michal.simek, andersson, linux-arm-kernel,
linux-kernel, linux-remoteproc
In-Reply-To: <ae-iTAk0KvtPvMSB@p14s>
On 4/27/2026 12:52 PM, Mathieu Poirier wrote:
> Good morning
>
> On Mon, Apr 27, 2026 at 11:15:29AM -0500, Shah, Tanmay wrote:
>> Hello Beleswar,
>>
>> Thanks for reviews. Please find my answer below:
>>
>> On 4/24/2026 10:51 PM, Padhi, Beleswar wrote:
>>> Hi Tanmay,
>>>
>>> In $subject-line, s/remote node/remoteproc
>>>
>>
>> Ack. 'node' is platform management firmware term, which might not be
>> right here. subject line already contains remoteproc so no need to have
>> it again. Instead, will replace 'node' with 'core'. new subject:
>>
>> remoteproc: xlnx: check remote core state.
>>
>
> Much better.
>
>>> On 4/25/2026 8:32 AM, Tanmay Shah wrote:
>>>> The remote state is set to RPROC_DETACHED if the resource table is found
>>>> in the memory. However, this can be wrong if the remote is not started,
>>>> but firmware is still loaded in the memory. Use PM_GET_NODE_STATUS call
>>>> to the firmware to request the state of the RPU node. If the RPU is
>>>> actually out of reset and running, only then move the remote state to
>>>> RPROC_DETACHED, otherwise keep the remote state to RPROC_OFFLINE.
>>>
>>>
>>> This is a good additional check. However, one thing to note is
[...]
>>>> +
>>>> + /*
>>>> + * If RPU state is power on and out of reset i.e. running, then
>>>> + * assign RPROC_DETACHED state. If the RPU is not out of reset
>>>> + * then do not attempt to attach to the remote processor.
>>>> + */
>>>> + if (status == PM_NODE_RUNNING) {
>>>> + if (zynqmp_r5_get_rsc_table_va(r5_core))
>>>> + dev_dbg(r5_core->dev, "rsc tbl not found\n");
>>>
>>>
>>> Do you still want to set state = RPROC_DETACHED if resource table is not
>>> found in the
>>> memory?
>>>
>>
>> Yes. Not all the firmware that is running on remote core is expected to
>> have the resource table. The firmware might not use RPMsg at all, and in
>> that case resource table becomes irrelevant. However, we still need to
>> make sure that running core is not reported as offline.
>
> Please add the above explanation to the inlined comment. Otherwise I'm good
> with this patch but I'll need an RB from Michael before moving forward.
>
Ack.
> Do you see this as a bug fix? Is there a point adding this patch to the stable
> kernels?
>
That's a good point. I should add Fixes tag as well, for the commit that
introduced attach-detach feature.
I will do that in v2.
Thanks,
Tanmay
>>
>> Thanks.
>>
>>> Thanks,
>>> Beleswar
>>>
>>>> + r5_core->rproc->state = RPROC_DETACHED;
>>>> + }
>>>> }
>>>> return 0;
>>>> diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/
>>>> firmware/xlnx-zynqmp.h
>>>> index d70dcd462b44..7e27b0f7bf7e 100644
>>>> --- a/include/linux/firmware/xlnx-zynqmp.h
>>>> +++ b/include/linux/firmware/xlnx-zynqmp.h
>>>> @@ -542,6 +542,18 @@ enum pm_gem_config_type {
>>>> GEM_CONFIG_FIXED = 2,
>>>> };
>>>> +/**
>>>> + * enum pm_node_status - Device node status provided by xilpm fw
>>>> + * @PM_NODE_UNUSED: Device is not used
>>>> + * @PM_NODE_RUNNING: Device is power-on and out of reset
>>>> + * @PM_NODE_HALT: Device is power-on but in the reset state
>>>> + */
>>>> +enum pm_node_status {
>>>> + PM_NODE_UNUSED = 0,
>>>> + PM_NODE_RUNNING = 1,
>>>> + PM_NODE_HALT = 12,
>>>> +};
>>>> +
>>>> /**
>>>> * struct zynqmp_pm_query_data - PM query data
>>>> * @qid: query ID
>>>> @@ -630,6 +642,8 @@ int zynqmp_pm_set_rpu_mode(u32 node_id, enum
>>>> rpu_oper_mode rpu_mode);
>>>> int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode);
>>>> int zynqmp_pm_get_node_status(const u32 node, u32 *const status,
>>>> u32 *const requirements, u32 *const usage);
>>>> +int zynqmp_pm_get_rpu_node_status(const u32 node, u32 *const status,
>>>> + u32 *const requirements, u32 *const usage);
>>>> int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config,
>>>> u32 value);
>>>> int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config,
>>>> u32 value);
>>>> @@ -939,6 +953,13 @@ static inline int zynqmp_pm_get_node_status(const
>>>> u32 node, u32 *const status,
>>>> return -ENODEV;
>>>> }
>>>> +static inline int zynqmp_pm_get_rpu_node_status(const u32 node, u32
>>>> *const status,
>>>> + u32 *const requirements,
>>>> + u32 *const usage)
>>>> +{
>>>> + return -ENODEV;
>>>> +}
>>>> +
>>>> static inline int zynqmp_pm_set_sd_config(u32 node,
>>>> enum pm_sd_config_type config,
>>>> u32 value)
>>>>
>>>> base-commit: 6f860d238b44da8ac57be25289b9f4410691c4e2
>>
^ permalink raw reply
* Re: [RFC PATCH v1 5/9] uaccess: Switch to copy_{to/from}_user_partial() when relevant
From: Linus Torvalds @ 2026-04-27 19:01 UTC (permalink / raw)
To: Christophe Leroy (CS GROUP)
Cc: Yury Norov, Andrew Morton, David Laight, Thomas Gleixner,
linux-alpha, linux-kernel, linux-snps-arc, linux-arm-kernel,
linux-mips, linuxppc-dev, kvm, linux-riscv, linux-s390,
sparclinux, linux-um, dmaengine, linux-efi, linux-fsi, amd-gfx,
dri-devel, intel-gfx, linux-wpan, netdev, linux-wireless,
linux-spi, linux-media, linux-staging, linux-serial, linux-usb,
xen-devel, linux-fsdevel, ocfs2-devel, bpf, kasan-dev, linux-mm,
linux-x25, rust-for-linux, linux-sound, sound-open-firmware,
linux-csky, linux-hexagon, loongarch, linux-m68k, linux-openrisc,
linux-parisc, linux-sh, linux-arch
In-Reply-To: <289b424e243ba2c4139ea04009cf8b9c448a87ff.1777306795.git.chleroy@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 6419 bytes --]
On Mon, 27 Apr 2026 at 10:18, Christophe Leroy (CS GROUP)
<chleroy@kernel.org> wrote:
>
> In a subsequent patch, copy_{to/from}_user() will be modified to
> return -EFAULT when copy fails.
Please don't do this.
This is a maintenance nightmare, and changes pretty much three decades
of semantics, and will cause *very* subtle backporting issues if
somebody happens to rely on the old / new behavior.
I understand the reasoning for the change, but I really don't think
the pain of creating yet another user copy interface is worth it.
We already have a lot of different versions of user copies for
different reasons, and while they all tend to have a good reason (and
some not-so-good, but historical reasons) for existing, this one
doesn't seem worth it.
The main - perhaps only - reason for this "partial" version is that
you want to do that "automatically inlined and optimized fixed-sized
case".
But here's the thing: I think you can already do that. Yes, it
requires some improvements to unsafe_copy_from_user(), but *that*
interface doesn't have three decades of history associated with it,
_and_ you're extending on that one anyway in this series.
"unsafe_copy_from_user()" is very odd, is meant only for small simple
copies that can be inlined and it's special-cased for 'objtool' anyway
(because objtool would have complained about an out-of-line call,
although it could have been special-cased other ways).
In other words: unsafe_copy_from_user() is *very* close to what you
want for that "Oh, I noticed that it's a small fixed-size copy, so I
want to special-case copy-from-user for that".
The _only_ issue with unsafe_copy_from_user() is that you can't see
that there were partial successes. But if *that* was fixed, then this
whole "create a new copy_from_user interface" issue would just go
away.
So please - let's just change unsafe_copy_from_user() to be usable for
the partial case.
And the thing is, all the existing unsafe_copy_from_user()
implementations already effectively *have* the "how much did I not
copy" internally, and they actually do extra work to hide it, ie they
have things like that
int _i;
that is "how many bytes have I copied" in the powerpc implementation,
or the x86 code does
size_t __ucu_len = (_len);
where that "ucu_len" is updated as you go along and is literally the
"how many bytes are left to copy" return value that is missing from
this interface.
So what I would suggest is
- introduce a new user accessor helper that is used for *both*
unsafe_copy_to/from_user() *and* the "inline small constant-sized
normal copy_to/from_user()" calls
- it's the same thing as the existing unsafe_copy_to/from_user()
implementation, except it exposes how many bytes are left to be copied
to the exception label.
IOW, it would look something like
#define unsafe_copy_to_user_outlen(_dst,_src,_len,label)...
which is exactly the same as the current unsafe_copy_to_user(),
*except* it changes "_len" as it does along.
And then you use that for both the "real" unsafe_copy_user and for the
"small constant values" case.
Just as an example, attached is a completely stupid rough draft of a
patch that does this for x86 and only for unsafe_copy_to_user().
And I made a very very hacky change to kernel/sys.c to see what the
code generation looks like.
This is what it results in on x86 with clang (with all the magic
.section data edited out):
... edited out the code to generate the times
... this is the actual user copy:
# HERE!
movabsq $81985529216486895, %rcx # imm = 0x123456789ABCDEF
cmpq %rcx, %rbx
cmovaq %rcx, %rbx
stac
movq %r13, (%rbx) # exception to .LBB45_8
movq %r14, 8(%rbx) # exception to .LBB45_8
movq %r15, 16(%rbx) # exception to .LBB45_8
movq %rax, 24(%rbx) # exception to .LBB45_8
clac
.LBB45_6:
movq jiffies(%rip), %rdi
callq jiffies_64_to_clock_t
.LBB45_7:
addq $16, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
.LBB45_8:
clac
movq $-14, %rax
jmp .LBB45_7
and notice how the compiler noticed that the 'outlen' isn't actually
used, and turned the exception label into just a "return -EFAULT" and
never actually generated any code for updating remaining lengths?
That actually looks pretty much optimal for a 32-byte user copy.
And it didn't involve changing the semantics at all.
Just to check, I changed that "times()" system call to return the
number of bytes uncopied instead (to emulate the "I actually want to
know what's left" case), and it generated this:
# HERE!
movabsq $81985529216486895, %rcx # imm = 0x123456789ABCDEF
cmpq %rcx, %rbx
cmovaq %rcx, %rbx
stac
movl $32, %ecx
movq %r13, (%rbx) # exception to .LBB45_7
movl $24, %ecx
movq %r15, 8(%rbx) # exception to .LBB45_7
movl $16, %ecx
movq %r14, 16(%rbx) # exception to .LBB45_7
movl $8, %ecx
movq %rax, 24(%rbx) # exception to .LBB45_7
clac
xorl %ecx, %ecx
.LBB45_8:
movq %rcx, %rax
addq $16, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
.LBB45_6:
movq jiffies(%rip), %rdi
jmp jiffies_64_to_clock_t # TAILCALL
.LBB45_7:
clac
jmp .LBB45_8
so it all seems to work - although obviously the above is *not* the normal case.
NOTE NOTE NOTE! The attached patch is entirely untested. I obviously
did some "test code generation" with it, but I only *looked* at the
result, and maybe it has some fundamental problem that I just didn't
notice. So treat this as a "how about this approach" patch, not as
anything more serious than that.
And the kerrnel/sys.c hack is very obviously just that: a complate
hack for testing.
A real patch would do that "for small constant-sized copies, turn
copy_to_user() automatically into "_small_copy_to_user()".
The attached is *not* a real patch. Treat it with the contempt it deserves.
Linus
[-- Attachment #2: patch.diff --]
[-- Type: text/x-patch, Size: 2637 bytes --]
arch/x86/include/asm/uaccess.h | 17 +++++++++++------
include/linux/uaccess.h | 16 ++++++++++++++++
kernel/sys.c | 3 ++-
3 files changed, 29 insertions(+), 7 deletions(-)
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index 3a0dd3c2b233..3b2c57c91418 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -606,15 +606,20 @@ _label: \
len -= sizeof(type); \
}
-#define unsafe_copy_to_user(_dst,_src,_len,label) \
+#define unsafe_copy_to_user_outlen(_dst,_src,_len,label) \
do { \
char __user *__ucu_dst = (_dst); \
const char *__ucu_src = (_src); \
- size_t __ucu_len = (_len); \
- unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u64, label); \
- unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u32, label); \
- unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u16, label); \
- unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u8, label); \
+ unsafe_copy_loop(__ucu_dst, __ucu_src, _len, u64, label); \
+ unsafe_copy_loop(__ucu_dst, __ucu_src, _len, u32, label); \
+ unsafe_copy_loop(__ucu_dst, __ucu_src, _len, u16, label); \
+ unsafe_copy_loop(__ucu_dst, __ucu_src, _len, u8, label); \
+} while (0)
+
+#define unsafe_copy_to_user(_dst,_src,_len,label) \
+do { \
+ size_t __ucu_len = _len; \
+ unsafe_copy_to_user_outlen(_dst,_src,__ucu_len,label); \
} while (0)
#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index 56328601218c..1a70ef70784c 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -874,4 +874,20 @@ void __noreturn usercopy_abort(const char *name, const char *detail,
unsigned long len);
#endif
+static __always_inline __must_check unsigned long
+_small_copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+ size_t uncopied = n;
+
+ might_fault();
+ if (should_fail_usercopy())
+ return n;
+ instrument_copy_to_user(to, from, n);
+ scoped_user_write_access_size(to, n, failed)
+ unsafe_copy_to_user_outlen(to, from, uncopied, failed);
+ return 0;
+failed:
+ return uncopied;
+}
+
#endif /* __LINUX_UACCESS_H__ */
diff --git a/kernel/sys.c b/kernel/sys.c
index 62e842055cc9..65b2d0103a73 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1067,7 +1067,8 @@ SYSCALL_DEFINE1(times, struct tms __user *, tbuf)
struct tms tmp;
do_sys_times(&tmp);
- if (copy_to_user(tbuf, &tmp, sizeof(struct tms)))
+ asm volatile("# HERE!");
+ if (_small_copy_to_user(tbuf, &tmp, sizeof(struct tms)))
return -EFAULT;
}
force_successful_syscall_return();
^ permalink raw reply related
* Re: [RFC PATCH v1 0/9] uaccess: Convert small fixed size copy_{to/from}_user() to scoped user access
From: Helge Deller @ 2026-04-27 19:01 UTC (permalink / raw)
To: Christophe Leroy (CS GROUP), Yury Norov, Andrew Morton,
Linus Torvalds, David Laight, Thomas Gleixner
Cc: linux-alpha, linux-kernel, linux-snps-arc, linux-arm-kernel,
linux-mips, linuxppc-dev, kvm, linux-riscv, linux-s390,
sparclinux, linux-um, dmaengine, linux-efi, linux-fsi, amd-gfx,
dri-devel, intel-gfx, linux-wpan, netdev, linux-wireless,
linux-spi, linux-media, linux-staging, linux-serial, linux-usb,
xen-devel, linux-fsdevel, ocfs2-devel, bpf, kasan-dev, linux-mm,
linux-x25, rust-for-linux, linux-sound, sound-open-firmware,
linux-csky, linux-hexagon, loongarch, linux-m68k, linux-openrisc,
linux-parisc, linux-sh, linux-arch
In-Reply-To: <cover.1777306795.git.chleroy@kernel.org>
Hello Christophe,
On 4/27/26 19:13, Christophe Leroy (CS GROUP) wrote:
> A lot of copy_from_user() and copy_to_user() perform copies of small
> fixed size pieces of data between kernel and userspace, and don't
> care about partial copies.
>
> copy_from_user() and copy_to_user() are big functions optimised for
> copying large amount of data, with cache management, etc ...
They take care of much more: alignments, exception handling (e.g. if userpage
is read-only and kernel writes to it), various rules when to return faults
(e.g. sometime reading from page0 is allowed for other arches not), and
much more. I've seen so many strange things during the last few years,
and you would need to get it right if you want to "make small" versions
of those functions.
> This is often overkill for small copies that could just be inlined
> instead.
Isn't put_user() and get_user() for that ?
And if you inline you need to take care of faults as well, so indirectly
you will add more fault handlers (or fault pointers) to the generated code,
effectively making the kernel bigger.
> What makes things a bit more tricky is that those copy functions
> are designed to handle partial copies in case of page fault. But among
> the 6000 callers of those functions, only 2% really care about the
> quantity of no-copied data that those functions return. All other ones
> fails as soon as the returned value is not 0, returning -EACCESS.
>
> So first step in this series is to introduce variants called
> copy_from_user_partial() and copy_to_user_partial() which will be
> called by the 2% users that care about the partial copy, then the
> original copy_from_user() and copy_to_user() are changed to return
> -EFAULT when the copy fails.
>
> Then the second step is to implement copy of small fixed-size data
> with scoped user access instead of calling the arch specific heavy
> user copy functions.
I'm not against your idea or your patch, but I wonder if you
really gain much from it.
Have you done some size or speed comparisons ?
Helge
> Patch 5, can be split in different patches for each archicture or
> subsystem, but let's get a first feedback and agree on the principle.
>
> Christophe Leroy (CS GROUP) (9):
> uaccess: Split check_zeroed_user() out of usercopy.c
> uaccess: Convert INLINE_COPY_{TO/FROM}_USER to kconfig and reduce
> ifdefery
> x86/umip: Be stricter in fixup_umip_exception()
> uaccess: Introduce copy_{to/from}_user_partial()
> uaccess: Switch to copy_{to/from}_user_partial() when relevant
> uaccess: Change copy_{to/from}_user to return -EFAULT
> x86: Add unsafe_copy_from_user()
> arm64: Add unsafe_copy_from_user()
> uaccess: Convert small fixed size copy_{to/from}_user() to scoped user
> access
>
> arch/alpha/Kconfig | 1 +
> arch/alpha/kernel/osf_sys.c | 4 +-
> arch/alpha/kernel/termios.c | 2 +-
> arch/arc/include/asm/uaccess.h | 3 -
> arch/arc/kernel/disasm.c | 2 +-
> arch/arm/include/asm/uaccess.h | 2 -
> arch/arm64/include/asm/gcs.h | 2 +-
> arch/arm64/include/asm/uaccess.h | 30 +++--
> arch/arm64/kernel/signal32.c | 2 +-
> arch/csky/Kconfig | 1 +
> arch/hexagon/include/asm/uaccess.h | 3 -
> arch/loongarch/include/asm/uaccess.h | 3 -
> arch/m68k/include/asm/uaccess.h | 3 -
> arch/microblaze/include/asm/uaccess.h | 2 -
> arch/mips/include/asm/uaccess.h | 3 -
> arch/mips/kernel/rtlx.c | 8 +-
> arch/mips/kernel/vpe.c | 2 +-
> arch/nios2/include/asm/uaccess.h | 2 -
> arch/openrisc/include/asm/uaccess.h | 2 -
> arch/parisc/include/asm/uaccess.h | 3 -
> arch/powerpc/Kconfig | 1 +
> arch/powerpc/kvm/book3s_64_mmu_hv.c | 4 +-
> arch/powerpc/kvm/book3s_64_mmu_radix.c | 4 +-
> arch/powerpc/kvm/book3s_hv.c | 2 +-
> arch/riscv/Kconfig | 1 +
> arch/riscv/kernel/signal.c | 2 +-
> arch/s390/include/asm/idals.h | 8 +-
> arch/s390/include/asm/uaccess.h | 3 -
> arch/sh/include/asm/uaccess.h | 2 -
> arch/sparc/include/asm/uaccess_32.h | 3 -
> arch/sparc/include/asm/uaccess_64.h | 2 -
> arch/sparc/kernel/termios.c | 2 +-
> arch/um/include/asm/uaccess.h | 3 -
> arch/um/kernel/process.c | 2 +-
> arch/x86/Kconfig | 1 +
> arch/x86/include/asm/uaccess.h | 29 ++++-
> arch/x86/kernel/umip.c | 2 +-
> arch/x86/lib/insn-eval.c | 2 +-
> arch/x86/um/signal.c | 2 +-
> arch/xtensa/include/asm/uaccess.h | 2 -
> drivers/android/binder_alloc.c | 2 +-
> drivers/comedi/comedi_fops.c | 4 +-
> drivers/dma/idxd/cdev.c | 2 +-
> drivers/firmware/efi/test/efi_test.c | 2 +-
> drivers/fsi/fsi-scom.c | 2 +-
> .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 2 +-
> drivers/gpu/drm/i915/gt/intel_sseu.c | 4 +-
> drivers/gpu/drm/i915/i915_gem.c | 4 +-
> drivers/hwtracing/intel_th/msu.c | 2 +-
> drivers/misc/ibmvmc.c | 2 +-
> drivers/misc/vmw_vmci/vmci_host.c | 2 +-
> drivers/most/most_cdev.c | 2 +-
> drivers/net/ieee802154/ca8210.c | 4 +-
> drivers/net/wireless/ath/wil6210/debugfs.c | 2 +-
> .../intel/iwlwifi/pcie/gen1_2/trans.c | 2 +-
> drivers/net/wireless/ti/wlcore/debugfs.c | 2 +-
> drivers/ps3/ps3-lpm.c | 2 +-
> drivers/s390/crypto/zcrypt_api.h | 4 +-
> drivers/spi/spidev.c | 2 +-
> .../staging/media/atomisp/pci/atomisp_cmd.c | 8 +-
> drivers/tty/tty_ioctl.c | 14 +--
> drivers/tty/vt/vc_screen.c | 4 +-
> drivers/usb/gadget/function/f_hid.c | 4 +-
> drivers/usb/gadget/function/f_printer.c | 2 +-
> drivers/vfio/vfio_iommu_type1.c | 4 +-
> drivers/xen/xenbus/xenbus_dev_frontend.c | 2 +-
> fs/namespace.c | 2 +-
> fs/ocfs2/dlmfs/dlmfs.c | 2 +-
> fs/proc/base.c | 4 +-
> include/asm-generic/uaccess.h | 2 -
> include/linux/bpfptr.h | 2 +-
> include/linux/sockptr.h | 4 +-
> include/linux/uaccess.h | 107 ++++++++++++++----
> ipc/msg.c | 8 +-
> ipc/sem.c | 8 +-
> ipc/shm.c | 18 +--
> kernel/regset.c | 2 +-
> kernel/sys.c | 4 +-
> lib/Kconfig | 3 +
> lib/Makefile | 4 +-
> lib/kfifo.c | 8 +-
> lib/{usercopy.c => usercheck.c} | 22 ----
> lib/usercopy.c | 66 -----------
> mm/kasan/kasan_test_c.c | 4 +-
> mm/memory.c | 2 +-
> net/x25/af_x25.c | 2 +-
> rust/helpers/uaccess.c | 6 +-
> sound/pci/emu10k1/emufx.c | 4 +-
> sound/pci/rme9652/hdsp.c | 6 +-
> sound/soc/intel/avs/probes.c | 6 +-
> sound/soc/sof/compress.c | 12 +-
> sound/soc/sof/sof-client-probes.c | 6 +-
> 92 files changed, 269 insertions(+), 288 deletions(-)
> copy lib/{usercopy.c => usercheck.c} (73%)
>
^ permalink raw reply
* Re: [PATCH net-next v7 3/4] dt-bindings: mfd: syscon: add ESWIN EIC7700 compatible
From: Conor Dooley @ 2026-04-27 19:05 UTC (permalink / raw)
To: lizhi2
Cc: devicetree, andrew+netdev, davem, edumazet, kuba, robh, krzk+dt,
conor+dt, netdev, pabeni, mcoquelin.stm32, alexandre.torgue,
rmk+kernel, pjw, palmer, aou, alex, linux-riscv, linux-stm32,
linux-arm-kernel, linux-kernel, maxime.chevallier, ningyu, linmin,
pinkesh.vaghela, pritesh.patel, weishangjuan, horms
In-Reply-To: <20260427072541.1174-1-lizhi2@eswincomputing.com>
[-- Attachment #1: Type: text/plain, Size: 323 bytes --]
On Mon, Apr 27, 2026 at 03:25:41PM +0800, lizhi2@eswincomputing.com wrote:
> From: Zhi Li <lizhi2@eswincomputing.com>
>
> Document ESWIN EIC7700 SoC compatible for syscon registers.
>
> Signed-off-by: Zhi Li <lizhi2@eswincomputing.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* [PATCH v3] iio: adc: mt6359: fix unchecked return value in mt6358_read_imp
From: Salah Triki @ 2026-04-27 19:08 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: linux-iio, linux-kernel, linux-arm-kernel, linux-mediatek,
Salah Triki
In mt6358_read_imp(), the variable val_v is passed to regmap_read()
but the return value is not checked. If the read fails, val_v remains
uninitialized and its random stack content is subsequently reported
as a measurement result.
Initialize val_v to zero to ensure a predictable value is reported
in case of bus failure and to prevent potential stack data leakage.
This also satisfies static analyzers that might otherwise flag the
variable as used uninitialized.
Fixes: 3587914bf61 ("iio: adc: Add support for MediaTek MT6357/8/9 Auxiliary ADC")
Signed-off-by: Salah Triki <salah.triki@gmail.com>
---
Changes in v3:
- Initialize val_v to zero at declaration instead of checking regmap_read()
return value, as suggested by Jonathan Cameron and Andy Shevchenko.
- Update commit message to reflect this new approach
Changes in v2:
- Added Fixes tag.
- Re-examined the entire driver for unchecked regmap operations.
While several regmap_write() and regmap_set_bits() calls also ignore
return values, I focused on this specific regmap_read() in
mt6358_read_imp() because it leads to an uninitialized variable usage
(val_v). This makes this fix critical for reporting correct data
to userspace
drivers/iio/adc/mt6359-auxadc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/mt6359-auxadc.c b/drivers/iio/adc/mt6359-auxadc.c
index 6b9ed9b1fde2..0e52effa55db 100644
--- a/drivers/iio/adc/mt6359-auxadc.c
+++ b/drivers/iio/adc/mt6359-auxadc.c
@@ -489,7 +489,7 @@ static int mt6358_read_imp(struct mt6359_auxadc *adc_dev,
const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info;
struct regmap *regmap = adc_dev->regmap;
u16 reg_adc0 = cinfo->regs[PMIC_AUXADC_ADC0];
- u32 val_v;
+ u32 val_v = 0;
int ret;
ret = mt6358_start_imp_conv(adc_dev, chan);
--
2.43.0
^ permalink raw reply related
* Re: [PATCH 3/3] wifi: mt76: remove mt76_get_of_data_from_mtd
From: Conor Dooley @ 2026-04-27 19:09 UTC (permalink / raw)
To: Rosen Penev
Cc: devicetree, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
Shayne Chen, Sean Wang, Johannes Berg, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Thomas Bogendoerfer,
open list:MEDIATEK MT76 WIRELESS LAN DRIVER,
open list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support, open list:MIPS
In-Reply-To: <20260427034427.881389-4-rosenp@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 4793 bytes --]
On Sun, Apr 26, 2026 at 08:44:27PM -0700, Rosen Penev wrote:
> mt76_get_of_data_from_mtd has been replaced by
> mt76_get_of_data_from_nvmem in all usages.
All users in the kernel, but what about other sources of devicetrees?
Those built into firmware etc? Are there none of those too?
Conor.
>
> Remove it to prevent people from using the deprecated
> mediatek,mtd-eeprom binding.
>
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---
> drivers/net/wireless/mediatek/mt76/eeprom.c | 87 -------------------
> drivers/net/wireless/mediatek/mt76/mt76.h | 1 -
> .../wireless/mediatek/mt76/mt7915/eeprom.c | 4 -
> 3 files changed, 92 deletions(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
> index afdb73661866..092804323d81 100644
> --- a/drivers/net/wireless/mediatek/mt76/eeprom.c
> +++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
> @@ -35,89 +35,6 @@ static int mt76_get_of_eeprom_data(struct mt76_dev *dev, void *eep, int len)
> return 0;
> }
>
> -int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len)
> -{
> -#ifdef CONFIG_MTD
> - struct device_node *np = dev->dev->of_node;
> - struct mtd_info *mtd;
> - const __be32 *list;
> - const char *part;
> - phandle phandle;
> - size_t retlen;
> - int size;
> - int ret;
> -
> - list = of_get_property(np, "mediatek,mtd-eeprom", &size);
> - if (!list)
> - return -ENOENT;
> -
> - phandle = be32_to_cpup(list++);
> - if (!phandle)
> - return -ENOENT;
> -
> - np = of_find_node_by_phandle(phandle);
> - if (!np)
> - return -EINVAL;
> -
> - part = of_get_property(np, "label", NULL);
> - if (!part)
> - part = np->name;
> -
> - mtd = get_mtd_device_nm(part);
> - if (IS_ERR(mtd)) {
> - ret = PTR_ERR(mtd);
> - goto out_put_node;
> - }
> -
> - if (size <= sizeof(*list)) {
> - ret = -EINVAL;
> - goto out_put_node;
> - }
> -
> - offset += be32_to_cpup(list);
> - ret = mtd_read(mtd, offset, len, &retlen, eep);
> - put_mtd_device(mtd);
> - if (mtd_is_bitflip(ret))
> - ret = 0;
> - if (ret) {
> - dev_err(dev->dev, "reading EEPROM from mtd %s failed: %i\n",
> - part, ret);
> - goto out_put_node;
> - }
> -
> - if (retlen < len) {
> - ret = -EINVAL;
> - goto out_put_node;
> - }
> -
> - if (of_property_read_bool(dev->dev->of_node, "big-endian")) {
> - u8 *data = (u8 *)eep;
> - int i;
> -
> - /* convert eeprom data in Little Endian */
> - for (i = 0; i < round_down(len, 2); i += 2)
> - put_unaligned_le16(get_unaligned_be16(&data[i]),
> - &data[i]);
> - }
> -
> -#ifdef CONFIG_NL80211_TESTMODE
> - dev->test_mtd.name = devm_kstrdup(dev->dev, part, GFP_KERNEL);
> - if (!dev->test_mtd.name) {
> - ret = -ENOMEM;
> - goto out_put_node;
> - }
> - dev->test_mtd.offset = offset;
> -#endif
> -
> -out_put_node:
> - of_node_put(np);
> - return ret;
> -#else
> - return -ENOENT;
> -#endif
> -}
> -EXPORT_SYMBOL_GPL(mt76_get_of_data_from_mtd);
> -
> int mt76_get_of_data_from_nvmem(struct mt76_dev *dev, void *eep,
> const char *cell_name, int len)
> {
> @@ -163,10 +80,6 @@ static int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int len)
> if (!ret)
> return 0;
>
> - ret = mt76_get_of_data_from_mtd(dev, eep, 0, len);
> - if (!ret)
> - return 0;
> -
> return mt76_get_of_data_from_nvmem(dev, eep, "eeprom", len);
> }
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
> index 527bef97e122..f447ecac664d 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> @@ -1339,7 +1339,6 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
>
> int mt76_eeprom_init(struct mt76_dev *dev, int len);
> int mt76_eeprom_override(struct mt76_phy *phy);
> -int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len);
> int mt76_get_of_data_from_nvmem(struct mt76_dev *dev, void *eep,
> const char *cell_name, int len);
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
> index eb92cbf1a284..c24e1276700b 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
> @@ -29,10 +29,6 @@ static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
>
> offs = is_mt7915(&dev->mt76) ? MT_EE_PRECAL : MT_EE_PRECAL_V2;
>
> - ret = mt76_get_of_data_from_mtd(mdev, dev->cal, offs, size);
> - if (!ret)
> - return ret;
> -
> ret = mt76_get_of_data_from_nvmem(mdev, dev->cal, "precal", size);
> if (!ret)
> return ret;
> --
> 2.54.0
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v5 05/10] drm/bridge: dw-hdmi-qp: Add HDMI 2.0 SCDC scrambling and high TMDS clock ratio support
From: Heiko Stuebner @ 2026-04-27 19:09 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Sandy Huang,
Andy Yan, Cristian Ciocaltea
Cc: kernel, dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip,
Diederik de Haas, Maud Spierings
In-Reply-To: <d3b5239b-e3d9-4d81-9220-d6057d670ff3@collabora.com>
Am Montag, 27. April 2026, 18:39:44 Mitteleuropäische Sommerzeit schrieb Cristian Ciocaltea:
> Hello Heiko,
>
> Thanks for the quick reviews!
>
> On 4/27/26 1:49 PM, Heiko Stuebner wrote:
> > Am Sonntag, 26. April 2026, 02:20:17 Mitteleuropäische Sommerzeit schrieb Cristian Ciocaltea:
> >> Enable HDMI 2.0 display modes (e.g. 4K@60Hz) by adding SCDC management
> >> for the high TMDS clock ratio and scrambling, required when the TMDS
> >> character rate exceeds the 340 MHz HDMI 1.4b limit.
> >>
> >> A periodic work item monitors the sink's scrambling status to recover
> >> from sink-side resets. On hotplug detect, if SCDC scrambling state is
> >> out of sync with the driver, trigger a CRTC reset to re-establish the
> >> link.
> >>
> >> Reject modes requiring TMDS rates above 600 MHz, as those fall in the
> >> HDMI 2.1 FRL domain which is not supported. In no_hpd configurations,
> >> further restrict to 340 MHz since SCDC requires a connected sink.
> >>
> >> Tested-by: Diederik de Haas <diederik@cknow-tech.com>
> >> Tested-by: Maud Spierings <maud_spierings@hotmail.com>
> >> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
> >> ---
> >> drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 188 ++++++++++++++++++++++++---
> >> 1 file changed, 172 insertions(+), 16 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> >> index d649a1cf07f5..c482a8e7da25 100644
> >> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> >> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> >> @@ -2,6 +2,7 @@
> >> /*
> >> * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd.
> >> * Copyright (c) 2024 Collabora Ltd.
> >> + * Copyright (c) 2025 Amazon.com, Inc. or its affiliates.
> >
> > I have no real clue about the inner workings of hdmi, but that line
> > does make me curious, because no part of the patch authorship does
> > mention Amazon ;-) .
>
> That was intentional: although the code was written by Collabora, the copyright
> belongs to Amazon.
They selected a nice chip then :-D
> > Also I think "or it's affiliates" might be way too broad, because this
> > can be essentially everyone. So noone in the future will know who to
> > ask on copyright questions.
> >
> > Similarly when _somebody_ comes forward with "I hold a copyright on this"
> > no-one could verify this claim as well.
> >
> > I somehow expect _one_ entity being specified, not possibly hundreds.
>
> Hmm, I followed the wording already used elsewhere in the kernel tree:
>
> $ git grep 'Copyright.*Amazon.*affiliates' | wc -l
> 93
>
> There appears to be only a single instance that omits “affiliates”:
>
> $ git grep 'Copyright.*Amazon' | grep -v affiliates
> drivers/power/supply/max14656_charger_detector.c: * Copyright (C) Amazon Technologies Inc. All rights reserved.
>
> Which was added nearly ten years ago, so I’m not sure it makes sense to adopt
> that form now.
>
> Actually, this seems to be fairly common among other vendors as well:
>
> $ git grep 'Copyright.*affiliates' | wc -l
> 1014
okay then ... if that is already used a lot, and nobody else complained
then it should be fine I guess :-) .
It just sounded strange to me when reading that earlier.
Thanks a lot for digging those stats up
Heiko
^ permalink raw reply
* Re: [PATCH v5 05/10] drm/bridge: dw-hdmi-qp: Add HDMI 2.0 SCDC scrambling and high TMDS clock ratio support
From: Heiko Stuebner @ 2026-04-27 19:10 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Sandy Huang,
Andy Yan, Cristian Ciocaltea
Cc: kernel, dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip,
Diederik de Haas, Maud Spierings
In-Reply-To: <20260426-dw-hdmi-qp-scramb-v5-5-d778e70c317b@collabora.com>
Am Sonntag, 26. April 2026, 02:20:17 Mitteleuropäische Sommerzeit schrieb Cristian Ciocaltea:
> Enable HDMI 2.0 display modes (e.g. 4K@60Hz) by adding SCDC management
> for the high TMDS clock ratio and scrambling, required when the TMDS
> character rate exceeds the 340 MHz HDMI 1.4b limit.
>
> A periodic work item monitors the sink's scrambling status to recover
> from sink-side resets. On hotplug detect, if SCDC scrambling state is
> out of sync with the driver, trigger a CRTC reset to re-establish the
> link.
>
> Reject modes requiring TMDS rates above 600 MHz, as those fall in the
> HDMI 2.1 FRL domain which is not supported. In no_hpd configurations,
> further restrict to 340 MHz since SCDC requires a connected sink.
>
> Tested-by: Diederik de Haas <diederik@cknow-tech.com>
> Tested-by: Maud Spierings <maud_spierings@hotmail.com>
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
The change looks fine to my semi-trained eye, so even with my copyright
concern addressed, I can only provide an
Acked-by: Heiko Stuebner <heiko@sntech.de>
^ permalink raw reply
* Re: [PATCH v2 1/4] dt-bindings: timer: allwinner,sun5i-a13-hstimer: add H616 and D1
From: Conor Dooley @ 2026-04-27 19:16 UTC (permalink / raw)
To: Michal Piekos
Cc: Daniel Lezcano, Thomas Gleixner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
Maxime Ripard, linux-kernel, devicetree, linux-arm-kernel,
linux-sunxi
In-Reply-To: <20260426-h616-t113s-hstimer-v2-1-e65e9dc0c9da@mmpsystems.pl>
[-- Attachment #1: Type: text/plain, Size: 1823 bytes --]
On Sun, Apr 26, 2026 at 12:15:26PM +0200, Michal Piekos wrote:
> D1 is similar to existing sun5i, but with different register offsets.
> H616 uses same offsets as D1.
>
> Add allwinner,sun20i-d1-hstimer
> Add allwinner,sun50i-h616-hstimer with fallback to
> allwinner,sun20i-d1-hstimer
> Extend schema condition for interrupts to cover D1 compatible variant.
>
> Signed-off-by: Michal Piekos <michal.piekos@mmpsystems.pl>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable
> ---
> .../devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.yaml | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.yaml b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.yaml
> index f1853daec2f9..3e2725c56995 100644
> --- a/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.yaml
> +++ b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.yaml
> @@ -15,9 +15,13 @@ properties:
> oneOf:
> - const: allwinner,sun5i-a13-hstimer
> - const: allwinner,sun7i-a20-hstimer
> + - const: allwinner,sun20i-d1-hstimer
> - items:
> - const: allwinner,sun6i-a31-hstimer
> - const: allwinner,sun7i-a20-hstimer
> + - items:
> + - const: allwinner,sun50i-h616-hstimer
> + - const: allwinner,sun20i-d1-hstimer
>
> reg:
> maxItems: 1
> @@ -45,7 +49,10 @@ required:
> if:
> properties:
> compatible:
> - const: allwinner,sun5i-a13-hstimer
> + anyOf:
> + - const: allwinner,sun5i-a13-hstimer
> + - contains:
> + const: allwinner,sun20i-d1-hstimer
>
> then:
> properties:
>
> --
> 2.43.0
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH 3/3] wifi: mt76: remove mt76_get_of_data_from_mtd
From: Rosen Penev @ 2026-04-27 19:17 UTC (permalink / raw)
To: Conor Dooley
Cc: devicetree, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
Shayne Chen, Sean Wang, Johannes Berg, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Thomas Bogendoerfer,
open list:MEDIATEK MT76 WIRELESS LAN DRIVER,
open list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support, open list:MIPS
In-Reply-To: <20260427-hug-baboon-d60bb8fdfa51@spud>
On Mon, Apr 27, 2026 at 12:09 PM Conor Dooley <conor@kernel.org> wrote:
>
> On Sun, Apr 26, 2026 at 08:44:27PM -0700, Rosen Penev wrote:
> > mt76_get_of_data_from_mtd has been replaced by
> > mt76_get_of_data_from_nvmem in all usages.
>
> All users in the kernel, but what about other sources of devicetrees?
> Those built into firmware etc? Are there none of those too?
I'm actively removing those: https://github.com/openwrt/openwrt/pull/23113
Anyway, irrelevant here.
>
> Conor.
>
> >
> > Remove it to prevent people from using the deprecated
> > mediatek,mtd-eeprom binding.
> >
> > Signed-off-by: Rosen Penev <rosenp@gmail.com>
> > ---
> > drivers/net/wireless/mediatek/mt76/eeprom.c | 87 -------------------
> > drivers/net/wireless/mediatek/mt76/mt76.h | 1 -
> > .../wireless/mediatek/mt76/mt7915/eeprom.c | 4 -
> > 3 files changed, 92 deletions(-)
> >
> > diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
> > index afdb73661866..092804323d81 100644
> > --- a/drivers/net/wireless/mediatek/mt76/eeprom.c
> > +++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
> > @@ -35,89 +35,6 @@ static int mt76_get_of_eeprom_data(struct mt76_dev *dev, void *eep, int len)
> > return 0;
> > }
> >
> > -int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len)
> > -{
> > -#ifdef CONFIG_MTD
> > - struct device_node *np = dev->dev->of_node;
> > - struct mtd_info *mtd;
> > - const __be32 *list;
> > - const char *part;
> > - phandle phandle;
> > - size_t retlen;
> > - int size;
> > - int ret;
> > -
> > - list = of_get_property(np, "mediatek,mtd-eeprom", &size);
> > - if (!list)
> > - return -ENOENT;
> > -
> > - phandle = be32_to_cpup(list++);
> > - if (!phandle)
> > - return -ENOENT;
> > -
> > - np = of_find_node_by_phandle(phandle);
> > - if (!np)
> > - return -EINVAL;
> > -
> > - part = of_get_property(np, "label", NULL);
> > - if (!part)
> > - part = np->name;
> > -
> > - mtd = get_mtd_device_nm(part);
> > - if (IS_ERR(mtd)) {
> > - ret = PTR_ERR(mtd);
> > - goto out_put_node;
> > - }
> > -
> > - if (size <= sizeof(*list)) {
> > - ret = -EINVAL;
> > - goto out_put_node;
> > - }
> > -
> > - offset += be32_to_cpup(list);
> > - ret = mtd_read(mtd, offset, len, &retlen, eep);
> > - put_mtd_device(mtd);
> > - if (mtd_is_bitflip(ret))
> > - ret = 0;
> > - if (ret) {
> > - dev_err(dev->dev, "reading EEPROM from mtd %s failed: %i\n",
> > - part, ret);
> > - goto out_put_node;
> > - }
> > -
> > - if (retlen < len) {
> > - ret = -EINVAL;
> > - goto out_put_node;
> > - }
> > -
> > - if (of_property_read_bool(dev->dev->of_node, "big-endian")) {
> > - u8 *data = (u8 *)eep;
> > - int i;
> > -
> > - /* convert eeprom data in Little Endian */
> > - for (i = 0; i < round_down(len, 2); i += 2)
> > - put_unaligned_le16(get_unaligned_be16(&data[i]),
> > - &data[i]);
> > - }
> > -
> > -#ifdef CONFIG_NL80211_TESTMODE
> > - dev->test_mtd.name = devm_kstrdup(dev->dev, part, GFP_KERNEL);
> > - if (!dev->test_mtd.name) {
> > - ret = -ENOMEM;
> > - goto out_put_node;
> > - }
> > - dev->test_mtd.offset = offset;
> > -#endif
> > -
> > -out_put_node:
> > - of_node_put(np);
> > - return ret;
> > -#else
> > - return -ENOENT;
> > -#endif
> > -}
> > -EXPORT_SYMBOL_GPL(mt76_get_of_data_from_mtd);
> > -
> > int mt76_get_of_data_from_nvmem(struct mt76_dev *dev, void *eep,
> > const char *cell_name, int len)
> > {
> > @@ -163,10 +80,6 @@ static int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int len)
> > if (!ret)
> > return 0;
> >
> > - ret = mt76_get_of_data_from_mtd(dev, eep, 0, len);
> > - if (!ret)
> > - return 0;
> > -
> > return mt76_get_of_data_from_nvmem(dev, eep, "eeprom", len);
> > }
> >
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
> > index 527bef97e122..f447ecac664d 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> > +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> > @@ -1339,7 +1339,6 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
> >
> > int mt76_eeprom_init(struct mt76_dev *dev, int len);
> > int mt76_eeprom_override(struct mt76_phy *phy);
> > -int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len);
> > int mt76_get_of_data_from_nvmem(struct mt76_dev *dev, void *eep,
> > const char *cell_name, int len);
> >
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
> > index eb92cbf1a284..c24e1276700b 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
> > +++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
> > @@ -29,10 +29,6 @@ static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
> >
> > offs = is_mt7915(&dev->mt76) ? MT_EE_PRECAL : MT_EE_PRECAL_V2;
> >
> > - ret = mt76_get_of_data_from_mtd(mdev, dev->cal, offs, size);
> > - if (!ret)
> > - return ret;
> > -
> > ret = mt76_get_of_data_from_nvmem(mdev, dev->cal, "precal", size);
> > if (!ret)
> > return ret;
> > --
> > 2.54.0
> >
^ permalink raw reply
* Re: [RFC PATCH v1 7/9] x86: Add unsafe_copy_from_user()
From: Yury Norov @ 2026-04-27 19:19 UTC (permalink / raw)
To: Christophe Leroy (CS GROUP)
Cc: Andrew Morton, Linus Torvalds, David Laight, Thomas Gleixner,
linux-alpha, Yury Norov, linux-kernel, linux-snps-arc,
linux-arm-kernel, linux-mips, linuxppc-dev, kvm, linux-riscv,
linux-s390, sparclinux, linux-um, dmaengine, linux-efi, linux-fsi,
amd-gfx, dri-devel, intel-gfx, linux-wpan, netdev, linux-wireless,
linux-spi, linux-media, linux-staging, linux-serial, linux-usb,
xen-devel, linux-fsdevel, ocfs2-devel, bpf, kasan-dev, linux-mm,
linux-x25, rust-for-linux, linux-sound, sound-open-firmware,
linux-csky, linux-hexagon, loongarch, linux-m68k, linux-openrisc,
linux-parisc, linux-sh, linux-arch
In-Reply-To: <63a4d0f6-0eb3-48cd-9f98-bf7b223b2606@kernel.org>
On Mon, Apr 27, 2026 at 08:20:38PM +0200, Christophe Leroy (CS GROUP) wrote:
>
>
> Le 27/04/2026 à 19:58, Yury Norov a écrit :
> > On Mon, Apr 27, 2026 at 07:13:48PM +0200, Christophe Leroy (CS GROUP) wrote:
> > > At the time being, x86 and arm64 are missing unsafe_copy_from_user().
> >
> > No, they don't. They (should) rely on a generic implementation from
> > linux/uaccess.h, like every other arch, except for PPC and RISCV.
> >
> > But they #define arch_unsafe_get_user, and the unsafe_copy_from_user()
> > becomes undefined conditionally on that.
> >
> > So please, fix that bug instead of introducing another arch flavor.
> > We'd always choose generic version, unless there's strong evidence
> > that arch one is better.
>
> But they both implement the exact same unsafe_copy_to_user(). What is the
> difference here ?
>
> Should that function become generic too ?
This is what Linus said when added x86 implementation for copy_from_user()
in c512c69187197:
Note that it only does this [arch version] for the copying _to_ user space,
and we still don't have a unsafe version of copy_from_user().
That's partly because we have no current users of it, but also partly
because the copy_from_user() case is slightly different and cannot
efficiently be implemented in terms of a unsafe_get_user() loop (because
gcc can't do asm goto with outputs).
In the unsafe_copy_to_user case, arch versions were justified. Just as
said, I'm not against arch version for unsafe_copy_from_user(), but it
should be explained very well.
^ permalink raw reply
* Re: [PATCH v13 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
From: Shenwei Wang @ 2026-04-27 19:23 UTC (permalink / raw)
To: Padhi, Beleswar, Linus Walleij, Bartosz Golaszewski,
Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer
Cc: Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org, dl-linux-imx,
Bartosz Golaszewski, Andrew Lunn
In-Reply-To: <22fb5fac-2568-42be-a7e3-7e89d0017eb3@ti.com>
> -----Original Message-----
> From: Padhi, Beleswar <b-padhi@ti.com>
> Sent: Sunday, April 26, 2026 7:44 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>; Linus Walleij
> <linusw@kernel.org>; Bartosz Golaszewski <brgl@kernel.org>; Jonathan Corbet
> <corbet@lwn.net>; Rob Herring <robh@kernel.org>; Krzysztof Kozlowski
> <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>; Bjorn Andersson
> <andersson@kernel.org>; Mathieu Poirier <mathieu.poirier@linaro.org>; Frank Li
> <frank.li@nxp.com>; Sascha Hauer <s.hauer@pengutronix.de>
> Cc: Shuah Khan <skhan@linuxfoundation.org>; linux-gpio@vger.kernel.org; linux-
> doc@vger.kernel.org; linux-kernel@vger.kernel.org; Pengutronix Kernel Team
> <kernel@pengutronix.de>; Fabio Estevam <festevam@gmail.com>; Peng Fan
> <peng.fan@nxp.com>; devicetree@vger.kernel.org; linux-
> remoteproc@vger.kernel.org; imx@lists.linux.dev; linux-arm-
> kernel@lists.infradead.org; dl-linux-imx <linux-imx@nxp.com>; Bartosz
> Golaszewski <brgl@bgdev.pl>; Andrew Lunn <andrew@lunn.ch>
> Subject: [EXT] Re: [PATCH v13 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> Hello Shenwei, Greetings,
>
> On 4/23/2026 2:58 AM, Shenwei Wang wrote:
> > On an AMP platform, the system may include two processors:
>
>
> s/two/multiple
>
> > - An MCU running an RTOS
>
>
> s/An MCU/MCUs
>
> > - An MPU running Linux
> >
> > These processors communicate via the RPMSG protocol.
> > The driver implements the standard GPIO interface, allowing the Linux
> > side to control GPIO controllers which reside in the remote processor
> > via RPMSG protocol.
> >
> > Cc: Bartosz Golaszewski <brgl@bgdev.pl>
> > Cc: Andrew Lunn <andrew@lunn.ch>
> > Signed-off-by: Shenwei Wang <shenwei.wang@nxp.com>
> > ---
> > drivers/gpio/Kconfig | 17 ++
> > drivers/gpio/Makefile | 1 +
> > drivers/gpio/gpio-rpmsg.c | 573
> ++++++++++++++++++++++++++++++++++++++
> > 3 files changed, 591 insertions(+)
> > create mode 100644 drivers/gpio/gpio-rpmsg.c
> >
> > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index
> > 020e51e30317..4ad299fe3c6f 100644
> > --- a/drivers/gpio/Kconfig
> > +++ b/drivers/gpio/Kconfig
> > @@ -1917,6 +1917,23 @@ config GPIO_SODAVILLE
> >
> > endmenu
> >
> > +menu "RPMSG GPIO drivers"
> > + depends on RPMSG
> > +
> > +config GPIO_RPMSG
> > + tristate "Generic RPMSG GPIO support"
> > + depends on OF && REMOTEPROC
> > + select GPIOLIB_IRQCHIP
> > + default REMOTEPROC
> > + help
> > + Say yes here to support the generic GPIO functions over the RPMSG
> > + bus. Currently supported devices: i.MX7ULP, i.MX8ULP, i.MX8x, and
> > + i.MX9x.
> > +
> > + If unsure, say N.
> > +
> > +endmenu
> > +
> > menu "SPI GPIO expanders"
> > depends on SPI_MASTER
> >
> > diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index
> > b267598b517d..ee75c0e65b8b 100644
> > --- a/drivers/gpio/Makefile
> > +++ b/drivers/gpio/Makefile
> > @@ -157,6 +157,7 @@ obj-$(CONFIG_GPIO_RDC321X) += gpio-
> rdc321x.o
> > obj-$(CONFIG_GPIO_REALTEK_OTTO) += gpio-realtek-otto.o
> > obj-$(CONFIG_GPIO_REG) += gpio-reg.o
> > obj-$(CONFIG_GPIO_ROCKCHIP) += gpio-rockchip.o
> > +obj-$(CONFIG_GPIO_RPMSG) += gpio-rpmsg.o
> > obj-$(CONFIG_GPIO_RTD) += gpio-rtd.o
> > obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
> > obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio-sama5d2-piobu.o
> > diff --git a/drivers/gpio/gpio-rpmsg.c b/drivers/gpio/gpio-rpmsg.c new
> > file mode 100644 index 000000000000..993cde7af2fa
> > --- /dev/null
> > +++ b/drivers/gpio/gpio-rpmsg.c
> > @@ -0,0 +1,573 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright 2026 NXP
> > + *
> > + * The driver exports a standard gpiochip interface to control
> > + * the GPIO controllers via RPMSG on a remote processor.
> > + */
> > +
> > +#include <linux/completion.h>
> > +#include <linux/device.h>
> > +#include <linux/err.h>
> > +#include <linux/gpio/driver.h>
> > +#include <linux/init.h>
> > +#include <linux/irqdomain.h>
> > +#include <linux/mod_devicetable.h>
> > +#include <linux/module.h>
> > +#include <linux/mutex.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/remoteproc.h>
> > +#include <linux/rpmsg.h>
> > +#include <linux/virtio_gpio.h>
> > +
> > +#define MAX_PORT_PER_CHANNEL 10
> > +#define GPIOS_PER_PORT_DEFAULT 32
> > +#define RPMSG_TIMEOUT 1000
> > +
> > +/* GPIO RPMSG Type */
> > +#define GPIO_RPMSG_SEND 0
> > +#define GPIO_RPMSG_REPLY 1
> > +#define GPIO_RPMSG_NOTIFY 2
> > +
> > +struct rpmsg_gpio_packet {
> > + u8 type; /* Message type */
> > + u8 cmd; /* Command code */
> > + u8 port_idx;
> > + u8 line;
> > + u8 val1;
> > + u8 val2;
> > +};
>
>
> Could you please document the fields in these structs (and the below ones too)?
> From the code, it looks like while sending a message from Linux to Firmware; val1
> and val2 are used to describe the values to set. Whereas while receiving a
> response, val1 represents a possible error code, and val2 represents the actual
> message of get type queries. If that is so, you might want to change the variable
> names to be more descriptive and also use a union.
>
The fields in the two structs are fairly self-explanatory. Do we really need the additional comments?
The previous version of the patch used a union, which was updated to support the fixed_up hooks.
Now that the fixed_up hooks have been removed, I can revert this back to the union-based implementation.
> > +
> > +struct rpmsg_gpio_line {
> > + u8 irq_shutdown;
> > + u8 irq_unmask;
> > + u8 irq_mask;
> > + u32 irq_wake_enable;
> > + u32 irq_type;
> > + struct rpmsg_gpio_packet msg;
>
>
> We don't need to have this field. More info at [0].
>
> > +};
> > +
> > +struct rpmsg_gpio_info {
> > + struct rpmsg_device *rpdev;
> > + struct rpmsg_gpio_packet *reply_msg;
> > + struct completion cmd_complete;
> > + struct mutex lock;
> > + void **port_store;
> > +};
> > +
> > +struct rpmsg_gpio_port {
> > + struct gpio_chip gc;
> > + struct rpmsg_gpio_line lines[GPIOS_PER_PORT_DEFAULT];
> > + struct rpmsg_gpio_info info;
> > + u32 ngpios;
> > + u32 idx;
> > +};
> > +
> > +/**
> > + * struct rpmsg_drvdata - driver data per channel.
> > + * @rproc_name: the name of the remote proc.
> > + * @recv_pkt: a pointer to the received packet for protocol fix up.
> > + * @channel_devices: an array of the devices related to the rpdev.
> > + */
> > +struct rpdev_drvdata {
> > + const char *rproc_name;
> > + void *recv_pkt;
>
>
> I don't see any use of this field in the code?
>
Will remove it. It was there for fixed_up hooks.
> > + void *channel_devices[MAX_PORT_PER_CHANNEL];
>
>
> So this is technically a rpmsg endpoint (struct rpmsg_endpoint) without naming it
> "endpoint". Every rpmsg endpoint has a reference to its parent rpmsg channel
> (struct rpmsg_device) which represents the same information here. So we should
> use the framework standard here.
>
Yes, agree to use "endpoint_devices".
> This also allows for dynamic creation and deletion of ports too! (if/when the
> firmware supports it)
>
> Which means at port init time, we should make a call to
> rpmsg_create_ept() for each port tying the same callback
> rpmsg_gpio_channel_callback(). And based on the 'u32 src', we could identify the
> appropriate gpio port in the callback.
>
> > +};
> > +
> > +static int rpmsg_gpio_send_message(struct rpmsg_gpio_port *port,
> > + struct rpmsg_gpio_packet *msg) {
> > + struct rpmsg_gpio_info *info = &port->info;
> > + int ret;
> > +
> > + reinit_completion(&info->cmd_complete);
> > +
> > + ret = rpmsg_send(info->rpdev->ept, msg, sizeof(*msg));
> > + if (ret) {
> > + dev_err(&info->rpdev->dev, "rpmsg_send failed: %d\n", ret);
> > + return ret;
> > + }
> > +
> > + ret = wait_for_completion_timeout(&info->cmd_complete,
> > + msecs_to_jiffies(RPMSG_TIMEOUT));
> > + if (ret == 0) {
> > + dev_err(&info->rpdev->dev, "rpmsg_send timeout!\n");
> > + return -ETIMEDOUT;
> > + }
> > +
> > + if (info->reply_msg->val1) {
> > + dev_err(&info->rpdev->dev, "remote core replies an error: %d!\n",
> > + info->reply_msg->val1);
> > + return -EINVAL;
> > + }
> > +
> > + /* copy the reply message */
> > + memcpy(&port->lines[info->reply_msg->line].msg,
> > + info->reply_msg, sizeof(*info->reply_msg));
>
>
> The rpmsg_gpio_port structure already holds a pointer to the reply message via -
> >info. We do not need this extra copy. More info at [0].
>
> > +
> > + return 0;
> > +}
> > +
> > +static struct rpmsg_gpio_packet *
> > +rpmsg_gpio_msg_init_common(struct rpmsg_gpio_port *port, unsigned int
> > +line, u8 cmd) {
> > + struct rpmsg_gpio_packet *msg = &port->lines[line].msg;
>
>
> [0]: We really don't need to carry the stale message in the line structure
> everytime. While sending requests, we should just request a buffer from kzalloc
> and use it everytime. As far as response is concerned, we are holding a lock
> everytime we are sending any message, so we are sure the pointer in info-
> >reply_msg would have the response to only one request that was sent.
>
looks reasonable.
> > +
> > + memset(msg, 0, sizeof(*msg));
>
>
> This also means we can get rid of this memset.
>
> > + msg->type = GPIO_RPMSG_SEND;
> > + msg->cmd = cmd;
> > + msg->port_idx = port->idx;
> > + msg->line = line;
> > +
> > + return msg;
> > +}
> > +
> > +static int rpmsg_gpio_get(struct gpio_chip *gc, unsigned int line) {
> > + struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
> > + struct rpmsg_gpio_packet *msg;
> > + int ret;
> > +
> > + guard(mutex)(&port->info.lock);
> > +
> > + msg = rpmsg_gpio_msg_init_common(port, line,
> > + VIRTIO_GPIO_MSG_GET_VALUE);
> > +
> > + ret = rpmsg_gpio_send_message(port, msg);
> > + if (!ret)
> > + ret = !!port->lines[line].msg.val2;
>
>
> Which means here & everywhere else, we could just read the reply message
> from !!port->info->reply_msg->val2
>
> > +
> > + return ret;
> > +}
> > +
> > +static int rpmsg_gpio_get_direction(struct gpio_chip *gc, unsigned
> > +int line) {
> > + struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
> > + struct rpmsg_gpio_packet *msg;
> > + int ret;
> > +
> > + guard(mutex)(&port->info.lock);
> > +
> > + msg = rpmsg_gpio_msg_init_common(port, line,
> > + VIRTIO_GPIO_MSG_GET_DIRECTION);
> > +
> > + ret = rpmsg_gpio_send_message(port, msg);
> > + if (ret)
> > + return ret;
> > +
> > + switch (port->lines[line].msg.val2) {
> > + case VIRTIO_GPIO_DIRECTION_IN:
> > + return GPIO_LINE_DIRECTION_IN;
> > + case VIRTIO_GPIO_DIRECTION_OUT:
> > + return GPIO_LINE_DIRECTION_OUT;
> > + default:
> > + break;
> > + }
> > +
> > + return -EINVAL;
> > +}
> > +
> > +static int rpmsg_gpio_direction_input(struct gpio_chip *gc, unsigned
> > +int line) {
> > + struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
> > + struct rpmsg_gpio_packet *msg;
> > +
> > + guard(mutex)(&port->info.lock);
> > +
> > + msg = rpmsg_gpio_msg_init_common(port, line,
> VIRTIO_GPIO_MSG_SET_DIRECTION);
> > + msg->val1 = VIRTIO_GPIO_DIRECTION_IN;
> > +
> > + return rpmsg_gpio_send_message(port, msg); }
> > +
> > +static int rpmsg_gpio_set(struct gpio_chip *gc, unsigned int line,
> > +int val) {
> > + struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
> > + struct rpmsg_gpio_packet *msg;
> > +
> > + guard(mutex)(&port->info.lock);
> > +
> > + msg = rpmsg_gpio_msg_init_common(port, line,
> VIRTIO_GPIO_MSG_SET_VALUE);
> > + msg->val1 = val;
> > +
> > + return rpmsg_gpio_send_message(port, msg); }
> > +
> > +static int rpmsg_gpio_direction_output(struct gpio_chip *gc, unsigned
> > +int line, int val) {
> > + struct rpmsg_gpio_port *port = gpiochip_get_data(gc);
> > + struct rpmsg_gpio_packet *msg;
> > + int ret;
> > +
> > + guard(mutex)(&port->info.lock);
> > +
> > + msg = rpmsg_gpio_msg_init_common(port, line,
> VIRTIO_GPIO_MSG_SET_DIRECTION);
> > + msg->val1 = VIRTIO_GPIO_DIRECTION_OUT;
> > +
> > + ret = rpmsg_gpio_send_message(port, msg);
> > + if (ret)
> > + return ret;
> > +
> > + msg = rpmsg_gpio_msg_init_common(port, line,
> VIRTIO_GPIO_MSG_SET_VALUE);
> > + msg->val1 = val;
> > +
> > + return rpmsg_gpio_send_message(port, msg); }
> > +
> > +static int gpio_rpmsg_irq_set_type(struct irq_data *d, u32 type) {
> > + struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> > + u32 line = d->hwirq;
> > +
> > + switch (type) {
> > + case IRQ_TYPE_EDGE_RISING:
> > + type = VIRTIO_GPIO_IRQ_TYPE_EDGE_RISING;
> > + irq_set_handler_locked(d, handle_simple_irq);
> > + break;
> > + case IRQ_TYPE_EDGE_FALLING:
> > + type = VIRTIO_GPIO_IRQ_TYPE_EDGE_FALLING;
> > + irq_set_handler_locked(d, handle_simple_irq);
> > + break;
> > + case IRQ_TYPE_EDGE_BOTH:
> > + type = VIRTIO_GPIO_IRQ_TYPE_EDGE_BOTH;
> > + irq_set_handler_locked(d, handle_simple_irq);
> > + break;
> > + case IRQ_TYPE_LEVEL_LOW:
> > + type = VIRTIO_GPIO_IRQ_TYPE_LEVEL_LOW;
> > + irq_set_handler_locked(d, handle_level_irq);
> > + break;
> > + case IRQ_TYPE_LEVEL_HIGH:
> > + type = VIRTIO_GPIO_IRQ_TYPE_LEVEL_HIGH;
> > + irq_set_handler_locked(d, handle_level_irq);
> > + break;
> > + default:
> > + dev_err(&port->info.rpdev->dev, "unsupported irq type: %u\n", type);
> > + return -EINVAL;
> > + }
> > +
> > + port->lines[line].irq_type = type;
> > +
> > + return 0;
> > +}
> > +
> > +static int gpio_rpmsg_irq_set_wake(struct irq_data *d, u32 enable) {
> > + struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> > + u32 line = d->hwirq;
> > +
> > + port->lines[line].irq_wake_enable = enable;
> > +
> > + return 0;
> > +}
> > +
> > +/*
> > + * This unmask/mask function is invoked in two situations:
> > + * - when an interrupt is being set up, and
> > + * - after an interrupt has occurred.
> > + *
> > + * The GPIO driver does not access hardware registers directly.
> > + * Instead, it caches all relevant information locally, and then
> > +sends
> > + * the accumulated state to the remote system at this stage.
>
>
> It is actually sent at the .bus_sync_unlock() stage.
>
> > + */
> > +static void gpio_rpmsg_unmask_irq(struct irq_data *d) {
> > + struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> > + u32 line = d->hwirq;
> > +
> > + port->lines[line].irq_unmask = 1; }
> > +
> > +static void gpio_rpmsg_mask_irq(struct irq_data *d) {
> > + struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> > + u32 line = d->hwirq;
> > +
> > + /*
> > + * When an interrupt occurs, the remote system masks the interrupt
> > + * and then sends a notification to Linux. After Linux processes
> > + * that notification, it sends an RPMsg command back to the remote
> > + * system to unmask the interrupt again.
> > + */
> > + port->lines[line].irq_mask = 1;
> > +}
> > +
> > +static void gpio_rpmsg_irq_shutdown(struct irq_data *d) {
> > + struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> > + u32 line = d->hwirq;
> > +
> > + port->lines[line].irq_shutdown = 1; }
> > +
> > +static void gpio_rpmsg_irq_bus_lock(struct irq_data *d) {
> > + struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> > +
> > + mutex_lock(&port->info.lock);
> > +}
> > +
> > +static void gpio_rpmsg_irq_bus_sync_unlock(struct irq_data *d) {
> > + struct rpmsg_gpio_port *port = irq_data_get_irq_chip_data(d);
> > + struct rpmsg_gpio_packet *msg;
> > + u32 line = d->hwirq;
> > +
> > + /*
> > + * For mask irq, do nothing here.
> > + * The remote system will mask interrupt after an interrupt occurs,
> > + * and then send a notification to Linux system. After Linux system
> > + * handles the notification, it sends an rpmsg back to the remote
> > + * system to unmask this interrupt again.
> > + */
> > + if (port->lines[line].irq_mask && !port->lines[line].irq_unmask) {
> > + port->lines[line].irq_mask = 0;
> > + mutex_unlock(&port->info.lock);
> > + return;
> > + }
> > +
> > + msg = rpmsg_gpio_msg_init_common(port, line,
> > + VIRTIO_GPIO_MSG_IRQ_TYPE);
> > +
> > + if (port->lines[line].irq_shutdown) {
> > + port->lines[line].irq_shutdown = 0;
> > + msg->val1 = VIRTIO_GPIO_IRQ_TYPE_NONE;
> > + msg->val2 = 0;
> > + } else {
> > + msg->val1 = port->lines[line].irq_type;
> > +
> > + if (port->lines[line].irq_unmask) {
> > + msg->val2 = 0;
> > + port->lines[line].irq_unmask = 0;
> > + } else /* irq set wake */
> > + msg->val2 = port->lines[line].irq_wake_enable;
> > + }
> > +
> > + rpmsg_gpio_send_message(port, msg);
> > + mutex_unlock(&port->info.lock);
> > +}
> > +
> > +static const struct irq_chip gpio_rpmsg_irq_chip = {
> > + .irq_mask = gpio_rpmsg_mask_irq,
> > + .irq_unmask = gpio_rpmsg_unmask_irq,
> > + .irq_set_wake = gpio_rpmsg_irq_set_wake,
> > + .irq_set_type = gpio_rpmsg_irq_set_type,
> > + .irq_shutdown = gpio_rpmsg_irq_shutdown,
> > + .irq_bus_lock = gpio_rpmsg_irq_bus_lock,
> > + .irq_bus_sync_unlock = gpio_rpmsg_irq_bus_sync_unlock,
> > + .flags = IRQCHIP_IMMUTABLE,
> > +};
> > +
> > +static void rpmsg_gpio_remove_action(void *data) {
> > + struct rpmsg_gpio_port *port = data;
> > +
> > + port->info.port_store[port->idx] = NULL; }
> > +
> > +static int rpmsg_gpiochip_register(struct rpmsg_device *rpdev, struct
> > +device_node *np) {
> > + struct rpdev_drvdata *drvdata = dev_get_drvdata(&rpdev->dev);
> > + struct rpmsg_gpio_port *port;
> > + struct gpio_irq_chip *girq;
> > + struct gpio_chip *gc;
> > + int ret;
> > +
> > + port = devm_kzalloc(&rpdev->dev, sizeof(*port), GFP_KERNEL);
> > + if (!port)
> > + return -ENOMEM;
> > +
> > + ret = of_property_read_u32(np, "reg", &port->idx);
> > + if (ret)
> > + return ret;
> > +
> > + if (port->idx >= MAX_PORT_PER_CHANNEL)
> > + return -EINVAL;
> > +
> > + ret = devm_mutex_init(&rpdev->dev, &port->info.lock);
> > + if (ret)
> > + return ret;
> > +
> > + ret = of_property_read_u32(np, "ngpios", &port->ngpios);
> > + if (ret || port->ngpios > GPIOS_PER_PORT_DEFAULT)
> > + port->ngpios = GPIOS_PER_PORT_DEFAULT;
> > +
> > + port->info.reply_msg = devm_kzalloc(&rpdev->dev,
> > + sizeof(*port->info.reply_msg),
> > + GFP_KERNEL);
> > + if (!port->info.reply_msg)
> > + return -ENOMEM;
> > +
> > + init_completion(&port->info.cmd_complete);
> > + port->info.port_store = drvdata->channel_devices;
> > + port->info.port_store[port->idx] = port;
> > + port->info.rpdev = rpdev;
> > +
> > + gc = &port->gc;
> > + gc->owner = THIS_MODULE;
> > + gc->parent = &rpdev->dev;
> > + gc->fwnode = of_fwnode_handle(np);
> > + gc->ngpio = port->ngpios;
> > + gc->base = -1;
> > + gc->label = devm_kasprintf(&rpdev->dev, GFP_KERNEL, "%s-gpio%d",
> > + drvdata->rproc_name, port->idx);
> > +
> > + gc->direction_input = rpmsg_gpio_direction_input;
> > + gc->direction_output = rpmsg_gpio_direction_output;
> > + gc->get_direction = rpmsg_gpio_get_direction;
> > + gc->get = rpmsg_gpio_get;
> > + gc->set = rpmsg_gpio_set;
> > +
> > + girq = &gc->irq;
> > + gpio_irq_chip_set_chip(girq, &gpio_rpmsg_irq_chip);
> > + girq->parent_handler = NULL;
> > + girq->num_parents = 0;
> > + girq->parents = NULL;
> > + girq->chip->name = devm_kasprintf(&rpdev->dev, GFP_KERNEL, "%s-
> gpio%d",
> > + drvdata->rproc_name,
> > + port->idx);
>
>
> We could just re-use gc->label here...
We also want to include the remoteproc name (for example, remoteproc-cm33-gpio0), rather than just gpio0.
>
> > +
> > + ret = devm_add_action_or_reset(&rpdev->dev,
> rpmsg_gpio_remove_action, port);
> > + if (ret)
> > + return ret;
> > +
> > + return devm_gpiochip_add_data(&rpdev->dev, gc, port); }
> > +
> > +static const char *rpmsg_get_rproc_node_name(struct rpmsg_device
> > +*rpdev) {
> > + const char *name = NULL;
> > + struct device_node *np;
> > + struct rproc *rproc;
> > +
> > + rproc = rproc_get_by_child(&rpdev->dev);
> > + if (!rproc)
> > + return NULL;
> > +
> > + np = of_node_get(rproc->dev.of_node);
> > + if (!np && rproc->dev.parent)
> > + np = of_node_get(rproc->dev.parent->of_node);
> > +
> > + if (np) {
> > + name = devm_kstrdup(&rpdev->dev, np->name, GFP_KERNEL);
> > + of_node_put(np);
> > + }
> > +
> > + return name;
> > +}
> > +
> > +static struct device_node *
> > +rpmsg_get_channel_ofnode(struct rpmsg_device *rpdev, char *chan_name)
> > +{
> > + struct device_node *np_chan = NULL, *np;
> > + struct rproc *rproc;
> > +
> > + rproc = rproc_get_by_child(&rpdev->dev);
> > + if (!rproc)
> > + return NULL;
> > +
> > + np = of_node_get(rproc->dev.of_node);
> > + if (!np && rproc->dev.parent)
> > + np = of_node_get(rproc->dev.parent->of_node);
> > +
> > + /* The of_node_put() is performed by of_find_node_by_name(). */
> > + if (np)
> > + np_chan = of_find_node_by_name(np, chan_name);
> > +
> > + return np_chan;
> > +}
> > +
> > +static int rpmsg_gpio_channel_callback(struct rpmsg_device *rpdev, void
> *data,
> > + int len, void *priv, u32 src) {
> > + struct rpmsg_gpio_packet *msg = data;
> > + struct rpmsg_gpio_port *port = NULL;
> > + struct rpdev_drvdata *drvdata;
> > +
> > + drvdata = dev_get_drvdata(&rpdev->dev);
> > + if (!msg || !drvdata)
> > + return -EINVAL;
> > +
> > + if (msg->port_idx < MAX_PORT_PER_CHANNEL)
> > + port = drvdata->channel_devices[msg->port_idx];
> > +
> > + if (!port || msg->line >= port->ngpios) {
> > + dev_err(&rpdev->dev, "wrong port index or line number. port:%d
> line:%d\n",
> > + msg->port_idx, msg->line);
> > + return -EINVAL;
> > + }
> > +
> > + if (msg->type == GPIO_RPMSG_REPLY) {
> > + *port->info.reply_msg = *msg;
> > + complete(&port->info.cmd_complete);
> > + } else if (msg->type == GPIO_RPMSG_NOTIFY) {
> > + generic_handle_domain_irq_safe(port->gc.irq.domain, msg->line);
> > + } else {
> > + dev_err(&rpdev->dev, "wrong command type (0x%x)\n", msg->type);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int rpmsg_gpio_channel_probe(struct rpmsg_device *rpdev) {
> > + struct device *dev = &rpdev->dev;
> > + struct rpdev_drvdata *drvdata;
> > + struct device_node *np;
> > + int ret = -ENODEV;
> > +
> > + if (!dev->of_node) {
> > + np = rpmsg_get_channel_ofnode(rpdev, rpdev->id.name);
> > + if (np) {
> > + dev->of_node = np;
> > + set_primary_fwnode(dev, of_fwnode_handle(np));
> > + }
> > + return -EPROBE_DEFER;
>
>
> I know this was asked in the v10 version also. But I don't think the answer is
> sufficient. Should we not continue the intialization of drvdata etc if np != 0? Why
> return a deferred probe, and let the kernel come back to it again to do the same
> stuff with extra latency?
>
> We could just do:
> if (!np) return -EPROBE_DEFER;
> else {everything_else};
>
After configuring dev->of_node, it would be better to restart the driver probe process.
This ensures that all required resources, such as pinctrl, clocks, and power domains, are
properly set up if they are specified in the device node, before the probe function is invoked.
Thanks,
Shenwei
> > + }
> > +
> > + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> > + if (!drvdata)
> > + return -ENOMEM;
> > +
> > + drvdata->rproc_name = rpmsg_get_rproc_node_name(rpdev);
> > + dev_set_drvdata(dev, drvdata);
> > +
> > + for_each_child_of_node_scoped(dev->of_node, child) {
> > + if (!of_device_is_available(child))
> > + continue;
> > +
> > + if (!of_match_node(dev->driver->of_match_table, child))
> > + continue;
> > +
> > + ret = rpmsg_gpiochip_register(rpdev, child);
> > + if (ret < 0)
> > + break;
>
>
> Why break here? If one port initialization fails, it shouldn't impact the other port
> right? We should just log this and store the appropriate value in ret.
>
> Thanks for your time,
> Beleswar
>
> > + }
> > +
> > + return ret;
> > +}
> > +
> > +static const struct of_device_id rpmsg_gpio_dt_ids[] = {
> > + { .compatible = "rpmsg-gpio" },
> > + { /* sentinel */ }
> > +};
> > +
> > +static struct rpmsg_device_id rpmsg_gpio_channel_id_table[] = {
> > + { .name = "rpmsg-io" },
> > + { },
> > +};
> > +MODULE_DEVICE_TABLE(rpmsg, rpmsg_gpio_channel_id_table);
> > +
> > +static struct rpmsg_driver rpmsg_gpio_channel_client = {
> > + .callback = rpmsg_gpio_channel_callback,
> > + .id_table = rpmsg_gpio_channel_id_table,
> > + .probe = rpmsg_gpio_channel_probe,
> > + .drv = {
> > + .name = KBUILD_MODNAME,
> > + .of_match_table = rpmsg_gpio_dt_ids,
> > + },
> > +};
> > +module_rpmsg_driver(rpmsg_gpio_channel_client);
> > +
> > +MODULE_AUTHOR("Shenwei Wang <shenwei.wang@nxp.com>");
> > +MODULE_DESCRIPTION("generic rpmsg gpio driver");
> > +MODULE_LICENSE("GPL");
^ permalink raw reply
* Re: [PATCH v3] iio: adc: mt6359: fix unchecked return value in mt6358_read_imp
From: Andy Shevchenko @ 2026-04-27 19:57 UTC (permalink / raw)
To: Salah Triki
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Matthias Brugger, AngeloGioacchino Del Regno, linux-iio,
linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <20260427190849.14963-1-salah.triki@gmail.com>
On Mon, Apr 27, 2026 at 08:08:49PM +0100, Salah Triki wrote:
> In mt6358_read_imp(), the variable val_v is passed to regmap_read()
> but the return value is not checked. If the read fails, val_v remains
> uninitialized and its random stack content is subsequently reported
> as a measurement result.
>
> Initialize val_v to zero to ensure a predictable value is reported
> in case of bus failure and to prevent potential stack data leakage.
> This also satisfies static analyzers that might otherwise flag the
> variable as used uninitialized.
...
> const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info;
> struct regmap *regmap = adc_dev->regmap;
> u16 reg_adc0 = cinfo->regs[PMIC_AUXADC_ADC0];
> - u32 val_v;
> + u32 val_v = 0;
This is hard to maintain. Better to assign it just immediately before the first use.
> int ret;
Otherwise, LGTM.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH 3/3] wifi: mt76: remove mt76_get_of_data_from_mtd
From: Conor Dooley @ 2026-04-27 20:02 UTC (permalink / raw)
To: Rosen Penev
Cc: devicetree, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
Shayne Chen, Sean Wang, Johannes Berg, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Thomas Bogendoerfer,
open list:MEDIATEK MT76 WIRELESS LAN DRIVER,
open list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support, open list:MIPS
In-Reply-To: <CAKxU2N-mhrhjDEc2MnOvDZC5PpMzj=vRgMemNK4qSQzNQ-=BPQ@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 6681 bytes --]
On Mon, Apr 27, 2026 at 12:17:04PM -0700, Rosen Penev wrote:
> On Mon, Apr 27, 2026 at 12:09 PM Conor Dooley <conor@kernel.org> wrote:
> >
> > On Sun, Apr 26, 2026 at 08:44:27PM -0700, Rosen Penev wrote:
> > > mt76_get_of_data_from_mtd has been replaced by
> > > mt76_get_of_data_from_nvmem in all usages.
> >
> > All users in the kernel, but what about other sources of devicetrees?
> > Those built into firmware etc? Are there none of those too?
> I'm actively removing those: https://github.com/openwrt/openwrt/pull/23113
>
> Anyway, irrelevant here.
Hardly, you can't break backwards compatibility with old devicetrees.
Removing known users from the kernel is one step in that process, but if
there's devicetrees in other places those cunt too!
With the moving pieces in this patchset alone it's problematic to move
this fast, since you're changing the dts user in the same series as
removing driver support (AFIACT), which means that neither netdev nor
the platform tree will work with their portion applied.
> >
> > Conor.
> >
> > >
> > > Remove it to prevent people from using the deprecated
> > > mediatek,mtd-eeprom binding.
> > >
> > > Signed-off-by: Rosen Penev <rosenp@gmail.com>
> > > ---
> > > drivers/net/wireless/mediatek/mt76/eeprom.c | 87 -------------------
> > > drivers/net/wireless/mediatek/mt76/mt76.h | 1 -
> > > .../wireless/mediatek/mt76/mt7915/eeprom.c | 4 -
> > > 3 files changed, 92 deletions(-)
> > >
> > > diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
> > > index afdb73661866..092804323d81 100644
> > > --- a/drivers/net/wireless/mediatek/mt76/eeprom.c
> > > +++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
> > > @@ -35,89 +35,6 @@ static int mt76_get_of_eeprom_data(struct mt76_dev *dev, void *eep, int len)
> > > return 0;
> > > }
> > >
> > > -int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len)
> > > -{
> > > -#ifdef CONFIG_MTD
> > > - struct device_node *np = dev->dev->of_node;
> > > - struct mtd_info *mtd;
> > > - const __be32 *list;
> > > - const char *part;
> > > - phandle phandle;
> > > - size_t retlen;
> > > - int size;
> > > - int ret;
> > > -
> > > - list = of_get_property(np, "mediatek,mtd-eeprom", &size);
> > > - if (!list)
> > > - return -ENOENT;
> > > -
> > > - phandle = be32_to_cpup(list++);
> > > - if (!phandle)
> > > - return -ENOENT;
> > > -
> > > - np = of_find_node_by_phandle(phandle);
> > > - if (!np)
> > > - return -EINVAL;
> > > -
> > > - part = of_get_property(np, "label", NULL);
> > > - if (!part)
> > > - part = np->name;
> > > -
> > > - mtd = get_mtd_device_nm(part);
> > > - if (IS_ERR(mtd)) {
> > > - ret = PTR_ERR(mtd);
> > > - goto out_put_node;
> > > - }
> > > -
> > > - if (size <= sizeof(*list)) {
> > > - ret = -EINVAL;
> > > - goto out_put_node;
> > > - }
> > > -
> > > - offset += be32_to_cpup(list);
> > > - ret = mtd_read(mtd, offset, len, &retlen, eep);
> > > - put_mtd_device(mtd);
> > > - if (mtd_is_bitflip(ret))
> > > - ret = 0;
> > > - if (ret) {
> > > - dev_err(dev->dev, "reading EEPROM from mtd %s failed: %i\n",
> > > - part, ret);
> > > - goto out_put_node;
> > > - }
> > > -
> > > - if (retlen < len) {
> > > - ret = -EINVAL;
> > > - goto out_put_node;
> > > - }
> > > -
> > > - if (of_property_read_bool(dev->dev->of_node, "big-endian")) {
> > > - u8 *data = (u8 *)eep;
> > > - int i;
> > > -
> > > - /* convert eeprom data in Little Endian */
> > > - for (i = 0; i < round_down(len, 2); i += 2)
> > > - put_unaligned_le16(get_unaligned_be16(&data[i]),
> > > - &data[i]);
> > > - }
> > > -
> > > -#ifdef CONFIG_NL80211_TESTMODE
> > > - dev->test_mtd.name = devm_kstrdup(dev->dev, part, GFP_KERNEL);
> > > - if (!dev->test_mtd.name) {
> > > - ret = -ENOMEM;
> > > - goto out_put_node;
> > > - }
> > > - dev->test_mtd.offset = offset;
> > > -#endif
> > > -
> > > -out_put_node:
> > > - of_node_put(np);
> > > - return ret;
> > > -#else
> > > - return -ENOENT;
> > > -#endif
> > > -}
> > > -EXPORT_SYMBOL_GPL(mt76_get_of_data_from_mtd);
> > > -
> > > int mt76_get_of_data_from_nvmem(struct mt76_dev *dev, void *eep,
> > > const char *cell_name, int len)
> > > {
> > > @@ -163,10 +80,6 @@ static int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int len)
> > > if (!ret)
> > > return 0;
> > >
> > > - ret = mt76_get_of_data_from_mtd(dev, eep, 0, len);
> > > - if (!ret)
> > > - return 0;
> > > -
> > > return mt76_get_of_data_from_nvmem(dev, eep, "eeprom", len);
> > > }
> > >
> > > diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
> > > index 527bef97e122..f447ecac664d 100644
> > > --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> > > +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> > > @@ -1339,7 +1339,6 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
> > >
> > > int mt76_eeprom_init(struct mt76_dev *dev, int len);
> > > int mt76_eeprom_override(struct mt76_phy *phy);
> > > -int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len);
> > > int mt76_get_of_data_from_nvmem(struct mt76_dev *dev, void *eep,
> > > const char *cell_name, int len);
> > >
> > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
> > > index eb92cbf1a284..c24e1276700b 100644
> > > --- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
> > > +++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
> > > @@ -29,10 +29,6 @@ static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
> > >
> > > offs = is_mt7915(&dev->mt76) ? MT_EE_PRECAL : MT_EE_PRECAL_V2;
> > >
> > > - ret = mt76_get_of_data_from_mtd(mdev, dev->cal, offs, size);
> > > - if (!ret)
> > > - return ret;
> > > -
> > > ret = mt76_get_of_data_from_nvmem(mdev, dev->cal, "precal", size);
> > > if (!ret)
> > > return ret;
> > > --
> > > 2.54.0
> > >
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH 3/3] wifi: mt76: remove mt76_get_of_data_from_mtd
From: Conor Dooley @ 2026-04-27 20:04 UTC (permalink / raw)
To: Rosen Penev
Cc: devicetree, Felix Fietkau, Lorenzo Bianconi, Ryder Lee,
Shayne Chen, Sean Wang, Johannes Berg, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Thomas Bogendoerfer,
open list:MEDIATEK MT76 WIRELESS LAN DRIVER,
open list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support, open list:MIPS
In-Reply-To: <20260427-safeguard-unthawed-cfb87dc55a32@spud>
[-- Attachment #1: Type: text/plain, Size: 7199 bytes --]
On Mon, Apr 27, 2026 at 09:02:56PM +0100, Conor Dooley wrote:
> On Mon, Apr 27, 2026 at 12:17:04PM -0700, Rosen Penev wrote:
> > On Mon, Apr 27, 2026 at 12:09 PM Conor Dooley <conor@kernel.org> wrote:
> > >
> > > On Sun, Apr 26, 2026 at 08:44:27PM -0700, Rosen Penev wrote:
> > > > mt76_get_of_data_from_mtd has been replaced by
> > > > mt76_get_of_data_from_nvmem in all usages.
> > >
> > > All users in the kernel, but what about other sources of devicetrees?
> > > Those built into firmware etc? Are there none of those too?
> > I'm actively removing those: https://github.com/openwrt/openwrt/pull/23113
> >
> > Anyway, irrelevant here.
>
> Hardly, you can't break backwards compatibility with old devicetrees.
> Removing known users from the kernel is one step in that process, but if
> there's devicetrees in other places those cunt too!
>
> With the moving pieces in this patchset alone it's problematic to move
> this fast, since you're changing the dts user in the same series as
> removing driver support (AFIACT), which means that neither netdev nor
> the platform tree will work with their portion applied.
Well, maybe the platform tree will work, but not the netdev tree unless
I've misunderstood completely.
>
> > >
> > > Conor.
> > >
> > > >
> > > > Remove it to prevent people from using the deprecated
> > > > mediatek,mtd-eeprom binding.
> > > >
> > > > Signed-off-by: Rosen Penev <rosenp@gmail.com>
> > > > ---
> > > > drivers/net/wireless/mediatek/mt76/eeprom.c | 87 -------------------
> > > > drivers/net/wireless/mediatek/mt76/mt76.h | 1 -
> > > > .../wireless/mediatek/mt76/mt7915/eeprom.c | 4 -
> > > > 3 files changed, 92 deletions(-)
> > > >
> > > > diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
> > > > index afdb73661866..092804323d81 100644
> > > > --- a/drivers/net/wireless/mediatek/mt76/eeprom.c
> > > > +++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
> > > > @@ -35,89 +35,6 @@ static int mt76_get_of_eeprom_data(struct mt76_dev *dev, void *eep, int len)
> > > > return 0;
> > > > }
> > > >
> > > > -int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len)
> > > > -{
> > > > -#ifdef CONFIG_MTD
> > > > - struct device_node *np = dev->dev->of_node;
> > > > - struct mtd_info *mtd;
> > > > - const __be32 *list;
> > > > - const char *part;
> > > > - phandle phandle;
> > > > - size_t retlen;
> > > > - int size;
> > > > - int ret;
> > > > -
> > > > - list = of_get_property(np, "mediatek,mtd-eeprom", &size);
> > > > - if (!list)
> > > > - return -ENOENT;
> > > > -
> > > > - phandle = be32_to_cpup(list++);
> > > > - if (!phandle)
> > > > - return -ENOENT;
> > > > -
> > > > - np = of_find_node_by_phandle(phandle);
> > > > - if (!np)
> > > > - return -EINVAL;
> > > > -
> > > > - part = of_get_property(np, "label", NULL);
> > > > - if (!part)
> > > > - part = np->name;
> > > > -
> > > > - mtd = get_mtd_device_nm(part);
> > > > - if (IS_ERR(mtd)) {
> > > > - ret = PTR_ERR(mtd);
> > > > - goto out_put_node;
> > > > - }
> > > > -
> > > > - if (size <= sizeof(*list)) {
> > > > - ret = -EINVAL;
> > > > - goto out_put_node;
> > > > - }
> > > > -
> > > > - offset += be32_to_cpup(list);
> > > > - ret = mtd_read(mtd, offset, len, &retlen, eep);
> > > > - put_mtd_device(mtd);
> > > > - if (mtd_is_bitflip(ret))
> > > > - ret = 0;
> > > > - if (ret) {
> > > > - dev_err(dev->dev, "reading EEPROM from mtd %s failed: %i\n",
> > > > - part, ret);
> > > > - goto out_put_node;
> > > > - }
> > > > -
> > > > - if (retlen < len) {
> > > > - ret = -EINVAL;
> > > > - goto out_put_node;
> > > > - }
> > > > -
> > > > - if (of_property_read_bool(dev->dev->of_node, "big-endian")) {
> > > > - u8 *data = (u8 *)eep;
> > > > - int i;
> > > > -
> > > > - /* convert eeprom data in Little Endian */
> > > > - for (i = 0; i < round_down(len, 2); i += 2)
> > > > - put_unaligned_le16(get_unaligned_be16(&data[i]),
> > > > - &data[i]);
> > > > - }
> > > > -
> > > > -#ifdef CONFIG_NL80211_TESTMODE
> > > > - dev->test_mtd.name = devm_kstrdup(dev->dev, part, GFP_KERNEL);
> > > > - if (!dev->test_mtd.name) {
> > > > - ret = -ENOMEM;
> > > > - goto out_put_node;
> > > > - }
> > > > - dev->test_mtd.offset = offset;
> > > > -#endif
> > > > -
> > > > -out_put_node:
> > > > - of_node_put(np);
> > > > - return ret;
> > > > -#else
> > > > - return -ENOENT;
> > > > -#endif
> > > > -}
> > > > -EXPORT_SYMBOL_GPL(mt76_get_of_data_from_mtd);
> > > > -
> > > > int mt76_get_of_data_from_nvmem(struct mt76_dev *dev, void *eep,
> > > > const char *cell_name, int len)
> > > > {
> > > > @@ -163,10 +80,6 @@ static int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int len)
> > > > if (!ret)
> > > > return 0;
> > > >
> > > > - ret = mt76_get_of_data_from_mtd(dev, eep, 0, len);
> > > > - if (!ret)
> > > > - return 0;
> > > > -
> > > > return mt76_get_of_data_from_nvmem(dev, eep, "eeprom", len);
> > > > }
> > > >
> > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
> > > > index 527bef97e122..f447ecac664d 100644
> > > > --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> > > > +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> > > > @@ -1339,7 +1339,6 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
> > > >
> > > > int mt76_eeprom_init(struct mt76_dev *dev, int len);
> > > > int mt76_eeprom_override(struct mt76_phy *phy);
> > > > -int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len);
> > > > int mt76_get_of_data_from_nvmem(struct mt76_dev *dev, void *eep,
> > > > const char *cell_name, int len);
> > > >
> > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
> > > > index eb92cbf1a284..c24e1276700b 100644
> > > > --- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
> > > > +++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
> > > > @@ -29,10 +29,6 @@ static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
> > > >
> > > > offs = is_mt7915(&dev->mt76) ? MT_EE_PRECAL : MT_EE_PRECAL_V2;
> > > >
> > > > - ret = mt76_get_of_data_from_mtd(mdev, dev->cal, offs, size);
> > > > - if (!ret)
> > > > - return ret;
> > > > -
> > > > ret = mt76_get_of_data_from_nvmem(mdev, dev->cal, "precal", size);
> > > > if (!ret)
> > > > return ret;
> > > > --
> > > > 2.54.0
> > > >
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* [PATCH v7 0/3] Adding brcmstb-hwspinlock support
From: Kamal Dasu @ 2026-04-27 20:12 UTC (permalink / raw)
To: andersson, robh
Cc: krzysztof.kozlowski, conor+dt, baolin.wang, florian.fainelli,
bcm-kernel-feedback-list, linux-remoteproc, devicetree,
linux-arm-kernel, linux-kernel, Kamal Dasu
This series adds hardware semaphore support for Broadcom set-top SoCs
via the generic hwspinlock framework.
The semaphore registers live in the sundry block; the DT binding
describes only the semaphore register range. The compatible is
brcm,bcm7038-sun-top-ctrl-semaphore (BCM7038 is where this block first
appeared on set-top chips).
The driver has been tested built-in and as a module.
v7 changes :
- Rebase: Whole series rebased onto Linux 7.1-rc1 (254f49634ee1) so it
applies cleanly on current upstream.
- Reviewed-by tag (PATCH 1/3, dt-bindings): Krzysztof Kozlowski's
v6 changes:
Addressed review comments from Krzysztof Kozlowski:
- Renamed DT binding YAML file from "brcm,brcmstb-hwspinlock.yaml"
to "brcm,bcm7038-sun-top-ctrl-semaphore.yaml" to match the
compatible string
- Updated $id in the YAML to match the new filename
- Updated MAINTAINERS F: entry to match the new filename
v5 changes:
Addressed review comments from Krzysztof Kozlowski:
- Changed compatible to "brcm,bcm7038-sun-top-ctrl-semaphore"
using the SoC where the semaphore hardware was first introduced,
following the brcm,bcm7038-l1-intc convention
v4 changes:
Addressed review comments from Krzysztof Kozlowski and Rob Herring:
- Renamed compatible from "brcm,brcmstb-hwspinlock" to
"brcm,brcmstb-sun-top-ctrl-semaphore" to use the hardware name
- Added description block to the DT binding YAML explaining what
the semaphore registers are and their relationship to the sundry
block
- Fixed typo in Kconfig "Setttop" -> "Settop"
- Fixed email typo in MODULE_AUTHOR
v3 changes:
Added detailed explanation in the all commit messages as per review
comments
- Added description of 'sundry' ip block that the hardware semaphore
belongs to
- Added reasoning for using common compatible string
v2 changes:
Addressed following review comments:
- fixed ordering of obj brcmstb_hwspinlock.o in Makefile
- fixed ordering of 'config HWSPINLOCK_BRCMSTB' block in Kconfig
- Renamed BRCMSTB_MAX_SEMAPHORES to BRCMSTB_NUM_SEMAPHORES
- Removed unnecessary platform_set_drvdata(pdev, bank);
Also addressing duplicate PATCH 1/3 sent in error as part of v1 change.
v1 changes:
based on fixes made to Initial patch:
Link: https://github.com/intel-lab-lkp/linux/commits/Kamal-Dasu/dt-bindings-brcmstb-hwspinlock-support-for-hwspinlock/20250712-034624
Link: https://lore.kernel.org/r/20250711154221.928164-4-kamal.dasu%40broadcom.com
[PATCH 2/4] hwspinlock: brcmstb hardware semaphore support
All the review comments and build warning have been fixed.
Kamal Dasu (3):
dt-bindings: hwlock: Adding brcmstb-hwspinlock support
hwspinlock: brcmstb hardware semaphore support
MAINTAINERS: adding entry for BRCMSTB HWSPINLOCK driver
.../brcm,bcm7038-sun-top-ctrl-semaphore.yaml | 44 +++++++++
MAINTAINERS | 8 ++
drivers/hwspinlock/Kconfig | 10 ++
drivers/hwspinlock/Makefile | 1 +
drivers/hwspinlock/brcmstb_hwspinlock.c | 96 +++++++++++++++++++
5 files changed, 159 insertions(+)
create mode 100644 Documentation/devicetree/bindings/hwlock/brcm,bcm7038-sun-top-ctrl-semaphore.yaml
create mode 100644 drivers/hwspinlock/brcmstb_hwspinlock.c
--
2.34.1
^ permalink raw reply
* [PATCH v7 2/3] hwspinlock: brcmstb hardware semaphore support
From: Kamal Dasu @ 2026-04-27 20:12 UTC (permalink / raw)
To: andersson, robh
Cc: krzysztof.kozlowski, conor+dt, baolin.wang, florian.fainelli,
bcm-kernel-feedback-list, linux-remoteproc, devicetree,
linux-arm-kernel, linux-kernel, Kamal Dasu
In-Reply-To: <20260427201233.380314-1-kamal.dasu@broadcom.com>
Broadcom settop SoCs have common 16 hardware semaphore registers that
can be used as part of the kernel hardware spinlock framework. The
hardware semaphores are part of the 'sundry' ip block that also has
controls like pin/mux controls, SoC identification, drive strength,
reset controls, and other misc bits.
Adding support for brcmstb_hwspinlock that only maps sundry block
registers SUN_TOP_CTRL_SEMAPHORE_[0:15] to implement the hardware
spinlock operations. Change allows other Broadcom settop drivers to
call hwspin_trylock() and hwspin_unlock() interfaces to make use of
hwspinlock framework. Other driver dt nodes just need to provide a
reference to the &hwspinlock and lock id to make use of a particular
hardware lock.
e.g. hwlocks = <&hwspinlock0 0>;
Signed-off-by: Kamal Dasu <kamal.dasu@broadcom.com>
---
drivers/hwspinlock/Kconfig | 10 +++
drivers/hwspinlock/Makefile | 1 +
drivers/hwspinlock/brcmstb_hwspinlock.c | 96 +++++++++++++++++++++++++
3 files changed, 107 insertions(+)
create mode 100644 drivers/hwspinlock/brcmstb_hwspinlock.c
diff --git a/drivers/hwspinlock/Kconfig b/drivers/hwspinlock/Kconfig
index d84e00084ee2..3a81a6785e45 100644
--- a/drivers/hwspinlock/Kconfig
+++ b/drivers/hwspinlock/Kconfig
@@ -8,6 +8,16 @@ menuconfig HWSPINLOCK
if HWSPINLOCK
+config HWSPINLOCK_BRCMSTB
+ tristate "Broadcom Settop Hardware Semaphore functionality"
+ depends on ARCH_BRCMSTB || COMPILE_TEST
+ help
+ Broadcom settop hwspinlock driver.
+ Say y here to support the Broadcom Hardware Semaphore functionality, which
+ provides a synchronisation mechanism on the SoC.
+
+ If unsure, say N.
+
config HWSPINLOCK_OMAP
tristate "OMAP Hardware Spinlock device"
depends on ARCH_OMAP4 || SOC_OMAP5 || SOC_DRA7XX || SOC_AM33XX || SOC_AM43XX || ARCH_K3 || COMPILE_TEST
diff --git a/drivers/hwspinlock/Makefile b/drivers/hwspinlock/Makefile
index 3a740805949d..379443987b94 100644
--- a/drivers/hwspinlock/Makefile
+++ b/drivers/hwspinlock/Makefile
@@ -4,6 +4,7 @@
#
obj-$(CONFIG_HWSPINLOCK) += hwspinlock_core.o
+obj-$(CONFIG_HWSPINLOCK_BRCMSTB) += brcmstb_hwspinlock.o
obj-$(CONFIG_HWSPINLOCK_OMAP) += omap_hwspinlock.o
obj-$(CONFIG_HWSPINLOCK_QCOM) += qcom_hwspinlock.o
obj-$(CONFIG_HWSPINLOCK_SPRD) += sprd_hwspinlock.o
diff --git a/drivers/hwspinlock/brcmstb_hwspinlock.c b/drivers/hwspinlock/brcmstb_hwspinlock.c
new file mode 100644
index 000000000000..7a5a35e741f3
--- /dev/null
+++ b/drivers/hwspinlock/brcmstb_hwspinlock.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * brcmstb HWSEM driver
+ *
+ * Copyright (C) 2025 Broadcom
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/hwspinlock.h>
+#include <linux/io.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include "hwspinlock_internal.h"
+
+#define BRCMSTB_NUM_SEMAPHORES 16
+#define RESET_SEMAPHORE 0
+
+#define HWSPINLOCK_VAL 'L'
+
+static int brcmstb_hwspinlock_trylock(struct hwspinlock *lock)
+{
+ void __iomem *lock_addr = (void __iomem *)lock->priv;
+
+ writel(HWSPINLOCK_VAL, lock_addr);
+
+ return (readl(lock_addr) == HWSPINLOCK_VAL);
+}
+
+static void brcmstb_hwspinlock_unlock(struct hwspinlock *lock)
+{
+ void __iomem *lock_addr = (void __iomem *)lock->priv;
+
+ /* release the lock by writing 0 to it */
+ writel(RESET_SEMAPHORE, lock_addr);
+}
+
+static void brcmstb_hwspinlock_relax(struct hwspinlock *lock)
+{
+ ndelay(50);
+}
+
+static const struct hwspinlock_ops brcmstb_hwspinlock_ops = {
+ .trylock = brcmstb_hwspinlock_trylock,
+ .unlock = brcmstb_hwspinlock_unlock,
+ .relax = brcmstb_hwspinlock_relax,
+};
+
+static int brcmstb_hwspinlock_probe(struct platform_device *pdev)
+{
+ struct hwspinlock_device *bank;
+ struct hwspinlock *hwlock;
+ void __iomem *io_base;
+ int i, num_locks = BRCMSTB_NUM_SEMAPHORES;
+
+ io_base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(io_base)) {
+ dev_err(&pdev->dev, "semaphore iobase mapping error\n");
+ return PTR_ERR(io_base);
+ }
+
+ bank = devm_kzalloc(&pdev->dev, struct_size(bank, lock, num_locks),
+ GFP_KERNEL);
+ if (!bank)
+ return -ENOMEM;
+
+ for (i = 0, hwlock = &bank->lock[0]; i < num_locks; i++, hwlock++)
+ hwlock->priv = (void __iomem *)(io_base + sizeof(u32) * i);
+
+ return devm_hwspin_lock_register(&pdev->dev, bank,
+ &brcmstb_hwspinlock_ops,
+ 0, num_locks);
+}
+
+static const struct of_device_id brcmstb_hwspinlock_ids[] = {
+ { .compatible = "brcm,bcm7038-sun-top-ctrl-semaphore", },
+ { /* end */ },
+};
+MODULE_DEVICE_TABLE(of, brcmstb_hwspinlock_ids);
+
+static struct platform_driver brcmstb_hwspinlock_driver = {
+ .probe = brcmstb_hwspinlock_probe,
+ .driver = {
+ .name = "brcmstb_hwspinlock",
+ .of_match_table = brcmstb_hwspinlock_ids,
+ },
+};
+
+module_platform_driver(brcmstb_hwspinlock_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Hardware Spinlock driver for brcmstb");
+MODULE_AUTHOR("Kamal Dasu <kamal.dasu@broadcom.com>");
--
2.34.1
^ permalink raw reply related
* [PATCH v7 1/3] dt-bindings: hwlock: Adding brcmstb-hwspinlock support
From: Kamal Dasu @ 2026-04-27 20:12 UTC (permalink / raw)
To: andersson, robh
Cc: krzysztof.kozlowski, conor+dt, baolin.wang, florian.fainelli,
bcm-kernel-feedback-list, linux-remoteproc, devicetree,
linux-arm-kernel, linux-kernel, Kamal Dasu
In-Reply-To: <20260427201233.380314-1-kamal.dasu@broadcom.com>
The Broadcom settop SoCs have hardware semaphores as part of the
"sundry" IP block which has other controls that do not belong anywhere
else e.g. pin/mux controls, SoC identification, drive strength, reset
controls, and other misc bits are part of this block.
Adding brcmstb-hwspinlock bindings which allows the hwspinlock driver
to iomap only the 16 hardware semaphore registers that are part of all
settop SoCs. The semaphore registers are based on the BCM7038 SoC
where they were first introduced in settop chips.
Signed-off-by: Kamal Dasu <kamal.dasu@broadcom.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
.../brcm,bcm7038-sun-top-ctrl-semaphore.yaml | 44 +++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 Documentation/devicetree/bindings/hwlock/brcm,bcm7038-sun-top-ctrl-semaphore.yaml
diff --git a/Documentation/devicetree/bindings/hwlock/brcm,bcm7038-sun-top-ctrl-semaphore.yaml b/Documentation/devicetree/bindings/hwlock/brcm,bcm7038-sun-top-ctrl-semaphore.yaml
new file mode 100644
index 000000000000..552f334256b5
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwlock/brcm,bcm7038-sun-top-ctrl-semaphore.yaml
@@ -0,0 +1,44 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwlock/brcm,bcm7038-sun-top-ctrl-semaphore.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom Settop Sundry Block Hardware Semaphore
+
+description:
+ Broadcom settop SoCs contain 16 hardware semaphore registers
+ (SEMAPHORE_0 through SEMAPHORE_15) that provide hardware-arbitrated
+ mutual exclusion between drivers running on the SoC.
+
+ The semaphore registers belong to the sundry hardware block. The
+ node describes the semaphore register range carved out of the larger
+ sundry block address space.
+
+maintainers:
+ - Kamal Dasu <kamal.dasu@broadcom.com>
+
+properties:
+ compatible:
+ const: brcm,bcm7038-sun-top-ctrl-semaphore
+
+ "#hwlock-cells":
+ const: 1
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - "#hwlock-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ hwlock@404038 {
+ compatible = "brcm,bcm7038-sun-top-ctrl-semaphore";
+ reg = <0x404038 0x40>;
+ #hwlock-cells = <1>;
+ };
--
2.34.1
^ permalink raw reply related
* [PATCH v4] iio: adc: mt6359: fix unchecked return value in mt6358_read_imp
From: Salah Triki @ 2026-04-27 20:12 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: linux-iio, linux-kernel, linux-arm-kernel, linux-mediatek,
Salah Triki
In mt6358_read_imp(), the variable val_v is passed to regmap_read()
but the return value is not checked. If the read fails, val_v remains
uninitialized and its random stack content is subsequently reported
as a measurement result.
Initialize val_v to zero to ensure a predictable value is reported
in case of bus failure and to prevent potential stack data leakage.
This also satisfies static analyzers that might otherwise flag the
variable as used uninitialized.
Fixes: 3587914bf61 ("iio: adc: Add support for MediaTek MT6357/8/9 Auxiliary ADC")
Signed-off-by: Salah Triki <salah.triki@gmail.com>
---
Changes in v4:
- Move val_v initialization just before regmap_read() call as suggested
by Andy Shevchenko to improve maintainability.
Changes in v3:
- Initialize val_v to zero at declaration instead of checking regmap_read()
return value, as suggested by Jonathan Cameron and Andy Shevchenko.
- Update commit message to reflect this new approach
Changes in v2:
- Added Fixes tag.
- Re-examined the entire driver for unchecked regmap operations.
While several regmap_write() and regmap_set_bits() calls also ignore
return values, I focused on this specific regmap_read() in
mt6358_read_imp() because it leads to an uninitialized variable usage
(val_v). This makes this fix critical for reporting correct data
to userspace
drivers/iio/adc/mt6359-auxadc.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/iio/adc/mt6359-auxadc.c b/drivers/iio/adc/mt6359-auxadc.c
index 6b9ed9b1fde2..1d9724ef0983 100644
--- a/drivers/iio/adc/mt6359-auxadc.c
+++ b/drivers/iio/adc/mt6359-auxadc.c
@@ -497,6 +497,7 @@ static int mt6358_read_imp(struct mt6359_auxadc *adc_dev,
return ret;
/* Read the params before stopping */
+ val_v = 0;
regmap_read(regmap, reg_adc0 + (cinfo->imp_adc_num << 1), &val_v);
mt6358_stop_imp_conv(adc_dev);
--
2.43.0
^ permalink raw reply related
* [PATCH v7 3/3] MAINTAINERS: adding entry for BRCMSTB HWSPINLOCK driver
From: Kamal Dasu @ 2026-04-27 20:12 UTC (permalink / raw)
To: andersson, robh
Cc: krzysztof.kozlowski, conor+dt, baolin.wang, florian.fainelli,
bcm-kernel-feedback-list, linux-remoteproc, devicetree,
linux-arm-kernel, linux-kernel, Kamal Dasu
In-Reply-To: <20260427201233.380314-1-kamal.dasu@broadcom.com>
Adding myself to the maintainers list for the hwspinlock
driver on broadcom settop platforms.
Signed-off-by: Kamal Dasu <kamal.dasu@broadcom.com>
---
MAINTAINERS | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 2fb1c75afd16..4f3dfc6a090c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5244,6 +5244,14 @@ S: Supported
F: Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
F: drivers/gpio/gpio-brcmstb.c
+BROADCOM BRCMSTB HWSPINLOCK DRIVER
+M: Kamal Dasu <kamal.dasu@broadcom.com>
+R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
+L: linux-remoteproc@vger.kernel.org
+S: Supported
+F: Documentation/devicetree/bindings/hwlock/brcm,bcm7038-sun-top-ctrl-semaphore.yaml
+F: drivers/hwspinlock/brcmstb_hwspinlock.c
+
BROADCOM BRCMSTB I2C DRIVER
M: Kamal Dasu <kamal.dasu@broadcom.com>
R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
--
2.34.1
^ permalink raw reply related
* Re: [RFC PATCH v1 9/9] uaccess: Convert small fixed size copy_{to/from}_user() to scoped user access
From: Yury Norov @ 2026-04-27 20:12 UTC (permalink / raw)
To: Christophe Leroy (CS GROUP)
Cc: Andrew Morton, Linus Torvalds, David Laight, Thomas Gleixner,
linux-alpha, Yury Norov, linux-kernel, linux-snps-arc,
linux-arm-kernel, linux-mips, linuxppc-dev, kvm, linux-riscv,
linux-s390, sparclinux, linux-um, dmaengine, linux-efi, linux-fsi,
amd-gfx, dri-devel, intel-gfx, linux-wpan, netdev, linux-wireless,
linux-spi, linux-media, linux-staging, linux-serial, linux-usb,
xen-devel, linux-fsdevel, ocfs2-devel, bpf, kasan-dev, linux-mm,
linux-x25, rust-for-linux, linux-sound, sound-open-firmware,
linux-csky, linux-hexagon, loongarch, linux-m68k, linux-openrisc,
linux-parisc, linux-sh, linux-arch
In-Reply-To: <8780eb2ef80575931a339e5225bc80eb13e9be6c.1777306795.git.chleroy@kernel.org>
On Mon, Apr 27, 2026 at 07:13:50PM +0200, Christophe Leroy (CS GROUP) wrote:
> copy_{to/from}_user() is a heavy function optimised for copy of large
> blocs of memory between user and kernel space.
>
> When the number of bytes to be copied is known at build time and small,
> using scoped user access removes the burden of that optimisation.
>
> Signed-off-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
> ---
> include/linux/uaccess.h | 47 +++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 47 insertions(+)
>
> diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
> index 33b7d0f5f808..3ac544527af2 100644
> --- a/include/linux/uaccess.h
> +++ b/include/linux/uaccess.h
> @@ -50,6 +50,8 @@
> #define mask_user_address(src) (src)
> #endif
>
> +#define SMALL_COPY_USER 64
Let's make it L1_CACHE_BYTES, and maybe configurable?
^ permalink raw reply
* Re: [PATCH v2 1/4] ARM: pxa: statify platform device definitions in spitz board file
From: Linus Walleij @ 2026-04-27 20:17 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Daniel Mack, Haojian Zhuang, Robert Jarzmik, Russell King,
Dmitry Torokhov, Arnd Bergmann, brgl, linux-arm-kernel,
linux-gpio, linux-kernel
In-Reply-To: <20260427-pxa-gpio-swnodes-v2-1-86fc24b9e714@oss.qualcomm.com>
On Mon, Apr 27, 2026 at 12:14 PM Bartosz Golaszewski
<bartosz.golaszewski@oss.qualcomm.com> wrote:
> The scoop devices are not used outside of this board file so make them
> static.
>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH] pinctrl: qcom: Make important drivers default
From: Linus Walleij @ 2026-04-27 20:18 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Russell King, Bjorn Andersson, Konrad Dybcio, linux-arm-kernel,
linux-kernel, linux-arm-msm, linux-gpio
In-Reply-To: <20260425155505.83688-2-krzysztof.kozlowski@oss.qualcomm.com>
On Sat, Apr 25, 2026 at 5:55 PM Krzysztof Kozlowski
<krzysztof.kozlowski@oss.qualcomm.com> wrote:
> The main SoC TLMM (Top-Level Multiplexer) pin controller drivers are
> essential for booting up SoCs and are not really optional for a given
> platform. Kernel should not ask users choice of drivers when that
> choice is obvious and known to the developers that answer should be
> 'yes' or 'module'.
>
> Switch all Qualcomm TLMM pin controller drivers to a default 'yes' for
> ARCH_QCOM. This has impact:
>
> 1. arm64 defconfig: enable PINCTRL_SM7150 and PINCTRL_HAWI, which were
> not selected before but should be, because these platforms need them
> for proper boot.
>
> 2. arm qcom_defconfig: no changes.
>
> 3. arm multi_v7 defconfig: enable drivers necessary to boot ARM 32-bit
> platforms, which are already enabled on qcom_defconfig.
>
> 4. COMPILE_TEST builds: enable by default all drivers for arm or arm64
> builds, whenever ARCH_QCOM is selected. This has impact on build
> time and feels logical, because if one selects ARCH_QCOM then
> probably by default wants to build test it entirely. Kernels with
> COMPILE_TEST are not supposed to be used for booting.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Way better like this.
Reviewed-by: Linus Walleij <linusw@kernel.org>
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH] pinctrl: mediatek: moore: implement gpio_chip::get_direction()
From: Linus Walleij @ 2026-04-27 20:19 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Frank Wunderlich, Frank Wunderlich, bartosz.golaszewski, linux,
sean.wang, matthias.bgg, angelogioacchino.delregno,
linux-mediatek, linux-gpio, linux-kernel, linux-arm-kernel
In-Reply-To: <CAMRc=McRuH5Fi-5UQWLRe4+wXKH8qikaYqiqbGXrPOgaifEesw@mail.gmail.com>
On Mon, Apr 27, 2026 at 12:33 PM Bartosz Golaszewski <brgl@kernel.org> wrote:
> > Fixed up and applied. Will be going in as fix for v7.1.
> >
> > Yours,
> > Linus Walleij
> >
>
> Hi Linus!
>
> It seems this one got lost somewhere along the way? I don't see it in
> mainline nor next.
I'm just slow at pushing out my tree, it's on its way!
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v13 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
From: Andrew Lunn @ 2026-04-27 20:28 UTC (permalink / raw)
To: Shenwei Wang
Cc: Padhi, Beleswar, Linus Walleij, Bartosz Golaszewski,
Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer,
Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org, dl-linux-imx,
Bartosz Golaszewski
In-Reply-To: <PAXPR04MB91850A11C58419C03909145F89362@PAXPR04MB9185.eurprd04.prod.outlook.com>
> > > +struct rpmsg_gpio_packet {
> > > + u8 type; /* Message type */
> > > + u8 cmd; /* Command code */
> > > + u8 port_idx;
> > > + u8 line;
> > > + u8 val1;
> > > + u8 val2;
> > > +};
> >
> >
> > Could you please document the fields in these structs (and the below ones too)?
> > From the code, it looks like while sending a message from Linux to Firmware; val1
> > and val2 are used to describe the values to set. Whereas while receiving a
> > response, val1 represents a possible error code, and val2 represents the actual
> > message of get type queries. If that is so, you might want to change the variable
> > names to be more descriptive and also use a union.
> >
>
> The fields in the two structs are fairly self-explanatory. Do we really need the additional comments?
> The previous version of the patch used a union, which was updated to support the fixed_up hooks.
> Now that the fixed_up hooks have been removed, I can revert this back to the union-based implementation.
I thought you had already adopted the virtio message format?
/* Possible values of the status field */
#define VIRTIO_GPIO_STATUS_OK 0x0
#define VIRTIO_GPIO_STATUS_ERR 0x1
struct virtio_gpio_response {
__u8 status;
__u8 value;
};
Seems pretty obvious what status means. value depends on the request,
get_direction actually uses it, and it can be one of
#define VIRTIO_GPIO_DIRECTION_NONE 0x00
#define VIRTIO_GPIO_DIRECTION_OUT 0x01
#define VIRTIO_GPIO_DIRECTION_IN 0x02
and gpio_get uses it as a bool for the state of the GPIO.
Why do we need all the complexity for val1, val2, etc?
Andrew
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox