#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;
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[] = {
{
struct stm32_rtc *rtc;
struct resource *res;
- const struct of_device_id *match;
int ret;
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
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;
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
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);
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);