Exemplo n.º 1
0
static int tegra_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
	NvU32 now;
#if SYNC_EXTERNAL_RTC_TO_INTERNAL_RTC
        struct rtc_time iner_rtc_tm;
        unsigned long iner_now;
        int ret = 0;
#endif

	if (hPmu == NULL)
		return -1;

	if (!NvOdmPmuReadRtc(hPmu, &now)) {
		printk("NvOdmPmuReadRtc failed\n");
		return -1;
	}

	rtc_time_to_tm(now, tm);

#if SYNC_EXTERNAL_RTC_TO_INTERNAL_RTC
        /* Read internal RTC time, if there are different, set internal rtc with external rtc time */
        ret = internal_tegra_rtc_read_time(&iner_rtc_tm);
        if(ret) return ret;
        
        ret = rtc_tm_to_time(&iner_rtc_tm, &iner_now);
        if((ret == 0) && (now != iner_now)) {
                ret = internal_tegra_rtc_set_time(tm); /* Set internal rtc with external rtc time */
        }

        return ret;
#else
	return 0;
#endif
}
Exemplo n.º 2
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;
}
static int tegra_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
{
	struct rtc_time *time = &wkalrm->time;
	NvU32 now;
	NvU32 alarm_sec;
	struct rtc_time now_time;

	printk("%s(): wkalrm->enabled=%d\n", __func__, wkalrm?wkalrm->enabled:-1);

	pr_debug("wkalrm->enabled = %d\n", wkalrm->enabled);
        if (wkalrm->enabled == 0) {
                if(!NvOdmPmuWriteAlarm(hPmu, 0))
                        return -EINVAL;
                return 0;
        }

	if (!NvOdmPmuReadRtc(hPmu, &now)) {
		pr_debug("NvOdmPmuReadRtc failed\n");
		return -1;
	}

	rtc_time_to_tm(now, &now_time);
	pr_debug( "read  now_time %02d:%02d:%02d %02d/%02d/%04d\n",
		now_time.tm_hour, now_time.tm_min, now_time.tm_sec,
		now_time.tm_mon + 1, now_time.tm_mday, now_time.tm_year + 1900);

	pr_debug("write alarm_time %02d:%02d:%02d %02d/%02d/%04d\n",
		time->tm_hour, time->tm_min, time->tm_sec,
		time->tm_mon+1, time->tm_mday, time->tm_yday+1900);

	alarm_sec = (NvU32)mktime(now_time.tm_year + 1900, time->tm_mon+1, time->tm_mday,
				time->tm_hour, time->tm_min, time->tm_sec);
	if (alarm_sec < now)
		alarm_sec = (NvU32)mktime(now_time.tm_year + 1901, time->tm_mon+1, time->tm_mday,
				time->tm_hour, time->tm_min, time->tm_sec);

	pr_debug("alarm_sec = %u\n", alarm_sec);

	if(!NvOdmPmuWriteAlarm(hPmu, alarm_sec-now))
		return -EINVAL;

#if SYNC_EXTERNAL_RTC_TO_INTERNAL_RTC

        return internal_tegra_rtc_set_alarm(wkalrm);
#else

	pr_info("%s():enter.\n", __func__);

	/* Alarm set */
	events |= RTC_IRQF | RTC_AF;

	if (rtc)
		rtc_update_irq(rtc, 1, events);

	return NV_TRUE;
#endif
}
static int tegra_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
	NvU32 now;

	if (hPmu == NULL)
		return -1;

	if (!NvOdmPmuReadRtc(hPmu, &now)) {
		printk("NvOdmPmuReadRtc failed\n");
		return -1;
	}

	rtc_time_to_tm(now, tm);
	return 0;
}
Exemplo n.º 5
0
NvBool
NvRmPmuReadRtc(
    NvRmDeviceHandle hRmDevice,
    NvU32* pCount)
{
    NvBool ReturnStatus = NV_FALSE;

    if (!s_PmuSupportedEnv)
        return NV_FALSE;

    NV_ASSERT(s_Pmu.hMutex);
    NvOsMutexLock(s_Pmu.hMutex);
    ReturnStatus = NvOdmPmuReadRtc(s_Pmu.hOdmPmu, pCount);
    NvOsMutexUnlock(s_Pmu.hMutex);
    return ReturnStatus;
}
Exemplo n.º 6
0
static int tegra_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
{
	struct rtc_time *time = &wkalrm->time;
	NvU32 now;
	NvU32 alarm_sec;
	struct rtc_time now_time;

	pr_debug("wkalrm->enabled = %d\n", wkalrm->enabled);
	if (wkalrm->enabled == 0)
		return 0;

	if (!NvOdmPmuReadRtc(hPmu, &now)) {
		pr_debug("NvOdmPmuReadRtc failed\n");
		return -1;
	}

	rtc_time_to_tm(now, &now_time);
	pr_debug( "read  now_time %02d:%02d:%02d %02d/%02d/%04d\n",
		now_time.tm_hour, now_time.tm_min, now_time.tm_sec,
		now_time.tm_mon + 1, now_time.tm_mday, now_time.tm_year + 1900);

	pr_debug("write alarm_time %02d:%02d:%02d %02d/%02d/%04d\n",
		time->tm_hour, time->tm_min, time->tm_sec,
		time->tm_mon+1, time->tm_mday, time->tm_yday+1900);

	alarm_sec = (NvU32)mktime(now_time.tm_year + 1900, time->tm_mon+1, time->tm_mday,
				time->tm_hour, time->tm_min, time->tm_sec);
	if (alarm_sec < now)
		alarm_sec = (NvU32)mktime(now_time.tm_year + 1901, time->tm_mon+1, time->tm_mday,
				time->tm_hour, time->tm_min, time->tm_sec);

	pr_debug("alarm_sec = %u\n", alarm_sec);

	if(!NvOdmPmuWriteAlarm(hPmu, alarm_sec-now))
		return -EINVAL;

#if SYNC_EXTERNAL_RTC_TO_INTERNAL_RTC
        return internal_tegra_rtc_set_alarm(wkalrm);
#else
	return 0;
#endif
}