/****************************************************************************
*
*    The MIT License (MIT)
*
*    Copyright (c) 2014 - 2020 Vivante Corporation
*
*    Permission is hereby granted, free of charge, to any person obtaining a
*    copy of this software and associated documentation files (the "Software"),
*    to deal in the Software without restriction, including without limitation
*    the rights to use, copy, modify, merge, publish, distribute, sublicense,
*    and/or sell copies of the Software, and to permit persons to whom the
*    Software is furnished to do so, subject to the following conditions:
*
*    The above copyright notice and this permission notice shall be included in
*    all copies or substantial portions of the Software.
*
*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
*    DEALINGS IN THE SOFTWARE.
*
*****************************************************************************
*
*    The GPL License (GPL)
*
*    Copyright (C) 2014 - 2020 Vivante Corporation
*
*    This program is free software; you can redistribute it and/or
*    modify it under the terms of the GNU General Public License
*    as published by the Free Software Foundation; either version 2
*    of the License, or (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License
*    along with this program; if not, write to the Free Software Foundation,
*    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*****************************************************************************
*
*    Note: This software is released under dual MIT and GPL licenses. A
*    recipient may use this file under the terms of either the MIT license or
*    GPL License. If you wish to use only one license not the other, you can
*    indicate your decision by deleting one of the above license notices in your
*    version of this file.
*
*****************************************************************************/


#include "gc_hal_kernel_linux.h"
#include "gc_hal_kernel_allocator.h"
#include <linux/pagemap.h>
#include <linux/seq_file.h>
#include <linux/mman.h>
#include <linux/slab.h>

#define _GC_OBJ_ZONE    gcvZONE_DEVICE

#define DEBUG_FILE          "galcore_trace"
#define PARENT_FILE         "gpu"

#define gcdDEBUG_FS_WARN    "Experimental debug entry, may be removed in future release, do NOT rely on it!\n"

static gckGALDEVICE galDevice;

extern gcTA globalTA[16];

/******************************************************************************\
******************************** Debugfs Support *******************************
\******************************************************************************/

/******************************************************************************\
***************************** DEBUG SHOW FUNCTIONS *****************************
\******************************************************************************/

int gc_info_show(struct seq_file* m, void* data)
{
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    int i = 0;
    gceCHIPMODEL chipModel = 0;
    gctUINT32 chipRevision = 0;
    gctUINT32 productID = 0;
    gctUINT32 ecoID = 0;

    if (!device)
        return -ENXIO;

    for (i = 0; i < gcdMAX_GPU_COUNT; i++)
    {
        if (device->kernels[i])
        {
            if (i == gcvCORE_VG)
            {
            }
            else
            {
                chipModel = device->kernels[i]->hardware->identity.chipModel;
                chipRevision = device->kernels[i]->hardware->identity.chipRevision;
                productID = device->kernels[i]->hardware->identity.productID;
                ecoID = device->kernels[i]->hardware->identity.ecoID;
            }

            seq_printf(m, "gpu      : %d\n", i);
            seq_printf(m, "model    : %4x\n", chipModel);
            seq_printf(m, "revision : %4x\n", chipRevision);
            seq_printf(m, "product  : %4x\n", productID);
            seq_printf(m, "eco      : %4x\n", ecoID);
            seq_printf(m, "\n");
        }
    }

    return 0;
}

int gc_clients_show(struct seq_file* m, void* data)
{
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;

    gckKERNEL kernel = _GetValidKernel(device);

    gcsDATABASE_PTR database;
    gctINT i, pid;
    char name[24];

    if (!kernel)
        return -ENXIO;

    seq_printf(m, "%-8s%s\n", "PID", "NAME");
    seq_printf(m, "------------------------\n");

    /* Acquire the database mutex. */
    gcmkVERIFY_OK(
        gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));

    /* Walk the databases. */
    for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
    {
        for (database = kernel->db->db[i];
             database != gcvNULL;
             database = database->next)
        {
            pid = database->processID;

            gcmkVERIFY_OK(gckOS_GetProcessNameByPid(pid, gcmSIZEOF(name), name));

            seq_printf(m, "%-8d%s\n", pid, name);
        }
    }

    /* Release the database mutex. */
    gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));

    /* Success. */
    return 0;
}

int gc_meminfo_show(struct seq_file* m, void* data)
{
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    gckKERNEL kernel = _GetValidKernel(device);
    gckVIDMEM memory;
    gceSTATUS status;
    gcsDATABASE_PTR database;
    gctUINT32 i;

    gctUINT32 free = 0, used = 0, total = 0, minFree = 0, maxUsed = 0;

    gcsDATABASE_COUNTERS virtualCounter = {0, 0, 0};
    gcsDATABASE_COUNTERS nonPagedCounter = {0, 0, 0};

    if (!kernel)
        return -ENXIO;

    status = gckKERNEL_GetVideoMemoryPool(kernel, gcvPOOL_SYSTEM, &memory);

    if (gcmIS_SUCCESS(status))
    {
        gcmkVERIFY_OK(
            gckOS_AcquireMutex(memory->os, memory->mutex, gcvINFINITE));

        free    = memory->freeBytes;
        minFree = memory->minFreeBytes;
        used    = memory->bytes - memory->freeBytes;
        maxUsed = memory->bytes - memory->minFreeBytes;
        total   = memory->bytes;

        gcmkVERIFY_OK(gckOS_ReleaseMutex(memory->os, memory->mutex));
    }

    seq_printf(m, "VIDEO MEMORY:\n");
    seq_printf(m, "  POOL SYSTEM:\n");
    seq_printf(m, "    Free :    %10u B\n", free);
    seq_printf(m, "    Used :    %10u B\n", used);
    seq_printf(m, "    MinFree : %10u B\n", minFree);
    seq_printf(m, "    MaxUsed : %10u B\n", maxUsed);
    seq_printf(m, "    Total :   %10u B\n", total);

    /* Acquire the database mutex. */
    gcmkVERIFY_OK(
        gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));

    /* Walk the databases. */
    for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
    {
        for (database = kernel->db->db[i];
             database != gcvNULL;
             database = database->next)
        {
            gcsDATABASE_COUNTERS * counter;
            counter = &database->vidMemPool[gcvPOOL_VIRTUAL];
            virtualCounter.bytes += counter->bytes;
            virtualCounter.maxBytes += counter->maxBytes;

            counter = &database->nonPaged;
            nonPagedCounter.bytes += counter->bytes;
            nonPagedCounter.bytes += counter->maxBytes;
        }
    }

    /* Release the database mutex. */
    gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));

    seq_printf(m, "  POOL VIRTUAL:\n");
    seq_printf(m, "    Used :    %10llu B\n", virtualCounter.bytes);
    seq_printf(m, "    MaxUsed : %10llu B\n", virtualCounter.bytes);

    return 0;
}

static const char * vidmemTypeStr[gcvVIDMEM_TYPE_COUNT] =
{
    "Generic",
    "Index",
    "Vertex",
    "Texture",
    "RenderTarget",
    "Depth",
    "Bitmap",
    "TileStatus",
    "Image",
    "Mask",
    "Scissor",
    "HZ",
    "ICache",
    "TxDesc",
    "Fence",
    "TFBHeader",
    "Command",
};

static const char * poolStr[gcvPOOL_NUMBER_OF_POOLS] =
{
    "Unknown",
    "Default",
    "Local",
    "Internal",
    "External",
    "Unified",
    "System",
    "Sram",
    "Virtual",
    "User",
    "Insram",
    "Exsram",
};

static void
_ShowDummyRecord(
    IN struct seq_file *File,
    IN gcsDATABASE_PTR Database
    )
{
}

static void
_ShowVideoMemoryRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    gctUINT i;
    gctUINT32 handle;
    gckVIDMEM_NODE nodeObject;
    gctPHYS_ADDR_T physical;
    gctINT32 refCount = 0;
    gctINT32 lockCount = 0;
    gceSTATUS status;

    seq_printf(m, "Video Memory Node:\n");
    seq_printf(m, "  handle         nodeObject       size         type     pool     physical  ref lock\n");

    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
    {
        gcsDATABASE_RECORD_PTR r = Database->list[i];

        while (r != NULL)
        {
            gcsDATABASE_RECORD_PTR record = r;
            r = r->next;

            if (record->type != gcvDB_VIDEO_MEMORY)
            {
                continue;
            }

            handle = gcmPTR2INT32(record->data);

            status = gckVIDMEM_HANDLE_Lookup2(
                record->kernel,
                Database,
                handle,
                &nodeObject
                );

            if (gcmIS_ERROR(status))
            {
                seq_printf(m, "%6u Invalid Node\n", handle);
                continue;
            }

            gcmkONERROR(gckVIDMEM_NODE_GetPhysical(record->kernel, nodeObject, 0, &physical));
            gcmkONERROR(gckVIDMEM_NODE_GetReference(record->kernel, nodeObject, &refCount));
            gcmkONERROR(gckVIDMEM_NODE_GetLockCount(record->kernel, nodeObject, &lockCount));

            seq_printf(m, "%#8x %#18lx %10lu %12s %8s %#12llx %4d %4d\n",
                handle,
                (unsigned long)nodeObject,
                (unsigned long)record->bytes,
                vidmemTypeStr[nodeObject->type],
                poolStr[nodeObject->pool],
                physical,
                refCount,
                lockCount
                );
        }
    }

OnError:
    return;
}

static void
_ShowCommandBufferRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    return;
}

static void
_ShowNonPagedRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    gctUINT i;

    seq_printf(m, "NonPaged Memory:\n");
    seq_printf(m, "  name              vaddr       size\n");

    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
    {
        gcsDATABASE_RECORD_PTR r = Database->list[i];

        while (r != NULL)
        {
            gcsDATABASE_RECORD_PTR record = r;
            r = r->next;

            if (record->type != gcvDB_NON_PAGED)
            {
                continue;
            }

            seq_printf(m, "%6u %#18lx %10lu\n",
                gcmPTR2INT32(record->physical),
                (unsigned long)record->data,
                (unsigned long)record->bytes
                );
        }
    }
}

static void
_ShowContiguousRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    return;
}

static void
_ShowSignalRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    gctUINT i;

    seq_printf(m, "User signal:\n");

    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
    {
        gcsDATABASE_RECORD_PTR r = Database->list[i];

        while (r != NULL)
        {
            gcsDATABASE_RECORD_PTR record = r;
            r = r->next;

            if (record->type != gcvDB_SIGNAL)
            {
                continue;
            }

            seq_printf(m, "%#10x\n", gcmPTR2INT32(record->data));
        }
    }
}

static void
_ShowLockRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    gctUINT i;
    gceSTATUS status;
    gctUINT32 handle;
    gckVIDMEM_NODE nodeObject;

    seq_printf(m, "Video Memory Lock:\n");
    seq_printf(m, "  handle         nodeObject              vaddr\n");

    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
    {
        gcsDATABASE_RECORD_PTR r = Database->list[i];

        while (r != NULL)
        {
            gcsDATABASE_RECORD_PTR record = r;
            r = r->next;

            if (record->type != gcvDB_VIDEO_MEMORY_LOCKED)
            {
                continue;
            }

            handle = gcmPTR2INT32(record->data);

            status = gckVIDMEM_HANDLE_Lookup2(
                record->kernel,
                Database,
                handle,
                &nodeObject
                );

            if (gcmIS_ERROR(status))
            {
                nodeObject = gcvNULL;
            }

            seq_printf(m, "%#8x %#18lx %#18lx\n",
                handle,
                (unsigned long)nodeObject,
                (unsigned long)record->physical
                );
        }
    }
}

static void
_ShowContextRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    gctUINT i;

    seq_printf(m, "Context:\n");

    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
    {
        gcsDATABASE_RECORD_PTR r = Database->list[i];

        while (r != NULL)
        {
            gcsDATABASE_RECORD_PTR record = r;
            r = r->next;

            if (record->type != gcvDB_CONTEXT)
            {
                continue;
            }

            seq_printf(m, "%6u\n", gcmPTR2INT32(record->data));
        }
    }
}

static void
_ShowMapMemoryRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    gctUINT i;

    seq_printf(m, "Map Memory:\n");
    seq_printf(m, "  name              vaddr       size\n");

    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
    {
        gcsDATABASE_RECORD_PTR r = Database->list[i];

        while (r != NULL)
        {
            gcsDATABASE_RECORD_PTR record = r;
            r = r->next;

            if (record->type != gcvDB_MAP_MEMORY)
            {
                continue;
            }

            seq_printf(m, "%#6lx %#18lx %10lu\n",
                (unsigned long)record->physical,
                (unsigned long)record->data,
                (unsigned long)record->bytes
                );
        }
    }
}

static void
_ShowMapUserMemoryRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    return;
}

static void
_ShowShbufRecord(
    IN struct seq_file *m,
    IN gcsDATABASE_PTR Database
    )
{
    gctUINT i;

    seq_printf(m, "ShBuf:\n");

    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
    {
        gcsDATABASE_RECORD_PTR r = Database->list[i];

        while (r != NULL)
        {
            gcsDATABASE_RECORD_PTR record = r;
            r = r->next;

            if (record->type != gcvDB_SHBUF)
            {
                continue;
            }

            seq_printf(m, "%#8x\n", gcmPTR2INT32(record->data));
        }
    }
}

static void
_ShowCounters(
    struct seq_file *File,
    gcsDATABASE_PTR Database
    )
{
    gctUINT i = 0;

    static const char * otherCounterNames[] = {
        "AllocNonPaged",
        "AllocContiguous",
        "MapUserMemory",
        "MapMemory",
    };

    gcsDATABASE_COUNTERS * otherCounters[] = {
        &Database->nonPaged,
        &Database->contiguous,
        &Database->mapUserMemory,
        &Database->mapMemory,
    };

    seq_printf(File, "%-16s %16s %16s %16s\n", "", "Current", "Maximum", "Total");

    /* Print surface type counters. */
    seq_printf(File, "%-16s %16lld %16lld %16lld\n",
               "All-Types",
               Database->vidMem.bytes,
               Database->vidMem.maxBytes,
               Database->vidMem.totalBytes);

    for (i = 1; i < gcvVIDMEM_TYPE_COUNT; i++)
    {
        seq_printf(File, "%-16s %16lld %16lld %16lld\n",
                   vidmemTypeStr[i],
                   Database->vidMemType[i].bytes,
                   Database->vidMemType[i].maxBytes,
                   Database->vidMemType[i].totalBytes);
    }
    seq_puts(File, "\n");

    /* Print surface pool counters. */
    seq_printf(File, "%-16s %16lld %16lld %16lld\n",
               "All-Pools",
               Database->vidMem.bytes,
               Database->vidMem.maxBytes,
               Database->vidMem.totalBytes);

    for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
    {
        seq_printf(File, "%-16s %16lld %16lld %16lld\n",
                   poolStr[i],
                   Database->vidMemPool[i].bytes,
                   Database->vidMemPool[i].maxBytes,
                   Database->vidMemPool[i].totalBytes);
    }
    seq_puts(File, "\n");

    /* Print other counters. */
    for (i = 0; i < gcmCOUNTOF(otherCounterNames); i++)
    {
        seq_printf(File, "%-16s %16lld %16lld %16lld\n",
                   otherCounterNames[i],
                   otherCounters[i]->bytes,
                   otherCounters[i]->maxBytes,
                   otherCounters[i]->totalBytes);
    }
    seq_puts(File, "\n");
}

static int
_ShowRecord(
    IN struct seq_file *File,
    IN gcsDATABASE_PTR Database,
    IN gcsDATABASE_RECORD_PTR Record
    )
{
    gctUINT32 handle;
    gckVIDMEM_NODE nodeObject;
    gctPHYS_ADDR_T physical;
    gceSTATUS status = gcvSTATUS_OK;

    static const char * recordTypes[gcvDB_NUM_TYPES] = {
        "Unknown",
        "VideoMemory",
        "CommandBuffer",
        "NonPaged",
        "Contiguous",
        "Signal",
        "VidMemLock",
        "Context",
        "Idel",
        "MapMemory",
        "MapUserMemory",
        "ShBuf",
    };

    handle = gcmPTR2INT32(Record->data);

    if (Record->type == gcvDB_VIDEO_MEMORY || Record->type == gcvDB_VIDEO_MEMORY_LOCKED)
    {
        status = gckVIDMEM_HANDLE_Lookup2(
            Record->kernel,
            Database,
            handle,
            &nodeObject
        );

        if (gcmIS_ERROR(status))
        {
            seq_printf(File, "%6u Invalid Node\n", handle);
            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
        }
        gcmkONERROR(gckVIDMEM_NODE_GetPhysical(Record->kernel, nodeObject, 0, &physical));
    }
    else
    {
        physical = (gctUINT64)(gctUINTPTR_T)Record->physical;
    }

    seq_printf(File, "%-14s %3d %16x %16zx %16zu\n",
        recordTypes[Record->type],
        Record->kernel->core,
        gcmPTR2INT32(Record->data),
        (size_t) physical,
        Record->bytes
        );

OnError:
    return status;
}

static void
_ShowDataBaseOldFormat(
    IN struct seq_file *File,
    IN gcsDATABASE_PTR Database
    )
{
    gctINT pid;
    gctUINT i;
    char name[24];

    /* Process ID and name */
    pid = Database->processID;
    gcmkVERIFY_OK(gckOS_GetProcessNameByPid(pid, gcmSIZEOF(name), name));

    seq_printf(File, "--------------------------------------------------------------------------------\n");
    seq_printf(File, "Process: %-8d %s\n", pid, name);

    seq_printf(File, "Records:\n");

    seq_printf(File, "%14s %3s %16s %16s %16s\n",
               "Type", "GPU", "Data/Node", "Physical/Node", "Bytes");

    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
    {
        gcsDATABASE_RECORD_PTR record = Database->list[i];

        while (record != NULL)
        {
            _ShowRecord(File, Database, record);
            record = record->next;
        }
    }

    seq_printf(File, "Counters:\n");

    _ShowCounters(File, Database);
}

static void
_ShowDatabase(
    IN struct seq_file *File,
    IN gcsDATABASE_PTR Database
    )
{
    gctINT pid;
    gctUINT i;
    char name[24];
    gctBOOL hasType[gcvDB_NUM_TYPES] = {0,};
    void (* showFuncs[])(struct seq_file *, gcsDATABASE_PTR) =
    {
        _ShowDummyRecord,
        _ShowVideoMemoryRecord,
        _ShowCommandBufferRecord,
        _ShowNonPagedRecord,
        _ShowContiguousRecord,
        _ShowSignalRecord,
        _ShowLockRecord,
        _ShowContextRecord,
        _ShowDummyRecord,
        _ShowMapMemoryRecord,
        _ShowMapUserMemoryRecord,
        _ShowShbufRecord,
    };

    gcmSTATIC_ASSERT(gcmCOUNTOF(showFuncs) == gcvDB_NUM_TYPES,
                     "DB type mismatch");

    /* Process ID and name */
    pid = Database->processID;
    gcmkVERIFY_OK(gckOS_GetProcessNameByPid(pid, gcmSIZEOF(name), name));

    seq_printf(File, "--------------------------------------------------------------------------------\n");
    seq_printf(File, "Process: %-8d %s\n", pid, name);

    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
    {
        gcsDATABASE_RECORD_PTR record = Database->list[i];

        while (record != NULL)
        {
            hasType[record->type] = gcvTRUE;
            record = record->next;
        }
    }

    for (i = 0; i < gcvDB_NUM_TYPES; i++)
    {
        if (hasType[i])
        {
            showFuncs[i](File, Database);
        }
    }
}

static int
gc_db_show_old(struct seq_file *m, void *data)
{
    gcsDATABASE_PTR database;
    gctINT i;
    static gctUINT64 idleTime = 0;
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    gckKERNEL kernel = _GetValidKernel(device);

    if (!kernel)
        return -ENXIO;

    /* Acquire the database mutex. */
    gcmkVERIFY_OK(
        gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));

    if (kernel->db->idleTime)
    {
        /* Record idle time if DB upated. */
        idleTime = kernel->db->idleTime;
        kernel->db->idleTime = 0;
    }

    /* Idle time since last call */
    seq_printf(m, "GPU Idle: %llu ns\n",  idleTime);

    /* Walk the databases. */
    for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
    {
        for (database = kernel->db->db[i];
             database != gcvNULL;
             database = database->next)
        {
            _ShowDataBaseOldFormat(m, database);
        }
    }

    /* Release the database mutex. */
    gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));

    return 0 ;
}

static int
gc_db_show(struct seq_file *m, void *data)
{
    gcsDATABASE_PTR database;
    gctINT i;
    static gctUINT64 idleTime = 0;
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    gckKERNEL kernel = _GetValidKernel(device);

    if (!kernel)
        return -ENXIO;

    /* Acquire the database mutex. */
    gcmkVERIFY_OK(
        gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));

    if (kernel->db->idleTime)
    {
        /* Record idle time if DB upated. */
        idleTime = kernel->db->idleTime;
        kernel->db->idleTime = 0;
    }

    /* Idle time since last call */
    seq_printf(m, "GPU Idle: %llu ns\n",  idleTime);

    /* Walk the databases. */
    for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
    {
        for (database = kernel->db->db[i];
             database != gcvNULL;
             database = database->next)
        {
            _ShowDatabase(m, database);
        }
    }

    /* Release the database mutex. */
    gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));

    return 0 ;
}

static int
gc_version_show(struct seq_file *m, void *data)
{
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    gcsPLATFORM * platform = gcvNULL;

    if (!device)
        return -ENXIO;

    platform = device->platform;
    if (!platform)
        return -ENXIO;

    seq_printf(m, "%s built at %s\n",  gcvVERSION_STRING, HOST);

    if (platform->name)
    {
        seq_printf(m, "Platform path: %s\n", platform->name);
    }
    else
    {
        seq_printf(m, "Code path: %s\n", __FILE__);
    }

    return 0 ;
}

static void print_ull(char dest[32], unsigned long long u)
{
    unsigned t[7];
    int i;

    if (u < 1000)
    {
        sprintf(dest, "%27llu", u);
        return;
    }

    for (i = 0; i < 7 && u; i++)
    {
        t[i] = do_div(u, 1000);
    }

    dest += sprintf(dest, "%*s", (7 - i) * 4, "");
    dest += sprintf(dest, "%3u", t[--i]);

    for (i--; i >= 0; i--)
    {
        dest += sprintf(dest, ",%03u", t[i]);
    }
}

/*******************************************************************************
**
** Show PM state timer.
**
** Entry is called as 'idle' for compatible reason, it shows more information
** than idle actually.
**
**  Start: Start time of this counting period.
**  End: End time of this counting peroid.
**  On: Time GPU stays in gcvPOWER_0N.
**  Off: Time GPU stays in gcvPOWER_0FF.
**  Idle: Time GPU stays in gcvPOWER_IDLE.
**  Suspend: Time GPU stays in gcvPOWER_SUSPEND.
*/
static int
gc_idle_show(struct seq_file *m, void *data)
{
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    gckKERNEL kernel = _GetValidKernel(device);
    char str[32];

    gctUINT64 on;
    gctUINT64 off;
    gctUINT64 idle;
    gctUINT64 suspend;

    if (!kernel)
        return -ENXIO;

    gckHARDWARE_QueryStateTimer(kernel->hardware, &on, &off, &idle, &suspend);

    /* Idle time since last call */
    print_ull(str, on);
    seq_printf(m, "On:      %s ns\n",  str);
    print_ull(str, off);
    seq_printf(m, "Off:     %s ns\n",  str);
    print_ull(str, idle);
    seq_printf(m, "Idle:    %s ns\n",  str);
    print_ull(str, suspend);
    seq_printf(m, "Suspend: %s ns\n",  str);

    return 0 ;
}

extern void
_DumpState(
    IN gckKERNEL Kernel
    );

/*******************************************************************************
**
** Show PM state timer.
**
** Entry is called as 'idle' for compatible reason, it shows more information
** than idle actually.
**
**  Start: Start time of this counting period.
**  End: End time of this counting peroid.
**  On: Time GPU stays in gcvPOWER_0N.
**  Off: Time GPU stays in gcvPOWER_0FF.
**  Idle: Time GPU stays in gcvPOWER_IDLE.
**  Suspend: Time GPU stays in gcvPOWER_SUSPEND.
*/

static int dumpCore = 0;

static int
gc_dump_trigger_show(struct seq_file *m, void *data)
{
#if gcdENABLE_3D
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    gckKERNEL kernel = gcvNULL;

    if (dumpCore >= gcvCORE_MAJOR && dumpCore < gcvCORE_COUNT)
    {
        kernel = device->kernels[dumpCore];
    }

    if (!kernel)
        return -ENXIO;

#endif

    seq_printf(m, gcdDEBUG_FS_WARN);

#if gcdENABLE_3D
    seq_printf(m, "Get dump from /proc/kmsg or /sys/kernel/debug/gc/galcore_trace\n");

    if (kernel && kernel->hardware->options.powerManagement == gcvFALSE)
    {
        _DumpState(kernel);
    }
#endif

    return 0;
}

static int dumpProcess = 0;

static void
_ShowVideoMemoryOldFormat(
    struct seq_file *File,
    gcsDATABASE_PTR Database
    )
{
    gctUINT i = 0;

    static const char * otherCounterNames[] = {
        "AllocNonPaged",
        "AllocContiguous",
        "MapUserMemory",
        "MapMemory",
    };

    gcsDATABASE_COUNTERS * otherCounters[] = {
        &Database->nonPaged,
        &Database->contiguous,
        &Database->mapUserMemory,
        &Database->mapMemory,
    };

    seq_printf(File, "%-16s %16s %16s %16s\n", "", "Current", "Maximum", "Total");

    /* Print surface type counters. */
    seq_printf(File, "%-16s %16llu %16llu %16llu\n",
               "All-Types",
               Database->vidMem.bytes,
               Database->vidMem.maxBytes,
               Database->vidMem.totalBytes);

    for (i = 1; i < gcvVIDMEM_TYPE_COUNT; i++)
    {
        seq_printf(File, "%-16s %16llu %16llu %16llu\n",
                   vidmemTypeStr[i],
                   Database->vidMemType[i].bytes,
                   Database->vidMemType[i].maxBytes,
                   Database->vidMemType[i].totalBytes);
    }
    seq_puts(File, "\n");

    /* Print surface pool counters. */
    seq_printf(File, "%-16s %16llu %16llu %16llu\n",
               "All-Pools",
               Database->vidMem.bytes,
               Database->vidMem.maxBytes,
               Database->vidMem.totalBytes);

    for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
    {
        seq_printf(File, "%-16s %16llu %16llu %16llu\n",
                   poolStr[i],
                   Database->vidMemPool[i].bytes,
                   Database->vidMemPool[i].maxBytes,
                   Database->vidMemPool[i].totalBytes);
    }
    seq_puts(File, "\n");

    /* Print other counters. */
    for (i = 0; i < gcmCOUNTOF(otherCounterNames); i++)
    {
        seq_printf(File, "%-16s %16llu %16llu %16llu\n",
                   otherCounterNames[i],
                   otherCounters[i]->bytes,
                   otherCounters[i]->maxBytes,
                   otherCounters[i]->totalBytes);
    }
    seq_puts(File, "\n");
}

static void
_ShowVideoMemory(
    struct seq_file *File,
    gcsDATABASE_PTR Database
    )
{
    gctUINT i = 0;

    static const char * otherCounterNames[] = {
        "AllocNonPaged",
        "MapMemory",
    };

    gcsDATABASE_COUNTERS * otherCounters[] = {
        &Database->nonPaged,
        &Database->mapMemory,
    };

    seq_printf(File, "%-16s %16s %16s %16s\n", "", "Current", "Maximum", "Total");

    /* Print surface type counters. */
    seq_printf(File, "%-16s %16llu %16llu %16llu\n",
               "All-Types",
               Database->vidMem.bytes,
               Database->vidMem.maxBytes,
               Database->vidMem.totalBytes);

    for (i = 1; i < gcvVIDMEM_TYPE_COUNT; i++)
    {
        seq_printf(File, "%-16s %16llu %16llu %16llu\n",
                   vidmemTypeStr[i],
                   Database->vidMemType[i].bytes,
                   Database->vidMemType[i].maxBytes,
                   Database->vidMemType[i].totalBytes);
    }
    seq_puts(File, "\n");

    /* Print surface pool counters. */
    seq_printf(File, "%-16s %16llu %16llu %16llu\n",
               "All-Pools",
               Database->vidMem.bytes,
               Database->vidMem.maxBytes,
               Database->vidMem.totalBytes);

    for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
    {
        seq_printf(File, "%-16s %16llu %16llu %16llu\n",
                   poolStr[i],
                   Database->vidMemPool[i].bytes,
                   Database->vidMemPool[i].maxBytes,
                   Database->vidMemPool[i].totalBytes);
    }
    seq_puts(File, "\n");

    /* Print other counters. */
    for (i = 0; i < gcmCOUNTOF(otherCounterNames); i++)
    {
        seq_printf(File, "%-16s %16llu %16llu %16llu\n",
                   otherCounterNames[i],
                   otherCounters[i]->bytes,
                   otherCounters[i]->maxBytes,
                   otherCounters[i]->totalBytes);
    }
    seq_puts(File, "\n");
}

static int gc_vidmem_show_old(struct seq_file *m, void *unused)
{
    gceSTATUS status;
    gcsDATABASE_PTR database;
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    char name[64];
    int i;

    gckKERNEL kernel = _GetValidKernel(device);

    if (!kernel)
        return -ENXIO;

    if (dumpProcess == 0)
    {
        /* Acquire the database mutex. */
        gcmkVERIFY_OK(
        gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));

        for (i = 0; i < gcmCOUNTOF(kernel->db->db); i++)
        {
            for (database = kernel->db->db[i];
                 database != gcvNULL;
                 database = database->next)
            {
                gckOS_GetProcessNameByPid(database->processID, gcmSIZEOF(name), name);
                seq_printf(m, "VidMem Usage (Process %u: %s):\n", database->processID, name);
                _ShowVideoMemoryOldFormat(m, database);
                seq_puts(m, "\n");
            }
        }

        /* Release the database mutex. */
        gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));
    }
    else
    {
        /* Find the database. */
        status = gckKERNEL_FindDatabase(kernel, dumpProcess, gcvFALSE, &database);

        if (gcmIS_ERROR(status))
        {
            seq_printf(m, "ERROR: process %d not found\n", dumpProcess);
            return 0;
        }

        gckOS_GetProcessNameByPid(dumpProcess, gcmSIZEOF(name), name);
        seq_printf(m, "VidMem Usage (Process %d: %s):\n", dumpProcess, name);
        _ShowVideoMemoryOldFormat(m, database);
    }

    return 0;
}

static int gc_vidmem_show(struct seq_file *m, void *unused)
{
    gceSTATUS status;
    gcsDATABASE_PTR database;
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    char name[64];
    int i;

    gckKERNEL kernel = _GetValidKernel(device);

    if (!kernel)
        return -ENXIO;

    if (dumpProcess == 0)
    {
        /* Acquire the database mutex. */
        gcmkVERIFY_OK(
        gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));

        for (i = 0; i < gcmCOUNTOF(kernel->db->db); i++)
        {
            for (database = kernel->db->db[i];
                 database != gcvNULL;
                 database = database->next)
            {
                gckOS_GetProcessNameByPid(database->processID, gcmSIZEOF(name), name);
                seq_printf(m, "VidMem Usage (Process %u: %s):\n", database->processID, name);
                _ShowVideoMemory(m, database);
                seq_puts(m, "\n");
            }
        }

        /* Release the database mutex. */
        gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));
    }
    else
    {
        /* Find the database. */
        status = gckKERNEL_FindDatabase(kernel, dumpProcess, gcvFALSE, &database);

        if (gcmIS_ERROR(status))
        {
            seq_printf(m, "ERROR: process %d not found\n", dumpProcess);
            return 0;
        }

        gckOS_GetProcessNameByPid(dumpProcess, gcmSIZEOF(name), name);
        seq_printf(m, "VidMem Usage (Process %d: %s):\n", dumpProcess, name);
        _ShowVideoMemory(m, database);
    }

    return 0;
}

static inline int strtoint_from_user(const char __user *s,
                        size_t count, int *res)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
    int ret = kstrtoint_from_user(s, count, 10, res);

    return ret < 0 ? ret : count;
#else
    /* sign, base 2 representation, newline, terminator */
    char buf[1 + sizeof(long) * 8 + 1 + 1];

    size_t len = min(count, sizeof(buf) - 1);

    if (copy_from_user(buf, s, len))
        return -EFAULT;
    buf[len] = '\0';

    *res = (int) simple_strtol(buf, NULL, 0);

    return count;
#endif
}

static int gc_vidmem_write(const char __user *buf, size_t count, void* data)
{
    return strtoint_from_user(buf, count, &dumpProcess);
}

static int gc_dump_trigger_write(const char __user *buf, size_t count, void* data)
{
    return strtoint_from_user(buf, count, &dumpCore);
}

static int gc_clk_show(struct seq_file* m, void* data)
{
    gcsINFO_NODE *node = m->private;
    gckGALDEVICE device = node->device;
    gctUINT i;
    gceSTATUS status;

    if (!device)
        return -ENXIO;

    for (i = gcvCORE_MAJOR; i < gcvCORE_COUNT; i++)
    {
        if (device->kernels[i])
        {
            gckHARDWARE hardware = device->kernels[i]->hardware;

            if (i == gcvCORE_VG)
            {
                continue;
            }

            status = gckHARDWARE_QueryFrequency(hardware);
            if (gcmIS_ERROR(status))
            {
                seq_printf(m, "query gpu%d clock fail.\n", i);
                continue;
            }

            if (hardware->mcClk)
            {
                seq_printf(m, "gpu%d mc clock: %d HZ.\n", i, hardware->mcClk);
            }

            if (hardware->shClk)
            {
                seq_printf(m, "gpu%d sh clock: %d HZ.\n", i, hardware->shClk);
            }
        }
    }

    return 0;
}

static gcsINFO InfoList[] =
{
    {"info", gc_info_show},
    {"clients", gc_clients_show},
    {"meminfo", gc_meminfo_show},
    {"idle", gc_idle_show},
    {"database", gc_db_show_old},
    {"database64x", gc_db_show},
    {"version", gc_version_show},
    {"vidmem", gc_vidmem_show_old, gc_vidmem_write},
    {"vidmem64x", gc_vidmem_show, gc_vidmem_write},
    {"dump_trigger", gc_dump_trigger_show, gc_dump_trigger_write},
    {"clk", gc_clk_show},
};

static gceSTATUS
_DebugfsInit(
    IN gckGALDEVICE Device
    )
{
    gceSTATUS status = gcvSTATUS_OK;
    gckDEBUGFS_DIR dir = &Device->debugfsDir;

    gcmkONERROR(gckDEBUGFS_DIR_Init(dir, gcvNULL, "gc"));
    gcmkONERROR(gckDEBUGFS_DIR_CreateFiles(dir, InfoList, gcmCOUNTOF(InfoList), Device));

OnError:
    return status;
}

static void
_DebugfsCleanup(
    IN gckGALDEVICE Device
    )
{
    gckDEBUGFS_DIR dir = &Device->debugfsDir;

    if (Device->debugfsDir.root)
    {
        gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles(dir, InfoList, gcmCOUNTOF(InfoList)));

        gckDEBUGFS_DIR_Deinit(dir);
    }
}


/******************************************************************************\
*************************** Memory Allocation Wrappers *************************
\******************************************************************************/

static gceSTATUS
_AllocateMemory(
    IN gckGALDEVICE Device,
    IN gctSIZE_T Bytes,
    OUT gctPOINTER *Logical,
    OUT gctPHYS_ADDR *Physical,
    OUT gctUINT64 *PhysAddr
    )
{
    gceSTATUS status = gcvSTATUS_OK;
    gctPHYS_ADDR_T physAddr;

    gcmkHEADER_ARG("Device=%p Bytes=0x%zx", Device, Bytes);

    gcmkVERIFY_ARGUMENT(Device != NULL);
    gcmkVERIFY_ARGUMENT(Logical != NULL);
    gcmkVERIFY_ARGUMENT(Physical != NULL);
    gcmkVERIFY_ARGUMENT(PhysAddr != NULL);

    gcmkONERROR(gckOS_AllocateNonPagedMemory(
        Device->os, gcvFALSE, gcvALLOC_FLAG_CONTIGUOUS, &Bytes, Physical, Logical
        ));

    gcmkONERROR(gckOS_GetPhysicalFromHandle(
        Device->os, *Physical, 0, &physAddr
        ));

    *PhysAddr = physAddr;

OnError:
    gcmkFOOTER_ARG(
        "*Logical=%p *Physical=%p *PhysAddr=0x%llx",
        gcmOPT_POINTER(Logical), gcmOPT_POINTER(Physical), gcmOPT_VALUE(PhysAddr)
        );

    return status;
}

static gceSTATUS
_FreeMemory(
    IN gckGALDEVICE Device,
    IN gctPOINTER Logical,
    IN gctPHYS_ADDR Physical
    )
{
    gceSTATUS status;

    gcmkHEADER_ARG("Device=%p Logical=%p Physical=%p",
                   Device, Logical, Physical);

    gcmkVERIFY_ARGUMENT(Device != NULL);

    status = gckOS_FreeNonPagedMemory(
        Device->os, Physical, Logical,
        ((PLINUX_MDL) Physical)->numPages * PAGE_SIZE
        );

    gcmkFOOTER();
    return status;
}

static gceSTATUS
_SetupContiguousVidMem(
    IN gckGALDEVICE Device,
    IN const gcsMODULE_PARAMETERS * Args
    )
{
    gceSTATUS status = gcvSTATUS_OK;
    gctUINT64 physAddr = ~0ULL;
    gckGALDEVICE device = Device;

    gcmkHEADER_ARG("Device=%p Args=%p", Device, Args);

    /* set up the contiguous memory */
    device->contiguousBase = Args->contiguousBase;
    device->contiguousSize = Args->contiguousSize;

    if (Args->contiguousSize == 0)
    {
        gcmkFOOTER_NO();
        return gcvSTATUS_OK;
    }

    if (Args->contiguousBase == 0)
    {
        while (device->contiguousSize > 0)
        {
            /* Allocate contiguous memory. */
            status = _AllocateMemory(
                device,
                device->contiguousSize,
                &device->contiguousLogical,
                &device->contiguousPhysical,
                &physAddr
                );

            if (gcmIS_SUCCESS(status))
            {
                status = gckVIDMEM_Construct(
                    device->os,
                    physAddr,
                    device->contiguousSize,
                    64,
                    Args->bankSize,
                    &device->contiguousVidMem
                    );

                if (gcmIS_SUCCESS(status))
                {
                    gckALLOCATOR allocator = ((PLINUX_MDL)device->contiguousPhysical)->allocator;
                    device->contiguousVidMem->capability = allocator->capability | gcvALLOC_FLAG_MEMLIMIT;
                    device->contiguousVidMem->physical = device->contiguousPhysical;
                    device->contiguousBase = physAddr;
                    if (device->contiguousBase > 0xFFFFFFFFULL)
                    {
                        device->contiguousVidMem->capability &= ~gcvALLOC_FLAG_4GB_ADDR;
                    }
                    break;
                }

                gcmkONERROR(_FreeMemory(
                    device,
                    device->contiguousLogical,
                    device->contiguousPhysical
                    ));

                device->contiguousLogical  = gcvNULL;
                device->contiguousPhysical = gcvNULL;
            }

            if (device->contiguousSize <= (4 << 20))
            {
                device->contiguousSize = 0;
            }
            else
            {
                device->contiguousSize -= (4 << 20);
            }
        }
    }
    else
    {
        /* Create the contiguous memory heap. */
        status = gckVIDMEM_Construct(
            device->os,
            Args->contiguousBase,
            Args->contiguousSize,
            64,
            Args->bankSize,
            &device->contiguousVidMem
            );

        if (gcmIS_ERROR(status))
        {
            /* Error, disable contiguous memory pool. */
            device->contiguousVidMem = gcvNULL;
            device->contiguousSize   = 0;
        }
        else
        {
            gckALLOCATOR allocator;
            gctBOOL contiguousRequested = Args->contiguousRequested;

#if gcdCAPTURE_ONLY_MODE
            contiguousRequested = gcvTRUE;
#endif

            gcmkONERROR(gckOS_RequestReservedMemory(
                device->os, Args->contiguousBase, Args->contiguousSize,
                "galcore contiguous memory",
                contiguousRequested,
                &device->contiguousPhysical
                ));

            allocator = ((PLINUX_MDL)device->contiguousPhysical)->allocator;

            device->contiguousVidMem->capability = allocator->capability | gcvALLOC_FLAG_MEMLIMIT;
            device->contiguousVidMem->physical = device->contiguousPhysical;
            device->requestedContiguousBase = Args->contiguousBase;
            device->requestedContiguousSize = Args->contiguousSize;

            device->contiguousPhysName = 0;
            device->contiguousSize = Args->contiguousSize;
        }
    }

    if (Args->showArgs)
    {
        gcmkPRINT("Galcore Info: ContiguousBase=0x%llx ContiguousSize=0x%zx\n", device->contiguousBase, device->contiguousSize);
    }

OnError:
    gcmkFOOTER();
    return status;
}

static gceSTATUS
_SetupExternalSRAMVidMem(
    IN gckGALDEVICE Device
    )
{
    gceSTATUS status = gcvSTATUS_OK;
    gckGALDEVICE device = Device;
    gctINT32 i, j = 0;

    gcmkHEADER_ARG("Device=%p", Device);

    /* Setup external SRAM memory region. */
    for (i = 0; i < gcvSRAM_EXT_COUNT; i++)
    {
        if (!device->extSRAMSizes[i])
        {
            /* Keep this path for internal test, read from feature database. */
            device->extSRAMSizes[i] = device->device->extSRAMSizes[i];
        }

        if (device->extSRAMSizes[i] > 0)
        {
            /* create the external SRAM memory heap */
            status = gckVIDMEM_Construct(
                device->os,
                device->extSRAMBases[i],
                device->extSRAMSizes[i],
                64,
                0,
                &device->extSRAMVidMem[i]
                );

            if (gcmIS_ERROR(status))
            {
                /* Error, disable external SRAM heap. */
                device->extSRAMSizes[i] = 0;
            }
            else
            {
                char sRAMName[40];
                snprintf(sRAMName, gcmSIZEOF(sRAMName) - 1, "Galcore external sram%d", i);

#if gcdCAPTURE_ONLY_MODE
                device->args.sRAMRequested = gcvTRUE;
#endif
                /* Map external SRAM memory. */
                gcmkONERROR(gckOS_RequestReservedMemory(
                        device->os,
                        device->extSRAMBases[i], device->extSRAMSizes[i],
                        sRAMName,
                        device->args.sRAMRequested,
                        &device->extSRAMPhysical[i]
                        ));

                device->extSRAMVidMem[i]->physical = device->extSRAMPhysical[i];
                device->device->extSRAMPhysical[i] = device->extSRAMPhysical[i];

                for (j = 0; j < gcdMAX_GPU_COUNT; j++)
                {
                    if (device->irqLines[j] != -1 && device->kernels[j])
                    {
                        device->kernels[j]->hardware->options.extSRAMGPUPhysNames[i] = gckKERNEL_AllocateNameFromPointer(device->kernels[j], device->extSRAMPhysical[i]);
                    }
                }
            }
        }
    }

OnError:
    gcmkFOOTER();
    return status;
}

/******************************************************************************\
******************************* Interrupt Handler ******************************
\******************************************************************************/
static irqreturn_t isrRoutine(int irq, void *ctxt)
{
    gceSTATUS status;
    gckGALDEVICE device;
    gceCORE core = (gceCORE)gcmPTR2INT32(ctxt) - 1;

    device = galDevice;

    /* Call kernel interrupt notification. */
    status = gckHARDWARE_Interrupt(device->kernels[core]->hardware);

    if (gcmIS_SUCCESS(status))
    {
        up(&device->semas[core]);
        return IRQ_HANDLED;
    }

    return IRQ_NONE;
}

static irqreturn_t isrRoutineVG(int irq, void *ctxt)
{
    return IRQ_NONE;
}

static const char *isrNames[] =
{
    "galcore:0",
    "galcore:3d-1",
    "galcore:3d-2",
    "galcore:3d-3",
    "galcore:3d-4",
    "galcore:3d-5",
    "galcore:3d-6",
    "galcore:3d-7",
    "galcore:2d",
    "galcore:vg",
#if gcdDEC_ENABLE_AHB
    "galcore:dec"
#endif
};

static int isrRoutinePoll(void *ctxt)
{
    gckGALDEVICE device;
    gceCORE core = (gceCORE)gcmPTR2INT32(ctxt);

    device = galDevice;

    gcmSTATIC_ASSERT(gcvCORE_COUNT == gcmCOUNTOF(isrNames),
                     "isrNames array does not match core types");

    while (1)
    {
        if (unlikely(device->killThread))
        {
            /* The daemon exits. */
            while (!kthread_should_stop())
            {
                gckOS_Delay(device->os, 1);
            }

            return 0;
        }

        if (core == gcvCORE_VG)
        {
            isrRoutineVG(-1, gcvNULL);
        }
        else
        {
            isrRoutine(-1, (gctPOINTER)(uintptr_t)(core + 1));
        }

        gckOS_Delay(device->os, 10);
    }

    return 0;
}

static gceSTATUS
_SetupIsr(
    IN gceCORE Core
    )
{
    gctINT ret = 0;
    gceSTATUS status = gcvSTATUS_OK;
    gckGALDEVICE Device = galDevice;
    irq_handler_t handler;

    gcmkHEADER_ARG("Device=%p Core=%d", Device, Core);

    gcmkVERIFY_ARGUMENT(Device != NULL);

    gcmSTATIC_ASSERT(gcvCORE_COUNT == gcmCOUNTOF(isrNames),
                     "isrNames array does not match core types");

    if (Device->irqLines[Core] == -1)
    {
        gctUINT64 isrPolling = -1;

        if (Device->isrThread[Core])
        {
            return status;
        }

        gckOS_QueryOption(Device->os, "isrPoll", &isrPolling);

        /* use kthread to poll int stat */
        if (gcmBITTEST(isrPolling, Core) != 0)
        {
            struct task_struct * task;

            Device->killIsrThread = gcvFALSE;

            task = kthread_run(isrRoutinePoll, (gctPOINTER)Core, "%s_poll", isrNames[Core]);

            if (IS_ERR(task))
            {
                gcmkTRACE_ZONE(
                    gcvLEVEL_ERROR, gcvZONE_DRIVER,
                    "%s(%d): Could not start the intr poll thread.\n",
                    __FUNCTION__, __LINE__
                    );

                gcmkONERROR(gcvSTATUS_GENERIC_IO);
            }

            gcmkPRINT("galcore: polling core%d int state\n", Core);

            Device->isrThread[Core] = task;
            Device->isrInitializeds[Core] = gcvTRUE;

            return status;
        }
        /* it should not run to here */
        return gcvSTATUS_INVALID_ARGUMENT;
    }

    handler = (Core == gcvCORE_VG) ? isrRoutineVG : isrRoutine;

    /*
     * Hook up the isr based on the irq line.
     * For shared irq, device-id can not be 0, but CORE_MAJOR value is.
     * Add by 1 here and subtract by 1 in isr to fix the issue.
     */
    ret = request_irq(
        Device->irqLines[Core], handler, gcdIRQF_FLAG,
        isrNames[Core], (void *)(uintptr_t)(Core + 1)
        );

    if (ret != 0)
    {
        gcmkTRACE_ZONE(
            gcvLEVEL_ERROR, gcvZONE_DRIVER,
            "%s(%d): Could not register irq line %d (error=%d)\n",
            __FUNCTION__, __LINE__,
            Device->irqLines[Core], ret
            );

        gcmkONERROR(gcvSTATUS_GENERIC_IO);
    }

    /* Mark ISR as initialized. */
    Device->isrInitializeds[Core] = gcvTRUE;

OnError:
    gcmkFOOTER();
    return status;
}

static gceSTATUS
_ReleaseIsr(
    IN gceCORE Core
    )
{
    gckGALDEVICE Device = galDevice;

    gcmkHEADER_ARG("Device=%p Core=%d", Device, Core);

    gcmkVERIFY_ARGUMENT(Device != NULL);

    /* release the irq */
    if (Device->isrInitializeds[Core])
    {
        if (Device->isrThread[Core])
        {
            Device->killIsrThread = gcvTRUE;
            kthread_stop(Device->isrThread[Core]);
            Device->isrThread[Core] = gcvNULL;
        }
        else
        {
            free_irq(Device->irqLines[Core], (void *)(uintptr_t)(Core + 1));
        }

        Device->isrInitializeds[Core] = gcvFALSE;
    }

    gcmkFOOTER_NO();
    return gcvSTATUS_OK;
}

static int threadRoutine(void *ctxt)
{
    gckGALDEVICE device = galDevice;
    gceCORE core = (gceCORE) gcmPTR2INT32(ctxt);

    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
                   "Starting isr Thread with extension=%p",
                   device);


    for (;;)
    {
        int down;

        down = down_interruptible(&device->semas[core]);
        if (down && down != -EINTR)
        {
            return down;
        }

        if (unlikely(device->killThread))
        {
            /* The daemon exits. */
            while (!kthread_should_stop())
            {
                gckOS_Delay(device->os, 1);
            }

            return 0;
        }

        gckKERNEL_Notify(device->kernels[core], gcvNOTIFY_INTERRUPT);
    }
}

static gceSTATUS
_StartThread(
    IN gckGALDEVICE Device,
    IN gceCORE Core
    )
{
    gceSTATUS status = gcvSTATUS_OK;
    gckGALDEVICE device = galDevice;
    struct task_struct * task;

    if (device->kernels[Core] != gcvNULL)
    {
        /* Start the kernel thread. */
        task = kthread_run(threadRoutine, (void *)Core,
                "galcore_deamon/%d", Core);

        if (IS_ERR(task))
        {
            gcmkTRACE_ZONE(
                gcvLEVEL_ERROR, gcvZONE_DRIVER,
                "%s(%d): Could not start the kernel thread.\n",
                __FUNCTION__, __LINE__
                );

            gcmkONERROR(gcvSTATUS_GENERIC_IO);
        }

        device->threadCtxts[Core]         = task;
        device->threadInitializeds[Core] = device->kernels[Core]->threadInitialized = gcvTRUE;
    }
    else
    {
        device->threadInitializeds[Core] = gcvFALSE;
    }

OnError:
    return status;
}

static void
_StopThread(
    gckGALDEVICE Device,
    gceCORE Core
    )
{
    if (Device->threadInitializeds[Core])
    {
        Device->killThread = gcvTRUE;
        up(&Device->semas[Core]);

        kthread_stop(Device->threadCtxts[Core]);
        Device->threadCtxts[Core]        = gcvNULL;
        Device->threadInitializeds[Core] = gcvFALSE;
    }
}

/*******************************************************************************
**
**  gckGALDEVICE_Construct
**
**  Constructor.
**
**  INPUT:
**
**  OUTPUT:
**
**      gckGALDEVICE * Device
**          Pointer to a variable receiving the gckGALDEVICE object pointer on
**          success.
*/
gceSTATUS
gckGALDEVICE_Construct(
    IN gcsPLATFORM * Platform,
    IN const gcsMODULE_PARAMETERS * Args,
    OUT gckGALDEVICE *Device
    )
{
    gckKERNEL kernel = gcvNULL;
    gckGALDEVICE device;
    gctINT32 i;

#if !gcdCAPTURE_ONLY_MODE
    gceHARDWARE_TYPE type;
#endif

    gceSTATUS status = gcvSTATUS_OK;
    gctUINT64 isrPolling = -1;

    gcmkHEADER_ARG("Platform=%p Args=%p", Platform, Args);

    /* Allocate device structure. */
    device = kmalloc(sizeof(struct _gckGALDEVICE), GFP_KERNEL | __GFP_NOWARN);

    if (!device)
    {
        gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
    }

    memset(device, 0, sizeof(struct _gckGALDEVICE));

    device->platform = Platform;
    device->platform->dev = gcvNULL;

    device->args = *Args;

    /* Clear irq lines. */
    for (i = 0; i < gcdMAX_GPU_COUNT; i++)
    {
        device->irqLines[i] = -1;
#if USE_LINUX_PCIE
        device->bars[i] = -1;
#endif
    }

    for (i = 0; i < gcvCORE_COUNT; i++)
    {
        device->irqLines[i]                  = Args->irqs[i];
        device->requestedRegisterMemBases[i] = Args->registerBases[i];
        device->requestedRegisterMemSizes[i] = Args->registerSizes[i];
#if USE_LINUX_PCIE
        device->bars[i]                      = Args->bars[i];
#endif
        gcmkTRACE_ZONE(gcvLEVEL_INFO, _GC_OBJ_ZONE,
                       "Get register base %llx of core %d",
                       Args->registerBases[i], i);
    }

    device->requestedContiguousBase  = 0;
    device->requestedContiguousSize  = 0;

    for (i = 0; i < gcdMAX_GPU_COUNT; i++)
    {
        unsigned long physical;
        physical = (unsigned long)device->requestedRegisterMemBases[i];

        /* Set up register memory region. */
        if (physical != 0)
        {
            if (Args->registerBasesMapped[i])
            {
                device->registerBases[i] = Args->registerBasesMapped[i];
                device->requestedRegisterMemBases[i] = 0;
            }
            else
            {
#if USE_LINUX_PCIE
                gcmkPRINT("register should be mapped in platform layer");
#endif
                if (!request_mem_region(physical,
                        device->requestedRegisterMemSizes[i],
                        "galcore register region"))
                {
                    gcmkTRACE_ZONE(
                            gcvLEVEL_ERROR, gcvZONE_DRIVER,
                            "%s(%d): Failed to claim %lu bytes @ 0x%llx\n",
                            __FUNCTION__, __LINE__,
                            device->requestedRegisterMemSizes[i], physical
                            );

                    gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
                }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,5,0) && (defined(CONFIG_ARM) || defined(CONFIG_ARM64))
                device->registerBases[i] = (gctPOINTER)ioremap(
#else
                device->registerBases[i] = (gctPOINTER)ioremap_nocache(
#endif
                        physical, device->requestedRegisterMemSizes[i]);

                if (device->registerBases[i] == gcvNULL)
                {
                    gcmkTRACE_ZONE(
                            gcvLEVEL_ERROR, gcvZONE_DRIVER,
                            "%s(%d): Unable to map %ld bytes @ 0x%zx\n",
                            __FUNCTION__, __LINE__,
                            physical, device->requestedRegisterMemSizes[i]
                            );

                    gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
                }
            }
        }
    }

    /* Set the base address */
    device->baseAddress = device->physBase = Args->baseAddress;
    device->physSize = Args->physSize;

    /* Set the external base address */
    device->externalBase = Args->externalBase;
    device->externalSize = Args->externalSize;

    for (i = 0; i < gcvSRAM_EXT_COUNT; i++)
    {
        device->extSRAMBases[i] = Args->extSRAMBases[i];
        device->extSRAMSizes[i] = Args->extSRAMSizes[i];
    }

    /* Construct the gckOS object. */
    gcmkONERROR(gckOS_Construct(device, &device->os));


    if (device->externalSize > 0)
    {
        /* create the external memory heap */
        status = gckVIDMEM_Construct(
            device->os,
            device->externalBase,
            device->externalSize,
            64,
            0,
            &device->externalVidMem
            );

        if (gcmIS_ERROR(status))
        {
            /* Error, disable external heap. */
            device->externalSize = 0;
        }
        else
        {
            /* Map external memory. */
            gcmkONERROR(gckOS_RequestReservedMemory(
                    device->os,
                    device->externalBase, device->externalSize,
                    "galcore external memory",
                    gcvTRUE,
                    &device->externalPhysical
                    ));

            device->externalVidMem->physical = device->externalPhysical;
        }
    }

    /* Construct the gckDEVICE object for os independent core management. */
    gcmkONERROR(gckDEVICE_Construct(device->os, &device->device));

    device->device->showSRAMMapInfo = Args->showArgs;

    device->platform->dev = device->device;

    gckOS_QueryOption(device->os, "isrPoll", &isrPolling);

    if (device->irqLines[gcvCORE_MAJOR] != -1 || gcmBITTEST(isrPolling, gcvCORE_MAJOR)!= 0)
    {
        gcmkONERROR(gctaOS_ConstructOS(device->os, &device->taos));
    }

    /* Setup contiguous video memory pool. */
    gcmkONERROR(_SetupContiguousVidMem(device, Args));

#if gcdEXTERNAL_SRAM_DEFAULT_POOL
    /* Setup external SRAM video memory pool. */
    gcmkONERROR(_SetupExternalSRAMVidMem(device));
#endif

    /* Add core for all available major cores. */
    for (i = gcvCORE_MAJOR; i <= gcvCORE_3D_MAX; i++)
    {
        if (device->irqLines[i] != -1 || gcmBITTEST(isrPolling, i)!= 0)
        {
            gcmkONERROR(gcTA_Construct(
                device->taos,
                (gceCORE)i,
                &globalTA[i]
                ));

            gcmkONERROR(gckDEVICE_AddCore(
                device->device,
                (gceCORE)i,
                Args->chipIDs[i],
                device,
                &device->kernels[i]
                ));

            gcmkONERROR(gckHARDWARE_SetFastClear(
                device->kernels[i]->hardware,
                Args->fastClear,
                Args->compression
                ));

            gcmkONERROR(gckHARDWARE_EnablePowerManagement(
                device->kernels[i]->hardware,
                Args->powerManagement
                ));

#if gcdENABLE_FSCALE_VAL_ADJUST
            gcmkONERROR(gckHARDWARE_SetMinFscaleValue(
                device->kernels[i]->hardware,
                Args->gpu3DMinClock
                ));
#endif

            gcmkONERROR(gckHARDWARE_SetGpuProfiler(
                device->kernels[i]->hardware,
                Args->gpuProfiler
                ));
        }
        else
        {
            device->kernels[i] = gcvNULL;
        }
    }

#if !gcdCAPTURE_ONLY_MODE
    if (device->irqLines[gcvCORE_2D] != -1 || gcmBITTEST(isrPolling, gcvCORE_2D)!= 0)
    {
        gcmkONERROR(gckDEVICE_AddCore(
            device->device,
            gcvCORE_2D,
            gcvCHIP_ID_DEFAULT,
            device,
            &device->kernels[gcvCORE_2D]
            ));

        /* Verify the hardware type */
        gcmkONERROR(gckHARDWARE_GetType(
            device->kernels[gcvCORE_2D]->hardware,
            &type
            ));

        if (type != gcvHARDWARE_2D)
        {
            gcmkTRACE_ZONE(
                gcvLEVEL_ERROR, gcvZONE_DRIVER,
                "%s(%d): Unexpected hardware type: %d\n",
                __FUNCTION__, __LINE__,
                type
                );

            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
        }

        gcmkONERROR(gckHARDWARE_EnablePowerManagement(
            device->kernels[gcvCORE_2D]->hardware,
            Args->powerManagement
            ));

#if gcdENABLE_FSCALE_VAL_ADJUST
        gcmkONERROR(gckHARDWARE_SetMinFscaleValue(
            device->kernels[gcvCORE_2D]->hardware, 1
            ));
#endif
    }
    else
    {
        device->kernels[gcvCORE_2D] = gcvNULL;
    }

    if (device->irqLines[gcvCORE_VG] != -1 || gcmBITTEST(isrPolling, gcvCORE_VG)!= 0)
    {
    }
    else
    {
        device->kernels[gcvCORE_VG] = gcvNULL;
    }
#else
    device->kernels[gcvCORE_2D] = gcvNULL;

    device->kernels[gcvCORE_VG] = gcvNULL;
#endif

#if !gcdEXTERNAL_SRAM_DEFAULT_POOL
    /* Setup external SRAM video memory pool. */
    gcmkONERROR(_SetupExternalSRAMVidMem(device));
#endif

    /* Initialize the kernel thread semaphores. */
    for (i = 0; i < gcdMAX_GPU_COUNT; i++)
    {
        if ((device->irqLines[i] != -1 || gcmBITTEST(isrPolling, i)!= 0)
            && device->kernels[i])
        {
            sema_init(&device->semas[i], 0);
        }
    }

    /* Grab the first valid kernel. */
    for (i = 0; i < gcdMAX_GPU_COUNT; i++)
    {
        if (device->kernels[i] != gcvNULL)
        {
            kernel = device->kernels[i];
            break;
        }
    }

    if (!kernel)
    {
        gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
    }

    if (device->internalPhysical)
    {
        device->internalPhysName = gcmPTR_TO_NAME(device->internalPhysical);
    }

    if (device->externalPhysical)
    {
        device->externalPhysName = gcmPTR_TO_NAME(device->externalPhysical);
    }

    if (device->contiguousPhysical)
    {
        device->contiguousPhysName = gcmPTR_TO_NAME(device->contiguousPhysical);
    }

    gcmkONERROR(_DebugfsInit(device));

    /* Return pointer to the device. */
    *Device = galDevice = device;

OnError:
    if (gcmIS_ERROR(status))
    {
        /* Roll back. */
        gcmkVERIFY_OK(gckGALDEVICE_Destroy(device));
    }

    gcmkFOOTER();
    return status;
}

/*******************************************************************************
**
**  gckGALDEVICE_Destroy
**
**  Class destructor.
**
**  INPUT:
**
**      Nothing.
**
**  OUTPUT:
**
**      Nothing.
**
**  RETURNS:
**
**      Nothing.
*/
gceSTATUS
gckGALDEVICE_Destroy(
    gckGALDEVICE Device)
{
    gctINT i, j = 0;
    gckKERNEL kernel = gcvNULL;

    gcmkHEADER_ARG("Device=%p", Device);

    if (Device != gcvNULL)
    {
        /* Grab the first available kernel */
        for (i = 0; i < gcdMAX_GPU_COUNT; i++)
        {
            if (Device->kernels[i])
            {
                kernel = Device->kernels[i];
                break;
            }
        }

        if (kernel)
        {
            if (Device->internalPhysName != 0)
            {
                gcmRELEASE_NAME(Device->internalPhysName);
                Device->internalPhysName = 0;
            }
            if (Device->externalPhysName != 0)
            {
                gcmRELEASE_NAME(Device->externalPhysName);
                Device->externalPhysName = 0;
            }
            if (Device->contiguousPhysName != 0)
            {
                gcmRELEASE_NAME(Device->contiguousPhysName);
                Device->contiguousPhysName = 0;
            }
        }

        /* Destroy per-core SRAM heap. */
        for (i = 0; i < gcvCORE_COUNT; i++)
        {
            if (Device->kernels[i])
            {
                kernel = Device->kernels[i];

                for (j = gcvSRAM_INTERNAL0; j < gcvSRAM_INTER_COUNT; j++)
                {
                    if (kernel->sRAMPhysical[j] != gcvNULL)
                    {
                        /* Release reserved SRAM memory. */
                        gckOS_ReleaseReservedMemory(
                            Device->os,
                            kernel->sRAMPhysical[j]
                            );

                        kernel->sRAMPhysical[j] = gcvNULL;
                    }

                    if (kernel->sRAMVidMem[j] != gcvNULL)
                    {
                        /* Destroy the SRAM contiguous heap. */
                        gcmkVERIFY_OK(gckVIDMEM_Destroy(kernel->sRAMVidMem[j]));
                        kernel->sRAMVidMem[j] = gcvNULL;
                    }
                }
            }
        }

        if (Device->device)
        {
            gcmkVERIFY_OK(gckDEVICE_Destroy(Device->os, Device->device));

            for (i = 0; i < gcdMAX_GPU_COUNT; i++)
            {
                if (globalTA[i])
                {
                    gcTA_Destroy(globalTA[i]);
                    globalTA[i] = gcvNULL;
                }
            }

            Device->device = gcvNULL;
        }

        for (i = 0; i < gcdMAX_GPU_COUNT; i++)
        {
            if (Device->kernels[i] != gcvNULL)
            {
                Device->kernels[i] = gcvNULL;
            }
        }

        if (Device->internalLogical != gcvNULL)
        {
            /* Unmap the internal memory. */
            iounmap(Device->internalLogical);
            Device->internalLogical = gcvNULL;
        }

        if (Device->internalVidMem != gcvNULL)
        {
            /* Destroy the internal heap. */
            gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->internalVidMem));
            Device->internalVidMem = gcvNULL;
        }

        for (i = 0; i < gcvSRAM_EXT_COUNT; i++)
        {
            if (Device->extSRAMPhysical[i] != gcvNULL)
            {
                gckOS_ReleaseReservedMemory(
                    Device->os,
                    Device->extSRAMPhysical[i]
                    );
                Device->extSRAMPhysical[i] = gcvNULL;
            }

            if (Device->extSRAMVidMem[i] != gcvNULL)
            {
                gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->extSRAMVidMem[i]));
                Device->extSRAMVidMem[i] = gcvNULL;
            }
        }

        if (Device->externalPhysical != gcvNULL)
        {
            gckOS_ReleaseReservedMemory(
                Device->os,
                Device->externalPhysical
                );
            Device->externalPhysical = gcvNULL;
        }

        if (Device->externalLogical != gcvNULL)
        {
            Device->externalLogical = gcvNULL;
        }

        if (Device->externalVidMem != gcvNULL)
        {
            /* destroy the external heap */
            gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->externalVidMem));
            Device->externalVidMem = gcvNULL;
        }

        /*
         * Destroy contiguous memory pool after gckDEVICE destroyed. gckDEVICE
         * may allocates GPU memory types from SYSTEM pool.
         */
        if (Device->contiguousPhysical != gcvNULL)
        {
            if (Device->requestedContiguousBase == 0)
            {
                gcmkVERIFY_OK(_FreeMemory(
                    Device,
                    Device->contiguousLogical,
                    Device->contiguousPhysical
                    ));
            }
            else
            {
                gckOS_ReleaseReservedMemory(
                    Device->os,
                    Device->contiguousPhysical
                    );
                Device->contiguousPhysical = gcvNULL;
                Device->requestedContiguousBase = 0;
                Device->requestedContiguousSize = 0;
            }

            Device->contiguousLogical  = gcvNULL;
            Device->contiguousPhysical = gcvNULL;
        }

        if (Device->contiguousVidMem != gcvNULL)
        {
            /* Destroy the contiguous heap. */
            gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->contiguousVidMem));
            Device->contiguousVidMem = gcvNULL;
        }

        for (i = 0; i < gcdMAX_GPU_COUNT; i++)
        {
            if (Device->registerBases[i])
            {
                /* Unmap register memory. */
                if (Device->requestedRegisterMemBases[i] != 0)
                {
                    iounmap(Device->registerBases[i]);
                    release_mem_region(Device->requestedRegisterMemBases[i],
                            Device->requestedRegisterMemSizes[i]);
                }

                Device->registerBases[i] = gcvNULL;
                Device->requestedRegisterMemBases[i] = 0;
                Device->requestedRegisterMemSizes[i] = 0;
            }
        }


        if (Device->taos)
        {
            gcmkVERIFY_OK(gctaOS_DestroyOS(Device->taos));
            Device->taos = gcvNULL;
        }

        /* Destroy the gckOS object. */
        if (Device->os != gcvNULL)
        {
            gcmkVERIFY_OK(gckOS_Destroy(Device->os));
            Device->os = gcvNULL;
        }

        _DebugfsCleanup(Device);

        /* Free the device. */
        kfree(Device);
    }

    gcmkFOOTER_NO();
    return gcvSTATUS_OK;
}

/*******************************************************************************
**
**  gckGALDEVICE_Start
**
**  Start the gal device, including the following actions: setup the isr routine
**  and start the daemoni thread.
**
**  INPUT:
**
**      gckGALDEVICE Device
**          Pointer to an gckGALDEVICE object.
**
**  OUTPUT:
**
**      Nothing.
**
**  RETURNS:
**
**      gcvSTATUS_OK
**          Start successfully.
*/
gceSTATUS
gckGALDEVICE_Start(
    IN gckGALDEVICE Device
    )
{
    gctUINT i;
    gceSTATUS status = gcvSTATUS_OK;

    gcmkHEADER_ARG("Device=%p", Device);

    /* Start the kernel threads. */
    for (i = 0; i < gcvCORE_COUNT; ++i)
    {
        if (i == gcvCORE_VG)
        {
            continue;
        }

        gcmkONERROR(_StartThread(Device, i));
    }

    for (i = 0; i < gcvCORE_COUNT; i++)
    {
        if (Device->kernels[i] == gcvNULL)
        {
            continue;
        }

        /* Setup the ISR routine. */
        gcmkONERROR(_SetupIsr(i));

        if (i == gcvCORE_VG)
        {
        }
        else
        {
            /* Switch to SUSPEND power state. */
            gcmkONERROR(gckHARDWARE_SetPowerState(
                Device->kernels[i]->hardware, gcvPOWER_OFF_BROADCAST
                ));

            gcmkONERROR(gckHARDWARE_StartTimerReset(Device->kernels[i]->hardware));
        }
    }

OnError:
    gcmkFOOTER();
    return status;
}

/*******************************************************************************
**
**  gckGALDEVICE_Stop
**
**  Stop the gal device, including the following actions: stop the daemon
**  thread, release the irq.
**
**  INPUT:
**
**      gckGALDEVICE Device
**          Pointer to an gckGALDEVICE object.
**
**  OUTPUT:
**
**      Nothing.
**
**  RETURNS:
**
**      Nothing.
*/
gceSTATUS
gckGALDEVICE_Stop(
    gckGALDEVICE Device
    )
{
    gctUINT i;
    gceSTATUS status = gcvSTATUS_OK;

    gcmkHEADER_ARG("Device=%p", Device);

    gcmkVERIFY_ARGUMENT(Device != NULL);

    for (i = 0; i < gcvCORE_COUNT; i++)
    {
        if (Device->kernels[i] == gcvNULL)
        {
            continue;
        }

        if (i == gcvCORE_VG)
        {
        }
        else
        {
            gcmkONERROR(gckHARDWARE_EnablePowerManagement(
                Device->kernels[i]->hardware, gcvTRUE
                ));

            /* Switch to OFF power state. */
            gcmkONERROR(gckHARDWARE_SetPowerState(
                Device->kernels[i]->hardware, gcvPOWER_OFF
                ));

            gckHARDWARE_StartTimerReset(Device->kernels[i]->hardware);
        }

        /* Stop the ISR routine. */
        gcmkONERROR(_ReleaseIsr(i));

    }

    /* Stop the kernel thread. */
    for (i = 0; i < gcvCORE_COUNT; i++)
    {
        _StopThread(Device, i);
    }

OnError:
    gcmkFOOTER();
    return status;
}

