From 264716935ed2c10adddbf6fe65214534346062fe Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 10 Jan 2020 14:19:15 +0100 Subject: pinctrl: sh-pfc: checker: Move data before code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restructure the checker to move all data definitions to the top, before the code. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20200110131927.1029-2-geert+renesas@glider.be --- drivers/pinctrl/sh-pfc/core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 82209116955b..a565effbff12 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -726,6 +726,9 @@ static int sh_pfc_suspend_init(struct sh_pfc *pfc) { return 0; } #endif /* CONFIG_PM_SLEEP && CONFIG_ARM_PSCI_FW */ #ifdef DEBUG +static unsigned int sh_pfc_errors __initdata = 0; +static unsigned int sh_pfc_warnings __initdata = 0; + static bool __init is0s(const u16 *enum_ids, unsigned int n) { unsigned int i; @@ -737,9 +740,6 @@ static bool __init is0s(const u16 *enum_ids, unsigned int n) return true; } -static unsigned int sh_pfc_errors __initdata = 0; -static unsigned int sh_pfc_warnings __initdata = 0; - static void __init sh_pfc_check_cfg_reg(const char *drvname, const struct pinmux_cfg_reg *cfg_reg) { -- cgit v1.2.3 From c3f8dcee7a0cfe2a94103c6213d74eac99122f01 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 10 Jan 2020 14:19:16 +0100 Subject: pinctrl: sh-pfc: checker: Add helpers for reporting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add helpers to report errors and warnings, and to increase the corresponding counters. This simplifies callers. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20200110131927.1029-3-geert+renesas@glider.be --- drivers/pinctrl/sh-pfc/core.c | 96 ++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 52 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index a565effbff12..d0b87a024516 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -729,6 +729,17 @@ static int sh_pfc_suspend_init(struct sh_pfc *pfc) { return 0; } static unsigned int sh_pfc_errors __initdata = 0; static unsigned int sh_pfc_warnings __initdata = 0; +#define sh_pfc_err(fmt, ...) \ + do { \ + pr_err("%s: " fmt, drvname, ##__VA_ARGS__); \ + sh_pfc_errors++; \ + } while (0) +#define sh_pfc_warn(fmt, ...) \ + do { \ + pr_warn("%s: " fmt, drvname, ##__VA_ARGS__); \ + sh_pfc_warnings++; \ + } while (0) + static bool __init is0s(const u16 *enum_ids, unsigned int n) { unsigned int i; @@ -751,26 +762,20 @@ static void __init sh_pfc_check_cfg_reg(const char *drvname, } for (i = 0, n = 0, rw = 0; (fw = cfg_reg->var_field_width[i]); i++) { - if (fw > 3 && is0s(&cfg_reg->enum_ids[n], 1 << fw)) { - pr_warn("%s: reg 0x%x: reserved field [%u:%u] can be split to reduce table size\n", - drvname, cfg_reg->reg, rw, rw + fw - 1); - sh_pfc_warnings++; - } + if (fw > 3 && is0s(&cfg_reg->enum_ids[n], 1 << fw)) + sh_pfc_warn("reg 0x%x: reserved field [%u:%u] can be split to reduce table size\n", + cfg_reg->reg, rw, rw + fw - 1); n += 1 << fw; rw += fw; } - if (rw != cfg_reg->reg_width) { - pr_err("%s: reg 0x%x: var_field_width declares %u instead of %u bits\n", - drvname, cfg_reg->reg, rw, cfg_reg->reg_width); - sh_pfc_errors++; - } + if (rw != cfg_reg->reg_width) + sh_pfc_err("reg 0x%x: var_field_width declares %u instead of %u bits\n", + cfg_reg->reg, rw, cfg_reg->reg_width); - 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++; - } + if (n != cfg_reg->nr_enum_ids) + sh_pfc_err("reg 0x%x: enum_ids[] has %u instead of %u values\n", + cfg_reg->reg, cfg_reg->nr_enum_ids, n); } static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) @@ -785,29 +790,24 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) /* Check pins */ for (i = 0; i < info->nr_pins; i++) { for (j = 0; j < i; j++) { - if (!strcmp(info->pins[i].name, info->pins[j].name)) { - pr_err("%s: pin %s/%s: name conflict\n", - drvname, info->pins[i].name, - info->pins[j].name); - sh_pfc_errors++; - } + if (!strcmp(info->pins[i].name, info->pins[j].name)) + sh_pfc_err("pin %s/%s: name conflict\n", + info->pins[i].name, + info->pins[j].name); if (info->pins[i].pin != (u16)-1 && - info->pins[i].pin == info->pins[j].pin) { - pr_err("%s: pin %s/%s: pin %u conflict\n", - drvname, info->pins[i].name, - info->pins[j].name, info->pins[i].pin); - sh_pfc_errors++; - } + info->pins[i].pin == info->pins[j].pin) + sh_pfc_err("pin %s/%s: pin %u conflict\n", + info->pins[i].name, + info->pins[j].name, + info->pins[i].pin); if (info->pins[i].enum_id && - info->pins[i].enum_id == info->pins[j].enum_id) { - pr_err("%s: pin %s/%s: enum_id %u conflict\n", - drvname, info->pins[i].name, - info->pins[j].name, - info->pins[i].enum_id); - sh_pfc_errors++; - } + info->pins[i].enum_id == info->pins[j].enum_id) + sh_pfc_err("pin %s/%s: enum_id %u conflict\n", + info->pins[i].name, + info->pins[j].name, + info->pins[i].enum_id); } } @@ -819,8 +819,7 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) for (i = 0; i < info->nr_functions; i++) { func = &info->functions[i]; if (!func->name) { - pr_err("%s: empty function %u\n", drvname, i); - sh_pfc_errors++; + sh_pfc_err("empty function %u\n", i); continue; } for (j = 0; j < func->nr_groups; j++) { @@ -833,29 +832,22 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) } } - if (k == info->nr_groups) { - pr_err("%s: function %s: group %s not found\n", - drvname, func->name, func->groups[j]); - sh_pfc_errors++; - } + if (k == info->nr_groups) + sh_pfc_err("function %s: group %s not found\n", + func->name, func->groups[j]); } } for (i = 0; i < info->nr_groups; i++) { if (!info->groups[i].name) { - pr_err("%s: empty group %u\n", drvname, i); - sh_pfc_errors++; + sh_pfc_err("empty group %u\n", i); continue; } - if (!refcnts[i]) { - pr_err("%s: orphan group %s\n", drvname, - info->groups[i].name); - sh_pfc_errors++; - } else if (refcnts[i] > 1) { - pr_warn("%s: group %s referenced by %u functions\n", - drvname, info->groups[i].name, refcnts[i]); - sh_pfc_warnings++; - } + if (!refcnts[i]) + sh_pfc_err("orphan group %s\n", info->groups[i].name); + else if (refcnts[i] > 1) + sh_pfc_warn("group %s referenced by %u functions\n", + info->groups[i].name, refcnts[i]); } kfree(refcnts); -- cgit v1.2.3 From 1251887c0c78fe7fee1eb1e13546c86a75368cef Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 10 Jan 2020 14:19:17 +0100 Subject: pinctrl: sh-pfc: checker: Add helper for safe name comparison MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a helper to check if two strings are identical, skipping NULL pointers. This simplifies callers. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20200110131927.1029-4-geert+renesas@glider.be --- drivers/pinctrl/sh-pfc/core.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index d0b87a024516..aad3f62c583f 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -751,6 +751,14 @@ static bool __init is0s(const u16 *enum_ids, unsigned int n) return true; } +static bool __init same_name(const char *a, const char *b) +{ + if (!a || !b) + return false; + + return !strcmp(a, b); +} + static void __init sh_pfc_check_cfg_reg(const char *drvname, const struct pinmux_cfg_reg *cfg_reg) { @@ -790,7 +798,7 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) /* Check pins */ for (i = 0; i < info->nr_pins; i++) { for (j = 0; j < i; j++) { - if (!strcmp(info->pins[i].name, info->pins[j].name)) + if (same_name(info->pins[i].name, info->pins[j].name)) sh_pfc_err("pin %s/%s: name conflict\n", info->pins[i].name, info->pins[j].name); @@ -824,9 +832,8 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) } for (j = 0; j < func->nr_groups; j++) { for (k = 0; k < info->nr_groups; k++) { - if (info->groups[k].name && - !strcmp(func->groups[j], - info->groups[k].name)) { + if (same_name(func->groups[j], + info->groups[k].name)) { refcnts[k]++; break; } -- cgit v1.2.3 From 3c26186472726fd22234fa63a6bc7c08112a4152 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 10 Jan 2020 14:19:18 +0100 Subject: pinctrl: sh-pfc: checker: Add check for config register conflicts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a helper to verify that register addresses are unique, and use it to validate config register descriptors. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20200110131927.1029-5-geert+renesas@glider.be --- drivers/pinctrl/sh-pfc/core.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index aad3f62c583f..69a6ec6aa334 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -726,8 +726,12 @@ static int sh_pfc_suspend_init(struct sh_pfc *pfc) { return 0; } #endif /* CONFIG_PM_SLEEP && CONFIG_ARM_PSCI_FW */ #ifdef DEBUG +#define SH_PFC_MAX_REGS 300 + static unsigned int sh_pfc_errors __initdata = 0; static unsigned int sh_pfc_warnings __initdata = 0; +static u32 *sh_pfc_regs __initdata = NULL; +static u32 sh_pfc_num_regs __initdata = 0; #define sh_pfc_err(fmt, ...) \ do { \ @@ -759,11 +763,31 @@ static bool __init same_name(const char *a, const char *b) return !strcmp(a, b); } +static void __init sh_pfc_check_reg(const char *drvname, u32 reg) +{ + unsigned int i; + + for (i = 0; i < sh_pfc_num_regs; i++) + if (reg == sh_pfc_regs[i]) { + sh_pfc_err("reg 0x%x conflict\n", reg); + return; + } + + if (sh_pfc_num_regs == SH_PFC_MAX_REGS) { + pr_warn_once("%s: Please increase SH_PFC_MAX_REGS\n", drvname); + return; + } + + sh_pfc_regs[sh_pfc_num_regs++] = reg; +} + static void __init sh_pfc_check_cfg_reg(const char *drvname, const struct pinmux_cfg_reg *cfg_reg) { unsigned int i, n, rw, fw; + sh_pfc_check_reg(drvname, cfg_reg->reg); + if (cfg_reg->field_width) { /* Checked at build time */ return; @@ -794,6 +818,7 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) unsigned int i, j, k; pr_info("Checking %s\n", drvname); + sh_pfc_num_regs = 0; /* Check pins */ for (i = 0; i < info->nr_pins; i++) { @@ -868,6 +893,11 @@ static void __init sh_pfc_check_driver(const struct platform_driver *pdrv) { unsigned int i; + sh_pfc_regs = kcalloc(SH_PFC_MAX_REGS, sizeof(*sh_pfc_regs), + GFP_KERNEL); + if (!sh_pfc_regs) + return; + pr_warn("Checking builtin pinmux tables\n"); for (i = 0; pdrv->id_table[i].name[0]; i++) @@ -880,6 +910,8 @@ static void __init sh_pfc_check_driver(const struct platform_driver *pdrv) pr_warn("Detected %u errors and %u warnings\n", sh_pfc_errors, sh_pfc_warnings); + + kfree(sh_pfc_regs); } #else /* !DEBUG */ -- cgit v1.2.3 From 12d057bad683b1c60476681ecc835c858018df60 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 10 Jan 2020 14:19:19 +0100 Subject: pinctrl: sh-pfc: checker: Add check for enum ID conflicts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a helper to verify that enum IDs are unique, and use it to validate the enum ID arrays in config register descriptors. This exposes bugs like those fixed in: - commit 805f635703b2562b ("pinctrl: sh-pfc: r8a7778: Fix duplicate SDSELF_B and SD1_CLK_B"), - commit 884caadad128efad ("pinctrl: sh-pfc: sh7734: Fix duplicate TCLK1_B"), - commit 2a069a92811fb35b ("pinctrl: sh-pfc: sh7264: Fix Port K I/O Register 0 definition"). Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20200110131927.1029-6-geert+renesas@glider.be --- drivers/pinctrl/sh-pfc/core.c | 49 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 69a6ec6aa334..6c6eb791f145 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -727,11 +727,14 @@ static int sh_pfc_suspend_init(struct sh_pfc *pfc) { return 0; } #ifdef DEBUG #define SH_PFC_MAX_REGS 300 +#define SH_PFC_MAX_ENUMS 3000 static unsigned int sh_pfc_errors __initdata = 0; static unsigned int sh_pfc_warnings __initdata = 0; static u32 *sh_pfc_regs __initdata = NULL; static u32 sh_pfc_num_regs __initdata = 0; +static u16 *sh_pfc_enums __initdata = NULL; +static u32 sh_pfc_num_enums __initdata = 0; #define sh_pfc_err(fmt, ...) \ do { \ @@ -781,6 +784,36 @@ static void __init sh_pfc_check_reg(const char *drvname, u32 reg) sh_pfc_regs[sh_pfc_num_regs++] = reg; } +static int __init sh_pfc_check_enum(const char *drvname, u16 enum_id) +{ + unsigned int i; + + for (i = 0; i < sh_pfc_num_enums; i++) { + if (enum_id == sh_pfc_enums[i]) + return -EINVAL; + } + + if (sh_pfc_num_enums == SH_PFC_MAX_ENUMS) { + pr_warn_once("%s: Please increase SH_PFC_MAX_ENUMS\n", drvname); + return 0; + } + + sh_pfc_enums[sh_pfc_num_enums++] = enum_id; + return 0; +} + +static void __init sh_pfc_check_reg_enums(const char *drvname, u32 reg, + const u16 *enums, unsigned int n) +{ + unsigned int i; + + for (i = 0; i < n; i++) { + if (enums[i] && sh_pfc_check_enum(drvname, enums[i])) + sh_pfc_err("reg 0x%x enum_id %u conflict\n", reg, + enums[i]); + } +} + static void __init sh_pfc_check_cfg_reg(const char *drvname, const struct pinmux_cfg_reg *cfg_reg) { @@ -789,8 +822,9 @@ static void __init sh_pfc_check_cfg_reg(const char *drvname, sh_pfc_check_reg(drvname, cfg_reg->reg); if (cfg_reg->field_width) { - /* Checked at build time */ - return; + n = cfg_reg->reg_width / cfg_reg->field_width; + /* Skip field checks (done at build time) */ + goto check_enum_ids; } for (i = 0, n = 0, rw = 0; (fw = cfg_reg->var_field_width[i]); i++) { @@ -808,6 +842,9 @@ static void __init sh_pfc_check_cfg_reg(const char *drvname, if (n != cfg_reg->nr_enum_ids) sh_pfc_err("reg 0x%x: enum_ids[] has %u instead of %u values\n", cfg_reg->reg, cfg_reg->nr_enum_ids, n); + +check_enum_ids: + sh_pfc_check_reg_enums(drvname, cfg_reg->reg, cfg_reg->enum_ids, n); } static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) @@ -819,6 +856,7 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) pr_info("Checking %s\n", drvname); sh_pfc_num_regs = 0; + sh_pfc_num_enums = 0; /* Check pins */ for (i = 0; i < info->nr_pins; i++) { @@ -898,6 +936,11 @@ static void __init sh_pfc_check_driver(const struct platform_driver *pdrv) if (!sh_pfc_regs) return; + sh_pfc_enums = kcalloc(SH_PFC_MAX_ENUMS, sizeof(*sh_pfc_enums), + GFP_KERNEL); + if (!sh_pfc_enums) + goto free_regs; + pr_warn("Checking builtin pinmux tables\n"); for (i = 0; pdrv->id_table[i].name[0]; i++) @@ -911,6 +954,8 @@ static void __init sh_pfc_check_driver(const struct platform_driver *pdrv) pr_warn("Detected %u errors and %u warnings\n", sh_pfc_errors, sh_pfc_warnings); + kfree(sh_pfc_enums); +free_regs: kfree(sh_pfc_regs); } -- cgit v1.2.3 From 4ef30dc72d0a3b3087078379b8e6d666a3c24270 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 10 Jan 2020 14:19:20 +0100 Subject: pinctrl: sh-pfc: checker: Improve pin checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improve the checks for pin descriptors: 1. Introduce local variables for the current pin, to make the checks easier to read, 2. Pins must have a name, 3. Fix double printing of identical pin names. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20200110131927.1029-7-geert+renesas@glider.be --- drivers/pinctrl/sh-pfc/core.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 6c6eb791f145..be7afc48703d 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -860,25 +860,27 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) /* Check pins */ for (i = 0; i < info->nr_pins; i++) { + const struct sh_pfc_pin *pin = &info->pins[i]; + + if (!pin->name) { + sh_pfc_err("empty pin %u\n", i); + continue; + } for (j = 0; j < i; j++) { - if (same_name(info->pins[i].name, info->pins[j].name)) - sh_pfc_err("pin %s/%s: name conflict\n", - info->pins[i].name, - info->pins[j].name); + const struct sh_pfc_pin *pin2 = &info->pins[j]; + + if (same_name(pin->name, pin2->name)) + sh_pfc_err("pin %s: name conflict\n", + pin->name); - if (info->pins[i].pin != (u16)-1 && - info->pins[i].pin == info->pins[j].pin) + if (pin->pin != (u16)-1 && pin->pin == pin2->pin) sh_pfc_err("pin %s/%s: pin %u conflict\n", - info->pins[i].name, - info->pins[j].name, - info->pins[i].pin); + pin->name, pin2->name, pin->pin); - if (info->pins[i].enum_id && - info->pins[i].enum_id == info->pins[j].enum_id) + if (pin->enum_id && pin->enum_id == pin2->enum_id) sh_pfc_err("pin %s/%s: enum_id %u conflict\n", - info->pins[i].name, - info->pins[j].name, - info->pins[i].enum_id); + pin->name, pin2->name, + pin->enum_id); } } -- cgit v1.2.3 From a95b077db4fcf5aeeaf74372e31d684df29cb033 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 10 Jan 2020 14:19:21 +0100 Subject: pinctrl: sh-pfc: checker: Improve pin function checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improve the checks for pin function descriptors: 1. Merge declaration and assignment of the local variable for the current pin function, 2. Pin function names must be unique. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20200110131927.1029-8-geert+renesas@glider.be --- drivers/pinctrl/sh-pfc/core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index be7afc48703d..fd649ab8ad1a 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -849,7 +849,6 @@ check_enum_ids: static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) { - const struct sh_pfc_function *func; const char *drvname = info->name; unsigned int *refcnts; unsigned int i, j, k; @@ -890,11 +889,17 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) return; for (i = 0; i < info->nr_functions; i++) { - func = &info->functions[i]; + const struct sh_pfc_function *func = &info->functions[i]; + if (!func->name) { sh_pfc_err("empty function %u\n", i); continue; } + for (j = 0; j < i; j++) { + if (same_name(func->name, info->functions[j].name)) + sh_pfc_err("function %s: name conflict\n", + func->name); + } for (j = 0; j < func->nr_groups; j++) { for (k = 0; k < info->nr_groups; k++) { if (same_name(func->groups[j], -- cgit v1.2.3 From 40c8e4aad4e1575e101576aab1313f99ed3df49d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 10 Jan 2020 14:19:22 +0100 Subject: pinctrl: sh-pfc: checker: Improve pin group checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improve the checks for pin group descriptors: 1. Introduce a local variable for the current group, to make the checks easier to read, 2. Pin group names must be unique. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20200110131927.1029-9-geert+renesas@glider.be --- drivers/pinctrl/sh-pfc/core.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index fd649ab8ad1a..b67584d65ecc 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -916,15 +916,22 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) } for (i = 0; i < info->nr_groups; i++) { - if (!info->groups[i].name) { + const struct sh_pfc_pin_group *group = &info->groups[i]; + + if (!group->name) { sh_pfc_err("empty group %u\n", i); continue; } + for (j = 0; j < i; j++) { + if (same_name(group->name, info->groups[j].name)) + sh_pfc_err("group %s: name conflict\n", + group->name); + } if (!refcnts[i]) - sh_pfc_err("orphan group %s\n", info->groups[i].name); + sh_pfc_err("orphan group %s\n", group->name); else if (refcnts[i] > 1) sh_pfc_warn("group %s referenced by %u functions\n", - info->groups[i].name, refcnts[i]); + group->name, refcnts[i]); } kfree(refcnts); -- cgit v1.2.3 From 08df16e07ad0a1ec0ccf9a154014cb80e82c773e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 10 Jan 2020 14:19:23 +0100 Subject: pinctrl: sh-pfc: checker: Add drive strength register checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add checks for drive strength register descriptors: 1. Register addresses must be unique, 2. Register fields must be non-overlapping, 3. Referred pins must exist. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20200110131927.1029-10-geert+renesas@glider.be --- drivers/pinctrl/sh-pfc/core.c | 45 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index b67584d65ecc..8304832e7c39 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -814,6 +814,23 @@ static void __init sh_pfc_check_reg_enums(const char *drvname, u32 reg, } } +static void __init sh_pfc_check_pin(const struct sh_pfc_soc_info *info, + u32 reg, unsigned int pin) +{ + const char *drvname = info->name; + unsigned int i; + + if (pin == SH_PFC_PIN_NONE) + return; + + for (i = 0; i < info->nr_pins; i++) { + if (pin == info->pins[i].pin) + return; + } + + sh_pfc_err("reg 0x%x: pin %u not found\n", reg, pin); +} + static void __init sh_pfc_check_cfg_reg(const char *drvname, const struct pinmux_cfg_reg *cfg_reg) { @@ -847,6 +864,30 @@ check_enum_ids: sh_pfc_check_reg_enums(drvname, cfg_reg->reg, cfg_reg->enum_ids, n); } +static void __init sh_pfc_check_drive_reg(const struct sh_pfc_soc_info *info, + const struct pinmux_drive_reg *drive) +{ + const char *drvname = info->name; + unsigned long seen = 0, mask; + unsigned int i; + + sh_pfc_check_reg(info->name, drive->reg); + for (i = 0; i < ARRAY_SIZE(drive->fields); i++) { + const struct pinmux_drive_reg_field *field = &drive->fields[i]; + + if (!field->pin && !field->offset && !field->size) + continue; + + mask = GENMASK(field->offset + field->size, field->offset); + if (mask & seen) + sh_pfc_err("drive_reg 0x%x: field %u overlap\n", + drive->reg, i); + seen |= mask; + + sh_pfc_check_pin(info, drive->reg, field->pin); + } +} + static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) { const char *drvname = info->name; @@ -939,6 +980,10 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) /* Check config register descriptions */ for (i = 0; info->cfg_regs && info->cfg_regs[i].reg; i++) sh_pfc_check_cfg_reg(drvname, &info->cfg_regs[i]); + + /* Check drive strength registers */ + for (i = 0; info->drive_regs && info->drive_regs[i].reg; i++) + sh_pfc_check_drive_reg(info, &info->drive_regs[i]); } static void __init sh_pfc_check_driver(const struct platform_driver *pdrv) -- cgit v1.2.3 From 8990cd297f1508904d3773f6a2c5af531e8649ca Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 10 Jan 2020 14:19:24 +0100 Subject: pinctrl: sh-pfc: checker: Add bias register checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add checks for bias register descriptors: 1. Pull-up and optional pull-down register addresses must be unique, 2. Referred pins must exist. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20200110131927.1029-11-geert+renesas@glider.be --- drivers/pinctrl/sh-pfc/core.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 8304832e7c39..fcd11d83ee41 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -888,6 +888,18 @@ static void __init sh_pfc_check_drive_reg(const struct sh_pfc_soc_info *info, } } +static void __init sh_pfc_check_bias_reg(const struct sh_pfc_soc_info *info, + const struct pinmux_bias_reg *bias) +{ + unsigned int i; + + sh_pfc_check_reg(info->name, bias->puen); + if (bias->pud) + sh_pfc_check_reg(info->name, bias->pud); + for (i = 0; i < ARRAY_SIZE(bias->pins); i++) + sh_pfc_check_pin(info, bias->puen, bias->pins[i]); +} + static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) { const char *drvname = info->name; @@ -984,6 +996,10 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) /* Check drive strength registers */ for (i = 0; info->drive_regs && info->drive_regs[i].reg; i++) sh_pfc_check_drive_reg(info, &info->drive_regs[i]); + + /* Check bias registers */ + for (i = 0; info->bias_regs && info->bias_regs[i].puen; i++) + sh_pfc_check_bias_reg(info, &info->bias_regs[i]); } static void __init sh_pfc_check_driver(const struct platform_driver *pdrv) -- cgit v1.2.3 From 4bd7d16a309e034ec92b13840bae5668918ddd5b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 10 Jan 2020 14:19:25 +0100 Subject: pinctrl: sh-pfc: checker: Add ioctrl register checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add checks for generic control register descriptors: 1. Register addresses must be unique. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20200110131927.1029-12-geert+renesas@glider.be --- drivers/pinctrl/sh-pfc/core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index fcd11d83ee41..42432db4fc0b 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -1000,6 +1000,10 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) /* Check bias registers */ for (i = 0; info->bias_regs && info->bias_regs[i].puen; i++) sh_pfc_check_bias_reg(info, &info->bias_regs[i]); + + /* Check ioctrl registers */ + for (i = 0; info->ioctrl_regs && info->ioctrl_regs[i].reg; i++) + sh_pfc_check_reg(drvname, info->ioctrl_regs[i].reg); } static void __init sh_pfc_check_driver(const struct platform_driver *pdrv) -- cgit v1.2.3 From 0e6cd847a420e21f6e0d476c355127a7cbcb4a5d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 10 Jan 2020 14:19:26 +0100 Subject: pinctrl: sh-pfc: checker: Add data register checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add checks for data register descriptors: 1. Register addresses must be unique. 2. Enum ID values must be unique. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20200110131927.1029-13-geert+renesas@glider.be --- drivers/pinctrl/sh-pfc/core.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 42432db4fc0b..da2baa9446ce 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -1004,6 +1004,14 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) /* Check ioctrl registers */ for (i = 0; info->ioctrl_regs && info->ioctrl_regs[i].reg; i++) sh_pfc_check_reg(drvname, info->ioctrl_regs[i].reg); + + /* Check data registers */ + for (i = 0; info->data_regs && info->data_regs[i].reg; i++) { + sh_pfc_check_reg(drvname, info->data_regs[i].reg); + sh_pfc_check_reg_enums(drvname, info->data_regs[i].reg, + info->data_regs[i].enum_ids, + info->data_regs[i].reg_width); + } } static void __init sh_pfc_check_driver(const struct platform_driver *pdrv) -- cgit v1.2.3 From 92c44680c5c6f1342288f6626da4008d416d8e40 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 10 Jan 2020 14:19:27 +0100 Subject: pinctrl: sh-pfc: checker: Add function GPIO checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add checks for legacy function GPIO descriptors: 1. Function GPIOs must have a name, 2. Names must be unique, 3. Enum ID values must be unique. This exposes bugs like those fixed in - commit 884caadad128efad ("pinctrl: sh-pfc: sh7734: Fix duplicate TCLK1_B"), - commit 55b1cb1f03ad5eea ("pinctrl: sh-pfc: sh7264: Fix CAN function GPIOs"), - commit 02aeb2f21530c98f ("pinctrl: sh-pfc: sh7269: Fix CAN function GPIOs"), - commit db9c07272c8245a2 ("sh: sh7264: Remove bogus SSU GPIO function definitions"), - commit b4fba344a2930769 ("sh: sh7269: Remove bogus SSU GPIO function definitions"). Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20200110131927.1029-14-geert+renesas@glider.be --- drivers/pinctrl/sh-pfc/core.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index da2baa9446ce..a2e19efa26e3 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -1012,6 +1012,26 @@ static void __init sh_pfc_check_info(const struct sh_pfc_soc_info *info) info->data_regs[i].enum_ids, info->data_regs[i].reg_width); } + +#ifdef CONFIG_PINCTRL_SH_FUNC_GPIO + /* Check function GPIOs */ + for (i = 0; i < info->nr_func_gpios; i++) { + const struct pinmux_func *func = &info->func_gpios[i]; + + if (!func->name) { + sh_pfc_err("empty function gpio %u\n", i); + continue; + } + for (j = 0; j < i; j++) { + if (same_name(func->name, info->func_gpios[j].name)) + sh_pfc_err("func_gpio %s: name conflict\n", + func->name); + } + if (sh_pfc_check_enum(drvname, func->enum_id)) + sh_pfc_err("%s enum_id %u conflict\n", func->name, + func->enum_id); + } +#endif } static void __init sh_pfc_check_driver(const struct platform_driver *pdrv) -- cgit v1.2.3 From 6793baa31d684f2cace0e2ee4af4bdbc993dbed8 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 12 Feb 2020 10:02:00 +0100 Subject: pinctrl: sh-pfc: gpio: Return early in gpio_pin_to_irq() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As of commit 4adeabd042422cee ("pinctrl: sh-pfc: Remove hardcoded IRQ numbers"), only a single operation needs to be performed after finding the wanted pin. Hence decrease the needed attention span of the casual reader by replacing the goto by a direct return. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20200212090200.11106-1-geert+renesas@glider.be --- drivers/pinctrl/sh-pfc/gpio.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 8213e118aa40..9c6e931ae766 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -205,14 +205,11 @@ static int gpio_pin_to_irq(struct gpio_chip *gc, unsigned offset) for (k = 0; gpios[k] >= 0; k++) { if (gpios[k] == offset) - goto found; + return pfc->irqs[i]; } } return 0; - -found: - return pfc->irqs[i]; } static int gpio_pin_setup(struct sh_pfc_chip *chip) -- cgit v1.2.3 From ffe9f9b0515600fc5ccf121315939c2ab2cd1486 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 18 Feb 2020 12:25:57 +0100 Subject: pinctrl: sh-pfc: Remove use of ARCH_R8A7795 CONFIG_ARCH_R8A7795 was split in CONFIG_ARCH_R8A77950 and CONFIG_ARCH_R8A77951 in commit b925adfceb529389 ("soc: renesas: Add ARCH_R8A7795[01] for existing R-Car H3"), so its users can be removed. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20200218112557.5924-1-geert+renesas@glider.be --- drivers/pinctrl/sh-pfc/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/sh-pfc/Kconfig b/drivers/pinctrl/sh-pfc/Kconfig index cf0e0dc42b84..9552851b96f1 100644 --- a/drivers/pinctrl/sh-pfc/Kconfig +++ b/drivers/pinctrl/sh-pfc/Kconfig @@ -26,8 +26,8 @@ config PINCTRL_SH_PFC select PINCTRL_PFC_R8A7792 if ARCH_R8A7792 select PINCTRL_PFC_R8A7793 if ARCH_R8A7793 select PINCTRL_PFC_R8A7794 if ARCH_R8A7794 - select PINCTRL_PFC_R8A77950 if ARCH_R8A77950 || ARCH_R8A7795 - select PINCTRL_PFC_R8A77951 if ARCH_R8A77951 || ARCH_R8A7795 + select PINCTRL_PFC_R8A77950 if ARCH_R8A77950 + select PINCTRL_PFC_R8A77951 if ARCH_R8A77951 select PINCTRL_PFC_R8A77960 if ARCH_R8A77960 select PINCTRL_PFC_R8A77961 if ARCH_R8A77961 select PINCTRL_PFC_R8A77965 if ARCH_R8A77965 -- cgit v1.2.3