in rtc-mxc.c [302:413]
static int mxc_rtc_probe(struct platform_device *pdev)
{
struct rtc_device *rtc;
struct rtc_plat_data *pdata = NULL;
u32 reg;
unsigned long rate;
int ret;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
pdata->devtype = (enum imx_rtc_type)of_device_get_match_data(&pdev->dev);
pdata->ioaddr = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pdata->ioaddr))
return PTR_ERR(pdata->ioaddr);
rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
pdata->rtc = rtc;
rtc->ops = &mxc_rtc_ops;
if (is_imx1_rtc(pdata)) {
struct rtc_time tm;
/* 9bit days + hours minutes seconds */
rtc->range_max = (1 << 9) * 86400 - 1;
/*
* Set the start date as beginning of the current year. This can
* be overridden using device tree.
*/
rtc_time64_to_tm(ktime_get_real_seconds(), &tm);
rtc->start_secs = mktime64(tm.tm_year, 1, 1, 0, 0, 0);
rtc->set_start_time = true;
} else {
/* 16bit days + hours minutes seconds */
rtc->range_max = (1 << 16) * 86400ULL - 1;
}
pdata->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
if (IS_ERR(pdata->clk_ipg)) {
dev_err(&pdev->dev, "unable to get ipg clock!\n");
return PTR_ERR(pdata->clk_ipg);
}
ret = clk_prepare_enable(pdata->clk_ipg);
if (ret)
return ret;
pdata->clk_ref = devm_clk_get(&pdev->dev, "ref");
if (IS_ERR(pdata->clk_ref)) {
clk_disable_unprepare(pdata->clk_ipg);
dev_err(&pdev->dev, "unable to get ref clock!\n");
return PTR_ERR(pdata->clk_ref);
}
ret = clk_prepare_enable(pdata->clk_ref);
if (ret) {
clk_disable_unprepare(pdata->clk_ipg);
return ret;
}
ret = devm_add_action_or_reset(&pdev->dev, mxc_rtc_action, pdata);
if (ret)
return ret;
rate = clk_get_rate(pdata->clk_ref);
if (rate == 32768)
reg = RTC_INPUT_CLK_32768HZ;
else if (rate == 32000)
reg = RTC_INPUT_CLK_32000HZ;
else if (rate == 38400)
reg = RTC_INPUT_CLK_38400HZ;
else {
dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", rate);
return -EINVAL;
}
reg |= RTC_ENABLE_BIT;
writew(reg, (pdata->ioaddr + RTC_RTCCTL));
if (((readw(pdata->ioaddr + RTC_RTCCTL)) & RTC_ENABLE_BIT) == 0) {
dev_err(&pdev->dev, "hardware module can't be enabled!\n");
return -EIO;
}
platform_set_drvdata(pdev, pdata);
/* Configure and enable the RTC */
pdata->irq = platform_get_irq(pdev, 0);
if (pdata->irq >= 0 &&
devm_request_irq(&pdev->dev, pdata->irq, mxc_rtc_interrupt,
IRQF_SHARED, pdev->name, pdev) < 0) {
dev_warn(&pdev->dev, "interrupt not available.\n");
pdata->irq = -1;
}
if (pdata->irq >= 0) {
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 = devm_rtc_register_device(rtc);
return ret;
}