From 5b19519d4e6ff70c8bd7fc50055c910e141fd5f8 Mon Sep 17 00:00:00 2001 From: Valentin Caron Date: Mon, 22 Jul 2024 18:00:19 +0200 Subject: [PATCH 01/17] dt-bindings: rtc: stm32: describe pinmux nodes STM32 RTC is capable to handle 3 specific pins of the soc (out1, out2, out2_rmp) and to outputs 2 signals (LSCO, alarm-a). This feature is configured thanks to pinmux nodes and pinctrl framework. This feature is available with compatible st,stm32mp1-rtc and st,stm32mp25-rtc only. Signed-off-by: Valentin Caron Reviewed-by: Krzysztof Kozlowski Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20240722160022.454226-2-valentin.caron@foss.st.com Signed-off-by: Alexandre Belloni --- .../devicetree/bindings/rtc/st,stm32-rtc.yaml | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml index 7a0fab721cf1..aae06e570c22 100644 --- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml @@ -53,6 +53,28 @@ properties: override default rtc_ck parent clock phandle of the new parent clock of rtc_ck maxItems: 1 +patternProperties: + "^rtc-[a-z]+-[0-9]+$": + type: object + $ref: /schemas/pinctrl/pinmux-node.yaml + description: | + Configuration of STM32 RTC pins description. STM32 RTC is able to output + some signals on specific pins: + - LSCO (Low Speed Clock Output) that allow to output LSE clock on a pin. + - Alarm out that allow to send a pulse on a pin when alarm A of the RTC + expires. + additionalProperties: false + properties: + function: + enum: + - lsco + - alarm-a + pins: + enum: + - out1 + - out2 + - out2_rmp + allOf: - if: properties: @@ -68,6 +90,9 @@ allOf: clock-names: false + patternProperties: + "^rtc-[a-z]+-[0-9]+$": false + required: - st,syscfg @@ -83,6 +108,9 @@ allOf: minItems: 2 maxItems: 2 + patternProperties: + "^rtc-[a-z]+-[0-9]+$": false + required: - clock-names - st,syscfg From 16ad2bc09efbcb9cb24f8d879ac218421cbef690 Mon Sep 17 00:00:00 2001 From: Valentin Caron Date: Mon, 22 Jul 2024 18:00:20 +0200 Subject: [PATCH 02/17] 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 Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20240722160022.454226-3-valentin.caron@foss.st.com Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 5 ++ drivers/rtc/rtc-stm32.c | 120 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 2a95b05982ad..4b1a87027a3d 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1923,6 +1923,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. diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c index 98b07969609d..6dfd9dc07e2e 100644 --- a/drivers/rtc/rtc-stm32.c +++ b/drivers/rtc/rtc-stm32.c @@ -13,6 +13,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -107,6 +110,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 { @@ -171,6 +182,106 @@ static void stm32_rtc_wpr_lock(struct stm32_rtc *rtc) 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; @@ -791,6 +902,7 @@ static int stm32_rtc_probe(struct platform_device *pdev) { 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); @@ -912,6 +1024,14 @@ static int stm32_rtc_probe(struct platform_device *pdev) 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 From bb7b0df2be5c6b7bfe0cf9c93067c5b1489566ca Mon Sep 17 00:00:00 2001 From: Valentin Caron Date: Mon, 22 Jul 2024 18:00:21 +0200 Subject: [PATCH 03/17] rtc: stm32: add Low Speed Clock Output (LSCO) support RTC is able to output on a pin the "LSE" internal clock. STM32 RTC is now registered as a clock provider. It provides rtc_lsco clock, that means RTC_LSCO is output on either RTC_OUT1 or RTC_OUT2_RMP, depending on pinmux DT property. The clock is marked as CLK_IGNORE_UNUSED and CLK_IS_CRITICAL because RTC_LSCO can be early required by devices needed it to init. Add LSCO in pinmux functions. Add "stm32_rtc_clean_outs" to disable LSCO. As RTC is part of "backup" power domain, it is not reset during shutdown or reboot. So force LSCO disable at probe. Co-developed-by: Amelie Delaunay Signed-off-by: Amelie Delaunay Signed-off-by: Valentin Caron Link: https://lore.kernel.org/r/20240722160022.454226-4-valentin.caron@foss.st.com Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 1 + drivers/rtc/rtc-stm32.c | 101 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 4b1a87027a3d..b3469f6986e9 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1928,6 +1928,7 @@ config RTC_DRV_STM32 select PINMUX select PINCONF select GENERIC_PINCONF + depends on COMMON_CLK help If you say yes here you get support for the STM32 On-Chip Real Time Clock. diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c index 6dfd9dc07e2e..675860a13051 100644 --- a/drivers/rtc/rtc-stm32.c +++ b/drivers/rtc/rtc-stm32.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +46,10 @@ #define STM32_RTC_CR_FMT BIT(6) #define STM32_RTC_CR_ALRAE BIT(8) #define STM32_RTC_CR_ALRAIE BIT(12) +#define STM32_RTC_CR_OSEL GENMASK(22, 21) +#define STM32_RTC_CR_COE BIT(23) +#define STM32_RTC_CR_TAMPOE BIT(26) +#define STM32_RTC_CR_OUT2EN BIT(31) /* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */ #define STM32_RTC_ISR_ALRAWF BIT(0) @@ -81,6 +86,12 @@ /* STM32_RTC_SR/_SCR bit fields */ #define STM32_RTC_SR_ALRA BIT(0) +/* STM32_RTC_CFGR bit fields */ +#define STM32_RTC_CFGR_OUT2_RMP BIT(0) +#define STM32_RTC_CFGR_LSCOEN GENMASK(2, 1) +#define STM32_RTC_CFGR_LSCOEN_OUT1 1 +#define STM32_RTC_CFGR_LSCOEN_OUT2_RMP 2 + /* STM32_RTC_VERR bit fields */ #define STM32_RTC_VERR_MINREV_SHIFT 0 #define STM32_RTC_VERR_MINREV GENMASK(3, 0) @@ -130,6 +141,7 @@ struct stm32_rtc_registers { u16 wpr; u16 sr; u16 scr; + u16 cfgr; u16 verr; }; @@ -145,6 +157,7 @@ struct stm32_rtc_data { bool need_dbp; bool need_accuracy; bool rif_protected; + bool has_lsco; }; struct stm32_rtc { @@ -157,6 +170,7 @@ struct stm32_rtc { struct clk *rtc_ck; const struct stm32_rtc_data *data; int irq_alarm; + struct clk *clk_lsco; }; struct stm32_rtc_rif_resource { @@ -231,7 +245,68 @@ struct stm32_rtc_pinmux_func { int (*action)(struct pinctrl_dev *pctl_dev, unsigned int pin); }; +static int stm32_rtc_pinmux_lsco_available(struct pinctrl_dev *pctldev, unsigned int pin) +{ + struct stm32_rtc *rtc = pinctrl_dev_get_drvdata(pctldev); + struct stm32_rtc_registers regs = rtc->data->regs; + unsigned int cr = readl_relaxed(rtc->base + regs.cr); + unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr); + unsigned int calib = STM32_RTC_CR_COE; + unsigned int tampalrm = STM32_RTC_CR_TAMPOE | STM32_RTC_CR_OSEL; + + switch (pin) { + case OUT1: + if ((!(cr & STM32_RTC_CR_OUT2EN) && + ((cr & calib) || cr & tampalrm)) || + ((cr & calib) && (cr & tampalrm))) + return -EBUSY; + break; + case OUT2_RMP: + if ((cr & STM32_RTC_CR_OUT2EN) && + (cfgr & STM32_RTC_CFGR_OUT2_RMP) && + ((cr & calib) || (cr & tampalrm))) + return -EBUSY; + break; + default: + return -EINVAL; + } + + if (clk_get_rate(rtc->rtc_ck) != 32768) + return -ERANGE; + + return 0; +} + +static int stm32_rtc_pinmux_action_lsco(struct pinctrl_dev *pctldev, unsigned int pin) +{ + struct stm32_rtc *rtc = pinctrl_dev_get_drvdata(pctldev); + struct stm32_rtc_registers regs = rtc->data->regs; + struct device *dev = rtc->rtc_dev->dev.parent; + u8 lscoen; + int ret; + + if (!rtc->data->has_lsco) + return -EPERM; + + ret = stm32_rtc_pinmux_lsco_available(pctldev, pin); + if (ret) + return ret; + + lscoen = (pin == OUT1) ? STM32_RTC_CFGR_LSCOEN_OUT1 : STM32_RTC_CFGR_LSCOEN_OUT2_RMP; + + rtc->clk_lsco = clk_register_gate(dev, "rtc_lsco", __clk_get_name(rtc->rtc_ck), + CLK_IGNORE_UNUSED | CLK_IS_CRITICAL, + rtc->base + regs.cfgr, lscoen, 0, NULL); + if (IS_ERR(rtc->clk_lsco)) + return PTR_ERR(rtc->clk_lsco); + + of_clk_add_provider(dev->of_node, of_clk_src_simple_get, rtc->clk_lsco); + + return 0; +} + static const struct stm32_rtc_pinmux_func stm32_rtc_pinmux_functions[] = { + STM32_RTC_PINMUX("lsco", &stm32_rtc_pinmux_action_lsco, "out1", "out2_rmp"), }; static int stm32_rtc_pinmux_get_functions_count(struct pinctrl_dev *pctldev) @@ -687,6 +762,7 @@ static const struct stm32_rtc_data stm32_rtc_data = { .need_dbp = true, .need_accuracy = false, .rif_protected = false, + .has_lsco = false, .regs = { .tr = 0x00, .dr = 0x04, @@ -697,6 +773,7 @@ static const struct stm32_rtc_data stm32_rtc_data = { .wpr = 0x24, .sr = 0x0C, /* set to ISR offset to ease alarm management */ .scr = UNDEF_REG, + .cfgr = UNDEF_REG, .verr = UNDEF_REG, }, .events = { @@ -710,6 +787,7 @@ static const struct stm32_rtc_data stm32h7_rtc_data = { .need_dbp = true, .need_accuracy = false, .rif_protected = false, + .has_lsco = false, .regs = { .tr = 0x00, .dr = 0x04, @@ -720,6 +798,7 @@ static const struct stm32_rtc_data stm32h7_rtc_data = { .wpr = 0x24, .sr = 0x0C, /* set to ISR offset to ease alarm management */ .scr = UNDEF_REG, + .cfgr = UNDEF_REG, .verr = UNDEF_REG, }, .events = { @@ -742,6 +821,7 @@ static const struct stm32_rtc_data stm32mp1_data = { .need_dbp = false, .need_accuracy = true, .rif_protected = false, + .has_lsco = true, .regs = { .tr = 0x00, .dr = 0x04, @@ -752,6 +832,7 @@ static const struct stm32_rtc_data stm32mp1_data = { .wpr = 0x24, .sr = 0x50, .scr = 0x5C, + .cfgr = 0x60, .verr = 0x3F4, }, .events = { @@ -765,6 +846,7 @@ static const struct stm32_rtc_data stm32mp25_data = { .need_dbp = false, .need_accuracy = true, .rif_protected = true, + .has_lsco = true, .regs = { .tr = 0x00, .dr = 0x04, @@ -775,6 +857,7 @@ static const struct stm32_rtc_data stm32mp25_data = { .wpr = 0x24, .sr = 0x50, .scr = 0x5C, + .cfgr = 0x60, .verr = 0x3F4, }, .events = { @@ -792,6 +875,19 @@ static const struct of_device_id stm32_rtc_of_match[] = { }; MODULE_DEVICE_TABLE(of, stm32_rtc_of_match); +static void stm32_rtc_clean_outs(struct stm32_rtc *rtc) +{ + struct stm32_rtc_registers regs = rtc->data->regs; + + if (regs.cfgr != UNDEF_REG) { + unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr); + + cfgr &= ~STM32_RTC_CFGR_LSCOEN; + cfgr &= ~STM32_RTC_CFGR_OUT2_RMP; + writel_relaxed(cfgr, rtc->base + regs.cfgr); + } +} + static int stm32_rtc_check_rif(struct stm32_rtc *stm32_rtc, struct stm32_rtc_rif_resource res) { @@ -1024,6 +1120,8 @@ static int stm32_rtc_probe(struct platform_device *pdev) goto err; } + stm32_rtc_clean_outs(rtc); + 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"); @@ -1070,6 +1168,9 @@ static void stm32_rtc_remove(struct platform_device *pdev) const struct stm32_rtc_registers *regs = &rtc->data->regs; unsigned int cr; + if (!IS_ERR_OR_NULL(rtc->clk_lsco)) + clk_unregister_gate(rtc->clk_lsco); + /* Disable interrupts */ stm32_rtc_wpr_unlock(rtc); cr = readl_relaxed(rtc->base + regs->cr); From 04dcadb87da68d1349b658b1fef04f077b78c13c Mon Sep 17 00:00:00 2001 From: Valentin Caron Date: Mon, 22 Jul 2024 18:00:22 +0200 Subject: [PATCH 04/17] rtc: stm32: add alarm A out feature STM32 RTC can pulse some SOC pins when an RTC alarm expires. This patch adds this functionality for alarm A. The pulse can out on three pins RTC_OUT1, RTC_OUT2, RTC_OUT2_RMP (PC13, PB2, PI8 on stm32mp15) (PC13, PB2, PI1 on stm32mp13) (PC13, PF4/PF6, PI8 on stm32mp25). This patch only adds the functionality for devices which are using st,stm32mp1-rtc and st,stm32mp25-rtc compatible. Add "alarm-a" in pinmux functions. Signed-off-by: Valentin Caron Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20240722160022.454226-5-valentin.caron@foss.st.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-stm32.c | 60 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c index 675860a13051..3e4f2ee22b0b 100644 --- a/drivers/rtc/rtc-stm32.c +++ b/drivers/rtc/rtc-stm32.c @@ -47,8 +47,10 @@ #define STM32_RTC_CR_ALRAE BIT(8) #define STM32_RTC_CR_ALRAIE BIT(12) #define STM32_RTC_CR_OSEL GENMASK(22, 21) +#define STM32_RTC_CR_OSEL_ALARM_A FIELD_PREP(STM32_RTC_CR_OSEL, 0x01) #define STM32_RTC_CR_COE BIT(23) #define STM32_RTC_CR_TAMPOE BIT(26) +#define STM32_RTC_CR_TAMPALRM_TYPE BIT(30) #define STM32_RTC_CR_OUT2EN BIT(31) /* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */ @@ -158,6 +160,7 @@ struct stm32_rtc_data { bool need_accuracy; bool rif_protected; bool has_lsco; + bool has_alarm_out; }; struct stm32_rtc { @@ -245,6 +248,47 @@ struct stm32_rtc_pinmux_func { int (*action)(struct pinctrl_dev *pctl_dev, unsigned int pin); }; +static int stm32_rtc_pinmux_action_alarm(struct pinctrl_dev *pctldev, unsigned int pin) +{ + struct stm32_rtc *rtc = pinctrl_dev_get_drvdata(pctldev); + struct stm32_rtc_registers regs = rtc->data->regs; + unsigned int cr = readl_relaxed(rtc->base + regs.cr); + unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr); + + if (!rtc->data->has_alarm_out) + return -EPERM; + + cr &= ~STM32_RTC_CR_OSEL; + cr |= STM32_RTC_CR_OSEL_ALARM_A; + cr &= ~STM32_RTC_CR_TAMPOE; + cr &= ~STM32_RTC_CR_COE; + cr &= ~STM32_RTC_CR_TAMPALRM_TYPE; + + switch (pin) { + case OUT1: + cr &= ~STM32_RTC_CR_OUT2EN; + cfgr &= ~STM32_RTC_CFGR_OUT2_RMP; + break; + case OUT2: + cr |= STM32_RTC_CR_OUT2EN; + cfgr &= ~STM32_RTC_CFGR_OUT2_RMP; + break; + case OUT2_RMP: + cr |= STM32_RTC_CR_OUT2EN; + cfgr |= STM32_RTC_CFGR_OUT2_RMP; + break; + default: + return -EINVAL; + } + + stm32_rtc_wpr_unlock(rtc); + writel_relaxed(cr, rtc->base + regs.cr); + writel_relaxed(cfgr, rtc->base + regs.cfgr); + stm32_rtc_wpr_lock(rtc); + + return 0; +} + static int stm32_rtc_pinmux_lsco_available(struct pinctrl_dev *pctldev, unsigned int pin) { struct stm32_rtc *rtc = pinctrl_dev_get_drvdata(pctldev); @@ -307,6 +351,7 @@ static int stm32_rtc_pinmux_action_lsco(struct pinctrl_dev *pctldev, unsigned in static const struct stm32_rtc_pinmux_func stm32_rtc_pinmux_functions[] = { STM32_RTC_PINMUX("lsco", &stm32_rtc_pinmux_action_lsco, "out1", "out2_rmp"), + STM32_RTC_PINMUX("alarm-a", &stm32_rtc_pinmux_action_alarm, "out1", "out2", "out2_rmp"), }; static int stm32_rtc_pinmux_get_functions_count(struct pinctrl_dev *pctldev) @@ -763,6 +808,7 @@ static const struct stm32_rtc_data stm32_rtc_data = { .need_accuracy = false, .rif_protected = false, .has_lsco = false, + .has_alarm_out = false, .regs = { .tr = 0x00, .dr = 0x04, @@ -788,6 +834,7 @@ static const struct stm32_rtc_data stm32h7_rtc_data = { .need_accuracy = false, .rif_protected = false, .has_lsco = false, + .has_alarm_out = false, .regs = { .tr = 0x00, .dr = 0x04, @@ -822,6 +869,7 @@ static const struct stm32_rtc_data stm32mp1_data = { .need_accuracy = true, .rif_protected = false, .has_lsco = true, + .has_alarm_out = true, .regs = { .tr = 0x00, .dr = 0x04, @@ -847,6 +895,7 @@ static const struct stm32_rtc_data stm32mp25_data = { .need_accuracy = true, .rif_protected = true, .has_lsco = true, + .has_alarm_out = true, .regs = { .tr = 0x00, .dr = 0x04, @@ -878,6 +927,17 @@ MODULE_DEVICE_TABLE(of, stm32_rtc_of_match); static void stm32_rtc_clean_outs(struct stm32_rtc *rtc) { struct stm32_rtc_registers regs = rtc->data->regs; + unsigned int cr = readl_relaxed(rtc->base + regs.cr); + + cr &= ~STM32_RTC_CR_OSEL; + cr &= ~STM32_RTC_CR_TAMPOE; + cr &= ~STM32_RTC_CR_COE; + cr &= ~STM32_RTC_CR_TAMPALRM_TYPE; + cr &= ~STM32_RTC_CR_OUT2EN; + + stm32_rtc_wpr_unlock(rtc); + writel_relaxed(cr, rtc->base + regs.cr); + stm32_rtc_wpr_lock(rtc); if (regs.cfgr != UNDEF_REG) { unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr); From adab39e1f48224d5a89b10d171cdd78c0c215539 Mon Sep 17 00:00:00 2001 From: Stanislav Jakubek Date: Sat, 6 Jul 2024 18:11:52 +0200 Subject: [PATCH 05/17] dt-bindings: rtc: sprd,sc2731-rtc: convert to YAML Convert the Spreadtrum SC2731 RTC bindings to DT schema. Rename file to match compatible. Signed-off-by: Stanislav Jakubek Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/ZolsyEC8eeJWNIb6@standask-GA-A55M-S2HP Signed-off-by: Alexandre Belloni --- .../bindings/rtc/sprd,sc2731-rtc.yaml | 49 +++++++++++++++++++ .../bindings/rtc/sprd,sc27xx-rtc.txt | 26 ---------- 2 files changed, 49 insertions(+), 26 deletions(-) create mode 100644 Documentation/devicetree/bindings/rtc/sprd,sc2731-rtc.yaml delete mode 100644 Documentation/devicetree/bindings/rtc/sprd,sc27xx-rtc.txt diff --git a/Documentation/devicetree/bindings/rtc/sprd,sc2731-rtc.yaml b/Documentation/devicetree/bindings/rtc/sprd,sc2731-rtc.yaml new file mode 100644 index 000000000000..f3d20e976965 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/sprd,sc2731-rtc.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/rtc/sprd,sc2731-rtc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Spreadtrum SC2731 Real Time Clock + +maintainers: + - Orson Zhai + - Baolin Wang + - Chunyan Zhang + +properties: + compatible: + const: sprd,sc2731-rtc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + +allOf: + - $ref: rtc.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + + pmic { + #address-cells = <1>; + #size-cells = <0>; + + rtc@280 { + compatible = "sprd,sc2731-rtc"; + reg = <0x280>; + interrupt-parent = <&sc2731_pmic>; + interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/rtc/sprd,sc27xx-rtc.txt b/Documentation/devicetree/bindings/rtc/sprd,sc27xx-rtc.txt deleted file mode 100644 index 1f5754299d31..000000000000 --- a/Documentation/devicetree/bindings/rtc/sprd,sc27xx-rtc.txt +++ /dev/null @@ -1,26 +0,0 @@ -Spreadtrum SC27xx Real Time Clock - -Required properties: -- compatible: should be "sprd,sc2731-rtc". -- reg: address offset of rtc register. -- interrupts: rtc alarm interrupt. - -Example: - - sc2731_pmic: pmic@0 { - compatible = "sprd,sc2731"; - reg = <0>; - spi-max-frequency = <26000000>; - interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; - #address-cells = <1>; - #size-cells = <0>; - - rtc@280 { - compatible = "sprd,sc2731-rtc"; - reg = <0x280>; - interrupt-parent = <&sc2731_pmic>; - interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; - }; - }; From 2d611fbe9a85971a38fe93a29512bd241e4d7035 Mon Sep 17 00:00:00 2001 From: Chen Ni Date: Tue, 16 Jul 2024 11:02:52 +0800 Subject: [PATCH 06/17] rtc: twl: convert comma to semicolon Replace a comma between expression statements by a semicolon. Fixes: 7130856f5605 ("rtc: twl: add NVRAM support") Signed-off-by: Chen Ni Link: https://lore.kernel.org/r/20240716030252.400340-1-nichen@iscas.ac.cn Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-twl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index 2cfacdd37e09..4e24c12004f1 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -591,8 +591,8 @@ static int twl_rtc_probe(struct platform_device *pdev) memset(&nvmem_cfg, 0, sizeof(nvmem_cfg)); nvmem_cfg.name = "twl-secured-"; nvmem_cfg.type = NVMEM_TYPE_BATTERY_BACKED; - nvmem_cfg.reg_read = twl_nvram_read, - nvmem_cfg.reg_write = twl_nvram_write, + nvmem_cfg.reg_read = twl_nvram_read; + nvmem_cfg.reg_write = twl_nvram_write; nvmem_cfg.word_size = 1; nvmem_cfg.stride = 1; if (twl_class_is_4030()) { From da1531ecf18612572c53878d5ef8e94673bf86ce Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Mon, 26 Aug 2024 14:13:20 -0500 Subject: [PATCH 07/17] rtc: s35390a: Drop vendorless compatible string from match table There's no need to list "s35390a" in the DT match table. The I2C core will strip any vendor prefix and match against the i2c_device_id table which has an "s35390a" entry. Signed-off-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20240826191321.1410668-1-robh@kernel.org Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-s35390a.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index 2d6b655a4b25..e3dc18882f41 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -56,7 +56,6 @@ static const struct i2c_device_id s35390a_id[] = { MODULE_DEVICE_TABLE(i2c, s35390a_id); static const __maybe_unused struct of_device_id s35390a_of_match[] = { - { .compatible = "s35390a" }, { .compatible = "sii,s35390a" }, { } }; From 5af858acea22bc5d8a2ebddcad57babca1442dd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B3th=20J=C3=A1nos?= Date: Fri, 30 Aug 2024 10:36:39 +0200 Subject: [PATCH 08/17] rtc: Add driver for SD2405AL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for the DFRobot SD2405AL I2C RTC Module. Datasheet: https://image.dfrobot.com/image/data/TOY0021/SD2405AL%20datasheet%20(Angelo%20v0.1).pdf Product: https://www.dfrobot.com/product-1600.html To instantiate (assuming device is connected to I2C-1) as root: echo sd2405al 0x32 > /sys/bus/i2c/devices/i2c-1/new_device as user: echo 'sd2405al 0x32' | sudo tee /sys/class/i2c-adapter/i2c-1/new_device The driver is tested with: + hwclock + tools/testing/selftests/rtc/setdate + tools/testing/selftests/rtc/rtctest Reviewed-by: Csókás Bence Signed-off-by: Tóth János Link: https://lore.kernel.org/r/20240830-rtc-sd2405al-v7-1-2f7102621b1d@gmail.com Signed-off-by: Alexandre Belloni --- MAINTAINERS | 6 + drivers/rtc/Kconfig | 10 ++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-sd2405al.c | 227 +++++++++++++++++++++++++++++++++++++ 4 files changed, 244 insertions(+) create mode 100644 drivers/rtc/rtc-sd2405al.c diff --git a/MAINTAINERS b/MAINTAINERS index 42decde38320..7c970944a5f6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6474,6 +6474,12 @@ F: include/net/devlink.h F: include/uapi/linux/devlink.h F: net/devlink/ +DFROBOT SD2405AL RTC DRIVER +M: Tóth János +L: linux-rtc@vger.kernel.org +S: Maintained +F: drivers/rtc/rtc-sd2405al.c + DH ELECTRONICS IMX6 DHCOM/DHCOR BOARD SUPPORT M: Christoph Niedermaier L: kernel@dh-electronics.com diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index b3469f6986e9..075151c4b786 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -743,6 +743,16 @@ config RTC_DRV_S5M This driver can also be built as a module. If so, the module will be called rtc-s5m. +config RTC_DRV_SD2405AL + tristate "DFRobot SD2405AL" + select REGMAP_I2C + help + If you say yes here you will get support for the + DFRobot SD2405AL I2C RTC Module. + + This driver can also be built as a module. If so, the module + will be called rtc-sd2405al. + config RTC_DRV_SD3078 tristate "ZXW Shenzhen whwave SD3078" select REGMAP_I2C diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 3004e372f25f..3d19feba1e1c 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -162,6 +162,7 @@ obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o obj-$(CONFIG_RTC_DRV_S5M) += rtc-s5m.o obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o obj-$(CONFIG_RTC_DRV_SC27XX) += rtc-sc27xx.o +obj-$(CONFIG_RTC_DRV_SD2405AL) += rtc-sd2405al.o obj-$(CONFIG_RTC_DRV_SD3078) += rtc-sd3078.o obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o diff --git a/drivers/rtc/rtc-sd2405al.c b/drivers/rtc/rtc-sd2405al.c new file mode 100644 index 000000000000..d2568c3e3876 --- /dev/null +++ b/drivers/rtc/rtc-sd2405al.c @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * RTC driver for the SD2405AL Real-Time Clock + * + * Datasheet: + * https://image.dfrobot.com/image/data/TOY0021/SD2405AL%20datasheet%20(Angelo%20v0.1).pdf + * + * Copyright (C) 2024 Tóth János + */ + +#include +#include +#include +#include + +/* Real time clock registers */ +#define SD2405AL_REG_T_SEC 0x00 +#define SD2405AL_REG_T_MIN 0x01 +#define SD2405AL_REG_T_HOUR 0x02 +# define SD2405AL_BIT_12H_PM BIT(5) +# define SD2405AL_BIT_24H BIT(7) +#define SD2405AL_REG_T_WEEK 0x03 +#define SD2405AL_REG_T_DAY 0x04 +#define SD2405AL_REG_T_MON 0x05 +#define SD2405AL_REG_T_YEAR 0x06 + +#define SD2405AL_NUM_T_REGS (SD2405AL_REG_T_YEAR - SD2405AL_REG_T_SEC + 1) + +/* Control registers */ +#define SD2405AL_REG_CTR1 0x0F +# define SD2405AL_BIT_WRTC2 BIT(2) +# define SD2405AL_BIT_WRTC3 BIT(7) +#define SD2405AL_REG_CTR2 0x10 +# define SD2405AL_BIT_WRTC1 BIT(7) +#define SD2405AL_REG_CTR3 0x11 +#define SD2405AL_REG_TTF 0x12 +#define SD2405AL_REG_CNTDWN 0x13 + +/* General RAM */ +#define SD2405AL_REG_M_START 0x14 +#define SD2405AL_REG_M_END 0x1F + +struct sd2405al { + struct device *dev; + struct rtc_device *rtc; + struct regmap *regmap; +}; + +static int sd2405al_enable_reg_write(struct sd2405al *sd2405al) +{ + int ret; + + /* order of writes is important */ + ret = regmap_update_bits(sd2405al->regmap, SD2405AL_REG_CTR2, + SD2405AL_BIT_WRTC1, SD2405AL_BIT_WRTC1); + if (ret < 0) + return ret; + + ret = regmap_update_bits(sd2405al->regmap, SD2405AL_REG_CTR1, + SD2405AL_BIT_WRTC2 | SD2405AL_BIT_WRTC3, + SD2405AL_BIT_WRTC2 | SD2405AL_BIT_WRTC3); + if (ret < 0) + return ret; + + return 0; +} + +static int sd2405al_disable_reg_write(struct sd2405al *sd2405al) +{ + int ret; + + /* order of writes is important */ + ret = regmap_update_bits(sd2405al->regmap, SD2405AL_REG_CTR1, + SD2405AL_BIT_WRTC2 | SD2405AL_BIT_WRTC3, 0x00); + if (ret < 0) + return ret; + + ret = regmap_update_bits(sd2405al->regmap, SD2405AL_REG_CTR2, + SD2405AL_BIT_WRTC1, 0x00); + if (ret < 0) + return ret; + + return 0; +} + +static int sd2405al_read_time(struct device *dev, struct rtc_time *time) +{ + u8 data[SD2405AL_NUM_T_REGS] = { 0 }; + struct sd2405al *sd2405al = dev_get_drvdata(dev); + int ret; + + ret = regmap_bulk_read(sd2405al->regmap, SD2405AL_REG_T_SEC, data, + SD2405AL_NUM_T_REGS); + if (ret < 0) + return ret; + + time->tm_sec = bcd2bin(data[SD2405AL_REG_T_SEC] & 0x7F); + time->tm_min = bcd2bin(data[SD2405AL_REG_T_MIN] & 0x7F); + + if (data[SD2405AL_REG_T_HOUR] & SD2405AL_BIT_24H) + time->tm_hour = bcd2bin(data[SD2405AL_REG_T_HOUR] & 0x3F); + else + if (data[SD2405AL_REG_T_HOUR] & SD2405AL_BIT_12H_PM) + time->tm_hour = bcd2bin(data[SD2405AL_REG_T_HOUR] + & 0x1F) + 12; + else /* 12 hour mode, AM */ + time->tm_hour = bcd2bin(data[SD2405AL_REG_T_HOUR] + & 0x1F); + + time->tm_wday = bcd2bin(data[SD2405AL_REG_T_WEEK] & 0x07); + time->tm_mday = bcd2bin(data[SD2405AL_REG_T_DAY] & 0x3F); + time->tm_mon = bcd2bin(data[SD2405AL_REG_T_MON] & 0x1F) - 1; + time->tm_year = bcd2bin(data[SD2405AL_REG_T_YEAR]) + 100; + + dev_dbg(sd2405al->dev, "read time: %ptR (%d)\n", time, time->tm_wday); + + return 0; +} + +static int sd2405al_set_time(struct device *dev, struct rtc_time *time) +{ + u8 data[SD2405AL_NUM_T_REGS]; + struct sd2405al *sd2405al = dev_get_drvdata(dev); + int ret; + + data[SD2405AL_REG_T_SEC] = bin2bcd(time->tm_sec); + data[SD2405AL_REG_T_MIN] = bin2bcd(time->tm_min); + data[SD2405AL_REG_T_HOUR] = bin2bcd(time->tm_hour) | SD2405AL_BIT_24H; + data[SD2405AL_REG_T_DAY] = bin2bcd(time->tm_mday); + data[SD2405AL_REG_T_WEEK] = bin2bcd(time->tm_wday); + data[SD2405AL_REG_T_MON] = bin2bcd(time->tm_mon) + 1; + data[SD2405AL_REG_T_YEAR] = bin2bcd(time->tm_year - 100); + + ret = sd2405al_enable_reg_write(sd2405al); + if (ret < 0) + return ret; + + ret = regmap_bulk_write(sd2405al->regmap, SD2405AL_REG_T_SEC, data, + SD2405AL_NUM_T_REGS); + if (ret < 0) + return ret; + + ret = regmap_write(sd2405al->regmap, SD2405AL_REG_TTF, 0x00); + if (ret < 0) + return ret; + + ret = sd2405al_disable_reg_write(sd2405al); + if (ret < 0) + return ret; + + dev_dbg(sd2405al->dev, "set time: %ptR (%d)\n", time, time->tm_wday); + + return 0; +} + +static const struct rtc_class_ops sd2405al_rtc_ops = { + .read_time = sd2405al_read_time, + .set_time = sd2405al_set_time, +}; + +static const struct regmap_config sd2405al_regmap_conf = { + .reg_bits = 8, + .val_bits = 8, + .max_register = SD2405AL_REG_M_END, +}; + +static int sd2405al_probe(struct i2c_client *client) +{ + struct sd2405al *sd2405al; + int ret; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -ENODEV; + + sd2405al = devm_kzalloc(&client->dev, sizeof(*sd2405al), GFP_KERNEL); + if (!sd2405al) + return -ENOMEM; + + sd2405al->dev = &client->dev; + + sd2405al->regmap = devm_regmap_init_i2c(client, &sd2405al_regmap_conf); + if (IS_ERR(sd2405al->regmap)) + return PTR_ERR(sd2405al->regmap); + + sd2405al->rtc = devm_rtc_allocate_device(&client->dev); + if (IS_ERR(sd2405al->rtc)) + return PTR_ERR(sd2405al->rtc); + + sd2405al->rtc->ops = &sd2405al_rtc_ops; + sd2405al->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; + sd2405al->rtc->range_max = RTC_TIMESTAMP_END_2099; + + dev_set_drvdata(&client->dev, sd2405al); + + ret = devm_rtc_register_device(sd2405al->rtc); + if (ret < 0) + return ret; + + return 0; +} + +static const struct i2c_device_id sd2405al_id[] = { + { "sd2405al" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(i2c, sd2405al_id); + +static const __maybe_unused struct of_device_id sd2405al_of_match[] = { + { .compatible = "dfrobot,sd2405al" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, sd2405al_of_match); + +static struct i2c_driver sd2405al_driver = { + .driver = { + .name = "sd2405al", + .of_match_table = of_match_ptr(sd2405al_of_match), + }, + .probe = sd2405al_probe, + .id_table = sd2405al_id, +}; + +module_i2c_driver(sd2405al_driver); + +MODULE_AUTHOR("Tóth János "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SD2405AL RTC driver"); From 0bb7e903e8a820fd5fa18ebc6820d4dfbfcaeae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B3th=20J=C3=A1nos?= Date: Fri, 30 Aug 2024 10:36:40 +0200 Subject: [PATCH 09/17] dt-bindings: rtc: Add support for SD2405AL. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the necessary documentation for SD2405AL. Acked-by: Conor Dooley Signed-off-by: Tóth János Link: https://lore.kernel.org/r/20240830-rtc-sd2405al-v7-2-2f7102621b1d@gmail.com Signed-off-by: Alexandre Belloni --- Documentation/devicetree/bindings/rtc/trivial-rtc.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml index fffd759c603f..dae594626b2e 100644 --- a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml @@ -38,6 +38,8 @@ properties: - dallas,ds1672 # Extremely Accurate I²C RTC with Integrated Crystal and SRAM - dallas,ds3232 + # SD2405AL Real-Time Clock + - dfrobot,sd2405al # EM Microelectronic EM3027 RTC - emmicro,em3027 # I2C-BUS INTERFACE REAL TIME CLOCK MODULE From 864f40bfdc5a7863ea4503e8893ee96f62f96522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B3th=20J=C3=A1nos?= Date: Fri, 30 Aug 2024 10:36:41 +0200 Subject: [PATCH 10/17] dt-bindings: vendor-prefixes: Add DFRobot. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Link: https://www.dfrobot.com/about-us Acked-by: Conor Dooley Signed-off-by: Tóth János Link: https://lore.kernel.org/r/20240830-rtc-sd2405al-v7-3-2f7102621b1d@gmail.com Signed-off-by: Alexandre Belloni --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index a70ce43b3dc0..bd8b279a5152 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -368,6 +368,8 @@ patternProperties: description: Devantech, Ltd. "^dfi,.*": description: DFI Inc. + "^dfrobot,.*": + description: DFRobot Corporation "^dh,.*": description: DH electronics GmbH "^difrnce,.*": From 0cfd26cc06ff353e9b59d0ee57a4950df2abd616 Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Tue, 10 Sep 2024 18:44:31 -0500 Subject: [PATCH 11/17] dt-bindings: rtc: Drop non-trivial duplicate compatibles Several compatibles documented in trivial-rtc.yaml are documented elsewhere and are not trivial, so drop them. Signed-off-by: Rob Herring (Arm) Acked-by: Conor Dooley Link: https://lore.kernel.org/r/20240910234431.1043923-1-robh@kernel.org Signed-off-by: Alexandre Belloni --- Documentation/devicetree/bindings/rtc/trivial-rtc.yaml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml index dae594626b2e..7330a7200831 100644 --- a/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/trivial-rtc.yaml @@ -45,7 +45,6 @@ properties: # I2C-BUS INTERFACE REAL TIME CLOCK MODULE - epson,rx8010 # I2C-BUS INTERFACE REAL TIME CLOCK MODULE - - epson,rx8025 - epson,rx8035 # I2C-BUS INTERFACE REAL TIME CLOCK MODULE with Battery Backed RAM - epson,rx8111 @@ -54,10 +53,6 @@ properties: - epson,rx8581 # Android Goldfish Real-time Clock - google,goldfish-rtc - # Intersil ISL1208 Low Power RTC with Battery Backed SRAM - - isil,isl1208 - # Intersil ISL1218 Low Power RTC with Battery Backed SRAM - - isil,isl1218 # Mvebu Real-time Clock - marvell,orion-rtc # Maxim DS1742/DS1743 Real-time Clock @@ -70,8 +65,6 @@ properties: - microcrystal,rv8523 # NXP LPC32xx SoC Real-time Clock - nxp,lpc3220-rtc - # Real-time Clock Module - - pericom,pt7c4338 # I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC - ricoh,r2025sd # I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC From 80bf13c07c07c43cc959b253305b64922cb20a92 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Tue, 30 Jul 2024 21:49:05 +0200 Subject: [PATCH 12/17] rtc: sun6i: disable automatic clock input switching The V3(s) will detect a valid external low frequency clock and if it is not present will automatically switch to the internal one. This might hide bugs and (hardware) configuration errors. It's even worse because the internal RTC runs significantly slower (32.000Hz vs 32.768Hz). Fortunately for us, the V3(s) has an (undocumented) bypass of this switching and the driver already supports it by setting the .has_auto_swt flag. Signed-off-by: Michael Walle Acked-by: Chen-Yu Tsai Link: https://lore.kernel.org/r/20240730194905.2587202-1-mwalle@kernel.org Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sun6i.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c index 8e0c66906103..e681c1745866 100644 --- a/drivers/rtc/rtc-sun6i.c +++ b/drivers/rtc/rtc-sun6i.c @@ -402,6 +402,7 @@ CLK_OF_DECLARE_DRIVER(sun8i_r40_rtc_clk, "allwinner,sun8i-r40-rtc", static const struct sun6i_rtc_clk_data sun8i_v3_rtc_data = { .rc_osc_rate = 32000, .has_out_clk = 1, + .has_auto_swt = 1, }; static void __init sun8i_v3_rtc_clk_init(struct device_node *node) From 73580e2ee6adfb40276bd420da3bb1abae204e10 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 25 Aug 2024 20:31:03 +0200 Subject: [PATCH 13/17] rtc: at91sam9: fix OF node leak in probe() error path Driver is leaking an OF node reference obtained from of_parse_phandle_with_fixed_args(). Fixes: 43e112bb3dea ("rtc: at91sam9: make use of syscon/regmap to access GPBR registers") Cc: stable@vger.kernel.org Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240825183103.102904-1-krzysztof.kozlowski@linaro.org Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-at91sam9.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index f93bee96e362..993c0878fb66 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -368,6 +368,7 @@ static int at91_rtc_probe(struct platform_device *pdev) return ret; rtc->gpbr = syscon_node_to_regmap(args.np); + of_node_put(args.np); rtc->gpbr_offset = args.args[0]; if (IS_ERR(rtc->gpbr)) { dev_err(&pdev->dev, "failed to retrieve gpbr regmap, aborting.\n"); From 60a06efc56d7d336d13fae58f9e90c8a4e21619e Mon Sep 17 00:00:00 2001 From: Abhishek Tamboli Date: Fri, 9 Aug 2024 21:26:31 +0530 Subject: [PATCH 14/17] rtc: m48t59: Remove division condition with direct comparison Replace 'year / 100' with a direct comparison 'year >= 100' in m48t59_rtc_set_time() function. Improve the code clarity and eliminate division overhead. Fix the following smatch warning: drivers/rtc/rtc-m48t59.c:135 m48t59_rtc_set_time() warn: replace divide condition 'year / 100' with 'year >= 100' Signed-off-by: Abhishek Tamboli Link: https://lore.kernel.org/r/20240809155631.548044-1-abhishektamboli9@gmail.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m48t59.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index f0f6b9b6daec..cd2ca49805d8 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c @@ -132,7 +132,7 @@ static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm) M48T59_WRITE((bin2bcd(tm->tm_mon + 1) & 0x1F), M48T59_MONTH); M48T59_WRITE(bin2bcd(year % 100), M48T59_YEAR); - if (pdata->type == M48T59RTC_TYPE_M48T59 && (year / 100)) + if (pdata->type == M48T59RTC_TYPE_M48T59 && (year >= 100)) val = (M48T59_WDAY_CEB | M48T59_WDAY_CB); val |= (bin2bcd(tm->tm_wday) & 0x07); M48T59_WRITE(val, M48T59_WDAY); From 4015580e983daa699d7e1693328dd81f0e295589 Mon Sep 17 00:00:00 2001 From: Karthikeyan Krishnasamy Date: Thu, 12 Sep 2024 19:54:48 +0530 Subject: [PATCH 15/17] dt-bindings: rtc: microcrystal,rv3028: add #clock-cells property RV3028 RTC has a clock out features, the clk out can be controlled using clkout register, to consume the clock out from rv3028 '#clock-cells' property is added. Acked-by: Conor Dooley Signed-off-by: Karthikeyan Krishnasamy Acked-by: Alexandre Belloni Link: https://lore.kernel.org/r/20240912142451.2952633-4-karthikeyan@linumiz.com Signed-off-by: Alexandre Belloni --- Documentation/devicetree/bindings/rtc/microcrystal,rv3028.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/rtc/microcrystal,rv3028.yaml b/Documentation/devicetree/bindings/rtc/microcrystal,rv3028.yaml index 5ade5dfad048..cda8ad7c1203 100644 --- a/Documentation/devicetree/bindings/rtc/microcrystal,rv3028.yaml +++ b/Documentation/devicetree/bindings/rtc/microcrystal,rv3028.yaml @@ -22,6 +22,9 @@ properties: interrupts: maxItems: 1 + "#clock-cells": + const: 0 + trickle-resistor-ohms: enum: - 3000 From b242650dfa17d8591d92e8e151438d1f8e54997a Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Thu, 12 Sep 2024 00:48:36 +0200 Subject: [PATCH 16/17] rtc: m48t59: set range The m48t59 leap year calculation will fail in 2100 Link: https://lore.kernel.org/r/20240911224836.1571831-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m48t59.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index cd2ca49805d8..5d30ce8e13ca 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c @@ -458,6 +458,8 @@ static int m48t59_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, m48t59); m48t59->rtc->ops = &m48t59_rtc_ops; + m48t59->rtc->range_min = RTC_TIMESTAMP_BEGIN_1900; + m48t59->rtc->range_max = RTC_TIMESTAMP_END_2099; nvmem_cfg.size = pdata->offset; ret = devm_rtc_nvmem_register(m48t59->rtc, &nvmem_cfg); From 690286214916f32d75de2667ec0fcfa9c3f4eefb Mon Sep 17 00:00:00 2001 From: Andreas Kemnade Date: Wed, 18 Sep 2024 23:21:59 +0200 Subject: [PATCH 17/17] rtc: rc5t619: use proper module tables Avoid requiring MODULE_ALIASES by declaring proper device id tables. Signed-off-by: Andreas Kemnade Link: https://lore.kernel.org/r/20240918212159.1191637-1-andreas@kemnade.info Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rc5t619.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-rc5t619.c b/drivers/rtc/rtc-rc5t619.c index e73102a39f1b..711f62eecd79 100644 --- a/drivers/rtc/rtc-rc5t619.c +++ b/drivers/rtc/rtc-rc5t619.c @@ -429,14 +429,23 @@ static int rc5t619_rtc_probe(struct platform_device *pdev) return devm_rtc_register_device(rtc->rtc); } +static const struct platform_device_id rc5t619_rtc_id[] = { + { + .name = "rc5t619-rtc", + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(platform, rc5t619_rtc_id); + static struct platform_driver rc5t619_rtc_driver = { .driver = { .name = "rc5t619-rtc", }, .probe = rc5t619_rtc_probe, + .id_table = rc5t619_rtc_id, }; - module_platform_driver(rc5t619_rtc_driver); -MODULE_ALIAS("platform:rc5t619-rtc"); + MODULE_DESCRIPTION("RICOH RC5T619 RTC driver"); MODULE_LICENSE("GPL");