This is an automatically generated commit which aids following Kernel patch history, as git will see the move and copy as a rename thus defeating the purpose. For the original discussion see: https://lists.openwrt.org/pipermail/openwrt-devel/2023-October/041673.html Signed-off-by: Thomas Richard <thomas.richard@bootlin.com> Link: https://github.com/openwrt/openwrt/pull/18740 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
		
			
				
	
	
		
			190 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			190 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From c15671ce05a038b8c92a6f1e24b0b850a154ba59 Mon Sep 17 00:00:00 2001
 | 
						|
From: Valentin Caron <valentin.caron@foss.st.com>
 | 
						|
Date: Mon, 22 Jul 2024 18:00:20 +0200
 | 
						|
Subject: [PATCH] rtc: stm32: add pinctrl and pinmux interfaces
 | 
						|
 | 
						|
STM32 RTC is capable to handle 3 specific pins of the soc.
 | 
						|
"out1, out2 and out2_rmp". To handle this, we use pinctrl framework.
 | 
						|
There is a single pin per group.
 | 
						|
 | 
						|
Signed-off-by: Valentin Caron <valentin.caron@foss.st.com>
 | 
						|
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
 | 
						|
Link: https://lore.kernel.org/r/20240722160022.454226-3-valentin.caron@foss.st.com
 | 
						|
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
 | 
						|
---
 | 
						|
 drivers/rtc/Kconfig     |   5 ++
 | 
						|
 drivers/rtc/rtc-stm32.c | 120 ++++++++++++++++++++++++++++++++++++++++
 | 
						|
 2 files changed, 125 insertions(+)
 | 
						|
 | 
						|
--- a/drivers/rtc/Kconfig
 | 
						|
+++ b/drivers/rtc/Kconfig
 | 
						|
@@ -1887,6 +1887,11 @@ config RTC_DRV_STM32
 | 
						|
 	tristate "STM32 RTC"
 | 
						|
 	select REGMAP_MMIO
 | 
						|
 	depends on ARCH_STM32 || COMPILE_TEST
 | 
						|
+	depends on OF
 | 
						|
+	depends on PINCTRL
 | 
						|
+	select PINMUX
 | 
						|
+	select PINCONF
 | 
						|
+	select GENERIC_PINCONF
 | 
						|
 	help
 | 
						|
 	   If you say yes here you get support for the STM32 On-Chip
 | 
						|
 	   Real Time Clock.
 | 
						|
--- a/drivers/rtc/rtc-stm32.c
 | 
						|
+++ b/drivers/rtc/rtc-stm32.c
 | 
						|
@@ -12,6 +12,9 @@
 | 
						|
 #include <linux/mfd/syscon.h>
 | 
						|
 #include <linux/module.h>
 | 
						|
 #include <linux/of.h>
 | 
						|
+#include <linux/pinctrl/pinctrl.h>
 | 
						|
+#include <linux/pinctrl/pinconf-generic.h>
 | 
						|
+#include <linux/pinctrl/pinmux.h>
 | 
						|
 #include <linux/platform_device.h>
 | 
						|
 #include <linux/pm_wakeirq.h>
 | 
						|
 #include <linux/regmap.h>
 | 
						|
@@ -94,6 +97,14 @@
 | 
						|
 /* STM32 RTC driver time helpers */
 | 
						|
 #define SEC_PER_DAY		(24 * 60 * 60)
 | 
						|
 
 | 
						|
+/* STM32 RTC pinctrl helpers */
 | 
						|
+#define STM32_RTC_PINMUX(_name, _action, ...) { \
 | 
						|
+	.name = (_name), \
 | 
						|
+	.action = (_action), \
 | 
						|
+	.groups = ((const char *[]){ __VA_ARGS__ }), \
 | 
						|
+	.num_groups = ARRAY_SIZE(((const char *[]){ __VA_ARGS__ })), \
 | 
						|
+}
 | 
						|
+
 | 
						|
 struct stm32_rtc;
 | 
						|
 
 | 
						|
 struct stm32_rtc_registers {
 | 
						|
@@ -149,6 +160,106 @@ static void stm32_rtc_wpr_lock(struct st
 | 
						|
 	writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + regs->wpr);
 | 
						|
 }
 | 
						|
 
 | 
						|
+enum stm32_rtc_pin_name {
 | 
						|
+	NONE,
 | 
						|
+	OUT1,
 | 
						|
+	OUT2,
 | 
						|
+	OUT2_RMP
 | 
						|
+};
 | 
						|
+
 | 
						|
+static const struct pinctrl_pin_desc stm32_rtc_pinctrl_pins[] = {
 | 
						|
+	PINCTRL_PIN(OUT1, "out1"),
 | 
						|
+	PINCTRL_PIN(OUT2, "out2"),
 | 
						|
+	PINCTRL_PIN(OUT2_RMP, "out2_rmp"),
 | 
						|
+};
 | 
						|
+
 | 
						|
+static int stm32_rtc_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
 | 
						|
+{
 | 
						|
+	return ARRAY_SIZE(stm32_rtc_pinctrl_pins);
 | 
						|
+}
 | 
						|
+
 | 
						|
+static const char *stm32_rtc_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
 | 
						|
+						    unsigned int selector)
 | 
						|
+{
 | 
						|
+	return stm32_rtc_pinctrl_pins[selector].name;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static int stm32_rtc_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
 | 
						|
+					    unsigned int selector,
 | 
						|
+					    const unsigned int **pins,
 | 
						|
+					    unsigned int *num_pins)
 | 
						|
+{
 | 
						|
+	*pins = &stm32_rtc_pinctrl_pins[selector].number;
 | 
						|
+	*num_pins = 1;
 | 
						|
+	return 0;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static const struct pinctrl_ops stm32_rtc_pinctrl_ops = {
 | 
						|
+	.dt_node_to_map		= pinconf_generic_dt_node_to_map_all,
 | 
						|
+	.dt_free_map		= pinconf_generic_dt_free_map,
 | 
						|
+	.get_groups_count	= stm32_rtc_pinctrl_get_groups_count,
 | 
						|
+	.get_group_name		= stm32_rtc_pinctrl_get_group_name,
 | 
						|
+	.get_group_pins		= stm32_rtc_pinctrl_get_group_pins,
 | 
						|
+};
 | 
						|
+
 | 
						|
+struct stm32_rtc_pinmux_func {
 | 
						|
+	const char *name;
 | 
						|
+	const char * const *groups;
 | 
						|
+	const unsigned int num_groups;
 | 
						|
+	int (*action)(struct pinctrl_dev *pctl_dev, unsigned int pin);
 | 
						|
+};
 | 
						|
+
 | 
						|
+static const struct stm32_rtc_pinmux_func stm32_rtc_pinmux_functions[] = {
 | 
						|
+};
 | 
						|
+
 | 
						|
+static int stm32_rtc_pinmux_get_functions_count(struct pinctrl_dev *pctldev)
 | 
						|
+{
 | 
						|
+	return ARRAY_SIZE(stm32_rtc_pinmux_functions);
 | 
						|
+}
 | 
						|
+
 | 
						|
+static const char *stm32_rtc_pinmux_get_fname(struct pinctrl_dev *pctldev, unsigned int selector)
 | 
						|
+{
 | 
						|
+	return stm32_rtc_pinmux_functions[selector].name;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static int stm32_rtc_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned int selector,
 | 
						|
+				       const char * const **groups, unsigned int * const num_groups)
 | 
						|
+{
 | 
						|
+	*groups = stm32_rtc_pinmux_functions[selector].groups;
 | 
						|
+	*num_groups = stm32_rtc_pinmux_functions[selector].num_groups;
 | 
						|
+	return 0;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static int stm32_rtc_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int selector,
 | 
						|
+				    unsigned int group)
 | 
						|
+{
 | 
						|
+	struct stm32_rtc_pinmux_func selected_func = stm32_rtc_pinmux_functions[selector];
 | 
						|
+	struct pinctrl_pin_desc pin = stm32_rtc_pinctrl_pins[group];
 | 
						|
+
 | 
						|
+	/* Call action */
 | 
						|
+	if (selected_func.action)
 | 
						|
+		return selected_func.action(pctldev, pin.number);
 | 
						|
+
 | 
						|
+	return -EINVAL;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static const struct pinmux_ops stm32_rtc_pinmux_ops = {
 | 
						|
+	.get_functions_count	= stm32_rtc_pinmux_get_functions_count,
 | 
						|
+	.get_function_name	= stm32_rtc_pinmux_get_fname,
 | 
						|
+	.get_function_groups	= stm32_rtc_pinmux_get_groups,
 | 
						|
+	.set_mux		= stm32_rtc_pinmux_set_mux,
 | 
						|
+	.strict			= true,
 | 
						|
+};
 | 
						|
+
 | 
						|
+static struct pinctrl_desc stm32_rtc_pdesc = {
 | 
						|
+	.name = DRIVER_NAME,
 | 
						|
+	.pins = stm32_rtc_pinctrl_pins,
 | 
						|
+	.npins = ARRAY_SIZE(stm32_rtc_pinctrl_pins),
 | 
						|
+	.owner = THIS_MODULE,
 | 
						|
+	.pctlops = &stm32_rtc_pinctrl_ops,
 | 
						|
+	.pmxops = &stm32_rtc_pinmux_ops,
 | 
						|
+};
 | 
						|
+
 | 
						|
 static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 | 
						|
 {
 | 
						|
 	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 | 
						|
@@ -723,6 +834,7 @@ static int stm32_rtc_probe(struct platfo
 | 
						|
 {
 | 
						|
 	struct stm32_rtc *rtc;
 | 
						|
 	const struct stm32_rtc_registers *regs;
 | 
						|
+	struct pinctrl_dev *pctl;
 | 
						|
 	int ret;
 | 
						|
 
 | 
						|
 	rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
 | 
						|
@@ -834,6 +946,14 @@ static int stm32_rtc_probe(struct platfo
 | 
						|
 		goto err;
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	ret = devm_pinctrl_register_and_init(&pdev->dev, &stm32_rtc_pdesc, rtc, &pctl);
 | 
						|
+	if (ret)
 | 
						|
+		return dev_err_probe(&pdev->dev, ret, "pinctrl register failed");
 | 
						|
+
 | 
						|
+	ret = pinctrl_enable(pctl);
 | 
						|
+	if (ret)
 | 
						|
+		return dev_err_probe(&pdev->dev, ret, "pinctrl enable failed");
 | 
						|
+
 | 
						|
 	/*
 | 
						|
 	 * If INITS flag is reset (calendar year field set to 0x00), calendar
 | 
						|
 	 * must be initialized
 |