in rtc-omap.c [726:911]
static int omap_rtc_probe(struct platform_device *pdev)
{
struct omap_rtc *rtc;
u8 reg, mask, new_ctrl;
const struct platform_device_id *id_entry;
const struct of_device_id *of_id;
int ret;
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
if (!rtc)
return -ENOMEM;
of_id = of_match_device(omap_rtc_of_match, &pdev->dev);
if (of_id) {
rtc->type = of_id->data;
rtc->is_pmic_controller = rtc->type->has_pmic_mode &&
of_device_is_system_power_controller(pdev->dev.of_node);
} else {
id_entry = platform_get_device_id(pdev);
rtc->type = (void *)id_entry->driver_data;
}
rtc->irq_timer = platform_get_irq(pdev, 0);
if (rtc->irq_timer <= 0)
return -ENOENT;
rtc->irq_alarm = platform_get_irq(pdev, 1);
if (rtc->irq_alarm <= 0)
return -ENOENT;
rtc->clk = devm_clk_get(&pdev->dev, "ext-clk");
if (!IS_ERR(rtc->clk))
rtc->has_ext_clk = true;
else
rtc->clk = devm_clk_get(&pdev->dev, "int-clk");
if (!IS_ERR(rtc->clk))
clk_prepare_enable(rtc->clk);
rtc->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtc->base)) {
clk_disable_unprepare(rtc->clk);
return PTR_ERR(rtc->base);
}
platform_set_drvdata(pdev, rtc);
/* Enable the clock/module so that we can access the registers */
pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
rtc->type->unlock(rtc);
/*
* disable interrupts
*
* NOTE: ALARM2 is not cleared on AM3352 if rtc_write (writeb) is used
*/
rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG, 0);
/* enable RTC functional clock */
if (rtc->type->has_32kclk_en) {
reg = rtc_read(rtc, OMAP_RTC_OSC_REG);
rtc_write(rtc, OMAP_RTC_OSC_REG, reg | OMAP_RTC_OSC_32KCLK_EN);
}
/* clear old status */
reg = rtc_read(rtc, OMAP_RTC_STATUS_REG);
mask = OMAP_RTC_STATUS_ALARM;
if (rtc->type->has_pmic_mode)
mask |= OMAP_RTC_STATUS_ALARM2;
if (rtc->type->has_power_up_reset) {
mask |= OMAP_RTC_STATUS_POWER_UP;
if (reg & OMAP_RTC_STATUS_POWER_UP)
dev_info(&pdev->dev, "RTC power up reset detected\n");
}
if (reg & mask)
rtc_write(rtc, OMAP_RTC_STATUS_REG, reg & mask);
/* On boards with split power, RTC_ON_NOFF won't reset the RTC */
reg = rtc_read(rtc, OMAP_RTC_CTRL_REG);
if (reg & OMAP_RTC_CTRL_STOP)
dev_info(&pdev->dev, "already running\n");
/* force to 24 hour mode */
new_ctrl = reg & (OMAP_RTC_CTRL_SPLIT | OMAP_RTC_CTRL_AUTO_COMP);
new_ctrl |= OMAP_RTC_CTRL_STOP;
/*
* BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE:
*
* - Device wake-up capability setting should come through chip
* init logic. OMAP1 boards should initialize the "wakeup capable"
* flag in the platform device if the board is wired right for
* being woken up by RTC alarm. For OMAP-L138, this capability
* is built into the SoC by the "Deep Sleep" capability.
*
* - Boards wired so RTC_ON_nOFF is used as the reset signal,
* rather than nPWRON_RESET, should forcibly enable split
* power mode. (Some chip errata report that RTC_CTRL_SPLIT
* is write-only, and always reads as zero...)
*/
if (new_ctrl & OMAP_RTC_CTRL_SPLIT)
dev_info(&pdev->dev, "split power mode\n");
if (reg != new_ctrl)
rtc_write(rtc, OMAP_RTC_CTRL_REG, new_ctrl);
/*
* If we have the external clock then switch to it so we can keep
* ticking across suspend.
*/
if (rtc->has_ext_clk) {
reg = rtc_read(rtc, OMAP_RTC_OSC_REG);
reg &= ~OMAP_RTC_OSC_OSC32K_GZ_DISABLE;
reg |= OMAP_RTC_OSC_32KCLK_EN | OMAP_RTC_OSC_SEL_32KCLK_SRC;
rtc_write(rtc, OMAP_RTC_OSC_REG, reg);
}
rtc->type->lock(rtc);
device_init_wakeup(&pdev->dev, true);
rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc->rtc)) {
ret = PTR_ERR(rtc->rtc);
goto err;
}
rtc->rtc->ops = &omap_rtc_ops;
rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
rtc->rtc->range_max = RTC_TIMESTAMP_END_2099;
omap_rtc_nvmem_config.priv = rtc;
/* handle periodic and alarm irqs */
ret = devm_request_irq(&pdev->dev, rtc->irq_timer, rtc_irq, 0,
dev_name(&rtc->rtc->dev), rtc);
if (ret)
goto err;
if (rtc->irq_timer != rtc->irq_alarm) {
ret = devm_request_irq(&pdev->dev, rtc->irq_alarm, rtc_irq, 0,
dev_name(&rtc->rtc->dev), rtc);
if (ret)
goto err;
}
/* Support ext_wakeup pinconf */
rtc_pinctrl_desc.name = dev_name(&pdev->dev);
rtc->pctldev = devm_pinctrl_register(&pdev->dev, &rtc_pinctrl_desc, rtc);
if (IS_ERR(rtc->pctldev)) {
dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
ret = PTR_ERR(rtc->pctldev);
goto err;
}
ret = devm_rtc_register_device(rtc->rtc);
if (ret)
goto err;
devm_rtc_nvmem_register(rtc->rtc, &omap_rtc_nvmem_config);
if (rtc->is_pmic_controller) {
if (!pm_power_off) {
omap_rtc_power_off_rtc = rtc;
pm_power_off = omap_rtc_power_off;
}
}
return 0;
err:
clk_disable_unprepare(rtc->clk);
device_init_wakeup(&pdev->dev, false);
rtc->type->lock(rtc);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return ret;
}