in rtc-mxc_v2.c [278:361]
static int mxc_rtc_probe(struct platform_device *pdev)
{
struct mxc_rtc_data *pdata;
void __iomem *ioaddr;
int ret = 0;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
pdata->ioaddr = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pdata->ioaddr))
return PTR_ERR(pdata->ioaddr);
ioaddr = pdata->ioaddr;
pdata->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(pdata->clk)) {
dev_err(&pdev->dev, "unable to get rtc clock!\n");
return PTR_ERR(pdata->clk);
}
spin_lock_init(&pdata->lock);
pdata->irq = platform_get_irq(pdev, 0);
if (pdata->irq < 0)
return pdata->irq;
device_init_wakeup(&pdev->dev, 1);
ret = dev_pm_set_wake_irq(&pdev->dev, pdata->irq);
if (ret)
dev_err(&pdev->dev, "failed to enable irq wake\n");
ret = clk_prepare_enable(pdata->clk);
if (ret)
return ret;
/* initialize glitch detect */
writel(SRTC_LPPDR_INIT, ioaddr + SRTC_LPPDR);
/* clear lp interrupt status */
writel(0xFFFFFFFF, ioaddr + SRTC_LPSR);
/* move out of init state */
writel((SRTC_LPCR_IE | SRTC_LPCR_NSA), ioaddr + SRTC_LPCR);
ret = mxc_rtc_wait_for_flag(ioaddr + SRTC_LPSR, SRTC_LPSR_IES);
if (ret) {
dev_err(&pdev->dev, "Timeout waiting for SRTC_LPSR_IES\n");
clk_disable_unprepare(pdata->clk);
return ret;
}
/* move out of non-valid state */
writel((SRTC_LPCR_IE | SRTC_LPCR_NVE | SRTC_LPCR_NSA |
SRTC_LPCR_EN_LP), ioaddr + SRTC_LPCR);
ret = mxc_rtc_wait_for_flag(ioaddr + SRTC_LPSR, SRTC_LPSR_NVES);
if (ret) {
dev_err(&pdev->dev, "Timeout waiting for SRTC_LPSR_NVES\n");
clk_disable_unprepare(pdata->clk);
return ret;
}
pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(pdata->rtc))
return PTR_ERR(pdata->rtc);
pdata->rtc->ops = &mxc_rtc_ops;
pdata->rtc->range_max = U32_MAX;
clk_disable(pdata->clk);
platform_set_drvdata(pdev, pdata);
ret =
devm_request_irq(&pdev->dev, pdata->irq, mxc_rtc_interrupt, 0,
pdev->name, &pdev->dev);
if (ret < 0) {
dev_err(&pdev->dev, "interrupt not available.\n");
clk_unprepare(pdata->clk);
return ret;
}
ret = devm_rtc_register_device(pdata->rtc);
if (ret < 0)
clk_unprepare(pdata->clk);
return ret;
}