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; }
NvError NvRmPrivPmuInit(NvRmDeviceHandle hRmDevice) { NvError e; ExecPlatform env; NvOdmPmuProperty PmuProperty; NV_ASSERT(hRmDevice); env = NvRmPrivGetExecPlatform(hRmDevice); NvOsMemset(&s_Pmu, 0, sizeof(NvRmPmu)); s_PmuSupportedEnv = NV_FALSE; if (env == ExecPlatform_Soc) { // Set supported environment flag s_PmuSupportedEnv = NV_TRUE; // Create the PMU mutex, semaphore, interrupt handler thread, // register PMU interrupt, and get ODM PMU handle NV_CHECK_ERROR_CLEANUP(NvOsMutexCreate(&s_Pmu.hMutex)); NV_CHECK_ERROR_CLEANUP(NvOsSemaphoreCreate(&s_Pmu.hSemaphore, 0)); if (NvOdmQueryGetPmuProperty(&PmuProperty) && PmuProperty.IrqConnected) { if (hRmDevice->ChipId.Id >= 0x20) NvRmPrivAp20SetPmuIrqPolarity( hRmDevice, PmuProperty.IrqPolarity); else NV_ASSERT(PmuProperty.IrqPolarity == NvOdmInterruptPolarity_Low); { NvOsInterruptHandler hPmuIsr = PmuIsr; NvU32 PmuExtIrq = NvRmGetIrqForLogicalInterrupt( hRmDevice, NVRM_MODULE_ID(NvRmPrivModuleID_PmuExt, 0), 0); NV_CHECK_ERROR_CLEANUP(NvRmInterruptRegister(hRmDevice, 1, &PmuExtIrq, &hPmuIsr, &s_Pmu, &s_Pmu.hInterrupt, NV_FALSE)); } } if(!NvOdmPmuDeviceOpen(&s_Pmu.hOdmPmu)) { e = NvError_NotInitialized; goto fail; } NV_CHECK_ERROR_CLEANUP(NvOsThreadCreate(PmuThread, &s_Pmu, &s_Pmu.hThread)); NvRmPrivIoPowerControlInit(hRmDevice); NvRmPrivCoreVoltageInit(hRmDevice); } return NvSuccess; fail: NvRmPrivPmuDeinit(hRmDevice); return e; }