static int thermal_hot_pm_notify(struct notifier_block *nb, unsigned long event,
	void *dummy)
{
    static gctUINT orgFscale, minFscale, maxFscale;
    static gctBOOL bAlreadyTooHot = gcvFALSE;
    gckHARDWARE hardware = galDevice->kernels[gcvCORE_MAJOR]->hardware;

    if (event && !bAlreadyTooHot) {
        gckHARDWARE_GetFscaleValue(hardware,&orgFscale,&minFscale, &maxFscale);
        gckHARDWARE_SetFscaleValue(hardware, minFscale);
        bAlreadyTooHot = gcvTRUE;
        gckOS_Print("System is too hot. GPU3D will work at %d/64 clock.\n", minFscale);
    } else if (!event && bAlreadyTooHot) {
        gckHARDWARE_SetFscaleValue(hardware, orgFscale);
        gckOS_Print("Hot alarm is canceled. GPU3D clock will return to %d/64\n", orgFscale);
        bAlreadyTooHot = gcvFALSE;
    }
    return NOTIFY_OK;
}
static int thermal_hot_pm_notify(struct notifier_block *nb, unsigned long event,
       void *dummy)
{
    static gctUINT orgFscale, minFscale, maxFscale;
    static gctBOOL bAlreadyTooHot = gcvFALSE;
    gckHARDWARE hardware;
    gckGALDEVICE galDevice;

    galDevice = platform_get_drvdata(pdevice);
    if (!galDevice)
    {
        /* GPU is not ready, so it is meaningless to change GPU freq. */
        return NOTIFY_OK;
    }

    if (!galDevice->kernels[gcvCORE_MAJOR])
    {
        return NOTIFY_OK;
    }

    hardware = galDevice->kernels[gcvCORE_MAJOR]->hardware;

    if (!hardware)
    {
        return NOTIFY_OK;
    }

    if (event && !bAlreadyTooHot) {
        gckHARDWARE_GetFscaleValue(hardware,&orgFscale,&minFscale, &maxFscale);
        gckHARDWARE_SetFscaleValue(hardware, minFscale);
        bAlreadyTooHot = gcvTRUE;
        gckOS_Print("System is too hot. GPU3D will work at %d/64 clock.\n", minFscale);
    } else if (!event && bAlreadyTooHot) {
        gckHARDWARE_SetFscaleValue(hardware, orgFscale);
        gckOS_Print("Hot alarm is canceled. GPU3D clock will return to %d/64\n", orgFscale);
        bAlreadyTooHot = gcvFALSE;
    }
    return NOTIFY_OK;
}
static int thermal_hot_pm_notify(struct notifier_block *nb, unsigned long event,
	void *dummy)
{
    static gctUINT orgFscale, minFscale, maxFscale;
    static gctBOOL critical;
    gckHARDWARE hardware = galDevice->kernels[gcvCORE_MAJOR]->hardware;

    if (event > 4) {
	critical = gcvTRUE;
        gckHARDWARE_GetFscaleValue(hardware,&orgFscale,&minFscale, &maxFscale);
        gckHARDWARE_SetFscaleValue(hardware, minFscale);
        gckOS_Print("System is too hot. GPU3D scalign to %d/64 clock.\n", minFscale);
    } else if (event > 1) {
        gckHARDWARE_GetFscaleValue(hardware,&orgFscale,&minFscale, &maxFscale);
        gckHARDWARE_SetFscaleValue(hardware, maxFscale - (8 * event));
    } else if (orgFscale) {
        gckHARDWARE_SetFscaleValue(hardware, orgFscale);
	if (critical) {
            gckOS_Print("Hot alarm is canceled. GPU3D clock will return to %d/64\n", orgFscale);
            critical = gcvFALSE;
        }
    }
    return NOTIFY_OK;
}
static ssize_t store_fscale (struct device *dev,
                    struct device_attribute *attr,
                    const char *buf, size_t count)
{
    int core, fscale, i, gpu_count;

    for (i = 0, gpu_count = 0; i < gcdMAX_GPU_COUNT; i++)
        if (galDevice->kernels[i] != gcvNULL)
            gpu_count++;

    /* read input and verify */
    SYSFS_VERIFY_INPUT(sscanf(buf, "%d,%d", &core, &fscale), 2);
    SYSFS_VERIFY_INPUT_RANGE(core, 0, (gpu_count-1));
    SYSFS_VERIFY_INPUT_RANGE(fscale, 1, 64);

#if gcdENABLE_FSCALE_VAL_ADJUST
    if(galDevice->kernels[core] != gcvNULL)
        gcmkVERIFY_OK(gckHARDWARE_SetFscaleValue(
                                galDevice->kernels[core]->hardware,
                                fscale));
#endif

    return count;
}