regmap-irq: Use the new num_config_regs property in regmap_add_irq_chip_fwnode
authorYassine Oudjana <y.oudjana@protonmail.com>
Mon, 7 Nov 2022 20:21:14 +0000 (23:21 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 31 Dec 2022 12:32:09 +0000 (13:32 +0100)
[ 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

index 4ef9488..3de8979 100644 (file)
@@ -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;