Beispiel #1
0
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
}