From: Yassine Oudjana y.oudjana@protonmail.com
[ Upstream commit 84498d1fb35de6ab71bdfdb6270a464fb4a0951b ]
Commit faa87ce9196d ("regmap-irq: Introduce config registers for irq types") added the num_config_regs, then commit 9edd4f5aee84 ("regmap-irq: Deprecate type registers and virtual registers") suggested to replace num_type_reg with it. However, regmap_add_irq_chip_fwnode wasn't modified to use the new property. Later on, commit 255a03bb1bb3 ("ASoC: wcd9335: Convert irq chip to config regs") removed the old num_type_reg property from the WCD9335 driver's struct regmap_irq_chip, causing a null pointer dereference in regmap_irq_set_type when it tried to index d->type_buf as it was never allocated in regmap_add_irq_chip_fwnode:
[ 39.199374] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
[ 39.200006] Call trace: [ 39.200014] regmap_irq_set_type+0x84/0x1c0 [ 39.200026] __irq_set_trigger+0x60/0x1c0 [ 39.200040] __setup_irq+0x2f4/0x78c [ 39.200051] request_threaded_irq+0xe8/0x1a0
Use num_config_regs in regmap_add_irq_chip_fwnode instead of num_type_reg, and fall back to it if num_config_regs isn't defined to maintain backward compatibility.
Fixes: faa87ce9196d ("regmap-irq: Introduce config registers for irq types") Signed-off-by: Yassine Oudjana y.oudjana@protonmail.com Link: https://lore.kernel.org/r/20221107202114.823975-1-y.oudjana@protonmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/base/regmap/regmap-irq.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index 4ef9488d05cd..3de89795f584 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -722,6 +722,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, int i; int ret = -ENOMEM; int num_type_reg; + int num_regs; u32 reg;
if (chip->num_regs <= 0) @@ -796,14 +797,20 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, goto err_alloc; }
- num_type_reg = chip->type_in_mask ? chip->num_regs : chip->num_type_reg; - if (num_type_reg) { - d->type_buf_def = kcalloc(num_type_reg, + /* + * Use num_config_regs if defined, otherwise fall back to num_type_reg + * to maintain backward compatibility. + */ + num_type_reg = chip->num_config_regs ? chip->num_config_regs + : chip->num_type_reg; + num_regs = chip->type_in_mask ? chip->num_regs : num_type_reg; + if (num_regs) { + d->type_buf_def = kcalloc(num_regs, sizeof(*d->type_buf_def), GFP_KERNEL); if (!d->type_buf_def) goto err_alloc;
- d->type_buf = kcalloc(num_type_reg, sizeof(*d->type_buf), + d->type_buf = kcalloc(num_regs, sizeof(*d->type_buf), GFP_KERNEL); if (!d->type_buf) goto err_alloc;