Add a run-time check to the PINMUX_CFG_REG_VAR() macro, to ensure the
number of provided enum IDs is correct.  This cannot be done at build
time, as the number of values depends on the variable-width fields in
the config register.

This helps catching bugs early.

Signed-off-by: Geert Uytterhoeven <[email protected]>
---
v2:
  - Extract into its own patch.
---
 drivers/pinctrl/sh-pfc/core.c   |  6 ++++++
 drivers/pinctrl/sh-pfc/sh_pfc.h | 15 +++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c
index f9371e160872f2b4..271f190d08a509f8 100644
--- a/drivers/pinctrl/sh-pfc/core.c
+++ b/drivers/pinctrl/sh-pfc/core.c
@@ -756,6 +756,12 @@ static void sh_pfc_check_cfg_reg(const char *drvname,
                       drvname, cfg_reg->reg, rw, cfg_reg->reg_width);
                sh_pfc_errors++;
        }
+
+       if (n != cfg_reg->nr_enum_ids) {
+               pr_err("%s: reg 0x%x: enum_ids[] has %u instead of %u values\n",
+                      drvname, cfg_reg->reg, cfg_reg->nr_enum_ids, n);
+               sh_pfc_errors++;
+       }
 }
 
 static void sh_pfc_check_info(const struct sh_pfc_soc_info *info)
diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h
index dd483dbb71f06be3..9f5d54b851b14ac9 100644
--- a/drivers/pinctrl/sh-pfc/sh_pfc.h
+++ b/drivers/pinctrl/sh-pfc/sh_pfc.h
@@ -113,6 +113,9 @@ struct pinmux_cfg_reg {
        u8 reg_width, field_width;
        const u16 *enum_ids;
        const u8 *var_field_width;
+#ifdef DEBUG
+       unsigned int nr_enum_ids;       /* for variable width regs only */
+#endif
 };
 
 #define GROUP(...)     __VA_ARGS__
@@ -148,11 +151,23 @@ struct pinmux_cfg_reg {
  *          combination of the register field bit values, all wrapped using
  *          the GROUP() macro.
  */
+#ifdef DEBUG
+
+#define PINMUX_CFG_REG_VAR(name, r, r_width, f_widths, ids)            \
+       .reg = r, .reg_width = r_width,                                 \
+       .var_field_width = (const u8 []) { f_widths, 0 },               \
+       .enum_ids = (const u16 []) { ids },                             \
+       .nr_enum_ids = sizeof((const u16 []) { ids }) / sizeof(u16)
+
+#else
+
 #define PINMUX_CFG_REG_VAR(name, r, r_width, f_widths, ids)            \
        .reg = r, .reg_width = r_width,                                 \
        .var_field_width = (const u8 []) { f_widths, 0 },               \
        .enum_ids = (const u16 []) { ids }
 
+#endif
+
 struct pinmux_drive_reg_field {
        u16 pin;
        u8 offset;
-- 
2.17.1

Reply via email to