Unverified Commit 84498d1f authored by Yassine Oudjana's avatar Yassine Oudjana Committed by Mark Brown
Browse files

regmap-irq: Use the new num_config_regs property in regmap_add_irq_chip_fwnode



Commit faa87ce9 ("regmap-irq: Introduce config registers for irq
types") added the num_config_regs, then commit 9edd4f5a ("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 255a03bb ("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: faa87ce9 ("regmap-irq: Introduce config registers for irq types")
Signed-off-by: default avatarYassine Oudjana <y.oudjana@protonmail.com>
Link: https://lore.kernel.org/r/20221107202114.823975-1-y.oudjana@protonmail.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent f0c4d9fc
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -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;