static int __init tegra_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; NvU32 initial; if (NvOdmPmuDeviceOpen(&hPmu) == NV_FALSE) { pr_debug("%s: NvOdmPmuDeviceOpen failed\n", pdev->name); return -ENXIO; } /* if the SoCs PMU has't been properly initialized, a bogus large * value may be returned which triggers the Y2038 bug in the kernel. * work-around this issue by checking the initial value of the PMU * and then clobbering it if the value is bogus */ if (NvOdmPmuReadRtc(hPmu, &initial) && ((time_t)initial < 0)) { if(!NvOdmPmuWriteRtc(hPmu, 0)) return -EINVAL; } rtc = rtc_device_register(pdev->name, &pdev->dev, &tegra_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { pr_debug("%s: can't register RTC device, err %ld\n", pdev->name, PTR_ERR(rtc)); NvOdmPmuDeviceClose(hPmu); return -1; } platform_set_drvdata(pdev, rtc); return 0; }
NvBool NvRmPmuWriteRtc( NvRmDeviceHandle hRmDevice, NvU32 Count) { NvBool ReturnStatus = NV_FALSE; if (!s_PmuSupportedEnv) return NV_FALSE; NV_ASSERT(s_Pmu.hMutex); NvOsMutexLock(s_Pmu.hMutex); ReturnStatus = NvOdmPmuWriteRtc(s_Pmu.hOdmPmu, Count); NvOsMutexUnlock(s_Pmu.hMutex); return ReturnStatus; }
static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm) { unsigned long now; int ret; if (hPmu == NULL) return -1; ret = rtc_tm_to_time(tm, &now); if (ret != 0) return -1; if (!NvOdmPmuWriteRtc(hPmu, (NvU32)now)) { printk("NvOdmPmuWriteRtc failed\n"); return -1; } return 0; }
static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm) { unsigned long now; int ret; if (hPmu == NULL) return -1; ret = rtc_tm_to_time(tm, &now); if (ret != 0) return -1; if (!NvOdmPmuWriteRtc(hPmu, (NvU32)now)) { printk("NvOdmPmuWriteRtc failed\n"); return -1; } #if SYNC_EXTERNAL_RTC_TO_INTERNAL_RTC return internal_tegra_rtc_set_time(tm); #else return 0; #endif }