NvBool NvOdmOsSemaphoreWaitTimeout(NvOdmOsSemaphoreHandle semaphore, NvU32 msec) { NvError err; err = NvOsSemaphoreWaitTimeout((NvOsSemaphoreHandle)semaphore, msec); if (err == NvError_Timeout) { return NV_FALSE; } return NV_TRUE; }
void NvBatteryEventHandlerThread(void *args) { NvU8 BatteryState = 0, BatteryEvent = 0; NvBool suspend_flag; for (;;) { NvOsSemaphoreWaitTimeout(batt_dev->hOdmSemaphore, batt_dev->batt_status_poll_period); if (batt_dev->exitThread) break; if (!batt_dev->hOdmBattDev) continue; NvOsMutexLock(batt_dev->hBattEventMutex); suspend_flag = batt_dev->inSuspend; NvOsMutexUnlock(batt_dev->hBattEventMutex); if (suspend_flag) continue; pr_info("\tBATTERY: polling battery information! --->>>\n"); NvOdmBatteryGetBatteryStatus(batt_dev->hOdmBattDev, NvOdmBatteryInst_Main, &BatteryState); NvOdmBatteryGetEvent(batt_dev->hOdmBattDev, &BatteryEvent); if ((BatteryState == NVODM_BATTERY_STATUS_UNKNOWN) || (BatteryEvent == NvOdmBatteryEventType_Num)) { /* Do nothing */ } else { if (BatteryEvent & NvOdmBatteryEventType_RemainingCapacityAlarm) { if (BatteryState == (NVODM_BATTERY_STATUS_CRITICAL | NVODM_BATTERY_STATUS_VERY_CRITICAL | NVODM_BATTERY_STATUS_DISCHARGING)) { pr_info("nvec_battery:calling kernel_power_off...\n"); kernel_power_off(); } } else { /* Update the battery and power supply info for other events */ power_supply_changed(&tegra_power_supplies[NvCharger_Type_Battery]); //power_supply_changed(&tegra_power_supplies[NvCharger_Type_USB]); // power_supply_changed(&tegra_power_supplies[NvCharger_Type_AC]); } } } }
/* * Always use one EcPrivThread-global clock/time for timeout calculations */ static void NvEcPrivThread( void * args ) { NvEcPrivState *ec = (NvEcPrivState *)args; NvU32 t, timeout = NV_WAIT_INFINITE; NvU32 tStatus = 0; NvError wait = NvSuccess; NvError e; while( !ec->exitThread ) { #if ENABLE_TIMEOUT if ( timeout ) wait = NvOsSemaphoreWaitTimeout( ec->sema, timeout ); #else NvOsSemaphoreWait( ec->sema ); wait = NvSuccess; #endif #if ENABLE_FAKE_TIMEOUT_TEST t = ec->lastTime + 0x200; #else t = NvOsGetTimeMS(); #endif ec->timeDiff = t - ec->lastTime; ec->lastTime = t; // update last timer value if ( !timeout || (wait == NvError_Timeout) ) { // timeout case NvEcPrivProcessTimeout( ec ); } // look for any pending packets tStatus = NvEcTransportQueryStatus( ec->transport ); e = NvSuccess; /* * SEND_COMPLETE event must be processed before RESPONSE_RECEIVE_COMPLETE * event as SEND_COMPLETE event schedules timeout for RESPONSE_RECEIVE event. */ if ( tStatus & (NVEC_TRANSPORT_STATUS_SEND_COMPLETE | NVEC_TRANSPORT_STATUS_SEND_ERROR) ) { NvEcPrivProcessPostSendRequest( ec, (tStatus & NVEC_TRANSPORT_STATUS_SEND_COMPLETE) ? NvSuccess : NvError_I2cWriteFailed ); } if ( tStatus & (NVEC_TRANSPORT_STATUS_RESPONSE_RECEIVE_ERROR | NVEC_TRANSPORT_STATUS_RESPONSE_RECEIVE_COMPLETE) ) { e = (tStatus & NVEC_TRANSPORT_STATUS_RESPONSE_RECEIVE_COMPLETE) ? NvSuccess : NvError_I2cReadFailed; e = NvEcPrivProcessReceiveResponse( ec, e ); // return ignored. Could be spurious response. } if ( tStatus & (NVEC_TRANSPORT_STATUS_EVENT_RECEIVE_ERROR | NVEC_TRANSPORT_STATUS_EVENT_RECEIVE_COMPLETE) ) { e = (tStatus & NVEC_TRANSPORT_STATUS_EVENT_RECEIVE_COMPLETE) ? NvSuccess : NvError_I2cReadFailed; e = NvEcPrivProcessReceiveEvent( ec, e ); // return ignored. Could be spurious event. } if ( tStatus & NVEC_TRANSPORT_STATUS_EVENT_PACKET_MAX_NACK ) { // signal the ping thread to send a ping command since max // number of nacks have been sent to the EC if (ec->hPingSema) { NvOsSemaphoreSignal(ec->hPingSema); } } // send request whenever possible if ( (ec->timeout[NVEC_IDX_REQUEST] == NV_WAIT_INFINITE) && (ec->EnterLowPowerState == NV_FALSE) ) NvEcPrivProcessSendRequest( ec ); #if ENABLE_TIMEOUT timeout = NvEcPrivUpdateActualTimeout( ec ); #endif if (ec->EnterLowPowerState) { // This code assumes that EC is already in kept in sleep mode by // either shim or top level code. And there will not be any activity // going on SM bus. if (ec->timeout[NVEC_IDX_REQUEST] != NV_WAIT_INFINITE) { NvOsDebugPrintf("\r\nNvEc has active requests during suspend. " "It shouldn't have. check it."); } // No active request is pending. Enter into low power state. // Signal power suspend API to enter into suspend mode. NvOsSemaphoreSignal(ec->LowPowerEntrySema); // Wait till power resume API signals resume operation. NvOsSemaphoreWait(ec->LowPowerExitSema); // Update the timeouts for the active responses, which are scheduled // to receive before system entering into suspend. #if ENABLE_TIMEOUT NvEcPrivResetActiveRequestResponseTimeouts( ec ); timeout = NvEcPrivUpdateActualTimeout( ec ); #endif // ENABLE_TIMEOUT } } }