From ea217fefef8c9632486a943a029b01cee717dce5 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 11 Mar 2024 16:08:33 +0200 Subject: pinctrl: pxa2xx: Make use of struct pinfunction Since pin control provides a generic data type for the pin function, use it in the driver. Signed-off-by: Andy Shevchenko Message-ID: <20240311140833.1168742-1-andriy.shevchenko@linux.intel.com> Signed-off-by: Linus Walleij --- drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 24 ++++++++++-------------- drivers/pinctrl/pxa/pinctrl-pxa2xx.h | 8 +------- 2 files changed, 11 insertions(+), 21 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c index d2568dab8c78..f24bf49fa82b 100644 --- a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c +++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c @@ -109,7 +109,7 @@ static const char *pxa2xx_pmx_get_func_name(struct pinctrl_dev *pctldev, unsigned function) { struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - struct pxa_pinctrl_function *pf = pctl->functions + function; + struct pinfunction *pf = pctl->functions + function; return pf->name; } @@ -127,7 +127,7 @@ static int pxa2xx_pmx_get_func_groups(struct pinctrl_dev *pctldev, unsigned * const num_groups) { struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - struct pxa_pinctrl_function *pf = pctl->functions + function; + struct pinfunction *pf = pctl->functions + function; *groups = pf->groups; *num_groups = pf->ngroups; @@ -249,11 +249,11 @@ static struct pinctrl_desc pxa2xx_pinctrl_desc = { .pmxops = &pxa2xx_pinmux_ops, }; -static const struct pxa_pinctrl_function * -pxa2xx_find_function(struct pxa_pinctrl *pctl, const char *fname, - const struct pxa_pinctrl_function *functions) +static const struct pinfunction *pxa2xx_find_function(struct pxa_pinctrl *pctl, + const char *fname, + const struct pinfunction *functions) { - const struct pxa_pinctrl_function *func; + const struct pinfunction *func; for (func = functions; func->name; func++) if (!strcmp(fname, func->name)) @@ -264,8 +264,8 @@ pxa2xx_find_function(struct pxa_pinctrl *pctl, const char *fname, static int pxa2xx_build_functions(struct pxa_pinctrl *pctl) { + struct pinfunction *functions; int i; - struct pxa_pinctrl_function *functions; struct pxa_desc_function *df; /* @@ -296,9 +296,9 @@ static int pxa2xx_build_functions(struct pxa_pinctrl *pctl) static int pxa2xx_build_groups(struct pxa_pinctrl *pctl) { int i, j, ngroups; - struct pxa_pinctrl_function *func; struct pxa_desc_function *df; - char **gtmp; + struct pinfunction *func; + const char **gtmp; gtmp = devm_kmalloc_array(pctl->dev, pctl->npins, sizeof(*gtmp), GFP_KERNEL); @@ -316,13 +316,9 @@ static int pxa2xx_build_groups(struct pxa_pinctrl *pctl) pctl->ppins[j].pin.name; func = pctl->functions + i; func->ngroups = ngroups; - func->groups = - devm_kmalloc_array(pctl->dev, ngroups, - sizeof(char *), GFP_KERNEL); + func->groups = devm_kmemdup(pctl->dev, gtmp, ngroups * sizeof(*gtmp), GFP_KERNEL); if (!func->groups) return -ENOMEM; - - memcpy(func->groups, gtmp, ngroups * sizeof(*gtmp)); } devm_kfree(pctl->dev, gtmp); diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.h b/drivers/pinctrl/pxa/pinctrl-pxa2xx.h index d86d47dbbc94..a0bdcec55158 100644 --- a/drivers/pinctrl/pxa/pinctrl-pxa2xx.h +++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.h @@ -57,12 +57,6 @@ struct pxa_pinctrl_group { unsigned pin; }; -struct pxa_pinctrl_function { - const char *name; - const char **groups; - unsigned ngroups; -}; - struct pxa_pinctrl { spinlock_t lock; void __iomem **base_gafr; @@ -76,7 +70,7 @@ struct pxa_pinctrl { unsigned ngroups; struct pxa_pinctrl_group *groups; unsigned nfuncs; - struct pxa_pinctrl_function *functions; + struct pinfunction *functions; char *name; }; -- cgit v1.2.3 From 76c22f094153478dc89735c9bd259ad99f933913 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 11 Mar 2024 16:22:48 +0200 Subject: pinctrl: pxa2xx: Make use of struct pingroup Since pin control provides a generic data type for the pin group, use it in the driver. Signed-off-by: Andy Shevchenko Message-ID: <20240311142346.1261203-1-andriy.shevchenko@linux.intel.com> Signed-off-by: Linus Walleij --- drivers/pinctrl/pxa/pinctrl-pxa2xx.c | 31 +++++++++++++++---------------- drivers/pinctrl/pxa/pinctrl-pxa2xx.h | 7 +------ 2 files changed, 16 insertions(+), 22 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c index f24bf49fa82b..9e34b92ff5f2 100644 --- a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c +++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c @@ -32,7 +32,7 @@ static const char *pxa2xx_pctrl_get_group_name(struct pinctrl_dev *pctldev, unsigned tgroup) { struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - struct pxa_pinctrl_group *group = pctl->groups + tgroup; + struct pingroup *group = pctl->groups + tgroup; return group->name; } @@ -43,10 +43,10 @@ static int pxa2xx_pctrl_get_group_pins(struct pinctrl_dev *pctldev, unsigned *num_pins) { struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - struct pxa_pinctrl_group *group = pctl->groups + tgroup; + struct pingroup *group = pctl->groups + tgroup; - *pins = (unsigned *)&group->pin; - *num_pins = 1; + *pins = group->pins; + *num_pins = group->npins; return 0; } @@ -139,20 +139,18 @@ static int pxa2xx_pmx_set_mux(struct pinctrl_dev *pctldev, unsigned function, unsigned tgroup) { struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - struct pxa_pinctrl_group *group = pctl->groups + tgroup; + struct pingroup *g = pctl->groups + tgroup; + unsigned int pin = g->pins[0]; struct pxa_desc_function *df; - int pin, shift; unsigned long flags; void __iomem *gafr, *gpdr; + int shift; u32 val; - - df = pxa_desc_by_func_group(pctl, group->name, - (pctl->functions + function)->name); + df = pxa_desc_by_func_group(pctl, g->name, (pctl->functions + function)->name); if (!df) return -EINVAL; - pin = group->pin; gafr = pctl->base_gafr[pin / 16]; gpdr = pctl->base_gpdr[pin / 32]; shift = (pin % 16) << 1; @@ -186,9 +184,9 @@ static int pxa2xx_pconf_group_get(struct pinctrl_dev *pctldev, unsigned long *config) { struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - struct pxa_pinctrl_group *g = pctl->groups + group; + struct pingroup *g = pctl->groups + group; + unsigned int pin = g->pins[0]; unsigned long flags; - unsigned pin = g->pin; void __iomem *pgsr = pctl->base_pgsr[pin / 32]; u32 val; @@ -208,9 +206,9 @@ static int pxa2xx_pconf_group_set(struct pinctrl_dev *pctldev, unsigned num_configs) { struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - struct pxa_pinctrl_group *g = pctl->groups + group; + struct pingroup *g = pctl->groups + group; + unsigned int pin = g->pins[0]; unsigned long flags; - unsigned pin = g->pin; void __iomem *pgsr = pctl->base_pgsr[pin / 32]; int i, is_set = 0; u32 val; @@ -328,8 +326,8 @@ static int pxa2xx_build_groups(struct pxa_pinctrl *pctl) static int pxa2xx_build_state(struct pxa_pinctrl *pctl, const struct pxa_desc_pin *ppins, int npins) { - struct pxa_pinctrl_group *group; struct pinctrl_pin_desc *pins; + struct pingroup *group; int ret, i; pctl->npins = npins; @@ -353,7 +351,8 @@ static int pxa2xx_build_state(struct pxa_pinctrl *pctl, for (i = 0; i < npins; i++) { group = pctl->groups + i; group->name = ppins[i].pin.name; - group->pin = ppins[i].pin.number; + group->pins = &ppins[i].pin.number; + group->npins = 1; } ret = pxa2xx_build_functions(pctl); diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.h b/drivers/pinctrl/pxa/pinctrl-pxa2xx.h index a0bdcec55158..b292b79efdf8 100644 --- a/drivers/pinctrl/pxa/pinctrl-pxa2xx.h +++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.h @@ -52,11 +52,6 @@ struct pxa_desc_pin { struct pxa_desc_function *functions; }; -struct pxa_pinctrl_group { - const char *name; - unsigned pin; -}; - struct pxa_pinctrl { spinlock_t lock; void __iomem **base_gafr; @@ -68,7 +63,7 @@ struct pxa_pinctrl { unsigned npins; const struct pxa_desc_pin *ppins; unsigned ngroups; - struct pxa_pinctrl_group *groups; + struct pingroup *groups; unsigned nfuncs; struct pinfunction *functions; char *name; -- cgit v1.2.3 From 85b02bc0785b5e6326814af7e1b7528ce3a488ea Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Thu, 7 Mar 2024 08:01:12 +0100 Subject: pinctrl: bcm2835: Implement bcm2835_pinconf_get Even the driver already has implemented pin_dbg_show, it could be helpful to implement pin_conf_get for a more generic behavior. Contrary to the BCM2711, the BCM2835 SOC doesn't allow to read the bias config, so the implementation is limited to the basics. Keep ENOTSUPP here, because it's only used internally. Signed-off-by: Stefan Wahren Reviewed-by: Chen-Yu Tsai Message-ID: <20240307070113.4888-2-wahrenst@gmx.net> Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index 1489191a213f..5d2b188a1ef4 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -1003,8 +1003,27 @@ static const struct pinmux_ops bcm2835_pmx_ops = { static int bcm2835_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, unsigned long *config) { - /* No way to read back config in HW */ - return -ENOTSUPP; + enum pin_config_param param = pinconf_to_config_param(*config); + struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, pin); + u32 val; + + /* No way to read back bias config in HW */ + + switch (param) { + case PIN_CONFIG_OUTPUT: + if (fsel != BCM2835_FSEL_GPIO_OUT) + return -EINVAL; + + val = bcm2835_gpio_get_bit(pc, GPLEV0, pin); + *config = pinconf_to_config_packed(param, val); + break; + + default: + return -ENOTSUPP; + } + + return 0; } static void bcm2835_pull_config_set(struct bcm2835_pinctrl *pc, -- cgit v1.2.3 From d54e4cda297241406bed37af3f836d242184ec84 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Thu, 7 Mar 2024 08:01:13 +0100 Subject: pinctrl: bcm2835: Implement bcm2711_pinconf_get The BCM2711 allows to read the bias config. So implement pin_conf_get accordingly. The pull resistor values has been taken from the BCM2711/7211 datasheet. This implementation assumes that BCM7211 behaves the same way. Signed-off-by: Stefan Wahren Reviewed-by: Florian Fainelli Tested-by: Florian Fainelli Message-ID: <20240307070113.4888-3-wahrenst@gmx.net> Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 41 ++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index 5d2b188a1ef4..f5a9372d43bd 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -1098,6 +1098,45 @@ static const struct pinconf_ops bcm2835_pinconf_ops = { .pin_config_set = bcm2835_pinconf_set, }; +static int bcm2711_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, + unsigned long *config) +{ + struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param param = pinconf_to_config_param(*config); + u32 offset, shift, val; + + offset = PUD_2711_REG_OFFSET(pin); + shift = PUD_2711_REG_SHIFT(pin); + val = bcm2835_gpio_rd(pc, GP_GPIO_PUP_PDN_CNTRL_REG0 + (offset * 4)); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + if (((val >> shift) & PUD_2711_MASK) != BCM2711_PULL_NONE) + return -EINVAL; + + break; + + case PIN_CONFIG_BIAS_PULL_UP: + if (((val >> shift) & PUD_2711_MASK) != BCM2711_PULL_UP) + return -EINVAL; + + *config = pinconf_to_config_packed(param, 50000); + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + if (((val >> shift) & PUD_2711_MASK) != BCM2711_PULL_DOWN) + return -EINVAL; + + *config = pinconf_to_config_packed(param, 50000); + break; + + default: + return bcm2835_pinconf_get(pctldev, pin, config); + } + + return 0; +} + static void bcm2711_pull_config_set(struct bcm2835_pinctrl *pc, unsigned int pin, unsigned int arg) { @@ -1165,7 +1204,7 @@ static int bcm2711_pinconf_set(struct pinctrl_dev *pctldev, static const struct pinconf_ops bcm2711_pinconf_ops = { .is_generic = true, - .pin_config_get = bcm2835_pinconf_get, + .pin_config_get = bcm2711_pinconf_get, .pin_config_set = bcm2711_pinconf_set, }; -- cgit v1.2.3 From e5c7b013cbcc7a4d91333811bd8524112f9c22a5 Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Tue, 26 Mar 2024 15:06:29 -0700 Subject: pinctrl: qcom: spmi-gpio: Add PMXR2230 and PM6450 support Add support for qcom,pmxr2230-gpio and qcom,pm6450-gpio. Signed-off-by: Anjelique Melendez Reviewed-by: Konrad Dybcio Message-ID: <20240326220628.2392802-4-quic_amelende@quicinc.com> Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index f4e2c88a7c82..54ffb7e1189a 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -1202,6 +1202,7 @@ static const struct of_device_id pmic_gpio_of_match[] = { { .compatible = "qcom,pm6150-gpio", .data = (void *) 10 }, { .compatible = "qcom,pm6150l-gpio", .data = (void *) 12 }, { .compatible = "qcom,pm6350-gpio", .data = (void *) 9 }, + { .compatible = "qcom,pm6450-gpio", .data = (void *) 9 }, { .compatible = "qcom,pm7250b-gpio", .data = (void *) 12 }, { .compatible = "qcom,pm7325-gpio", .data = (void *) 10 }, { .compatible = "qcom,pm7550ba-gpio", .data = (void *) 8}, @@ -1253,6 +1254,7 @@ static const struct of_device_id pmic_gpio_of_match[] = { { .compatible = "qcom,pmx55-gpio", .data = (void *) 11 }, { .compatible = "qcom,pmx65-gpio", .data = (void *) 16 }, { .compatible = "qcom,pmx75-gpio", .data = (void *) 16 }, + { .compatible = "qcom,pmxr2230-gpio", .data = (void *) 12 }, { }, }; -- cgit v1.2.3 From b5658c7ab942cc9c49a164dd8e027096b3e3c0f4 Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Tue, 26 Mar 2024 15:06:30 -0700 Subject: pinctrl: qcom: spmi-gpio: Add PMIH0108 and PMD8028 support Add support for qcom,pmih0108-gpio and qcom,pmd8028-gpio. Signed-off-by: Anjelique Melendez Reviewed-by: Konrad Dybcio Message-ID: <20240326220628.2392802-5-quic_amelende@quicinc.com> Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index 54ffb7e1189a..4e80c7204e5f 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -1235,10 +1235,12 @@ static const struct of_device_id pmic_gpio_of_match[] = { { .compatible = "qcom,pm8994-gpio", .data = (void *) 22 }, { .compatible = "qcom,pm8998-gpio", .data = (void *) 26 }, { .compatible = "qcom,pma8084-gpio", .data = (void *) 22 }, + { .compatible = "qcom,pmd8028-gpio", .data = (void *) 4 }, { .compatible = "qcom,pmi632-gpio", .data = (void *) 8 }, { .compatible = "qcom,pmi8950-gpio", .data = (void *) 2 }, { .compatible = "qcom,pmi8994-gpio", .data = (void *) 10 }, { .compatible = "qcom,pmi8998-gpio", .data = (void *) 14 }, + { .compatible = "qcom,pmih0108-gpio", .data = (void *) 18 }, { .compatible = "qcom,pmk8350-gpio", .data = (void *) 4 }, { .compatible = "qcom,pmk8550-gpio", .data = (void *) 6 }, { .compatible = "qcom,pmm8155au-gpio", .data = (void *) 10 }, -- cgit v1.2.3 From 85dfe458376c01282261bb3555f623f2afb1b203 Mon Sep 17 00:00:00 2001 From: Thomas Richard Date: Mon, 4 Mar 2024 16:35:45 +0100 Subject: pinctrl: pinctrl-single: move suspend()/resume() callbacks to noirq The goal is to extend the active period of pinctrl. Some devices may need active pinctrl after suspend() and/or before resume(). So move suspend()/resume() to suspend_noirq()/resume_noirq() in order to have active pinctrl until suspend_noirq() (included), and from resume_noirq() (included). The deprecated API has been removed to use the new one (dev_pm_ops struct). No need to check the pointer returned by dev_get_drvdata(), as platform_set_drvdata() is called during the probe. Reviewed-by: Linus Walleij Reviewed-by: Andy Shevchenko Signed-off-by: Thomas Richard Reviewed-by: Tony Lindgren Reviewed-by: Dhruva Gole Message-ID: <20240102-j7200-pcie-s2r-v4-2-6f1f53390c85@bootlin.com> Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 19cc0db771a5..0dd4b0e11adf 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -1625,7 +1625,6 @@ static int pcs_irq_init_chained_handler(struct pcs_device *pcs, return 0; } -#ifdef CONFIG_PM static int pcs_save_context(struct pcs_device *pcs) { int i, mux_bytes; @@ -1690,14 +1689,9 @@ static void pcs_restore_context(struct pcs_device *pcs) } } -static int pinctrl_single_suspend(struct platform_device *pdev, - pm_message_t state) +static int pinctrl_single_suspend_noirq(struct device *dev) { - struct pcs_device *pcs; - - pcs = platform_get_drvdata(pdev); - if (!pcs) - return -EINVAL; + struct pcs_device *pcs = dev_get_drvdata(dev); if (pcs->flags & PCS_CONTEXT_LOSS_OFF) { int ret; @@ -1710,20 +1704,19 @@ static int pinctrl_single_suspend(struct platform_device *pdev, return pinctrl_force_sleep(pcs->pctl); } -static int pinctrl_single_resume(struct platform_device *pdev) +static int pinctrl_single_resume_noirq(struct device *dev) { - struct pcs_device *pcs; - - pcs = platform_get_drvdata(pdev); - if (!pcs) - return -EINVAL; + struct pcs_device *pcs = dev_get_drvdata(dev); if (pcs->flags & PCS_CONTEXT_LOSS_OFF) pcs_restore_context(pcs); return pinctrl_force_default(pcs->pctl); } -#endif + +static DEFINE_NOIRQ_DEV_PM_OPS(pinctrl_single_pm_ops, + pinctrl_single_suspend_noirq, + pinctrl_single_resume_noirq); /** * pcs_quirk_missing_pinctrl_cells - handle legacy binding @@ -1986,11 +1979,8 @@ static struct platform_driver pcs_driver = { .driver = { .name = DRIVER_NAME, .of_match_table = pcs_of_match, + .pm = pm_sleep_ptr(&pinctrl_single_pm_ops), }, -#ifdef CONFIG_PM - .suspend = pinctrl_single_suspend, - .resume = pinctrl_single_resume, -#endif }; module_platform_driver(pcs_driver); -- cgit v1.2.3 From d303735ce5dcd79783e65a3710f7f16d14f8900a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 22 Mar 2024 14:21:43 +0100 Subject: pinctrl: armada-37xx: remove an unused variable This variable has never been used and can be removed to avoid a W=1 warning: drivers/pinctrl/mvebu/pinctrl-armada-37xx.c:837:6: error: variable 'i' set but not used [-Werror,-Wunused-but-set-variable] 837 | int i = 0; Fixes: 87466ccd9401 ("pinctrl: armada-37xx: Add pin controller support for Armada 37xx") Signed-off-by: Arnd Bergmann Reviewed-by: Andrew Lunn Message-ID: <20240322132205.906729-1-arnd@kernel.org> Signed-off-by: Linus Walleij --- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index c34719b7506d..4c4ada06423d 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -834,8 +834,6 @@ static int armada_37xx_gpiochip_register(struct platform_device *pdev, static int armada_37xx_add_function(struct armada_37xx_pmx_func *funcs, int *funcsize, const char *name) { - int i = 0; - if (*funcsize <= 0) return -EOVERFLOW; @@ -847,7 +845,6 @@ static int armada_37xx_add_function(struct armada_37xx_pmx_func *funcs, return -EEXIST; } funcs++; - i++; } /* append new unique function */ -- cgit v1.2.3 From e5e8a58023707472e5dbe9bc7b473a8703b401e0 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 29 Mar 2024 12:55:15 +0200 Subject: pinctrl: aw9523: Destroy mutex on ->remove() If aw9523_hw_init() fails on ->remove() the mutex left alive. Destroy it in that case as well. While at it, remove never true check at the beginning of the function. Signed-off-by: Andy Shevchenko Message-ID: <20240329105634.712457-2-andy.shevchenko@gmail.com> Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-aw9523.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pinctrl-aw9523.c b/drivers/pinctrl/pinctrl-aw9523.c index 4edd371c469f..66629af0b88b 100644 --- a/drivers/pinctrl/pinctrl-aw9523.c +++ b/drivers/pinctrl/pinctrl-aw9523.c @@ -1067,10 +1067,6 @@ err_disable_vregs: static void aw9523_remove(struct i2c_client *client) { struct aw9523 *awi = i2c_get_clientdata(client); - int ret; - - if (!awi) - return; /* * If the chip VIO is connected to a regulator that we can turn @@ -1082,10 +1078,8 @@ static void aw9523_remove(struct i2c_client *client) regulator_disable(awi->vio_vreg); } else { mutex_lock(&awi->i2c_lock); - ret = aw9523_hw_init(awi); + aw9523_hw_init(awi); mutex_unlock(&awi->i2c_lock); - if (ret) - return; } mutex_destroy(&awi->i2c_lock); -- cgit v1.2.3 From f91eafcb18e096108cd19d24ab71a0db5bc12416 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 29 Mar 2024 12:55:16 +0200 Subject: pinctrl: aw9523: Use correct error code for not supported functionality The pin control subsystem internally uses ENOTSUPP for the not supported functionality. The checkpatch is false positive about this error code. Signed-off-by: Andy Shevchenko Message-ID: <20240329105634.712457-3-andy.shevchenko@gmail.com> Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-aw9523.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pinctrl-aw9523.c b/drivers/pinctrl/pinctrl-aw9523.c index 66629af0b88b..65d523697b73 100644 --- a/drivers/pinctrl/pinctrl-aw9523.c +++ b/drivers/pinctrl/pinctrl-aw9523.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -239,7 +240,7 @@ static int aw9523_pcfg_param_to_reg(enum pin_config_param pcp, int pin, u8 *r) reg = AW9523_REG_OUT_STATE(pin); break; default: - return -EOPNOTSUPP; + return -ENOTSUPP; } *r = reg; @@ -290,7 +291,7 @@ static int aw9523_pconf_get(struct pinctrl_dev *pctldev, unsigned int pin, val = FIELD_GET(AW9523_GCR_GPOMD_MASK, val); break; default: - return -EOPNOTSUPP; + return -ENOTSUPP; } if (val < 1) return -EINVAL; @@ -344,7 +345,7 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin, case PIN_CONFIG_DRIVE_OPEN_DRAIN: /* Open-Drain is supported only on port 0 */ if (pin >= AW9523_PINS_PER_PORT) { - rc = -EOPNOTSUPP; + rc = -ENOTSUPP; goto end; } mask = AW9523_GCR_GPOMD_MASK; @@ -361,7 +362,7 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin, val = AW9523_GCR_GPOMD_MASK; break; default: - rc = -EOPNOTSUPP; + rc = -ENOTSUPP; goto end; } -- cgit v1.2.3 From 091655b9285d837db520381924c689bd5dc5d286 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 29 Mar 2024 12:55:17 +0200 Subject: pinctrl: aw9523: Always try both ports in aw9523_gpio_set_multiple() The ports are equivalent from the user's point of view. Don't limit trying them both if writing to one fails. Signed-off-by: Andy Shevchenko Message-ID: <20240329105634.712457-4-andy.shevchenko@gmail.com> Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-aw9523.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pinctrl-aw9523.c b/drivers/pinctrl/pinctrl-aw9523.c index 65d523697b73..d93640a02d1d 100644 --- a/drivers/pinctrl/pinctrl-aw9523.c +++ b/drivers/pinctrl/pinctrl-aw9523.c @@ -653,7 +653,7 @@ static void aw9523_gpio_set_multiple(struct gpio_chip *chip, struct aw9523 *awi = gpiochip_get_data(chip); u8 mask_lo, mask_hi, bits_lo, bits_hi; unsigned int reg; - int ret = 0; + int ret; mask_lo = *mask & U8_MAX; mask_hi = (*mask >> 8) & U8_MAX; @@ -663,10 +663,8 @@ static void aw9523_gpio_set_multiple(struct gpio_chip *chip, bits_hi = (*bits >> 8) & U8_MAX; ret = regmap_write_bits(awi->regmap, reg, mask_hi, bits_hi); - if (ret) { + if (ret) dev_warn(awi->dev, "Cannot write port1 out level\n"); - goto out; - } } if (mask_lo) { reg = AW9523_REG_OUT_STATE(0); @@ -675,7 +673,6 @@ static void aw9523_gpio_set_multiple(struct gpio_chip *chip, if (ret) dev_warn(awi->dev, "Cannot write port0 out level\n"); } -out: mutex_unlock(&awi->i2c_lock); } -- cgit v1.2.3 From 418ee9488ff74ab4ada3a539a2840dda9e56f847 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 29 Mar 2024 12:55:18 +0200 Subject: pinctrl: aw9523: Make use of struct pinfunction and PINCTRL_PINFUNCTION() Since pin control provides a generic data type and a macro for the pin function definition, use them in the driver. Signed-off-by: Andy Shevchenko Message-ID: <20240329105634.712457-5-andy.shevchenko@gmail.com> Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-aw9523.c | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pinctrl-aw9523.c b/drivers/pinctrl/pinctrl-aw9523.c index d93640a02d1d..7db901216a94 100644 --- a/drivers/pinctrl/pinctrl-aw9523.c +++ b/drivers/pinctrl/pinctrl-aw9523.c @@ -66,18 +66,6 @@ struct aw9523_irq { u16 cached_gpio; }; -/* - * struct aw9523_pinmux - Pin mux params - * @name: Name of the mux - * @grps: Groups of the mux - * @num_grps: Number of groups (sizeof array grps) - */ -struct aw9523_pinmux { - const char *name; - const char * const *grps; - const u8 num_grps; -}; - /* * struct aw9523 - Main driver structure * @dev: device handle @@ -158,17 +146,9 @@ static const char * const gpio_pwm_groups[] = { }; /* Warning: Do NOT reorder this array */ -static const struct aw9523_pinmux aw9523_pmx[] = { - { - .name = "pwm", - .grps = gpio_pwm_groups, - .num_grps = ARRAY_SIZE(gpio_pwm_groups), - }, - { - .name = "gpio", - .grps = gpio_pwm_groups, - .num_grps = ARRAY_SIZE(gpio_pwm_groups), - }, +static const struct pinfunction aw9523_pmx[] = { + PINCTRL_PINFUNCTION("pwm", gpio_pwm_groups, ARRAY_SIZE(gpio_pwm_groups)), + PINCTRL_PINFUNCTION("gpio", gpio_pwm_groups, ARRAY_SIZE(gpio_pwm_groups)), }; static int aw9523_pmx_get_funcs_count(struct pinctrl_dev *pctl) @@ -184,10 +164,10 @@ static const char *aw9523_pmx_get_fname(struct pinctrl_dev *pctl, static int aw9523_pmx_get_groups(struct pinctrl_dev *pctl, unsigned int sel, const char * const **groups, - unsigned int * const num_groups) + unsigned int * const ngroups) { - *groups = aw9523_pmx[sel].grps; - *num_groups = aw9523_pmx[sel].num_grps; + *groups = aw9523_pmx[sel].groups; + *ngroups = aw9523_pmx[sel].ngroups; return 0; } -- cgit v1.2.3 From 66413f0468d35adb352c76bc286bf6f6746ba354 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 29 Mar 2024 12:55:19 +0200 Subject: pinctrl: aw9523: Use temporary variable for HW IRQ number There are two different ways on how to get HW IRQ number in some functions. Unify that by using temporary variable and irqd_to_hwirq() call. Signed-off-by: Andy Shevchenko Message-ID: <20240329105634.712457-6-andy.shevchenko@gmail.com> Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-aw9523.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pinctrl-aw9523.c b/drivers/pinctrl/pinctrl-aw9523.c index 7db901216a94..0f3361fa9ed8 100644 --- a/drivers/pinctrl/pinctrl-aw9523.c +++ b/drivers/pinctrl/pinctrl-aw9523.c @@ -428,12 +428,12 @@ static int aw9523_gpio_irq_type(struct irq_data *d, unsigned int type) static void aw9523_irq_mask(struct irq_data *d) { struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d)); - unsigned int n = d->hwirq % AW9523_PINS_PER_PORT; + irq_hw_number_t hwirq = irqd_to_hwirq(d); + unsigned int n = hwirq % AW9523_PINS_PER_PORT; - regmap_update_bits(awi->regmap, - AW9523_REG_INTR_DIS(d->hwirq), + regmap_update_bits(awi->regmap, AW9523_REG_INTR_DIS(hwirq), BIT(n), BIT(n)); - gpiochip_disable_irq(&awi->gpio, irqd_to_hwirq(d)); + gpiochip_disable_irq(&awi->gpio, hwirq); } /* @@ -446,11 +446,11 @@ static void aw9523_irq_mask(struct irq_data *d) static void aw9523_irq_unmask(struct irq_data *d) { struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d)); - unsigned int n = d->hwirq % AW9523_PINS_PER_PORT; + irq_hw_number_t hwirq = irqd_to_hwirq(d); + unsigned int n = hwirq % AW9523_PINS_PER_PORT; - gpiochip_enable_irq(&awi->gpio, irqd_to_hwirq(d)); - regmap_update_bits(awi->regmap, - AW9523_REG_INTR_DIS(d->hwirq), + gpiochip_enable_irq(&awi->gpio, hwirq); + regmap_update_bits(awi->regmap, AW9523_REG_INTR_DIS(hwirq), BIT(n), 0); } -- cgit v1.2.3 From 4210ef801a248223a0ea5f47b5446081b4925e10 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 29 Mar 2024 12:55:20 +0200 Subject: pinctrl: aw9523: Get rid of redundant ' & U8_MAX' pieces When the variable is declared as u8, no need to perform ' & U8_MAX' as it's implied anyway. Signed-off-by: Andy Shevchenko Message-ID: <20240329105634.712457-7-andy.shevchenko@gmail.com> Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-aw9523.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pinctrl-aw9523.c b/drivers/pinctrl/pinctrl-aw9523.c index 0f3361fa9ed8..8c615adb3d57 100644 --- a/drivers/pinctrl/pinctrl-aw9523.c +++ b/drivers/pinctrl/pinctrl-aw9523.c @@ -603,7 +603,7 @@ static int aw9523_gpio_get_multiple(struct gpio_chip *chip, mutex_lock(&awi->i2c_lock); /* Port 0 (gpio 0-7) */ - m = *mask & U8_MAX; + m = *mask; if (m) { ret = _aw9523_gpio_get_multiple(awi, 0, &state, m); if (ret) @@ -612,7 +612,7 @@ static int aw9523_gpio_get_multiple(struct gpio_chip *chip, *bits = state; /* Port 1 (gpio 8-15) */ - m = (*mask >> 8) & U8_MAX; + m = *mask >> 8; if (m) { ret = _aw9523_gpio_get_multiple(awi, AW9523_PINS_PER_PORT, &state, m); @@ -635,20 +635,20 @@ static void aw9523_gpio_set_multiple(struct gpio_chip *chip, unsigned int reg; int ret; - mask_lo = *mask & U8_MAX; - mask_hi = (*mask >> 8) & U8_MAX; + mask_lo = *mask; + mask_hi = *mask >> 8; + bits_lo = *bits; + bits_hi = *bits >> 8; + mutex_lock(&awi->i2c_lock); if (mask_hi) { reg = AW9523_REG_OUT_STATE(AW9523_PINS_PER_PORT); - bits_hi = (*bits >> 8) & U8_MAX; - ret = regmap_write_bits(awi->regmap, reg, mask_hi, bits_hi); if (ret) dev_warn(awi->dev, "Cannot write port1 out level\n"); } if (mask_lo) { reg = AW9523_REG_OUT_STATE(0); - bits_lo = *bits & U8_MAX; ret = regmap_write_bits(awi->regmap, reg, mask_lo, bits_lo); if (ret) dev_warn(awi->dev, "Cannot write port0 out level\n"); -- cgit v1.2.3 From 6bf270863ade776485d1c6bdb8f69d642b0e5f64 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 29 Mar 2024 12:55:21 +0200 Subject: pinctrl: aw9523: Remove unused irqchip field in struct aw9523_irq The irqchip field is allocated, assigned but never used. Remove it. Signed-off-by: Andy Shevchenko Message-ID: <20240329105634.712457-8-andy.shevchenko@gmail.com> Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-aw9523.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pinctrl-aw9523.c b/drivers/pinctrl/pinctrl-aw9523.c index 8c615adb3d57..f084dad5c88f 100644 --- a/drivers/pinctrl/pinctrl-aw9523.c +++ b/drivers/pinctrl/pinctrl-aw9523.c @@ -57,12 +57,10 @@ /* * struct aw9523_irq - Interrupt controller structure * @lock: mutex locking for the irq bus - * @irqchip: structure holding irqchip params * @cached_gpio: stores the previous gpio status for bit comparison */ struct aw9523_irq { struct mutex lock; - struct irq_chip *irqchip; u16 cached_gpio; }; @@ -805,21 +803,15 @@ static int aw9523_init_irq(struct aw9523 *awi, int irq) { struct device *dev = awi->dev; struct gpio_irq_chip *girq; - struct irq_chip *irqchip; int ret; if (!device_property_read_bool(dev, "interrupt-controller")) return 0; - irqchip = devm_kzalloc(dev, sizeof(*irqchip), GFP_KERNEL); - if (!irqchip) - return -ENOMEM; - awi->irq = devm_kzalloc(dev, sizeof(*awi->irq), GFP_KERNEL); if (!awi->irq) return -ENOMEM; - awi->irq->irqchip = irqchip; mutex_init(&awi->irq->lock); ret = devm_request_threaded_irq(dev, irq, NULL, aw9523_irq_thread_func, -- cgit v1.2.3 From c567b00cc3d73f3ce4e92126731545d177262090 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 29 Mar 2024 12:55:22 +0200 Subject: pinctrl: aw9523: Make use of dev_err_probe() Simplify the error handling in probe function by switching from dev_err() to dev_err_probe(). Signed-off-by: Andy Shevchenko Message-ID: <20240329105634.712457-9-andy.shevchenko@gmail.com> Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-aw9523.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pinctrl-aw9523.c b/drivers/pinctrl/pinctrl-aw9523.c index f084dad5c88f..fe398c59c2d1 100644 --- a/drivers/pinctrl/pinctrl-aw9523.c +++ b/drivers/pinctrl/pinctrl-aw9523.c @@ -816,10 +816,8 @@ static int aw9523_init_irq(struct aw9523 *awi, int irq) ret = devm_request_threaded_irq(dev, irq, NULL, aw9523_irq_thread_func, IRQF_ONESHOT, dev_name(dev), awi); - if (ret) { - dev_err(dev, "Failed to request irq %d\n", irq); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to request irq %d\n", irq); girq = &awi->gpio.irq; gpio_irq_chip_set_chip(girq, &aw9523_irq_chip); @@ -1016,8 +1014,7 @@ static int aw9523_probe(struct i2c_client *client) awi->pctl = devm_pinctrl_register(dev, pdesc, awi); if (IS_ERR(awi->pctl)) { - ret = PTR_ERR(awi->pctl); - dev_err(dev, "Cannot register pinctrl: %d", ret); + ret = dev_err_probe(dev, PTR_ERR(awi->pctl), "Cannot register pinctrl"); goto err_disable_vregs; } -- cgit v1.2.3 From 7b8b9b5450b89d01e4b8f120b903cee85b529231 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 29 Mar 2024 12:55:23 +0200 Subject: pinctrl: aw9523: Sort headers and group pinctrl/* One header was misplaced and group pinctrl/* ones to show the relation with the pin control subsystem. Signed-off-by: Andy Shevchenko Message-ID: <20240329105634.712457-10-andy.shevchenko@gmail.com> Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-aw9523.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pinctrl-aw9523.c b/drivers/pinctrl/pinctrl-aw9523.c index fe398c59c2d1..49d503589922 100644 --- a/drivers/pinctrl/pinctrl-aw9523.c +++ b/drivers/pinctrl/pinctrl-aw9523.c @@ -13,17 +13,18 @@ #include #include #include -#include #include -#include -#include -#include -#include +#include #include #include #include #include +#include +#include +#include +#include + #define AW9523_MAX_FUNCS 2 #define AW9523_NUM_PORTS 2 #define AW9523_PINS_PER_PORT 8 -- cgit v1.2.3 From 4aad0ad20f4ea80180a3e58b04b701728541c0f7 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 29 Mar 2024 12:55:24 +0200 Subject: pinctrl: aw9523: Fix indentation in a few places In the comment, function prototype, and array of strings indentation is kinda broken. Reindent that. Signed-off-by: Andy Shevchenko Message-ID: <20240329105634.712457-11-andy.shevchenko@gmail.com> Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-aw9523.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pinctrl-aw9523.c b/drivers/pinctrl/pinctrl-aw9523.c index 49d503589922..b5e1c467625b 100644 --- a/drivers/pinctrl/pinctrl-aw9523.c +++ b/drivers/pinctrl/pinctrl-aw9523.c @@ -1,8 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Awinic AW9523B i2c pin controller driver - * Copyright (c) 2020, AngeloGioacchino Del Regno - * + * Copyright (c) 2020, AngeloGioacchino Del Regno */ #include @@ -139,9 +138,10 @@ static const struct pinctrl_ops aw9523_pinctrl_ops = { }; static const char * const gpio_pwm_groups[] = { - "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", - "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11", - "gpio12", "gpio13", "gpio14", "gpio15" + "gpio0", "gpio1", "gpio2", "gpio3", /* 0-3 */ + "gpio4", "gpio5", "gpio6", "gpio7", /* 4-7 */ + "gpio8", "gpio9", "gpio10", "gpio11", /* 8-11 */ + "gpio12", "gpio13", "gpio14", "gpio15", /* 11-15 */ }; /* Warning: Do NOT reorder this array */ @@ -388,8 +388,8 @@ static int aw9523_get_pin_direction(struct regmap *regmap, u8 pin, u8 n) * * Return: Zero for success or negative number for error */ -static int aw9523_get_port_state(struct regmap *regmap, u8 pin, - u8 regbit, unsigned int *state) +static int aw9523_get_port_state(struct regmap *regmap, u8 pin, u8 regbit, + unsigned int *state) { u8 reg; int dir; @@ -984,8 +984,7 @@ static int aw9523_probe(struct i2c_client *client) } mutex_init(&awi->i2c_lock); - lockdep_set_subclass(&awi->i2c_lock, - i2c_adapter_depth(client->adapter)); + lockdep_set_subclass(&awi->i2c_lock, i2c_adapter_depth(client->adapter)); pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL); if (!pdesc) -- cgit v1.2.3 From e798845d685e0ca652d4fd954a81edd1626f235d Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 30 Mar 2024 22:09:54 +0100 Subject: pinctrl: sunxi: sun9i-a80-r: drop driver owner assignment Core in platform_driver_register() already sets the .owner, so driver does not need to. Signed-off-by: Krzysztof Kozlowski Acked-by: Chen-Yu Tsai Message-ID: <20240330210954.100842-1-krzysztof.kozlowski@linaro.org> Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sun9i-a80-r.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/sunxi/pinctrl-sun9i-a80-r.c b/drivers/pinctrl/sunxi/pinctrl-sun9i-a80-r.c index 919b6a20af83..5b4822f77d2a 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun9i-a80-r.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun9i-a80-r.c @@ -169,7 +169,6 @@ static struct platform_driver sun9i_a80_r_pinctrl_driver = { .probe = sun9i_a80_r_pinctrl_probe, .driver = { .name = "sun9i-a80-r-pinctrl", - .owner = THIS_MODULE, .of_match_table = sun9i_a80_r_pinctrl_match, }, }; -- cgit v1.2.3 From 922c86f8d3ad6c85142be3b8317f0e28a794116c Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Mon, 1 Apr 2024 19:30:05 +0200 Subject: pinctrl: max77620: Remove an unused fields in struct max77620_pin_info and max77620_pctrl_info In "struct max77620_pin_info", the 'pull_config' field is unused. In "struct max77620_pctrl_info", the 'pins_current_opt' field is unused. Remove them. On my x86_64 config, with allmodconfig, this shrinks the struct max77620_pctrl_info from 360 bytes to 296. Found with cppcheck, unusedStructMember. Signed-off-by: Christophe JAILLET Message-ID: <60af8968864ae4a83a76e589b39a2b1e1f65c9db.1711992588.git.christophe.jaillet@wanadoo.fr> Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-max77620.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pinctrl-max77620.c b/drivers/pinctrl/pinctrl-max77620.c index ab723ab4ec1d..d236daa7c13e 100644 --- a/drivers/pinctrl/pinctrl-max77620.c +++ b/drivers/pinctrl/pinctrl-max77620.c @@ -88,7 +88,6 @@ struct max77620_pingroup { struct max77620_pin_info { enum max77620_pin_ppdrv drv_type; - int pull_config; }; struct max77620_fps_config { @@ -104,7 +103,6 @@ struct max77620_pctrl_info { struct device *dev; struct pinctrl_dev *pctl; struct regmap *rmap; - int pins_current_opt[MAX77620_GPIO_NR]; const struct max77620_pin_function *functions; unsigned int num_functions; const struct max77620_pingroup *pin_groups; -- cgit v1.2.3 From a95e2bc817feac96f229910c6822c682da887fa1 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Mon, 1 Apr 2024 22:48:55 +0200 Subject: pinctrl: pinctrl-single: Remove some unused fields in struct pcs_function In "struct pcs_function", the 'pgnames' and 'npgnames' fields are unused. This is a left-over from commit 571aec4df5b7 ("pinctrl: single: Use generic pinmux helpers for managing functions"); Remove them. Found with cppcheck, unusedStructMember. Signed-off-by: Christophe JAILLET Message-ID: Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 0dd4b0e11adf..b4f8aa609b97 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -81,8 +81,6 @@ struct pcs_conf_type { * @name: pinctrl function name * @vals: register and vals array * @nvals: number of entries in vals array - * @pgnames: array of pingroup names the function uses - * @npgnames: number of pingroup names the function uses * @conf: array of pin configurations * @nconfs: number of pin configurations available * @node: list node @@ -91,8 +89,6 @@ struct pcs_function { const char *name; struct pcs_func_vals *vals; unsigned nvals; - const char **pgnames; - int npgnames; struct pcs_conf_vals *conf; int nconfs; struct list_head node; -- cgit v1.2.3 From b5fe46efc147516a908d2d31bf40eb858ab76d51 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Tue, 19 Mar 2024 12:06:34 +0100 Subject: pinctrl: single: Fix PIN_CONFIG_BIAS_DISABLE handling The pinctrl-single driver handles pin_config_set by looking up the requested setting in a DT-defined lookup table, which defines what bits correspond to each setting. There is no way to add PIN_CONFIG_BIAS_DISABLE entries to the table, since there is instead code to disable the bias by applying the disable values of both the pullup and pulldown entries in the table. However, this code is inside the table-lookup loop, so it would only execute if there is an entry for PIN_CONFIG_BIAS_DISABLE in the table, which can never exist, so this code never runs. This commit lifts the offending code out of the loop, so it just executes directly whenever PIN_CONFIG_BIAS_DISABLE is requested, skippipng the table lookup loop. This also introduces a new `param` variable to make the code slightly more readable. This bug seems to have existed when this code was first merged in commit 9dddb4df90d13 ("pinctrl: single: support generic pinconf"). Earlier versions of this patch did have an entry for PIN_CONFIG_BIAS_DISABLE in the lookup table, but that was removed, which is probably how this bug was introduced. Signed-off-by: Matthijs Kooijman Reviewed-by: Haojian Zhuang Reviewed-by: Tony Lindgren Message-ID: <20240319110633.230329-1-matthijs@stdin.nl> Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index b4f8aa609b97..a798f31d6954 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -550,21 +550,30 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, unsigned offset = 0, shift = 0, i, data, ret; u32 arg; int j; + enum pin_config_param param; ret = pcs_get_function(pctldev, pin, &func); if (ret) return ret; for (j = 0; j < num_configs; j++) { + param = pinconf_to_config_param(configs[j]); + + /* BIAS_DISABLE has no entry in the func->conf table */ + if (param == PIN_CONFIG_BIAS_DISABLE) { + /* This just disables all bias entries */ + pcs_pinconf_clear_bias(pctldev, pin); + continue; + } + for (i = 0; i < func->nconfs; i++) { - if (pinconf_to_config_param(configs[j]) - != func->conf[i].param) + if (param != func->conf[i].param) continue; offset = pin * (pcs->width / BITS_PER_BYTE); data = pcs->read(pcs->base + offset); arg = pinconf_to_config_argument(configs[j]); - switch (func->conf[i].param) { + switch (param) { /* 2 parameters */ case PIN_CONFIG_INPUT_SCHMITT: case PIN_CONFIG_DRIVE_STRENGTH: @@ -576,9 +585,6 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, data |= (arg << shift) & func->conf[i].mask; break; /* 4 parameters */ - case PIN_CONFIG_BIAS_DISABLE: - pcs_pinconf_clear_bias(pctldev, pin); - break; case PIN_CONFIG_BIAS_PULL_DOWN: case PIN_CONFIG_BIAS_PULL_UP: if (arg) -- cgit v1.2.3 From 932640c0f78947c59a6e9c743a17a355165d69d5 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 4 Apr 2024 22:35:21 +0300 Subject: pinctrl: Use DEFINE_SHOW_STORE_ATTRIBUTE() helper for debugfs Use DEFINE_SHOW_STORE_ATTRIBUTE() helper for read-write file to reduce some duplicated code. Signed-off-by: Andy Shevchenko Message-ID: <20240404193521.3581399-1-andriy.shevchenko@linux.intel.com> Signed-off-by: Linus Walleij --- drivers/pinctrl/pinmux.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index d924207d629b..addba55334d9 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -578,6 +578,7 @@ static int pinmux_functions_show(struct seq_file *s, void *what) return 0; } +DEFINE_SHOW_ATTRIBUTE(pinmux_functions); static int pinmux_pins_show(struct seq_file *s, void *what) { @@ -650,6 +651,7 @@ static int pinmux_pins_show(struct seq_file *s, void *what) return 0; } +DEFINE_SHOW_ATTRIBUTE(pinmux_pins); void pinmux_show_map(struct seq_file *s, const struct pinctrl_map *map) { @@ -672,10 +674,12 @@ void pinmux_show_setting(struct seq_file *s, setting->data.mux.func); } -DEFINE_SHOW_ATTRIBUTE(pinmux_functions); -DEFINE_SHOW_ATTRIBUTE(pinmux_pins); +static int pinmux_select_show(struct seq_file *s, void *unused) +{ + return -EPERM; +} -static ssize_t pinmux_select(struct file *file, const char __user *user_buf, +static ssize_t pinmux_select_write(struct file *file, const char __user *user_buf, size_t len, loff_t *ppos) { struct seq_file *sfile = file->private_data; @@ -749,19 +753,7 @@ exit_free_buf: return ret; } - -static int pinmux_select_open(struct inode *inode, struct file *file) -{ - return single_open(file, NULL, inode->i_private); -} - -static const struct file_operations pinmux_select_ops = { - .owner = THIS_MODULE, - .open = pinmux_select_open, - .write = pinmux_select, - .llseek = no_llseek, - .release = single_release, -}; +DEFINE_SHOW_STORE_ATTRIBUTE(pinmux_select); void pinmux_init_device_debugfs(struct dentry *devroot, struct pinctrl_dev *pctldev) @@ -771,7 +763,7 @@ void pinmux_init_device_debugfs(struct dentry *devroot, debugfs_create_file("pinmux-pins", 0444, devroot, pctldev, &pinmux_pins_fops); debugfs_create_file("pinmux-select", 0200, - devroot, pctldev, &pinmux_select_ops); + devroot, pctldev, &pinmux_select_fops); } #endif /* CONFIG_DEBUG_FS */ -- cgit v1.2.3 From a310822fe731ba22928c40bdd3b4da69483b0b81 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 11 Apr 2024 08:46:10 +0200 Subject: pinctrl: freescale: imx8ulp: fix module autoloading Add MODULE_DEVICE_TABLE(), so the module could be properly autoloaded based on the alias from of_device_id table. Pin controllers are considered core components, so usually they are built-in, however these can be built and used as modules on some generic kernel. Signed-off-by: Krzysztof Kozlowski Message-ID: <20240411064614.7409-1-krzk@kernel.org> Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/pinctrl-imx8ulp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/freescale/pinctrl-imx8ulp.c b/drivers/pinctrl/freescale/pinctrl-imx8ulp.c index 2e86ca9fc7ac..5632c7285147 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8ulp.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8ulp.c @@ -252,6 +252,7 @@ static const struct of_device_id imx8ulp_pinctrl_of_match[] = { { .compatible = "fsl,imx8ulp-iomuxc1", }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx8ulp_pinctrl_of_match); static int imx8ulp_pinctrl_probe(struct platform_device *pdev) { -- cgit v1.2.3 From d42005c03a48fbb49d7a5c808992618f398963ca Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 11 Apr 2024 08:46:11 +0200 Subject: pinctrl: mediatek: fix module autoloading Add MODULE_DEVICE_TABLE(), so the module could be properly autoloaded based on the alias from of_device_id table. Pin controllers are considered core components, so usually they are built-in, however these can be built and used as modules on some generic kernel. Signed-off-by: Krzysztof Kozlowski Reviewed-by: AngeloGioacchino Del Regno Message-ID: <20240411064614.7409-2-krzk@kernel.org> Signed-off-by: Linus Walleij --- drivers/pinctrl/mediatek/pinctrl-mt6765.c | 1 + drivers/pinctrl/mediatek/pinctrl-mt6779.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c index f6ec41eb6e0c..72609cf74760 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c @@ -1086,6 +1086,7 @@ static const struct of_device_id mt6765_pinctrl_of_match[] = { { .compatible = "mediatek,mt6765-pinctrl", .data = &mt6765_data }, { } }; +MODULE_DEVICE_TABLE(of, mt6765_pinctrl_of_match); static struct platform_driver mt6765_pinctrl_driver = { .driver = { diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6779.c b/drivers/pinctrl/mediatek/pinctrl-mt6779.c index 62d4f5ad6737..591905e4132a 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt6779.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt6779.c @@ -762,6 +762,7 @@ static const struct of_device_id mt6779_pinctrl_of_match[] = { { .compatible = "mediatek,mt6779-pinctrl", .data = &mt6779_data }, { } }; +MODULE_DEVICE_TABLE(of, mt6779_pinctrl_of_match); static struct platform_driver mt6779_pinctrl_driver = { .driver = { -- cgit v1.2.3 From 75589d6b11000605cebcbafd92e620dafc44694f Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 11 Apr 2024 08:46:12 +0200 Subject: pinctrl: loongson2: fix module autoloading Add MODULE_DEVICE_TABLE(), so the module could be properly autoloaded based on the alias from of_device_id table. Pin controllers are considered core components, so usually they are built-in, however these can be built and used as modules on some generic kernel. Signed-off-by: Krzysztof Kozlowski Message-ID: <20240411064614.7409-3-krzk@kernel.org> Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-loongson2.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pinctrl-loongson2.c b/drivers/pinctrl/pinctrl-loongson2.c index a72ffeca26fb..4d4fbeadafb7 100644 --- a/drivers/pinctrl/pinctrl-loongson2.c +++ b/drivers/pinctrl/pinctrl-loongson2.c @@ -286,6 +286,7 @@ static const struct of_device_id loongson2_pinctrl_dt_match[] = { }, { } }; +MODULE_DEVICE_TABLE(of, loongson2_pinctrl_dt_match); static struct platform_driver loongson2_pinctrl_driver = { .probe = loongson2_pinctrl_probe, -- cgit v1.2.3 From abda4619f41cd52a90b068ce728027c529d7b759 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 11 Apr 2024 08:46:13 +0200 Subject: pinctrl: qcom: sm7150: fix module autoloading Add MODULE_DEVICE_TABLE(), so the module could be properly autoloaded based on the alias from of_device_id table. Pin controllers are considered core components, so usually they are built-in, however these can be built and used as modules on some generic kernel. Reviewed-by: Konrad Dybcio Signed-off-by: Krzysztof Kozlowski Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Bjorn Andersson Message-ID: <20240411064614.7409-4-krzk@kernel.org> Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-sm7150.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/qcom/pinctrl-sm7150.c b/drivers/pinctrl/qcom/pinctrl-sm7150.c index c25357ca1963..c542f9bc6bcd 100644 --- a/drivers/pinctrl/qcom/pinctrl-sm7150.c +++ b/drivers/pinctrl/qcom/pinctrl-sm7150.c @@ -1246,6 +1246,7 @@ static const struct of_device_id sm7150_tlmm_of_match[] = { { .compatible = "qcom,sm7150-tlmm", }, { }, }; +MODULE_DEVICE_TABLE(of, sm7150_tlmm_of_match); static struct platform_driver sm7150_tlmm_driver = { .driver = { -- cgit v1.2.3 From 9d2df36538d5ad7338007dc5726dabca4aa16813 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 11 Apr 2024 08:46:14 +0200 Subject: pinctrl: realtek: fix module autoloading Add MODULE_DEVICE_TABLE(), so the module could be properly autoloaded based on the alias from of_device_id table. Pin controllers are considered core components, so usually they are built-in, however these can be built and used as modules on some generic kernel. Signed-off-by: Krzysztof Kozlowski Message-ID: <20240411064614.7409-5-krzk@kernel.org> Signed-off-by: Linus Walleij --- drivers/pinctrl/realtek/pinctrl-rtd1315e.c | 1 + drivers/pinctrl/realtek/pinctrl-rtd1319d.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/realtek/pinctrl-rtd1315e.c b/drivers/pinctrl/realtek/pinctrl-rtd1315e.c index 10afc736a52b..86f919122bed 100644 --- a/drivers/pinctrl/realtek/pinctrl-rtd1315e.c +++ b/drivers/pinctrl/realtek/pinctrl-rtd1315e.c @@ -1414,6 +1414,7 @@ static const struct of_device_id rtd1315e_pinctrl_of_match[] = { { .compatible = "realtek,rtd1315e-pinctrl", }, {}, }; +MODULE_DEVICE_TABLE(of, rtd1315e_pinctrl_of_match); static struct platform_driver rtd1315e_pinctrl_driver = { .driver = { diff --git a/drivers/pinctrl/realtek/pinctrl-rtd1319d.c b/drivers/pinctrl/realtek/pinctrl-rtd1319d.c index b1a654ac30dc..474c337d2d05 100644 --- a/drivers/pinctrl/realtek/pinctrl-rtd1319d.c +++ b/drivers/pinctrl/realtek/pinctrl-rtd1319d.c @@ -1584,6 +1584,7 @@ static const struct of_device_id rtd1319d_pinctrl_of_match[] = { { .compatible = "realtek,rtd1319d-pinctrl", }, {}, }; +MODULE_DEVICE_TABLE(of, rtd1319d_pinctrl_of_match); static struct platform_driver rtd1319d_pinctrl_driver = { .driver = { -- cgit v1.2.3 From 3ba11e684d163f4ab17719a8bbe1382276312e27 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 12 Apr 2024 08:51:28 +0800 Subject: pinctrl: pinconf-generic: print hex value Hex value will be easier to match hardware register bits layout, so same as pinconf_generic_dump_config, print hex value. Signed-off-by: Peng Fan Message-ID: <20240412005128.2937486-1-peng.fan@oss.nxp.com> Signed-off-by: Linus Walleij --- drivers/pinctrl/pinconf-generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c index cada5d18ffae..80de389199bd 100644 --- a/drivers/pinctrl/pinconf-generic.c +++ b/drivers/pinctrl/pinconf-generic.c @@ -88,7 +88,7 @@ static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev, seq_puts(s, items[i].display); /* Print unit if available */ if (items[i].has_arg) { - seq_printf(s, " (%u", + seq_printf(s, " (0x%x", pinconf_to_config_argument(config)); if (items[i].format) seq_printf(s, " %s)", items[i].format); -- cgit v1.2.3 From 2487dc87aeeb58a07406f1da0ee36e069c3f42e3 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Mon, 26 Feb 2024 19:25:30 +0000 Subject: pinctrl: renesas: rzg2l: Remove extra space in function parameter Remove unnecessary space in rzg2l_pinctrl_pm_setup_pfc() function parameter. Signed-off-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20240226192530.141945-1-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/pinctrl/renesas/pinctrl-rzg2l.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c index 20425afc6b33..dbcf009837ef 100644 --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c @@ -2514,7 +2514,7 @@ static void rzg2l_pinctrl_pm_setup_dedicated_regs(struct rzg2l_pinctrl *pctrl, b } } -static void rzg2l_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl) +static void rzg2l_pinctrl_pm_setup_pfc(struct rzg2l_pinctrl *pctrl) { u32 nports = pctrl->data->n_port_pins / RZG2L_PINS_PER_PORT; const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg; -- cgit v1.2.3 From c3bec9547c1be0cce3060368dd92abf610c65f24 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 16 Apr 2024 17:47:22 +0200 Subject: pinctrl: renesas: r8a779h0: Fix IRQ suffixes The suffixes of the IRQ identifiers, as used for pins related to the Interrupt Controller for External Devices (INTC-EX), are inconsistent. Correct them to match the Pin Multiplex attachment in Rev.0.51 of the R-Car V4M Series Hardware User's Manual. Fixes: 291f7856fc451cbe ("pinctrl: renesas: Initial R8A779H0 (R-Car V4M) PFC support") Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/7d3c7498d9e8eda5583b15f9163eb25bb797ed24.1713282028.git.geert+renesas@glider.be --- drivers/pinctrl/renesas/pfc-r8a779h0.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/renesas/pfc-r8a779h0.c b/drivers/pinctrl/renesas/pfc-r8a779h0.c index afa8f06c85cf..0cbfe7637fc9 100644 --- a/drivers/pinctrl/renesas/pfc-r8a779h0.c +++ b/drivers/pinctrl/renesas/pfc-r8a779h0.c @@ -75,10 +75,10 @@ #define GPSR0_9 F_(MSIOF5_SYNC, IP1SR0_7_4) #define GPSR0_8 F_(MSIOF5_SS1, IP1SR0_3_0) #define GPSR0_7 F_(MSIOF5_SS2, IP0SR0_31_28) -#define GPSR0_6 F_(IRQ0, IP0SR0_27_24) -#define GPSR0_5 F_(IRQ1, IP0SR0_23_20) -#define GPSR0_4 F_(IRQ2, IP0SR0_19_16) -#define GPSR0_3 F_(IRQ3, IP0SR0_15_12) +#define GPSR0_6 F_(IRQ0_A, IP0SR0_27_24) +#define GPSR0_5 F_(IRQ1_A, IP0SR0_23_20) +#define GPSR0_4 F_(IRQ2_A, IP0SR0_19_16) +#define GPSR0_3 F_(IRQ3_A, IP0SR0_15_12) #define GPSR0_2 F_(GP0_02, IP0SR0_11_8) #define GPSR0_1 F_(GP0_01, IP0SR0_7_4) #define GPSR0_0 F_(GP0_00, IP0SR0_3_0) @@ -265,10 +265,10 @@ #define IP0SR0_3_0 F_(0, 0) FM(ERROROUTC_N_B) FM(TCLK2_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP0SR0_7_4 F_(0, 0) FM(MSIOF3_SS1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP0SR0_11_8 F_(0, 0) FM(MSIOF3_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP0SR0_15_12 FM(IRQ3) FM(MSIOF3_SCK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP0SR0_19_16 FM(IRQ2) FM(MSIOF3_TXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP0SR0_23_20 FM(IRQ1) FM(MSIOF3_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) -#define IP0SR0_27_24 FM(IRQ0) FM(MSIOF3_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR0_15_12 FM(IRQ3_A) FM(MSIOF3_SCK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR0_19_16 FM(IRQ2_A) FM(MSIOF3_TXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR0_23_20 FM(IRQ1_A) FM(MSIOF3_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) +#define IP0SR0_27_24 FM(IRQ0_A) FM(MSIOF3_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) #define IP0SR0_31_28 FM(MSIOF5_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) /* IP1SR0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 4 5 6 7 8 9 A B C D E F */ @@ -672,16 +672,16 @@ static const u16 pinmux_data[] = { PINMUX_IPSR_GPSR(IP0SR0_11_8, MSIOF3_SS2), - PINMUX_IPSR_GPSR(IP0SR0_15_12, IRQ3), + PINMUX_IPSR_GPSR(IP0SR0_15_12, IRQ3_A), PINMUX_IPSR_GPSR(IP0SR0_15_12, MSIOF3_SCK), - PINMUX_IPSR_GPSR(IP0SR0_19_16, IRQ2), + PINMUX_IPSR_GPSR(IP0SR0_19_16, IRQ2_A), PINMUX_IPSR_GPSR(IP0SR0_19_16, MSIOF3_TXD), - PINMUX_IPSR_GPSR(IP0SR0_23_20, IRQ1), + PINMUX_IPSR_GPSR(IP0SR0_23_20, IRQ1_A), PINMUX_IPSR_GPSR(IP0SR0_23_20, MSIOF3_RXD), - PINMUX_IPSR_GPSR(IP0SR0_27_24, IRQ0), + PINMUX_IPSR_GPSR(IP0SR0_27_24, IRQ0_A), PINMUX_IPSR_GPSR(IP0SR0_27_24, MSIOF3_SYNC), PINMUX_IPSR_GPSR(IP0SR0_31_28, MSIOF5_SS2), -- cgit v1.2.3 From 21fc4d195922f6b29233d2d22e9631cada7db259 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 16 Apr 2024 17:47:23 +0200 Subject: pinctrl: renesas: r8a779h0: Add INTC-EX pins, groups, and function Add pins, groups, and function for the Interrupt Controller for External Devices (INTC-EX) on the Renesas R-Car V4M (R8A779H0) SoC. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/258d03b27b77f60cc03fc3257bb4c6715b612a61.1713282028.git.geert+renesas@glider.be --- drivers/pinctrl/renesas/pfc-r8a779h0.c | 112 +++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/renesas/pfc-r8a779h0.c b/drivers/pinctrl/renesas/pfc-r8a779h0.c index 0cbfe7637fc9..438d1f2739dd 100644 --- a/drivers/pinctrl/renesas/pfc-r8a779h0.c +++ b/drivers/pinctrl/renesas/pfc-r8a779h0.c @@ -1660,6 +1660,90 @@ static const unsigned int i2c3_mux[] = { SDA3_MARK, SCL3_MARK, }; +/* - INTC-EX ---------------------------------------------------------------- */ +static const unsigned int intc_ex_irq0_a_pins[] = { + /* IRQ0_A */ + RCAR_GP_PIN(0, 6), +}; +static const unsigned int intc_ex_irq0_a_mux[] = { + IRQ0_A_MARK, +}; +static const unsigned int intc_ex_irq0_b_pins[] = { + /* IRQ0_B */ + RCAR_GP_PIN(1, 20), +}; +static const unsigned int intc_ex_irq0_b_mux[] = { + IRQ0_B_MARK, +}; + +static const unsigned int intc_ex_irq1_a_pins[] = { + /* IRQ1_A */ + RCAR_GP_PIN(0, 5), +}; +static const unsigned int intc_ex_irq1_a_mux[] = { + IRQ1_A_MARK, +}; +static const unsigned int intc_ex_irq1_b_pins[] = { + /* IRQ1_B */ + RCAR_GP_PIN(1, 21), +}; +static const unsigned int intc_ex_irq1_b_mux[] = { + IRQ1_B_MARK, +}; + +static const unsigned int intc_ex_irq2_a_pins[] = { + /* IRQ2_A */ + RCAR_GP_PIN(0, 4), +}; +static const unsigned int intc_ex_irq2_a_mux[] = { + IRQ2_A_MARK, +}; +static const unsigned int intc_ex_irq2_b_pins[] = { + /* IRQ2_B */ + RCAR_GP_PIN(0, 13), +}; +static const unsigned int intc_ex_irq2_b_mux[] = { + IRQ2_B_MARK, +}; + +static const unsigned int intc_ex_irq3_a_pins[] = { + /* IRQ3_A */ + RCAR_GP_PIN(0, 3), +}; +static const unsigned int intc_ex_irq3_a_mux[] = { + IRQ3_A_MARK, +}; +static const unsigned int intc_ex_irq3_b_pins[] = { + /* IRQ3_B */ + RCAR_GP_PIN(1, 23), +}; +static const unsigned int intc_ex_irq3_b_mux[] = { + IRQ3_B_MARK, +}; + +static const unsigned int intc_ex_irq4_a_pins[] = { + /* IRQ4_A */ + RCAR_GP_PIN(1, 17), +}; +static const unsigned int intc_ex_irq4_a_mux[] = { + IRQ4_A_MARK, +}; +static const unsigned int intc_ex_irq4_b_pins[] = { + /* IRQ4_B */ + RCAR_GP_PIN(2, 3), +}; +static const unsigned int intc_ex_irq4_b_mux[] = { + IRQ4_B_MARK, +}; + +static const unsigned int intc_ex_irq5_pins[] = { + /* IRQ5 */ + RCAR_GP_PIN(2, 2), +}; +static const unsigned int intc_ex_irq5_mux[] = { + IRQ5_MARK, +}; + /* - MMC -------------------------------------------------------------------- */ static const unsigned int mmc_data_pins[] = { /* MMC_SD_D[0:3], MMC_D[4:7] */ @@ -2416,6 +2500,18 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(i2c2), SH_PFC_PIN_GROUP(i2c3), + SH_PFC_PIN_GROUP(intc_ex_irq0_a), + SH_PFC_PIN_GROUP(intc_ex_irq0_b), + SH_PFC_PIN_GROUP(intc_ex_irq1_a), + SH_PFC_PIN_GROUP(intc_ex_irq1_b), + SH_PFC_PIN_GROUP(intc_ex_irq2_a), + SH_PFC_PIN_GROUP(intc_ex_irq2_b), + SH_PFC_PIN_GROUP(intc_ex_irq3_a), + SH_PFC_PIN_GROUP(intc_ex_irq3_b), + SH_PFC_PIN_GROUP(intc_ex_irq4_a), + SH_PFC_PIN_GROUP(intc_ex_irq4_b), + SH_PFC_PIN_GROUP(intc_ex_irq5), + BUS_DATA_PIN_GROUP(mmc_data, 1), BUS_DATA_PIN_GROUP(mmc_data, 4), BUS_DATA_PIN_GROUP(mmc_data, 8), @@ -2629,6 +2725,20 @@ static const char * const i2c3_groups[] = { "i2c3", }; +static const char * const intc_ex_groups[] = { + "intc_ex_irq0_a", + "intc_ex_irq0_b", + "intc_ex_irq1_a", + "intc_ex_irq1_b", + "intc_ex_irq2_a", + "intc_ex_irq2_b", + "intc_ex_irq3_a", + "intc_ex_irq3_b", + "intc_ex_irq4_a", + "intc_ex_irq4_b", + "intc_ex_irq5", +}; + static const char * const mmc_groups[] = { "mmc_data1", "mmc_data4", @@ -2813,6 +2923,8 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(i2c2), SH_PFC_FUNCTION(i2c3), + SH_PFC_FUNCTION(intc_ex), + SH_PFC_FUNCTION(mmc), SH_PFC_FUNCTION(msiof0), -- cgit v1.2.3 From cd27553b0dee6fdc4a2535ab9fc3c8fbdd811d13 Mon Sep 17 00:00:00 2001 From: Paul Barker Date: Wed, 17 Apr 2024 12:41:31 +0100 Subject: pinctrl: renesas: rzg2l: Limit 2.5V power supply to Ethernet interfaces The RZ/G3S SoC supports configurable supply voltages for several of its I/O interfaces. All of these interfaces support both 1.8V and 3.3V supplies, but only the Ethernet and XSPI interfaces support a 2.5V supply. Voltage selection for the XSPI interface is not yet supported, so this leaves only the Ethernet interfaces currently supporting selection of a 2.5V supply. So we need to return an error if there is an attempt to select a 2.5V supply for any non-Ethernet interface. Fixes: 51996952b8b5 ("pinctrl: renesas: rzg2l: Add support to select power source for Ethernet pins") Signed-off-by: Paul Barker Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20240417114132.6605-1-paul.barker.ct@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/pinctrl/renesas/pinctrl-rzg2l.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c index dbcf009837ef..c3256bfde502 100644 --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c @@ -892,6 +892,8 @@ static int rzg2l_set_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps val = PVDD_1800; break; case 2500: + if (!(caps & (PIN_CFG_IO_VMC_ETH0 | PIN_CFG_IO_VMC_ETH1))) + return -EINVAL; val = PVDD_2500; break; case 3300: -- cgit v1.2.3 From f9c74474797351c60e009ebc59a798fcfd93ee57 Mon Sep 17 00:00:00 2001 From: André Draszik Date: Fri, 26 Apr 2024 14:25:15 +0100 Subject: pinctrl: samsung: support a bus clock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On some Samsung-based SoCs there are separate bus clocks / gates each for each pinctrl instance. To be able to access each pinctrl instance's registers, this bus clock needs to be running, otherwise register access will hang. Google Tensor gs101 is one example for such an implementation. Update the driver to handle this optional bus clock: * handle an optional bus clock from DT * prepare it during driver probe * enclose all relevant register accesses with a clock enable & disable Signed-off-by: André Draszik Link: https://lore.kernel.org/r/20240426-samsung-pinctrl-busclock-v3-2-adb8664b8a7e@linaro.org Signed-off-by: Krzysztof Kozlowski --- drivers/pinctrl/samsung/pinctrl-exynos.c | 112 ++++++++++++++++++++++++++++++ drivers/pinctrl/samsung/pinctrl-samsung.c | 97 ++++++++++++++++++++++++-- drivers/pinctrl/samsung/pinctrl-samsung.h | 2 + 3 files changed, 207 insertions(+), 4 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 871c1eb46ddf..ce5e6783b5b9 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -13,6 +13,7 @@ // the Samsung pinctrl/gpiolib driver. It also includes the implementation of // external gpio and wakeup interrupt support. +#include #include #include #include @@ -61,6 +62,12 @@ static void exynos_irq_mask(struct irq_data *irqd) else reg_mask = our_chip->eint_mask + bank->eint_offset; + if (clk_enable(bank->drvdata->pclk)) { + dev_err(bank->gpio_chip.parent, + "unable to enable clock for masking IRQ\n"); + return; + } + raw_spin_lock_irqsave(&bank->slock, flags); mask = readl(bank->eint_base + reg_mask); @@ -68,6 +75,8 @@ static void exynos_irq_mask(struct irq_data *irqd) writel(mask, bank->eint_base + reg_mask); raw_spin_unlock_irqrestore(&bank->slock, flags); + + clk_disable(bank->drvdata->pclk); } static void exynos_irq_ack(struct irq_data *irqd) @@ -82,7 +91,15 @@ static void exynos_irq_ack(struct irq_data *irqd) else reg_pend = our_chip->eint_pend + bank->eint_offset; + if (clk_enable(bank->drvdata->pclk)) { + dev_err(bank->gpio_chip.parent, + "unable to enable clock to ack IRQ\n"); + return; + } + writel(1 << irqd->hwirq, bank->eint_base + reg_pend); + + clk_disable(bank->drvdata->pclk); } static void exynos_irq_unmask(struct irq_data *irqd) @@ -110,6 +127,12 @@ static void exynos_irq_unmask(struct irq_data *irqd) else reg_mask = our_chip->eint_mask + bank->eint_offset; + if (clk_enable(bank->drvdata->pclk)) { + dev_err(bank->gpio_chip.parent, + "unable to enable clock for unmasking IRQ\n"); + return; + } + raw_spin_lock_irqsave(&bank->slock, flags); mask = readl(bank->eint_base + reg_mask); @@ -117,6 +140,8 @@ static void exynos_irq_unmask(struct irq_data *irqd) writel(mask, bank->eint_base + reg_mask); raw_spin_unlock_irqrestore(&bank->slock, flags); + + clk_disable(bank->drvdata->pclk); } static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type) @@ -127,6 +152,7 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type) unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; unsigned int con, trig_type; unsigned long reg_con; + int ret; switch (type) { case IRQ_TYPE_EDGE_RISING: @@ -159,11 +185,20 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type) else reg_con = our_chip->eint_con + bank->eint_offset; + ret = clk_enable(bank->drvdata->pclk); + if (ret) { + dev_err(bank->gpio_chip.parent, + "unable to enable clock for configuring IRQ type\n"); + return ret; + } + con = readl(bank->eint_base + reg_con); con &= ~(EXYNOS_EINT_CON_MASK << shift); con |= trig_type << shift; writel(con, bank->eint_base + reg_con); + clk_disable(bank->drvdata->pclk); + return 0; } @@ -200,6 +235,14 @@ static int exynos_irq_request_resources(struct irq_data *irqd) shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC]; mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; + ret = clk_enable(bank->drvdata->pclk); + if (ret) { + dev_err(bank->gpio_chip.parent, + "unable to enable clock for configuring pin %s-%lu\n", + bank->name, irqd->hwirq); + return ret; + } + raw_spin_lock_irqsave(&bank->slock, flags); con = readl(bank->pctl_base + reg_con); @@ -209,6 +252,8 @@ static int exynos_irq_request_resources(struct irq_data *irqd) raw_spin_unlock_irqrestore(&bank->slock, flags); + clk_disable(bank->drvdata->pclk); + return 0; } @@ -223,6 +268,13 @@ static void exynos_irq_release_resources(struct irq_data *irqd) shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC]; mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; + if (clk_enable(bank->drvdata->pclk)) { + dev_err(bank->gpio_chip.parent, + "unable to enable clock for deconfiguring pin %s-%lu\n", + bank->name, irqd->hwirq); + return; + } + raw_spin_lock_irqsave(&bank->slock, flags); con = readl(bank->pctl_base + reg_con); @@ -232,6 +284,8 @@ static void exynos_irq_release_resources(struct irq_data *irqd) raw_spin_unlock_irqrestore(&bank->slock, flags); + clk_disable(bank->drvdata->pclk); + gpiochip_unlock_as_irq(&bank->gpio_chip, irqd->hwirq); } @@ -281,10 +335,19 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) unsigned int svc, group, pin; int ret; + if (clk_enable(bank->drvdata->pclk)) { + dev_err(bank->gpio_chip.parent, + "unable to enable clock for handling IRQ\n"); + return IRQ_NONE; + } + if (bank->eint_con_offset) svc = readl(bank->eint_base + EXYNOSAUTO_SVC_OFFSET); else svc = readl(bank->eint_base + EXYNOS_SVC_OFFSET); + + clk_disable(bank->drvdata->pclk); + group = EXYNOS_SVC_GROUP(svc); pin = svc & EXYNOS_SVC_NUM_MASK; @@ -563,6 +626,20 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc) chained_irq_enter(chip, desc); + /* + * just enable the clock once here, to avoid an enable/disable dance for + * each bank. + */ + if (eintd->nr_banks) { + struct samsung_pin_bank *b = eintd->banks[0]; + + if (clk_enable(b->drvdata->pclk)) { + dev_err(b->gpio_chip.parent, + "unable to enable clock for pending IRQs\n"); + return; + } + } + for (i = 0; i < eintd->nr_banks; ++i) { struct samsung_pin_bank *b = eintd->banks[i]; pend = readl(b->eint_base + b->irq_chip->eint_pend @@ -572,6 +649,9 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc) exynos_irq_demux_eint(pend & ~mask, b->irq_domain); } + if (eintd->nr_banks) + clk_disable(eintd->banks[0]->drvdata->pclk); + chained_irq_exit(chip, desc); } @@ -695,6 +775,12 @@ static void exynos_pinctrl_suspend_bank( struct exynos_eint_gpio_save *save = bank->soc_priv; const void __iomem *regs = bank->eint_base; + if (clk_enable(bank->drvdata->pclk)) { + dev_err(bank->gpio_chip.parent, + "unable to enable clock for saving state\n"); + return; + } + save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET + bank->eint_offset); save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET @@ -704,6 +790,8 @@ static void exynos_pinctrl_suspend_bank( save->eint_mask = readl(regs + bank->irq_chip->eint_mask + bank->eint_offset); + clk_disable(bank->drvdata->pclk); + pr_debug("%s: save con %#010x\n", bank->name, save->eint_con); pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0); pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1); @@ -716,9 +804,17 @@ static void exynosauto_pinctrl_suspend_bank(struct samsung_pinctrl_drv_data *drv struct exynos_eint_gpio_save *save = bank->soc_priv; const void __iomem *regs = bank->eint_base; + if (clk_enable(bank->drvdata->pclk)) { + dev_err(bank->gpio_chip.parent, + "unable to enable clock for saving state\n"); + return; + } + save->eint_con = readl(regs + bank->pctl_offset + bank->eint_con_offset); save->eint_mask = readl(regs + bank->pctl_offset + bank->eint_mask_offset); + clk_disable(bank->drvdata->pclk); + pr_debug("%s: save con %#010x\n", bank->name, save->eint_con); pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask); } @@ -753,6 +849,12 @@ static void exynos_pinctrl_resume_bank( struct exynos_eint_gpio_save *save = bank->soc_priv; void __iomem *regs = bank->eint_base; + if (clk_enable(bank->drvdata->pclk)) { + dev_err(bank->gpio_chip.parent, + "unable to enable clock for restoring state\n"); + return; + } + pr_debug("%s: con %#010x => %#010x\n", bank->name, readl(regs + EXYNOS_GPIO_ECON_OFFSET + bank->eint_offset), save->eint_con); @@ -774,6 +876,8 @@ static void exynos_pinctrl_resume_bank( + 2 * bank->eint_offset + 4); writel(save->eint_mask, regs + bank->irq_chip->eint_mask + bank->eint_offset); + + clk_disable(bank->drvdata->pclk); } static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvdata, @@ -782,6 +886,12 @@ static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvd struct exynos_eint_gpio_save *save = bank->soc_priv; void __iomem *regs = bank->eint_base; + if (clk_enable(bank->drvdata->pclk)) { + dev_err(bank->gpio_chip.parent, + "unable to enable clock for restoring state\n"); + return; + } + pr_debug("%s: con %#010x => %#010x\n", bank->name, readl(regs + bank->pctl_offset + bank->eint_con_offset), save->eint_con); pr_debug("%s: mask %#010x => %#010x\n", bank->name, @@ -789,6 +899,8 @@ static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvd writel(save->eint_con, regs + bank->pctl_offset + bank->eint_con_offset); writel(save->eint_mask, regs + bank->pctl_offset + bank->eint_mask_offset); + + clk_disable(bank->drvdata->pclk); } void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata) diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index ed07e23e0912..f4607b8493ff 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -15,6 +15,7 @@ // but provides extensions to which platform specific implementation of the gpio // and wakeup interrupts can be hooked to. +#include #include #include #include @@ -371,8 +372,8 @@ static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata, } /* enable or disable a pinmux function */ -static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, - unsigned group) +static int samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, + unsigned group) { struct samsung_pinctrl_drv_data *drvdata; const struct samsung_pin_bank_type *type; @@ -382,6 +383,7 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, unsigned long flags; const struct samsung_pmx_func *func; const struct samsung_pin_group *grp; + int ret; drvdata = pinctrl_dev_get_drvdata(pctldev); func = &drvdata->pmx_functions[selector]; @@ -397,6 +399,12 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, reg += 4; } + ret = clk_enable(drvdata->pclk); + if (ret) { + dev_err(pctldev->dev, "failed to enable clock for setup\n"); + return ret; + } + raw_spin_lock_irqsave(&bank->slock, flags); data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]); @@ -405,6 +413,10 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]); raw_spin_unlock_irqrestore(&bank->slock, flags); + + clk_disable(drvdata->pclk); + + return 0; } /* enable a specified pinmux by writing to registers */ @@ -412,8 +424,7 @@ static int samsung_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned selector, unsigned group) { - samsung_pinmux_setup(pctldev, selector, group); - return 0; + return samsung_pinmux_setup(pctldev, selector, group); } /* list of pinmux callbacks for the pinmux vertical in pinctrl core */ @@ -436,6 +447,7 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, u32 data, width, pin_offset, mask, shift; u32 cfg_value, cfg_reg; unsigned long flags; + int ret; drvdata = pinctrl_dev_get_drvdata(pctldev); pin_to_reg_bank(drvdata, pin, ®_base, &pin_offset, &bank); @@ -447,6 +459,12 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, width = type->fld_width[cfg_type]; cfg_reg = type->reg_offset[cfg_type]; + ret = clk_enable(drvdata->pclk); + if (ret) { + dev_err(drvdata->dev, "failed to enable clock\n"); + return ret; + } + raw_spin_lock_irqsave(&bank->slock, flags); mask = (1 << width) - 1; @@ -466,6 +484,8 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, raw_spin_unlock_irqrestore(&bank->slock, flags); + clk_disable(drvdata->pclk); + return 0; } @@ -555,11 +575,19 @@ static void samsung_gpio_set_value(struct gpio_chip *gc, static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) { struct samsung_pin_bank *bank = gpiochip_get_data(gc); + struct samsung_pinctrl_drv_data *drvdata = bank->drvdata; unsigned long flags; + if (clk_enable(drvdata->pclk)) { + dev_err(drvdata->dev, "failed to enable clock\n"); + return; + } + raw_spin_lock_irqsave(&bank->slock, flags); samsung_gpio_set_value(gc, offset, value); raw_spin_unlock_irqrestore(&bank->slock, flags); + + clk_disable(drvdata->pclk); } /* gpiolib gpio_get callback function */ @@ -569,12 +597,23 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) u32 data; struct samsung_pin_bank *bank = gpiochip_get_data(gc); const struct samsung_pin_bank_type *type = bank->type; + struct samsung_pinctrl_drv_data *drvdata = bank->drvdata; + int ret; reg = bank->pctl_base + bank->pctl_offset; + ret = clk_enable(drvdata->pclk); + if (ret) { + dev_err(drvdata->dev, "failed to enable clock\n"); + return ret; + } + data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]); data >>= offset; data &= 1; + + clk_disable(drvdata->pclk); + return data; } @@ -591,9 +630,11 @@ static int samsung_gpio_set_direction(struct gpio_chip *gc, struct samsung_pin_bank *bank; void __iomem *reg; u32 data, mask, shift; + struct samsung_pinctrl_drv_data *drvdata; bank = gpiochip_get_data(gc); type = bank->type; + drvdata = bank->drvdata; reg = bank->pctl_base + bank->pctl_offset + type->reg_offset[PINCFG_TYPE_FUNC]; @@ -619,12 +660,22 @@ static int samsung_gpio_set_direction(struct gpio_chip *gc, static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset) { struct samsung_pin_bank *bank = gpiochip_get_data(gc); + struct samsung_pinctrl_drv_data *drvdata = bank->drvdata; unsigned long flags; int ret; + ret = clk_enable(drvdata->pclk); + if (ret) { + dev_err(drvdata->dev, "failed to enable clock\n"); + return ret; + } + raw_spin_lock_irqsave(&bank->slock, flags); ret = samsung_gpio_set_direction(gc, offset, true); raw_spin_unlock_irqrestore(&bank->slock, flags); + + clk_disable(drvdata->pclk); + return ret; } @@ -633,14 +684,23 @@ static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset, int value) { struct samsung_pin_bank *bank = gpiochip_get_data(gc); + struct samsung_pinctrl_drv_data *drvdata = bank->drvdata; unsigned long flags; int ret; + ret = clk_enable(drvdata->pclk); + if (ret) { + dev_err(drvdata->dev, "failed to enable clock\n"); + return ret; + } + raw_spin_lock_irqsave(&bank->slock, flags); samsung_gpio_set_value(gc, offset, value); ret = samsung_gpio_set_direction(gc, offset, false); raw_spin_unlock_irqrestore(&bank->slock, flags); + clk_disable(drvdata->pclk); + return ret; } @@ -1164,6 +1224,12 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) } } + drvdata->pclk = devm_clk_get_optional_prepared(dev, "pclk"); + if (IS_ERR(drvdata->pclk)) { + ret = PTR_ERR(drvdata->pclk); + goto err_put_banks; + } + ret = samsung_pinctrl_register(pdev, drvdata); if (ret) goto err_put_banks; @@ -1202,6 +1268,13 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev) struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev); int i; + i = clk_enable(drvdata->pclk); + if (i) { + dev_err(drvdata->dev, + "failed to enable clock for saving state\n"); + return i; + } + for (i = 0; i < drvdata->nr_banks; i++) { struct samsung_pin_bank *bank = &drvdata->pin_banks[i]; const void __iomem *reg = bank->pctl_base + bank->pctl_offset; @@ -1231,6 +1304,8 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev) } } + clk_disable(drvdata->pclk); + if (drvdata->suspend) drvdata->suspend(drvdata); if (drvdata->retention_ctrl && drvdata->retention_ctrl->enable) @@ -1250,8 +1325,20 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev) static int __maybe_unused samsung_pinctrl_resume(struct device *dev) { struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev); + int ret; int i; + /* + * enable clock before the callback, as we don't want to have to deal + * with callback cleanup on clock failures. + */ + ret = clk_enable(drvdata->pclk); + if (ret) { + dev_err(drvdata->dev, + "failed to enable clock for restoring state\n"); + return ret; + } + if (drvdata->resume) drvdata->resume(drvdata); @@ -1286,6 +1373,8 @@ static int __maybe_unused samsung_pinctrl_resume(struct device *dev) writel(bank->pm_save[type], reg + offs[type]); } + clk_disable(drvdata->pclk); + if (drvdata->retention_ctrl && drvdata->retention_ctrl->disable) drvdata->retention_ctrl->disable(drvdata); diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index ab791afaabf5..d50ba6f07d5d 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h @@ -274,6 +274,7 @@ struct samsung_pin_ctrl { * through samsung_pinctrl_drv_data, not samsung_pin_bank). * @dev: device instance representing the controller. * @irq: interrpt number used by the controller to notify gpio interrupts. + * @pclk: optional bus clock if required for accessing registers * @ctrl: pin controller instance managed by the driver. * @pctl: pin controller descriptor registered with the pinctrl subsystem. * @pctl_dev: cookie representing pinctrl device instance. @@ -293,6 +294,7 @@ struct samsung_pinctrl_drv_data { void __iomem *virt_base; struct device *dev; int irq; + struct clk *pclk; struct pinctrl_desc pctl; struct pinctrl_dev *pctl_dev; -- cgit v1.2.3 From e5b3732a9654f26d21647d9e7b4fec846f6d4810 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 30 Apr 2024 08:03:04 +0200 Subject: pinctrl: samsung: drop redundant drvdata assignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix W=1 warning: drivers/pinctrl/samsung/pinctrl-samsung.c: In function ‘samsung_gpio_set_direction’: drivers/pinctrl/samsung/pinctrl-samsung.c:633:42: warning: variable ‘drvdata’ set but not used [-Wunused-but-set-variable] Fixes: f9c744747973 ("pinctrl: samsung: support a bus clock") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202404300825.6lxLwvUY-lkp@intel.com/ Reviewed-by: André Draszik Link: https://lore.kernel.org/r/20240430060304.12332-1-krzysztof.kozlowski@linaro.org Signed-off-by: Krzysztof Kozlowski --- drivers/pinctrl/samsung/pinctrl-samsung.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index f4607b8493ff..623df65a5d6f 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -630,11 +630,9 @@ static int samsung_gpio_set_direction(struct gpio_chip *gc, struct samsung_pin_bank *bank; void __iomem *reg; u32 data, mask, shift; - struct samsung_pinctrl_drv_data *drvdata; bank = gpiochip_get_data(gc); type = bank->type; - drvdata = bank->drvdata; reg = bank->pctl_base + bank->pctl_offset + type->reg_offset[PINCFG_TYPE_FUNC]; -- cgit v1.2.3 From 5ed79863fae5c06eb33f5cd6b6bdf22dd7089392 Mon Sep 17 00:00:00 2001 From: Danila Tikhonov Date: Tue, 23 Apr 2024 23:32:45 +0300 Subject: pinctrl: qcom: pinctrl-sm7150: Fix sdc1 and ufs special pins regs SDC1 and UFS_RESET special pins are located in the west memory bank. SDC1 have address 0x359a000: 0x3500000 (TLMM BASE) + 0x0 (WEST) + 0x9a000 (SDC1_OFFSET) = 0x359a000 UFS_RESET have address 0x359f000: 0x3500000 (TLMM BASE) + 0x0 (WEST) + 0x9f000 (UFS_OFFSET) = 0x359a000 Fixes: b915395c9e04 ("pinctrl: qcom: Add SM7150 pinctrl driver") Signed-off-by: Danila Tikhonov Message-ID: <20240423203245.188480-1-danila@jiaxyga.com> Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-sm7150.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/qcom/pinctrl-sm7150.c b/drivers/pinctrl/qcom/pinctrl-sm7150.c index c542f9bc6bcd..095a1ca75849 100644 --- a/drivers/pinctrl/qcom/pinctrl-sm7150.c +++ b/drivers/pinctrl/qcom/pinctrl-sm7150.c @@ -65,7 +65,7 @@ enum { .intr_detection_width = 2, \ } -#define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \ +#define SDC_QDSD_PINGROUP(pg_name, _tile, ctl, pull, drv) \ { \ .grp = PINCTRL_PINGROUP(#pg_name, \ pg_name##_pins, \ @@ -75,7 +75,7 @@ enum { .intr_cfg_reg = 0, \ .intr_status_reg = 0, \ .intr_target_reg = 0, \ - .tile = SOUTH, \ + .tile = _tile, \ .mux_bit = -1, \ .pull_bit = pull, \ .drv_bit = drv, \ @@ -101,7 +101,7 @@ enum { .intr_cfg_reg = 0, \ .intr_status_reg = 0, \ .intr_target_reg = 0, \ - .tile = SOUTH, \ + .tile = WEST, \ .mux_bit = -1, \ .pull_bit = 3, \ .drv_bit = 0, \ @@ -1199,13 +1199,13 @@ static const struct msm_pingroup sm7150_groups[] = { [117] = PINGROUP(117, NORTH, _, _, _, _, _, _, _, _, _), [118] = PINGROUP(118, NORTH, _, _, _, _, _, _, _, _, _), [119] = UFS_RESET(ufs_reset, 0x9f000), - [120] = SDC_QDSD_PINGROUP(sdc1_rclk, 0x9a000, 15, 0), - [121] = SDC_QDSD_PINGROUP(sdc1_clk, 0x9a000, 13, 6), - [122] = SDC_QDSD_PINGROUP(sdc1_cmd, 0x9a000, 11, 3), - [123] = SDC_QDSD_PINGROUP(sdc1_data, 0x9a000, 9, 0), - [124] = SDC_QDSD_PINGROUP(sdc2_clk, 0x98000, 14, 6), - [125] = SDC_QDSD_PINGROUP(sdc2_cmd, 0x98000, 11, 3), - [126] = SDC_QDSD_PINGROUP(sdc2_data, 0x98000, 9, 0), + [120] = SDC_QDSD_PINGROUP(sdc1_rclk, WEST, 0x9a000, 15, 0), + [121] = SDC_QDSD_PINGROUP(sdc1_clk, WEST, 0x9a000, 13, 6), + [122] = SDC_QDSD_PINGROUP(sdc1_cmd, WEST, 0x9a000, 11, 3), + [123] = SDC_QDSD_PINGROUP(sdc1_data, WEST, 0x9a000, 9, 0), + [124] = SDC_QDSD_PINGROUP(sdc2_clk, SOUTH, 0x98000, 14, 6), + [125] = SDC_QDSD_PINGROUP(sdc2_cmd, SOUTH, 0x98000, 11, 3), + [126] = SDC_QDSD_PINGROUP(sdc2_data, SOUTH, 0x98000, 9, 0), }; static const struct msm_gpio_wakeirq_map sm7150_pdc_map[] = { -- cgit v1.2.3 From 8ff05989b44e1a8f7d2bbe67320990ebc2fbb5e5 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Fri, 3 May 2024 08:27:45 +0200 Subject: pinctrl: bcm2835: Make pin freeing behavior configurable Until now after a bcm2835 pin was freed its pinmux was set to GPIO_IN. So in case it was configured as GPIO_OUT before the configured output level also get lost. As long as GPIO sysfs was used this wasn't actually a problem because the pins and their possible output level were kept by sysfs. Since more and more Raspberry Pi users start using libgpiod they are confused about this behavior. So make the pin freeing behavior of GPIO_OUT configurable via module parameter. In case pinctrl-bcm2835.persist_gpio_outputs is set to 1, the output level is kept. This patch based on the downstream work of Phil Elwell. Link: https://github.com/raspberrypi/linux/pull/6117 Signed-off-by: Stefan Wahren Message-ID: <20240503062745.11298-1-wahrenst@gmx.net> Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers/pinctrl') diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index f5a9372d43bd..7178a38475cc 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -244,6 +244,10 @@ static const char * const irq_type_names[] = { [IRQ_TYPE_LEVEL_LOW] = "level-low", }; +static bool persist_gpio_outputs; +module_param(persist_gpio_outputs, bool, 0644); +MODULE_PARM_DESC(persist_gpio_outputs, "Enable GPIO_OUT persistence when pin is freed"); + static inline u32 bcm2835_gpio_rd(struct bcm2835_pinctrl *pc, unsigned reg) { return readl(pc->base + reg); @@ -926,6 +930,13 @@ static int bcm2835_pmx_free(struct pinctrl_dev *pctldev, unsigned offset) { struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, offset); + + if (fsel == BCM2835_FSEL_GPIO_IN) + return 0; + + if (persist_gpio_outputs && fsel == BCM2835_FSEL_GPIO_OUT) + return 0; /* disable by setting to GPIO_IN */ bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN); @@ -970,10 +981,7 @@ static void bcm2835_pmx_gpio_disable_free(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset) { - struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); - - /* disable by setting to GPIO_IN */ - bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN); + bcm2835_pmx_free(pctldev, offset); } static int bcm2835_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, @@ -1419,6 +1427,9 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) goto out_remove; } + dev_info(dev, "GPIO_OUT persistence: %s\n", + persist_gpio_outputs ? "yes" : "no"); + return 0; out_remove: -- cgit v1.2.3