static int threadRoutineVG(void *ctxt) { gckGALDEVICE device = (gckGALDEVICE) ctxt; gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER, "Starting isr Thread with extension=%p", device); for (;;) { static int down; down = down_interruptible(&device->semas[gcvCORE_VG]); if (down); /*To make gcc 4.6 happye*/ device->dataReadys[gcvCORE_VG] = gcvFALSE; if (device->killThread == gcvTRUE) { /* The daemon exits. */ while (!kthread_should_stop()) { gckOS_Delay(device->os, 1); } return 0; } gckKERNEL_Notify(device->kernels[gcvCORE_VG], gcvNOTIFY_INTERRUPT, gcvFALSE); } }
static ssize_t store_mutex (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int core, time, gpu_count, i; gceSTATUS status = gcvSTATUS_OK; gckHARDWARE hardware; /* count core numbers */ for (i = 0, gpu_count = 0; i < gcdMAX_GPU_COUNT; i++) if (galDevice->kernels[i] != gcvNULL) gpu_count++; /* scan input value and verify */ SYSFS_VERIFY_INPUT(sscanf(buf, "%d,%d", &core, &time), 2); SYSFS_VERIFY_INPUT_RANGE(core, 0, 1); SYSFS_VERIFY_INPUT_RANGE(time, 0, 1000); /* lock recMutexPower for some time */ printk("[pm_test] mutex lock %s core %d\n", (core == gcvCORE_MAJOR)?"3D":"2D", time); hardware = galDevice->kernels[core]->hardware; /* Grab the mutex. */ gcmkONERROR(gckOS_AcquireRecMutex(hardware->os, hardware->recMutexPower, gcvINFINITE)); /* sleep some time */ gcmkONERROR(gckOS_Delay(hardware->os, time)); /* Release the mutex */ gcmkONERROR(gckOS_ReleaseRecMutex(hardware->os, hardware->recMutexPower)); return count; OnError: return (ssize_t)-EINVAL; }
/* ** PM Thread Routine **/ static int threadRoutinePM(void *ctxt) { gckGALDEVICE device = (gckGALDEVICE) ctxt; gckHARDWARE hardware = device->kernels[gcvCORE_MAJOR]->hardware; gceCHIPPOWERSTATE state; for(;;) { /* wait for idle */ gcmkVERIFY_OK( gckOS_WaitSignal(device->os, hardware->powerOffSignal, gcvINFINITE)); /* We try to power off every 200 ms, until GPU is not idle */ do { if (device->killThread == gcvTRUE) { /* The daemon exits. */ while (!kthread_should_stop()) { gckOS_Delay(device->os, 1); } return 0; } gcmkVERIFY_OK( gckHARDWARE_SetPowerManagementState( hardware, gcvPOWER_OFF_TIMEOUT)); /* relax cpu 200 ms before retry */ gckOS_Delay(device->os, 200); gcmkVERIFY_OK( gckHARDWARE_QueryPowerManagementState(hardware, &state)); } while (state == gcvPOWER_IDLE); } }
/* ** PM Thread Routine **/ static int _threadRoutinePM(gckGALDEVICE Device, gckHARDWARE Hardware) { gceCHIPPOWERSTATE state; for(;;) { /* wait for idle */ gcmkVERIFY_OK( gckOS_AcquireMutex(Device->os, Hardware->powerOffSema, gcvINFINITE)); /* We try to power off every 200 ms, until GPU is not idle */ do { if (Device->killThread == gcvTRUE) { /* The daemon exits. */ while (!kthread_should_stop()) { gckOS_Delay(Device->os, 1); } return 0; } gcmkVERIFY_OK( gckHARDWARE_SetPowerManagementState( Hardware, gcvPOWER_OFF_TIMEOUT)); /* relax cpu 200 ms before retry */ gckOS_Delay(Device->os, 200); gcmkVERIFY_OK( gckHARDWARE_QueryPowerManagementState(Hardware, &state)); } while (state == gcvPOWER_IDLE); } }