← Back to team overview

asus-ul30 team mailing list archive

solution to power down nvidia card in UL*0Vt models

 

Hi,

One of the Linux users has found a solution to switch off the nvidia
card in the UL30Vt models,
which by the looks of the DSDT tables, will also work for the UL50Vt
and UL80Vt models with nvidia card.

It uses the ACPI P0P1.VGA._OFF method, which is the same for all 3 models.

The code file, "asus_nvidia.c" is derived from "lenovo_acpi.c" by
Sylvain Joyeux.

Here is the original post and another one that adds hibernation support:
http://forum.notebookreview.com/showpost.php?p=5663702&postcount=1239
http://forum.notebookreview.com/showpost.php?p=5664880&postcount=1244

Cheers,

Albert.
#include <acpi/acpi.h>
#include <linux/suspend.h>

MODULE_LICENSE("GPL");

static acpi_handle root_handle;

static int kill_nvidia(void)
{
    acpi_status status;
    // The device handle
    acpi_handle handle;
    struct acpi_object_list args;
    // For the return value
    struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };

    status = acpi_get_handle(root_handle, "\\_SB.PCI0.P0P1.VGA._OFF", &handle);
    if (ACPI_FAILURE(status))
    {
        printk("%s: cannot get ACPI handle: %s\n", __func__, acpi_format_exception(status));
        return -ENOSYS;
    }

    args.count = 0;
    args.pointer = NULL;

    status = acpi_evaluate_object(handle, NULL, &args, &buffer);
    if (ACPI_FAILURE(status))
    {
        printk("%s: _OFF method call failed: %s\n", __func__, acpi_format_exception(status));
        return -ENOSYS;
    }
    kfree(buffer.pointer);

    printk("%s: disabled the discrete graphics card\n",__func__);
    return 0;
}

static int power_event(struct notifier_block *this, unsigned long event,
                       void *ptr)
{
        switch (event) {
        case PM_POST_HIBERNATION:
                kill_nvidia();
                return NOTIFY_DONE;
        case PM_POST_SUSPEND:
        case PM_HIBERNATION_PREPARE:
        case PM_SUSPEND_PREPARE:
        default:
                return NOTIFY_DONE;
        }
}

static struct notifier_block power_notifier = {
        .notifier_call = power_event,
};

static int __init asus_nvidia(void)
{
    int ret = register_pm_notifier(&power_notifier);
    if (ret) return ret;
    return kill_nvidia();
}

static void dummy(void)
{
}

module_init(asus_nvidia);
module_exit(dummy);

Attachment: Makefile
Description: Binary data