From 358ce15bc1205ea1d5cfaa78c1e6bfbbffb72e1d Mon Sep 17 00:00:00 2001 From: Lekensteyn Date: Sat, 14 Jan 2012 19:40:41 +0100 Subject: [PATCH 1/5] Probe for nvidia DSM on Intel ACPI handle (GH-4) --- bbswitch.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/bbswitch.c b/bbswitch.c index dfd634a..5bce3e5 100644 --- a/bbswitch.c +++ b/bbswitch.c @@ -328,6 +328,7 @@ static struct file_operations bbswitch_fops = { static int __init bbswitch_init(void) { struct proc_dir_entry *acpi_entry; struct pci_dev *pdev = NULL; + acpi_handle igd_handle = NULL; int class = PCI_CLASS_DISPLAY_VGA << 8; while ((pdev = pci_get_class(class, pdev)) != NULL) { @@ -338,10 +339,15 @@ static int __init bbswitch_init(void) { if (!handle) continue; - if (pdev->vendor != PCI_VENDOR_ID_INTEL) { + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buf); + + if (pdev->vendor == PCI_VENDOR_ID_INTEL) { + igd_handle = handle; + printk(KERN_INFO "bbswitch: Found integrated VGA device %s: %s\n", + dev_name(&pdev->dev), (char *)buf.pointer); + } else { dis_dev = pdev; dis_handle = handle; - acpi_get_name(handle, ACPI_FULL_PATHNAME, &buf); printk(KERN_INFO "bbswitch: Found discrete VGA device %s: %s\n", dev_name(&pdev->dev), (char *)buf.pointer); } @@ -360,8 +366,17 @@ static int __init bbswitch_init(void) { dsm_type = DSM_TYPE_NVIDIA; printk(KERN_INFO "bbswitch: detected a nVidia _DSM function\n"); } else { - printk(KERN_ERR "bbswitch: No suitable _DSM call found.\n"); - return -ENODEV; + /* At least two Acer machines are known to use the intel ACPI handle + * with the legacy nvidia DSM */ + dis_handle = igd_handle; + if (has_dsm_func(acpi_nvidia_dsm_muid, 0x102, 0x3)) { + dsm_type = DSM_TYPE_NVIDIA; + printk(KERN_INFO "bbswitch: detected a nVidia _DSM function on the" + " integrated video card\n"); + } else { + printk(KERN_ERR "bbswitch: No suitable _DSM call found.\n"); + return -ENODEV; + } } acpi_entry = proc_create("bbswitch", 0660, acpi_root_dir, &bbswitch_fops); From 5e297c27add5cde2ceaa0fdbbadd060800124e87 Mon Sep 17 00:00:00 2001 From: Lekensteyn Date: Sat, 14 Jan 2012 22:13:55 +0100 Subject: [PATCH 2/5] Add note that a driver must not be loaded if the card is off --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index feca059..56aed69 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,10 @@ unload the driver, $ dmesg |tail -1 bbswitch: device 0000:01:00.0 is in use by driver 'nouveau', refusing OFF +Do **not** attempt to load a driver while the card is off or the card won't be +usable until the PCI configuration space has been recovered (for example, after +writing the contents manually or rebooting). + Reporting bugs -------------- From 031bcfe8a62f2eae755993dd809291330bc40e59 Mon Sep 17 00:00:00 2001 From: Lekensteyn Date: Sat, 14 Jan 2012 22:49:46 +0100 Subject: [PATCH 3/5] Update README with module options --- README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/README.md b/README.md index 56aed69..5376608 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,39 @@ Do **not** attempt to load a driver while the card is off or the card won't be usable until the PCI configuration space has been recovered (for example, after writing the contents manually or rebooting). +### Module options + +The module has some options that control the behavior on loading and unloading: +`load_state` and `unload_state`. Valid values are `-1`, `0` and `1` meaning "do +not change the card state", "turn the card off" and "turn the card on" +respectively. For example, if you want to have `bbswitch` disable the card +immediately when loading the module while disabling the card on unload, load the +module with: + + # modprobe bbswitch load_state=0 unload_state=1 + +The `unload_state` value can be changed on runtime, the above command yields the +same behavior as: + + # modprobe bbswitch load_state=0 + # echo 1 | tee /sys/module/bbswitch/parameters/unload_state + +If not explictly set, the default behavior is not to change the power state of +the discrete video card which equals to `load_state=-1 unload_state=-1`. + +### Disable card on boot + +These options can be useful to disable the card on boot time. Depending on your +distribution, `/etc/modules`, `/etc/modules.conf` or some other file can be used +to load modules on boot time. Adding the below line to the file makes the card +get disabled on boot: + + bbswitch load_state=0 + +You have to update your initial ramdisk (initrd) for the changes propagate to +the boot process. On Debian and Ubuntu, this can performed by running +`update-initramfs -u` as root. + Reporting bugs -------------- From 9f0ae8f723e7c7098f70ac91aa768f06edefa375 Mon Sep 17 00:00:00 2001 From: Lekensteyn Date: Sat, 14 Jan 2012 22:54:33 +0100 Subject: [PATCH 4/5] Ignore files generated from build --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9d6c35d --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.cmd +.tmp_versions +Module.symvers +*.ko +*.mod.c +*.o +modules.order From c8b303c36c52587a904c2d8aa1d55c015fbba297 Mon Sep 17 00:00:00 2001 From: Lekensteyn Date: Sat, 14 Jan 2012 23:16:45 +0100 Subject: [PATCH 5/5] Add NEWS file, bump version to 0.3 --- NEWS | 10 ++++++++++ bbswitch.c | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 NEWS diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..1d1c033 --- /dev/null +++ b/NEWS @@ -0,0 +1,10 @@ +Version 0.3 - 14 January 2012 + +* Support for models that have the nvidia DSM method on the integrated Intel + video card instead of the nvidia one. This includes at the Acer Travelmate + 8472TG and Acer Aspire 5745G. + +Version 0.2 - 2 January 2012 + +* Initial release, adding a kernel module that can disable discrete nvidia cards + on Optimus systems. diff --git a/bbswitch.c b/bbswitch.c index 5bce3e5..7d69dee 100644 --- a/bbswitch.c +++ b/bbswitch.c @@ -19,7 +19,7 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Toggle the discrete graphics card"); MODULE_AUTHOR("Peter Lekensteyn "); -MODULE_VERSION("0.2"); +MODULE_VERSION("0.3"); enum { CARD_UNCHANGED = -1,