Re: [PATCH v4 1/1] regmap: Synchronize cache for the page selector
From: Marek Szyprowski
Date: Wed Feb 18 2026 - 03:31:00 EST
On 18.02.2026 08:46, Andy Shevchenko wrote:
> If the selector register is represented in each page, its value
> according to the debugfs is stale because it gets synchronized
> only after the real page switch happens. Hence the regmap cache
> initialisation from the HW inherits outdated data in the selector
> register.
>
> Synchronize cache for the page selector just in time.
>
> Before (offset followed by hexdump, the first byte is selector):
>
> // Real registers
> 18: 05 ff 00 00 ff 0f 00 00 f0 00 00 00
> ...
> // Virtual (per port)
> 40: 05 ff 00 00 e0 e0 00 00 00 00 00 1f
> 50: 00 ff 00 00 e0 e0 00 00 00 00 00 1f
> 60: 01 ff 00 00 ff ff 00 00 00 00 00 00
> 70: 02 ff 00 00 cf f3 00 00 00 00 00 0c
> 80: 03 ff 00 00 00 00 00 00 00 00 00 ff
> 90: 04 ff 00 00 ff 0f 00 00 f0 00 00 00
>
> After:
>
> // Real registers
> 18: 05 ff 00 00 ff 0f 00 00 f0 00 00 00
> ...
> // Virtual (per port)
> 40: 00 ff 00 00 e0 e0 00 00 00 00 00 1f
> 50: 01 ff 00 00 e0 e0 00 00 00 00 00 1f
> 60: 02 ff 00 00 ff ff 00 00 00 00 00 00
> 70: 03 ff 00 00 cf f3 00 00 00 00 00 0c
> 80: 04 ff 00 00 00 00 00 00 00 00 00 ff
> 90: 05 ff 00 00 ff 0f 00 00 f0 00 00 00
>
> Fixes: 6863ca622759 ("regmap: Add support for register indirect addressing.")
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
> ---
> v4: reworked the approach completely
>
> Marek, Dmitry,
> Please, test on your HW to be sure this will have no side effects
> in your case with LT9611.
It looks that it ends in infinite recurrent calls after this patch:
Insufficient stack space to handle exception!
ESR: 0x0000000096000047 -- DABT (current EL)
FAR: 0xffff8000859bffe0
Task stack: [0xffff8000859c0000..0xffff8000859c4000]
IRQ stack: [0xffff800080030000..0xffff800080034000]
Overflow stack: [0xffff0001fef36140..0xffff0001fef37140]
CPU: 6 UID: 0 PID: 341 Comm: (udev-worker) Not tainted
6.19.0-next-20260217+ #12215 PREEMPT
Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT)
pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : _regmap_select_page+0x4/0x120
lr : _regmap_raw_read+0x240/0x340
...
Kernel panic - not syncing: kernel stack overflow
CPU: 6 UID: 0 PID: 341 Comm: (udev-worker) Not tainted
6.19.0-next-20260217+ #12215 PREEMPT
Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT)
Call trace:
show_stack+0x18/0x24 (C)
dump_stack_lvl+0x38/0xd0
dump_stack+0x18/0x24
vpanic+0x4f8/0x4fc
do_panic_on_target_cpu+0x0/0x1c
add_taint+0x0/0xbc
panic_bad_stack+0x104/0x124
__sdei_handler+0x0/0x2c4
__bad_stack+0x80/0x84
_regmap_select_page+0x4/0x120 (P)
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_read+0x240/0x340
_regmap_bus_read+0x44/0x7c
_regmap_read+0x64/0x1f0
_regmap_update_bits+0xec/0x134
_regmap_select_page+0x9c/0x120
_regmap_raw_write_impl+0x414/0x7b8
_regmap_bus_raw_write+0x60/0x7c
_regmap_write+0x60/0x1b8
regmap_write+0x4c/0x78
lt9611uxc_probe+0x208/0x684 [lontium_lt9611uxc]
i2c_device_probe+0x154/0x344
really_probe+0xbc/0x298
__driver_probe_device+0x78/0x12c
driver_probe_device+0x40/0x164
__driver_attach+0xe4/0x224
bus_for_each_dev+0x74/0xd0
driver_attach+0x24/0x30
bus_add_driver+0xe4/0x208
driver_register+0x60/0x128
i2c_register_driver+0x48/0xd0
lt9611uxc_driver_init+0x20/0x1000 [lontium_lt9611uxc]
do_one_initcall+0x64/0x504
do_init_module+0x58/0x23c
load_module+0x1b48/0x1e64
init_module_from_file+0xd4/0xec
idempotent_init_module+0x188/0x280
__arm64_sys_finit_module+0x68/0xac
invoke_syscall+0x48/0x10c
el0_svc_common.constprop.0+0xc8/0xe8
do_el0_svc+0x20/0x2c
el0_svc+0x50/0x2e8
el0t_64_sync_handler+0xa0/0xe4
el0t_64_sync+0x198/0x19c
SMP: stopping secondary CPUs
> drivers/base/regmap/regmap.c | 14 +++++++++++---
> 1 file changed, 11 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
> index 5d5a3e115022..1b90f00a5005 100644
> --- a/drivers/base/regmap/regmap.c
> +++ b/drivers/base/regmap/regmap.c
> @@ -1525,10 +1525,18 @@ static int _regmap_select_page(struct regmap *map, unsigned int *reg,
> return -EINVAL;
> }
>
> - /* It is possible to have selector register inside data window.
> - In that case, selector register is located on every page and
> - it needs no page switching, when accessed alone. */
> + /*
> + * It is possible to have selector register inside data window.
> + * In that case, selector register is located on every page and it
> + * needs no page switching, when accessed alone.
> + *
> + * Nevertheless we should synchronize the cache values for it.
> + * This can't be properly achieved if the selector register is
> + * the first and the only one to be read inside the data window.
> + * That's why we update it in that case as well.
> + */
> if (val_num > 1 ||
> + in_range(range->selector_reg, range->window_start, range->window_len) ||
> range->window_start + win_offset != range->selector_reg) {
> /* Use separate work_buf during page switching */
> orig_work_buf = map->work_buf;
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland