mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 04:24:31 +01:00
Commit4e65bda827("ASoC: wcd934x: fix error handling in wcd934x_codec_parse_data()") revealed the problem in the slimbus regmap. That commit breaks audio playback, for instance, on sdm845 Thundercomm Dragonboard 845c board: Unable to handle kernel paging request at virtual address ffff8000847cbad4 ... CPU: 5 UID: 0 PID: 776 Comm: aplay Not tainted 6.18.0-rc1-00028-g7ea30958b305 #11 PREEMPT Hardware name: Thundercomm Dragonboard 845c (DT) ... Call trace: slim_xfer_msg+0x24/0x1ac [slimbus] (P) slim_read+0x48/0x74 [slimbus] regmap_slimbus_read+0x18/0x24 [regmap_slimbus] _regmap_raw_read+0xe8/0x174 _regmap_bus_read+0x44/0x80 _regmap_read+0x60/0xd8 _regmap_update_bits+0xf4/0x140 _regmap_select_page+0xa8/0x124 _regmap_raw_write_impl+0x3b8/0x65c _regmap_bus_raw_write+0x60/0x80 _regmap_write+0x58/0xc0 regmap_write+0x4c/0x80 wcd934x_hw_params+0x494/0x8b8 [snd_soc_wcd934x] snd_soc_dai_hw_params+0x3c/0x7c [snd_soc_core] __soc_pcm_hw_params+0x22c/0x634 [snd_soc_core] dpcm_be_dai_hw_params+0x1d4/0x38c [snd_soc_core] dpcm_fe_dai_hw_params+0x9c/0x17c [snd_soc_core] snd_pcm_hw_params+0x124/0x464 [snd_pcm] snd_pcm_common_ioctl+0x110c/0x1820 [snd_pcm] snd_pcm_ioctl+0x34/0x4c [snd_pcm] __arm64_sys_ioctl+0xac/0x104 invoke_syscall+0x48/0x104 el0_svc_common.constprop.0+0x40/0xe0 do_el0_svc+0x1c/0x28 el0_svc+0x34/0xec el0t_64_sync_handler+0xa0/0xf0 el0t_64_sync+0x198/0x19c The __devm_regmap_init_slimbus() started to be used instead of __regmap_init_slimbus() after the commit mentioned above and turns out the incorrect bus_context pointer (3rd argument) was used in __devm_regmap_init_slimbus(). It should be just "slimbus" (which is equal to &slimbus->dev). Correct it. The wcd934x codec seems to be the only or the first user of devm_regmap_init_slimbus() but we should fix it till the point where __devm_regmap_init_slimbus() was introduced therefore two "Fixes" tags. While at this, also correct the same argument in __regmap_init_slimbus(). Fixes:4e65bda827("ASoC: wcd934x: fix error handling in wcd934x_codec_parse_data()") Fixes:7d6f7fb053("regmap: add SLIMbus support") Cc: stable@vger.kernel.org Cc: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Cc: Ma Ke <make24@iscas.ac.cn> Cc: Steev Klimaszewski <steev@kali.org> Cc: Srinivas Kandagatla <srini@kernel.org> Reviewed-by: Abel Vesa <abel.vesa@linaro.org> Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Link: https://patch.msgid.link/20251022201013.1740211-1-alexey.klimov@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org>
70 lines
1.9 KiB
C
70 lines
1.9 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
// Copyright (c) 2017, Linaro Ltd.
|
|
|
|
#include <linux/regmap.h>
|
|
#include <linux/slimbus.h>
|
|
#include <linux/module.h>
|
|
|
|
#include "internal.h"
|
|
|
|
static int regmap_slimbus_write(void *context, const void *data, size_t count)
|
|
{
|
|
struct slim_device *sdev = context;
|
|
|
|
return slim_write(sdev, *(u16 *)data, count - 2, (u8 *)data + 2);
|
|
}
|
|
|
|
static int regmap_slimbus_read(void *context, const void *reg, size_t reg_size,
|
|
void *val, size_t val_size)
|
|
{
|
|
struct slim_device *sdev = context;
|
|
|
|
return slim_read(sdev, *(u16 *)reg, val_size, val);
|
|
}
|
|
|
|
static const struct regmap_bus regmap_slimbus_bus = {
|
|
.write = regmap_slimbus_write,
|
|
.read = regmap_slimbus_read,
|
|
.reg_format_endian_default = REGMAP_ENDIAN_LITTLE,
|
|
.val_format_endian_default = REGMAP_ENDIAN_LITTLE,
|
|
};
|
|
|
|
static const struct regmap_bus *regmap_get_slimbus(struct slim_device *slim,
|
|
const struct regmap_config *config)
|
|
{
|
|
if (config->val_bits == 8 && config->reg_bits == 16)
|
|
return ®map_slimbus_bus;
|
|
|
|
return ERR_PTR(-ENOTSUPP);
|
|
}
|
|
|
|
struct regmap *__regmap_init_slimbus(struct slim_device *slimbus,
|
|
const struct regmap_config *config,
|
|
struct lock_class_key *lock_key,
|
|
const char *lock_name)
|
|
{
|
|
const struct regmap_bus *bus = regmap_get_slimbus(slimbus, config);
|
|
|
|
if (IS_ERR(bus))
|
|
return ERR_CAST(bus);
|
|
|
|
return __regmap_init(&slimbus->dev, bus, slimbus, config, lock_key, lock_name);
|
|
}
|
|
EXPORT_SYMBOL_GPL(__regmap_init_slimbus);
|
|
|
|
struct regmap *__devm_regmap_init_slimbus(struct slim_device *slimbus,
|
|
const struct regmap_config *config,
|
|
struct lock_class_key *lock_key,
|
|
const char *lock_name)
|
|
{
|
|
const struct regmap_bus *bus = regmap_get_slimbus(slimbus, config);
|
|
|
|
if (IS_ERR(bus))
|
|
return ERR_CAST(bus);
|
|
|
|
return __devm_regmap_init(&slimbus->dev, bus, slimbus, config, lock_key, lock_name);
|
|
}
|
|
EXPORT_SYMBOL_GPL(__devm_regmap_init_slimbus);
|
|
|
|
MODULE_DESCRIPTION("Register map access API - SLIMbus support");
|
|
MODULE_LICENSE("GPL v2");
|