in rtc-stm32.c [692:847]
static int stm32_rtc_probe(struct platform_device *pdev)
{
struct stm32_rtc *rtc;
const struct stm32_rtc_registers *regs;
int ret;
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
if (!rtc)
return -ENOMEM;
rtc->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtc->base))
return PTR_ERR(rtc->base);
rtc->data = (struct stm32_rtc_data *)
of_device_get_match_data(&pdev->dev);
regs = &rtc->data->regs;
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);
}
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;
rtc->rtc_ck = devm_clk_get(&pdev->dev, NULL);
} else {
rtc->pclk = devm_clk_get(&pdev->dev, "pclk");
if (IS_ERR(rtc->pclk)) {
dev_err(&pdev->dev, "no pclk clock");
return PTR_ERR(rtc->pclk);
}
rtc->rtc_ck = devm_clk_get(&pdev->dev, "rtc_ck");
}
if (IS_ERR(rtc->rtc_ck)) {
dev_err(&pdev->dev, "no rtc_ck clock");
return PTR_ERR(rtc->rtc_ck);
}
if (rtc->data->has_pclk) {
ret = clk_prepare_enable(rtc->pclk);
if (ret)
return ret;
}
ret = clk_prepare_enable(rtc->rtc_ck);
if (ret)
goto err_no_rtc_ck;
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
* the calendar has been initialized or not. INITS flag is reset by a
* power-on reset (no vbat, no power-supply). It is not reset if
* rtc_ck parent clock has changed (so RTC prescalers need to be
* changed). That's why we cannot rely on this flag to know if RTC
* init has to be done.
*/
ret = stm32_rtc_init(pdev, rtc);
if (ret)
goto err;
rtc->irq_alarm = platform_get_irq(pdev, 0);
if (rtc->irq_alarm <= 0) {
ret = rtc->irq_alarm;
goto err;
}
ret = device_init_wakeup(&pdev->dev, true);
if (rtc->data->has_wakeirq) {
rtc->wakeirq_alarm = platform_get_irq(pdev, 1);
if (rtc->wakeirq_alarm > 0) {
ret = dev_pm_set_dedicated_wake_irq(&pdev->dev,
rtc->wakeirq_alarm);
} else {
ret = rtc->wakeirq_alarm;
if (rtc->wakeirq_alarm == -EPROBE_DEFER)
goto err;
}
}
if (ret)
dev_warn(&pdev->dev, "alarm can't wake up the system: %d", ret);
platform_set_drvdata(pdev, rtc);
rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
&stm32_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc_dev)) {
ret = PTR_ERR(rtc->rtc_dev);
dev_err(&pdev->dev, "rtc device registration failed, err=%d\n",
ret);
goto err;
}
/* Handle RTC alarm interrupts */
ret = devm_request_threaded_irq(&pdev->dev, rtc->irq_alarm, NULL,
stm32_rtc_alarm_irq, IRQF_ONESHOT,
pdev->name, rtc);
if (ret) {
dev_err(&pdev->dev, "IRQ%d (alarm interrupt) already claimed\n",
rtc->irq_alarm);
goto err;
}
/*
* If INITS flag is reset (calendar year field set to 0x00), calendar
* must be initialized
*/
if (!(readl_relaxed(rtc->base + regs->isr) & STM32_RTC_ISR_INITS))
dev_warn(&pdev->dev, "Date/Time must be initialized\n");
if (regs->verr != UNDEF_REG) {
u32 ver = readl_relaxed(rtc->base + regs->verr);
dev_info(&pdev->dev, "registered rev:%d.%d\n",
(ver >> STM32_RTC_VERR_MAJREV_SHIFT) & 0xF,
(ver >> STM32_RTC_VERR_MINREV_SHIFT) & 0xF);
}
return 0;
err:
clk_disable_unprepare(rtc->rtc_ck);
err_no_rtc_ck:
if (rtc->data->has_pclk)
clk_disable_unprepare(rtc->pclk);
if (rtc->data->need_dbp)
regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
dev_pm_clear_wake_irq(&pdev->dev);
device_init_wakeup(&pdev->dev, false);
return ret;
}