diff options
| author | Len Brown <len.brown@intel.com> | 2010-08-15 01:06:31 -0400 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2010-08-15 01:06:31 -0400 |
| commit | 95ee46aa8698f2000647dfb362400fadbb5807cf (patch) | |
| tree | e5a05c7297f997e191c73091934e42e3195c0e40 /drivers/acpi | |
| parent | cfa806f059801dbe7e435745eb2e187c8bfe1e7f (diff) | |
| parent | 92fa5bd9a946b6e7aab6764e7312e4e3d9bed295 (diff) | |
Merge branch 'linus' into release
Conflicts:
drivers/acpi/debug.c
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
| -rw-r--r-- | drivers/acpi/Kconfig | 18 | ||||
| -rw-r--r-- | drivers/acpi/Makefile | 1 | ||||
| -rw-r--r-- | drivers/acpi/acpi_pad.c | 2 | ||||
| -rw-r--r-- | drivers/acpi/apei/erst.c | 1 | ||||
| -rw-r--r-- | drivers/acpi/ec.c | 107 | ||||
| -rw-r--r-- | drivers/acpi/ec_sys.c | 160 | ||||
| -rw-r--r-- | drivers/acpi/internal.h | 24 | ||||
| -rw-r--r-- | drivers/acpi/osl.c | 40 | ||||
| -rw-r--r-- | drivers/acpi/pci_root.c | 9 | ||||
| -rw-r--r-- | drivers/acpi/processor_idle.c | 4 |
10 files changed, 241 insertions, 125 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 5ed51b3d7522..b811f2173f6f 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
| @@ -97,6 +97,24 @@ config ACPI_SYSFS_POWER | |||
| 97 | help | 97 | help |
| 98 | Say N to disable power /sys interface | 98 | Say N to disable power /sys interface |
| 99 | 99 | ||
| 100 | config ACPI_EC_DEBUGFS | ||
| 101 | tristate "EC read/write access through /sys/kernel/debug/ec" | ||
| 102 | default n | ||
| 103 | help | ||
| 104 | Say N to disable Embedded Controller /sys/kernel/debug interface | ||
| 105 | |||
| 106 | Be aware that using this interface can confuse your Embedded | ||
| 107 | Controller in a way that a normal reboot is not enough. You then | ||
| 108 | have to power of your system, and remove the laptop battery for | ||
| 109 | some seconds. | ||
| 110 | An Embedded Controller typically is available on laptops and reads | ||
| 111 | sensor values like battery state and temperature. | ||
| 112 | The kernel accesses the EC through ACPI parsed code provided by BIOS | ||
| 113 | tables. This option allows to access the EC directly without ACPI | ||
| 114 | code being involved. | ||
| 115 | Thus this option is a debug option that helps to write ACPI drivers | ||
| 116 | and can be used to identify ACPI code or EC firmware bugs. | ||
| 117 | |||
| 100 | config ACPI_PROC_EVENT | 118 | config ACPI_PROC_EVENT |
| 101 | bool "Deprecated /proc/acpi/event support" | 119 | bool "Deprecated /proc/acpi/event support" |
| 102 | depends on PROC_FS | 120 | depends on PROC_FS |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 3f0449622e69..3d031d02e54b 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
| @@ -61,6 +61,7 @@ obj-$(CONFIG_ACPI_SBS) += sbshc.o | |||
| 61 | obj-$(CONFIG_ACPI_SBS) += sbs.o | 61 | obj-$(CONFIG_ACPI_SBS) += sbs.o |
| 62 | obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o | 62 | obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o |
| 63 | obj-$(CONFIG_ACPI_HED) += hed.o | 63 | obj-$(CONFIG_ACPI_HED) += hed.o |
| 64 | obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o | ||
| 64 | 65 | ||
| 65 | # processor has its own "processor." module_param namespace | 66 | # processor has its own "processor." module_param namespace |
| 66 | processor-y := processor_driver.o processor_throttling.o | 67 | processor-y := processor_driver.o processor_throttling.o |
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 446aced33aff..b76848c80be3 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c | |||
| @@ -77,7 +77,7 @@ static void power_saving_mwait_init(void) | |||
| 77 | power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) | | 77 | power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) | |
| 78 | (highest_subcstate - 1); | 78 | (highest_subcstate - 1); |
| 79 | 79 | ||
| 80 | #if defined(CONFIG_GENERIC_TIME) && defined(CONFIG_X86) | 80 | #if defined(CONFIG_X86) |
| 81 | switch (boot_cpu_data.x86_vendor) { | 81 | switch (boot_cpu_data.x86_vendor) { |
| 82 | case X86_VENDOR_AMD: | 82 | case X86_VENDOR_AMD: |
| 83 | case X86_VENDOR_INTEL: | 83 | case X86_VENDOR_INTEL: |
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 864dd46c346f..18645f4e83cd 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <linux/uaccess.h> | 33 | #include <linux/uaccess.h> |
| 34 | #include <linux/cper.h> | 34 | #include <linux/cper.h> |
| 35 | #include <linux/nmi.h> | 35 | #include <linux/nmi.h> |
| 36 | #include <linux/hardirq.h> | ||
| 36 | #include <acpi/apei.h> | 37 | #include <acpi/apei.h> |
| 37 | 38 | ||
| 38 | #include "apei-internal.h" | 39 | #include "apei-internal.h" |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 1e6d4184f0ea..f31291ba94d0 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
| @@ -34,8 +34,6 @@ | |||
| 34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
| 35 | #include <linux/types.h> | 35 | #include <linux/types.h> |
| 36 | #include <linux/delay.h> | 36 | #include <linux/delay.h> |
| 37 | #include <linux/proc_fs.h> | ||
| 38 | #include <linux/seq_file.h> | ||
| 39 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
| 40 | #include <linux/list.h> | 38 | #include <linux/list.h> |
| 41 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
| @@ -45,10 +43,13 @@ | |||
| 45 | #include <acpi/acpi_drivers.h> | 43 | #include <acpi/acpi_drivers.h> |
| 46 | #include <linux/dmi.h> | 44 | #include <linux/dmi.h> |
| 47 | 45 | ||
| 46 | #include "internal.h" | ||
| 47 | |||
| 48 | #define ACPI_EC_CLASS "embedded_controller" | 48 | #define ACPI_EC_CLASS "embedded_controller" |
| 49 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" | 49 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" |
| 50 | #define ACPI_EC_FILE_INFO "info" | 50 | #define ACPI_EC_FILE_INFO "info" |
| 51 | 51 | ||
| 52 | #undef PREFIX | ||
| 52 | #define PREFIX "ACPI: EC: " | 53 | #define PREFIX "ACPI: EC: " |
| 53 | 54 | ||
| 54 | /* EC status register */ | 55 | /* EC status register */ |
| @@ -106,19 +107,8 @@ struct transaction { | |||
| 106 | bool done; | 107 | bool done; |
| 107 | }; | 108 | }; |
| 108 | 109 | ||
| 109 | static struct acpi_ec { | 110 | struct acpi_ec *boot_ec, *first_ec; |
| 110 | acpi_handle handle; | 111 | EXPORT_SYMBOL(first_ec); |
| 111 | unsigned long gpe; | ||
| 112 | unsigned long command_addr; | ||
| 113 | unsigned long data_addr; | ||
| 114 | unsigned long global_lock; | ||
| 115 | unsigned long flags; | ||
| 116 | struct mutex lock; | ||
| 117 | wait_queue_head_t wait; | ||
| 118 | struct list_head list; | ||
| 119 | struct transaction *curr; | ||
| 120 | spinlock_t curr_lock; | ||
| 121 | } *boot_ec, *first_ec; | ||
| 122 | 112 | ||
| 123 | static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ | 113 | static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ |
| 124 | static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ | 114 | static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ |
| @@ -672,72 +662,6 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, | |||
| 672 | } | 662 | } |
| 673 | 663 | ||
| 674 | /* -------------------------------------------------------------------------- | 664 | /* -------------------------------------------------------------------------- |
| 675 | FS Interface (/proc) | ||
| 676 | -------------------------------------------------------------------------- */ | ||
| 677 | |||
| 678 | static struct proc_dir_entry *acpi_ec_dir; | ||
| 679 | |||
| 680 | static int acpi_ec_read_info(struct seq_file *seq, void *offset) | ||
| 681 | { | ||
| 682 | struct acpi_ec *ec = seq->private; | ||
| 683 | |||
| 684 | if (!ec) | ||
| 685 | goto end; | ||
| 686 | |||
| 687 | seq_printf(seq, "gpe:\t\t\t0x%02x\n", (u32) ec->gpe); | ||
| 688 | seq_printf(seq, "ports:\t\t\t0x%02x, 0x%02x\n", | ||
| 689 | (unsigned)ec->command_addr, (unsigned)ec->data_addr); | ||
| 690 | seq_printf(seq, "use global lock:\t%s\n", | ||
| 691 | ec->global_lock ? "yes" : "no"); | ||
| 692 | end: | ||
| 693 | return 0; | ||
| 694 | } | ||
| 695 | |||
| 696 | static int acpi_ec_info_open_fs(struct inode *inode, struct file *file) | ||
| 697 | { | ||
| 698 | return single_open(file, acpi_ec_read_info, PDE(inode)->data); | ||
| 699 | } | ||
| 700 | |||
| 701 | static const struct file_operations acpi_ec_info_ops = { | ||
| 702 | .open = acpi_ec_info_open_fs, | ||
| 703 | .read = seq_read, | ||
| 704 | .llseek = seq_lseek, | ||
| 705 | .release = single_release, | ||
| 706 | .owner = THIS_MODULE, | ||
| 707 | }; | ||
| 708 | |||
| 709 | static int acpi_ec_add_fs(struct acpi_device *device) | ||
| 710 | { | ||
| 711 | struct proc_dir_entry *entry = NULL; | ||
| 712 | |||
| 713 | if (!acpi_device_dir(device)) { | ||
| 714 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | ||
| 715 | acpi_ec_dir); | ||
| 716 | if (!acpi_device_dir(device)) | ||
| 717 | return -ENODEV; | ||
| 718 | } | ||
| 719 | |||
| 720 | entry = proc_create_data(ACPI_EC_FILE_INFO, S_IRUGO, | ||
| 721 | acpi_device_dir(device), | ||
| 722 | &acpi_ec_info_ops, acpi_driver_data(device)); | ||
| 723 | if (!entry) | ||
| 724 | return -ENODEV; | ||
| 725 | return 0; | ||
| 726 | } | ||
| 727 | |||
| 728 | static int acpi_ec_remove_fs(struct acpi_device *device) | ||
| 729 | { | ||
| 730 | |||
| 731 | if (acpi_device_dir(device)) { | ||
| 732 | remove_proc_entry(ACPI_EC_FILE_INFO, acpi_device_dir(device)); | ||
| 733 | remove_proc_entry(acpi_device_bid(device), acpi_ec_dir); | ||
| 734 | acpi_device_dir(device) = NULL; | ||
| 735 | } | ||
| 736 | |||
| 737 | return 0; | ||
| 738 | } | ||
| 739 | |||
| 740 | /* -------------------------------------------------------------------------- | ||
| 741 | Driver Interface | 665 | Driver Interface |
| 742 | -------------------------------------------------------------------------- */ | 666 | -------------------------------------------------------------------------- */ |
| 743 | static acpi_status | 667 | static acpi_status |
| @@ -887,7 +811,12 @@ static int acpi_ec_add(struct acpi_device *device) | |||
| 887 | if (!first_ec) | 811 | if (!first_ec) |
| 888 | first_ec = ec; | 812 | first_ec = ec; |
| 889 | device->driver_data = ec; | 813 | device->driver_data = ec; |
| 890 | acpi_ec_add_fs(device); | 814 | |
| 815 | WARN(!request_region(ec->data_addr, 1, "EC data"), | ||
| 816 | "Could not request EC data io port 0x%lx", ec->data_addr); | ||
| 817 | WARN(!request_region(ec->command_addr, 1, "EC cmd"), | ||
| 818 | "Could not request EC cmd io port 0x%lx", ec->command_addr); | ||
| 819 | |||
| 891 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", | 820 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", |
| 892 | ec->gpe, ec->command_addr, ec->data_addr); | 821 | ec->gpe, ec->command_addr, ec->data_addr); |
| 893 | 822 | ||
| @@ -914,7 +843,8 @@ static int acpi_ec_remove(struct acpi_device *device, int type) | |||
| 914 | kfree(handler); | 843 | kfree(handler); |
| 915 | } | 844 | } |
| 916 | mutex_unlock(&ec->lock); | 845 | mutex_unlock(&ec->lock); |
| 917 | acpi_ec_remove_fs(device); | 846 | release_region(ec->data_addr, 1); |
| 847 | release_region(ec->command_addr, 1); | ||
| 918 | device->driver_data = NULL; | 848 | device->driver_data = NULL; |
| 919 | if (ec == first_ec) | 849 | if (ec == first_ec) |
| 920 | first_ec = NULL; | 850 | first_ec = NULL; |
| @@ -1095,16 +1025,10 @@ int __init acpi_ec_init(void) | |||
| 1095 | { | 1025 | { |
| 1096 | int result = 0; | 1026 | int result = 0; |
| 1097 | 1027 | ||
| 1098 | acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir); | ||
| 1099 | if (!acpi_ec_dir) | ||
| 1100 | return -ENODEV; | ||
| 1101 | |||
| 1102 | /* Now register the driver for the EC */ | 1028 | /* Now register the driver for the EC */ |
| 1103 | result = acpi_bus_register_driver(&acpi_ec_driver); | 1029 | result = acpi_bus_register_driver(&acpi_ec_driver); |
| 1104 | if (result < 0) { | 1030 | if (result < 0) |
| 1105 | remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir); | ||
| 1106 | return -ENODEV; | 1031 | return -ENODEV; |
| 1107 | } | ||
| 1108 | 1032 | ||
| 1109 | return result; | 1033 | return result; |
| 1110 | } | 1034 | } |
| @@ -1115,9 +1039,6 @@ static void __exit acpi_ec_exit(void) | |||
| 1115 | { | 1039 | { |
| 1116 | 1040 | ||
| 1117 | acpi_bus_unregister_driver(&acpi_ec_driver); | 1041 | acpi_bus_unregister_driver(&acpi_ec_driver); |
| 1118 | |||
| 1119 | remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir); | ||
| 1120 | |||
| 1121 | return; | 1042 | return; |
| 1122 | } | 1043 | } |
| 1123 | #endif /* 0 */ | 1044 | #endif /* 0 */ |
diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c new file mode 100644 index 000000000000..0e869b3f81ca --- /dev/null +++ b/drivers/acpi/ec_sys.c | |||
| @@ -0,0 +1,160 @@ | |||
| 1 | /* | ||
| 2 | * ec_sys.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 SUSE Products GmbH/Novell | ||
| 5 | * Author: | ||
| 6 | * Thomas Renninger <trenn@suse.de> | ||
| 7 | * | ||
| 8 | * This work is licensed under the terms of the GNU GPL, version 2. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/acpi.h> | ||
| 13 | #include <linux/debugfs.h> | ||
| 14 | #include "internal.h" | ||
| 15 | |||
| 16 | MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>"); | ||
| 17 | MODULE_DESCRIPTION("ACPI EC sysfs access driver"); | ||
| 18 | MODULE_LICENSE("GPL"); | ||
| 19 | |||
| 20 | static bool write_support; | ||
| 21 | module_param(write_support, bool, 0644); | ||
| 22 | MODULE_PARM_DESC(write_support, "Dangerous, reboot and removal of battery may " | ||
| 23 | "be needed."); | ||
| 24 | |||
| 25 | #define EC_SPACE_SIZE 256 | ||
| 26 | |||
| 27 | struct sysdev_class acpi_ec_sysdev_class = { | ||
| 28 | .name = "ec", | ||
| 29 | }; | ||
| 30 | |||
| 31 | static struct dentry *acpi_ec_debugfs_dir; | ||
| 32 | |||
| 33 | static int acpi_ec_open_io(struct inode *i, struct file *f) | ||
| 34 | { | ||
| 35 | f->private_data = i->i_private; | ||
| 36 | return 0; | ||
| 37 | } | ||
| 38 | |||
| 39 | static ssize_t acpi_ec_read_io(struct file *f, char __user *buf, | ||
| 40 | size_t count, loff_t *off) | ||
| 41 | { | ||
| 42 | /* Use this if support reading/writing multiple ECs exists in ec.c: | ||
| 43 | * struct acpi_ec *ec = ((struct seq_file *)f->private_data)->private; | ||
| 44 | */ | ||
| 45 | unsigned int size = EC_SPACE_SIZE; | ||
| 46 | u8 *data = (u8 *) buf; | ||
| 47 | loff_t init_off = *off; | ||
| 48 | int err = 0; | ||
| 49 | |||
| 50 | if (*off >= size) | ||
| 51 | return 0; | ||
| 52 | if (*off + count >= size) { | ||
| 53 | size -= *off; | ||
| 54 | count = size; | ||
| 55 | } else | ||
| 56 | size = count; | ||
| 57 | |||
| 58 | while (size) { | ||
| 59 | err = ec_read(*off, &data[*off - init_off]); | ||
| 60 | if (err) | ||
| 61 | return err; | ||
| 62 | *off += 1; | ||
| 63 | size--; | ||
| 64 | } | ||
| 65 | return count; | ||
| 66 | } | ||
| 67 | |||
| 68 | static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf, | ||
| 69 | size_t count, loff_t *off) | ||
| 70 | { | ||
| 71 | /* Use this if support reading/writing multiple ECs exists in ec.c: | ||
| 72 | * struct acpi_ec *ec = ((struct seq_file *)f->private_data)->private; | ||
| 73 | */ | ||
| 74 | |||
| 75 | unsigned int size = count; | ||
| 76 | loff_t init_off = *off; | ||
| 77 | u8 *data = (u8 *) buf; | ||
| 78 | int err = 0; | ||
| 79 | |||
| 80 | if (*off >= EC_SPACE_SIZE) | ||
| 81 | return 0; | ||
| 82 | if (*off + count >= EC_SPACE_SIZE) { | ||
| 83 | size = EC_SPACE_SIZE - *off; | ||
| 84 | count = size; | ||
| 85 | } | ||
| 86 | |||
| 87 | while (size) { | ||
| 88 | u8 byte_write = data[*off - init_off]; | ||
| 89 | err = ec_write(*off, byte_write); | ||
| 90 | if (err) | ||
| 91 | return err; | ||
| 92 | |||
| 93 | *off += 1; | ||
| 94 | size--; | ||
| 95 | } | ||
| 96 | return count; | ||
| 97 | } | ||
| 98 | |||
| 99 | static struct file_operations acpi_ec_io_ops = { | ||
| 100 | .owner = THIS_MODULE, | ||
| 101 | .open = acpi_ec_open_io, | ||
| 102 | .read = acpi_ec_read_io, | ||
| 103 | .write = acpi_ec_write_io, | ||
| 104 | }; | ||
| 105 | |||
| 106 | int acpi_ec_add_debugfs(struct acpi_ec *ec, unsigned int ec_device_count) | ||
| 107 | { | ||
| 108 | struct dentry *dev_dir; | ||
| 109 | char name[64]; | ||
| 110 | mode_t mode = 0400; | ||
| 111 | |||
| 112 | if (ec_device_count == 0) { | ||
| 113 | acpi_ec_debugfs_dir = debugfs_create_dir("ec", NULL); | ||
| 114 | if (!acpi_ec_debugfs_dir) | ||
| 115 | return -ENOMEM; | ||
| 116 | } | ||
| 117 | |||
| 118 | sprintf(name, "ec%u", ec_device_count); | ||
| 119 | dev_dir = debugfs_create_dir(name, acpi_ec_debugfs_dir); | ||
| 120 | if (!dev_dir) { | ||
| 121 | if (ec_device_count != 0) | ||
| 122 | goto error; | ||
| 123 | return -ENOMEM; | ||
| 124 | } | ||
| 125 | |||
| 126 | if (!debugfs_create_x32("gpe", 0444, dev_dir, (u32 *)&first_ec->gpe)) | ||
| 127 | goto error; | ||
| 128 | if (!debugfs_create_bool("use_global_lock", 0444, dev_dir, | ||
| 129 | (u32 *)&first_ec->global_lock)) | ||
| 130 | goto error; | ||
| 131 | |||
| 132 | if (write_support) | ||
| 133 | mode = 0600; | ||
| 134 | if (!debugfs_create_file("io", mode, dev_dir, ec, &acpi_ec_io_ops)) | ||
| 135 | goto error; | ||
| 136 | |||
| 137 | return 0; | ||
| 138 | |||
| 139 | error: | ||
| 140 | debugfs_remove_recursive(acpi_ec_debugfs_dir); | ||
| 141 | return -ENOMEM; | ||
| 142 | } | ||
| 143 | |||
| 144 | static int __init acpi_ec_sys_init(void) | ||
| 145 | { | ||
| 146 | int err = 0; | ||
| 147 | if (first_ec) | ||
| 148 | err = acpi_ec_add_debugfs(first_ec, 0); | ||
| 149 | else | ||
| 150 | err = -ENODEV; | ||
| 151 | return err; | ||
| 152 | } | ||
| 153 | |||
| 154 | static void __exit acpi_ec_sys_exit(void) | ||
| 155 | { | ||
| 156 | debugfs_remove_recursive(acpi_ec_debugfs_dir); | ||
| 157 | } | ||
| 158 | |||
| 159 | module_init(acpi_ec_sys_init); | ||
| 160 | module_exit(acpi_ec_sys_exit); | ||
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index e37964439d66..a212bfeddf8c 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
| @@ -18,6 +18,11 @@ | |||
| 18 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | 18 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | #ifndef _ACPI_INTERNAL_H_ | ||
| 22 | #define _ACPI_INTERNAL_H_ | ||
| 23 | |||
| 24 | #include <linux/sysdev.h> | ||
| 25 | |||
| 21 | #define PREFIX "ACPI: " | 26 | #define PREFIX "ACPI: " |
| 22 | 27 | ||
| 23 | int init_acpi_device_notify(void); | 28 | int init_acpi_device_notify(void); |
| @@ -46,6 +51,23 @@ void acpi_early_processor_set_pdc(void); | |||
| 46 | /* -------------------------------------------------------------------------- | 51 | /* -------------------------------------------------------------------------- |
| 47 | Embedded Controller | 52 | Embedded Controller |
| 48 | -------------------------------------------------------------------------- */ | 53 | -------------------------------------------------------------------------- */ |
| 54 | struct acpi_ec { | ||
| 55 | acpi_handle handle; | ||
| 56 | unsigned long gpe; | ||
| 57 | unsigned long command_addr; | ||
| 58 | unsigned long data_addr; | ||
| 59 | unsigned long global_lock; | ||
| 60 | unsigned long flags; | ||
| 61 | struct mutex lock; | ||
| 62 | wait_queue_head_t wait; | ||
| 63 | struct list_head list; | ||
| 64 | struct transaction *curr; | ||
| 65 | spinlock_t curr_lock; | ||
| 66 | struct sys_device sysdev; | ||
| 67 | }; | ||
| 68 | |||
| 69 | extern struct acpi_ec *first_ec; | ||
| 70 | |||
| 49 | int acpi_ec_init(void); | 71 | int acpi_ec_init(void); |
| 50 | int acpi_ec_ecdt_probe(void); | 72 | int acpi_ec_ecdt_probe(void); |
| 51 | int acpi_boot_ec_enable(void); | 73 | int acpi_boot_ec_enable(void); |
| @@ -63,3 +85,5 @@ int acpi_sleep_proc_init(void); | |||
| 63 | #else | 85 | #else |
| 64 | static inline int acpi_sleep_proc_init(void) { return 0; } | 86 | static inline int acpi_sleep_proc_init(void) { return 0; } |
| 65 | #endif | 87 | #endif |
| 88 | |||
| 89 | #endif /* _ACPI_INTERNAL_H_ */ | ||
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 03017b1eb38b..65b25a303b86 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
| @@ -190,36 +190,11 @@ acpi_status __init acpi_os_initialize(void) | |||
| 190 | return AE_OK; | 190 | return AE_OK; |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | static void bind_to_cpu0(struct work_struct *work) | ||
| 194 | { | ||
| 195 | set_cpus_allowed_ptr(current, cpumask_of(0)); | ||
| 196 | kfree(work); | ||
| 197 | } | ||
| 198 | |||
| 199 | static void bind_workqueue(struct workqueue_struct *wq) | ||
| 200 | { | ||
| 201 | struct work_struct *work; | ||
| 202 | |||
| 203 | work = kzalloc(sizeof(struct work_struct), GFP_KERNEL); | ||
| 204 | INIT_WORK(work, bind_to_cpu0); | ||
| 205 | queue_work(wq, work); | ||
| 206 | } | ||
| 207 | |||
| 208 | acpi_status acpi_os_initialize1(void) | 193 | acpi_status acpi_os_initialize1(void) |
| 209 | { | 194 | { |
| 210 | /* | 195 | kacpid_wq = create_workqueue("kacpid"); |
| 211 | * On some machines, a software-initiated SMI causes corruption unless | 196 | kacpi_notify_wq = create_workqueue("kacpi_notify"); |
| 212 | * the SMI runs on CPU 0. An SMI can be initiated by any AML, but | 197 | kacpi_hotplug_wq = create_workqueue("kacpi_hotplug"); |
| 213 | * typically it's done in GPE-related methods that are run via | ||
| 214 | * workqueues, so we can avoid the known corruption cases by binding | ||
| 215 | * the workqueues to CPU 0. | ||
| 216 | */ | ||
| 217 | kacpid_wq = create_singlethread_workqueue("kacpid"); | ||
| 218 | bind_workqueue(kacpid_wq); | ||
| 219 | kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify"); | ||
| 220 | bind_workqueue(kacpi_notify_wq); | ||
| 221 | kacpi_hotplug_wq = create_singlethread_workqueue("kacpi_hotplug"); | ||
| 222 | bind_workqueue(kacpi_hotplug_wq); | ||
| 223 | BUG_ON(!kacpid_wq); | 198 | BUG_ON(!kacpid_wq); |
| 224 | BUG_ON(!kacpi_notify_wq); | 199 | BUG_ON(!kacpi_notify_wq); |
| 225 | BUG_ON(!kacpi_hotplug_wq); | 200 | BUG_ON(!kacpi_hotplug_wq); |
| @@ -765,7 +740,14 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, | |||
| 765 | else | 740 | else |
| 766 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | 741 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); |
| 767 | 742 | ||
| 768 | ret = queue_work(queue, &dpc->work); | 743 | /* |
| 744 | * On some machines, a software-initiated SMI causes corruption unless | ||
| 745 | * the SMI runs on CPU 0. An SMI can be initiated by any AML, but | ||
| 746 | * typically it's done in GPE-related methods that are run via | ||
| 747 | * workqueues, so we can avoid the known corruption cases by always | ||
| 748 | * queueing on CPU 0. | ||
| 749 | */ | ||
| 750 | ret = queue_work_on(0, queue, &dpc->work); | ||
| 769 | 751 | ||
| 770 | if (!ret) { | 752 | if (!ret) { |
| 771 | printk(KERN_ERR PREFIX | 753 | printk(KERN_ERR PREFIX |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 4eac59393edc..1f67057af2a5 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <linux/pm_runtime.h> | 33 | #include <linux/pm_runtime.h> |
| 34 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
| 35 | #include <linux/pci-acpi.h> | 35 | #include <linux/pci-acpi.h> |
| 36 | #include <linux/pci-aspm.h> | ||
| 36 | #include <linux/acpi.h> | 37 | #include <linux/acpi.h> |
| 37 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
| 38 | #include <acpi/acpi_bus.h> | 39 | #include <acpi/acpi_bus.h> |
| @@ -543,6 +544,14 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
| 543 | if (flags != base_flags) | 544 | if (flags != base_flags) |
| 544 | acpi_pci_osc_support(root, flags); | 545 | acpi_pci_osc_support(root, flags); |
| 545 | 546 | ||
| 547 | status = acpi_pci_osc_control_set(root->device->handle, | ||
| 548 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
| 549 | |||
| 550 | if (ACPI_FAILURE(status)) { | ||
| 551 | printk(KERN_INFO "Unable to assume PCIe control: Disabling ASPM\n"); | ||
| 552 | pcie_no_aspm(); | ||
| 553 | } | ||
| 554 | |||
| 546 | pci_acpi_add_bus_pm_notifier(device, root->bus); | 555 | pci_acpi_add_bus_pm_notifier(device, root->bus); |
| 547 | if (device->wakeup.flags.run_wake) | 556 | if (device->wakeup.flags.run_wake) |
| 548 | device_set_run_wake(root->bus->bridge, true); | 557 | device_set_run_wake(root->bus->bridge, true); |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 07bc74d8356e..f4428e82b352 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
| @@ -155,7 +155,7 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr, | |||
| 155 | if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT)) | 155 | if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT)) |
| 156 | return; | 156 | return; |
| 157 | 157 | ||
| 158 | if (boot_cpu_has(X86_FEATURE_AMDC1E)) | 158 | if (c1e_detected) |
| 159 | type = ACPI_STATE_C1; | 159 | type = ACPI_STATE_C1; |
| 160 | 160 | ||
| 161 | /* | 161 | /* |
| @@ -255,7 +255,7 @@ int acpi_processor_resume(struct acpi_device * device) | |||
| 255 | return 0; | 255 | return 0; |
| 256 | } | 256 | } |
| 257 | 257 | ||
| 258 | #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) | 258 | #if defined(CONFIG_X86) |
| 259 | static void tsc_check_state(int state) | 259 | static void tsc_check_state(int state) |
| 260 | { | 260 | { |
| 261 | switch (boot_cpu_data.x86_vendor) { | 261 | switch (boot_cpu_data.x86_vendor) { |
