|
|
@ -16,10 +16,12 @@
|
|
|
|
#include <linux/suspend.h>
|
|
|
|
#include <linux/suspend.h>
|
|
|
|
#include <linux/seq_file.h>
|
|
|
|
#include <linux/seq_file.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define BBSWITCH_VERSION "0.4.2"
|
|
|
|
|
|
|
|
|
|
|
|
MODULE_LICENSE("GPL");
|
|
|
|
MODULE_LICENSE("GPL");
|
|
|
|
MODULE_DESCRIPTION("Toggle the discrete graphics card");
|
|
|
|
MODULE_DESCRIPTION("Toggle the discrete graphics card");
|
|
|
|
MODULE_AUTHOR("Peter Lekensteyn <lekensteyn@gmail.com>");
|
|
|
|
MODULE_AUTHOR("Peter Lekensteyn <lekensteyn@gmail.com>");
|
|
|
|
MODULE_VERSION("0.4.1");
|
|
|
|
MODULE_VERSION(BBSWITCH_VERSION);
|
|
|
|
|
|
|
|
|
|
|
|
enum {
|
|
|
|
enum {
|
|
|
|
CARD_UNCHANGED = -1,
|
|
|
|
CARD_UNCHANGED = -1,
|
|
|
@ -69,12 +71,11 @@ static struct notifier_block nb;
|
|
|
|
/* whether the card was off before suspend or not; on: 0, off: 1 */
|
|
|
|
/* whether the card was off before suspend or not; on: 0, off: 1 */
|
|
|
|
int dis_before_suspend_disabled;
|
|
|
|
int dis_before_suspend_disabled;
|
|
|
|
|
|
|
|
|
|
|
|
static char *buffer_to_string(const char buffer[], char *target) {
|
|
|
|
static char *buffer_to_string(const char *buffer, size_t n, char *target) {
|
|
|
|
int i;
|
|
|
|
int i;
|
|
|
|
for (i=0; i<sizeof(buffer); i++) {
|
|
|
|
for (i=0; i<n; i++) {
|
|
|
|
sprintf(target + i * 5, "%02X,", buffer[i]);
|
|
|
|
snprintf(target + i * 5, 5 * (n - i), "0x%02X,", buffer ? buffer[i] & 0xFF : 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
target[sizeof(buffer) * 5] = '\0';
|
|
|
|
|
|
|
|
return target;
|
|
|
|
return target;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -110,12 +111,13 @@ static int acpi_call_dsm(acpi_handle handle, const char muid[16], int revid,
|
|
|
|
|
|
|
|
|
|
|
|
err = acpi_evaluate_object(handle, "_DSM", &input, &output);
|
|
|
|
err = acpi_evaluate_object(handle, "_DSM", &input, &output);
|
|
|
|
if (err) {
|
|
|
|
if (err) {
|
|
|
|
char tmp[5 * max(sizeof(muid), sizeof(args))];
|
|
|
|
char muid_str[5 * 16];
|
|
|
|
|
|
|
|
char args_str[5 * 4];
|
|
|
|
|
|
|
|
|
|
|
|
printk(KERN_WARNING "bbswitch: failed to evaluate _DSM {%s} %X %X"
|
|
|
|
printk(KERN_WARNING "bbswitch: failed to evaluate _DSM {%s} 0x%X 0x%X"
|
|
|
|
" {%s}: %s\n",
|
|
|
|
" {%s}: %s\n",
|
|
|
|
buffer_to_string(muid, tmp), revid, func,
|
|
|
|
buffer_to_string(muid, 16, muid_str), revid, func,
|
|
|
|
buffer_to_string(args, tmp), acpi_format_exception(err));
|
|
|
|
buffer_to_string(args, 4, args_str), acpi_format_exception(err));
|
|
|
|
return err;
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -330,6 +332,8 @@ static int __init bbswitch_init(void) {
|
|
|
|
struct pci_dev *pdev = NULL;
|
|
|
|
struct pci_dev *pdev = NULL;
|
|
|
|
acpi_handle igd_handle = NULL;
|
|
|
|
acpi_handle igd_handle = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printk(KERN_INFO "bbswitch: version %s\n", BBSWITCH_VERSION);
|
|
|
|
|
|
|
|
|
|
|
|
while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
|
|
|
|
while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
|
|
|
|
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
|
|
|
|
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
|
|
|
|
acpi_handle handle;
|
|
|
|
acpi_handle handle;
|
|
|
@ -386,7 +390,7 @@ static int __init bbswitch_init(void) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
acpi_entry = proc_create("bbswitch", 0660, acpi_root_dir, &bbswitch_fops);
|
|
|
|
acpi_entry = proc_create("bbswitch", 0664, acpi_root_dir, &bbswitch_fops);
|
|
|
|
if (acpi_entry == NULL) {
|
|
|
|
if (acpi_entry == NULL) {
|
|
|
|
printk(KERN_ERR "bbswitch: Couldn't create proc entry\n");
|
|
|
|
printk(KERN_ERR "bbswitch: Couldn't create proc entry\n");
|
|
|
|
return -ENOMEM;
|
|
|
|
return -ENOMEM;
|
|
|
|