diff options
-rw-r--r-- | drivers/rtc/rtc-stm32.c | 59 |
1 files changed, 37 insertions, 22 deletions
diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c index 6a060780f797..de49b5b12951 100644 --- a/drivers/rtc/rtc-stm32.c +++ b/drivers/rtc/rtc-stm32.c @@ -85,23 +85,17 @@ #define RTC_WPR_2ND_KEY 0x53 #define RTC_WPR_WRONG_KEY 0xFF -/* - * RTC registers are protected against parasitic write access. - * PWR_CR_DBP bit must be set to enable write access to RTC registers. - */ -/* STM32_PWR_CR */ -#define PWR_CR 0x00 -/* STM32_PWR_CR bit field */ -#define PWR_CR_DBP BIT(8) - struct stm32_rtc_data { bool has_pclk; + bool need_dbp; }; struct stm32_rtc { struct rtc_device *rtc_dev; void __iomem *base; struct regmap *dbp; + unsigned int dbp_reg; + unsigned int dbp_mask; struct stm32_rtc_data *data; struct clk *pclk; struct clk *rtc_ck; @@ -498,10 +492,12 @@ static const struct rtc_class_ops stm32_rtc_ops = { static const struct stm32_rtc_data stm32_rtc_data = { .has_pclk = false, + .need_dbp = true, }; static const struct stm32_rtc_data stm32h7_rtc_data = { .has_pclk = true, + .need_dbp = true, }; static const struct of_device_id stm32_rtc_of_match[] = { @@ -576,7 +572,6 @@ static int stm32_rtc_probe(struct platform_device *pdev) { struct stm32_rtc *rtc; struct resource *res; - const struct of_device_id *match; int ret; rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); @@ -588,15 +583,31 @@ static int stm32_rtc_probe(struct platform_device *pdev) if (IS_ERR(rtc->base)) return PTR_ERR(rtc->base); - rtc->dbp = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, - "st,syscfg"); - if (IS_ERR(rtc->dbp)) { - dev_err(&pdev->dev, "no st,syscfg\n"); - return PTR_ERR(rtc->dbp); - } + rtc->data = (struct stm32_rtc_data *) + of_device_get_match_data(&pdev->dev); + + if (rtc->data->need_dbp) { + rtc->dbp = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, + "st,syscfg"); + if (IS_ERR(rtc->dbp)) { + dev_err(&pdev->dev, "no st,syscfg\n"); + return PTR_ERR(rtc->dbp); + } - match = of_match_device(stm32_rtc_of_match, &pdev->dev); - rtc->data = (struct stm32_rtc_data *)match->data; + ret = of_property_read_u32_index(pdev->dev.of_node, "st,syscfg", + 1, &rtc->dbp_reg); + if (ret) { + dev_err(&pdev->dev, "can't read DBP register offset\n"); + return ret; + } + + ret = of_property_read_u32_index(pdev->dev.of_node, "st,syscfg", + 2, &rtc->dbp_mask); + if (ret) { + dev_err(&pdev->dev, "can't read DBP register mask\n"); + return ret; + } + } if (!rtc->data->has_pclk) { rtc->pclk = NULL; @@ -624,7 +635,9 @@ static int stm32_rtc_probe(struct platform_device *pdev) if (ret) goto err; - regmap_update_bits(rtc->dbp, PWR_CR, PWR_CR_DBP, PWR_CR_DBP); + if (rtc->data->need_dbp) + regmap_update_bits(rtc->dbp, rtc->dbp_reg, + rtc->dbp_mask, rtc->dbp_mask); /* * After a system reset, RTC_ISR.INITS flag can be read to check if @@ -684,7 +697,8 @@ err: clk_disable_unprepare(rtc->pclk); clk_disable_unprepare(rtc->rtc_ck); - regmap_update_bits(rtc->dbp, PWR_CR, PWR_CR_DBP, 0); + if (rtc->data->need_dbp) + regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0); device_init_wakeup(&pdev->dev, false); @@ -707,8 +721,9 @@ static int stm32_rtc_remove(struct platform_device *pdev) if (rtc->data->has_pclk) clk_disable_unprepare(rtc->pclk); - /* Enable backup domain write protection */ - regmap_update_bits(rtc->dbp, PWR_CR, PWR_CR_DBP, 0); + /* Enable backup domain write protection if needed */ + if (rtc->data->need_dbp) + regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0); device_init_wakeup(&pdev->dev, false); |