diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 13:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 13:20:36 -0400 |
commit | 765426e8ee4c0ab2bc9d44951f4865b8494cdbd0 (patch) | |
tree | 2b46ab8953eff175c8d3474a9754c1ab1394e4de /drivers | |
parent | 36ec891895020f3bc9953c8b11d079c6d77d76bd (diff) | |
parent | 898b054f3eec5921320ae8614b5bdd7b07ea5b43 (diff) |
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (123 commits)
dock: make dock driver not a module
ACPI: fix ia64 build warning
ACPI: hack around sysfs warning with link order
ACPI suspend: fix build warning when CONFIG_ACPI_SLEEP=n
intel_menlo: fix build warning
panasonic-laptop: fix build
ACPICA: Update version to 20080926
ACPICA: Add support for zero-length buffer-to-string conversions
ACPICA: New: Validation for predefined ACPI methods/objects
ACPICA: Fix for implicit return compatibility
ACPICA: Fixed a couple memory leaks associated with "implicit return"
ACPICA: Optimize buffer allocation procedure
ACPICA: Fix possible memory leak, error exit path
ACPICA: Fix fault after mem allocation failure in AML parser
ACPICA: Remove unused ACPI register bit definition
ACPICA: Update version to 20080829
ACPICA: Fix possible memory leak in acpi_ns_get_external_pathname
ACPICA: Cleanup for internal Reference Object
ACPICA: Update comments - no functional changes
ACPICA: Update for Reference ACPI_OPERAND_OBJECT
...
Diffstat (limited to 'drivers')
111 files changed, 4929 insertions, 1864 deletions
diff --git a/drivers/Makefile b/drivers/Makefile index cadc64fe8f68..2503f7b99b2f 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -82,6 +82,7 @@ obj-$(CONFIG_EISA) += eisa/ | |||
82 | obj-y += lguest/ | 82 | obj-y += lguest/ |
83 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ | 83 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ |
84 | obj-$(CONFIG_CPU_IDLE) += cpuidle/ | 84 | obj-$(CONFIG_CPU_IDLE) += cpuidle/ |
85 | obj-y += idle/ | ||
85 | obj-$(CONFIG_MMC) += mmc/ | 86 | obj-$(CONFIG_MMC) += mmc/ |
86 | obj-$(CONFIG_MEMSTICK) += memstick/ | 87 | obj-$(CONFIG_MEMSTICK) += memstick/ |
87 | obj-$(CONFIG_NEW_LEDS) += leds/ | 88 | obj-$(CONFIG_NEW_LEDS) += leds/ |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index da49b006bcc5..f4f632917509 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -42,7 +42,7 @@ if ACPI | |||
42 | 42 | ||
43 | config ACPI_SLEEP | 43 | config ACPI_SLEEP |
44 | bool | 44 | bool |
45 | depends on PM_SLEEP | 45 | depends on SUSPEND || HIBERNATION |
46 | default y | 46 | default y |
47 | 47 | ||
48 | config ACPI_PROCFS | 48 | config ACPI_PROCFS |
@@ -157,18 +157,11 @@ config ACPI_FAN | |||
157 | applications to perform basic fan control (on, off, status). | 157 | applications to perform basic fan control (on, off, status). |
158 | 158 | ||
159 | config ACPI_DOCK | 159 | config ACPI_DOCK |
160 | tristate "Dock" | 160 | bool "Dock" |
161 | depends on EXPERIMENTAL | 161 | depends on EXPERIMENTAL |
162 | help | 162 | help |
163 | This driver adds support for ACPI controlled docking stations | 163 | This driver adds support for ACPI controlled docking stations and removable |
164 | 164 | drive bays such as the IBM ultrabay or the Dell Module Bay. | |
165 | config ACPI_BAY | ||
166 | tristate "Removable Drive Bay (EXPERIMENTAL)" | ||
167 | depends on EXPERIMENTAL | ||
168 | depends on ACPI_DOCK | ||
169 | help | ||
170 | This driver adds support for ACPI controlled removable drive | ||
171 | bays such as the IBM ultrabay or the Dell Module Bay. | ||
172 | 165 | ||
173 | config ACPI_PROCESSOR | 166 | config ACPI_PROCESSOR |
174 | tristate "Processor" | 167 | tristate "Processor" |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 52a4cd4b81d0..d91c027ece8f 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -45,14 +45,13 @@ obj-$(CONFIG_ACPI_BATTERY) += battery.o | |||
45 | obj-$(CONFIG_ACPI_BUTTON) += button.o | 45 | obj-$(CONFIG_ACPI_BUTTON) += button.o |
46 | obj-$(CONFIG_ACPI_FAN) += fan.o | 46 | obj-$(CONFIG_ACPI_FAN) += fan.o |
47 | obj-$(CONFIG_ACPI_DOCK) += dock.o | 47 | obj-$(CONFIG_ACPI_DOCK) += dock.o |
48 | obj-$(CONFIG_ACPI_BAY) += bay.o | ||
49 | obj-$(CONFIG_ACPI_VIDEO) += video.o | 48 | obj-$(CONFIG_ACPI_VIDEO) += video.o |
50 | obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o | 49 | obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o |
51 | obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o | 50 | obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o |
52 | obj-$(CONFIG_ACPI_POWER) += power.o | ||
53 | obj-$(CONFIG_ACPI_PROCESSOR) += processor.o | 51 | obj-$(CONFIG_ACPI_PROCESSOR) += processor.o |
54 | obj-$(CONFIG_ACPI_CONTAINER) += container.o | 52 | obj-$(CONFIG_ACPI_CONTAINER) += container.o |
55 | obj-$(CONFIG_ACPI_THERMAL) += thermal.o | 53 | obj-$(CONFIG_ACPI_THERMAL) += thermal.o |
54 | obj-$(CONFIG_ACPI_POWER) += power.o | ||
56 | obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o | 55 | obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o |
57 | obj-$(CONFIG_ACPI_DEBUG) += debug.o | 56 | obj-$(CONFIG_ACPI_DEBUG) += debug.o |
58 | obj-$(CONFIG_ACPI_NUMA) += numa.o | 57 | obj-$(CONFIG_ACPI_NUMA) += numa.o |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 831883b7d6c9..d72a1b6c8a94 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -85,7 +85,7 @@ struct acpi_ac { | |||
85 | struct power_supply charger; | 85 | struct power_supply charger; |
86 | #endif | 86 | #endif |
87 | struct acpi_device * device; | 87 | struct acpi_device * device; |
88 | unsigned long state; | 88 | unsigned long long state; |
89 | }; | 89 | }; |
90 | 90 | ||
91 | #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger); | 91 | #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger); |
@@ -269,7 +269,7 @@ static int acpi_ac_add(struct acpi_device *device) | |||
269 | ac->device = device; | 269 | ac->device = device; |
270 | strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME); | 270 | strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME); |
271 | strcpy(acpi_device_class(device), ACPI_AC_CLASS); | 271 | strcpy(acpi_device_class(device), ACPI_AC_CLASS); |
272 | acpi_driver_data(device) = ac; | 272 | device->driver_data = ac; |
273 | 273 | ||
274 | result = acpi_ac_get_state(ac); | 274 | result = acpi_ac_get_state(ac); |
275 | if (result) | 275 | if (result) |
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 5f1127ad5a95..71d21c51c45f 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c | |||
@@ -194,8 +194,7 @@ acpi_memory_get_device(acpi_handle handle, | |||
194 | 194 | ||
195 | static int acpi_memory_check_device(struct acpi_memory_device *mem_device) | 195 | static int acpi_memory_check_device(struct acpi_memory_device *mem_device) |
196 | { | 196 | { |
197 | unsigned long current_status; | 197 | unsigned long long current_status; |
198 | |||
199 | 198 | ||
200 | /* Get device present/absent information from the _STA */ | 199 | /* Get device present/absent information from the _STA */ |
201 | if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->device->handle, "_STA", | 200 | if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->device->handle, "_STA", |
@@ -264,7 +263,7 @@ static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device) | |||
264 | acpi_status status; | 263 | acpi_status status; |
265 | struct acpi_object_list arg_list; | 264 | struct acpi_object_list arg_list; |
266 | union acpi_object arg; | 265 | union acpi_object arg; |
267 | unsigned long current_status; | 266 | unsigned long long current_status; |
268 | 267 | ||
269 | 268 | ||
270 | /* Issue the _EJ0 command */ | 269 | /* Issue the _EJ0 command */ |
@@ -403,7 +402,7 @@ static int acpi_memory_device_add(struct acpi_device *device) | |||
403 | mem_device->device = device; | 402 | mem_device->device = device; |
404 | sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME); | 403 | sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME); |
405 | sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS); | 404 | sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS); |
406 | acpi_driver_data(device) = mem_device; | 405 | device->driver_data = mem_device; |
407 | 406 | ||
408 | /* Get the range from the _CRS */ | 407 | /* Get the range from the _CRS */ |
409 | result = acpi_memory_get_device_resources(mem_device); | 408 | result = acpi_memory_get_device_resources(mem_device); |
@@ -454,8 +453,8 @@ static int acpi_memory_device_start (struct acpi_device *device) | |||
454 | /* call add_memory func */ | 453 | /* call add_memory func */ |
455 | result = acpi_memory_enable_device(mem_device); | 454 | result = acpi_memory_enable_device(mem_device); |
456 | if (result) | 455 | if (result) |
457 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 456 | printk(KERN_ERR PREFIX |
458 | "Error in acpi_memory_enable_device\n")); | 457 | "Error in acpi_memory_enable_device\n"); |
459 | } | 458 | } |
460 | return result; | 459 | return result; |
461 | } | 460 | } |
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index d3d0886d637f..1e74988c7b2d 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c | |||
@@ -42,7 +42,7 @@ | |||
42 | 42 | ||
43 | #define ASUS_ACPI_VERSION "0.30" | 43 | #define ASUS_ACPI_VERSION "0.30" |
44 | 44 | ||
45 | #define PROC_ASUS "asus" //the directory | 45 | #define PROC_ASUS "asus" /* The directory */ |
46 | #define PROC_MLED "mled" | 46 | #define PROC_MLED "mled" |
47 | #define PROC_WLED "wled" | 47 | #define PROC_WLED "wled" |
48 | #define PROC_TLED "tled" | 48 | #define PROC_TLED "tled" |
@@ -66,10 +66,10 @@ | |||
66 | /* | 66 | /* |
67 | * Flags for hotk status | 67 | * Flags for hotk status |
68 | */ | 68 | */ |
69 | #define MLED_ON 0x01 //mail LED | 69 | #define MLED_ON 0x01 /* Mail LED */ |
70 | #define WLED_ON 0x02 //wireless LED | 70 | #define WLED_ON 0x02 /* Wireless LED */ |
71 | #define TLED_ON 0x04 //touchpad LED | 71 | #define TLED_ON 0x04 /* Touchpad LED */ |
72 | #define BT_ON 0x08 //internal Bluetooth | 72 | #define BT_ON 0x08 /* Internal Bluetooth */ |
73 | 73 | ||
74 | MODULE_AUTHOR("Julien Lerouge, Karol Kozimor"); | 74 | MODULE_AUTHOR("Julien Lerouge, Karol Kozimor"); |
75 | MODULE_DESCRIPTION(ACPI_HOTK_NAME); | 75 | MODULE_DESCRIPTION(ACPI_HOTK_NAME); |
@@ -82,28 +82,28 @@ MODULE_PARM_DESC(asus_uid, "UID for entries in /proc/acpi/asus"); | |||
82 | module_param(asus_gid, uint, 0); | 82 | module_param(asus_gid, uint, 0); |
83 | MODULE_PARM_DESC(asus_gid, "GID for entries in /proc/acpi/asus"); | 83 | MODULE_PARM_DESC(asus_gid, "GID for entries in /proc/acpi/asus"); |
84 | 84 | ||
85 | /* For each model, all features implemented, | 85 | /* For each model, all features implemented, |
86 | * those marked with R are relative to HOTK, A for absolute */ | 86 | * those marked with R are relative to HOTK, A for absolute */ |
87 | struct model_data { | 87 | struct model_data { |
88 | char *name; //name of the laptop________________A | 88 | char *name; /* name of the laptop________________A */ |
89 | char *mt_mled; //method to handle mled_____________R | 89 | char *mt_mled; /* method to handle mled_____________R */ |
90 | char *mled_status; //node to handle mled reading_______A | 90 | char *mled_status; /* node to handle mled reading_______A */ |
91 | char *mt_wled; //method to handle wled_____________R | 91 | char *mt_wled; /* method to handle wled_____________R */ |
92 | char *wled_status; //node to handle wled reading_______A | 92 | char *wled_status; /* node to handle wled reading_______A */ |
93 | char *mt_tled; //method to handle tled_____________R | 93 | char *mt_tled; /* method to handle tled_____________R */ |
94 | char *tled_status; //node to handle tled reading_______A | 94 | char *tled_status; /* node to handle tled reading_______A */ |
95 | char *mt_ledd; //method to handle LED display______R | 95 | char *mt_ledd; /* method to handle LED display______R */ |
96 | char *mt_bt_switch; //method to switch Bluetooth on/off_R | 96 | char *mt_bt_switch; /* method to switch Bluetooth on/off_R */ |
97 | char *bt_status; //no model currently supports this__? | 97 | char *bt_status; /* no model currently supports this__? */ |
98 | char *mt_lcd_switch; //method to turn LCD on/off_________A | 98 | char *mt_lcd_switch; /* method to turn LCD on/off_________A */ |
99 | char *lcd_status; //node to read LCD panel state______A | 99 | char *lcd_status; /* node to read LCD panel state______A */ |
100 | char *brightness_up; //method to set brightness up_______A | 100 | char *brightness_up; /* method to set brightness up_______A */ |
101 | char *brightness_down; //guess what ?______________________A | 101 | char *brightness_down; /* method to set brightness down ____A */ |
102 | char *brightness_set; //method to set absolute brightness_R | 102 | char *brightness_set; /* method to set absolute brightness_R */ |
103 | char *brightness_get; //method to get absolute brightness_R | 103 | char *brightness_get; /* method to get absolute brightness_R */ |
104 | char *brightness_status; //node to get brightness____________A | 104 | char *brightness_status;/* node to get brightness____________A */ |
105 | char *display_set; //method to set video output________R | 105 | char *display_set; /* method to set video output________R */ |
106 | char *display_get; //method to get video output________R | 106 | char *display_get; /* method to get video output________R */ |
107 | }; | 107 | }; |
108 | 108 | ||
109 | /* | 109 | /* |
@@ -111,41 +111,41 @@ struct model_data { | |||
111 | * about the hotk device | 111 | * about the hotk device |
112 | */ | 112 | */ |
113 | struct asus_hotk { | 113 | struct asus_hotk { |
114 | struct acpi_device *device; //the device we are in | 114 | struct acpi_device *device; /* the device we are in */ |
115 | acpi_handle handle; //the handle of the hotk device | 115 | acpi_handle handle; /* the handle of the hotk device */ |
116 | char status; //status of the hotk, for LEDs, ... | 116 | char status; /* status of the hotk, for LEDs */ |
117 | u32 ledd_status; //status of the LED display | 117 | u32 ledd_status; /* status of the LED display */ |
118 | struct model_data *methods; //methods available on the laptop | 118 | struct model_data *methods; /* methods available on the laptop */ |
119 | u8 brightness; //brightness level | 119 | u8 brightness; /* brightness level */ |
120 | enum { | 120 | enum { |
121 | A1x = 0, //A1340D, A1300F | 121 | A1x = 0, /* A1340D, A1300F */ |
122 | A2x, //A2500H | 122 | A2x, /* A2500H */ |
123 | A4G, //A4700G | 123 | A4G, /* A4700G */ |
124 | D1x, //D1 | 124 | D1x, /* D1 */ |
125 | L2D, //L2000D | 125 | L2D, /* L2000D */ |
126 | L3C, //L3800C | 126 | L3C, /* L3800C */ |
127 | L3D, //L3400D | 127 | L3D, /* L3400D */ |
128 | L3H, //L3H, L2000E, L5D | 128 | L3H, /* L3H, L2000E, L5D */ |
129 | L4R, //L4500R | 129 | L4R, /* L4500R */ |
130 | L5x, //L5800C | 130 | L5x, /* L5800C */ |
131 | L8L, //L8400L | 131 | L8L, /* L8400L */ |
132 | M1A, //M1300A | 132 | M1A, /* M1300A */ |
133 | M2E, //M2400E, L4400L | 133 | M2E, /* M2400E, L4400L */ |
134 | M6N, //M6800N, W3400N | 134 | M6N, /* M6800N, W3400N */ |
135 | M6R, //M6700R, A3000G | 135 | M6R, /* M6700R, A3000G */ |
136 | P30, //Samsung P30 | 136 | P30, /* Samsung P30 */ |
137 | S1x, //S1300A, but also L1400B and M2400A (L84F) | 137 | S1x, /* S1300A, but also L1400B and M2400A (L84F) */ |
138 | S2x, //S200 (J1 reported), Victor MP-XP7210 | 138 | S2x, /* S200 (J1 reported), Victor MP-XP7210 */ |
139 | W1N, //W1000N | 139 | W1N, /* W1000N */ |
140 | W5A, //W5A | 140 | W5A, /* W5A */ |
141 | W3V, //W3030V | 141 | W3V, /* W3030V */ |
142 | xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N | 142 | xxN, /* M2400N, M3700N, M5200N, M6800N, |
143 | A4S, //Z81sp | 143 | S1300N, S5200N*/ |
144 | //(Centrino) | 144 | A4S, /* Z81sp */ |
145 | F3Sa, | 145 | F3Sa, /* (Centrino) */ |
146 | END_MODEL | 146 | END_MODEL |
147 | } model; //Models currently supported | 147 | } model; /* Models currently supported */ |
148 | u16 event_count[128]; //count for each event TODO make this better | 148 | u16 event_count[128]; /* Count for each event TODO make this better */ |
149 | }; | 149 | }; |
150 | 150 | ||
151 | /* Here we go */ | 151 | /* Here we go */ |
@@ -459,18 +459,18 @@ static struct acpi_driver asus_hotk_driver = { | |||
459 | }, | 459 | }, |
460 | }; | 460 | }; |
461 | 461 | ||
462 | /* | 462 | /* |
463 | * This function evaluates an ACPI method, given an int as parameter, the | 463 | * This function evaluates an ACPI method, given an int as parameter, the |
464 | * method is searched within the scope of the handle, can be NULL. The output | 464 | * method is searched within the scope of the handle, can be NULL. The output |
465 | * of the method is written is output, which can also be NULL | 465 | * of the method is written is output, which can also be NULL |
466 | * | 466 | * |
467 | * returns 1 if write is successful, 0 else. | 467 | * returns 1 if write is successful, 0 else. |
468 | */ | 468 | */ |
469 | static int write_acpi_int(acpi_handle handle, const char *method, int val, | 469 | static int write_acpi_int(acpi_handle handle, const char *method, int val, |
470 | struct acpi_buffer *output) | 470 | struct acpi_buffer *output) |
471 | { | 471 | { |
472 | struct acpi_object_list params; //list of input parameters (an int here) | 472 | struct acpi_object_list params; /* list of input parameters (int) */ |
473 | union acpi_object in_obj; //the only param we use | 473 | union acpi_object in_obj; /* the only param we use */ |
474 | acpi_status status; | 474 | acpi_status status; |
475 | 475 | ||
476 | params.count = 1; | 476 | params.count = 1; |
@@ -507,18 +507,18 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof, | |||
507 | { | 507 | { |
508 | int len = 0; | 508 | int len = 0; |
509 | int temp; | 509 | int temp; |
510 | char buf[16]; //enough for all info | 510 | char buf[16]; /* enough for all info */ |
511 | /* | 511 | /* |
512 | * We use the easy way, we don't care of off and count, so we don't set eof | 512 | * We use the easy way, we don't care of off and count, |
513 | * to 1 | 513 | * so we don't set eof to 1 |
514 | */ | 514 | */ |
515 | 515 | ||
516 | len += sprintf(page, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n"); | 516 | len += sprintf(page, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n"); |
517 | len += sprintf(page + len, "Model reference : %s\n", | 517 | len += sprintf(page + len, "Model reference : %s\n", |
518 | hotk->methods->name); | 518 | hotk->methods->name); |
519 | /* | 519 | /* |
520 | * The SFUN method probably allows the original driver to get the list | 520 | * The SFUN method probably allows the original driver to get the list |
521 | * of features supported by a given model. For now, 0x0100 or 0x0800 | 521 | * of features supported by a given model. For now, 0x0100 or 0x0800 |
522 | * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card. | 522 | * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card. |
523 | * The significance of others is yet to be found. | 523 | * The significance of others is yet to be found. |
524 | */ | 524 | */ |
@@ -528,7 +528,7 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof, | |||
528 | /* | 528 | /* |
529 | * Another value for userspace: the ASYM method returns 0x02 for | 529 | * Another value for userspace: the ASYM method returns 0x02 for |
530 | * battery low and 0x04 for battery critical, its readings tend to be | 530 | * battery low and 0x04 for battery critical, its readings tend to be |
531 | * more accurate than those provided by _BST. | 531 | * more accurate than those provided by _BST. |
532 | * Note: since not all the laptops provide this method, errors are | 532 | * Note: since not all the laptops provide this method, errors are |
533 | * silently ignored. | 533 | * silently ignored. |
534 | */ | 534 | */ |
@@ -579,7 +579,7 @@ static int read_led(const char *ledname, int ledmask) | |||
579 | return (hotk->status & ledmask) ? 1 : 0; | 579 | return (hotk->status & ledmask) ? 1 : 0; |
580 | } | 580 | } |
581 | 581 | ||
582 | static int parse_arg(const char __user * buf, unsigned long count, int *val) | 582 | static int parse_arg(const char __user *buf, unsigned long count, int *val) |
583 | { | 583 | { |
584 | char s[32]; | 584 | char s[32]; |
585 | if (!count) | 585 | if (!count) |
@@ -596,7 +596,7 @@ static int parse_arg(const char __user * buf, unsigned long count, int *val) | |||
596 | 596 | ||
597 | /* FIXME: kill extraneous args so it can be called independently */ | 597 | /* FIXME: kill extraneous args so it can be called independently */ |
598 | static int | 598 | static int |
599 | write_led(const char __user * buffer, unsigned long count, | 599 | write_led(const char __user *buffer, unsigned long count, |
600 | char *ledname, int ledmask, int invert) | 600 | char *ledname, int ledmask, int invert) |
601 | { | 601 | { |
602 | int rv, value; | 602 | int rv, value; |
@@ -631,7 +631,7 @@ proc_read_mled(char *page, char **start, off_t off, int count, int *eof, | |||
631 | } | 631 | } |
632 | 632 | ||
633 | static int | 633 | static int |
634 | proc_write_mled(struct file *file, const char __user * buffer, | 634 | proc_write_mled(struct file *file, const char __user *buffer, |
635 | unsigned long count, void *data) | 635 | unsigned long count, void *data) |
636 | { | 636 | { |
637 | return write_led(buffer, count, hotk->methods->mt_mled, MLED_ON, 1); | 637 | return write_led(buffer, count, hotk->methods->mt_mled, MLED_ON, 1); |
@@ -648,7 +648,7 @@ proc_read_ledd(char *page, char **start, off_t off, int count, int *eof, | |||
648 | } | 648 | } |
649 | 649 | ||
650 | static int | 650 | static int |
651 | proc_write_ledd(struct file *file, const char __user * buffer, | 651 | proc_write_ledd(struct file *file, const char __user *buffer, |
652 | unsigned long count, void *data) | 652 | unsigned long count, void *data) |
653 | { | 653 | { |
654 | int rv, value; | 654 | int rv, value; |
@@ -677,7 +677,7 @@ proc_read_wled(char *page, char **start, off_t off, int count, int *eof, | |||
677 | } | 677 | } |
678 | 678 | ||
679 | static int | 679 | static int |
680 | proc_write_wled(struct file *file, const char __user * buffer, | 680 | proc_write_wled(struct file *file, const char __user *buffer, |
681 | unsigned long count, void *data) | 681 | unsigned long count, void *data) |
682 | { | 682 | { |
683 | return write_led(buffer, count, hotk->methods->mt_wled, WLED_ON, 0); | 683 | return write_led(buffer, count, hotk->methods->mt_wled, WLED_ON, 0); |
@@ -694,10 +694,10 @@ proc_read_bluetooth(char *page, char **start, off_t off, int count, int *eof, | |||
694 | } | 694 | } |
695 | 695 | ||
696 | static int | 696 | static int |
697 | proc_write_bluetooth(struct file *file, const char __user * buffer, | 697 | proc_write_bluetooth(struct file *file, const char __user *buffer, |
698 | unsigned long count, void *data) | 698 | unsigned long count, void *data) |
699 | { | 699 | { |
700 | /* Note: mt_bt_switch controls both internal Bluetooth adapter's | 700 | /* Note: mt_bt_switch controls both internal Bluetooth adapter's |
701 | presence and its LED */ | 701 | presence and its LED */ |
702 | return write_led(buffer, count, hotk->methods->mt_bt_switch, BT_ON, 0); | 702 | return write_led(buffer, count, hotk->methods->mt_bt_switch, BT_ON, 0); |
703 | } | 703 | } |
@@ -714,7 +714,7 @@ proc_read_tled(char *page, char **start, off_t off, int count, int *eof, | |||
714 | } | 714 | } |
715 | 715 | ||
716 | static int | 716 | static int |
717 | proc_write_tled(struct file *file, const char __user * buffer, | 717 | proc_write_tled(struct file *file, const char __user *buffer, |
718 | unsigned long count, void *data) | 718 | unsigned long count, void *data) |
719 | { | 719 | { |
720 | return write_led(buffer, count, hotk->methods->mt_tled, TLED_ON, 0); | 720 | return write_led(buffer, count, hotk->methods->mt_tled, TLED_ON, 0); |
@@ -734,7 +734,7 @@ static int get_lcd_state(void) | |||
734 | 734 | ||
735 | input.count = 2; | 735 | input.count = 2; |
736 | input.pointer = mt_params; | 736 | input.pointer = mt_params; |
737 | /* Note: the following values are partly guessed up, but | 737 | /* Note: the following values are partly guessed up, but |
738 | otherwise they seem to work */ | 738 | otherwise they seem to work */ |
739 | mt_params[0].type = ACPI_TYPE_INTEGER; | 739 | mt_params[0].type = ACPI_TYPE_INTEGER; |
740 | mt_params[0].integer.value = 0x02; | 740 | mt_params[0].integer.value = 0x02; |
@@ -753,7 +753,7 @@ static int get_lcd_state(void) | |||
753 | /* That's what the AML code does */ | 753 | /* That's what the AML code does */ |
754 | lcd = out_obj.integer.value >> 8; | 754 | lcd = out_obj.integer.value >> 8; |
755 | } else if (hotk->model == F3Sa) { | 755 | } else if (hotk->model == F3Sa) { |
756 | unsigned long tmp; | 756 | unsigned long long tmp; |
757 | union acpi_object param; | 757 | union acpi_object param; |
758 | struct acpi_object_list input; | 758 | struct acpi_object_list input; |
759 | acpi_status status; | 759 | acpi_status status; |
@@ -796,12 +796,13 @@ static int set_lcd_state(int value) | |||
796 | acpi_evaluate_object(NULL, | 796 | acpi_evaluate_object(NULL, |
797 | hotk->methods->mt_lcd_switch, | 797 | hotk->methods->mt_lcd_switch, |
798 | NULL, NULL); | 798 | NULL, NULL); |
799 | } else { /* L3H and the like have to be handled differently */ | 799 | } else { |
800 | /* L3H and the like must be handled differently */ | ||
800 | if (!write_acpi_int | 801 | if (!write_acpi_int |
801 | (hotk->handle, hotk->methods->mt_lcd_switch, 0x07, | 802 | (hotk->handle, hotk->methods->mt_lcd_switch, 0x07, |
802 | NULL)) | 803 | NULL)) |
803 | status = AE_ERROR; | 804 | status = AE_ERROR; |
804 | /* L3H's AML executes EHK (0x07) upon Fn+F7 keypress, | 805 | /* L3H's AML executes EHK (0x07) upon Fn+F7 keypress, |
805 | the exact behaviour is simulated here */ | 806 | the exact behaviour is simulated here */ |
806 | } | 807 | } |
807 | if (ACPI_FAILURE(status)) | 808 | if (ACPI_FAILURE(status)) |
@@ -819,7 +820,7 @@ proc_read_lcd(char *page, char **start, off_t off, int count, int *eof, | |||
819 | } | 820 | } |
820 | 821 | ||
821 | static int | 822 | static int |
822 | proc_write_lcd(struct file *file, const char __user * buffer, | 823 | proc_write_lcd(struct file *file, const char __user *buffer, |
823 | unsigned long count, void *data) | 824 | unsigned long count, void *data) |
824 | { | 825 | { |
825 | int rv, value; | 826 | int rv, value; |
@@ -897,7 +898,7 @@ proc_read_brn(char *page, char **start, off_t off, int count, int *eof, | |||
897 | } | 898 | } |
898 | 899 | ||
899 | static int | 900 | static int |
900 | proc_write_brn(struct file *file, const char __user * buffer, | 901 | proc_write_brn(struct file *file, const char __user *buffer, |
901 | unsigned long count, void *data) | 902 | unsigned long count, void *data) |
902 | { | 903 | { |
903 | int rv, value; | 904 | int rv, value; |
@@ -921,7 +922,7 @@ static void set_display(int value) | |||
921 | } | 922 | } |
922 | 923 | ||
923 | /* | 924 | /* |
924 | * Now, *this* one could be more user-friendly, but so far, no-one has | 925 | * Now, *this* one could be more user-friendly, but so far, no-one has |
925 | * complained. The significance of bits is the same as in proc_write_disp() | 926 | * complained. The significance of bits is the same as in proc_write_disp() |
926 | */ | 927 | */ |
927 | static int | 928 | static int |
@@ -933,18 +934,18 @@ proc_read_disp(char *page, char **start, off_t off, int count, int *eof, | |||
933 | if (!read_acpi_int(hotk->handle, hotk->methods->display_get, &value)) | 934 | if (!read_acpi_int(hotk->handle, hotk->methods->display_get, &value)) |
934 | printk(KERN_WARNING | 935 | printk(KERN_WARNING |
935 | "Asus ACPI: Error reading display status\n"); | 936 | "Asus ACPI: Error reading display status\n"); |
936 | value &= 0x07; /* needed for some models, shouldn't hurt others */ | 937 | value &= 0x07; /* needed for some models, shouldn't hurt others */ |
937 | return sprintf(page, "%d\n", value); | 938 | return sprintf(page, "%d\n", value); |
938 | } | 939 | } |
939 | 940 | ||
940 | /* | 941 | /* |
941 | * Experimental support for display switching. As of now: 1 should activate | 942 | * Experimental support for display switching. As of now: 1 should activate |
942 | * the LCD output, 2 should do for CRT, and 4 for TV-Out. Any combination | 943 | * the LCD output, 2 should do for CRT, and 4 for TV-Out. Any combination |
943 | * (bitwise) of these will suffice. I never actually tested 3 displays hooked up | 944 | * (bitwise) of these will suffice. I never actually tested 3 displays hooked |
944 | * simultaneously, so be warned. See the acpi4asus README for more info. | 945 | * up simultaneously, so be warned. See the acpi4asus README for more info. |
945 | */ | 946 | */ |
946 | static int | 947 | static int |
947 | proc_write_disp(struct file *file, const char __user * buffer, | 948 | proc_write_disp(struct file *file, const char __user *buffer, |
948 | unsigned long count, void *data) | 949 | unsigned long count, void *data) |
949 | { | 950 | { |
950 | int rv, value; | 951 | int rv, value; |
@@ -957,12 +958,12 @@ proc_write_disp(struct file *file, const char __user * buffer, | |||
957 | 958 | ||
958 | typedef int (proc_readfunc) (char *page, char **start, off_t off, int count, | 959 | typedef int (proc_readfunc) (char *page, char **start, off_t off, int count, |
959 | int *eof, void *data); | 960 | int *eof, void *data); |
960 | typedef int (proc_writefunc) (struct file * file, const char __user * buffer, | 961 | typedef int (proc_writefunc) (struct file *file, const char __user *buffer, |
961 | unsigned long count, void *data); | 962 | unsigned long count, void *data); |
962 | 963 | ||
963 | static int | 964 | static int |
964 | asus_proc_add(char *name, proc_writefunc * writefunc, | 965 | asus_proc_add(char *name, proc_writefunc *writefunc, |
965 | proc_readfunc * readfunc, mode_t mode, | 966 | proc_readfunc *readfunc, mode_t mode, |
966 | struct acpi_device *device) | 967 | struct acpi_device *device) |
967 | { | 968 | { |
968 | struct proc_dir_entry *proc = | 969 | struct proc_dir_entry *proc = |
@@ -1040,9 +1041,9 @@ static int asus_hotk_add_fs(struct acpi_device *device) | |||
1040 | &proc_read_bluetooth, mode, device); | 1041 | &proc_read_bluetooth, mode, device); |
1041 | } | 1042 | } |
1042 | 1043 | ||
1043 | /* | 1044 | /* |
1044 | * We need both read node and write method as LCD switch is also accessible | 1045 | * We need both read node and write method as LCD switch is also |
1045 | * from keyboard | 1046 | * accessible from the keyboard |
1046 | */ | 1047 | */ |
1047 | if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) { | 1048 | if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) { |
1048 | asus_proc_add(PROC_LCD, &proc_write_lcd, &proc_read_lcd, mode, | 1049 | asus_proc_add(PROC_LCD, &proc_write_lcd, &proc_read_lcd, mode, |
@@ -1096,11 +1097,10 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) | |||
1096 | if (!hotk) | 1097 | if (!hotk) |
1097 | return; | 1098 | return; |
1098 | 1099 | ||
1099 | if ((event & ~((u32) BR_UP)) < 16) { | 1100 | if ((event & ~((u32) BR_UP)) < 16) |
1100 | hotk->brightness = (event & ~((u32) BR_UP)); | 1101 | hotk->brightness = (event & ~((u32) BR_UP)); |
1101 | } else if ((event & ~((u32) BR_DOWN)) < 16) { | 1102 | else if ((event & ~((u32) BR_DOWN)) < 16) |
1102 | hotk->brightness = (event & ~((u32) BR_DOWN)); | 1103 | hotk->brightness = (event & ~((u32) BR_DOWN)); |
1103 | } | ||
1104 | 1104 | ||
1105 | acpi_bus_generate_proc_event(hotk->device, event, | 1105 | acpi_bus_generate_proc_event(hotk->device, event, |
1106 | hotk->event_count[event % 128]++); | 1106 | hotk->event_count[event % 128]++); |
@@ -1186,8 +1186,8 @@ static int asus_hotk_get_info(void) | |||
1186 | acpi_status status; | 1186 | acpi_status status; |
1187 | 1187 | ||
1188 | /* | 1188 | /* |
1189 | * Get DSDT headers early enough to allow for differentiating between | 1189 | * Get DSDT headers early enough to allow for differentiating between |
1190 | * models, but late enough to allow acpi_bus_register_driver() to fail | 1190 | * models, but late enough to allow acpi_bus_register_driver() to fail |
1191 | * before doing anything ACPI-specific. Should we encounter a machine, | 1191 | * before doing anything ACPI-specific. Should we encounter a machine, |
1192 | * which needs special handling (i.e. its hotkey device has a different | 1192 | * which needs special handling (i.e. its hotkey device has a different |
1193 | * HID), this bit will be moved. A global variable asus_info contains | 1193 | * HID), this bit will be moved. A global variable asus_info contains |
@@ -1212,8 +1212,8 @@ static int asus_hotk_get_info(void) | |||
1212 | 1212 | ||
1213 | /* | 1213 | /* |
1214 | * Try to match the object returned by INIT to the specific model. | 1214 | * Try to match the object returned by INIT to the specific model. |
1215 | * Handle every possible object (or the lack of thereof) the DSDT | 1215 | * Handle every possible object (or the lack of thereof) the DSDT |
1216 | * writers might throw at us. When in trouble, we pass NULL to | 1216 | * writers might throw at us. When in trouble, we pass NULL to |
1217 | * asus_model_match() and try something completely different. | 1217 | * asus_model_match() and try something completely different. |
1218 | */ | 1218 | */ |
1219 | if (buffer.pointer) { | 1219 | if (buffer.pointer) { |
@@ -1244,6 +1244,8 @@ static int asus_hotk_get_info(void) | |||
1244 | "default values\n", string); | 1244 | "default values\n", string); |
1245 | printk(KERN_NOTICE | 1245 | printk(KERN_NOTICE |
1246 | " send /proc/acpi/dsdt to the developers\n"); | 1246 | " send /proc/acpi/dsdt to the developers\n"); |
1247 | kfree(model); | ||
1248 | return -ENODEV; | ||
1247 | } | 1249 | } |
1248 | hotk->methods = &model_conf[hotk->model]; | 1250 | hotk->methods = &model_conf[hotk->model]; |
1249 | return AE_OK; | 1251 | return AE_OK; |
@@ -1254,7 +1256,7 @@ static int asus_hotk_get_info(void) | |||
1254 | /* Sort of per-model blacklist */ | 1256 | /* Sort of per-model blacklist */ |
1255 | if (strncmp(string, "L2B", 3) == 0) | 1257 | if (strncmp(string, "L2B", 3) == 0) |
1256 | hotk->methods->lcd_status = NULL; | 1258 | hotk->methods->lcd_status = NULL; |
1257 | /* L2B is similar enough to L3C to use its settings, with this only | 1259 | /* L2B is similar enough to L3C to use its settings, with this only |
1258 | exception */ | 1260 | exception */ |
1259 | else if (strncmp(string, "A3G", 3) == 0) | 1261 | else if (strncmp(string, "A3G", 3) == 0) |
1260 | hotk->methods->lcd_status = "\\BLFG"; | 1262 | hotk->methods->lcd_status = "\\BLFG"; |
@@ -1321,7 +1323,7 @@ static int asus_hotk_add(struct acpi_device *device) | |||
1321 | hotk->handle = device->handle; | 1323 | hotk->handle = device->handle; |
1322 | strcpy(acpi_device_name(device), ACPI_HOTK_DEVICE_NAME); | 1324 | strcpy(acpi_device_name(device), ACPI_HOTK_DEVICE_NAME); |
1323 | strcpy(acpi_device_class(device), ACPI_HOTK_CLASS); | 1325 | strcpy(acpi_device_class(device), ACPI_HOTK_CLASS); |
1324 | acpi_driver_data(device) = hotk; | 1326 | device->driver_data = hotk; |
1325 | hotk->device = device; | 1327 | hotk->device = device; |
1326 | 1328 | ||
1327 | result = asus_hotk_check(); | 1329 | result = asus_hotk_check(); |
@@ -1366,10 +1368,9 @@ static int asus_hotk_add(struct acpi_device *device) | |||
1366 | /* LED display is off by default */ | 1368 | /* LED display is off by default */ |
1367 | hotk->ledd_status = 0xFFF; | 1369 | hotk->ledd_status = 0xFFF; |
1368 | 1370 | ||
1369 | end: | 1371 | end: |
1370 | if (result) { | 1372 | if (result) |
1371 | kfree(hotk); | 1373 | kfree(hotk); |
1372 | } | ||
1373 | 1374 | ||
1374 | return result; | 1375 | return result; |
1375 | } | 1376 | } |
@@ -1394,8 +1395,8 @@ static int asus_hotk_remove(struct acpi_device *device, int type) | |||
1394 | } | 1395 | } |
1395 | 1396 | ||
1396 | static struct backlight_ops asus_backlight_data = { | 1397 | static struct backlight_ops asus_backlight_data = { |
1397 | .get_brightness = read_brightness, | 1398 | .get_brightness = read_brightness, |
1398 | .update_status = set_brightness_status, | 1399 | .update_status = set_brightness_status, |
1399 | }; | 1400 | }; |
1400 | 1401 | ||
1401 | static void asus_acpi_exit(void) | 1402 | static void asus_acpi_exit(void) |
@@ -1442,15 +1443,15 @@ static int __init asus_acpi_init(void) | |||
1442 | return -ENODEV; | 1443 | return -ENODEV; |
1443 | } | 1444 | } |
1444 | 1445 | ||
1445 | asus_backlight_device = backlight_device_register("asus",NULL,NULL, | 1446 | asus_backlight_device = backlight_device_register("asus", NULL, NULL, |
1446 | &asus_backlight_data); | 1447 | &asus_backlight_data); |
1447 | if (IS_ERR(asus_backlight_device)) { | 1448 | if (IS_ERR(asus_backlight_device)) { |
1448 | printk(KERN_ERR "Could not register asus backlight device\n"); | 1449 | printk(KERN_ERR "Could not register asus backlight device\n"); |
1449 | asus_backlight_device = NULL; | 1450 | asus_backlight_device = NULL; |
1450 | asus_acpi_exit(); | 1451 | asus_acpi_exit(); |
1451 | return -ENODEV; | 1452 | return -ENODEV; |
1452 | } | 1453 | } |
1453 | asus_backlight_device->props.max_brightness = 15; | 1454 | asus_backlight_device->props.max_brightness = 15; |
1454 | 1455 | ||
1455 | return 0; | 1456 | return 0; |
1456 | } | 1457 | } |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 70f7f60929ca..b2133e89ad9a 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -804,7 +804,7 @@ static int acpi_battery_add(struct acpi_device *device) | |||
804 | battery->device = device; | 804 | battery->device = device; |
805 | strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); | 805 | strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); |
806 | strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); | 806 | strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); |
807 | acpi_driver_data(device) = battery; | 807 | device->driver_data = battery; |
808 | mutex_init(&battery->lock); | 808 | mutex_init(&battery->lock); |
809 | acpi_battery_update(battery); | 809 | acpi_battery_update(battery); |
810 | #ifdef CONFIG_ACPI_PROCFS_POWER | 810 | #ifdef CONFIG_ACPI_PROCFS_POWER |
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c deleted file mode 100644 index 61b6c5beb2d3..000000000000 --- a/drivers/acpi/bay.c +++ /dev/null | |||
@@ -1,411 +0,0 @@ | |||
1 | /* | ||
2 | * bay.c - ACPI removable drive bay driver | ||
3 | * | ||
4 | * Copyright (C) 2006 Kristen Carlson Accardi <kristen.c.accardi@intel.com> | ||
5 | * | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or (at | ||
11 | * your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
21 | * | ||
22 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
23 | */ | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/notifier.h> | ||
29 | #include <acpi/acpi_bus.h> | ||
30 | #include <acpi/acpi_drivers.h> | ||
31 | #include <linux/seq_file.h> | ||
32 | #include <asm/uaccess.h> | ||
33 | #include <linux/platform_device.h> | ||
34 | |||
35 | ACPI_MODULE_NAME("bay"); | ||
36 | MODULE_AUTHOR("Kristen Carlson Accardi"); | ||
37 | MODULE_DESCRIPTION("ACPI Removable Drive Bay Driver"); | ||
38 | MODULE_LICENSE("GPL"); | ||
39 | #define ACPI_BAY_CLASS "bay" | ||
40 | #define ACPI_BAY_COMPONENT 0x10000000 | ||
41 | #define _COMPONENT ACPI_BAY_COMPONENT | ||
42 | #define bay_dprintk(h,s) {\ | ||
43 | char prefix[80] = {'\0'};\ | ||
44 | struct acpi_buffer buffer = {sizeof(prefix), prefix};\ | ||
45 | acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\ | ||
46 | printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); } | ||
47 | static void bay_notify(acpi_handle handle, u32 event, void *data); | ||
48 | |||
49 | static const struct acpi_device_id bay_device_ids[] = { | ||
50 | {"LNXIOBAY", 0}, | ||
51 | {"", 0}, | ||
52 | }; | ||
53 | MODULE_DEVICE_TABLE(acpi, bay_device_ids); | ||
54 | |||
55 | struct bay { | ||
56 | acpi_handle handle; | ||
57 | char *name; | ||
58 | struct list_head list; | ||
59 | struct platform_device *pdev; | ||
60 | }; | ||
61 | |||
62 | static LIST_HEAD(drive_bays); | ||
63 | |||
64 | |||
65 | /***************************************************************************** | ||
66 | * Drive Bay functions * | ||
67 | *****************************************************************************/ | ||
68 | /** | ||
69 | * is_ejectable - see if a device is ejectable | ||
70 | * @handle: acpi handle of the device | ||
71 | * | ||
72 | * If an acpi object has a _EJ0 method, then it is ejectable | ||
73 | */ | ||
74 | static int is_ejectable(acpi_handle handle) | ||
75 | { | ||
76 | acpi_status status; | ||
77 | acpi_handle tmp; | ||
78 | |||
79 | status = acpi_get_handle(handle, "_EJ0", &tmp); | ||
80 | if (ACPI_FAILURE(status)) | ||
81 | return 0; | ||
82 | return 1; | ||
83 | } | ||
84 | |||
85 | /** | ||
86 | * bay_present - see if the bay device is present | ||
87 | * @bay: the drive bay | ||
88 | * | ||
89 | * execute the _STA method. | ||
90 | */ | ||
91 | static int bay_present(struct bay *bay) | ||
92 | { | ||
93 | unsigned long sta; | ||
94 | acpi_status status; | ||
95 | |||
96 | if (bay) { | ||
97 | status = acpi_evaluate_integer(bay->handle, "_STA", NULL, &sta); | ||
98 | if (ACPI_SUCCESS(status) && sta) | ||
99 | return 1; | ||
100 | } | ||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | /** | ||
105 | * eject_device - respond to an eject request | ||
106 | * @handle - the device to eject | ||
107 | * | ||
108 | * Call this devices _EJ0 method. | ||
109 | */ | ||
110 | static void eject_device(acpi_handle handle) | ||
111 | { | ||
112 | struct acpi_object_list arg_list; | ||
113 | union acpi_object arg; | ||
114 | |||
115 | bay_dprintk(handle, "Ejecting device"); | ||
116 | |||
117 | arg_list.count = 1; | ||
118 | arg_list.pointer = &arg; | ||
119 | arg.type = ACPI_TYPE_INTEGER; | ||
120 | arg.integer.value = 1; | ||
121 | |||
122 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_EJ0", | ||
123 | &arg_list, NULL))) | ||
124 | pr_debug("Failed to evaluate _EJ0!\n"); | ||
125 | } | ||
126 | |||
127 | /* | ||
128 | * show_present - read method for "present" file in sysfs | ||
129 | */ | ||
130 | static ssize_t show_present(struct device *dev, | ||
131 | struct device_attribute *attr, char *buf) | ||
132 | { | ||
133 | struct bay *bay = dev_get_drvdata(dev); | ||
134 | return snprintf(buf, PAGE_SIZE, "%d\n", bay_present(bay)); | ||
135 | |||
136 | } | ||
137 | static DEVICE_ATTR(present, S_IRUGO, show_present, NULL); | ||
138 | |||
139 | /* | ||
140 | * write_eject - write method for "eject" file in sysfs | ||
141 | */ | ||
142 | static ssize_t write_eject(struct device *dev, struct device_attribute *attr, | ||
143 | const char *buf, size_t count) | ||
144 | { | ||
145 | struct bay *bay = dev_get_drvdata(dev); | ||
146 | |||
147 | if (!count) | ||
148 | return -EINVAL; | ||
149 | |||
150 | eject_device(bay->handle); | ||
151 | return count; | ||
152 | } | ||
153 | static DEVICE_ATTR(eject, S_IWUSR, NULL, write_eject); | ||
154 | |||
155 | /** | ||
156 | * is_ata - see if a device is an ata device | ||
157 | * @handle: acpi handle of the device | ||
158 | * | ||
159 | * If an acpi object has one of 4 ATA ACPI methods defined, | ||
160 | * then it is an ATA device | ||
161 | */ | ||
162 | static int is_ata(acpi_handle handle) | ||
163 | { | ||
164 | acpi_handle tmp; | ||
165 | |||
166 | if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) || | ||
167 | (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) || | ||
168 | (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) || | ||
169 | (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp)))) | ||
170 | return 1; | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | /** | ||
176 | * parent_is_ata(acpi_handle handle) | ||
177 | * | ||
178 | */ | ||
179 | static int parent_is_ata(acpi_handle handle) | ||
180 | { | ||
181 | acpi_handle phandle; | ||
182 | |||
183 | if (acpi_get_parent(handle, &phandle)) | ||
184 | return 0; | ||
185 | |||
186 | return is_ata(phandle); | ||
187 | } | ||
188 | |||
189 | /** | ||
190 | * is_ejectable_bay - see if a device is an ejectable drive bay | ||
191 | * @handle: acpi handle of the device | ||
192 | * | ||
193 | * If an acpi object is ejectable and has one of the ACPI ATA | ||
194 | * methods defined, then we can safely call it an ejectable | ||
195 | * drive bay | ||
196 | */ | ||
197 | static int is_ejectable_bay(acpi_handle handle) | ||
198 | { | ||
199 | if ((is_ata(handle) || parent_is_ata(handle)) && is_ejectable(handle)) | ||
200 | return 1; | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | #if 0 | ||
205 | /** | ||
206 | * eject_removable_drive - try to eject this drive | ||
207 | * @dev : the device structure of the drive | ||
208 | * | ||
209 | * If a device is a removable drive that requires an _EJ0 method | ||
210 | * to be executed in order to safely remove from the system, do | ||
211 | * it. ATM - always returns success | ||
212 | */ | ||
213 | int eject_removable_drive(struct device *dev) | ||
214 | { | ||
215 | acpi_handle handle = DEVICE_ACPI_HANDLE(dev); | ||
216 | |||
217 | if (handle) { | ||
218 | bay_dprintk(handle, "Got device handle"); | ||
219 | if (is_ejectable_bay(handle)) | ||
220 | eject_device(handle); | ||
221 | } else { | ||
222 | printk("No acpi handle for device\n"); | ||
223 | } | ||
224 | |||
225 | /* should I return an error code? */ | ||
226 | return 0; | ||
227 | } | ||
228 | EXPORT_SYMBOL_GPL(eject_removable_drive); | ||
229 | #endif /* 0 */ | ||
230 | |||
231 | static int acpi_bay_add_fs(struct bay *bay) | ||
232 | { | ||
233 | int ret; | ||
234 | struct device *dev = &bay->pdev->dev; | ||
235 | |||
236 | ret = device_create_file(dev, &dev_attr_present); | ||
237 | if (ret) | ||
238 | goto add_fs_err; | ||
239 | ret = device_create_file(dev, &dev_attr_eject); | ||
240 | if (ret) { | ||
241 | device_remove_file(dev, &dev_attr_present); | ||
242 | goto add_fs_err; | ||
243 | } | ||
244 | return 0; | ||
245 | |||
246 | add_fs_err: | ||
247 | bay_dprintk(bay->handle, "Error adding sysfs files\n"); | ||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | static void acpi_bay_remove_fs(struct bay *bay) | ||
252 | { | ||
253 | struct device *dev = &bay->pdev->dev; | ||
254 | |||
255 | /* cleanup sysfs */ | ||
256 | device_remove_file(dev, &dev_attr_present); | ||
257 | device_remove_file(dev, &dev_attr_eject); | ||
258 | } | ||
259 | |||
260 | static int bay_is_dock_device(acpi_handle handle) | ||
261 | { | ||
262 | acpi_handle parent; | ||
263 | |||
264 | acpi_get_parent(handle, &parent); | ||
265 | |||
266 | /* if the device or it's parent is dependent on the | ||
267 | * dock, then we are a dock device | ||
268 | */ | ||
269 | return (is_dock_device(handle) || is_dock_device(parent)); | ||
270 | } | ||
271 | |||
272 | static int bay_add(acpi_handle handle, int id) | ||
273 | { | ||
274 | acpi_status status; | ||
275 | struct bay *new_bay; | ||
276 | struct platform_device *pdev; | ||
277 | struct acpi_buffer nbuffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
278 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &nbuffer); | ||
279 | |||
280 | bay_dprintk(handle, "Adding notify handler"); | ||
281 | |||
282 | /* | ||
283 | * Initialize bay device structure | ||
284 | */ | ||
285 | new_bay = kzalloc(sizeof(*new_bay), GFP_ATOMIC); | ||
286 | INIT_LIST_HEAD(&new_bay->list); | ||
287 | new_bay->handle = handle; | ||
288 | new_bay->name = (char *)nbuffer.pointer; | ||
289 | |||
290 | /* initialize platform device stuff */ | ||
291 | pdev = platform_device_register_simple(ACPI_BAY_CLASS, id, NULL, 0); | ||
292 | if (IS_ERR(pdev)) { | ||
293 | printk(KERN_ERR PREFIX "Error registering bay device\n"); | ||
294 | goto bay_add_err; | ||
295 | } | ||
296 | new_bay->pdev = pdev; | ||
297 | platform_set_drvdata(pdev, new_bay); | ||
298 | |||
299 | /* | ||
300 | * we want the bay driver to be able to send uevents | ||
301 | */ | ||
302 | pdev->dev.uevent_suppress = 0; | ||
303 | |||
304 | /* register for events on this device */ | ||
305 | status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | ||
306 | bay_notify, new_bay); | ||
307 | if (ACPI_FAILURE(status)) { | ||
308 | printk(KERN_INFO PREFIX "Error installing bay notify handler\n"); | ||
309 | platform_device_unregister(new_bay->pdev); | ||
310 | goto bay_add_err; | ||
311 | } | ||
312 | |||
313 | if (acpi_bay_add_fs(new_bay)) { | ||
314 | acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | ||
315 | bay_notify); | ||
316 | platform_device_unregister(new_bay->pdev); | ||
317 | goto bay_add_err; | ||
318 | } | ||
319 | |||
320 | /* if we are on a dock station, we should register for dock | ||
321 | * notifications. | ||
322 | */ | ||
323 | if (bay_is_dock_device(handle)) { | ||
324 | bay_dprintk(handle, "Is dependent on dock\n"); | ||
325 | register_hotplug_dock_device(handle, bay_notify, new_bay); | ||
326 | } | ||
327 | list_add(&new_bay->list, &drive_bays); | ||
328 | printk(KERN_INFO PREFIX "Bay [%s] Added\n", new_bay->name); | ||
329 | return 0; | ||
330 | |||
331 | bay_add_err: | ||
332 | kfree(new_bay->name); | ||
333 | kfree(new_bay); | ||
334 | return -ENODEV; | ||
335 | } | ||
336 | |||
337 | /** | ||
338 | * bay_notify - act upon an acpi bay notification | ||
339 | * @handle: the bay handle | ||
340 | * @event: the acpi event | ||
341 | * @data: our driver data struct | ||
342 | * | ||
343 | */ | ||
344 | static void bay_notify(acpi_handle handle, u32 event, void *data) | ||
345 | { | ||
346 | struct bay *bay_dev = (struct bay *)data; | ||
347 | struct device *dev = &bay_dev->pdev->dev; | ||
348 | char event_string[12]; | ||
349 | char *envp[] = { event_string, NULL }; | ||
350 | |||
351 | bay_dprintk(handle, "Bay event"); | ||
352 | sprintf(event_string, "BAY_EVENT=%d", event); | ||
353 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); | ||
354 | } | ||
355 | |||
356 | static acpi_status | ||
357 | find_bay(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
358 | { | ||
359 | int *count = (int *)context; | ||
360 | |||
361 | /* | ||
362 | * there could be more than one ejectable bay. | ||
363 | * so, just return AE_OK always so that every object | ||
364 | * will be checked. | ||
365 | */ | ||
366 | if (is_ejectable_bay(handle)) { | ||
367 | bay_dprintk(handle, "found ejectable bay"); | ||
368 | if (!bay_add(handle, *count)) | ||
369 | (*count)++; | ||
370 | } | ||
371 | return AE_OK; | ||
372 | } | ||
373 | |||
374 | static int __init bay_init(void) | ||
375 | { | ||
376 | int bays = 0; | ||
377 | |||
378 | INIT_LIST_HEAD(&drive_bays); | ||
379 | |||
380 | if (acpi_disabled) | ||
381 | return -ENODEV; | ||
382 | |||
383 | /* look for dockable drive bays */ | ||
384 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
385 | ACPI_UINT32_MAX, find_bay, &bays, NULL); | ||
386 | |||
387 | if (!bays) | ||
388 | return -ENODEV; | ||
389 | |||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | static void __exit bay_exit(void) | ||
394 | { | ||
395 | struct bay *bay, *tmp; | ||
396 | |||
397 | list_for_each_entry_safe(bay, tmp, &drive_bays, list) { | ||
398 | if (is_dock_device(bay->handle)) | ||
399 | unregister_hotplug_dock_device(bay->handle); | ||
400 | acpi_bay_remove_fs(bay); | ||
401 | acpi_remove_notify_handler(bay->handle, ACPI_SYSTEM_NOTIFY, | ||
402 | bay_notify); | ||
403 | platform_device_unregister(bay->pdev); | ||
404 | kfree(bay->name); | ||
405 | kfree(bay); | ||
406 | } | ||
407 | } | ||
408 | |||
409 | postcore_initcall(bay_init); | ||
410 | module_exit(bay_exit); | ||
411 | |||
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index ccae305ee55d..c797c6473f31 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -48,6 +48,23 @@ EXPORT_SYMBOL(acpi_root_dir); | |||
48 | 48 | ||
49 | #define STRUCT_TO_INT(s) (*((int*)&s)) | 49 | #define STRUCT_TO_INT(s) (*((int*)&s)) |
50 | 50 | ||
51 | static int set_power_nocheck(const struct dmi_system_id *id) | ||
52 | { | ||
53 | printk(KERN_NOTICE PREFIX "%s detected - " | ||
54 | "disable power check in power transistion\n", id->ident); | ||
55 | acpi_power_nocheck = 1; | ||
56 | return 0; | ||
57 | } | ||
58 | static struct dmi_system_id __cpuinitdata power_nocheck_dmi_table[] = { | ||
59 | { | ||
60 | set_power_nocheck, "HP Pavilion 05", { | ||
61 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), | ||
62 | DMI_MATCH(DMI_SYS_VENDOR, "HP Pavilion 05"), | ||
63 | DMI_MATCH(DMI_PRODUCT_VERSION, "2001211RE101GLEND") }, NULL}, | ||
64 | {}, | ||
65 | }; | ||
66 | |||
67 | |||
51 | /* -------------------------------------------------------------------------- | 68 | /* -------------------------------------------------------------------------- |
52 | Device Management | 69 | Device Management |
53 | -------------------------------------------------------------------------- */ | 70 | -------------------------------------------------------------------------- */ |
@@ -77,7 +94,7 @@ EXPORT_SYMBOL(acpi_bus_get_device); | |||
77 | int acpi_bus_get_status(struct acpi_device *device) | 94 | int acpi_bus_get_status(struct acpi_device *device) |
78 | { | 95 | { |
79 | acpi_status status = AE_OK; | 96 | acpi_status status = AE_OK; |
80 | unsigned long sta = 0; | 97 | unsigned long long sta = 0; |
81 | 98 | ||
82 | 99 | ||
83 | if (!device) | 100 | if (!device) |
@@ -95,21 +112,21 @@ int acpi_bus_get_status(struct acpi_device *device) | |||
95 | } | 112 | } |
96 | 113 | ||
97 | /* | 114 | /* |
98 | * Otherwise we assume the status of our parent (unless we don't | 115 | * According to ACPI spec some device can be present and functional |
99 | * have one, in which case status is implied). | 116 | * even if the parent is not present but functional. |
117 | * In such conditions the child device should not inherit the status | ||
118 | * from the parent. | ||
100 | */ | 119 | */ |
101 | else if (device->parent) | ||
102 | device->status = device->parent->status; | ||
103 | else | 120 | else |
104 | STRUCT_TO_INT(device->status) = | 121 | STRUCT_TO_INT(device->status) = |
105 | ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | | 122 | ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | |
106 | ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING; | 123 | ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING; |
107 | 124 | ||
108 | if (device->status.functional && !device->status.present) { | 125 | if (device->status.functional && !device->status.present) { |
109 | printk(KERN_WARNING PREFIX "Device [%s] status [%08x]: " | 126 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: " |
110 | "functional but not present; setting present\n", | 127 | "functional but not present;\n", |
111 | device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status)); | 128 | device->pnp.bus_id, |
112 | device->status.present = 1; | 129 | (u32) STRUCT_TO_INT(device->status))); |
113 | } | 130 | } |
114 | 131 | ||
115 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n", | 132 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n", |
@@ -155,7 +172,7 @@ int acpi_bus_get_power(acpi_handle handle, int *state) | |||
155 | int result = 0; | 172 | int result = 0; |
156 | acpi_status status = 0; | 173 | acpi_status status = 0; |
157 | struct acpi_device *device = NULL; | 174 | struct acpi_device *device = NULL; |
158 | unsigned long psc = 0; | 175 | unsigned long long psc = 0; |
159 | 176 | ||
160 | 177 | ||
161 | result = acpi_bus_get_device(handle, &device); | 178 | result = acpi_bus_get_device(handle, &device); |
@@ -223,7 +240,19 @@ int acpi_bus_set_power(acpi_handle handle, int state) | |||
223 | /* | 240 | /* |
224 | * Get device's current power state | 241 | * Get device's current power state |
225 | */ | 242 | */ |
226 | acpi_bus_get_power(device->handle, &device->power.state); | 243 | if (!acpi_power_nocheck) { |
244 | /* | ||
245 | * Maybe the incorrect power state is returned on the bogus | ||
246 | * bios, which is different with the real power state. | ||
247 | * For example: the bios returns D0 state and the real power | ||
248 | * state is D3. OS expects to set the device to D0 state. In | ||
249 | * such case if OS uses the power state returned by the BIOS, | ||
250 | * the device can't be transisted to the correct power state. | ||
251 | * So if the acpi_power_nocheck is set, it is unnecessary to | ||
252 | * get the power state by calling acpi_bus_get_power. | ||
253 | */ | ||
254 | acpi_bus_get_power(device->handle, &device->power.state); | ||
255 | } | ||
227 | if ((state == device->power.state) && !device->flags.force_power_state) { | 256 | if ((state == device->power.state) && !device->flags.force_power_state) { |
228 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", | 257 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", |
229 | state)); | 258 | state)); |
@@ -496,6 +525,19 @@ static int acpi_bus_check_scope(struct acpi_device *device) | |||
496 | return 0; | 525 | return 0; |
497 | } | 526 | } |
498 | 527 | ||
528 | static BLOCKING_NOTIFIER_HEAD(acpi_bus_notify_list); | ||
529 | int register_acpi_bus_notifier(struct notifier_block *nb) | ||
530 | { | ||
531 | return blocking_notifier_chain_register(&acpi_bus_notify_list, nb); | ||
532 | } | ||
533 | EXPORT_SYMBOL_GPL(register_acpi_bus_notifier); | ||
534 | |||
535 | void unregister_acpi_bus_notifier(struct notifier_block *nb) | ||
536 | { | ||
537 | blocking_notifier_chain_unregister(&acpi_bus_notify_list, nb); | ||
538 | } | ||
539 | EXPORT_SYMBOL_GPL(unregister_acpi_bus_notifier); | ||
540 | |||
499 | /** | 541 | /** |
500 | * acpi_bus_notify | 542 | * acpi_bus_notify |
501 | * --------------- | 543 | * --------------- |
@@ -506,6 +548,8 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) | |||
506 | int result = 0; | 548 | int result = 0; |
507 | struct acpi_device *device = NULL; | 549 | struct acpi_device *device = NULL; |
508 | 550 | ||
551 | blocking_notifier_call_chain(&acpi_bus_notify_list, | ||
552 | type, (void *)handle); | ||
509 | 553 | ||
510 | if (acpi_bus_get_device(handle, &device)) | 554 | if (acpi_bus_get_device(handle, &device)) |
511 | return; | 555 | return; |
@@ -749,6 +793,12 @@ static int __init acpi_bus_init(void) | |||
749 | goto error1; | 793 | goto error1; |
750 | } | 794 | } |
751 | 795 | ||
796 | /* | ||
797 | * Maybe EC region is required at bus_scan/acpi_get_devices. So it | ||
798 | * is necessary to enable it as early as possible. | ||
799 | */ | ||
800 | acpi_boot_ec_enable(); | ||
801 | |||
752 | printk(KERN_INFO PREFIX "Interpreter enabled\n"); | 802 | printk(KERN_INFO PREFIX "Interpreter enabled\n"); |
753 | 803 | ||
754 | /* Initialize sleep structures */ | 804 | /* Initialize sleep structures */ |
@@ -818,7 +868,11 @@ static int __init acpi_init(void) | |||
818 | } | 868 | } |
819 | } else | 869 | } else |
820 | disable_acpi(); | 870 | disable_acpi(); |
821 | 871 | /* | |
872 | * If the laptop falls into the DMI check table, the power state check | ||
873 | * will be disabled in the course of device power transistion. | ||
874 | */ | ||
875 | dmi_check_system(power_nocheck_dmi_table); | ||
822 | return result; | 876 | return result; |
823 | } | 877 | } |
824 | 878 | ||
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 1dfec413588c..9d568d417eaa 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -145,7 +145,7 @@ static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) | |||
145 | { | 145 | { |
146 | struct acpi_button *button = seq->private; | 146 | struct acpi_button *button = seq->private; |
147 | acpi_status status; | 147 | acpi_status status; |
148 | unsigned long state; | 148 | unsigned long long state; |
149 | 149 | ||
150 | if (!button || !button->device) | 150 | if (!button || !button->device) |
151 | return 0; | 151 | return 0; |
@@ -253,7 +253,7 @@ static int acpi_button_remove_fs(struct acpi_device *device) | |||
253 | -------------------------------------------------------------------------- */ | 253 | -------------------------------------------------------------------------- */ |
254 | static int acpi_lid_send_state(struct acpi_button *button) | 254 | static int acpi_lid_send_state(struct acpi_button *button) |
255 | { | 255 | { |
256 | unsigned long state; | 256 | unsigned long long state; |
257 | acpi_status status; | 257 | acpi_status status; |
258 | 258 | ||
259 | status = acpi_evaluate_integer(button->device->handle, "_LID", NULL, | 259 | status = acpi_evaluate_integer(button->device->handle, "_LID", NULL, |
@@ -384,7 +384,7 @@ static int acpi_button_add(struct acpi_device *device) | |||
384 | return -ENOMEM; | 384 | return -ENOMEM; |
385 | 385 | ||
386 | button->device = device; | 386 | button->device = device; |
387 | acpi_driver_data(device) = button; | 387 | device->driver_data = button; |
388 | 388 | ||
389 | button->input = input = input_allocate_device(); | 389 | button->input = input = input_allocate_device(); |
390 | if (!input) { | 390 | if (!input) { |
diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c index f9db4f444bd0..4441e84b28a9 100644 --- a/drivers/acpi/cm_sbs.c +++ b/drivers/acpi/cm_sbs.c | |||
@@ -52,8 +52,8 @@ struct proc_dir_entry *acpi_lock_ac_dir(void) | |||
52 | if (acpi_ac_dir) { | 52 | if (acpi_ac_dir) { |
53 | lock_ac_dir_cnt++; | 53 | lock_ac_dir_cnt++; |
54 | } else { | 54 | } else { |
55 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 55 | printk(KERN_ERR PREFIX |
56 | "Cannot create %s\n", ACPI_AC_CLASS)); | 56 | "Cannot create %s\n", ACPI_AC_CLASS); |
57 | } | 57 | } |
58 | mutex_unlock(&cm_sbs_mutex); | 58 | mutex_unlock(&cm_sbs_mutex); |
59 | return acpi_ac_dir; | 59 | return acpi_ac_dir; |
@@ -83,8 +83,8 @@ struct proc_dir_entry *acpi_lock_battery_dir(void) | |||
83 | if (acpi_battery_dir) { | 83 | if (acpi_battery_dir) { |
84 | lock_battery_dir_cnt++; | 84 | lock_battery_dir_cnt++; |
85 | } else { | 85 | } else { |
86 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 86 | printk(KERN_ERR PREFIX |
87 | "Cannot create %s\n", ACPI_BATTERY_CLASS)); | 87 | "Cannot create %s\n", ACPI_BATTERY_CLASS); |
88 | } | 88 | } |
89 | mutex_unlock(&cm_sbs_mutex); | 89 | mutex_unlock(&cm_sbs_mutex); |
90 | return acpi_battery_dir; | 90 | return acpi_battery_dir; |
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 3c25ec7a1871..134818b265a9 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c | |||
@@ -76,7 +76,7 @@ static int is_device_present(acpi_handle handle) | |||
76 | { | 76 | { |
77 | acpi_handle temp; | 77 | acpi_handle temp; |
78 | acpi_status status; | 78 | acpi_status status; |
79 | unsigned long sta; | 79 | unsigned long long sta; |
80 | 80 | ||
81 | 81 | ||
82 | status = acpi_get_handle(handle, "_STA", &temp); | 82 | status = acpi_get_handle(handle, "_STA", &temp); |
@@ -108,7 +108,7 @@ static int acpi_container_add(struct acpi_device *device) | |||
108 | container->handle = device->handle; | 108 | container->handle = device->handle; |
109 | strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME); | 109 | strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME); |
110 | strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS); | 110 | strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS); |
111 | acpi_driver_data(device) = container; | 111 | device->driver_data = container; |
112 | 112 | ||
113 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device <%s> bid <%s>\n", | 113 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device <%s> bid <%s>\n", |
114 | acpi_device_name(device), acpi_device_bid(device))); | 114 | acpi_device_name(device), acpi_device_bid(device))); |
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c index 6df564f4ca6e..abf36b4b1d1d 100644 --- a/drivers/acpi/debug.c +++ b/drivers/acpi/debug.c | |||
@@ -47,8 +47,6 @@ static const struct acpi_dlayer acpi_debug_layers[] = { | |||
47 | }; | 47 | }; |
48 | 48 | ||
49 | static const struct acpi_dlevel acpi_debug_levels[] = { | 49 | static const struct acpi_dlevel acpi_debug_levels[] = { |
50 | ACPI_DEBUG_INIT(ACPI_LV_ERROR), | ||
51 | ACPI_DEBUG_INIT(ACPI_LV_WARN), | ||
52 | ACPI_DEBUG_INIT(ACPI_LV_INIT), | 50 | ACPI_DEBUG_INIT(ACPI_LV_INIT), |
53 | ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT), | 51 | ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT), |
54 | ACPI_DEBUG_INIT(ACPI_LV_INFO), | 52 | ACPI_DEBUG_INIT(ACPI_LV_INFO), |
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index 4613b9ca5792..279a5a60a0dd 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c | |||
@@ -103,6 +103,9 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state) | |||
103 | NULL); | 103 | NULL); |
104 | acpi_ex_enter_interpreter(); | 104 | acpi_ex_enter_interpreter(); |
105 | } | 105 | } |
106 | |||
107 | acpi_ds_clear_implicit_return(walk_state); | ||
108 | |||
106 | #ifdef ACPI_DISASSEMBLER | 109 | #ifdef ACPI_DISASSEMBLER |
107 | if (ACPI_FAILURE(status)) { | 110 | if (ACPI_FAILURE(status)) { |
108 | 111 | ||
diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c index 13c43eac35db..d03f81bd1bcb 100644 --- a/drivers/acpi/dispatcher/dsmthdat.c +++ b/drivers/acpi/dispatcher/dsmthdat.c | |||
@@ -43,7 +43,6 @@ | |||
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acdispat.h> | 45 | #include <acpi/acdispat.h> |
46 | #include <acpi/amlcode.h> | ||
47 | #include <acpi/acnamesp.h> | 46 | #include <acpi/acnamesp.h> |
48 | #include <acpi/acinterp.h> | 47 | #include <acpi/acinterp.h> |
49 | 48 | ||
@@ -52,11 +51,11 @@ ACPI_MODULE_NAME("dsmthdat") | |||
52 | 51 | ||
53 | /* Local prototypes */ | 52 | /* Local prototypes */ |
54 | static void | 53 | static void |
55 | acpi_ds_method_data_delete_value(u16 opcode, | 54 | acpi_ds_method_data_delete_value(u8 type, |
56 | u32 index, struct acpi_walk_state *walk_state); | 55 | u32 index, struct acpi_walk_state *walk_state); |
57 | 56 | ||
58 | static acpi_status | 57 | static acpi_status |
59 | acpi_ds_method_data_set_value(u16 opcode, | 58 | acpi_ds_method_data_set_value(u8 type, |
60 | u32 index, | 59 | u32 index, |
61 | union acpi_operand_object *object, | 60 | union acpi_operand_object *object, |
62 | struct acpi_walk_state *walk_state); | 61 | struct acpi_walk_state *walk_state); |
@@ -216,7 +215,7 @@ acpi_ds_method_data_init_args(union acpi_operand_object **params, | |||
216 | * Store the argument in the method/walk descriptor. | 215 | * Store the argument in the method/walk descriptor. |
217 | * Do not copy the arg in order to implement call by reference | 216 | * Do not copy the arg in order to implement call by reference |
218 | */ | 217 | */ |
219 | status = acpi_ds_method_data_set_value(AML_ARG_OP, index, | 218 | status = acpi_ds_method_data_set_value(ACPI_REFCLASS_ARG, index, |
220 | params[index], | 219 | params[index], |
221 | walk_state); | 220 | walk_state); |
222 | if (ACPI_FAILURE(status)) { | 221 | if (ACPI_FAILURE(status)) { |
@@ -234,7 +233,8 @@ acpi_ds_method_data_init_args(union acpi_operand_object **params, | |||
234 | * | 233 | * |
235 | * FUNCTION: acpi_ds_method_data_get_node | 234 | * FUNCTION: acpi_ds_method_data_get_node |
236 | * | 235 | * |
237 | * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP | 236 | * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or |
237 | * ACPI_REFCLASS_ARG | ||
238 | * Index - Which Local or Arg whose type to get | 238 | * Index - Which Local or Arg whose type to get |
239 | * walk_state - Current walk state object | 239 | * walk_state - Current walk state object |
240 | * Node - Where the node is returned. | 240 | * Node - Where the node is returned. |
@@ -246,7 +246,7 @@ acpi_ds_method_data_init_args(union acpi_operand_object **params, | |||
246 | ******************************************************************************/ | 246 | ******************************************************************************/ |
247 | 247 | ||
248 | acpi_status | 248 | acpi_status |
249 | acpi_ds_method_data_get_node(u16 opcode, | 249 | acpi_ds_method_data_get_node(u8 type, |
250 | u32 index, | 250 | u32 index, |
251 | struct acpi_walk_state *walk_state, | 251 | struct acpi_walk_state *walk_state, |
252 | struct acpi_namespace_node **node) | 252 | struct acpi_namespace_node **node) |
@@ -256,8 +256,8 @@ acpi_ds_method_data_get_node(u16 opcode, | |||
256 | /* | 256 | /* |
257 | * Method Locals and Arguments are supported | 257 | * Method Locals and Arguments are supported |
258 | */ | 258 | */ |
259 | switch (opcode) { | 259 | switch (type) { |
260 | case AML_LOCAL_OP: | 260 | case ACPI_REFCLASS_LOCAL: |
261 | 261 | ||
262 | if (index > ACPI_METHOD_MAX_LOCAL) { | 262 | if (index > ACPI_METHOD_MAX_LOCAL) { |
263 | ACPI_ERROR((AE_INFO, | 263 | ACPI_ERROR((AE_INFO, |
@@ -271,7 +271,7 @@ acpi_ds_method_data_get_node(u16 opcode, | |||
271 | *node = &walk_state->local_variables[index]; | 271 | *node = &walk_state->local_variables[index]; |
272 | break; | 272 | break; |
273 | 273 | ||
274 | case AML_ARG_OP: | 274 | case ACPI_REFCLASS_ARG: |
275 | 275 | ||
276 | if (index > ACPI_METHOD_MAX_ARG) { | 276 | if (index > ACPI_METHOD_MAX_ARG) { |
277 | ACPI_ERROR((AE_INFO, | 277 | ACPI_ERROR((AE_INFO, |
@@ -286,8 +286,8 @@ acpi_ds_method_data_get_node(u16 opcode, | |||
286 | break; | 286 | break; |
287 | 287 | ||
288 | default: | 288 | default: |
289 | ACPI_ERROR((AE_INFO, "Opcode %d is invalid", opcode)); | 289 | ACPI_ERROR((AE_INFO, "Type %d is invalid", type)); |
290 | return_ACPI_STATUS(AE_AML_BAD_OPCODE); | 290 | return_ACPI_STATUS(AE_TYPE); |
291 | } | 291 | } |
292 | 292 | ||
293 | return_ACPI_STATUS(AE_OK); | 293 | return_ACPI_STATUS(AE_OK); |
@@ -297,7 +297,8 @@ acpi_ds_method_data_get_node(u16 opcode, | |||
297 | * | 297 | * |
298 | * FUNCTION: acpi_ds_method_data_set_value | 298 | * FUNCTION: acpi_ds_method_data_set_value |
299 | * | 299 | * |
300 | * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP | 300 | * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or |
301 | * ACPI_REFCLASS_ARG | ||
301 | * Index - Which Local or Arg to get | 302 | * Index - Which Local or Arg to get |
302 | * Object - Object to be inserted into the stack entry | 303 | * Object - Object to be inserted into the stack entry |
303 | * walk_state - Current walk state object | 304 | * walk_state - Current walk state object |
@@ -310,7 +311,7 @@ acpi_ds_method_data_get_node(u16 opcode, | |||
310 | ******************************************************************************/ | 311 | ******************************************************************************/ |
311 | 312 | ||
312 | static acpi_status | 313 | static acpi_status |
313 | acpi_ds_method_data_set_value(u16 opcode, | 314 | acpi_ds_method_data_set_value(u8 type, |
314 | u32 index, | 315 | u32 index, |
315 | union acpi_operand_object *object, | 316 | union acpi_operand_object *object, |
316 | struct acpi_walk_state *walk_state) | 317 | struct acpi_walk_state *walk_state) |
@@ -321,13 +322,13 @@ acpi_ds_method_data_set_value(u16 opcode, | |||
321 | ACPI_FUNCTION_TRACE(ds_method_data_set_value); | 322 | ACPI_FUNCTION_TRACE(ds_method_data_set_value); |
322 | 323 | ||
323 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 324 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
324 | "NewObj %p Opcode %X, Refs=%d [%s]\n", object, | 325 | "NewObj %p Type %2.2X, Refs=%d [%s]\n", object, |
325 | opcode, object->common.reference_count, | 326 | type, object->common.reference_count, |
326 | acpi_ut_get_type_name(object->common.type))); | 327 | acpi_ut_get_type_name(object->common.type))); |
327 | 328 | ||
328 | /* Get the namespace node for the arg/local */ | 329 | /* Get the namespace node for the arg/local */ |
329 | 330 | ||
330 | status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node); | 331 | status = acpi_ds_method_data_get_node(type, index, walk_state, &node); |
331 | if (ACPI_FAILURE(status)) { | 332 | if (ACPI_FAILURE(status)) { |
332 | return_ACPI_STATUS(status); | 333 | return_ACPI_STATUS(status); |
333 | } | 334 | } |
@@ -350,7 +351,8 @@ acpi_ds_method_data_set_value(u16 opcode, | |||
350 | * | 351 | * |
351 | * FUNCTION: acpi_ds_method_data_get_value | 352 | * FUNCTION: acpi_ds_method_data_get_value |
352 | * | 353 | * |
353 | * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP | 354 | * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or |
355 | * ACPI_REFCLASS_ARG | ||
354 | * Index - Which local_var or argument to get | 356 | * Index - Which local_var or argument to get |
355 | * walk_state - Current walk state object | 357 | * walk_state - Current walk state object |
356 | * dest_desc - Where Arg or Local value is returned | 358 | * dest_desc - Where Arg or Local value is returned |
@@ -363,7 +365,7 @@ acpi_ds_method_data_set_value(u16 opcode, | |||
363 | ******************************************************************************/ | 365 | ******************************************************************************/ |
364 | 366 | ||
365 | acpi_status | 367 | acpi_status |
366 | acpi_ds_method_data_get_value(u16 opcode, | 368 | acpi_ds_method_data_get_value(u8 type, |
367 | u32 index, | 369 | u32 index, |
368 | struct acpi_walk_state *walk_state, | 370 | struct acpi_walk_state *walk_state, |
369 | union acpi_operand_object **dest_desc) | 371 | union acpi_operand_object **dest_desc) |
@@ -383,7 +385,7 @@ acpi_ds_method_data_get_value(u16 opcode, | |||
383 | 385 | ||
384 | /* Get the namespace node for the arg/local */ | 386 | /* Get the namespace node for the arg/local */ |
385 | 387 | ||
386 | status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node); | 388 | status = acpi_ds_method_data_get_node(type, index, walk_state, &node); |
387 | if (ACPI_FAILURE(status)) { | 389 | if (ACPI_FAILURE(status)) { |
388 | return_ACPI_STATUS(status); | 390 | return_ACPI_STATUS(status); |
389 | } | 391 | } |
@@ -419,8 +421,8 @@ acpi_ds_method_data_get_value(u16 opcode, | |||
419 | /* Otherwise, return the error */ | 421 | /* Otherwise, return the error */ |
420 | 422 | ||
421 | else | 423 | else |
422 | switch (opcode) { | 424 | switch (type) { |
423 | case AML_ARG_OP: | 425 | case ACPI_REFCLASS_ARG: |
424 | 426 | ||
425 | ACPI_ERROR((AE_INFO, | 427 | ACPI_ERROR((AE_INFO, |
426 | "Uninitialized Arg[%d] at node %p", | 428 | "Uninitialized Arg[%d] at node %p", |
@@ -428,7 +430,7 @@ acpi_ds_method_data_get_value(u16 opcode, | |||
428 | 430 | ||
429 | return_ACPI_STATUS(AE_AML_UNINITIALIZED_ARG); | 431 | return_ACPI_STATUS(AE_AML_UNINITIALIZED_ARG); |
430 | 432 | ||
431 | case AML_LOCAL_OP: | 433 | case ACPI_REFCLASS_LOCAL: |
432 | 434 | ||
433 | ACPI_ERROR((AE_INFO, | 435 | ACPI_ERROR((AE_INFO, |
434 | "Uninitialized Local[%d] at node %p", | 436 | "Uninitialized Local[%d] at node %p", |
@@ -437,9 +439,10 @@ acpi_ds_method_data_get_value(u16 opcode, | |||
437 | return_ACPI_STATUS(AE_AML_UNINITIALIZED_LOCAL); | 439 | return_ACPI_STATUS(AE_AML_UNINITIALIZED_LOCAL); |
438 | 440 | ||
439 | default: | 441 | default: |
442 | |||
440 | ACPI_ERROR((AE_INFO, | 443 | ACPI_ERROR((AE_INFO, |
441 | "Not a Arg/Local opcode: %X", | 444 | "Not a Arg/Local opcode: %X", |
442 | opcode)); | 445 | type)); |
443 | return_ACPI_STATUS(AE_AML_INTERNAL); | 446 | return_ACPI_STATUS(AE_AML_INTERNAL); |
444 | } | 447 | } |
445 | } | 448 | } |
@@ -458,7 +461,8 @@ acpi_ds_method_data_get_value(u16 opcode, | |||
458 | * | 461 | * |
459 | * FUNCTION: acpi_ds_method_data_delete_value | 462 | * FUNCTION: acpi_ds_method_data_delete_value |
460 | * | 463 | * |
461 | * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP | 464 | * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or |
465 | * ACPI_REFCLASS_ARG | ||
462 | * Index - Which local_var or argument to delete | 466 | * Index - Which local_var or argument to delete |
463 | * walk_state - Current walk state object | 467 | * walk_state - Current walk state object |
464 | * | 468 | * |
@@ -470,7 +474,7 @@ acpi_ds_method_data_get_value(u16 opcode, | |||
470 | ******************************************************************************/ | 474 | ******************************************************************************/ |
471 | 475 | ||
472 | static void | 476 | static void |
473 | acpi_ds_method_data_delete_value(u16 opcode, | 477 | acpi_ds_method_data_delete_value(u8 type, |
474 | u32 index, struct acpi_walk_state *walk_state) | 478 | u32 index, struct acpi_walk_state *walk_state) |
475 | { | 479 | { |
476 | acpi_status status; | 480 | acpi_status status; |
@@ -481,7 +485,7 @@ acpi_ds_method_data_delete_value(u16 opcode, | |||
481 | 485 | ||
482 | /* Get the namespace node for the arg/local */ | 486 | /* Get the namespace node for the arg/local */ |
483 | 487 | ||
484 | status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node); | 488 | status = acpi_ds_method_data_get_node(type, index, walk_state, &node); |
485 | if (ACPI_FAILURE(status)) { | 489 | if (ACPI_FAILURE(status)) { |
486 | return_VOID; | 490 | return_VOID; |
487 | } | 491 | } |
@@ -514,7 +518,8 @@ acpi_ds_method_data_delete_value(u16 opcode, | |||
514 | * | 518 | * |
515 | * FUNCTION: acpi_ds_store_object_to_local | 519 | * FUNCTION: acpi_ds_store_object_to_local |
516 | * | 520 | * |
517 | * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP | 521 | * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or |
522 | * ACPI_REFCLASS_ARG | ||
518 | * Index - Which Local or Arg to set | 523 | * Index - Which Local or Arg to set |
519 | * obj_desc - Value to be stored | 524 | * obj_desc - Value to be stored |
520 | * walk_state - Current walk state | 525 | * walk_state - Current walk state |
@@ -528,7 +533,7 @@ acpi_ds_method_data_delete_value(u16 opcode, | |||
528 | ******************************************************************************/ | 533 | ******************************************************************************/ |
529 | 534 | ||
530 | acpi_status | 535 | acpi_status |
531 | acpi_ds_store_object_to_local(u16 opcode, | 536 | acpi_ds_store_object_to_local(u8 type, |
532 | u32 index, | 537 | u32 index, |
533 | union acpi_operand_object *obj_desc, | 538 | union acpi_operand_object *obj_desc, |
534 | struct acpi_walk_state *walk_state) | 539 | struct acpi_walk_state *walk_state) |
@@ -539,8 +544,8 @@ acpi_ds_store_object_to_local(u16 opcode, | |||
539 | union acpi_operand_object *new_obj_desc; | 544 | union acpi_operand_object *new_obj_desc; |
540 | 545 | ||
541 | ACPI_FUNCTION_TRACE(ds_store_object_to_local); | 546 | ACPI_FUNCTION_TRACE(ds_store_object_to_local); |
542 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Opcode=%X Index=%d Obj=%p\n", | 547 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Type=%2.2X Index=%d Obj=%p\n", |
543 | opcode, index, obj_desc)); | 548 | type, index, obj_desc)); |
544 | 549 | ||
545 | /* Parameter validation */ | 550 | /* Parameter validation */ |
546 | 551 | ||
@@ -550,7 +555,7 @@ acpi_ds_store_object_to_local(u16 opcode, | |||
550 | 555 | ||
551 | /* Get the namespace node for the arg/local */ | 556 | /* Get the namespace node for the arg/local */ |
552 | 557 | ||
553 | status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node); | 558 | status = acpi_ds_method_data_get_node(type, index, walk_state, &node); |
554 | if (ACPI_FAILURE(status)) { | 559 | if (ACPI_FAILURE(status)) { |
555 | return_ACPI_STATUS(status); | 560 | return_ACPI_STATUS(status); |
556 | } | 561 | } |
@@ -602,7 +607,7 @@ acpi_ds_store_object_to_local(u16 opcode, | |||
602 | * | 607 | * |
603 | * Weird, but true. | 608 | * Weird, but true. |
604 | */ | 609 | */ |
605 | if (opcode == AML_ARG_OP) { | 610 | if (type == ACPI_REFCLASS_ARG) { |
606 | /* | 611 | /* |
607 | * If we have a valid reference object that came from ref_of(), | 612 | * If we have a valid reference object that came from ref_of(), |
608 | * do the indirect store | 613 | * do the indirect store |
@@ -611,8 +616,8 @@ acpi_ds_store_object_to_local(u16 opcode, | |||
611 | ACPI_DESC_TYPE_OPERAND) | 616 | ACPI_DESC_TYPE_OPERAND) |
612 | && (current_obj_desc->common.type == | 617 | && (current_obj_desc->common.type == |
613 | ACPI_TYPE_LOCAL_REFERENCE) | 618 | ACPI_TYPE_LOCAL_REFERENCE) |
614 | && (current_obj_desc->reference.opcode == | 619 | && (current_obj_desc->reference.class == |
615 | AML_REF_OF_OP)) { | 620 | ACPI_REFCLASS_REFOF)) { |
616 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 621 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
617 | "Arg (%p) is an ObjRef(Node), storing in node %p\n", | 622 | "Arg (%p) is an ObjRef(Node), storing in node %p\n", |
618 | new_obj_desc, | 623 | new_obj_desc, |
@@ -640,11 +645,9 @@ acpi_ds_store_object_to_local(u16 opcode, | |||
640 | } | 645 | } |
641 | } | 646 | } |
642 | 647 | ||
643 | /* | 648 | /* Delete the existing object before storing the new one */ |
644 | * Delete the existing object | 649 | |
645 | * before storing the new one | 650 | acpi_ds_method_data_delete_value(type, index, walk_state); |
646 | */ | ||
647 | acpi_ds_method_data_delete_value(opcode, index, walk_state); | ||
648 | } | 651 | } |
649 | 652 | ||
650 | /* | 653 | /* |
@@ -653,7 +656,7 @@ acpi_ds_store_object_to_local(u16 opcode, | |||
653 | * (increments the object reference count by one) | 656 | * (increments the object reference count by one) |
654 | */ | 657 | */ |
655 | status = | 658 | status = |
656 | acpi_ds_method_data_set_value(opcode, index, new_obj_desc, | 659 | acpi_ds_method_data_set_value(type, index, new_obj_desc, |
657 | walk_state); | 660 | walk_state); |
658 | 661 | ||
659 | /* Remove local reference if we copied the object above */ | 662 | /* Remove local reference if we copied the object above */ |
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c index 0f2805899210..4f08e599d07e 100644 --- a/drivers/acpi/dispatcher/dsobject.c +++ b/drivers/acpi/dispatcher/dsobject.c | |||
@@ -731,54 +731,70 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, | |||
731 | switch (op_info->type) { | 731 | switch (op_info->type) { |
732 | case AML_TYPE_LOCAL_VARIABLE: | 732 | case AML_TYPE_LOCAL_VARIABLE: |
733 | 733 | ||
734 | /* Split the opcode into a base opcode + offset */ | 734 | /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */ |
735 | 735 | ||
736 | obj_desc->reference.opcode = AML_LOCAL_OP; | 736 | obj_desc->reference.value = opcode - AML_LOCAL_OP; |
737 | obj_desc->reference.offset = opcode - AML_LOCAL_OP; | 737 | obj_desc->reference.class = ACPI_REFCLASS_LOCAL; |
738 | 738 | ||
739 | #ifndef ACPI_NO_METHOD_EXECUTION | 739 | #ifndef ACPI_NO_METHOD_EXECUTION |
740 | status = acpi_ds_method_data_get_node(AML_LOCAL_OP, | 740 | status = |
741 | obj_desc-> | 741 | acpi_ds_method_data_get_node(ACPI_REFCLASS_LOCAL, |
742 | reference.offset, | 742 | obj_desc->reference. |
743 | walk_state, | 743 | value, walk_state, |
744 | (struct | 744 | ACPI_CAST_INDIRECT_PTR |
745 | acpi_namespace_node | 745 | (struct |
746 | **)&obj_desc-> | 746 | acpi_namespace_node, |
747 | reference.object); | 747 | &obj_desc->reference. |
748 | object)); | ||
748 | #endif | 749 | #endif |
749 | break; | 750 | break; |
750 | 751 | ||
751 | case AML_TYPE_METHOD_ARGUMENT: | 752 | case AML_TYPE_METHOD_ARGUMENT: |
752 | 753 | ||
753 | /* Split the opcode into a base opcode + offset */ | 754 | /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */ |
754 | 755 | ||
755 | obj_desc->reference.opcode = AML_ARG_OP; | 756 | obj_desc->reference.value = opcode - AML_ARG_OP; |
756 | obj_desc->reference.offset = opcode - AML_ARG_OP; | 757 | obj_desc->reference.class = ACPI_REFCLASS_ARG; |
757 | 758 | ||
758 | #ifndef ACPI_NO_METHOD_EXECUTION | 759 | #ifndef ACPI_NO_METHOD_EXECUTION |
759 | status = acpi_ds_method_data_get_node(AML_ARG_OP, | 760 | status = acpi_ds_method_data_get_node(ACPI_REFCLASS_ARG, |
760 | obj_desc-> | 761 | obj_desc-> |
761 | reference.offset, | 762 | reference.value, |
762 | walk_state, | 763 | walk_state, |
764 | ACPI_CAST_INDIRECT_PTR | ||
763 | (struct | 765 | (struct |
764 | acpi_namespace_node | 766 | acpi_namespace_node, |
765 | **)&obj_desc-> | 767 | &obj_desc-> |
766 | reference.object); | 768 | reference. |
769 | object)); | ||
767 | #endif | 770 | #endif |
768 | break; | 771 | break; |
769 | 772 | ||
770 | default: /* Other literals, etc.. */ | 773 | default: /* Object name or Debug object */ |
771 | 774 | ||
772 | if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) { | 775 | switch (op->common.aml_opcode) { |
776 | case AML_INT_NAMEPATH_OP: | ||
773 | 777 | ||
774 | /* Node was saved in Op */ | 778 | /* Node was saved in Op */ |
775 | 779 | ||
776 | obj_desc->reference.node = op->common.node; | 780 | obj_desc->reference.node = op->common.node; |
777 | obj_desc->reference.object = | 781 | obj_desc->reference.object = |
778 | op->common.node->object; | 782 | op->common.node->object; |
779 | } | 783 | obj_desc->reference.class = ACPI_REFCLASS_NAME; |
784 | break; | ||
785 | |||
786 | case AML_DEBUG_OP: | ||
780 | 787 | ||
781 | obj_desc->reference.opcode = opcode; | 788 | obj_desc->reference.class = ACPI_REFCLASS_DEBUG; |
789 | break; | ||
790 | |||
791 | default: | ||
792 | |||
793 | ACPI_ERROR((AE_INFO, | ||
794 | "Unimplemented reference type for AML opcode: %4.4X", | ||
795 | opcode)); | ||
796 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | ||
797 | } | ||
782 | break; | 798 | break; |
783 | } | 799 | } |
784 | break; | 800 | break; |
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c index 6a81c4400edf..69fae5905bb8 100644 --- a/drivers/acpi/dispatcher/dsopcode.c +++ b/drivers/acpi/dispatcher/dsopcode.c | |||
@@ -1330,7 +1330,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, | |||
1330 | (walk_state->results->results.obj_desc[0]) == | 1330 | (walk_state->results->results.obj_desc[0]) == |
1331 | ACPI_TYPE_LOCAL_REFERENCE) | 1331 | ACPI_TYPE_LOCAL_REFERENCE) |
1332 | && ((walk_state->results->results.obj_desc[0])-> | 1332 | && ((walk_state->results->results.obj_desc[0])-> |
1333 | reference.opcode != AML_INDEX_OP)) { | 1333 | reference.class != ACPI_REFCLASS_INDEX)) { |
1334 | status = | 1334 | status = |
1335 | acpi_ex_resolve_to_value(&walk_state-> | 1335 | acpi_ex_resolve_to_value(&walk_state-> |
1336 | results->results. | 1336 | results->results. |
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c index b5072fa9c920..396fe12078cd 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/dispatcher/dswexec.c | |||
@@ -166,6 +166,10 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, | |||
166 | status = AE_CTRL_FALSE; | 166 | status = AE_CTRL_FALSE; |
167 | } | 167 | } |
168 | 168 | ||
169 | /* Predicate can be used for an implicit return value */ | ||
170 | |||
171 | (void)acpi_ds_do_implicit_return(local_obj_desc, walk_state, TRUE); | ||
172 | |||
169 | cleanup: | 173 | cleanup: |
170 | 174 | ||
171 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n", | 175 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n", |
@@ -429,10 +433,10 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) | |||
429 | ACPI_TYPE_LOCAL_REFERENCE) | 433 | ACPI_TYPE_LOCAL_REFERENCE) |
430 | && (walk_state->operands[1]->common.type == | 434 | && (walk_state->operands[1]->common.type == |
431 | ACPI_TYPE_LOCAL_REFERENCE) | 435 | ACPI_TYPE_LOCAL_REFERENCE) |
432 | && (walk_state->operands[0]->reference.opcode == | 436 | && (walk_state->operands[0]->reference.class == |
433 | walk_state->operands[1]->reference.opcode) | 437 | walk_state->operands[1]->reference.class) |
434 | && (walk_state->operands[0]->reference.offset == | 438 | && (walk_state->operands[0]->reference.value == |
435 | walk_state->operands[1]->reference.offset)) { | 439 | walk_state->operands[1]->reference.value)) { |
436 | status = AE_OK; | 440 | status = AE_OK; |
437 | } else { | 441 | } else { |
438 | ACPI_EXCEPTION((AE_INFO, status, | 442 | ACPI_EXCEPTION((AE_INFO, status, |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 7d2edf143f16..5b30b8d91d71 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -48,7 +48,6 @@ MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to " | |||
48 | " before undocking"); | 48 | " before undocking"); |
49 | 49 | ||
50 | static struct atomic_notifier_head dock_notifier_list; | 50 | static struct atomic_notifier_head dock_notifier_list; |
51 | static struct platform_device *dock_device; | ||
52 | static char dock_device_name[] = "dock"; | 51 | static char dock_device_name[] = "dock"; |
53 | 52 | ||
54 | static const struct acpi_device_id dock_device_ids[] = { | 53 | static const struct acpi_device_id dock_device_ids[] = { |
@@ -65,23 +64,29 @@ struct dock_station { | |||
65 | struct mutex hp_lock; | 64 | struct mutex hp_lock; |
66 | struct list_head dependent_devices; | 65 | struct list_head dependent_devices; |
67 | struct list_head hotplug_devices; | 66 | struct list_head hotplug_devices; |
67 | |||
68 | struct list_head sibiling; | ||
69 | struct platform_device *dock_device; | ||
68 | }; | 70 | }; |
71 | static LIST_HEAD(dock_stations); | ||
72 | static int dock_station_count; | ||
69 | 73 | ||
70 | struct dock_dependent_device { | 74 | struct dock_dependent_device { |
71 | struct list_head list; | 75 | struct list_head list; |
72 | struct list_head hotplug_list; | 76 | struct list_head hotplug_list; |
73 | acpi_handle handle; | 77 | acpi_handle handle; |
74 | acpi_notify_handler handler; | 78 | struct acpi_dock_ops *ops; |
75 | void *context; | 79 | void *context; |
76 | }; | 80 | }; |
77 | 81 | ||
78 | #define DOCK_DOCKING 0x00000001 | 82 | #define DOCK_DOCKING 0x00000001 |
79 | #define DOCK_UNDOCKING 0x00000002 | 83 | #define DOCK_UNDOCKING 0x00000002 |
84 | #define DOCK_IS_DOCK 0x00000010 | ||
85 | #define DOCK_IS_ATA 0x00000020 | ||
86 | #define DOCK_IS_BAT 0x00000040 | ||
80 | #define DOCK_EVENT 3 | 87 | #define DOCK_EVENT 3 |
81 | #define UNDOCK_EVENT 2 | 88 | #define UNDOCK_EVENT 2 |
82 | 89 | ||
83 | static struct dock_station *dock_station; | ||
84 | |||
85 | /***************************************************************************** | 90 | /***************************************************************************** |
86 | * Dock Dependent device functions * | 91 | * Dock Dependent device functions * |
87 | *****************************************************************************/ | 92 | *****************************************************************************/ |
@@ -199,6 +204,60 @@ static int is_dock(acpi_handle handle) | |||
199 | return 1; | 204 | return 1; |
200 | } | 205 | } |
201 | 206 | ||
207 | static int is_ejectable(acpi_handle handle) | ||
208 | { | ||
209 | acpi_status status; | ||
210 | acpi_handle tmp; | ||
211 | |||
212 | status = acpi_get_handle(handle, "_EJ0", &tmp); | ||
213 | if (ACPI_FAILURE(status)) | ||
214 | return 0; | ||
215 | return 1; | ||
216 | } | ||
217 | |||
218 | static int is_ata(acpi_handle handle) | ||
219 | { | ||
220 | acpi_handle tmp; | ||
221 | |||
222 | if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) || | ||
223 | (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) || | ||
224 | (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) || | ||
225 | (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp)))) | ||
226 | return 1; | ||
227 | |||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static int is_battery(acpi_handle handle) | ||
232 | { | ||
233 | struct acpi_device_info *info; | ||
234 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
235 | int ret = 1; | ||
236 | |||
237 | if (!ACPI_SUCCESS(acpi_get_object_info(handle, &buffer))) | ||
238 | return 0; | ||
239 | info = buffer.pointer; | ||
240 | if (!(info->valid & ACPI_VALID_HID)) | ||
241 | ret = 0; | ||
242 | else | ||
243 | ret = !strcmp("PNP0C0A", info->hardware_id.value); | ||
244 | |||
245 | kfree(buffer.pointer); | ||
246 | return ret; | ||
247 | } | ||
248 | |||
249 | static int is_ejectable_bay(acpi_handle handle) | ||
250 | { | ||
251 | acpi_handle phandle; | ||
252 | if (!is_ejectable(handle)) | ||
253 | return 0; | ||
254 | if (is_battery(handle) || is_ata(handle)) | ||
255 | return 1; | ||
256 | if (!acpi_get_parent(handle, &phandle) && is_ata(phandle)) | ||
257 | return 1; | ||
258 | return 0; | ||
259 | } | ||
260 | |||
202 | /** | 261 | /** |
203 | * is_dock_device - see if a device is on a dock station | 262 | * is_dock_device - see if a device is on a dock station |
204 | * @handle: acpi handle of the device | 263 | * @handle: acpi handle of the device |
@@ -209,11 +268,17 @@ static int is_dock(acpi_handle handle) | |||
209 | */ | 268 | */ |
210 | int is_dock_device(acpi_handle handle) | 269 | int is_dock_device(acpi_handle handle) |
211 | { | 270 | { |
212 | if (!dock_station) | 271 | struct dock_station *dock_station; |
272 | |||
273 | if (!dock_station_count) | ||
213 | return 0; | 274 | return 0; |
214 | 275 | ||
215 | if (is_dock(handle) || find_dock_dependent_device(dock_station, handle)) | 276 | if (is_dock(handle)) |
216 | return 1; | 277 | return 1; |
278 | list_for_each_entry(dock_station, &dock_stations, sibiling) { | ||
279 | if (find_dock_dependent_device(dock_station, handle)) | ||
280 | return 1; | ||
281 | } | ||
217 | 282 | ||
218 | return 0; | 283 | return 0; |
219 | } | 284 | } |
@@ -229,7 +294,7 @@ EXPORT_SYMBOL_GPL(is_dock_device); | |||
229 | */ | 294 | */ |
230 | static int dock_present(struct dock_station *ds) | 295 | static int dock_present(struct dock_station *ds) |
231 | { | 296 | { |
232 | unsigned long sta; | 297 | unsigned long long sta; |
233 | acpi_status status; | 298 | acpi_status status; |
234 | 299 | ||
235 | if (ds) { | 300 | if (ds) { |
@@ -320,8 +385,8 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) | |||
320 | * First call driver specific hotplug functions | 385 | * First call driver specific hotplug functions |
321 | */ | 386 | */ |
322 | list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) { | 387 | list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) { |
323 | if (dd->handler) | 388 | if (dd->ops && dd->ops->handler) |
324 | dd->handler(dd->handle, event, dd->context); | 389 | dd->ops->handler(dd->handle, event, dd->context); |
325 | } | 390 | } |
326 | 391 | ||
327 | /* | 392 | /* |
@@ -341,9 +406,10 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) | |||
341 | 406 | ||
342 | static void dock_event(struct dock_station *ds, u32 event, int num) | 407 | static void dock_event(struct dock_station *ds, u32 event, int num) |
343 | { | 408 | { |
344 | struct device *dev = &dock_device->dev; | 409 | struct device *dev = &ds->dock_device->dev; |
345 | char event_string[13]; | 410 | char event_string[13]; |
346 | char *envp[] = { event_string, NULL }; | 411 | char *envp[] = { event_string, NULL }; |
412 | struct dock_dependent_device *dd; | ||
347 | 413 | ||
348 | if (num == UNDOCK_EVENT) | 414 | if (num == UNDOCK_EVENT) |
349 | sprintf(event_string, "EVENT=undock"); | 415 | sprintf(event_string, "EVENT=undock"); |
@@ -354,7 +420,14 @@ static void dock_event(struct dock_station *ds, u32 event, int num) | |||
354 | * Indicate that the status of the dock station has | 420 | * Indicate that the status of the dock station has |
355 | * changed. | 421 | * changed. |
356 | */ | 422 | */ |
357 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); | 423 | if (num == DOCK_EVENT) |
424 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); | ||
425 | |||
426 | list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) | ||
427 | if (dd->ops && dd->ops->uevent) | ||
428 | dd->ops->uevent(dd->handle, event, dd->context); | ||
429 | if (num != DOCK_EVENT) | ||
430 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); | ||
358 | } | 431 | } |
359 | 432 | ||
360 | /** | 433 | /** |
@@ -414,9 +487,10 @@ static void handle_dock(struct dock_station *ds, int dock) | |||
414 | arg.type = ACPI_TYPE_INTEGER; | 487 | arg.type = ACPI_TYPE_INTEGER; |
415 | arg.integer.value = dock; | 488 | arg.integer.value = dock; |
416 | status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer); | 489 | status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer); |
417 | if (ACPI_FAILURE(status)) | 490 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) |
418 | printk(KERN_ERR PREFIX "%s - failed to execute _DCK\n", | 491 | ACPI_EXCEPTION((AE_INFO, status, "%s - failed to execute" |
419 | (char *)name_buffer.pointer); | 492 | " _DCK\n", (char *)name_buffer.pointer)); |
493 | |||
420 | kfree(buffer.pointer); | 494 | kfree(buffer.pointer); |
421 | kfree(name_buffer.pointer); | 495 | kfree(name_buffer.pointer); |
422 | } | 496 | } |
@@ -452,6 +526,25 @@ static inline void complete_undock(struct dock_station *ds) | |||
452 | ds->flags &= ~(DOCK_UNDOCKING); | 526 | ds->flags &= ~(DOCK_UNDOCKING); |
453 | } | 527 | } |
454 | 528 | ||
529 | static void dock_lock(struct dock_station *ds, int lock) | ||
530 | { | ||
531 | struct acpi_object_list arg_list; | ||
532 | union acpi_object arg; | ||
533 | acpi_status status; | ||
534 | |||
535 | arg_list.count = 1; | ||
536 | arg_list.pointer = &arg; | ||
537 | arg.type = ACPI_TYPE_INTEGER; | ||
538 | arg.integer.value = !!lock; | ||
539 | status = acpi_evaluate_object(ds->handle, "_LCK", &arg_list, NULL); | ||
540 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
541 | if (lock) | ||
542 | printk(KERN_WARNING PREFIX "Locking device failed\n"); | ||
543 | else | ||
544 | printk(KERN_WARNING PREFIX "Unlocking device failed\n"); | ||
545 | } | ||
546 | } | ||
547 | |||
455 | /** | 548 | /** |
456 | * dock_in_progress - see if we are in the middle of handling a dock event | 549 | * dock_in_progress - see if we are in the middle of handling a dock event |
457 | * @ds: the dock station | 550 | * @ds: the dock station |
@@ -479,7 +572,7 @@ static int dock_in_progress(struct dock_station *ds) | |||
479 | */ | 572 | */ |
480 | int register_dock_notifier(struct notifier_block *nb) | 573 | int register_dock_notifier(struct notifier_block *nb) |
481 | { | 574 | { |
482 | if (!dock_station) | 575 | if (!dock_station_count) |
483 | return -ENODEV; | 576 | return -ENODEV; |
484 | 577 | ||
485 | return atomic_notifier_chain_register(&dock_notifier_list, nb); | 578 | return atomic_notifier_chain_register(&dock_notifier_list, nb); |
@@ -493,7 +586,7 @@ EXPORT_SYMBOL_GPL(register_dock_notifier); | |||
493 | */ | 586 | */ |
494 | void unregister_dock_notifier(struct notifier_block *nb) | 587 | void unregister_dock_notifier(struct notifier_block *nb) |
495 | { | 588 | { |
496 | if (!dock_station) | 589 | if (!dock_station_count) |
497 | return; | 590 | return; |
498 | 591 | ||
499 | atomic_notifier_chain_unregister(&dock_notifier_list, nb); | 592 | atomic_notifier_chain_unregister(&dock_notifier_list, nb); |
@@ -504,7 +597,7 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier); | |||
504 | /** | 597 | /** |
505 | * register_hotplug_dock_device - register a hotplug function | 598 | * register_hotplug_dock_device - register a hotplug function |
506 | * @handle: the handle of the device | 599 | * @handle: the handle of the device |
507 | * @handler: the acpi_notifier_handler to call after docking | 600 | * @ops: handlers to call after docking |
508 | * @context: device specific data | 601 | * @context: device specific data |
509 | * | 602 | * |
510 | * If a driver would like to perform a hotplug operation after a dock | 603 | * If a driver would like to perform a hotplug operation after a dock |
@@ -512,27 +605,36 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier); | |||
512 | * the dock driver after _DCK is executed. | 605 | * the dock driver after _DCK is executed. |
513 | */ | 606 | */ |
514 | int | 607 | int |
515 | register_hotplug_dock_device(acpi_handle handle, acpi_notify_handler handler, | 608 | register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops, |
516 | void *context) | 609 | void *context) |
517 | { | 610 | { |
518 | struct dock_dependent_device *dd; | 611 | struct dock_dependent_device *dd; |
612 | struct dock_station *dock_station; | ||
613 | int ret = -EINVAL; | ||
519 | 614 | ||
520 | if (!dock_station) | 615 | if (!dock_station_count) |
521 | return -ENODEV; | 616 | return -ENODEV; |
522 | 617 | ||
523 | /* | 618 | /* |
524 | * make sure this handle is for a device dependent on the dock, | 619 | * make sure this handle is for a device dependent on the dock, |
525 | * this would include the dock station itself | 620 | * this would include the dock station itself |
526 | */ | 621 | */ |
527 | dd = find_dock_dependent_device(dock_station, handle); | 622 | list_for_each_entry(dock_station, &dock_stations, sibiling) { |
528 | if (dd) { | 623 | /* |
529 | dd->handler = handler; | 624 | * An ATA bay can be in a dock and itself can be ejected |
530 | dd->context = context; | 625 | * seperately, so there are two 'dock stations' which need the |
531 | dock_add_hotplug_device(dock_station, dd); | 626 | * ops |
532 | return 0; | 627 | */ |
628 | dd = find_dock_dependent_device(dock_station, handle); | ||
629 | if (dd) { | ||
630 | dd->ops = ops; | ||
631 | dd->context = context; | ||
632 | dock_add_hotplug_device(dock_station, dd); | ||
633 | ret = 0; | ||
634 | } | ||
533 | } | 635 | } |
534 | 636 | ||
535 | return -EINVAL; | 637 | return ret; |
536 | } | 638 | } |
537 | 639 | ||
538 | EXPORT_SYMBOL_GPL(register_hotplug_dock_device); | 640 | EXPORT_SYMBOL_GPL(register_hotplug_dock_device); |
@@ -544,13 +646,16 @@ EXPORT_SYMBOL_GPL(register_hotplug_dock_device); | |||
544 | void unregister_hotplug_dock_device(acpi_handle handle) | 646 | void unregister_hotplug_dock_device(acpi_handle handle) |
545 | { | 647 | { |
546 | struct dock_dependent_device *dd; | 648 | struct dock_dependent_device *dd; |
649 | struct dock_station *dock_station; | ||
547 | 650 | ||
548 | if (!dock_station) | 651 | if (!dock_station_count) |
549 | return; | 652 | return; |
550 | 653 | ||
551 | dd = find_dock_dependent_device(dock_station, handle); | 654 | list_for_each_entry(dock_station, &dock_stations, sibiling) { |
552 | if (dd) | 655 | dd = find_dock_dependent_device(dock_station, handle); |
553 | dock_del_hotplug_device(dock_station, dd); | 656 | if (dd) |
657 | dock_del_hotplug_device(dock_station, dd); | ||
658 | } | ||
554 | } | 659 | } |
555 | 660 | ||
556 | EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); | 661 | EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); |
@@ -575,13 +680,9 @@ static int handle_eject_request(struct dock_station *ds, u32 event) | |||
575 | */ | 680 | */ |
576 | dock_event(ds, event, UNDOCK_EVENT); | 681 | dock_event(ds, event, UNDOCK_EVENT); |
577 | 682 | ||
578 | if (!dock_present(ds)) { | ||
579 | complete_undock(ds); | ||
580 | return -ENODEV; | ||
581 | } | ||
582 | |||
583 | hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST); | 683 | hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST); |
584 | undock(ds); | 684 | undock(ds); |
685 | dock_lock(ds, 0); | ||
585 | eject_dock(ds); | 686 | eject_dock(ds); |
586 | if (dock_present(ds)) { | 687 | if (dock_present(ds)) { |
587 | printk(KERN_ERR PREFIX "Unable to undock!\n"); | 688 | printk(KERN_ERR PREFIX "Unable to undock!\n"); |
@@ -604,14 +705,36 @@ static int handle_eject_request(struct dock_station *ds, u32 event) | |||
604 | static void dock_notify(acpi_handle handle, u32 event, void *data) | 705 | static void dock_notify(acpi_handle handle, u32 event, void *data) |
605 | { | 706 | { |
606 | struct dock_station *ds = data; | 707 | struct dock_station *ds = data; |
708 | struct acpi_device *tmp; | ||
709 | int surprise_removal = 0; | ||
710 | |||
711 | /* | ||
712 | * According to acpi spec 3.0a, if a DEVICE_CHECK notification | ||
713 | * is sent and _DCK is present, it is assumed to mean an undock | ||
714 | * request. | ||
715 | */ | ||
716 | if ((ds->flags & DOCK_IS_DOCK) && event == ACPI_NOTIFY_DEVICE_CHECK) | ||
717 | event = ACPI_NOTIFY_EJECT_REQUEST; | ||
607 | 718 | ||
719 | /* | ||
720 | * dock station: BUS_CHECK - docked or surprise removal | ||
721 | * DEVICE_CHECK - undocked | ||
722 | * other device: BUS_CHECK/DEVICE_CHECK - added or surprise removal | ||
723 | * | ||
724 | * To simplify event handling, dock dependent device handler always | ||
725 | * get ACPI_NOTIFY_BUS_CHECK/ACPI_NOTIFY_DEVICE_CHECK for add and | ||
726 | * ACPI_NOTIFY_EJECT_REQUEST for removal | ||
727 | */ | ||
608 | switch (event) { | 728 | switch (event) { |
609 | case ACPI_NOTIFY_BUS_CHECK: | 729 | case ACPI_NOTIFY_BUS_CHECK: |
610 | if (!dock_in_progress(ds) && dock_present(ds)) { | 730 | case ACPI_NOTIFY_DEVICE_CHECK: |
731 | if (!dock_in_progress(ds) && acpi_bus_get_device(ds->handle, | ||
732 | &tmp)) { | ||
611 | begin_dock(ds); | 733 | begin_dock(ds); |
612 | dock(ds); | 734 | dock(ds); |
613 | if (!dock_present(ds)) { | 735 | if (!dock_present(ds)) { |
614 | printk(KERN_ERR PREFIX "Unable to dock!\n"); | 736 | printk(KERN_ERR PREFIX "Unable to dock!\n"); |
737 | complete_dock(ds); | ||
615 | break; | 738 | break; |
616 | } | 739 | } |
617 | atomic_notifier_call_chain(&dock_notifier_list, | 740 | atomic_notifier_call_chain(&dock_notifier_list, |
@@ -619,20 +742,19 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) | |||
619 | hotplug_dock_devices(ds, event); | 742 | hotplug_dock_devices(ds, event); |
620 | complete_dock(ds); | 743 | complete_dock(ds); |
621 | dock_event(ds, event, DOCK_EVENT); | 744 | dock_event(ds, event, DOCK_EVENT); |
745 | dock_lock(ds, 1); | ||
746 | break; | ||
622 | } | 747 | } |
623 | break; | 748 | if (dock_present(ds) || dock_in_progress(ds)) |
624 | case ACPI_NOTIFY_DEVICE_CHECK: | 749 | break; |
625 | /* | 750 | /* This is a surprise removal */ |
626 | * According to acpi spec 3.0a, if a DEVICE_CHECK notification | 751 | surprise_removal = 1; |
627 | * is sent and _DCK is present, it is assumed to mean an | 752 | event = ACPI_NOTIFY_EJECT_REQUEST; |
628 | * undock request. This notify routine will only be called | 753 | /* Fall back */ |
629 | * for objects defining _DCK, so we will fall through to eject | ||
630 | * request here. However, we will pass an eject request through | ||
631 | * to the driver who wish to hotplug. | ||
632 | */ | ||
633 | case ACPI_NOTIFY_EJECT_REQUEST: | 754 | case ACPI_NOTIFY_EJECT_REQUEST: |
634 | begin_undock(ds); | 755 | begin_undock(ds); |
635 | if (immediate_undock) | 756 | if ((immediate_undock && !(ds->flags & DOCK_IS_ATA)) |
757 | || surprise_removal) | ||
636 | handle_eject_request(ds, event); | 758 | handle_eject_request(ds, event); |
637 | else | 759 | else |
638 | dock_event(ds, event, UNDOCK_EVENT); | 760 | dock_event(ds, event, UNDOCK_EVENT); |
@@ -642,6 +764,51 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) | |||
642 | } | 764 | } |
643 | } | 765 | } |
644 | 766 | ||
767 | struct dock_data { | ||
768 | acpi_handle handle; | ||
769 | unsigned long event; | ||
770 | struct dock_station *ds; | ||
771 | }; | ||
772 | |||
773 | static void acpi_dock_deferred_cb(void *context) | ||
774 | { | ||
775 | struct dock_data *data = (struct dock_data *)context; | ||
776 | |||
777 | dock_notify(data->handle, data->event, data->ds); | ||
778 | kfree(data); | ||
779 | } | ||
780 | |||
781 | static int acpi_dock_notifier_call(struct notifier_block *this, | ||
782 | unsigned long event, void *data) | ||
783 | { | ||
784 | struct dock_station *dock_station; | ||
785 | acpi_handle handle = (acpi_handle)data; | ||
786 | |||
787 | if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK | ||
788 | && event != ACPI_NOTIFY_EJECT_REQUEST) | ||
789 | return 0; | ||
790 | list_for_each_entry(dock_station, &dock_stations, sibiling) { | ||
791 | if (dock_station->handle == handle) { | ||
792 | struct dock_data *dock_data; | ||
793 | |||
794 | dock_data = kmalloc(sizeof(*dock_data), GFP_KERNEL); | ||
795 | if (!dock_data) | ||
796 | return 0; | ||
797 | dock_data->handle = handle; | ||
798 | dock_data->event = event; | ||
799 | dock_data->ds = dock_station; | ||
800 | acpi_os_hotplug_execute(acpi_dock_deferred_cb, | ||
801 | dock_data); | ||
802 | return 0 ; | ||
803 | } | ||
804 | } | ||
805 | return 0; | ||
806 | } | ||
807 | |||
808 | static struct notifier_block dock_acpi_notifier = { | ||
809 | .notifier_call = acpi_dock_notifier_call, | ||
810 | }; | ||
811 | |||
645 | /** | 812 | /** |
646 | * find_dock_devices - find devices on the dock station | 813 | * find_dock_devices - find devices on the dock station |
647 | * @handle: the handle of the device we are examining | 814 | * @handle: the handle of the device we are examining |
@@ -688,6 +855,8 @@ fdd_out: | |||
688 | static ssize_t show_docked(struct device *dev, | 855 | static ssize_t show_docked(struct device *dev, |
689 | struct device_attribute *attr, char *buf) | 856 | struct device_attribute *attr, char *buf) |
690 | { | 857 | { |
858 | struct dock_station *dock_station = *((struct dock_station **) | ||
859 | dev->platform_data); | ||
691 | return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station)); | 860 | return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station)); |
692 | 861 | ||
693 | } | 862 | } |
@@ -699,6 +868,8 @@ static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); | |||
699 | static ssize_t show_flags(struct device *dev, | 868 | static ssize_t show_flags(struct device *dev, |
700 | struct device_attribute *attr, char *buf) | 869 | struct device_attribute *attr, char *buf) |
701 | { | 870 | { |
871 | struct dock_station *dock_station = *((struct dock_station **) | ||
872 | dev->platform_data); | ||
702 | return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags); | 873 | return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags); |
703 | 874 | ||
704 | } | 875 | } |
@@ -711,6 +882,8 @@ static ssize_t write_undock(struct device *dev, struct device_attribute *attr, | |||
711 | const char *buf, size_t count) | 882 | const char *buf, size_t count) |
712 | { | 883 | { |
713 | int ret; | 884 | int ret; |
885 | struct dock_station *dock_station = *((struct dock_station **) | ||
886 | dev->platform_data); | ||
714 | 887 | ||
715 | if (!count) | 888 | if (!count) |
716 | return -EINVAL; | 889 | return -EINVAL; |
@@ -727,16 +900,38 @@ static DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock); | |||
727 | static ssize_t show_dock_uid(struct device *dev, | 900 | static ssize_t show_dock_uid(struct device *dev, |
728 | struct device_attribute *attr, char *buf) | 901 | struct device_attribute *attr, char *buf) |
729 | { | 902 | { |
730 | unsigned long lbuf; | 903 | unsigned long long lbuf; |
904 | struct dock_station *dock_station = *((struct dock_station **) | ||
905 | dev->platform_data); | ||
731 | acpi_status status = acpi_evaluate_integer(dock_station->handle, | 906 | acpi_status status = acpi_evaluate_integer(dock_station->handle, |
732 | "_UID", NULL, &lbuf); | 907 | "_UID", NULL, &lbuf); |
733 | if (ACPI_FAILURE(status)) | 908 | if (ACPI_FAILURE(status)) |
734 | return 0; | 909 | return 0; |
735 | 910 | ||
736 | return snprintf(buf, PAGE_SIZE, "%lx\n", lbuf); | 911 | return snprintf(buf, PAGE_SIZE, "%llx\n", lbuf); |
737 | } | 912 | } |
738 | static DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL); | 913 | static DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL); |
739 | 914 | ||
915 | static ssize_t show_dock_type(struct device *dev, | ||
916 | struct device_attribute *attr, char *buf) | ||
917 | { | ||
918 | struct dock_station *dock_station = *((struct dock_station **) | ||
919 | dev->platform_data); | ||
920 | char *type; | ||
921 | |||
922 | if (dock_station->flags & DOCK_IS_DOCK) | ||
923 | type = "dock_station"; | ||
924 | else if (dock_station->flags & DOCK_IS_ATA) | ||
925 | type = "ata_bay"; | ||
926 | else if (dock_station->flags & DOCK_IS_BAT) | ||
927 | type = "battery_bay"; | ||
928 | else | ||
929 | type = "unknown"; | ||
930 | |||
931 | return snprintf(buf, PAGE_SIZE, "%s\n", type); | ||
932 | } | ||
933 | static DEVICE_ATTR(type, S_IRUGO, show_dock_type, NULL); | ||
934 | |||
740 | /** | 935 | /** |
741 | * dock_add - add a new dock station | 936 | * dock_add - add a new dock station |
742 | * @handle: the dock station handle | 937 | * @handle: the dock station handle |
@@ -747,8 +942,9 @@ static DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL); | |||
747 | static int dock_add(acpi_handle handle) | 942 | static int dock_add(acpi_handle handle) |
748 | { | 943 | { |
749 | int ret; | 944 | int ret; |
750 | acpi_status status; | ||
751 | struct dock_dependent_device *dd; | 945 | struct dock_dependent_device *dd; |
946 | struct dock_station *dock_station; | ||
947 | struct platform_device *dock_device; | ||
752 | 948 | ||
753 | /* allocate & initialize the dock_station private data */ | 949 | /* allocate & initialize the dock_station private data */ |
754 | dock_station = kzalloc(sizeof(*dock_station), GFP_KERNEL); | 950 | dock_station = kzalloc(sizeof(*dock_station), GFP_KERNEL); |
@@ -758,22 +954,34 @@ static int dock_add(acpi_handle handle) | |||
758 | dock_station->last_dock_time = jiffies - HZ; | 954 | dock_station->last_dock_time = jiffies - HZ; |
759 | INIT_LIST_HEAD(&dock_station->dependent_devices); | 955 | INIT_LIST_HEAD(&dock_station->dependent_devices); |
760 | INIT_LIST_HEAD(&dock_station->hotplug_devices); | 956 | INIT_LIST_HEAD(&dock_station->hotplug_devices); |
957 | INIT_LIST_HEAD(&dock_station->sibiling); | ||
761 | spin_lock_init(&dock_station->dd_lock); | 958 | spin_lock_init(&dock_station->dd_lock); |
762 | mutex_init(&dock_station->hp_lock); | 959 | mutex_init(&dock_station->hp_lock); |
763 | ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); | 960 | ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); |
764 | 961 | ||
765 | /* initialize platform device stuff */ | 962 | /* initialize platform device stuff */ |
766 | dock_device = | 963 | dock_station->dock_device = |
767 | platform_device_register_simple(dock_device_name, 0, NULL, 0); | 964 | platform_device_register_simple(dock_device_name, |
965 | dock_station_count, NULL, 0); | ||
966 | dock_device = dock_station->dock_device; | ||
768 | if (IS_ERR(dock_device)) { | 967 | if (IS_ERR(dock_device)) { |
769 | kfree(dock_station); | 968 | kfree(dock_station); |
770 | dock_station = NULL; | 969 | dock_station = NULL; |
771 | return PTR_ERR(dock_device); | 970 | return PTR_ERR(dock_device); |
772 | } | 971 | } |
972 | platform_device_add_data(dock_device, &dock_station, | ||
973 | sizeof(struct dock_station *)); | ||
773 | 974 | ||
774 | /* we want the dock device to send uevents */ | 975 | /* we want the dock device to send uevents */ |
775 | dock_device->dev.uevent_suppress = 0; | 976 | dock_device->dev.uevent_suppress = 0; |
776 | 977 | ||
978 | if (is_dock(handle)) | ||
979 | dock_station->flags |= DOCK_IS_DOCK; | ||
980 | if (is_ata(handle)) | ||
981 | dock_station->flags |= DOCK_IS_ATA; | ||
982 | if (is_battery(handle)) | ||
983 | dock_station->flags |= DOCK_IS_BAT; | ||
984 | |||
777 | ret = device_create_file(&dock_device->dev, &dev_attr_docked); | 985 | ret = device_create_file(&dock_device->dev, &dev_attr_docked); |
778 | if (ret) { | 986 | if (ret) { |
779 | printk("Error %d adding sysfs file\n", ret); | 987 | printk("Error %d adding sysfs file\n", ret); |
@@ -812,6 +1020,9 @@ static int dock_add(acpi_handle handle) | |||
812 | dock_station = NULL; | 1020 | dock_station = NULL; |
813 | return ret; | 1021 | return ret; |
814 | } | 1022 | } |
1023 | ret = device_create_file(&dock_device->dev, &dev_attr_type); | ||
1024 | if (ret) | ||
1025 | printk(KERN_ERR"Error %d adding sysfs file\n", ret); | ||
815 | 1026 | ||
816 | /* Find dependent devices */ | 1027 | /* Find dependent devices */ |
817 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | 1028 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, |
@@ -828,24 +1039,12 @@ static int dock_add(acpi_handle handle) | |||
828 | } | 1039 | } |
829 | add_dock_dependent_device(dock_station, dd); | 1040 | add_dock_dependent_device(dock_station, dd); |
830 | 1041 | ||
831 | /* register for dock events */ | 1042 | dock_station_count++; |
832 | status = acpi_install_notify_handler(dock_station->handle, | 1043 | list_add(&dock_station->sibiling, &dock_stations); |
833 | ACPI_SYSTEM_NOTIFY, | ||
834 | dock_notify, dock_station); | ||
835 | |||
836 | if (ACPI_FAILURE(status)) { | ||
837 | printk(KERN_ERR PREFIX "Error installing notify handler\n"); | ||
838 | ret = -ENODEV; | ||
839 | goto dock_add_err; | ||
840 | } | ||
841 | |||
842 | printk(KERN_INFO PREFIX "%s\n", ACPI_DOCK_DRIVER_DESCRIPTION); | ||
843 | |||
844 | return 0; | 1044 | return 0; |
845 | 1045 | ||
846 | dock_add_err: | ||
847 | kfree(dd); | ||
848 | dock_add_err_unregister: | 1046 | dock_add_err_unregister: |
1047 | device_remove_file(&dock_device->dev, &dev_attr_type); | ||
849 | device_remove_file(&dock_device->dev, &dev_attr_docked); | 1048 | device_remove_file(&dock_device->dev, &dev_attr_docked); |
850 | device_remove_file(&dock_device->dev, &dev_attr_undock); | 1049 | device_remove_file(&dock_device->dev, &dev_attr_undock); |
851 | device_remove_file(&dock_device->dev, &dev_attr_uid); | 1050 | device_remove_file(&dock_device->dev, &dev_attr_uid); |
@@ -859,12 +1058,12 @@ dock_add_err_unregister: | |||
859 | /** | 1058 | /** |
860 | * dock_remove - free up resources related to the dock station | 1059 | * dock_remove - free up resources related to the dock station |
861 | */ | 1060 | */ |
862 | static int dock_remove(void) | 1061 | static int dock_remove(struct dock_station *dock_station) |
863 | { | 1062 | { |
864 | struct dock_dependent_device *dd, *tmp; | 1063 | struct dock_dependent_device *dd, *tmp; |
865 | acpi_status status; | 1064 | struct platform_device *dock_device = dock_station->dock_device; |
866 | 1065 | ||
867 | if (!dock_station) | 1066 | if (!dock_station_count) |
868 | return 0; | 1067 | return 0; |
869 | 1068 | ||
870 | /* remove dependent devices */ | 1069 | /* remove dependent devices */ |
@@ -872,14 +1071,8 @@ static int dock_remove(void) | |||
872 | list) | 1071 | list) |
873 | kfree(dd); | 1072 | kfree(dd); |
874 | 1073 | ||
875 | /* remove dock notify handler */ | ||
876 | status = acpi_remove_notify_handler(dock_station->handle, | ||
877 | ACPI_SYSTEM_NOTIFY, | ||
878 | dock_notify); | ||
879 | if (ACPI_FAILURE(status)) | ||
880 | printk(KERN_ERR "Error removing notify handler\n"); | ||
881 | |||
882 | /* cleanup sysfs */ | 1074 | /* cleanup sysfs */ |
1075 | device_remove_file(&dock_device->dev, &dev_attr_type); | ||
883 | device_remove_file(&dock_device->dev, &dev_attr_docked); | 1076 | device_remove_file(&dock_device->dev, &dev_attr_docked); |
884 | device_remove_file(&dock_device->dev, &dev_attr_undock); | 1077 | device_remove_file(&dock_device->dev, &dev_attr_undock); |
885 | device_remove_file(&dock_device->dev, &dev_attr_uid); | 1078 | device_remove_file(&dock_device->dev, &dev_attr_uid); |
@@ -904,41 +1097,60 @@ static int dock_remove(void) | |||
904 | static acpi_status | 1097 | static acpi_status |
905 | find_dock(acpi_handle handle, u32 lvl, void *context, void **rv) | 1098 | find_dock(acpi_handle handle, u32 lvl, void *context, void **rv) |
906 | { | 1099 | { |
907 | int *count = context; | ||
908 | acpi_status status = AE_OK; | 1100 | acpi_status status = AE_OK; |
909 | 1101 | ||
910 | if (is_dock(handle)) { | 1102 | if (is_dock(handle)) { |
911 | if (dock_add(handle) >= 0) { | 1103 | if (dock_add(handle) >= 0) { |
912 | (*count)++; | ||
913 | status = AE_CTRL_TERMINATE; | 1104 | status = AE_CTRL_TERMINATE; |
914 | } | 1105 | } |
915 | } | 1106 | } |
916 | return status; | 1107 | return status; |
917 | } | 1108 | } |
918 | 1109 | ||
919 | static int __init dock_init(void) | 1110 | static acpi_status |
1111 | find_bay(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
920 | { | 1112 | { |
921 | int num = 0; | 1113 | /* If bay is a dock, it's already handled */ |
922 | 1114 | if (is_ejectable_bay(handle) && !is_dock(handle)) | |
923 | dock_station = NULL; | 1115 | dock_add(handle); |
1116 | return AE_OK; | ||
1117 | } | ||
924 | 1118 | ||
1119 | static int __init dock_init(void) | ||
1120 | { | ||
925 | if (acpi_disabled) | 1121 | if (acpi_disabled) |
926 | return 0; | 1122 | return 0; |
927 | 1123 | ||
928 | /* look for a dock station */ | 1124 | /* look for a dock station */ |
929 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | 1125 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, |
930 | ACPI_UINT32_MAX, find_dock, &num, NULL); | 1126 | ACPI_UINT32_MAX, find_dock, NULL, NULL); |
931 | 1127 | ||
932 | if (!num) | 1128 | /* look for bay */ |
933 | printk(KERN_INFO "No dock devices found.\n"); | 1129 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, |
1130 | ACPI_UINT32_MAX, find_bay, NULL, NULL); | ||
1131 | if (!dock_station_count) { | ||
1132 | printk(KERN_INFO PREFIX "No dock devices found.\n"); | ||
1133 | return 0; | ||
1134 | } | ||
934 | 1135 | ||
1136 | register_acpi_bus_notifier(&dock_acpi_notifier); | ||
1137 | printk(KERN_INFO PREFIX "%s: %d docks/bays found\n", | ||
1138 | ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count); | ||
935 | return 0; | 1139 | return 0; |
936 | } | 1140 | } |
937 | 1141 | ||
938 | static void __exit dock_exit(void) | 1142 | static void __exit dock_exit(void) |
939 | { | 1143 | { |
940 | dock_remove(); | 1144 | struct dock_station *dock_station; |
1145 | |||
1146 | unregister_acpi_bus_notifier(&dock_acpi_notifier); | ||
1147 | list_for_each_entry(dock_station, &dock_stations, sibiling) | ||
1148 | dock_remove(dock_station); | ||
941 | } | 1149 | } |
942 | 1150 | ||
943 | postcore_initcall(dock_init); | 1151 | /* |
1152 | * Must be called before drivers of devices in dock, otherwise we can't know | ||
1153 | * which devices are in a dock | ||
1154 | */ | ||
1155 | subsys_initcall(dock_init); | ||
944 | module_exit(dock_exit); | 1156 | module_exit(dock_exit); |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 13593f9f2197..ef42316f89f5 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * ec.c - ACPI Embedded Controller Driver (v2.0) | 2 | * ec.c - ACPI Embedded Controller Driver (v2.1) |
3 | * | 3 | * |
4 | * Copyright (C) 2006, 2007 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> | 4 | * Copyright (C) 2006-2008 Alexey Starikovskiy <astarikovskiy@suse.de> |
5 | * Copyright (C) 2006 Denis Sadykov <denis.m.sadykov@intel.com> | 5 | * Copyright (C) 2006 Denis Sadykov <denis.m.sadykov@intel.com> |
6 | * Copyright (C) 2004 Luming Yu <luming.yu@intel.com> | 6 | * Copyright (C) 2004 Luming Yu <luming.yu@intel.com> |
7 | * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> | 7 | * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> |
@@ -26,7 +26,7 @@ | |||
26 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 26 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
27 | */ | 27 | */ |
28 | 28 | ||
29 | /* Uncomment next line to get verbose print outs*/ | 29 | /* Uncomment next line to get verbose printout */ |
30 | /* #define DEBUG */ | 30 | /* #define DEBUG */ |
31 | 31 | ||
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/seq_file.h> | 38 | #include <linux/seq_file.h> |
39 | #include <linux/interrupt.h> | 39 | #include <linux/interrupt.h> |
40 | #include <linux/list.h> | 40 | #include <linux/list.h> |
41 | #include <linux/spinlock.h> | ||
41 | #include <asm/io.h> | 42 | #include <asm/io.h> |
42 | #include <acpi/acpi_bus.h> | 43 | #include <acpi/acpi_bus.h> |
43 | #include <acpi/acpi_drivers.h> | 44 | #include <acpi/acpi_drivers.h> |
@@ -65,22 +66,21 @@ enum ec_command { | |||
65 | ACPI_EC_COMMAND_QUERY = 0x84, | 66 | ACPI_EC_COMMAND_QUERY = 0x84, |
66 | }; | 67 | }; |
67 | 68 | ||
68 | /* EC events */ | ||
69 | enum ec_event { | ||
70 | ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ | ||
71 | ACPI_EC_EVENT_IBF_0, /* Input buffer empty */ | ||
72 | }; | ||
73 | |||
74 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ | 69 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ |
75 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ | 70 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
76 | #define ACPI_EC_UDELAY 100 /* Wait 100us before polling EC again */ | 71 | #define ACPI_EC_UDELAY 100 /* Wait 100us before polling EC again */ |
77 | 72 | ||
73 | #define ACPI_EC_STORM_THRESHOLD 20 /* number of false interrupts | ||
74 | per one transaction */ | ||
75 | |||
78 | enum { | 76 | enum { |
79 | EC_FLAGS_WAIT_GPE = 0, /* Don't check status until GPE arrives */ | ||
80 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ | 77 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ |
81 | EC_FLAGS_GPE_MODE, /* Expect GPE to be sent for status change */ | 78 | EC_FLAGS_GPE_MODE, /* Expect GPE to be sent |
79 | * for status change */ | ||
82 | EC_FLAGS_NO_GPE, /* Don't use GPE mode */ | 80 | EC_FLAGS_NO_GPE, /* Don't use GPE mode */ |
83 | EC_FLAGS_RESCHEDULE_POLL /* Re-schedule poll */ | 81 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ |
82 | EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and | ||
83 | * OpReg are installed */ | ||
84 | }; | 84 | }; |
85 | 85 | ||
86 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ | 86 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ |
@@ -95,6 +95,15 @@ struct acpi_ec_query_handler { | |||
95 | u8 query_bit; | 95 | u8 query_bit; |
96 | }; | 96 | }; |
97 | 97 | ||
98 | struct transaction { | ||
99 | const u8 *wdata; | ||
100 | u8 *rdata; | ||
101 | unsigned short irq_count; | ||
102 | u8 command; | ||
103 | u8 wlen; | ||
104 | u8 rlen; | ||
105 | }; | ||
106 | |||
98 | static struct acpi_ec { | 107 | static struct acpi_ec { |
99 | acpi_handle handle; | 108 | acpi_handle handle; |
100 | unsigned long gpe; | 109 | unsigned long gpe; |
@@ -105,9 +114,8 @@ static struct acpi_ec { | |||
105 | struct mutex lock; | 114 | struct mutex lock; |
106 | wait_queue_head_t wait; | 115 | wait_queue_head_t wait; |
107 | struct list_head list; | 116 | struct list_head list; |
108 | struct delayed_work work; | 117 | struct transaction *curr; |
109 | atomic_t irq_count; | 118 | spinlock_t curr_lock; |
110 | u8 handlers_installed; | ||
111 | } *boot_ec, *first_ec; | 119 | } *boot_ec, *first_ec; |
112 | 120 | ||
113 | /* | 121 | /* |
@@ -150,7 +158,7 @@ static inline u8 acpi_ec_read_data(struct acpi_ec *ec) | |||
150 | { | 158 | { |
151 | u8 x = inb(ec->data_addr); | 159 | u8 x = inb(ec->data_addr); |
152 | pr_debug(PREFIX "---> data = 0x%2.2x\n", x); | 160 | pr_debug(PREFIX "---> data = 0x%2.2x\n", x); |
153 | return inb(ec->data_addr); | 161 | return x; |
154 | } | 162 | } |
155 | 163 | ||
156 | static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) | 164 | static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) |
@@ -165,158 +173,172 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) | |||
165 | outb(data, ec->data_addr); | 173 | outb(data, ec->data_addr); |
166 | } | 174 | } |
167 | 175 | ||
168 | static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event) | 176 | static int ec_transaction_done(struct acpi_ec *ec) |
169 | { | 177 | { |
170 | if (test_bit(EC_FLAGS_WAIT_GPE, &ec->flags)) | 178 | unsigned long flags; |
171 | return 0; | 179 | int ret = 0; |
172 | if (event == ACPI_EC_EVENT_OBF_1) { | 180 | spin_lock_irqsave(&ec->curr_lock, flags); |
173 | if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF) | 181 | if (!ec->curr || (!ec->curr->wlen && !ec->curr->rlen)) |
174 | return 1; | 182 | ret = 1; |
175 | } else if (event == ACPI_EC_EVENT_IBF_0) { | 183 | spin_unlock_irqrestore(&ec->curr_lock, flags); |
176 | if (!(acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)) | 184 | return ret; |
177 | return 1; | ||
178 | } | ||
179 | |||
180 | return 0; | ||
181 | } | 185 | } |
182 | 186 | ||
183 | static void ec_schedule_ec_poll(struct acpi_ec *ec) | 187 | static void gpe_transaction(struct acpi_ec *ec, u8 status) |
184 | { | 188 | { |
185 | if (test_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags)) | 189 | unsigned long flags; |
186 | schedule_delayed_work(&ec->work, | 190 | spin_lock_irqsave(&ec->curr_lock, flags); |
187 | msecs_to_jiffies(ACPI_EC_DELAY)); | 191 | if (!ec->curr) |
192 | goto unlock; | ||
193 | if (ec->curr->wlen > 0) { | ||
194 | if ((status & ACPI_EC_FLAG_IBF) == 0) { | ||
195 | acpi_ec_write_data(ec, *(ec->curr->wdata++)); | ||
196 | --ec->curr->wlen; | ||
197 | } else | ||
198 | /* false interrupt, state didn't change */ | ||
199 | ++ec->curr->irq_count; | ||
200 | |||
201 | } else if (ec->curr->rlen > 0) { | ||
202 | if ((status & ACPI_EC_FLAG_OBF) == 1) { | ||
203 | *(ec->curr->rdata++) = acpi_ec_read_data(ec); | ||
204 | --ec->curr->rlen; | ||
205 | } else | ||
206 | /* false interrupt, state didn't change */ | ||
207 | ++ec->curr->irq_count; | ||
208 | } | ||
209 | unlock: | ||
210 | spin_unlock_irqrestore(&ec->curr_lock, flags); | ||
188 | } | 211 | } |
189 | 212 | ||
190 | static void ec_switch_to_poll_mode(struct acpi_ec *ec) | 213 | static int acpi_ec_wait(struct acpi_ec *ec) |
191 | { | 214 | { |
215 | if (wait_event_timeout(ec->wait, ec_transaction_done(ec), | ||
216 | msecs_to_jiffies(ACPI_EC_DELAY))) | ||
217 | return 0; | ||
218 | /* missing GPEs, switch back to poll mode */ | ||
219 | if (printk_ratelimit()) | ||
220 | pr_info(PREFIX "missing confirmations, " | ||
221 | "switch off interrupt mode.\n"); | ||
192 | set_bit(EC_FLAGS_NO_GPE, &ec->flags); | 222 | set_bit(EC_FLAGS_NO_GPE, &ec->flags); |
193 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | 223 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); |
194 | acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); | 224 | return 1; |
195 | set_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags); | ||
196 | } | 225 | } |
197 | 226 | ||
198 | static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) | 227 | static void acpi_ec_gpe_query(void *ec_cxt); |
228 | |||
229 | static int ec_check_sci(struct acpi_ec *ec, u8 state) | ||
199 | { | 230 | { |
200 | atomic_set(&ec->irq_count, 0); | 231 | if (state & ACPI_EC_FLAG_SCI) { |
201 | if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) && | 232 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) |
202 | likely(!force_poll)) { | 233 | return acpi_os_execute(OSL_EC_BURST_HANDLER, |
203 | if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event), | 234 | acpi_ec_gpe_query, ec); |
204 | msecs_to_jiffies(ACPI_EC_DELAY))) | 235 | } |
205 | return 0; | 236 | return 0; |
206 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | 237 | } |
207 | if (acpi_ec_check_status(ec, event)) { | 238 | |
208 | /* missing GPEs, switch back to poll mode */ | 239 | static int ec_poll(struct acpi_ec *ec) |
209 | if (printk_ratelimit()) | 240 | { |
210 | pr_info(PREFIX "missing confirmations, " | 241 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); |
211 | "switch off interrupt mode.\n"); | 242 | msleep(1); |
212 | ec_switch_to_poll_mode(ec); | 243 | while (time_before(jiffies, delay)) { |
213 | ec_schedule_ec_poll(ec); | 244 | gpe_transaction(ec, acpi_ec_read_status(ec)); |
214 | return 0; | 245 | msleep(1); |
215 | } | 246 | if (ec_transaction_done(ec)) |
216 | } else { | ||
217 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); | ||
218 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | ||
219 | while (time_before(jiffies, delay)) { | ||
220 | if (acpi_ec_check_status(ec, event)) | ||
221 | return 0; | ||
222 | msleep(1); | ||
223 | } | ||
224 | if (acpi_ec_check_status(ec,event)) | ||
225 | return 0; | 247 | return 0; |
226 | } | 248 | } |
227 | pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n", | ||
228 | acpi_ec_read_status(ec), | ||
229 | (event == ACPI_EC_EVENT_OBF_1) ? "\"b0=1\"" : "\"b1=0\""); | ||
230 | return -ETIME; | 249 | return -ETIME; |
231 | } | 250 | } |
232 | 251 | ||
233 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, | 252 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, |
234 | const u8 * wdata, unsigned wdata_len, | 253 | struct transaction *t, |
235 | u8 * rdata, unsigned rdata_len, | ||
236 | int force_poll) | 254 | int force_poll) |
237 | { | 255 | { |
238 | int result = 0; | 256 | unsigned long tmp; |
239 | set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | 257 | int ret = 0; |
240 | pr_debug(PREFIX "transaction start\n"); | 258 | pr_debug(PREFIX "transaction start\n"); |
241 | acpi_ec_write_cmd(ec, command); | 259 | /* disable GPE during transaction if storm is detected */ |
242 | for (; wdata_len > 0; --wdata_len) { | 260 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
243 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll); | 261 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); |
244 | if (result) { | 262 | acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); |
245 | pr_err(PREFIX | ||
246 | "write_cmd timeout, command = %d\n", command); | ||
247 | goto end; | ||
248 | } | ||
249 | set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | ||
250 | acpi_ec_write_data(ec, *(wdata++)); | ||
251 | } | 263 | } |
252 | 264 | /* start transaction */ | |
253 | if (!rdata_len) { | 265 | spin_lock_irqsave(&ec->curr_lock, tmp); |
254 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll); | 266 | /* following two actions should be kept atomic */ |
255 | if (result) { | 267 | t->irq_count = 0; |
256 | pr_err(PREFIX | 268 | ec->curr = t; |
257 | "finish-write timeout, command = %d\n", command); | 269 | acpi_ec_write_cmd(ec, ec->curr->command); |
258 | goto end; | 270 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) |
259 | } | ||
260 | } else if (command == ACPI_EC_COMMAND_QUERY) | ||
261 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 271 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
262 | 272 | spin_unlock_irqrestore(&ec->curr_lock, tmp); | |
263 | for (; rdata_len > 0; --rdata_len) { | 273 | /* if we selected poll mode or failed in GPE-mode do a poll loop */ |
264 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, force_poll); | 274 | if (force_poll || |
265 | if (result) { | 275 | !test_bit(EC_FLAGS_GPE_MODE, &ec->flags) || |
266 | pr_err(PREFIX "read timeout, command = %d\n", command); | 276 | acpi_ec_wait(ec)) |
267 | goto end; | 277 | ret = ec_poll(ec); |
268 | } | ||
269 | /* Don't expect GPE after last read */ | ||
270 | if (rdata_len > 1) | ||
271 | set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | ||
272 | *(rdata++) = acpi_ec_read_data(ec); | ||
273 | } | ||
274 | end: | ||
275 | pr_debug(PREFIX "transaction end\n"); | 278 | pr_debug(PREFIX "transaction end\n"); |
276 | return result; | 279 | spin_lock_irqsave(&ec->curr_lock, tmp); |
280 | ec->curr = NULL; | ||
281 | spin_unlock_irqrestore(&ec->curr_lock, tmp); | ||
282 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | ||
283 | /* check if we received SCI during transaction */ | ||
284 | ec_check_sci(ec, acpi_ec_read_status(ec)); | ||
285 | /* it is safe to enable GPE outside of transaction */ | ||
286 | acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); | ||
287 | } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && | ||
288 | t->irq_count > ACPI_EC_STORM_THRESHOLD) { | ||
289 | pr_debug(PREFIX "GPE storm detected\n"); | ||
290 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); | ||
291 | } | ||
292 | return ret; | ||
293 | } | ||
294 | |||
295 | static int ec_check_ibf0(struct acpi_ec *ec) | ||
296 | { | ||
297 | u8 status = acpi_ec_read_status(ec); | ||
298 | return (status & ACPI_EC_FLAG_IBF) == 0; | ||
277 | } | 299 | } |
278 | 300 | ||
279 | static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, | 301 | static int ec_wait_ibf0(struct acpi_ec *ec) |
280 | const u8 * wdata, unsigned wdata_len, | 302 | { |
281 | u8 * rdata, unsigned rdata_len, | 303 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); |
304 | /* interrupt wait manually if GPE mode is not active */ | ||
305 | unsigned long timeout = test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ? | ||
306 | msecs_to_jiffies(ACPI_EC_DELAY) : msecs_to_jiffies(1); | ||
307 | while (time_before(jiffies, delay)) | ||
308 | if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), timeout)) | ||
309 | return 0; | ||
310 | return -ETIME; | ||
311 | } | ||
312 | |||
313 | static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t, | ||
282 | int force_poll) | 314 | int force_poll) |
283 | { | 315 | { |
284 | int status; | 316 | int status; |
285 | u32 glk; | 317 | u32 glk; |
286 | 318 | if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata)) | |
287 | if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata)) | ||
288 | return -EINVAL; | 319 | return -EINVAL; |
289 | 320 | if (t->rdata) | |
290 | if (rdata) | 321 | memset(t->rdata, 0, t->rlen); |
291 | memset(rdata, 0, rdata_len); | ||
292 | |||
293 | mutex_lock(&ec->lock); | 322 | mutex_lock(&ec->lock); |
294 | if (ec->global_lock) { | 323 | if (ec->global_lock) { |
295 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | 324 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); |
296 | if (ACPI_FAILURE(status)) { | 325 | if (ACPI_FAILURE(status)) { |
297 | mutex_unlock(&ec->lock); | 326 | status = -ENODEV; |
298 | return -ENODEV; | 327 | goto unlock; |
299 | } | 328 | } |
300 | } | 329 | } |
301 | 330 | if (ec_wait_ibf0(ec)) { | |
302 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0); | ||
303 | if (status) { | ||
304 | pr_err(PREFIX "input buffer is not empty, " | 331 | pr_err(PREFIX "input buffer is not empty, " |
305 | "aborting transaction\n"); | 332 | "aborting transaction\n"); |
333 | status = -ETIME; | ||
306 | goto end; | 334 | goto end; |
307 | } | 335 | } |
308 | 336 | status = acpi_ec_transaction_unlocked(ec, t, force_poll); | |
309 | status = acpi_ec_transaction_unlocked(ec, command, | 337 | end: |
310 | wdata, wdata_len, | ||
311 | rdata, rdata_len, | ||
312 | force_poll); | ||
313 | |||
314 | end: | ||
315 | |||
316 | if (ec->global_lock) | 338 | if (ec->global_lock) |
317 | acpi_release_global_lock(glk); | 339 | acpi_release_global_lock(glk); |
340 | unlock: | ||
318 | mutex_unlock(&ec->lock); | 341 | mutex_unlock(&ec->lock); |
319 | |||
320 | return status; | 342 | return status; |
321 | } | 343 | } |
322 | 344 | ||
@@ -327,21 +349,32 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, | |||
327 | int acpi_ec_burst_enable(struct acpi_ec *ec) | 349 | int acpi_ec_burst_enable(struct acpi_ec *ec) |
328 | { | 350 | { |
329 | u8 d; | 351 | u8 d; |
330 | return acpi_ec_transaction(ec, ACPI_EC_BURST_ENABLE, NULL, 0, &d, 1, 0); | 352 | struct transaction t = {.command = ACPI_EC_BURST_ENABLE, |
353 | .wdata = NULL, .rdata = &d, | ||
354 | .wlen = 0, .rlen = 1}; | ||
355 | |||
356 | return acpi_ec_transaction(ec, &t, 0); | ||
331 | } | 357 | } |
332 | 358 | ||
333 | int acpi_ec_burst_disable(struct acpi_ec *ec) | 359 | int acpi_ec_burst_disable(struct acpi_ec *ec) |
334 | { | 360 | { |
335 | return acpi_ec_transaction(ec, ACPI_EC_BURST_DISABLE, NULL, 0, NULL, 0, 0); | 361 | struct transaction t = {.command = ACPI_EC_BURST_DISABLE, |
362 | .wdata = NULL, .rdata = NULL, | ||
363 | .wlen = 0, .rlen = 0}; | ||
364 | |||
365 | return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? | ||
366 | acpi_ec_transaction(ec, &t, 0) : 0; | ||
336 | } | 367 | } |
337 | 368 | ||
338 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) | 369 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) |
339 | { | 370 | { |
340 | int result; | 371 | int result; |
341 | u8 d; | 372 | u8 d; |
373 | struct transaction t = {.command = ACPI_EC_COMMAND_READ, | ||
374 | .wdata = &address, .rdata = &d, | ||
375 | .wlen = 1, .rlen = 1}; | ||
342 | 376 | ||
343 | result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_READ, | 377 | result = acpi_ec_transaction(ec, &t, 0); |
344 | &address, 1, &d, 1, 0); | ||
345 | *data = d; | 378 | *data = d; |
346 | return result; | 379 | return result; |
347 | } | 380 | } |
@@ -349,8 +382,11 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) | |||
349 | static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) | 382 | static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) |
350 | { | 383 | { |
351 | u8 wdata[2] = { address, data }; | 384 | u8 wdata[2] = { address, data }; |
352 | return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE, | 385 | struct transaction t = {.command = ACPI_EC_COMMAND_WRITE, |
353 | wdata, 2, NULL, 0, 0); | 386 | .wdata = wdata, .rdata = NULL, |
387 | .wlen = 2, .rlen = 0}; | ||
388 | |||
389 | return acpi_ec_transaction(ec, &t, 0); | ||
354 | } | 390 | } |
355 | 391 | ||
356 | /* | 392 | /* |
@@ -412,12 +448,13 @@ int ec_transaction(u8 command, | |||
412 | u8 * rdata, unsigned rdata_len, | 448 | u8 * rdata, unsigned rdata_len, |
413 | int force_poll) | 449 | int force_poll) |
414 | { | 450 | { |
451 | struct transaction t = {.command = command, | ||
452 | .wdata = wdata, .rdata = rdata, | ||
453 | .wlen = wdata_len, .rlen = rdata_len}; | ||
415 | if (!first_ec) | 454 | if (!first_ec) |
416 | return -ENODEV; | 455 | return -ENODEV; |
417 | 456 | ||
418 | return acpi_ec_transaction(first_ec, command, wdata, | 457 | return acpi_ec_transaction(first_ec, &t, force_poll); |
419 | wdata_len, rdata, rdata_len, | ||
420 | force_poll); | ||
421 | } | 458 | } |
422 | 459 | ||
423 | EXPORT_SYMBOL(ec_transaction); | 460 | EXPORT_SYMBOL(ec_transaction); |
@@ -426,7 +463,9 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data) | |||
426 | { | 463 | { |
427 | int result; | 464 | int result; |
428 | u8 d; | 465 | u8 d; |
429 | 466 | struct transaction t = {.command = ACPI_EC_COMMAND_QUERY, | |
467 | .wdata = NULL, .rdata = &d, | ||
468 | .wlen = 0, .rlen = 1}; | ||
430 | if (!ec || !data) | 469 | if (!ec || !data) |
431 | return -EINVAL; | 470 | return -EINVAL; |
432 | 471 | ||
@@ -436,7 +475,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data) | |||
436 | * bit to be cleared (and thus clearing the interrupt source). | 475 | * bit to be cleared (and thus clearing the interrupt source). |
437 | */ | 476 | */ |
438 | 477 | ||
439 | result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1, 0); | 478 | result = acpi_ec_transaction(ec, &t, 0); |
440 | if (result) | 479 | if (result) |
441 | return result; | 480 | return result; |
442 | 481 | ||
@@ -513,46 +552,26 @@ static void acpi_ec_gpe_query(void *ec_cxt) | |||
513 | 552 | ||
514 | static u32 acpi_ec_gpe_handler(void *data) | 553 | static u32 acpi_ec_gpe_handler(void *data) |
515 | { | 554 | { |
516 | acpi_status status = AE_OK; | ||
517 | struct acpi_ec *ec = data; | 555 | struct acpi_ec *ec = data; |
518 | u8 state = acpi_ec_read_status(ec); | 556 | u8 status; |
519 | 557 | ||
520 | pr_debug(PREFIX "~~~> interrupt\n"); | 558 | pr_debug(PREFIX "~~~> interrupt\n"); |
521 | atomic_inc(&ec->irq_count); | 559 | status = acpi_ec_read_status(ec); |
522 | if (atomic_read(&ec->irq_count) > 5) { | 560 | |
523 | pr_err(PREFIX "GPE storm detected, disabling EC GPE\n"); | 561 | gpe_transaction(ec, status); |
524 | ec_switch_to_poll_mode(ec); | 562 | if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0) |
525 | goto end; | ||
526 | } | ||
527 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | ||
528 | if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) | ||
529 | wake_up(&ec->wait); | 563 | wake_up(&ec->wait); |
530 | 564 | ||
531 | if (state & ACPI_EC_FLAG_SCI) { | 565 | ec_check_sci(ec, status); |
532 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) | 566 | if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && |
533 | status = acpi_os_execute(OSL_EC_BURST_HANDLER, | 567 | !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) { |
534 | acpi_ec_gpe_query, ec); | ||
535 | } else if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && | ||
536 | !test_bit(EC_FLAGS_NO_GPE, &ec->flags) && | ||
537 | in_interrupt()) { | ||
538 | /* this is non-query, must be confirmation */ | 568 | /* this is non-query, must be confirmation */ |
539 | if (printk_ratelimit()) | 569 | if (printk_ratelimit()) |
540 | pr_info(PREFIX "non-query interrupt received," | 570 | pr_info(PREFIX "non-query interrupt received," |
541 | " switching to interrupt mode\n"); | 571 | " switching to interrupt mode\n"); |
542 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); | 572 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); |
543 | clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags); | ||
544 | } | 573 | } |
545 | end: | 574 | return ACPI_INTERRUPT_HANDLED; |
546 | ec_schedule_ec_poll(ec); | ||
547 | return ACPI_SUCCESS(status) ? | ||
548 | ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; | ||
549 | } | ||
550 | |||
551 | static void do_ec_poll(struct work_struct *work) | ||
552 | { | ||
553 | struct acpi_ec *ec = container_of(work, struct acpi_ec, work.work); | ||
554 | atomic_set(&ec->irq_count, 0); | ||
555 | (void)acpi_ec_gpe_handler(ec); | ||
556 | } | 575 | } |
557 | 576 | ||
558 | /* -------------------------------------------------------------------------- | 577 | /* -------------------------------------------------------------------------- |
@@ -696,8 +715,7 @@ static struct acpi_ec *make_acpi_ec(void) | |||
696 | mutex_init(&ec->lock); | 715 | mutex_init(&ec->lock); |
697 | init_waitqueue_head(&ec->wait); | 716 | init_waitqueue_head(&ec->wait); |
698 | INIT_LIST_HEAD(&ec->list); | 717 | INIT_LIST_HEAD(&ec->list); |
699 | INIT_DELAYED_WORK_DEFERRABLE(&ec->work, do_ec_poll); | 718 | spin_lock_init(&ec->curr_lock); |
700 | atomic_set(&ec->irq_count, 0); | ||
701 | return ec; | 719 | return ec; |
702 | } | 720 | } |
703 | 721 | ||
@@ -718,6 +736,7 @@ static acpi_status | |||
718 | ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) | 736 | ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) |
719 | { | 737 | { |
720 | acpi_status status; | 738 | acpi_status status; |
739 | unsigned long long tmp; | ||
721 | 740 | ||
722 | struct acpi_ec *ec = context; | 741 | struct acpi_ec *ec = context; |
723 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, | 742 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, |
@@ -727,31 +746,26 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) | |||
727 | 746 | ||
728 | /* Get GPE bit assignment (EC events). */ | 747 | /* Get GPE bit assignment (EC events). */ |
729 | /* TODO: Add support for _GPE returning a package */ | 748 | /* TODO: Add support for _GPE returning a package */ |
730 | status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe); | 749 | status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp); |
731 | if (ACPI_FAILURE(status)) | 750 | if (ACPI_FAILURE(status)) |
732 | return status; | 751 | return status; |
752 | ec->gpe = tmp; | ||
733 | /* Use the global lock for all EC transactions? */ | 753 | /* Use the global lock for all EC transactions? */ |
734 | acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock); | 754 | acpi_evaluate_integer(handle, "_GLK", NULL, &tmp); |
755 | ec->global_lock = tmp; | ||
735 | ec->handle = handle; | 756 | ec->handle = handle; |
736 | return AE_CTRL_TERMINATE; | 757 | return AE_CTRL_TERMINATE; |
737 | } | 758 | } |
738 | 759 | ||
739 | static void ec_poll_stop(struct acpi_ec *ec) | ||
740 | { | ||
741 | clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags); | ||
742 | cancel_delayed_work(&ec->work); | ||
743 | } | ||
744 | |||
745 | static void ec_remove_handlers(struct acpi_ec *ec) | 760 | static void ec_remove_handlers(struct acpi_ec *ec) |
746 | { | 761 | { |
747 | ec_poll_stop(ec); | ||
748 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, | 762 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, |
749 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) | 763 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) |
750 | pr_err(PREFIX "failed to remove space handler\n"); | 764 | pr_err(PREFIX "failed to remove space handler\n"); |
751 | if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, | 765 | if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, |
752 | &acpi_ec_gpe_handler))) | 766 | &acpi_ec_gpe_handler))) |
753 | pr_err(PREFIX "failed to remove gpe handler\n"); | 767 | pr_err(PREFIX "failed to remove gpe handler\n"); |
754 | ec->handlers_installed = 0; | 768 | clear_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); |
755 | } | 769 | } |
756 | 770 | ||
757 | static int acpi_ec_add(struct acpi_device *device) | 771 | static int acpi_ec_add(struct acpi_device *device) |
@@ -788,7 +802,7 @@ static int acpi_ec_add(struct acpi_device *device) | |||
788 | 802 | ||
789 | if (!first_ec) | 803 | if (!first_ec) |
790 | first_ec = ec; | 804 | first_ec = ec; |
791 | acpi_driver_data(device) = ec; | 805 | device->driver_data = ec; |
792 | acpi_ec_add_fs(device); | 806 | acpi_ec_add_fs(device); |
793 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", | 807 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", |
794 | ec->gpe, ec->command_addr, ec->data_addr); | 808 | ec->gpe, ec->command_addr, ec->data_addr); |
@@ -813,7 +827,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type) | |||
813 | } | 827 | } |
814 | mutex_unlock(&ec->lock); | 828 | mutex_unlock(&ec->lock); |
815 | acpi_ec_remove_fs(device); | 829 | acpi_ec_remove_fs(device); |
816 | acpi_driver_data(device) = NULL; | 830 | device->driver_data = NULL; |
817 | if (ec == first_ec) | 831 | if (ec == first_ec) |
818 | first_ec = NULL; | 832 | first_ec = NULL; |
819 | kfree(ec); | 833 | kfree(ec); |
@@ -846,27 +860,36 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context) | |||
846 | static int ec_install_handlers(struct acpi_ec *ec) | 860 | static int ec_install_handlers(struct acpi_ec *ec) |
847 | { | 861 | { |
848 | acpi_status status; | 862 | acpi_status status; |
849 | if (ec->handlers_installed) | 863 | if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) |
850 | return 0; | 864 | return 0; |
851 | status = acpi_install_gpe_handler(NULL, ec->gpe, | 865 | status = acpi_install_gpe_handler(NULL, ec->gpe, |
852 | ACPI_GPE_EDGE_TRIGGERED, | 866 | ACPI_GPE_EDGE_TRIGGERED, |
853 | &acpi_ec_gpe_handler, ec); | 867 | &acpi_ec_gpe_handler, ec); |
854 | if (ACPI_FAILURE(status)) | 868 | if (ACPI_FAILURE(status)) |
855 | return -ENODEV; | 869 | return -ENODEV; |
856 | |||
857 | acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); | 870 | acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); |
858 | acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); | 871 | acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); |
859 | |||
860 | status = acpi_install_address_space_handler(ec->handle, | 872 | status = acpi_install_address_space_handler(ec->handle, |
861 | ACPI_ADR_SPACE_EC, | 873 | ACPI_ADR_SPACE_EC, |
862 | &acpi_ec_space_handler, | 874 | &acpi_ec_space_handler, |
863 | NULL, ec); | 875 | NULL, ec); |
864 | if (ACPI_FAILURE(status)) { | 876 | if (ACPI_FAILURE(status)) { |
865 | acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); | 877 | if (status == AE_NOT_FOUND) { |
866 | return -ENODEV; | 878 | /* |
879 | * Maybe OS fails in evaluating the _REG object. | ||
880 | * The AE_NOT_FOUND error will be ignored and OS | ||
881 | * continue to initialize EC. | ||
882 | */ | ||
883 | printk(KERN_ERR "Fail in evaluating the _REG object" | ||
884 | " of EC device. Broken bios is suspected.\n"); | ||
885 | } else { | ||
886 | acpi_remove_gpe_handler(NULL, ec->gpe, | ||
887 | &acpi_ec_gpe_handler); | ||
888 | return -ENODEV; | ||
889 | } | ||
867 | } | 890 | } |
868 | 891 | ||
869 | ec->handlers_installed = 1; | 892 | set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); |
870 | return 0; | 893 | return 0; |
871 | } | 894 | } |
872 | 895 | ||
@@ -887,7 +910,6 @@ static int acpi_ec_start(struct acpi_device *device) | |||
887 | 910 | ||
888 | /* EC is fully operational, allow queries */ | 911 | /* EC is fully operational, allow queries */ |
889 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 912 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
890 | ec_schedule_ec_poll(ec); | ||
891 | return ret; | 913 | return ret; |
892 | } | 914 | } |
893 | 915 | ||
@@ -906,7 +928,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type) | |||
906 | 928 | ||
907 | int __init acpi_boot_ec_enable(void) | 929 | int __init acpi_boot_ec_enable(void) |
908 | { | 930 | { |
909 | if (!boot_ec || boot_ec->handlers_installed) | 931 | if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags)) |
910 | return 0; | 932 | return 0; |
911 | if (!ec_install_handlers(boot_ec)) { | 933 | if (!ec_install_handlers(boot_ec)) { |
912 | first_ec = boot_ec; | 934 | first_ec = boot_ec; |
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index 8892b9824fae..74da6fa52ef1 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c | |||
@@ -43,7 +43,6 @@ | |||
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acinterp.h> | 45 | #include <acpi/acinterp.h> |
46 | #include <acpi/amlcode.h> | ||
47 | #include <acpi/acnamesp.h> | 46 | #include <acpi/acnamesp.h> |
48 | #include <acpi/actables.h> | 47 | #include <acpi/actables.h> |
49 | #include <acpi/acdispat.h> | 48 | #include <acpi/acdispat.h> |
@@ -91,13 +90,12 @@ acpi_ex_add_table(u32 table_index, | |||
91 | 90 | ||
92 | /* Init the table handle */ | 91 | /* Init the table handle */ |
93 | 92 | ||
94 | obj_desc->reference.opcode = AML_LOAD_OP; | 93 | obj_desc->reference.class = ACPI_REFCLASS_TABLE; |
95 | *ddb_handle = obj_desc; | 94 | *ddb_handle = obj_desc; |
96 | 95 | ||
97 | /* Install the new table into the local data structures */ | 96 | /* Install the new table into the local data structures */ |
98 | 97 | ||
99 | obj_desc->reference.object = ACPI_CAST_PTR(void, | 98 | obj_desc->reference.value = table_index; |
100 | (unsigned long)table_index); | ||
101 | 99 | ||
102 | /* Add the table to the namespace */ | 100 | /* Add the table to the namespace */ |
103 | 101 | ||
@@ -280,6 +278,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
280 | struct acpi_walk_state *walk_state) | 278 | struct acpi_walk_state *walk_state) |
281 | { | 279 | { |
282 | union acpi_operand_object *ddb_handle; | 280 | union acpi_operand_object *ddb_handle; |
281 | struct acpi_table_header *table; | ||
283 | struct acpi_table_desc table_desc; | 282 | struct acpi_table_desc table_desc; |
284 | u32 table_index; | 283 | u32 table_index; |
285 | acpi_status status; | 284 | acpi_status status; |
@@ -294,9 +293,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
294 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 293 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { |
295 | case ACPI_TYPE_REGION: | 294 | case ACPI_TYPE_REGION: |
296 | 295 | ||
297 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n", | 296 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
298 | obj_desc, | 297 | "Load table from Region %p\n", obj_desc)); |
299 | acpi_ut_get_object_type_name(obj_desc))); | ||
300 | 298 | ||
301 | /* Region must be system_memory (from ACPI spec) */ | 299 | /* Region must be system_memory (from ACPI spec) */ |
302 | 300 | ||
@@ -316,61 +314,112 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
316 | } | 314 | } |
317 | 315 | ||
318 | /* | 316 | /* |
319 | * We will simply map the memory region for the table. However, the | 317 | * Map the table header and get the actual table length. The region |
320 | * memory region is technically not guaranteed to remain stable and | 318 | * length is not guaranteed to be the same as the table length. |
321 | * we may eventually have to copy the table to a local buffer. | 319 | */ |
320 | table = acpi_os_map_memory(obj_desc->region.address, | ||
321 | sizeof(struct acpi_table_header)); | ||
322 | if (!table) { | ||
323 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
324 | } | ||
325 | |||
326 | length = table->length; | ||
327 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | ||
328 | |||
329 | /* Must have at least an ACPI table header */ | ||
330 | |||
331 | if (length < sizeof(struct acpi_table_header)) { | ||
332 | return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); | ||
333 | } | ||
334 | |||
335 | /* | ||
336 | * The memory region is not guaranteed to remain stable and we must | ||
337 | * copy the table to a local buffer. For example, the memory region | ||
338 | * is corrupted after suspend on some machines. Dynamically loaded | ||
339 | * tables are usually small, so this overhead is minimal. | ||
322 | */ | 340 | */ |
341 | |||
342 | /* Allocate a buffer for the table */ | ||
343 | |||
344 | table_desc.pointer = ACPI_ALLOCATE(length); | ||
345 | if (!table_desc.pointer) { | ||
346 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
347 | } | ||
348 | |||
349 | /* Map the entire table and copy it */ | ||
350 | |||
351 | table = acpi_os_map_memory(obj_desc->region.address, length); | ||
352 | if (!table) { | ||
353 | ACPI_FREE(table_desc.pointer); | ||
354 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
355 | } | ||
356 | |||
357 | ACPI_MEMCPY(table_desc.pointer, table, length); | ||
358 | acpi_os_unmap_memory(table, length); | ||
359 | |||
323 | table_desc.address = obj_desc->region.address; | 360 | table_desc.address = obj_desc->region.address; |
324 | table_desc.length = obj_desc->region.length; | ||
325 | table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED; | ||
326 | break; | 361 | break; |
327 | 362 | ||
328 | case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ | 363 | case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ |
329 | 364 | ||
330 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 365 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
331 | "Load from Buffer or Field %p %s\n", obj_desc, | 366 | "Load table from Buffer or Field %p\n", |
332 | acpi_ut_get_object_type_name(obj_desc))); | 367 | obj_desc)); |
333 | |||
334 | length = obj_desc->buffer.length; | ||
335 | 368 | ||
336 | /* Must have at least an ACPI table header */ | 369 | /* Must have at least an ACPI table header */ |
337 | 370 | ||
338 | if (length < sizeof(struct acpi_table_header)) { | 371 | if (obj_desc->buffer.length < sizeof(struct acpi_table_header)) { |
339 | return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); | 372 | return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); |
340 | } | 373 | } |
341 | 374 | ||
342 | /* Validate checksum here. It won't get validated in tb_add_table */ | 375 | /* Get the actual table length from the table header */ |
343 | 376 | ||
344 | status = | 377 | table = |
345 | acpi_tb_verify_checksum(ACPI_CAST_PTR | 378 | ACPI_CAST_PTR(struct acpi_table_header, |
346 | (struct acpi_table_header, | 379 | obj_desc->buffer.pointer); |
347 | obj_desc->buffer.pointer), length); | 380 | length = table->length; |
348 | if (ACPI_FAILURE(status)) { | 381 | |
349 | return_ACPI_STATUS(status); | 382 | /* Table cannot extend beyond the buffer */ |
383 | |||
384 | if (length > obj_desc->buffer.length) { | ||
385 | return_ACPI_STATUS(AE_AML_BUFFER_LIMIT); | ||
386 | } | ||
387 | if (length < sizeof(struct acpi_table_header)) { | ||
388 | return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); | ||
350 | } | 389 | } |
351 | 390 | ||
352 | /* | 391 | /* |
353 | * We need to copy the buffer since the original buffer could be | 392 | * Copy the table from the buffer because the buffer could be modified |
354 | * changed or deleted in the future | 393 | * or even deleted in the future |
355 | */ | 394 | */ |
356 | table_desc.pointer = ACPI_ALLOCATE(length); | 395 | table_desc.pointer = ACPI_ALLOCATE(length); |
357 | if (!table_desc.pointer) { | 396 | if (!table_desc.pointer) { |
358 | return_ACPI_STATUS(AE_NO_MEMORY); | 397 | return_ACPI_STATUS(AE_NO_MEMORY); |
359 | } | 398 | } |
360 | 399 | ||
361 | ACPI_MEMCPY(table_desc.pointer, obj_desc->buffer.pointer, | 400 | ACPI_MEMCPY(table_desc.pointer, table, length); |
362 | length); | 401 | table_desc.address = ACPI_TO_INTEGER(table_desc.pointer); |
363 | table_desc.length = length; | ||
364 | table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED; | ||
365 | break; | 402 | break; |
366 | 403 | ||
367 | default: | 404 | default: |
368 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 405 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
369 | } | 406 | } |
370 | 407 | ||
371 | /* | 408 | /* Validate table checksum (will not get validated in tb_add_table) */ |
372 | * Install the new table into the local data structures | 409 | |
373 | */ | 410 | status = acpi_tb_verify_checksum(table_desc.pointer, length); |
411 | if (ACPI_FAILURE(status)) { | ||
412 | ACPI_FREE(table_desc.pointer); | ||
413 | return_ACPI_STATUS(status); | ||
414 | } | ||
415 | |||
416 | /* Complete the table descriptor */ | ||
417 | |||
418 | table_desc.length = length; | ||
419 | table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED; | ||
420 | |||
421 | /* Install the new table into the local data structures */ | ||
422 | |||
374 | status = acpi_tb_add_table(&table_desc, &table_index); | 423 | status = acpi_tb_add_table(&table_desc, &table_index); |
375 | if (ACPI_FAILURE(status)) { | 424 | if (ACPI_FAILURE(status)) { |
376 | goto cleanup; | 425 | goto cleanup; |
@@ -379,7 +428,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
379 | /* | 428 | /* |
380 | * Add the table to the namespace. | 429 | * Add the table to the namespace. |
381 | * | 430 | * |
382 | * Note: We load the table objects relative to the root of the namespace. | 431 | * Note: Load the table objects relative to the root of the namespace. |
383 | * This appears to go against the ACPI specification, but we do it for | 432 | * This appears to go against the ACPI specification, but we do it for |
384 | * compatibility with other ACPI implementations. | 433 | * compatibility with other ACPI implementations. |
385 | */ | 434 | */ |
@@ -415,7 +464,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
415 | cleanup: | 464 | cleanup: |
416 | if (ACPI_FAILURE(status)) { | 465 | if (ACPI_FAILURE(status)) { |
417 | 466 | ||
418 | /* Delete allocated buffer or mapping */ | 467 | /* Delete allocated table buffer */ |
419 | 468 | ||
420 | acpi_tb_delete_table(&table_desc); | 469 | acpi_tb_delete_table(&table_desc); |
421 | } | 470 | } |
@@ -455,9 +504,9 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
455 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 504 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
456 | } | 505 | } |
457 | 506 | ||
458 | /* Get the table index from the ddb_handle (acpi_size for 64-bit case) */ | 507 | /* Get the table index from the ddb_handle */ |
459 | 508 | ||
460 | table_index = (u32) (acpi_size) table_desc->reference.object; | 509 | table_index = table_desc->reference.value; |
461 | 510 | ||
462 | /* Invoke table handler if present */ | 511 | /* Invoke table handler if present */ |
463 | 512 | ||
diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c index 261d97516d9b..1d1f35adddde 100644 --- a/drivers/acpi/executer/exconvrt.c +++ b/drivers/acpi/executer/exconvrt.c | |||
@@ -57,7 +57,7 @@ acpi_ex_convert_to_ascii(acpi_integer integer, | |||
57 | * | 57 | * |
58 | * FUNCTION: acpi_ex_convert_to_integer | 58 | * FUNCTION: acpi_ex_convert_to_integer |
59 | * | 59 | * |
60 | * PARAMETERS: obj_desc - Object to be converted. Must be an | 60 | * PARAMETERS: obj_desc - Object to be converted. Must be an |
61 | * Integer, Buffer, or String | 61 | * Integer, Buffer, or String |
62 | * result_desc - Where the new Integer object is returned | 62 | * result_desc - Where the new Integer object is returned |
63 | * Flags - Used for string conversion | 63 | * Flags - Used for string conversion |
@@ -103,7 +103,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, | |||
103 | } | 103 | } |
104 | 104 | ||
105 | /* | 105 | /* |
106 | * Convert the buffer/string to an integer. Note that both buffers and | 106 | * Convert the buffer/string to an integer. Note that both buffers and |
107 | * strings are treated as raw data - we don't convert ascii to hex for | 107 | * strings are treated as raw data - we don't convert ascii to hex for |
108 | * strings. | 108 | * strings. |
109 | * | 109 | * |
@@ -120,7 +120,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, | |||
120 | 120 | ||
121 | /* | 121 | /* |
122 | * Convert string to an integer - for most cases, the string must be | 122 | * Convert string to an integer - for most cases, the string must be |
123 | * hexadecimal as per the ACPI specification. The only exception (as | 123 | * hexadecimal as per the ACPI specification. The only exception (as |
124 | * of ACPI 3.0) is that the to_integer() operator allows both decimal | 124 | * of ACPI 3.0) is that the to_integer() operator allows both decimal |
125 | * and hexadecimal strings (hex prefixed with "0x"). | 125 | * and hexadecimal strings (hex prefixed with "0x"). |
126 | */ | 126 | */ |
@@ -159,6 +159,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, | |||
159 | break; | 159 | break; |
160 | 160 | ||
161 | default: | 161 | default: |
162 | |||
162 | /* No other types can get here */ | 163 | /* No other types can get here */ |
163 | break; | 164 | break; |
164 | } | 165 | } |
@@ -185,7 +186,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, | |||
185 | * | 186 | * |
186 | * FUNCTION: acpi_ex_convert_to_buffer | 187 | * FUNCTION: acpi_ex_convert_to_buffer |
187 | * | 188 | * |
188 | * PARAMETERS: obj_desc - Object to be converted. Must be an | 189 | * PARAMETERS: obj_desc - Object to be converted. Must be an |
189 | * Integer, Buffer, or String | 190 | * Integer, Buffer, or String |
190 | * result_desc - Where the new buffer object is returned | 191 | * result_desc - Where the new buffer object is returned |
191 | * | 192 | * |
@@ -365,7 +366,7 @@ acpi_ex_convert_to_ascii(acpi_integer integer, | |||
365 | } | 366 | } |
366 | 367 | ||
367 | /* | 368 | /* |
368 | * Since leading zeros are supressed, we must check for the case where | 369 | * Since leading zeros are suppressed, we must check for the case where |
369 | * the integer equals 0 | 370 | * the integer equals 0 |
370 | * | 371 | * |
371 | * Finally, null terminate the string and return the length | 372 | * Finally, null terminate the string and return the length |
@@ -383,7 +384,7 @@ acpi_ex_convert_to_ascii(acpi_integer integer, | |||
383 | * | 384 | * |
384 | * FUNCTION: acpi_ex_convert_to_string | 385 | * FUNCTION: acpi_ex_convert_to_string |
385 | * | 386 | * |
386 | * PARAMETERS: obj_desc - Object to be converted. Must be an | 387 | * PARAMETERS: obj_desc - Object to be converted. Must be an |
387 | * Integer, Buffer, or String | 388 | * Integer, Buffer, or String |
388 | * result_desc - Where the string object is returned | 389 | * result_desc - Where the string object is returned |
389 | * Type - String flags (base and conversion type) | 390 | * Type - String flags (base and conversion type) |
@@ -472,7 +473,7 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc, | |||
472 | base = 10; | 473 | base = 10; |
473 | 474 | ||
474 | /* | 475 | /* |
475 | * Calculate the final string length. Individual string values | 476 | * Calculate the final string length. Individual string values |
476 | * are variable length (include separator for each) | 477 | * are variable length (include separator for each) |
477 | */ | 478 | */ |
478 | for (i = 0; i < obj_desc->buffer.length; i++) { | 479 | for (i = 0; i < obj_desc->buffer.length; i++) { |
@@ -511,9 +512,14 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc, | |||
511 | /* | 512 | /* |
512 | * Create a new string object and string buffer | 513 | * Create a new string object and string buffer |
513 | * (-1 because of extra separator included in string_length from above) | 514 | * (-1 because of extra separator included in string_length from above) |
515 | * Allow creation of zero-length strings from zero-length buffers. | ||
514 | */ | 516 | */ |
517 | if (string_length) { | ||
518 | string_length--; | ||
519 | } | ||
520 | |||
515 | return_desc = acpi_ut_create_string_object((acpi_size) | 521 | return_desc = acpi_ut_create_string_object((acpi_size) |
516 | (string_length - 1)); | 522 | string_length); |
517 | if (!return_desc) { | 523 | if (!return_desc) { |
518 | return_ACPI_STATUS(AE_NO_MEMORY); | 524 | return_ACPI_STATUS(AE_NO_MEMORY); |
519 | } | 525 | } |
@@ -536,7 +542,9 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc, | |||
536 | * Null terminate the string | 542 | * Null terminate the string |
537 | * (overwrites final comma/space from above) | 543 | * (overwrites final comma/space from above) |
538 | */ | 544 | */ |
539 | new_buf--; | 545 | if (obj_desc->buffer.length) { |
546 | new_buf--; | ||
547 | } | ||
540 | *new_buf = 0; | 548 | *new_buf = 0; |
541 | break; | 549 | break; |
542 | 550 | ||
@@ -617,7 +625,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type, | |||
617 | case ACPI_TYPE_LOCAL_BANK_FIELD: | 625 | case ACPI_TYPE_LOCAL_BANK_FIELD: |
618 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | 626 | case ACPI_TYPE_LOCAL_INDEX_FIELD: |
619 | /* | 627 | /* |
620 | * These types require an Integer operand. We can convert | 628 | * These types require an Integer operand. We can convert |
621 | * a Buffer or a String to an Integer if necessary. | 629 | * a Buffer or a String to an Integer if necessary. |
622 | */ | 630 | */ |
623 | status = | 631 | status = |
@@ -627,7 +635,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type, | |||
627 | 635 | ||
628 | case ACPI_TYPE_STRING: | 636 | case ACPI_TYPE_STRING: |
629 | /* | 637 | /* |
630 | * The operand must be a String. We can convert an | 638 | * The operand must be a String. We can convert an |
631 | * Integer or Buffer if necessary | 639 | * Integer or Buffer if necessary |
632 | */ | 640 | */ |
633 | status = | 641 | status = |
@@ -637,7 +645,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type, | |||
637 | 645 | ||
638 | case ACPI_TYPE_BUFFER: | 646 | case ACPI_TYPE_BUFFER: |
639 | /* | 647 | /* |
640 | * The operand must be a Buffer. We can convert an | 648 | * The operand must be a Buffer. We can convert an |
641 | * Integer or String if necessary | 649 | * Integer or String if necessary |
642 | */ | 650 | */ |
643 | status = | 651 | status = |
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 2be2e2bf95bf..d087a7d28aa5 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #include <acpi/acinterp.h> | 45 | #include <acpi/acinterp.h> |
46 | #include <acpi/amlcode.h> | 46 | #include <acpi/amlcode.h> |
47 | #include <acpi/acnamesp.h> | 47 | #include <acpi/acnamesp.h> |
48 | #include <acpi/acparser.h> | ||
49 | 48 | ||
50 | #define _COMPONENT ACPI_EXECUTER | 49 | #define _COMPONENT ACPI_EXECUTER |
51 | ACPI_MODULE_NAME("exdump") | 50 | ACPI_MODULE_NAME("exdump") |
@@ -214,10 +213,11 @@ static struct acpi_exdump_info acpi_ex_dump_index_field[5] = { | |||
214 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(index_field.data_obj), "Data Object"} | 213 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(index_field.data_obj), "Data Object"} |
215 | }; | 214 | }; |
216 | 215 | ||
217 | static struct acpi_exdump_info acpi_ex_dump_reference[7] = { | 216 | static struct acpi_exdump_info acpi_ex_dump_reference[8] = { |
218 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_reference), NULL}, | 217 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_reference), NULL}, |
218 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(reference.class), "Class"}, | ||
219 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(reference.target_type), "Target Type"}, | 219 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(reference.target_type), "Target Type"}, |
220 | {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(reference.offset), "Offset"}, | 220 | {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(reference.value), "Value"}, |
221 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.object), "Object Desc"}, | 221 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.object), "Object Desc"}, |
222 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.node), "Node"}, | 222 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.node), "Node"}, |
223 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.where), "Where"}, | 223 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.where), "Where"}, |
@@ -413,10 +413,10 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, | |||
413 | 413 | ||
414 | case ACPI_EXD_REFERENCE: | 414 | case ACPI_EXD_REFERENCE: |
415 | 415 | ||
416 | acpi_ex_out_string("Opcode", | 416 | acpi_ex_out_string("Class Name", |
417 | (acpi_ps_get_opcode_info | 417 | (char *) |
418 | (obj_desc->reference.opcode))-> | 418 | acpi_ut_get_reference_name |
419 | name); | 419 | (obj_desc)); |
420 | acpi_ex_dump_reference_obj(obj_desc); | 420 | acpi_ex_dump_reference_obj(obj_desc); |
421 | break; | 421 | break; |
422 | 422 | ||
@@ -494,40 +494,41 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) | |||
494 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 494 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { |
495 | case ACPI_TYPE_LOCAL_REFERENCE: | 495 | case ACPI_TYPE_LOCAL_REFERENCE: |
496 | 496 | ||
497 | switch (obj_desc->reference.opcode) { | 497 | acpi_os_printf("Reference: [%s] ", |
498 | case AML_DEBUG_OP: | 498 | acpi_ut_get_reference_name(obj_desc)); |
499 | |||
500 | switch (obj_desc->reference.class) { | ||
501 | case ACPI_REFCLASS_DEBUG: | ||
499 | 502 | ||
500 | acpi_os_printf("Reference: Debug\n"); | 503 | acpi_os_printf("\n"); |
501 | break; | 504 | break; |
502 | 505 | ||
503 | case AML_INDEX_OP: | 506 | case ACPI_REFCLASS_INDEX: |
504 | 507 | ||
505 | acpi_os_printf("Reference: Index %p\n", | 508 | acpi_os_printf("%p\n", obj_desc->reference.object); |
506 | obj_desc->reference.object); | ||
507 | break; | 509 | break; |
508 | 510 | ||
509 | case AML_LOAD_OP: | 511 | case ACPI_REFCLASS_TABLE: |
510 | 512 | ||
511 | acpi_os_printf("Reference: [DdbHandle] TableIndex %p\n", | 513 | acpi_os_printf("Table Index %X\n", |
512 | obj_desc->reference.object); | 514 | obj_desc->reference.value); |
513 | break; | 515 | break; |
514 | 516 | ||
515 | case AML_REF_OF_OP: | 517 | case ACPI_REFCLASS_REFOF: |
516 | 518 | ||
517 | acpi_os_printf("Reference: (RefOf) %p [%s]\n", | 519 | acpi_os_printf("%p [%s]\n", obj_desc->reference.object, |
518 | obj_desc->reference.object, | ||
519 | acpi_ut_get_type_name(((union | 520 | acpi_ut_get_type_name(((union |
520 | acpi_operand_object | 521 | acpi_operand_object |
521 | *)obj_desc-> | 522 | *) |
523 | obj_desc-> | ||
522 | reference. | 524 | reference. |
523 | object)->common. | 525 | object)->common. |
524 | type)); | 526 | type)); |
525 | break; | 527 | break; |
526 | 528 | ||
527 | case AML_ARG_OP: | 529 | case ACPI_REFCLASS_ARG: |
528 | 530 | ||
529 | acpi_os_printf("Reference: Arg%d", | 531 | acpi_os_printf("%X", obj_desc->reference.value); |
530 | obj_desc->reference.offset); | ||
531 | 532 | ||
532 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { | 533 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { |
533 | 534 | ||
@@ -542,10 +543,9 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) | |||
542 | acpi_os_printf("\n"); | 543 | acpi_os_printf("\n"); |
543 | break; | 544 | break; |
544 | 545 | ||
545 | case AML_LOCAL_OP: | 546 | case ACPI_REFCLASS_LOCAL: |
546 | 547 | ||
547 | acpi_os_printf("Reference: Local%d", | 548 | acpi_os_printf("%X", obj_desc->reference.value); |
548 | obj_desc->reference.offset); | ||
549 | 549 | ||
550 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { | 550 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { |
551 | 551 | ||
@@ -560,21 +560,16 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) | |||
560 | acpi_os_printf("\n"); | 560 | acpi_os_printf("\n"); |
561 | break; | 561 | break; |
562 | 562 | ||
563 | case AML_INT_NAMEPATH_OP: | 563 | case ACPI_REFCLASS_NAME: |
564 | 564 | ||
565 | acpi_os_printf("Reference: Namepath %X [%4.4s]\n", | 565 | acpi_os_printf("- [%4.4s]\n", |
566 | obj_desc->reference.node->name.integer, | ||
567 | obj_desc->reference.node->name.ascii); | 566 | obj_desc->reference.node->name.ascii); |
568 | break; | 567 | break; |
569 | 568 | ||
570 | default: | 569 | default: /* Unknown reference class */ |
571 | |||
572 | /* Unknown opcode */ | ||
573 | 570 | ||
574 | acpi_os_printf("Unknown Reference opcode=%X\n", | 571 | acpi_os_printf("%2.2X\n", obj_desc->reference.class); |
575 | obj_desc->reference.opcode); | ||
576 | break; | 572 | break; |
577 | |||
578 | } | 573 | } |
579 | break; | 574 | break; |
580 | 575 | ||
@@ -865,8 +860,8 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc) | |||
865 | 860 | ||
866 | ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER; | 861 | ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER; |
867 | 862 | ||
868 | if (obj_desc->reference.opcode == AML_INT_NAMEPATH_OP) { | 863 | if (obj_desc->reference.class == ACPI_REFCLASS_NAME) { |
869 | acpi_os_printf(" Named Object %p ", obj_desc->reference.node); | 864 | acpi_os_printf(" %p ", obj_desc->reference.node); |
870 | 865 | ||
871 | status = | 866 | status = |
872 | acpi_ns_handle_to_pathname(obj_desc->reference.node, | 867 | acpi_ns_handle_to_pathname(obj_desc->reference.node, |
@@ -882,14 +877,12 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc) | |||
882 | ACPI_DESC_TYPE_OPERAND) { | 877 | ACPI_DESC_TYPE_OPERAND) { |
883 | acpi_os_printf(" Target: %p", | 878 | acpi_os_printf(" Target: %p", |
884 | obj_desc->reference.object); | 879 | obj_desc->reference.object); |
885 | if (obj_desc->reference.opcode == AML_LOAD_OP) { | 880 | if (obj_desc->reference.class == ACPI_REFCLASS_TABLE) { |
886 | /* | 881 | acpi_os_printf(" Table Index: %X\n", |
887 | * For DDBHandle reference, | 882 | obj_desc->reference.value); |
888 | * obj_desc->Reference.Object is the table index | ||
889 | */ | ||
890 | acpi_os_printf(" [DDBHandle]\n"); | ||
891 | } else { | 883 | } else { |
892 | acpi_os_printf(" [%s]\n", | 884 | acpi_os_printf(" Target: %p [%s]\n", |
885 | obj_desc->reference.object, | ||
893 | acpi_ut_get_type_name(((union | 886 | acpi_ut_get_type_name(((union |
894 | acpi_operand_object | 887 | acpi_operand_object |
895 | *) | 888 | *) |
@@ -988,9 +981,9 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc, | |||
988 | 981 | ||
989 | case ACPI_TYPE_LOCAL_REFERENCE: | 982 | case ACPI_TYPE_LOCAL_REFERENCE: |
990 | 983 | ||
991 | acpi_os_printf("[Object Reference] %s", | 984 | acpi_os_printf("[Object Reference] Type [%s] %2.2X", |
992 | (acpi_ps_get_opcode_info | 985 | acpi_ut_get_reference_name(obj_desc), |
993 | (obj_desc->reference.opcode))->name); | 986 | obj_desc->reference.class); |
994 | acpi_ex_dump_reference_obj(obj_desc); | 987 | acpi_ex_dump_reference_obj(obj_desc); |
995 | break; | 988 | break; |
996 | 989 | ||
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c index 731414a581a6..efb191340059 100644 --- a/drivers/acpi/executer/exmisc.c +++ b/drivers/acpi/executer/exmisc.c | |||
@@ -86,10 +86,10 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc, | |||
86 | /* | 86 | /* |
87 | * Must be a reference to a Local or Arg | 87 | * Must be a reference to a Local or Arg |
88 | */ | 88 | */ |
89 | switch (obj_desc->reference.opcode) { | 89 | switch (obj_desc->reference.class) { |
90 | case AML_LOCAL_OP: | 90 | case ACPI_REFCLASS_LOCAL: |
91 | case AML_ARG_OP: | 91 | case ACPI_REFCLASS_ARG: |
92 | case AML_DEBUG_OP: | 92 | case ACPI_REFCLASS_DEBUG: |
93 | 93 | ||
94 | /* The referenced object is the pseudo-node for the local/arg */ | 94 | /* The referenced object is the pseudo-node for the local/arg */ |
95 | 95 | ||
@@ -98,8 +98,8 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc, | |||
98 | 98 | ||
99 | default: | 99 | default: |
100 | 100 | ||
101 | ACPI_ERROR((AE_INFO, "Unknown Reference opcode %X", | 101 | ACPI_ERROR((AE_INFO, "Unknown Reference Class %2.2X", |
102 | obj_desc->reference.opcode)); | 102 | obj_desc->reference.class)); |
103 | return_ACPI_STATUS(AE_AML_INTERNAL); | 103 | return_ACPI_STATUS(AE_AML_INTERNAL); |
104 | } | 104 | } |
105 | break; | 105 | break; |
@@ -127,7 +127,7 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc, | |||
127 | return_ACPI_STATUS(AE_NO_MEMORY); | 127 | return_ACPI_STATUS(AE_NO_MEMORY); |
128 | } | 128 | } |
129 | 129 | ||
130 | reference_obj->reference.opcode = AML_REF_OF_OP; | 130 | reference_obj->reference.class = ACPI_REFCLASS_REFOF; |
131 | reference_obj->reference.object = referenced_obj; | 131 | reference_obj->reference.object = referenced_obj; |
132 | *return_desc = reference_obj; | 132 | *return_desc = reference_obj; |
133 | 133 | ||
diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c index 7c3bea575e02..f622f9eac8a1 100644 --- a/drivers/acpi/executer/exoparg1.c +++ b/drivers/acpi/executer/exoparg1.c | |||
@@ -825,16 +825,16 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) | |||
825 | * | 825 | * |
826 | * Must resolve/dereference the local/arg reference first | 826 | * Must resolve/dereference the local/arg reference first |
827 | */ | 827 | */ |
828 | switch (operand[0]->reference.opcode) { | 828 | switch (operand[0]->reference.class) { |
829 | case AML_LOCAL_OP: | 829 | case ACPI_REFCLASS_LOCAL: |
830 | case AML_ARG_OP: | 830 | case ACPI_REFCLASS_ARG: |
831 | 831 | ||
832 | /* Set Operand[0] to the value of the local/arg */ | 832 | /* Set Operand[0] to the value of the local/arg */ |
833 | 833 | ||
834 | status = | 834 | status = |
835 | acpi_ds_method_data_get_value | 835 | acpi_ds_method_data_get_value |
836 | (operand[0]->reference.opcode, | 836 | (operand[0]->reference.class, |
837 | operand[0]->reference.offset, | 837 | operand[0]->reference.value, |
838 | walk_state, &temp_desc); | 838 | walk_state, &temp_desc); |
839 | if (ACPI_FAILURE(status)) { | 839 | if (ACPI_FAILURE(status)) { |
840 | goto cleanup; | 840 | goto cleanup; |
@@ -848,7 +848,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) | |||
848 | operand[0] = temp_desc; | 848 | operand[0] = temp_desc; |
849 | break; | 849 | break; |
850 | 850 | ||
851 | case AML_REF_OF_OP: | 851 | case ACPI_REFCLASS_REFOF: |
852 | 852 | ||
853 | /* Get the object to which the reference refers */ | 853 | /* Get the object to which the reference refers */ |
854 | 854 | ||
@@ -928,8 +928,8 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) | |||
928 | * This must be a reference object produced by either the | 928 | * This must be a reference object produced by either the |
929 | * Index() or ref_of() operator | 929 | * Index() or ref_of() operator |
930 | */ | 930 | */ |
931 | switch (operand[0]->reference.opcode) { | 931 | switch (operand[0]->reference.class) { |
932 | case AML_INDEX_OP: | 932 | case ACPI_REFCLASS_INDEX: |
933 | 933 | ||
934 | /* | 934 | /* |
935 | * The target type for the Index operator must be | 935 | * The target type for the Index operator must be |
@@ -965,7 +965,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) | |||
965 | return_desc->integer.value = | 965 | return_desc->integer.value = |
966 | temp_desc->buffer. | 966 | temp_desc->buffer. |
967 | pointer[operand[0]->reference. | 967 | pointer[operand[0]->reference. |
968 | offset]; | 968 | value]; |
969 | break; | 969 | break; |
970 | 970 | ||
971 | case ACPI_TYPE_PACKAGE: | 971 | case ACPI_TYPE_PACKAGE: |
@@ -985,7 +985,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) | |||
985 | default: | 985 | default: |
986 | 986 | ||
987 | ACPI_ERROR((AE_INFO, | 987 | ACPI_ERROR((AE_INFO, |
988 | "Unknown Index TargetType %X in obj %p", | 988 | "Unknown Index TargetType %X in reference object %p", |
989 | operand[0]->reference. | 989 | operand[0]->reference. |
990 | target_type, operand[0])); | 990 | target_type, operand[0])); |
991 | status = AE_AML_OPERAND_TYPE; | 991 | status = AE_AML_OPERAND_TYPE; |
@@ -993,7 +993,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) | |||
993 | } | 993 | } |
994 | break; | 994 | break; |
995 | 995 | ||
996 | case AML_REF_OF_OP: | 996 | case ACPI_REFCLASS_REFOF: |
997 | 997 | ||
998 | return_desc = operand[0]->reference.object; | 998 | return_desc = operand[0]->reference.object; |
999 | 999 | ||
@@ -1013,9 +1013,9 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) | |||
1013 | 1013 | ||
1014 | default: | 1014 | default: |
1015 | ACPI_ERROR((AE_INFO, | 1015 | ACPI_ERROR((AE_INFO, |
1016 | "Unknown opcode in reference(%p) - %X", | 1016 | "Unknown class in reference(%p) - %2.2X", |
1017 | operand[0], | 1017 | operand[0], |
1018 | operand[0]->reference.opcode)); | 1018 | operand[0]->reference.class)); |
1019 | 1019 | ||
1020 | status = AE_TYPE; | 1020 | status = AE_TYPE; |
1021 | goto cleanup; | 1021 | goto cleanup; |
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c index 8e8bbb6ccebd..368def5dffce 100644 --- a/drivers/acpi/executer/exoparg2.c +++ b/drivers/acpi/executer/exoparg2.c | |||
@@ -391,8 +391,8 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) | |||
391 | /* Initialize the Index reference object */ | 391 | /* Initialize the Index reference object */ |
392 | 392 | ||
393 | index = operand[1]->integer.value; | 393 | index = operand[1]->integer.value; |
394 | return_desc->reference.offset = (u32) index; | 394 | return_desc->reference.value = (u32) index; |
395 | return_desc->reference.opcode = AML_INDEX_OP; | 395 | return_desc->reference.class = ACPI_REFCLASS_INDEX; |
396 | 396 | ||
397 | /* | 397 | /* |
398 | * At this point, the Source operand is a String, Buffer, or Package. | 398 | * At this point, the Source operand is a String, Buffer, or Package. |
diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c index 5596f42c9676..423ad3635f3d 100644 --- a/drivers/acpi/executer/exresnte.c +++ b/drivers/acpi/executer/exresnte.c | |||
@@ -46,8 +46,6 @@ | |||
46 | #include <acpi/acdispat.h> | 46 | #include <acpi/acdispat.h> |
47 | #include <acpi/acinterp.h> | 47 | #include <acpi/acinterp.h> |
48 | #include <acpi/acnamesp.h> | 48 | #include <acpi/acnamesp.h> |
49 | #include <acpi/acparser.h> | ||
50 | #include <acpi/amlcode.h> | ||
51 | 49 | ||
52 | #define _COMPONENT ACPI_EXECUTER | 50 | #define _COMPONENT ACPI_EXECUTER |
53 | ACPI_MODULE_NAME("exresnte") | 51 | ACPI_MODULE_NAME("exresnte") |
@@ -238,10 +236,10 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, | |||
238 | 236 | ||
239 | case ACPI_TYPE_LOCAL_REFERENCE: | 237 | case ACPI_TYPE_LOCAL_REFERENCE: |
240 | 238 | ||
241 | switch (source_desc->reference.opcode) { | 239 | switch (source_desc->reference.class) { |
242 | case AML_LOAD_OP: /* This is a ddb_handle */ | 240 | case ACPI_REFCLASS_TABLE: /* This is a ddb_handle */ |
243 | case AML_REF_OF_OP: | 241 | case ACPI_REFCLASS_REFOF: |
244 | case AML_INDEX_OP: | 242 | case ACPI_REFCLASS_INDEX: |
245 | 243 | ||
246 | /* Return an additional reference to the object */ | 244 | /* Return an additional reference to the object */ |
247 | 245 | ||
@@ -253,10 +251,8 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, | |||
253 | /* No named references are allowed here */ | 251 | /* No named references are allowed here */ |
254 | 252 | ||
255 | ACPI_ERROR((AE_INFO, | 253 | ACPI_ERROR((AE_INFO, |
256 | "Unsupported Reference opcode %X (%s)", | 254 | "Unsupported Reference type %X", |
257 | source_desc->reference.opcode, | 255 | source_desc->reference.class)); |
258 | acpi_ps_get_opcode_name(source_desc-> | ||
259 | reference.opcode))); | ||
260 | 256 | ||
261 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 257 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
262 | } | 258 | } |
diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c index b35f7c817acf..89571b92a522 100644 --- a/drivers/acpi/executer/exresolv.c +++ b/drivers/acpi/executer/exresolv.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <acpi/acdispat.h> | 47 | #include <acpi/acdispat.h> |
48 | #include <acpi/acinterp.h> | 48 | #include <acpi/acinterp.h> |
49 | #include <acpi/acnamesp.h> | 49 | #include <acpi/acnamesp.h> |
50 | #include <acpi/acparser.h> | ||
51 | 50 | ||
52 | #define _COMPONENT ACPI_EXECUTER | 51 | #define _COMPONENT ACPI_EXECUTER |
53 | ACPI_MODULE_NAME("exresolv") | 52 | ACPI_MODULE_NAME("exresolv") |
@@ -141,7 +140,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, | |||
141 | acpi_status status = AE_OK; | 140 | acpi_status status = AE_OK; |
142 | union acpi_operand_object *stack_desc; | 141 | union acpi_operand_object *stack_desc; |
143 | union acpi_operand_object *obj_desc = NULL; | 142 | union acpi_operand_object *obj_desc = NULL; |
144 | u16 opcode; | 143 | u8 ref_type; |
145 | 144 | ||
146 | ACPI_FUNCTION_TRACE(ex_resolve_object_to_value); | 145 | ACPI_FUNCTION_TRACE(ex_resolve_object_to_value); |
147 | 146 | ||
@@ -152,19 +151,19 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, | |||
152 | switch (ACPI_GET_OBJECT_TYPE(stack_desc)) { | 151 | switch (ACPI_GET_OBJECT_TYPE(stack_desc)) { |
153 | case ACPI_TYPE_LOCAL_REFERENCE: | 152 | case ACPI_TYPE_LOCAL_REFERENCE: |
154 | 153 | ||
155 | opcode = stack_desc->reference.opcode; | 154 | ref_type = stack_desc->reference.class; |
156 | 155 | ||
157 | switch (opcode) { | 156 | switch (ref_type) { |
158 | case AML_LOCAL_OP: | 157 | case ACPI_REFCLASS_LOCAL: |
159 | case AML_ARG_OP: | 158 | case ACPI_REFCLASS_ARG: |
160 | 159 | ||
161 | /* | 160 | /* |
162 | * Get the local from the method's state info | 161 | * Get the local from the method's state info |
163 | * Note: this increments the local's object reference count | 162 | * Note: this increments the local's object reference count |
164 | */ | 163 | */ |
165 | status = acpi_ds_method_data_get_value(opcode, | 164 | status = acpi_ds_method_data_get_value(ref_type, |
166 | stack_desc-> | 165 | stack_desc-> |
167 | reference.offset, | 166 | reference.value, |
168 | walk_state, | 167 | walk_state, |
169 | &obj_desc); | 168 | &obj_desc); |
170 | if (ACPI_FAILURE(status)) { | 169 | if (ACPI_FAILURE(status)) { |
@@ -173,7 +172,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, | |||
173 | 172 | ||
174 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 173 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
175 | "[Arg/Local %X] ValueObj is %p\n", | 174 | "[Arg/Local %X] ValueObj is %p\n", |
176 | stack_desc->reference.offset, | 175 | stack_desc->reference.value, |
177 | obj_desc)); | 176 | obj_desc)); |
178 | 177 | ||
179 | /* | 178 | /* |
@@ -184,7 +183,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, | |||
184 | *stack_ptr = obj_desc; | 183 | *stack_ptr = obj_desc; |
185 | break; | 184 | break; |
186 | 185 | ||
187 | case AML_INDEX_OP: | 186 | case ACPI_REFCLASS_INDEX: |
188 | 187 | ||
189 | switch (stack_desc->reference.target_type) { | 188 | switch (stack_desc->reference.target_type) { |
190 | case ACPI_TYPE_BUFFER_FIELD: | 189 | case ACPI_TYPE_BUFFER_FIELD: |
@@ -239,15 +238,15 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, | |||
239 | } | 238 | } |
240 | break; | 239 | break; |
241 | 240 | ||
242 | case AML_REF_OF_OP: | 241 | case ACPI_REFCLASS_REFOF: |
243 | case AML_DEBUG_OP: | 242 | case ACPI_REFCLASS_DEBUG: |
244 | case AML_LOAD_OP: | 243 | case ACPI_REFCLASS_TABLE: |
245 | 244 | ||
246 | /* Just leave the object as-is, do not dereference */ | 245 | /* Just leave the object as-is, do not dereference */ |
247 | 246 | ||
248 | break; | 247 | break; |
249 | 248 | ||
250 | case AML_INT_NAMEPATH_OP: /* Reference to a named object */ | 249 | case ACPI_REFCLASS_NAME: /* Reference to a named object */ |
251 | 250 | ||
252 | /* Dereference the name */ | 251 | /* Dereference the name */ |
253 | 252 | ||
@@ -273,8 +272,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, | |||
273 | default: | 272 | default: |
274 | 273 | ||
275 | ACPI_ERROR((AE_INFO, | 274 | ACPI_ERROR((AE_INFO, |
276 | "Unknown Reference opcode %X (%s) in %p", | 275 | "Unknown Reference type %X in %p", ref_type, |
277 | opcode, acpi_ps_get_opcode_name(opcode), | ||
278 | stack_desc)); | 276 | stack_desc)); |
279 | status = AE_AML_INTERNAL; | 277 | status = AE_AML_INTERNAL; |
280 | break; | 278 | break; |
@@ -388,13 +386,13 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, | |||
388 | * traversing the list of possibly many nested references. | 386 | * traversing the list of possibly many nested references. |
389 | */ | 387 | */ |
390 | while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) { | 388 | while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) { |
391 | switch (obj_desc->reference.opcode) { | 389 | switch (obj_desc->reference.class) { |
392 | case AML_REF_OF_OP: | 390 | case ACPI_REFCLASS_REFOF: |
393 | case AML_INT_NAMEPATH_OP: | 391 | case ACPI_REFCLASS_NAME: |
394 | 392 | ||
395 | /* Dereference the reference pointer */ | 393 | /* Dereference the reference pointer */ |
396 | 394 | ||
397 | if (obj_desc->reference.opcode == AML_REF_OF_OP) { | 395 | if (obj_desc->reference.class == ACPI_REFCLASS_REFOF) { |
398 | node = obj_desc->reference.object; | 396 | node = obj_desc->reference.object; |
399 | } else { /* AML_INT_NAMEPATH_OP */ | 397 | } else { /* AML_INT_NAMEPATH_OP */ |
400 | 398 | ||
@@ -429,7 +427,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, | |||
429 | } | 427 | } |
430 | break; | 428 | break; |
431 | 429 | ||
432 | case AML_INDEX_OP: | 430 | case ACPI_REFCLASS_INDEX: |
433 | 431 | ||
434 | /* Get the type of this reference (index into another object) */ | 432 | /* Get the type of this reference (index into another object) */ |
435 | 433 | ||
@@ -455,22 +453,22 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, | |||
455 | } | 453 | } |
456 | break; | 454 | break; |
457 | 455 | ||
458 | case AML_LOAD_OP: | 456 | case ACPI_REFCLASS_TABLE: |
459 | 457 | ||
460 | type = ACPI_TYPE_DDB_HANDLE; | 458 | type = ACPI_TYPE_DDB_HANDLE; |
461 | goto exit; | 459 | goto exit; |
462 | 460 | ||
463 | case AML_LOCAL_OP: | 461 | case ACPI_REFCLASS_LOCAL: |
464 | case AML_ARG_OP: | 462 | case ACPI_REFCLASS_ARG: |
465 | 463 | ||
466 | if (return_desc) { | 464 | if (return_desc) { |
467 | status = | 465 | status = |
468 | acpi_ds_method_data_get_value(obj_desc-> | 466 | acpi_ds_method_data_get_value(obj_desc-> |
469 | reference. | 467 | reference. |
470 | opcode, | 468 | class, |
471 | obj_desc-> | 469 | obj_desc-> |
472 | reference. | 470 | reference. |
473 | offset, | 471 | value, |
474 | walk_state, | 472 | walk_state, |
475 | &obj_desc); | 473 | &obj_desc); |
476 | if (ACPI_FAILURE(status)) { | 474 | if (ACPI_FAILURE(status)) { |
@@ -481,10 +479,10 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, | |||
481 | status = | 479 | status = |
482 | acpi_ds_method_data_get_node(obj_desc-> | 480 | acpi_ds_method_data_get_node(obj_desc-> |
483 | reference. | 481 | reference. |
484 | opcode, | 482 | class, |
485 | obj_desc-> | 483 | obj_desc-> |
486 | reference. | 484 | reference. |
487 | offset, | 485 | value, |
488 | walk_state, | 486 | walk_state, |
489 | &node); | 487 | &node); |
490 | if (ACPI_FAILURE(status)) { | 488 | if (ACPI_FAILURE(status)) { |
@@ -499,7 +497,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, | |||
499 | } | 497 | } |
500 | break; | 498 | break; |
501 | 499 | ||
502 | case AML_DEBUG_OP: | 500 | case ACPI_REFCLASS_DEBUG: |
503 | 501 | ||
504 | /* The Debug Object is of type "DebugObject" */ | 502 | /* The Debug Object is of type "DebugObject" */ |
505 | 503 | ||
@@ -509,8 +507,8 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, | |||
509 | default: | 507 | default: |
510 | 508 | ||
511 | ACPI_ERROR((AE_INFO, | 509 | ACPI_ERROR((AE_INFO, |
512 | "Unknown Reference subtype %X", | 510 | "Unknown Reference Class %2.2X", |
513 | obj_desc->reference.opcode)); | 511 | obj_desc->reference.class)); |
514 | return_ACPI_STATUS(AE_AML_INTERNAL); | 512 | return_ACPI_STATUS(AE_AML_INTERNAL); |
515 | } | 513 | } |
516 | } | 514 | } |
diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c index 54085f16ec28..0bb82593da72 100644 --- a/drivers/acpi/executer/exresop.c +++ b/drivers/acpi/executer/exresop.c | |||
@@ -225,41 +225,36 @@ acpi_ex_resolve_operands(u16 opcode, | |||
225 | 225 | ||
226 | if (object_type == (u8) ACPI_TYPE_LOCAL_REFERENCE) { | 226 | if (object_type == (u8) ACPI_TYPE_LOCAL_REFERENCE) { |
227 | 227 | ||
228 | /* Decode the Reference */ | 228 | /* Validate the Reference */ |
229 | 229 | ||
230 | op_info = acpi_ps_get_opcode_info(opcode); | 230 | switch (obj_desc->reference.class) { |
231 | if (op_info->class == AML_CLASS_UNKNOWN) { | 231 | case ACPI_REFCLASS_DEBUG: |
232 | return_ACPI_STATUS(AE_AML_BAD_OPCODE); | ||
233 | } | ||
234 | 232 | ||
235 | switch (obj_desc->reference.opcode) { | ||
236 | case AML_DEBUG_OP: | ||
237 | target_op = AML_DEBUG_OP; | 233 | target_op = AML_DEBUG_OP; |
238 | 234 | ||
239 | /*lint -fallthrough */ | 235 | /*lint -fallthrough */ |
240 | 236 | ||
241 | case AML_INDEX_OP: | 237 | case ACPI_REFCLASS_ARG: |
242 | case AML_REF_OF_OP: | 238 | case ACPI_REFCLASS_LOCAL: |
243 | case AML_ARG_OP: | 239 | case ACPI_REFCLASS_INDEX: |
244 | case AML_LOCAL_OP: | 240 | case ACPI_REFCLASS_REFOF: |
245 | case AML_LOAD_OP: /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */ | 241 | case ACPI_REFCLASS_TABLE: /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */ |
246 | case AML_INT_NAMEPATH_OP: /* Reference to a named object */ | 242 | case ACPI_REFCLASS_NAME: /* Reference to a named object */ |
247 | 243 | ||
248 | ACPI_DEBUG_ONLY_MEMBERS(ACPI_DEBUG_PRINT | 244 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
249 | ((ACPI_DB_EXEC, | 245 | "Operand is a Reference, Class [%s] %2.2X\n", |
250 | "Operand is a Reference, RefOpcode [%s]\n", | 246 | acpi_ut_get_reference_name |
251 | (acpi_ps_get_opcode_info | 247 | (obj_desc), |
252 | (obj_desc-> | 248 | obj_desc->reference. |
253 | reference. | 249 | class)); |
254 | opcode))-> | ||
255 | name))); | ||
256 | break; | 250 | break; |
257 | 251 | ||
258 | default: | 252 | default: |
253 | |||
259 | ACPI_ERROR((AE_INFO, | 254 | ACPI_ERROR((AE_INFO, |
260 | "Operand is a Reference, Unknown Reference Opcode: %X", | 255 | "Unknown Reference Class %2.2X in %p", |
261 | obj_desc->reference. | 256 | obj_desc->reference.class, |
262 | opcode)); | 257 | obj_desc)); |
263 | 258 | ||
264 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 259 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
265 | } | 260 | } |
@@ -270,8 +265,7 @@ acpi_ex_resolve_operands(u16 opcode, | |||
270 | 265 | ||
271 | /* Invalid descriptor */ | 266 | /* Invalid descriptor */ |
272 | 267 | ||
273 | ACPI_ERROR((AE_INFO, | 268 | ACPI_ERROR((AE_INFO, "Invalid descriptor %p [%s]", |
274 | "Invalid descriptor %p [%s]", | ||
275 | obj_desc, | 269 | obj_desc, |
276 | acpi_ut_get_descriptor_name(obj_desc))); | 270 | acpi_ut_get_descriptor_name(obj_desc))); |
277 | 271 | ||
@@ -343,7 +337,7 @@ acpi_ex_resolve_operands(u16 opcode, | |||
343 | if ((opcode == AML_STORE_OP) && | 337 | if ((opcode == AML_STORE_OP) && |
344 | (ACPI_GET_OBJECT_TYPE(*stack_ptr) == | 338 | (ACPI_GET_OBJECT_TYPE(*stack_ptr) == |
345 | ACPI_TYPE_LOCAL_REFERENCE) | 339 | ACPI_TYPE_LOCAL_REFERENCE) |
346 | && ((*stack_ptr)->reference.opcode == AML_INDEX_OP)) { | 340 | && ((*stack_ptr)->reference.class == ACPI_REFCLASS_INDEX)) { |
347 | goto next_operand; | 341 | goto next_operand; |
348 | } | 342 | } |
349 | break; | 343 | break; |
diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c index 38b55e352495..3318df4cbd98 100644 --- a/drivers/acpi/executer/exstore.c +++ b/drivers/acpi/executer/exstore.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <acpi/acinterp.h> | 47 | #include <acpi/acinterp.h> |
48 | #include <acpi/amlcode.h> | 48 | #include <acpi/amlcode.h> |
49 | #include <acpi/acnamesp.h> | 49 | #include <acpi/acnamesp.h> |
50 | #include <acpi/acparser.h> | ||
51 | 50 | ||
52 | #define _COMPONENT ACPI_EXECUTER | 51 | #define _COMPONENT ACPI_EXECUTER |
53 | ACPI_MODULE_NAME("exstore") | 52 | ACPI_MODULE_NAME("exstore") |
@@ -179,22 +178,26 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, | |||
179 | 178 | ||
180 | case ACPI_TYPE_LOCAL_REFERENCE: | 179 | case ACPI_TYPE_LOCAL_REFERENCE: |
181 | 180 | ||
182 | if (source_desc->reference.opcode == AML_INDEX_OP) { | 181 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[%s] ", |
183 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, | 182 | acpi_ut_get_reference_name(source_desc))); |
184 | "[%s, 0x%X]\n", | 183 | |
185 | acpi_ps_get_opcode_name | 184 | /* Decode the reference */ |
186 | (source_desc->reference.opcode), | 185 | |
187 | source_desc->reference.offset)); | 186 | switch (source_desc->reference.class) { |
188 | } else { | 187 | case ACPI_REFCLASS_INDEX: |
189 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[%s]", | 188 | |
190 | acpi_ps_get_opcode_name | 189 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "0x%X\n", |
191 | (source_desc->reference.opcode))); | 190 | source_desc->reference.value)); |
192 | } | 191 | break; |
192 | |||
193 | case ACPI_REFCLASS_TABLE: | ||
193 | 194 | ||
194 | if (source_desc->reference.opcode == AML_LOAD_OP) { /* Load and load_table */ | ||
195 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, | 195 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, |
196 | " Table OwnerId %p\n", | 196 | "Table Index 0x%X\n", |
197 | source_desc->reference.object)); | 197 | source_desc->reference.value)); |
198 | break; | ||
199 | |||
200 | default: | ||
198 | break; | 201 | break; |
199 | } | 202 | } |
200 | 203 | ||
@@ -347,15 +350,15 @@ acpi_ex_store(union acpi_operand_object *source_desc, | |||
347 | } | 350 | } |
348 | 351 | ||
349 | /* | 352 | /* |
350 | * Examine the Reference opcode. These cases are handled: | 353 | * Examine the Reference class. These cases are handled: |
351 | * | 354 | * |
352 | * 1) Store to Name (Change the object associated with a name) | 355 | * 1) Store to Name (Change the object associated with a name) |
353 | * 2) Store to an indexed area of a Buffer or Package | 356 | * 2) Store to an indexed area of a Buffer or Package |
354 | * 3) Store to a Method Local or Arg | 357 | * 3) Store to a Method Local or Arg |
355 | * 4) Store to the debug object | 358 | * 4) Store to the debug object |
356 | */ | 359 | */ |
357 | switch (ref_desc->reference.opcode) { | 360 | switch (ref_desc->reference.class) { |
358 | case AML_REF_OF_OP: | 361 | case ACPI_REFCLASS_REFOF: |
359 | 362 | ||
360 | /* Storing an object into a Name "container" */ | 363 | /* Storing an object into a Name "container" */ |
361 | 364 | ||
@@ -365,7 +368,7 @@ acpi_ex_store(union acpi_operand_object *source_desc, | |||
365 | ACPI_IMPLICIT_CONVERSION); | 368 | ACPI_IMPLICIT_CONVERSION); |
366 | break; | 369 | break; |
367 | 370 | ||
368 | case AML_INDEX_OP: | 371 | case ACPI_REFCLASS_INDEX: |
369 | 372 | ||
370 | /* Storing to an Index (pointer into a packager or buffer) */ | 373 | /* Storing to an Index (pointer into a packager or buffer) */ |
371 | 374 | ||
@@ -374,18 +377,18 @@ acpi_ex_store(union acpi_operand_object *source_desc, | |||
374 | walk_state); | 377 | walk_state); |
375 | break; | 378 | break; |
376 | 379 | ||
377 | case AML_LOCAL_OP: | 380 | case ACPI_REFCLASS_LOCAL: |
378 | case AML_ARG_OP: | 381 | case ACPI_REFCLASS_ARG: |
379 | 382 | ||
380 | /* Store to a method local/arg */ | 383 | /* Store to a method local/arg */ |
381 | 384 | ||
382 | status = | 385 | status = |
383 | acpi_ds_store_object_to_local(ref_desc->reference.opcode, | 386 | acpi_ds_store_object_to_local(ref_desc->reference.class, |
384 | ref_desc->reference.offset, | 387 | ref_desc->reference.value, |
385 | source_desc, walk_state); | 388 | source_desc, walk_state); |
386 | break; | 389 | break; |
387 | 390 | ||
388 | case AML_DEBUG_OP: | 391 | case ACPI_REFCLASS_DEBUG: |
389 | 392 | ||
390 | /* | 393 | /* |
391 | * Storing to the Debug object causes the value stored to be | 394 | * Storing to the Debug object causes the value stored to be |
@@ -401,9 +404,9 @@ acpi_ex_store(union acpi_operand_object *source_desc, | |||
401 | 404 | ||
402 | default: | 405 | default: |
403 | 406 | ||
404 | ACPI_ERROR((AE_INFO, "Unknown Reference opcode %X", | 407 | ACPI_ERROR((AE_INFO, "Unknown Reference Class %2.2X", |
405 | ref_desc->reference.opcode)); | 408 | ref_desc->reference.class)); |
406 | ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_ERROR); | 409 | ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_INFO); |
407 | 410 | ||
408 | status = AE_AML_INTERNAL; | 411 | status = AE_AML_INTERNAL; |
409 | break; | 412 | break; |
@@ -458,7 +461,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, | |||
458 | 461 | ||
459 | if (ACPI_GET_OBJECT_TYPE(source_desc) == | 462 | if (ACPI_GET_OBJECT_TYPE(source_desc) == |
460 | ACPI_TYPE_LOCAL_REFERENCE | 463 | ACPI_TYPE_LOCAL_REFERENCE |
461 | && source_desc->reference.opcode == AML_LOAD_OP) { | 464 | && source_desc->reference.class == ACPI_REFCLASS_TABLE) { |
462 | 465 | ||
463 | /* This is a DDBHandle, just add a reference to it */ | 466 | /* This is a DDBHandle, just add a reference to it */ |
464 | 467 | ||
@@ -553,7 +556,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, | |||
553 | 556 | ||
554 | /* Store the source value into the target buffer byte */ | 557 | /* Store the source value into the target buffer byte */ |
555 | 558 | ||
556 | obj_desc->buffer.pointer[index_desc->reference.offset] = value; | 559 | obj_desc->buffer.pointer[index_desc->reference.value] = value; |
557 | break; | 560 | break; |
558 | 561 | ||
559 | default: | 562 | default: |
diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c index a6d2168b81f9..eef61a00803e 100644 --- a/drivers/acpi/executer/exstoren.c +++ b/drivers/acpi/executer/exstoren.c | |||
@@ -121,7 +121,8 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr, | |||
121 | (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) && | 121 | (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) && |
122 | !((ACPI_GET_OBJECT_TYPE(source_desc) == | 122 | !((ACPI_GET_OBJECT_TYPE(source_desc) == |
123 | ACPI_TYPE_LOCAL_REFERENCE) | 123 | ACPI_TYPE_LOCAL_REFERENCE) |
124 | && (source_desc->reference.opcode == AML_LOAD_OP))) { | 124 | && (source_desc->reference.class == |
125 | ACPI_REFCLASS_TABLE))) { | ||
125 | 126 | ||
126 | /* Conversion successful but still not a valid type */ | 127 | /* Conversion successful but still not a valid type */ |
127 | 128 | ||
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 2655bc1b4eeb..60d54d1f6b19 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -265,7 +265,7 @@ static int acpi_fan_add(struct acpi_device *device) | |||
265 | 265 | ||
266 | dev_info(&device->dev, "registered as cooling_device%d\n", cdev->id); | 266 | dev_info(&device->dev, "registered as cooling_device%d\n", cdev->id); |
267 | 267 | ||
268 | acpi_driver_data(device) = cdev; | 268 | device->driver_data = cdev; |
269 | result = sysfs_create_link(&device->dev.kobj, | 269 | result = sysfs_create_link(&device->dev.kobj, |
270 | &cdev->device.kobj, | 270 | &cdev->device.kobj, |
271 | "thermal_cooling"); | 271 | "thermal_cooling"); |
@@ -327,8 +327,8 @@ static int acpi_fan_resume(struct acpi_device *device) | |||
327 | 327 | ||
328 | result = acpi_bus_get_power(device->handle, &power_state); | 328 | result = acpi_bus_get_power(device->handle, &power_state); |
329 | if (result) { | 329 | if (result) { |
330 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 330 | printk(KERN_ERR PREFIX |
331 | "Error reading fan power state\n")); | 331 | "Error reading fan power state\n"); |
332 | return result; | 332 | return result; |
333 | } | 333 | } |
334 | 334 | ||
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c index dba3cfbe8cba..25dccdf179b9 100644 --- a/drivers/acpi/hardware/hwsleep.c +++ b/drivers/acpi/hardware/hwsleep.c | |||
@@ -78,19 +78,17 @@ acpi_set_firmware_waking_vector(acpi_physical_address physical_address) | |||
78 | return_ACPI_STATUS(status); | 78 | return_ACPI_STATUS(status); |
79 | } | 79 | } |
80 | 80 | ||
81 | /* Set the vector */ | 81 | /* |
82 | * According to the ACPI specification 2.0c and later, the 64-bit | ||
83 | * waking vector should be cleared and the 32-bit waking vector should | ||
84 | * be used, unless we want the wake-up code to be called by the BIOS in | ||
85 | * Protected Mode. Some systems (for example HP dv5-1004nr) are known | ||
86 | * to fail to resume if the 64-bit vector is used. | ||
87 | */ | ||
88 | if (facs->version >= 1) | ||
89 | facs->xfirmware_waking_vector = 0; | ||
82 | 90 | ||
83 | if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) { | 91 | facs->firmware_waking_vector = (u32)physical_address; |
84 | /* | ||
85 | * ACPI 1.0 FACS or short table or optional X_ field is zero | ||
86 | */ | ||
87 | facs->firmware_waking_vector = (u32) physical_address; | ||
88 | } else { | ||
89 | /* | ||
90 | * ACPI 2.0 FACS with valid X_ field | ||
91 | */ | ||
92 | facs->xfirmware_waking_vector = physical_address; | ||
93 | } | ||
94 | 92 | ||
95 | return_ACPI_STATUS(AE_OK); | 93 | return_ACPI_STATUS(AE_OK); |
96 | } | 94 | } |
@@ -134,20 +132,7 @@ acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) | |||
134 | } | 132 | } |
135 | 133 | ||
136 | /* Get the vector */ | 134 | /* Get the vector */ |
137 | 135 | *physical_address = (acpi_physical_address)facs->firmware_waking_vector; | |
138 | if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) { | ||
139 | /* | ||
140 | * ACPI 1.0 FACS or short table or optional X_ field is zero | ||
141 | */ | ||
142 | *physical_address = | ||
143 | (acpi_physical_address) facs->firmware_waking_vector; | ||
144 | } else { | ||
145 | /* | ||
146 | * ACPI 2.0 FACS with valid X_ field | ||
147 | */ | ||
148 | *physical_address = | ||
149 | (acpi_physical_address) facs->xfirmware_waking_vector; | ||
150 | } | ||
151 | 136 | ||
152 | return_ACPI_STATUS(AE_OK); | 137 | return_ACPI_STATUS(AE_OK); |
153 | } | 138 | } |
@@ -627,6 +612,13 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) | |||
627 | } | 612 | } |
628 | /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */ | 613 | /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */ |
629 | 614 | ||
615 | /* | ||
616 | * Some BIOSes assume that WAK_STS will be cleared on resume and use | ||
617 | * it to determine whether the system is rebooting or resuming. Clear | ||
618 | * it for compatibility. | ||
619 | */ | ||
620 | acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1); | ||
621 | |||
630 | acpi_gbl_system_awake_and_running = TRUE; | 622 | acpi_gbl_system_awake_and_running = TRUE; |
631 | 623 | ||
632 | /* Enable power button */ | 624 | /* Enable power button */ |
diff --git a/drivers/acpi/namespace/Makefile b/drivers/acpi/namespace/Makefile index 3f63d3640696..371a2daf837f 100644 --- a/drivers/acpi/namespace/Makefile +++ b/drivers/acpi/namespace/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | obj-y := nsaccess.o nsload.o nssearch.o nsxfeval.o \ | 5 | obj-y := nsaccess.o nsload.o nssearch.o nsxfeval.o \ |
6 | nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \ | 6 | nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \ |
7 | nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \ | 7 | nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \ |
8 | nsparse.o | 8 | nsparse.o nspredef.o |
9 | 9 | ||
10 | obj-$(ACPI_FUTURE_USAGE) += nsdumpdv.o | 10 | obj-$(ACPI_FUTURE_USAGE) += nsdumpdv.o |
11 | 11 | ||
diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c index 0ab22004728a..cc0ae39440e4 100644 --- a/drivers/acpi/namespace/nsdump.c +++ b/drivers/acpi/namespace/nsdump.c | |||
@@ -43,7 +43,6 @@ | |||
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acnamesp.h> | 45 | #include <acpi/acnamesp.h> |
46 | #include <acpi/acparser.h> | ||
47 | 46 | ||
48 | #define _COMPONENT ACPI_NAMESPACE | 47 | #define _COMPONENT ACPI_NAMESPACE |
49 | ACPI_MODULE_NAME("nsdump") | 48 | ACPI_MODULE_NAME("nsdump") |
@@ -334,9 +333,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, | |||
334 | case ACPI_TYPE_LOCAL_REFERENCE: | 333 | case ACPI_TYPE_LOCAL_REFERENCE: |
335 | 334 | ||
336 | acpi_os_printf("[%s]\n", | 335 | acpi_os_printf("[%s]\n", |
337 | acpi_ps_get_opcode_name(obj_desc-> | 336 | acpi_ut_get_reference_name(obj_desc)); |
338 | reference. | ||
339 | opcode)); | ||
340 | break; | 337 | break; |
341 | 338 | ||
342 | case ACPI_TYPE_BUFFER_FIELD: | 339 | case ACPI_TYPE_BUFFER_FIELD: |
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index d369164e00b0..4cdf03ac2b46 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/namespace/nseval.c | |||
@@ -78,6 +78,7 @@ ACPI_MODULE_NAME("nseval") | |||
78 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | 78 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) |
79 | { | 79 | { |
80 | acpi_status status; | 80 | acpi_status status; |
81 | struct acpi_namespace_node *node; | ||
81 | 82 | ||
82 | ACPI_FUNCTION_TRACE(ns_evaluate); | 83 | ACPI_FUNCTION_TRACE(ns_evaluate); |
83 | 84 | ||
@@ -117,6 +118,8 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | |||
117 | info->resolved_node, | 118 | info->resolved_node, |
118 | acpi_ns_get_attached_object(info->resolved_node))); | 119 | acpi_ns_get_attached_object(info->resolved_node))); |
119 | 120 | ||
121 | node = info->resolved_node; | ||
122 | |||
120 | /* | 123 | /* |
121 | * Two major cases here: | 124 | * Two major cases here: |
122 | * | 125 | * |
@@ -148,21 +151,22 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | |||
148 | info->param_count++; | 151 | info->param_count++; |
149 | } | 152 | } |
150 | 153 | ||
151 | /* Error if too few arguments were passed in */ | 154 | /* |
155 | * Warning if too few or too many arguments have been passed by the | ||
156 | * caller. We don't want to abort here with an error because an | ||
157 | * incorrect number of arguments may not cause the method to fail. | ||
158 | * However, the method will fail if there are too few arguments passed | ||
159 | * and the method attempts to use one of the missing ones. | ||
160 | */ | ||
152 | 161 | ||
153 | if (info->param_count < info->obj_desc->method.param_count) { | 162 | if (info->param_count < info->obj_desc->method.param_count) { |
154 | ACPI_ERROR((AE_INFO, | 163 | ACPI_WARNING((AE_INFO, |
155 | "Insufficient arguments - " | 164 | "Insufficient arguments - " |
156 | "method [%4.4s] needs %d, found %d", | 165 | "method [%4.4s] needs %d, found %d", |
157 | acpi_ut_get_node_name(info->resolved_node), | 166 | acpi_ut_get_node_name(info->resolved_node), |
158 | info->obj_desc->method.param_count, | 167 | info->obj_desc->method.param_count, |
159 | info->param_count)); | 168 | info->param_count)); |
160 | return_ACPI_STATUS(AE_MISSING_ARGUMENTS); | 169 | } else if (info->param_count > |
161 | } | ||
162 | |||
163 | /* Just a warning if too many arguments */ | ||
164 | |||
165 | else if (info->param_count > | ||
166 | info->obj_desc->method.param_count) { | 170 | info->obj_desc->method.param_count) { |
167 | ACPI_WARNING((AE_INFO, | 171 | ACPI_WARNING((AE_INFO, |
168 | "Excess arguments - " | 172 | "Excess arguments - " |
@@ -195,7 +199,28 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | |||
195 | } else { | 199 | } else { |
196 | /* | 200 | /* |
197 | * 2) Object is not a method, return its current value | 201 | * 2) Object is not a method, return its current value |
202 | * | ||
203 | * Disallow certain object types. For these, "evaluation" is undefined. | ||
198 | */ | 204 | */ |
205 | switch (info->resolved_node->type) { | ||
206 | case ACPI_TYPE_DEVICE: | ||
207 | case ACPI_TYPE_EVENT: | ||
208 | case ACPI_TYPE_MUTEX: | ||
209 | case ACPI_TYPE_REGION: | ||
210 | case ACPI_TYPE_THERMAL: | ||
211 | case ACPI_TYPE_LOCAL_SCOPE: | ||
212 | |||
213 | ACPI_ERROR((AE_INFO, | ||
214 | "[%4.4s] Evaluation of object type [%s] is not supported", | ||
215 | info->resolved_node->name.ascii, | ||
216 | acpi_ut_get_type_name(info->resolved_node-> | ||
217 | type))); | ||
218 | |||
219 | return_ACPI_STATUS(AE_TYPE); | ||
220 | |||
221 | default: | ||
222 | break; | ||
223 | } | ||
199 | 224 | ||
200 | /* | 225 | /* |
201 | * Objects require additional resolution steps (e.g., the Node may be | 226 | * Objects require additional resolution steps (e.g., the Node may be |
@@ -239,9 +264,35 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | |||
239 | } | 264 | } |
240 | } | 265 | } |
241 | 266 | ||
242 | /* | 267 | /* Validation of return values for ACPI-predefined methods and objects */ |
243 | * Check if there is a return value that must be dealt with | 268 | |
244 | */ | 269 | if ((status == AE_OK) || (status == AE_CTRL_RETURN_VALUE)) { |
270 | /* | ||
271 | * If this is the first evaluation, check the return value. This | ||
272 | * ensures that any warnings will only be emitted during the very | ||
273 | * first evaluation of the object. | ||
274 | */ | ||
275 | if (!(node->flags & ANOBJ_EVALUATED)) { | ||
276 | /* | ||
277 | * Check for a predefined ACPI name. If found, validate the | ||
278 | * returned object. | ||
279 | * | ||
280 | * Note: Ignore return status for now, emit warnings if there are | ||
281 | * problems with the returned object. May change later to abort | ||
282 | * the method on invalid return object. | ||
283 | */ | ||
284 | (void)acpi_ns_check_predefined_names(node, | ||
285 | info-> | ||
286 | return_object); | ||
287 | } | ||
288 | |||
289 | /* Mark the node as having been evaluated */ | ||
290 | |||
291 | node->flags |= ANOBJ_EVALUATED; | ||
292 | } | ||
293 | |||
294 | /* Check if there is a return value that must be dealt with */ | ||
295 | |||
245 | if (status == AE_CTRL_RETURN_VALUE) { | 296 | if (status == AE_CTRL_RETURN_VALUE) { |
246 | 297 | ||
247 | /* If caller does not want the return value, delete it */ | 298 | /* If caller does not want the return value, delete it */ |
diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c index bd5773878009..42a39a7c96e9 100644 --- a/drivers/acpi/namespace/nsnames.c +++ b/drivers/acpi/namespace/nsnames.c | |||
@@ -115,7 +115,6 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node, | |||
115 | return (AE_OK); | 115 | return (AE_OK); |
116 | } | 116 | } |
117 | 117 | ||
118 | #ifdef ACPI_DEBUG_OUTPUT | ||
119 | /******************************************************************************* | 118 | /******************************************************************************* |
120 | * | 119 | * |
121 | * FUNCTION: acpi_ns_get_external_pathname | 120 | * FUNCTION: acpi_ns_get_external_pathname |
@@ -142,7 +141,7 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) | |||
142 | 141 | ||
143 | size = acpi_ns_get_pathname_length(node); | 142 | size = acpi_ns_get_pathname_length(node); |
144 | if (!size) { | 143 | if (!size) { |
145 | return (NULL); | 144 | return_PTR(NULL); |
146 | } | 145 | } |
147 | 146 | ||
148 | /* Allocate a buffer to be returned to caller */ | 147 | /* Allocate a buffer to be returned to caller */ |
@@ -157,12 +156,12 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) | |||
157 | 156 | ||
158 | status = acpi_ns_build_external_path(node, size, name_buffer); | 157 | status = acpi_ns_build_external_path(node, size, name_buffer); |
159 | if (ACPI_FAILURE(status)) { | 158 | if (ACPI_FAILURE(status)) { |
160 | return (NULL); | 159 | ACPI_FREE(name_buffer); |
160 | return_PTR(NULL); | ||
161 | } | 161 | } |
162 | 162 | ||
163 | return_PTR(name_buffer); | 163 | return_PTR(name_buffer); |
164 | } | 164 | } |
165 | #endif | ||
166 | 165 | ||
167 | /******************************************************************************* | 166 | /******************************************************************************* |
168 | * | 167 | * |
diff --git a/drivers/acpi/namespace/nspredef.c b/drivers/acpi/namespace/nspredef.c new file mode 100644 index 000000000000..0f17cf0898c9 --- /dev/null +++ b/drivers/acpi/namespace/nspredef.c | |||
@@ -0,0 +1,900 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: nspredef - Validation of ACPI predefined methods and objects | ||
4 | * $Revision: 1.1 $ | ||
5 | * | ||
6 | *****************************************************************************/ | ||
7 | |||
8 | /* | ||
9 | * Copyright (C) 2000 - 2008, Intel Corp. | ||
10 | * All rights reserved. | ||
11 | * | ||
12 | * Redistribution and use in source and binary forms, with or without | ||
13 | * modification, are permitted provided that the following conditions | ||
14 | * are met: | ||
15 | * 1. Redistributions of source code must retain the above copyright | ||
16 | * notice, this list of conditions, and the following disclaimer, | ||
17 | * without modification. | ||
18 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
19 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
20 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
21 | * including a substantially similar Disclaimer requirement for further | ||
22 | * binary redistribution. | ||
23 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
24 | * of any contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * Alternatively, this software may be distributed under the terms of the | ||
28 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
29 | * Software Foundation. | ||
30 | * | ||
31 | * NO WARRANTY | ||
32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
36 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
37 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
38 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
39 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
40 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
41 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
42 | * POSSIBILITY OF SUCH DAMAGES. | ||
43 | */ | ||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/acnamesp.h> | ||
47 | #include <acpi/acpredef.h> | ||
48 | |||
49 | #define _COMPONENT ACPI_NAMESPACE | ||
50 | ACPI_MODULE_NAME("nspredef") | ||
51 | |||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * This module validates predefined ACPI objects that appear in the namespace, | ||
55 | * at the time they are evaluated (via acpi_evaluate_object). The purpose of this | ||
56 | * validation is to detect problems with BIOS-exposed predefined ACPI objects | ||
57 | * before the results are returned to the ACPI-related drivers. | ||
58 | * | ||
59 | * There are several areas that are validated: | ||
60 | * | ||
61 | * 1) The number of input arguments as defined by the method/object in the | ||
62 | * ASL is validated against the ACPI specification. | ||
63 | * 2) The type of the return object (if any) is validated against the ACPI | ||
64 | * specification. | ||
65 | * 3) For returned package objects, the count of package elements is | ||
66 | * validated, as well as the type of each package element. Nested | ||
67 | * packages are supported. | ||
68 | * | ||
69 | * For any problems found, a warning message is issued. | ||
70 | * | ||
71 | ******************************************************************************/ | ||
72 | /* Local prototypes */ | ||
73 | static acpi_status | ||
74 | acpi_ns_check_package(char *pathname, | ||
75 | union acpi_operand_object *return_object, | ||
76 | const union acpi_predefined_info *predefined); | ||
77 | |||
78 | static acpi_status | ||
79 | acpi_ns_check_package_elements(char *pathname, | ||
80 | union acpi_operand_object **elements, | ||
81 | u8 type1, u32 count1, u8 type2, u32 count2); | ||
82 | |||
83 | static acpi_status | ||
84 | acpi_ns_check_object_type(char *pathname, | ||
85 | union acpi_operand_object *return_object, | ||
86 | u32 expected_btypes, u32 package_index); | ||
87 | |||
88 | static acpi_status | ||
89 | acpi_ns_check_reference(char *pathname, | ||
90 | union acpi_operand_object *return_object); | ||
91 | |||
92 | /* | ||
93 | * Names for the types that can be returned by the predefined objects. | ||
94 | * Used for warning messages. Must be in the same order as the ACPI_RTYPEs | ||
95 | */ | ||
96 | static const char *acpi_rtype_names[] = { | ||
97 | "/Integer", | ||
98 | "/String", | ||
99 | "/Buffer", | ||
100 | "/Package", | ||
101 | "/Reference", | ||
102 | }; | ||
103 | |||
104 | #define ACPI_NOT_PACKAGE ACPI_UINT32_MAX | ||
105 | |||
106 | /******************************************************************************* | ||
107 | * | ||
108 | * FUNCTION: acpi_ns_check_predefined_names | ||
109 | * | ||
110 | * PARAMETERS: Node - Namespace node for the method/object | ||
111 | * return_object - Object returned from the evaluation of this | ||
112 | * method/object | ||
113 | * | ||
114 | * RETURN: Status | ||
115 | * | ||
116 | * DESCRIPTION: Check an ACPI name for a match in the predefined name list. | ||
117 | * | ||
118 | ******************************************************************************/ | ||
119 | |||
120 | acpi_status | ||
121 | acpi_ns_check_predefined_names(struct acpi_namespace_node *node, | ||
122 | union acpi_operand_object *return_object) | ||
123 | { | ||
124 | acpi_status status = AE_OK; | ||
125 | const union acpi_predefined_info *predefined; | ||
126 | char *pathname; | ||
127 | |||
128 | /* Match the name for this method/object against the predefined list */ | ||
129 | |||
130 | predefined = acpi_ns_check_for_predefined_name(node); | ||
131 | if (!predefined) { | ||
132 | |||
133 | /* Name was not one of the predefined names */ | ||
134 | |||
135 | return (AE_OK); | ||
136 | } | ||
137 | |||
138 | /* Get the full pathname to the object, for use in error messages */ | ||
139 | |||
140 | pathname = acpi_ns_get_external_pathname(node); | ||
141 | if (!pathname) { | ||
142 | pathname = ACPI_CAST_PTR(char, predefined->info.name); | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * Check that the parameter count for this method is in accordance | ||
147 | * with the ACPI specification. | ||
148 | */ | ||
149 | acpi_ns_check_parameter_count(pathname, node, predefined); | ||
150 | |||
151 | /* | ||
152 | * If there is no return value, check if we require a return value for | ||
153 | * this predefined name. Either one return value is expected, or none, | ||
154 | * for both methods and other objects. | ||
155 | * | ||
156 | * Exit now if there is no return object. Warning if one was expected. | ||
157 | */ | ||
158 | if (!return_object) { | ||
159 | if ((predefined->info.expected_btypes) && | ||
160 | (!(predefined->info.expected_btypes & ACPI_RTYPE_NONE))) { | ||
161 | ACPI_ERROR((AE_INFO, | ||
162 | "%s: Missing expected return value", | ||
163 | pathname)); | ||
164 | |||
165 | status = AE_AML_NO_RETURN_VALUE; | ||
166 | } | ||
167 | goto exit; | ||
168 | } | ||
169 | |||
170 | /* | ||
171 | * We have a return value, but if one wasn't expected, just exit, this is | ||
172 | * not a problem | ||
173 | * | ||
174 | * For example, if "Implicit return value" is enabled, methods will | ||
175 | * always return a value | ||
176 | */ | ||
177 | if (!predefined->info.expected_btypes) { | ||
178 | goto exit; | ||
179 | } | ||
180 | |||
181 | /* | ||
182 | * Check that the type of the return object is what is expected for | ||
183 | * this predefined name | ||
184 | */ | ||
185 | status = acpi_ns_check_object_type(pathname, return_object, | ||
186 | predefined->info.expected_btypes, | ||
187 | ACPI_NOT_PACKAGE); | ||
188 | if (ACPI_FAILURE(status)) { | ||
189 | goto exit; | ||
190 | } | ||
191 | |||
192 | /* For returned Package objects, check the type of all sub-objects */ | ||
193 | |||
194 | if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_PACKAGE) { | ||
195 | status = | ||
196 | acpi_ns_check_package(pathname, return_object, predefined); | ||
197 | } | ||
198 | |||
199 | exit: | ||
200 | if (pathname) { | ||
201 | ACPI_FREE(pathname); | ||
202 | } | ||
203 | |||
204 | return (status); | ||
205 | } | ||
206 | |||
207 | /******************************************************************************* | ||
208 | * | ||
209 | * FUNCTION: acpi_ns_check_parameter_count | ||
210 | * | ||
211 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | ||
212 | * Node - Namespace node for the method/object | ||
213 | * Predefined - Pointer to entry in predefined name table | ||
214 | * | ||
215 | * RETURN: None | ||
216 | * | ||
217 | * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a | ||
218 | * predefined name is what is expected (i.e., what is defined in | ||
219 | * the ACPI specification for this predefined name.) | ||
220 | * | ||
221 | ******************************************************************************/ | ||
222 | |||
223 | void | ||
224 | acpi_ns_check_parameter_count(char *pathname, | ||
225 | struct acpi_namespace_node *node, | ||
226 | const union acpi_predefined_info *predefined) | ||
227 | { | ||
228 | u32 param_count; | ||
229 | u32 required_params_current; | ||
230 | u32 required_params_old; | ||
231 | |||
232 | /* | ||
233 | * Check that the ASL-defined parameter count is what is expected for | ||
234 | * this predefined name. | ||
235 | * | ||
236 | * Methods have 0-7 parameters. All other types have zero. | ||
237 | */ | ||
238 | param_count = 0; | ||
239 | if (node->type == ACPI_TYPE_METHOD) { | ||
240 | param_count = node->object->method.param_count; | ||
241 | } | ||
242 | |||
243 | /* Validate parameter count - allow two different legal counts (_SCP) */ | ||
244 | |||
245 | required_params_current = predefined->info.param_count & 0x0F; | ||
246 | required_params_old = predefined->info.param_count >> 4; | ||
247 | |||
248 | if ((param_count != required_params_current) && | ||
249 | (param_count != required_params_old)) { | ||
250 | ACPI_WARNING((AE_INFO, | ||
251 | "%s: Parameter count mismatch - ASL declared %d, expected %d", | ||
252 | pathname, param_count, required_params_current)); | ||
253 | } | ||
254 | } | ||
255 | |||
256 | /******************************************************************************* | ||
257 | * | ||
258 | * FUNCTION: acpi_ns_check_for_predefined_name | ||
259 | * | ||
260 | * PARAMETERS: Node - Namespace node for the method/object | ||
261 | * | ||
262 | * RETURN: Pointer to entry in predefined table. NULL indicates not found. | ||
263 | * | ||
264 | * DESCRIPTION: Check an object name against the predefined object list. | ||
265 | * | ||
266 | ******************************************************************************/ | ||
267 | |||
268 | const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct | ||
269 | acpi_namespace_node | ||
270 | *node) | ||
271 | { | ||
272 | const union acpi_predefined_info *this_name; | ||
273 | |||
274 | /* Quick check for a predefined name, first character must be underscore */ | ||
275 | |||
276 | if (node->name.ascii[0] != '_') { | ||
277 | return (NULL); | ||
278 | } | ||
279 | |||
280 | /* Search info table for a predefined method/object name */ | ||
281 | |||
282 | this_name = predefined_names; | ||
283 | while (this_name->info.name[0]) { | ||
284 | if (ACPI_COMPARE_NAME(node->name.ascii, this_name->info.name)) { | ||
285 | |||
286 | /* Return pointer to this table entry */ | ||
287 | |||
288 | return (this_name); | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * Skip next entry in the table if this name returns a Package | ||
293 | * (next entry contains the package info) | ||
294 | */ | ||
295 | if (this_name->info.expected_btypes & ACPI_RTYPE_PACKAGE) { | ||
296 | this_name++; | ||
297 | } | ||
298 | |||
299 | this_name++; | ||
300 | } | ||
301 | |||
302 | return (NULL); | ||
303 | } | ||
304 | |||
305 | /******************************************************************************* | ||
306 | * | ||
307 | * FUNCTION: acpi_ns_check_package | ||
308 | * | ||
309 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | ||
310 | * return_object - Object returned from the evaluation of a | ||
311 | * method or object | ||
312 | * Predefined - Pointer to entry in predefined name table | ||
313 | * | ||
314 | * RETURN: Status | ||
315 | * | ||
316 | * DESCRIPTION: Check a returned package object for the correct count and | ||
317 | * correct type of all sub-objects. | ||
318 | * | ||
319 | ******************************************************************************/ | ||
320 | |||
321 | static acpi_status | ||
322 | acpi_ns_check_package(char *pathname, | ||
323 | union acpi_operand_object *return_object, | ||
324 | const union acpi_predefined_info *predefined) | ||
325 | { | ||
326 | const union acpi_predefined_info *package; | ||
327 | union acpi_operand_object *sub_package; | ||
328 | union acpi_operand_object **elements; | ||
329 | union acpi_operand_object **sub_elements; | ||
330 | acpi_status status; | ||
331 | u32 expected_count; | ||
332 | u32 count; | ||
333 | u32 i; | ||
334 | u32 j; | ||
335 | |||
336 | ACPI_FUNCTION_NAME(ns_check_package); | ||
337 | |||
338 | /* The package info for this name is in the next table entry */ | ||
339 | |||
340 | package = predefined + 1; | ||
341 | |||
342 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
343 | "%s Validating return Package of Type %X, Count %X\n", | ||
344 | pathname, package->ret_info.type, | ||
345 | return_object->package.count)); | ||
346 | |||
347 | /* Extract package count and elements array */ | ||
348 | |||
349 | elements = return_object->package.elements; | ||
350 | count = return_object->package.count; | ||
351 | |||
352 | /* The package must have at least one element, else invalid */ | ||
353 | |||
354 | if (!count) { | ||
355 | ACPI_WARNING((AE_INFO, | ||
356 | "%s: Return Package has no elements (empty)", | ||
357 | pathname)); | ||
358 | |||
359 | return (AE_AML_OPERAND_VALUE); | ||
360 | } | ||
361 | |||
362 | /* | ||
363 | * Decode the type of the expected package contents | ||
364 | * | ||
365 | * PTYPE1 packages contain no subpackages | ||
366 | * PTYPE2 packages contain sub-packages | ||
367 | */ | ||
368 | switch (package->ret_info.type) { | ||
369 | case ACPI_PTYPE1_FIXED: | ||
370 | |||
371 | /* | ||
372 | * The package count is fixed and there are no sub-packages | ||
373 | * | ||
374 | * If package is too small, exit. | ||
375 | * If package is larger than expected, issue warning but continue | ||
376 | */ | ||
377 | expected_count = | ||
378 | package->ret_info.count1 + package->ret_info.count2; | ||
379 | if (count < expected_count) { | ||
380 | goto package_too_small; | ||
381 | } else if (count > expected_count) { | ||
382 | ACPI_WARNING((AE_INFO, | ||
383 | "%s: Return Package is larger than needed - " | ||
384 | "found %u, expected %u", pathname, count, | ||
385 | expected_count)); | ||
386 | } | ||
387 | |||
388 | /* Validate all elements of the returned package */ | ||
389 | |||
390 | status = acpi_ns_check_package_elements(pathname, elements, | ||
391 | package->ret_info. | ||
392 | object_type1, | ||
393 | package->ret_info. | ||
394 | count1, | ||
395 | package->ret_info. | ||
396 | object_type2, | ||
397 | package->ret_info. | ||
398 | count2); | ||
399 | if (ACPI_FAILURE(status)) { | ||
400 | return (status); | ||
401 | } | ||
402 | break; | ||
403 | |||
404 | case ACPI_PTYPE1_VAR: | ||
405 | |||
406 | /* | ||
407 | * The package count is variable, there are no sub-packages, and all | ||
408 | * elements must be of the same type | ||
409 | */ | ||
410 | for (i = 0; i < count; i++) { | ||
411 | status = acpi_ns_check_object_type(pathname, *elements, | ||
412 | package->ret_info. | ||
413 | object_type1, i); | ||
414 | if (ACPI_FAILURE(status)) { | ||
415 | return (status); | ||
416 | } | ||
417 | elements++; | ||
418 | } | ||
419 | break; | ||
420 | |||
421 | case ACPI_PTYPE1_OPTION: | ||
422 | |||
423 | /* | ||
424 | * The package count is variable, there are no sub-packages. There are | ||
425 | * a fixed number of required elements, and a variable number of | ||
426 | * optional elements. | ||
427 | * | ||
428 | * Check if package is at least as large as the minimum required | ||
429 | */ | ||
430 | expected_count = package->ret_info3.count; | ||
431 | if (count < expected_count) { | ||
432 | goto package_too_small; | ||
433 | } | ||
434 | |||
435 | /* Variable number of sub-objects */ | ||
436 | |||
437 | for (i = 0; i < count; i++) { | ||
438 | if (i < package->ret_info3.count) { | ||
439 | |||
440 | /* These are the required package elements (0, 1, or 2) */ | ||
441 | |||
442 | status = | ||
443 | acpi_ns_check_object_type(pathname, | ||
444 | *elements, | ||
445 | package-> | ||
446 | ret_info3. | ||
447 | object_type[i], | ||
448 | i); | ||
449 | if (ACPI_FAILURE(status)) { | ||
450 | return (status); | ||
451 | } | ||
452 | } else { | ||
453 | /* These are the optional package elements */ | ||
454 | |||
455 | status = | ||
456 | acpi_ns_check_object_type(pathname, | ||
457 | *elements, | ||
458 | package-> | ||
459 | ret_info3. | ||
460 | tail_object_type, | ||
461 | i); | ||
462 | if (ACPI_FAILURE(status)) { | ||
463 | return (status); | ||
464 | } | ||
465 | } | ||
466 | elements++; | ||
467 | } | ||
468 | break; | ||
469 | |||
470 | case ACPI_PTYPE2_PKG_COUNT: | ||
471 | |||
472 | /* First element is the (Integer) count of sub-packages to follow */ | ||
473 | |||
474 | status = acpi_ns_check_object_type(pathname, *elements, | ||
475 | ACPI_RTYPE_INTEGER, 0); | ||
476 | if (ACPI_FAILURE(status)) { | ||
477 | return (status); | ||
478 | } | ||
479 | |||
480 | /* | ||
481 | * Count cannot be larger than the parent package length, but allow it | ||
482 | * to be smaller. The >= accounts for the Integer above. | ||
483 | */ | ||
484 | expected_count = (u32) (*elements)->integer.value; | ||
485 | if (expected_count >= count) { | ||
486 | goto package_too_small; | ||
487 | } | ||
488 | |||
489 | count = expected_count; | ||
490 | elements++; | ||
491 | |||
492 | /* Now we can walk the sub-packages */ | ||
493 | |||
494 | /*lint -fallthrough */ | ||
495 | |||
496 | case ACPI_PTYPE2: | ||
497 | case ACPI_PTYPE2_FIXED: | ||
498 | case ACPI_PTYPE2_MIN: | ||
499 | case ACPI_PTYPE2_COUNT: | ||
500 | |||
501 | /* | ||
502 | * These types all return a single package that consists of a variable | ||
503 | * number of sub-packages | ||
504 | */ | ||
505 | for (i = 0; i < count; i++) { | ||
506 | sub_package = *elements; | ||
507 | sub_elements = sub_package->package.elements; | ||
508 | |||
509 | /* Each sub-object must be of type Package */ | ||
510 | |||
511 | status = | ||
512 | acpi_ns_check_object_type(pathname, sub_package, | ||
513 | ACPI_RTYPE_PACKAGE, i); | ||
514 | if (ACPI_FAILURE(status)) { | ||
515 | return (status); | ||
516 | } | ||
517 | |||
518 | /* Examine the different types of sub-packages */ | ||
519 | |||
520 | switch (package->ret_info.type) { | ||
521 | case ACPI_PTYPE2: | ||
522 | case ACPI_PTYPE2_PKG_COUNT: | ||
523 | |||
524 | /* Each subpackage has a fixed number of elements */ | ||
525 | |||
526 | expected_count = | ||
527 | package->ret_info.count1 + | ||
528 | package->ret_info.count2; | ||
529 | if (sub_package->package.count != | ||
530 | expected_count) { | ||
531 | count = sub_package->package.count; | ||
532 | goto package_too_small; | ||
533 | } | ||
534 | |||
535 | status = | ||
536 | acpi_ns_check_package_elements(pathname, | ||
537 | sub_elements, | ||
538 | package-> | ||
539 | ret_info. | ||
540 | object_type1, | ||
541 | package-> | ||
542 | ret_info. | ||
543 | count1, | ||
544 | package-> | ||
545 | ret_info. | ||
546 | object_type2, | ||
547 | package-> | ||
548 | ret_info. | ||
549 | count2); | ||
550 | if (ACPI_FAILURE(status)) { | ||
551 | return (status); | ||
552 | } | ||
553 | break; | ||
554 | |||
555 | case ACPI_PTYPE2_FIXED: | ||
556 | |||
557 | /* Each sub-package has a fixed length */ | ||
558 | |||
559 | expected_count = package->ret_info2.count; | ||
560 | if (sub_package->package.count < expected_count) { | ||
561 | count = sub_package->package.count; | ||
562 | goto package_too_small; | ||
563 | } | ||
564 | |||
565 | /* Check the type of each sub-package element */ | ||
566 | |||
567 | for (j = 0; j < expected_count; j++) { | ||
568 | status = | ||
569 | acpi_ns_check_object_type(pathname, | ||
570 | sub_elements | ||
571 | [j], | ||
572 | package-> | ||
573 | ret_info2. | ||
574 | object_type | ||
575 | [j], j); | ||
576 | if (ACPI_FAILURE(status)) { | ||
577 | return (status); | ||
578 | } | ||
579 | } | ||
580 | break; | ||
581 | |||
582 | case ACPI_PTYPE2_MIN: | ||
583 | |||
584 | /* Each sub-package has a variable but minimum length */ | ||
585 | |||
586 | expected_count = package->ret_info.count1; | ||
587 | if (sub_package->package.count < expected_count) { | ||
588 | count = sub_package->package.count; | ||
589 | goto package_too_small; | ||
590 | } | ||
591 | |||
592 | /* Check the type of each sub-package element */ | ||
593 | |||
594 | status = | ||
595 | acpi_ns_check_package_elements(pathname, | ||
596 | sub_elements, | ||
597 | package-> | ||
598 | ret_info. | ||
599 | object_type1, | ||
600 | sub_package-> | ||
601 | package. | ||
602 | count, 0, 0); | ||
603 | if (ACPI_FAILURE(status)) { | ||
604 | return (status); | ||
605 | } | ||
606 | break; | ||
607 | |||
608 | case ACPI_PTYPE2_COUNT: | ||
609 | |||
610 | /* First element is the (Integer) count of elements to follow */ | ||
611 | |||
612 | status = | ||
613 | acpi_ns_check_object_type(pathname, | ||
614 | *sub_elements, | ||
615 | ACPI_RTYPE_INTEGER, | ||
616 | 0); | ||
617 | if (ACPI_FAILURE(status)) { | ||
618 | return (status); | ||
619 | } | ||
620 | |||
621 | /* Make sure package is large enough for the Count */ | ||
622 | |||
623 | expected_count = | ||
624 | (u32) (*sub_elements)->integer.value; | ||
625 | if (sub_package->package.count < expected_count) { | ||
626 | count = sub_package->package.count; | ||
627 | goto package_too_small; | ||
628 | } | ||
629 | |||
630 | /* Check the type of each sub-package element */ | ||
631 | |||
632 | status = | ||
633 | acpi_ns_check_package_elements(pathname, | ||
634 | (sub_elements | ||
635 | + 1), | ||
636 | package-> | ||
637 | ret_info. | ||
638 | object_type1, | ||
639 | (expected_count | ||
640 | - 1), 0, 0); | ||
641 | if (ACPI_FAILURE(status)) { | ||
642 | return (status); | ||
643 | } | ||
644 | break; | ||
645 | |||
646 | default: | ||
647 | break; | ||
648 | } | ||
649 | |||
650 | elements++; | ||
651 | } | ||
652 | break; | ||
653 | |||
654 | default: | ||
655 | |||
656 | /* Should not get here if predefined info table is correct */ | ||
657 | |||
658 | ACPI_WARNING((AE_INFO, | ||
659 | "%s: Invalid internal return type in table entry: %X", | ||
660 | pathname, package->ret_info.type)); | ||
661 | |||
662 | return (AE_AML_INTERNAL); | ||
663 | } | ||
664 | |||
665 | return (AE_OK); | ||
666 | |||
667 | package_too_small: | ||
668 | |||
669 | /* Error exit for the case with an incorrect package count */ | ||
670 | |||
671 | ACPI_WARNING((AE_INFO, "%s: Return Package is too small - " | ||
672 | "found %u, expected %u", pathname, count, | ||
673 | expected_count)); | ||
674 | |||
675 | return (AE_AML_OPERAND_VALUE); | ||
676 | } | ||
677 | |||
678 | /******************************************************************************* | ||
679 | * | ||
680 | * FUNCTION: acpi_ns_check_package_elements | ||
681 | * | ||
682 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | ||
683 | * Elements - Pointer to the package elements array | ||
684 | * Type1 - Object type for first group | ||
685 | * Count1 - Count for first group | ||
686 | * Type2 - Object type for second group | ||
687 | * Count2 - Count for second group | ||
688 | * | ||
689 | * RETURN: Status | ||
690 | * | ||
691 | * DESCRIPTION: Check that all elements of a package are of the correct object | ||
692 | * type. Supports up to two groups of different object types. | ||
693 | * | ||
694 | ******************************************************************************/ | ||
695 | |||
696 | static acpi_status | ||
697 | acpi_ns_check_package_elements(char *pathname, | ||
698 | union acpi_operand_object **elements, | ||
699 | u8 type1, u32 count1, u8 type2, u32 count2) | ||
700 | { | ||
701 | union acpi_operand_object **this_element = elements; | ||
702 | acpi_status status; | ||
703 | u32 i; | ||
704 | |||
705 | /* | ||
706 | * Up to two groups of package elements are supported by the data | ||
707 | * structure. All elements in each group must be of the same type. | ||
708 | * The second group can have a count of zero. | ||
709 | */ | ||
710 | for (i = 0; i < count1; i++) { | ||
711 | status = acpi_ns_check_object_type(pathname, *this_element, | ||
712 | type1, i); | ||
713 | if (ACPI_FAILURE(status)) { | ||
714 | return (status); | ||
715 | } | ||
716 | this_element++; | ||
717 | } | ||
718 | |||
719 | for (i = 0; i < count2; i++) { | ||
720 | status = acpi_ns_check_object_type(pathname, *this_element, | ||
721 | type2, (i + count1)); | ||
722 | if (ACPI_FAILURE(status)) { | ||
723 | return (status); | ||
724 | } | ||
725 | this_element++; | ||
726 | } | ||
727 | |||
728 | return (AE_OK); | ||
729 | } | ||
730 | |||
731 | /******************************************************************************* | ||
732 | * | ||
733 | * FUNCTION: acpi_ns_check_object_type | ||
734 | * | ||
735 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | ||
736 | * return_object - Object return from the execution of this | ||
737 | * method/object | ||
738 | * expected_btypes - Bitmap of expected return type(s) | ||
739 | * package_index - Index of object within parent package (if | ||
740 | * applicable - ACPI_NOT_PACKAGE otherwise) | ||
741 | * | ||
742 | * RETURN: Status | ||
743 | * | ||
744 | * DESCRIPTION: Check the type of the return object against the expected object | ||
745 | * type(s). Use of Btype allows multiple expected object types. | ||
746 | * | ||
747 | ******************************************************************************/ | ||
748 | |||
749 | static acpi_status | ||
750 | acpi_ns_check_object_type(char *pathname, | ||
751 | union acpi_operand_object *return_object, | ||
752 | u32 expected_btypes, u32 package_index) | ||
753 | { | ||
754 | acpi_status status = AE_OK; | ||
755 | u32 return_btype; | ||
756 | char type_buffer[48]; /* Room for 5 types */ | ||
757 | u32 this_rtype; | ||
758 | u32 i; | ||
759 | u32 j; | ||
760 | |||
761 | /* | ||
762 | * If we get a NULL return_object here, it is a NULL package element, | ||
763 | * and this is always an error. | ||
764 | */ | ||
765 | if (!return_object) { | ||
766 | goto type_error_exit; | ||
767 | } | ||
768 | |||
769 | /* A Namespace node should not get here, but make sure */ | ||
770 | |||
771 | if (ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) { | ||
772 | ACPI_WARNING((AE_INFO, | ||
773 | "%s: Invalid return type - Found a Namespace node [%4.4s] type %s", | ||
774 | pathname, return_object->node.name.ascii, | ||
775 | acpi_ut_get_type_name(return_object->node.type))); | ||
776 | return (AE_AML_OPERAND_TYPE); | ||
777 | } | ||
778 | |||
779 | /* | ||
780 | * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type. | ||
781 | * The bitmapped type allows multiple possible return types. | ||
782 | * | ||
783 | * Note, the cases below must handle all of the possible types returned | ||
784 | * from all of the predefined names (including elements of returned | ||
785 | * packages) | ||
786 | */ | ||
787 | switch (ACPI_GET_OBJECT_TYPE(return_object)) { | ||
788 | case ACPI_TYPE_INTEGER: | ||
789 | return_btype = ACPI_RTYPE_INTEGER; | ||
790 | break; | ||
791 | |||
792 | case ACPI_TYPE_BUFFER: | ||
793 | return_btype = ACPI_RTYPE_BUFFER; | ||
794 | break; | ||
795 | |||
796 | case ACPI_TYPE_STRING: | ||
797 | return_btype = ACPI_RTYPE_STRING; | ||
798 | break; | ||
799 | |||
800 | case ACPI_TYPE_PACKAGE: | ||
801 | return_btype = ACPI_RTYPE_PACKAGE; | ||
802 | break; | ||
803 | |||
804 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
805 | return_btype = ACPI_RTYPE_REFERENCE; | ||
806 | break; | ||
807 | |||
808 | default: | ||
809 | /* Not one of the supported objects, must be incorrect */ | ||
810 | |||
811 | goto type_error_exit; | ||
812 | } | ||
813 | |||
814 | /* Is the object one of the expected types? */ | ||
815 | |||
816 | if (!(return_btype & expected_btypes)) { | ||
817 | goto type_error_exit; | ||
818 | } | ||
819 | |||
820 | /* For reference objects, check that the reference type is correct */ | ||
821 | |||
822 | if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_LOCAL_REFERENCE) { | ||
823 | status = acpi_ns_check_reference(pathname, return_object); | ||
824 | } | ||
825 | |||
826 | return (status); | ||
827 | |||
828 | type_error_exit: | ||
829 | |||
830 | /* Create a string with all expected types for this predefined object */ | ||
831 | |||
832 | j = 1; | ||
833 | type_buffer[0] = 0; | ||
834 | this_rtype = ACPI_RTYPE_INTEGER; | ||
835 | |||
836 | for (i = 0; i < ACPI_NUM_RTYPES; i++) { | ||
837 | |||
838 | /* If one of the expected types, concatenate the name of this type */ | ||
839 | |||
840 | if (expected_btypes & this_rtype) { | ||
841 | ACPI_STRCAT(type_buffer, &acpi_rtype_names[i][j]); | ||
842 | j = 0; /* Use name separator from now on */ | ||
843 | } | ||
844 | this_rtype <<= 1; /* Next Rtype */ | ||
845 | } | ||
846 | |||
847 | if (package_index == ACPI_NOT_PACKAGE) { | ||
848 | ACPI_WARNING((AE_INFO, | ||
849 | "%s: Return type mismatch - found %s, expected %s", | ||
850 | pathname, | ||
851 | acpi_ut_get_object_type_name(return_object), | ||
852 | type_buffer)); | ||
853 | } else { | ||
854 | ACPI_WARNING((AE_INFO, | ||
855 | "%s: Return Package type mismatch at index %u - " | ||
856 | "found %s, expected %s", pathname, package_index, | ||
857 | acpi_ut_get_object_type_name(return_object), | ||
858 | type_buffer)); | ||
859 | } | ||
860 | |||
861 | return (AE_AML_OPERAND_TYPE); | ||
862 | } | ||
863 | |||
864 | /******************************************************************************* | ||
865 | * | ||
866 | * FUNCTION: acpi_ns_check_reference | ||
867 | * | ||
868 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | ||
869 | * return_object - Object returned from the evaluation of a | ||
870 | * method or object | ||
871 | * | ||
872 | * RETURN: Status | ||
873 | * | ||
874 | * DESCRIPTION: Check a returned reference object for the correct reference | ||
875 | * type. The only reference type that can be returned from a | ||
876 | * predefined method is a named reference. All others are invalid. | ||
877 | * | ||
878 | ******************************************************************************/ | ||
879 | |||
880 | static acpi_status | ||
881 | acpi_ns_check_reference(char *pathname, | ||
882 | union acpi_operand_object *return_object) | ||
883 | { | ||
884 | |||
885 | /* | ||
886 | * Check the reference object for the correct reference type (opcode). | ||
887 | * The only type of reference that can be converted to an union acpi_object is | ||
888 | * a reference to a named object (reference class: NAME) | ||
889 | */ | ||
890 | if (return_object->reference.class == ACPI_REFCLASS_NAME) { | ||
891 | return (AE_OK); | ||
892 | } | ||
893 | |||
894 | ACPI_WARNING((AE_INFO, | ||
895 | "%s: Return type mismatch - unexpected reference object type [%s] %2.2X", | ||
896 | pathname, acpi_ut_get_reference_name(return_object), | ||
897 | return_object->reference.class)); | ||
898 | |||
899 | return (AE_AML_OPERAND_TYPE); | ||
900 | } | ||
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c index 8399276cba1e..a9a80bf811b3 100644 --- a/drivers/acpi/namespace/nssearch.c +++ b/drivers/acpi/namespace/nssearch.c | |||
@@ -331,7 +331,7 @@ acpi_ns_search_and_enter(u32 target_name, | |||
331 | "Found bad character(s) in name, repaired: [%4.4s]\n", | 331 | "Found bad character(s) in name, repaired: [%4.4s]\n", |
332 | ACPI_CAST_PTR(char, &target_name))); | 332 | ACPI_CAST_PTR(char, &target_name))); |
333 | } else { | 333 | } else { |
334 | ACPI_DEBUG_PRINT((ACPI_DB_WARN, | 334 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
335 | "Found bad character(s) in name, repaired: [%4.4s]\n", | 335 | "Found bad character(s) in name, repaired: [%4.4s]\n", |
336 | ACPI_CAST_PTR(char, &target_name))); | 336 | ACPI_CAST_PTR(char, &target_name))); |
337 | } | 337 | } |
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index 38be5865d95d..a085cc39c055 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c | |||
@@ -48,6 +48,10 @@ | |||
48 | 48 | ||
49 | #define _COMPONENT ACPI_NAMESPACE | 49 | #define _COMPONENT ACPI_NAMESPACE |
50 | ACPI_MODULE_NAME("nsxfeval") | 50 | ACPI_MODULE_NAME("nsxfeval") |
51 | |||
52 | /* Local prototypes */ | ||
53 | static void acpi_ns_resolve_references(struct acpi_evaluate_info *info); | ||
54 | |||
51 | #ifdef ACPI_FUTURE_USAGE | 55 | #ifdef ACPI_FUTURE_USAGE |
52 | /******************************************************************************* | 56 | /******************************************************************************* |
53 | * | 57 | * |
@@ -69,6 +73,7 @@ ACPI_MODULE_NAME("nsxfeval") | |||
69 | * be valid (non-null) | 73 | * be valid (non-null) |
70 | * | 74 | * |
71 | ******************************************************************************/ | 75 | ******************************************************************************/ |
76 | |||
72 | acpi_status | 77 | acpi_status |
73 | acpi_evaluate_object_typed(acpi_handle handle, | 78 | acpi_evaluate_object_typed(acpi_handle handle, |
74 | acpi_string pathname, | 79 | acpi_string pathname, |
@@ -283,6 +288,10 @@ acpi_evaluate_object(acpi_handle handle, | |||
283 | 288 | ||
284 | if (ACPI_SUCCESS(status)) { | 289 | if (ACPI_SUCCESS(status)) { |
285 | 290 | ||
291 | /* Dereference Index and ref_of references */ | ||
292 | |||
293 | acpi_ns_resolve_references(info); | ||
294 | |||
286 | /* Get the size of the returned object */ | 295 | /* Get the size of the returned object */ |
287 | 296 | ||
288 | status = | 297 | status = |
@@ -352,6 +361,74 @@ ACPI_EXPORT_SYMBOL(acpi_evaluate_object) | |||
352 | 361 | ||
353 | /******************************************************************************* | 362 | /******************************************************************************* |
354 | * | 363 | * |
364 | * FUNCTION: acpi_ns_resolve_references | ||
365 | * | ||
366 | * PARAMETERS: Info - Evaluation info block | ||
367 | * | ||
368 | * RETURN: Info->return_object is replaced with the dereferenced object | ||
369 | * | ||
370 | * DESCRIPTION: Dereference certain reference objects. Called before an | ||
371 | * internal return object is converted to an external union acpi_object. | ||
372 | * | ||
373 | * Performs an automatic dereference of Index and ref_of reference objects. | ||
374 | * These reference objects are not supported by the union acpi_object, so this is a | ||
375 | * last resort effort to return something useful. Also, provides compatibility | ||
376 | * with other ACPI implementations. | ||
377 | * | ||
378 | * NOTE: does not handle references within returned package objects or nested | ||
379 | * references, but this support could be added later if found to be necessary. | ||
380 | * | ||
381 | ******************************************************************************/ | ||
382 | static void acpi_ns_resolve_references(struct acpi_evaluate_info *info) | ||
383 | { | ||
384 | union acpi_operand_object *obj_desc = NULL; | ||
385 | struct acpi_namespace_node *node; | ||
386 | |||
387 | /* We are interested in reference objects only */ | ||
388 | |||
389 | if (ACPI_GET_OBJECT_TYPE(info->return_object) != | ||
390 | ACPI_TYPE_LOCAL_REFERENCE) { | ||
391 | return; | ||
392 | } | ||
393 | |||
394 | /* | ||
395 | * Two types of references are supported - those created by Index and | ||
396 | * ref_of operators. A name reference (AML_NAMEPATH_OP) can be converted | ||
397 | * to an union acpi_object, so it is not dereferenced here. A ddb_handle | ||
398 | * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to | ||
399 | * an union acpi_object. | ||
400 | */ | ||
401 | switch (info->return_object->reference.class) { | ||
402 | case ACPI_REFCLASS_INDEX: | ||
403 | |||
404 | obj_desc = *(info->return_object->reference.where); | ||
405 | break; | ||
406 | |||
407 | case ACPI_REFCLASS_REFOF: | ||
408 | |||
409 | node = info->return_object->reference.object; | ||
410 | if (node) { | ||
411 | obj_desc = node->object; | ||
412 | } | ||
413 | break; | ||
414 | |||
415 | default: | ||
416 | return; | ||
417 | } | ||
418 | |||
419 | /* Replace the existing reference object */ | ||
420 | |||
421 | if (obj_desc) { | ||
422 | acpi_ut_add_reference(obj_desc); | ||
423 | acpi_ut_remove_reference(info->return_object); | ||
424 | info->return_object = obj_desc; | ||
425 | } | ||
426 | |||
427 | return; | ||
428 | } | ||
429 | |||
430 | /******************************************************************************* | ||
431 | * | ||
355 | * FUNCTION: acpi_walk_namespace | 432 | * FUNCTION: acpi_walk_namespace |
356 | * | 433 | * |
357 | * PARAMETERS: Type - acpi_object_type to search for | 434 | * PARAMETERS: Type - acpi_object_type to search for |
@@ -379,6 +456,7 @@ ACPI_EXPORT_SYMBOL(acpi_evaluate_object) | |||
379 | * function, etc. | 456 | * function, etc. |
380 | * | 457 | * |
381 | ******************************************************************************/ | 458 | ******************************************************************************/ |
459 | |||
382 | acpi_status | 460 | acpi_status |
383 | acpi_walk_namespace(acpi_object_type type, | 461 | acpi_walk_namespace(acpi_object_type type, |
384 | acpi_handle start_object, | 462 | acpi_handle start_object, |
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c index a287ed550f54..5efa4e7ddb0b 100644 --- a/drivers/acpi/namespace/nsxfname.c +++ b/drivers/acpi/namespace/nsxfname.c | |||
@@ -253,6 +253,7 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) | |||
253 | node = acpi_ns_map_handle_to_node(handle); | 253 | node = acpi_ns_map_handle_to_node(handle); |
254 | if (!node) { | 254 | if (!node) { |
255 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 255 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
256 | status = AE_BAD_PARAMETER; | ||
256 | goto cleanup; | 257 | goto cleanup; |
257 | } | 258 | } |
258 | 259 | ||
@@ -264,6 +265,10 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) | |||
264 | info->name = node->name.integer; | 265 | info->name = node->name.integer; |
265 | info->valid = 0; | 266 | info->valid = 0; |
266 | 267 | ||
268 | if (node->type == ACPI_TYPE_METHOD) { | ||
269 | info->param_count = node->object->method.param_count; | ||
270 | } | ||
271 | |||
267 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 272 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
268 | if (ACPI_FAILURE(status)) { | 273 | if (ACPI_FAILURE(status)) { |
269 | goto cleanup; | 274 | goto cleanup; |
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index cb9864e39bae..25ceae9191ef 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -258,7 +258,7 @@ int __init acpi_numa_init(void) | |||
258 | 258 | ||
259 | int acpi_get_pxm(acpi_handle h) | 259 | int acpi_get_pxm(acpi_handle h) |
260 | { | 260 | { |
261 | unsigned long pxm; | 261 | unsigned long long pxm; |
262 | acpi_status status; | 262 | acpi_status status; |
263 | acpi_handle handle; | 263 | acpi_handle handle; |
264 | acpi_handle phandle = h; | 264 | acpi_handle phandle = h; |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 235a1386888a..4be252145cb4 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -608,7 +608,7 @@ static void acpi_os_derive_pci_id_2(acpi_handle rhandle, /* upper bound */ | |||
608 | acpi_handle handle; | 608 | acpi_handle handle; |
609 | struct acpi_pci_id *pci_id = *id; | 609 | struct acpi_pci_id *pci_id = *id; |
610 | acpi_status status; | 610 | acpi_status status; |
611 | unsigned long temp; | 611 | unsigned long long temp; |
612 | acpi_object_type type; | 612 | acpi_object_type type; |
613 | 613 | ||
614 | acpi_get_parent(chandle, &handle); | 614 | acpi_get_parent(chandle, &handle); |
@@ -620,8 +620,7 @@ static void acpi_os_derive_pci_id_2(acpi_handle rhandle, /* upper bound */ | |||
620 | if ((ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE)) | 620 | if ((ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE)) |
621 | return; | 621 | return; |
622 | 622 | ||
623 | status = | 623 | status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, |
624 | acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, | ||
625 | &temp); | 624 | &temp); |
626 | if (ACPI_SUCCESS(status)) { | 625 | if (ACPI_SUCCESS(status)) { |
627 | u32 val; | 626 | u32 val; |
@@ -682,6 +681,22 @@ static void acpi_os_execute_deferred(struct work_struct *work) | |||
682 | return; | 681 | return; |
683 | } | 682 | } |
684 | 683 | ||
684 | static void acpi_os_execute_hp_deferred(struct work_struct *work) | ||
685 | { | ||
686 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); | ||
687 | if (!dpc) { | ||
688 | printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); | ||
689 | return; | ||
690 | } | ||
691 | |||
692 | acpi_os_wait_events_complete(NULL); | ||
693 | |||
694 | dpc->function(dpc->context); | ||
695 | kfree(dpc); | ||
696 | |||
697 | return; | ||
698 | } | ||
699 | |||
685 | /******************************************************************************* | 700 | /******************************************************************************* |
686 | * | 701 | * |
687 | * FUNCTION: acpi_os_execute | 702 | * FUNCTION: acpi_os_execute |
@@ -697,12 +712,13 @@ static void acpi_os_execute_deferred(struct work_struct *work) | |||
697 | * | 712 | * |
698 | ******************************************************************************/ | 713 | ******************************************************************************/ |
699 | 714 | ||
700 | acpi_status acpi_os_execute(acpi_execute_type type, | 715 | static acpi_status __acpi_os_execute(acpi_execute_type type, |
701 | acpi_osd_exec_callback function, void *context) | 716 | acpi_osd_exec_callback function, void *context, int hp) |
702 | { | 717 | { |
703 | acpi_status status = AE_OK; | 718 | acpi_status status = AE_OK; |
704 | struct acpi_os_dpc *dpc; | 719 | struct acpi_os_dpc *dpc; |
705 | struct workqueue_struct *queue; | 720 | struct workqueue_struct *queue; |
721 | int ret; | ||
706 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 722 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
707 | "Scheduling function [%p(%p)] for deferred execution.\n", | 723 | "Scheduling function [%p(%p)] for deferred execution.\n", |
708 | function, context)); | 724 | function, context)); |
@@ -726,19 +742,38 @@ acpi_status acpi_os_execute(acpi_execute_type type, | |||
726 | dpc->function = function; | 742 | dpc->function = function; |
727 | dpc->context = context; | 743 | dpc->context = context; |
728 | 744 | ||
729 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | 745 | if (!hp) { |
730 | queue = (type == OSL_NOTIFY_HANDLER) ? kacpi_notify_wq : kacpid_wq; | 746 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); |
731 | if (!queue_work(queue, &dpc->work)) { | 747 | queue = (type == OSL_NOTIFY_HANDLER) ? |
732 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 748 | kacpi_notify_wq : kacpid_wq; |
733 | "Call to queue_work() failed.\n")); | 749 | ret = queue_work(queue, &dpc->work); |
750 | } else { | ||
751 | INIT_WORK(&dpc->work, acpi_os_execute_hp_deferred); | ||
752 | ret = schedule_work(&dpc->work); | ||
753 | } | ||
754 | |||
755 | if (!ret) { | ||
756 | printk(KERN_ERR PREFIX | ||
757 | "Call to queue_work() failed.\n"); | ||
734 | status = AE_ERROR; | 758 | status = AE_ERROR; |
735 | kfree(dpc); | 759 | kfree(dpc); |
736 | } | 760 | } |
737 | return_ACPI_STATUS(status); | 761 | return_ACPI_STATUS(status); |
738 | } | 762 | } |
739 | 763 | ||
764 | acpi_status acpi_os_execute(acpi_execute_type type, | ||
765 | acpi_osd_exec_callback function, void *context) | ||
766 | { | ||
767 | return __acpi_os_execute(type, function, context, 0); | ||
768 | } | ||
740 | EXPORT_SYMBOL(acpi_os_execute); | 769 | EXPORT_SYMBOL(acpi_os_execute); |
741 | 770 | ||
771 | acpi_status acpi_os_hotplug_execute(acpi_osd_exec_callback function, | ||
772 | void *context) | ||
773 | { | ||
774 | return __acpi_os_execute(0, function, context, 1); | ||
775 | } | ||
776 | |||
742 | void acpi_os_wait_events_complete(void *context) | 777 | void acpi_os_wait_events_complete(void *context) |
743 | { | 778 | { |
744 | flush_workqueue(kacpid_wq); | 779 | flush_workqueue(kacpid_wq); |
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c index c06238e55d98..4647039a0d8a 100644 --- a/drivers/acpi/parser/psloop.c +++ b/drivers/acpi/parser/psloop.c | |||
@@ -719,6 +719,8 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state, | |||
719 | *op = NULL; | 719 | *op = NULL; |
720 | } | 720 | } |
721 | 721 | ||
722 | ACPI_PREEMPTION_POINT(); | ||
723 | |||
722 | return_ACPI_STATUS(AE_OK); | 724 | return_ACPI_STATUS(AE_OK); |
723 | } | 725 | } |
724 | 726 | ||
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index 15e1702e48d6..68e932f215ea 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c | |||
@@ -137,6 +137,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, | |||
137 | union acpi_parse_object *next; | 137 | union acpi_parse_object *next; |
138 | const struct acpi_opcode_info *parent_info; | 138 | const struct acpi_opcode_info *parent_info; |
139 | union acpi_parse_object *replacement_op = NULL; | 139 | union acpi_parse_object *replacement_op = NULL; |
140 | acpi_status status = AE_OK; | ||
140 | 141 | ||
141 | ACPI_FUNCTION_TRACE_PTR(ps_complete_this_op, op); | 142 | ACPI_FUNCTION_TRACE_PTR(ps_complete_this_op, op); |
142 | 143 | ||
@@ -186,7 +187,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, | |||
186 | replacement_op = | 187 | replacement_op = |
187 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); | 188 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); |
188 | if (!replacement_op) { | 189 | if (!replacement_op) { |
189 | goto allocate_error; | 190 | status = AE_NO_MEMORY; |
190 | } | 191 | } |
191 | break; | 192 | break; |
192 | 193 | ||
@@ -211,7 +212,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, | |||
211 | replacement_op = | 212 | replacement_op = |
212 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); | 213 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); |
213 | if (!replacement_op) { | 214 | if (!replacement_op) { |
214 | goto allocate_error; | 215 | status = AE_NO_MEMORY; |
215 | } | 216 | } |
216 | } else | 217 | } else |
217 | if ((op->common.parent->common.aml_opcode == | 218 | if ((op->common.parent->common.aml_opcode == |
@@ -226,13 +227,13 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, | |||
226 | acpi_ps_alloc_op(op->common. | 227 | acpi_ps_alloc_op(op->common. |
227 | aml_opcode); | 228 | aml_opcode); |
228 | if (!replacement_op) { | 229 | if (!replacement_op) { |
229 | goto allocate_error; | 230 | status = AE_NO_MEMORY; |
231 | } else { | ||
232 | replacement_op->named.data = | ||
233 | op->named.data; | ||
234 | replacement_op->named.length = | ||
235 | op->named.length; | ||
230 | } | 236 | } |
231 | |||
232 | replacement_op->named.data = | ||
233 | op->named.data; | ||
234 | replacement_op->named.length = | ||
235 | op->named.length; | ||
236 | } | 237 | } |
237 | } | 238 | } |
238 | break; | 239 | break; |
@@ -242,7 +243,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, | |||
242 | replacement_op = | 243 | replacement_op = |
243 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); | 244 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); |
244 | if (!replacement_op) { | 245 | if (!replacement_op) { |
245 | goto allocate_error; | 246 | status = AE_NO_MEMORY; |
246 | } | 247 | } |
247 | } | 248 | } |
248 | 249 | ||
@@ -302,14 +303,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, | |||
302 | /* Now we can actually delete the subtree rooted at Op */ | 303 | /* Now we can actually delete the subtree rooted at Op */ |
303 | 304 | ||
304 | acpi_ps_delete_parse_tree(op); | 305 | acpi_ps_delete_parse_tree(op); |
305 | return_ACPI_STATUS(AE_OK); | 306 | return_ACPI_STATUS(status); |
306 | |||
307 | allocate_error: | ||
308 | |||
309 | /* Always delete the subtree, even on error */ | ||
310 | |||
311 | acpi_ps_delete_parse_tree(op); | ||
312 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
313 | } | 307 | } |
314 | 308 | ||
315 | /******************************************************************************* | 309 | /******************************************************************************* |
@@ -641,10 +635,12 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) | |||
641 | ACPI_WALK_METHOD_RESTART; | 635 | ACPI_WALK_METHOD_RESTART; |
642 | } | 636 | } |
643 | } else { | 637 | } else { |
644 | /* On error, delete any return object */ | 638 | /* On error, delete any return object or implicit return */ |
645 | 639 | ||
646 | acpi_ut_remove_reference(previous_walk_state-> | 640 | acpi_ut_remove_reference(previous_walk_state-> |
647 | return_desc); | 641 | return_desc); |
642 | acpi_ds_clear_implicit_return | ||
643 | (previous_walk_state); | ||
648 | } | 644 | } |
649 | } | 645 | } |
650 | 646 | ||
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index cf47805a7448..fcfdef7b4fdd 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
@@ -709,7 +709,7 @@ int acpi_pci_link_free_irq(acpi_handle handle) | |||
709 | acpi_device_bid(link->device))); | 709 | acpi_device_bid(link->device))); |
710 | 710 | ||
711 | if (link->refcnt == 0) { | 711 | if (link->refcnt == 0) { |
712 | acpi_ut_evaluate_object(link->device->handle, "_DIS", 0, NULL); | 712 | acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL); |
713 | } | 713 | } |
714 | mutex_unlock(&acpi_link_lock); | 714 | mutex_unlock(&acpi_link_lock); |
715 | return (link->irq.active); | 715 | return (link->irq.active); |
@@ -737,7 +737,7 @@ static int acpi_pci_link_add(struct acpi_device *device) | |||
737 | link->device = device; | 737 | link->device = device; |
738 | strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME); | 738 | strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME); |
739 | strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS); | 739 | strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS); |
740 | acpi_driver_data(device) = link; | 740 | device->driver_data = link; |
741 | 741 | ||
742 | mutex_lock(&acpi_link_lock); | 742 | mutex_lock(&acpi_link_lock); |
743 | result = acpi_pci_link_get_possible(link); | 743 | result = acpi_pci_link_get_possible(link); |
@@ -773,7 +773,7 @@ static int acpi_pci_link_add(struct acpi_device *device) | |||
773 | 773 | ||
774 | end: | 774 | end: |
775 | /* disable all links -- to be activated on use */ | 775 | /* disable all links -- to be activated on use */ |
776 | acpi_ut_evaluate_object(device->handle, "_DIS", 0, NULL); | 776 | acpi_evaluate_object(device->handle, "_DIS", NULL, NULL); |
777 | mutex_unlock(&acpi_link_lock); | 777 | mutex_unlock(&acpi_link_lock); |
778 | 778 | ||
779 | if (result) | 779 | if (result) |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index c3fed31166b5..1b8f67d21d53 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -190,7 +190,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
190 | struct acpi_pci_root *root = NULL; | 190 | struct acpi_pci_root *root = NULL; |
191 | struct acpi_pci_root *tmp; | 191 | struct acpi_pci_root *tmp; |
192 | acpi_status status = AE_OK; | 192 | acpi_status status = AE_OK; |
193 | unsigned long value = 0; | 193 | unsigned long long value = 0; |
194 | acpi_handle handle = NULL; | 194 | acpi_handle handle = NULL; |
195 | struct acpi_device *child; | 195 | struct acpi_device *child; |
196 | 196 | ||
@@ -206,7 +206,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
206 | root->device = device; | 206 | root->device = device; |
207 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); | 207 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); |
208 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); | 208 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); |
209 | acpi_driver_data(device) = root; | 209 | device->driver_data = root; |
210 | 210 | ||
211 | device->ops.bind = acpi_pci_bind; | 211 | device->ops.bind = acpi_pci_bind; |
212 | 212 | ||
diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c index 8d4a568be1cc..cd1f4467be7b 100644 --- a/drivers/acpi/pci_slot.c +++ b/drivers/acpi/pci_slot.c | |||
@@ -76,10 +76,10 @@ static struct acpi_pci_driver acpi_pci_slot_driver = { | |||
76 | }; | 76 | }; |
77 | 77 | ||
78 | static int | 78 | static int |
79 | check_slot(acpi_handle handle, unsigned long *sun) | 79 | check_slot(acpi_handle handle, unsigned long long *sun) |
80 | { | 80 | { |
81 | int device = -1; | 81 | int device = -1; |
82 | unsigned long adr, sta; | 82 | unsigned long long adr, sta; |
83 | acpi_status status; | 83 | acpi_status status; |
84 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 84 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
85 | 85 | ||
@@ -132,7 +132,7 @@ static acpi_status | |||
132 | register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | 132 | register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) |
133 | { | 133 | { |
134 | int device; | 134 | int device; |
135 | unsigned long sun; | 135 | unsigned long long sun; |
136 | char name[SLOT_NAME_SIZE]; | 136 | char name[SLOT_NAME_SIZE]; |
137 | struct acpi_pci_slot *slot; | 137 | struct acpi_pci_slot *slot; |
138 | struct pci_slot *pci_slot; | 138 | struct pci_slot *pci_slot; |
@@ -182,7 +182,7 @@ static acpi_status | |||
182 | walk_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) | 182 | walk_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) |
183 | { | 183 | { |
184 | int device, function; | 184 | int device, function; |
185 | unsigned long adr; | 185 | unsigned long long adr; |
186 | acpi_status status; | 186 | acpi_status status; |
187 | acpi_handle dummy_handle; | 187 | acpi_handle dummy_handle; |
188 | acpi_walk_callback user_function; | 188 | acpi_walk_callback user_function; |
@@ -239,7 +239,7 @@ static int | |||
239 | walk_root_bridge(acpi_handle handle, acpi_walk_callback user_function) | 239 | walk_root_bridge(acpi_handle handle, acpi_walk_callback user_function) |
240 | { | 240 | { |
241 | int seg, bus; | 241 | int seg, bus; |
242 | unsigned long tmp; | 242 | unsigned long long tmp; |
243 | acpi_status status; | 243 | acpi_status status; |
244 | acpi_handle dummy_handle; | 244 | acpi_handle dummy_handle; |
245 | struct pci_bus *pci_bus; | 245 | struct pci_bus *pci_bus; |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 4ab21cb1c8c7..a1718e56103b 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -54,6 +54,14 @@ ACPI_MODULE_NAME("power"); | |||
54 | #define ACPI_POWER_RESOURCE_STATE_OFF 0x00 | 54 | #define ACPI_POWER_RESOURCE_STATE_OFF 0x00 |
55 | #define ACPI_POWER_RESOURCE_STATE_ON 0x01 | 55 | #define ACPI_POWER_RESOURCE_STATE_ON 0x01 |
56 | #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF | 56 | #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF |
57 | |||
58 | #ifdef MODULE_PARAM_PREFIX | ||
59 | #undef MODULE_PARAM_PREFIX | ||
60 | #endif | ||
61 | #define MODULE_PARAM_PREFIX "acpi." | ||
62 | int acpi_power_nocheck; | ||
63 | module_param_named(power_nocheck, acpi_power_nocheck, bool, 000); | ||
64 | |||
57 | static int acpi_power_add(struct acpi_device *device); | 65 | static int acpi_power_add(struct acpi_device *device); |
58 | static int acpi_power_remove(struct acpi_device *device, int type); | 66 | static int acpi_power_remove(struct acpi_device *device, int type); |
59 | static int acpi_power_resume(struct acpi_device *device); | 67 | static int acpi_power_resume(struct acpi_device *device); |
@@ -128,16 +136,16 @@ acpi_power_get_context(acpi_handle handle, | |||
128 | return 0; | 136 | return 0; |
129 | } | 137 | } |
130 | 138 | ||
131 | static int acpi_power_get_state(struct acpi_power_resource *resource, int *state) | 139 | static int acpi_power_get_state(acpi_handle handle, int *state) |
132 | { | 140 | { |
133 | acpi_status status = AE_OK; | 141 | acpi_status status = AE_OK; |
134 | unsigned long sta = 0; | 142 | unsigned long long sta = 0; |
135 | 143 | ||
136 | 144 | ||
137 | if (!resource || !state) | 145 | if (!handle || !state) |
138 | return -EINVAL; | 146 | return -EINVAL; |
139 | 147 | ||
140 | status = acpi_evaluate_integer(resource->device->handle, "_STA", NULL, &sta); | 148 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); |
141 | if (ACPI_FAILURE(status)) | 149 | if (ACPI_FAILURE(status)) |
142 | return -ENODEV; | 150 | return -ENODEV; |
143 | 151 | ||
@@ -145,7 +153,7 @@ static int acpi_power_get_state(struct acpi_power_resource *resource, int *state | |||
145 | ACPI_POWER_RESOURCE_STATE_OFF; | 153 | ACPI_POWER_RESOURCE_STATE_OFF; |
146 | 154 | ||
147 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n", | 155 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n", |
148 | resource->name, state ? "on" : "off")); | 156 | acpi_ut_get_node_name(handle), state ? "on" : "off")); |
149 | 157 | ||
150 | return 0; | 158 | return 0; |
151 | } | 159 | } |
@@ -153,7 +161,6 @@ static int acpi_power_get_state(struct acpi_power_resource *resource, int *state | |||
153 | static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state) | 161 | static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state) |
154 | { | 162 | { |
155 | int result = 0, state1; | 163 | int result = 0, state1; |
156 | struct acpi_power_resource *resource = NULL; | ||
157 | u32 i = 0; | 164 | u32 i = 0; |
158 | 165 | ||
159 | 166 | ||
@@ -161,12 +168,15 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state) | |||
161 | return -EINVAL; | 168 | return -EINVAL; |
162 | 169 | ||
163 | /* The state of the list is 'on' IFF all resources are 'on'. */ | 170 | /* The state of the list is 'on' IFF all resources are 'on'. */ |
171 | /* */ | ||
164 | 172 | ||
165 | for (i = 0; i < list->count; i++) { | 173 | for (i = 0; i < list->count; i++) { |
166 | result = acpi_power_get_context(list->handles[i], &resource); | 174 | /* |
167 | if (result) | 175 | * The state of the power resource can be obtained by |
168 | return result; | 176 | * using the ACPI handle. In such case it is unnecessary to |
169 | result = acpi_power_get_state(resource, &state1); | 177 | * get the Power resource first and then get its state again. |
178 | */ | ||
179 | result = acpi_power_get_state(list->handles[i], &state1); | ||
170 | if (result) | 180 | if (result) |
171 | return result; | 181 | return result; |
172 | 182 | ||
@@ -226,12 +236,18 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev) | |||
226 | if (ACPI_FAILURE(status)) | 236 | if (ACPI_FAILURE(status)) |
227 | return -ENODEV; | 237 | return -ENODEV; |
228 | 238 | ||
229 | result = acpi_power_get_state(resource, &state); | 239 | if (!acpi_power_nocheck) { |
230 | if (result) | 240 | /* |
231 | return result; | 241 | * If acpi_power_nocheck is set, it is unnecessary to check |
232 | if (state != ACPI_POWER_RESOURCE_STATE_ON) | 242 | * the power state after power transition. |
233 | return -ENOEXEC; | 243 | */ |
234 | 244 | result = acpi_power_get_state(resource->device->handle, | |
245 | &state); | ||
246 | if (result) | ||
247 | return result; | ||
248 | if (state != ACPI_POWER_RESOURCE_STATE_ON) | ||
249 | return -ENOEXEC; | ||
250 | } | ||
235 | /* Update the power resource's _device_ power state */ | 251 | /* Update the power resource's _device_ power state */ |
236 | resource->device->power.state = ACPI_STATE_D0; | 252 | resource->device->power.state = ACPI_STATE_D0; |
237 | 253 | ||
@@ -277,11 +293,17 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) | |||
277 | if (ACPI_FAILURE(status)) | 293 | if (ACPI_FAILURE(status)) |
278 | return -ENODEV; | 294 | return -ENODEV; |
279 | 295 | ||
280 | result = acpi_power_get_state(resource, &state); | 296 | if (!acpi_power_nocheck) { |
281 | if (result) | 297 | /* |
282 | return result; | 298 | * If acpi_power_nocheck is set, it is unnecessary to check |
283 | if (state != ACPI_POWER_RESOURCE_STATE_OFF) | 299 | * the power state after power transition. |
284 | return -ENOEXEC; | 300 | */ |
301 | result = acpi_power_get_state(handle, &state); | ||
302 | if (result) | ||
303 | return result; | ||
304 | if (state != ACPI_POWER_RESOURCE_STATE_OFF) | ||
305 | return -ENOEXEC; | ||
306 | } | ||
285 | 307 | ||
286 | /* Update the power resource's _device_ power state */ | 308 | /* Update the power resource's _device_ power state */ |
287 | resource->device->power.state = ACPI_STATE_D3; | 309 | resource->device->power.state = ACPI_STATE_D3; |
@@ -555,7 +577,7 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset) | |||
555 | if (!resource) | 577 | if (!resource) |
556 | goto end; | 578 | goto end; |
557 | 579 | ||
558 | result = acpi_power_get_state(resource, &state); | 580 | result = acpi_power_get_state(resource->device->handle, &state); |
559 | if (result) | 581 | if (result) |
560 | goto end; | 582 | goto end; |
561 | 583 | ||
@@ -657,7 +679,7 @@ static int acpi_power_add(struct acpi_device *device) | |||
657 | strcpy(resource->name, device->pnp.bus_id); | 679 | strcpy(resource->name, device->pnp.bus_id); |
658 | strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); | 680 | strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); |
659 | strcpy(acpi_device_class(device), ACPI_POWER_CLASS); | 681 | strcpy(acpi_device_class(device), ACPI_POWER_CLASS); |
660 | acpi_driver_data(device) = resource; | 682 | device->driver_data = resource; |
661 | 683 | ||
662 | /* Evalute the object to get the system level and resource order. */ | 684 | /* Evalute the object to get the system level and resource order. */ |
663 | status = acpi_evaluate_object(device->handle, NULL, NULL, &buffer); | 685 | status = acpi_evaluate_object(device->handle, NULL, NULL, &buffer); |
@@ -668,7 +690,7 @@ static int acpi_power_add(struct acpi_device *device) | |||
668 | resource->system_level = acpi_object.power_resource.system_level; | 690 | resource->system_level = acpi_object.power_resource.system_level; |
669 | resource->order = acpi_object.power_resource.resource_order; | 691 | resource->order = acpi_object.power_resource.resource_order; |
670 | 692 | ||
671 | result = acpi_power_get_state(resource, &state); | 693 | result = acpi_power_get_state(device->handle, &state); |
672 | if (result) | 694 | if (result) |
673 | goto end; | 695 | goto end; |
674 | 696 | ||
@@ -733,9 +755,9 @@ static int acpi_power_resume(struct acpi_device *device) | |||
733 | if (!device || !acpi_driver_data(device)) | 755 | if (!device || !acpi_driver_data(device)) |
734 | return -EINVAL; | 756 | return -EINVAL; |
735 | 757 | ||
736 | resource = (struct acpi_power_resource *)acpi_driver_data(device); | 758 | resource = acpi_driver_data(device); |
737 | 759 | ||
738 | result = acpi_power_get_state(resource, &state); | 760 | result = acpi_power_get_state(device->handle, &state); |
739 | if (result) | 761 | if (result) |
740 | return result; | 762 | return result; |
741 | 763 | ||
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index ee68ac54c0d4..24a362f8034c 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -563,7 +563,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) | |||
563 | 563 | ||
564 | /* Check if it is a Device with HID and UID */ | 564 | /* Check if it is a Device with HID and UID */ |
565 | if (has_uid) { | 565 | if (has_uid) { |
566 | unsigned long value; | 566 | unsigned long long value; |
567 | status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, | 567 | status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, |
568 | NULL, &value); | 568 | NULL, &value); |
569 | if (ACPI_FAILURE(status)) { | 569 | if (ACPI_FAILURE(status)) { |
@@ -818,7 +818,7 @@ static int acpi_processor_add(struct acpi_device *device) | |||
818 | pr->handle = device->handle; | 818 | pr->handle = device->handle; |
819 | strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME); | 819 | strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME); |
820 | strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); | 820 | strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); |
821 | acpi_driver_data(device) = pr; | 821 | device->driver_data = pr; |
822 | 822 | ||
823 | return 0; | 823 | return 0; |
824 | } | 824 | } |
@@ -875,7 +875,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type) | |||
875 | static int is_processor_present(acpi_handle handle) | 875 | static int is_processor_present(acpi_handle handle) |
876 | { | 876 | { |
877 | acpi_status status; | 877 | acpi_status status; |
878 | unsigned long sta = 0; | 878 | unsigned long long sta = 0; |
879 | 879 | ||
880 | 880 | ||
881 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | 881 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index cf5b1b7b684f..81b40ed5379e 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -1587,6 +1587,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
1587 | 1587 | ||
1588 | if (acpi_idle_bm_check()) { | 1588 | if (acpi_idle_bm_check()) { |
1589 | if (dev->safe_state) { | 1589 | if (dev->safe_state) { |
1590 | dev->last_state = dev->safe_state; | ||
1590 | return dev->safe_state->enter(dev, dev->safe_state); | 1591 | return dev->safe_state->enter(dev, dev->safe_state); |
1591 | } else { | 1592 | } else { |
1592 | local_irq_disable(); | 1593 | local_irq_disable(); |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 80c251ec6d2a..dc98f7a6f2c4 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -38,6 +38,7 @@ | |||
38 | 38 | ||
39 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
40 | #endif | 40 | #endif |
41 | #include <asm/cpufeature.h> | ||
41 | 42 | ||
42 | #include <acpi/acpi_bus.h> | 43 | #include <acpi/acpi_bus.h> |
43 | #include <acpi/processor.h> | 44 | #include <acpi/processor.h> |
@@ -126,7 +127,7 @@ static struct notifier_block acpi_ppc_notifier_block = { | |||
126 | static int acpi_processor_get_platform_limit(struct acpi_processor *pr) | 127 | static int acpi_processor_get_platform_limit(struct acpi_processor *pr) |
127 | { | 128 | { |
128 | acpi_status status = 0; | 129 | acpi_status status = 0; |
129 | unsigned long ppc = 0; | 130 | unsigned long long ppc = 0; |
130 | 131 | ||
131 | 132 | ||
132 | if (!pr) | 133 | if (!pr) |
@@ -334,7 +335,6 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr) | |||
334 | acpi_status status = AE_OK; | 335 | acpi_status status = AE_OK; |
335 | acpi_handle handle = NULL; | 336 | acpi_handle handle = NULL; |
336 | 337 | ||
337 | |||
338 | if (!pr || !pr->performance || !pr->handle) | 338 | if (!pr || !pr->performance || !pr->handle) |
339 | return -EINVAL; | 339 | return -EINVAL; |
340 | 340 | ||
@@ -347,13 +347,25 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr) | |||
347 | 347 | ||
348 | result = acpi_processor_get_performance_control(pr); | 348 | result = acpi_processor_get_performance_control(pr); |
349 | if (result) | 349 | if (result) |
350 | return result; | 350 | goto update_bios; |
351 | 351 | ||
352 | result = acpi_processor_get_performance_states(pr); | 352 | result = acpi_processor_get_performance_states(pr); |
353 | if (result) | 353 | if (result) |
354 | return result; | 354 | goto update_bios; |
355 | 355 | ||
356 | return 0; | 356 | return 0; |
357 | |||
358 | /* | ||
359 | * Having _PPC but missing frequencies (_PSS, _PCT) is a very good hint that | ||
360 | * the BIOS is older than the CPU and does not know its frequencies | ||
361 | */ | ||
362 | update_bios: | ||
363 | if (ACPI_SUCCESS(acpi_get_handle(pr->handle, "_PPC", &handle))){ | ||
364 | if(boot_cpu_has(X86_FEATURE_EST)) | ||
365 | printk(KERN_WARNING FW_BUG "BIOS needs update for CPU " | ||
366 | "frequency support\n"); | ||
367 | } | ||
368 | return result; | ||
357 | } | 369 | } |
358 | 370 | ||
359 | int acpi_processor_notify_smm(struct module *calling_module) | 371 | int acpi_processor_notify_smm(struct module *calling_module) |
@@ -524,13 +536,13 @@ static int acpi_processor_get_psd(struct acpi_processor *pr) | |||
524 | 536 | ||
525 | psd = buffer.pointer; | 537 | psd = buffer.pointer; |
526 | if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) { | 538 | if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) { |
527 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n")); | 539 | printk(KERN_ERR PREFIX "Invalid _PSD data\n"); |
528 | result = -EFAULT; | 540 | result = -EFAULT; |
529 | goto end; | 541 | goto end; |
530 | } | 542 | } |
531 | 543 | ||
532 | if (psd->package.count != 1) { | 544 | if (psd->package.count != 1) { |
533 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n")); | 545 | printk(KERN_ERR PREFIX "Invalid _PSD data\n"); |
534 | result = -EFAULT; | 546 | result = -EFAULT; |
535 | goto end; | 547 | goto end; |
536 | } | 548 | } |
@@ -543,19 +555,19 @@ static int acpi_processor_get_psd(struct acpi_processor *pr) | |||
543 | status = acpi_extract_package(&(psd->package.elements[0]), | 555 | status = acpi_extract_package(&(psd->package.elements[0]), |
544 | &format, &state); | 556 | &format, &state); |
545 | if (ACPI_FAILURE(status)) { | 557 | if (ACPI_FAILURE(status)) { |
546 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n")); | 558 | printk(KERN_ERR PREFIX "Invalid _PSD data\n"); |
547 | result = -EFAULT; | 559 | result = -EFAULT; |
548 | goto end; | 560 | goto end; |
549 | } | 561 | } |
550 | 562 | ||
551 | if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) { | 563 | if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) { |
552 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _PSD:num_entries\n")); | 564 | printk(KERN_ERR PREFIX "Unknown _PSD:num_entries\n"); |
553 | result = -EFAULT; | 565 | result = -EFAULT; |
554 | goto end; | 566 | goto end; |
555 | } | 567 | } |
556 | 568 | ||
557 | if (pdomain->revision != ACPI_PSD_REV0_REVISION) { | 569 | if (pdomain->revision != ACPI_PSD_REV0_REVISION) { |
558 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _PSD:revision\n")); | 570 | printk(KERN_ERR PREFIX "Unknown _PSD:revision\n"); |
559 | result = -EFAULT; | 571 | result = -EFAULT; |
560 | goto end; | 572 | goto end; |
561 | } | 573 | } |
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index a56fc6c4394b..3da2df93d924 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
@@ -274,7 +274,7 @@ static int acpi_processor_throttling_notifier(unsigned long event, void *data) | |||
274 | static int acpi_processor_get_platform_limit(struct acpi_processor *pr) | 274 | static int acpi_processor_get_platform_limit(struct acpi_processor *pr) |
275 | { | 275 | { |
276 | acpi_status status = 0; | 276 | acpi_status status = 0; |
277 | unsigned long tpc = 0; | 277 | unsigned long long tpc = 0; |
278 | 278 | ||
279 | if (!pr) | 279 | if (!pr) |
280 | return -EINVAL; | 280 | return -EINVAL; |
@@ -528,13 +528,13 @@ static int acpi_processor_get_tsd(struct acpi_processor *pr) | |||
528 | 528 | ||
529 | tsd = buffer.pointer; | 529 | tsd = buffer.pointer; |
530 | if (!tsd || (tsd->type != ACPI_TYPE_PACKAGE)) { | 530 | if (!tsd || (tsd->type != ACPI_TYPE_PACKAGE)) { |
531 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n")); | 531 | printk(KERN_ERR PREFIX "Invalid _TSD data\n"); |
532 | result = -EFAULT; | 532 | result = -EFAULT; |
533 | goto end; | 533 | goto end; |
534 | } | 534 | } |
535 | 535 | ||
536 | if (tsd->package.count != 1) { | 536 | if (tsd->package.count != 1) { |
537 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n")); | 537 | printk(KERN_ERR PREFIX "Invalid _TSD data\n"); |
538 | result = -EFAULT; | 538 | result = -EFAULT; |
539 | goto end; | 539 | goto end; |
540 | } | 540 | } |
@@ -547,19 +547,19 @@ static int acpi_processor_get_tsd(struct acpi_processor *pr) | |||
547 | status = acpi_extract_package(&(tsd->package.elements[0]), | 547 | status = acpi_extract_package(&(tsd->package.elements[0]), |
548 | &format, &state); | 548 | &format, &state); |
549 | if (ACPI_FAILURE(status)) { | 549 | if (ACPI_FAILURE(status)) { |
550 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n")); | 550 | printk(KERN_ERR PREFIX "Invalid _TSD data\n"); |
551 | result = -EFAULT; | 551 | result = -EFAULT; |
552 | goto end; | 552 | goto end; |
553 | } | 553 | } |
554 | 554 | ||
555 | if (pdomain->num_entries != ACPI_TSD_REV0_ENTRIES) { | 555 | if (pdomain->num_entries != ACPI_TSD_REV0_ENTRIES) { |
556 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:num_entries\n")); | 556 | printk(KERN_ERR PREFIX "Unknown _TSD:num_entries\n"); |
557 | result = -EFAULT; | 557 | result = -EFAULT; |
558 | goto end; | 558 | goto end; |
559 | } | 559 | } |
560 | 560 | ||
561 | if (pdomain->revision != ACPI_TSD_REV0_REVISION) { | 561 | if (pdomain->revision != ACPI_TSD_REV0_REVISION) { |
562 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:revision\n")); | 562 | printk(KERN_ERR PREFIX "Unknown _TSD:revision\n"); |
563 | result = -EFAULT; | 563 | result = -EFAULT; |
564 | goto end; | 564 | goto end; |
565 | } | 565 | } |
diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c index a6b662c00b67..755baf2ca70a 100644 --- a/drivers/acpi/reboot.c +++ b/drivers/acpi/reboot.c | |||
@@ -15,9 +15,28 @@ void acpi_reboot(void) | |||
15 | 15 | ||
16 | rr = &acpi_gbl_FADT.reset_register; | 16 | rr = &acpi_gbl_FADT.reset_register; |
17 | 17 | ||
18 | /* Is the reset register supported? */ | 18 | /* |
19 | if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || | 19 | * Is the ACPI reset register supported? |
20 | rr->bit_width != 8 || rr->bit_offset != 0) | 20 | * |
21 | * According to ACPI 3.0, FADT.flags.RESET_REG_SUP indicates | ||
22 | * whether the ACPI reset mechanism is supported. | ||
23 | * | ||
24 | * However, some boxes have this bit clear, yet a valid | ||
25 | * ACPI_RESET_REG & RESET_VALUE, and ACPI reboot is the only | ||
26 | * mechanism that works for them after S3. | ||
27 | * | ||
28 | * This suggests that other operating systems may not be checking | ||
29 | * the RESET_REG_SUP bit, and are using other means to decide | ||
30 | * whether to use the ACPI reboot mechanism or not. | ||
31 | * | ||
32 | * So when acpi reboot is requested, | ||
33 | * only the reset_register is checked. If the following | ||
34 | * conditions are met, it indicates that the reset register is supported. | ||
35 | * a. reset_register is not zero | ||
36 | * b. the access width is eight | ||
37 | * c. the bit_offset is zero | ||
38 | */ | ||
39 | if (!(rr->address) || rr->bit_width != 8 || rr->bit_offset != 0) | ||
21 | return; | 40 | return; |
22 | 41 | ||
23 | reset_value = acpi_gbl_FADT.reset_value; | 42 | reset_value = acpi_gbl_FADT.reset_value; |
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index d9063ea414e3..8eaaecf92009 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c | |||
@@ -43,7 +43,6 @@ | |||
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acresrc.h> | 45 | #include <acpi/acresrc.h> |
46 | #include <acpi/amlcode.h> | ||
47 | #include <acpi/acnamesp.h> | 46 | #include <acpi/acnamesp.h> |
48 | 47 | ||
49 | #define _COMPONENT ACPI_RESOURCES | 48 | #define _COMPONENT ACPI_RESOURCES |
@@ -560,8 +559,8 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, | |||
560 | ACPI_GET_OBJECT_TYPE(*sub_object_list)) || | 559 | ACPI_GET_OBJECT_TYPE(*sub_object_list)) || |
561 | ((ACPI_TYPE_LOCAL_REFERENCE == | 560 | ((ACPI_TYPE_LOCAL_REFERENCE == |
562 | ACPI_GET_OBJECT_TYPE(*sub_object_list)) && | 561 | ACPI_GET_OBJECT_TYPE(*sub_object_list)) && |
563 | ((*sub_object_list)->reference.opcode == | 562 | ((*sub_object_list)->reference.class == |
564 | AML_INT_NAMEPATH_OP)))) { | 563 | ACPI_REFCLASS_NAME)))) { |
565 | name_found = TRUE; | 564 | name_found = TRUE; |
566 | } else { | 565 | } else { |
567 | /* Look at the next element */ | 566 | /* Look at the next element */ |
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c index 7804a8c40e7a..c0bbfa2c4193 100644 --- a/drivers/acpi/resources/rscreate.c +++ b/drivers/acpi/resources/rscreate.c | |||
@@ -43,7 +43,6 @@ | |||
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acresrc.h> | 45 | #include <acpi/acresrc.h> |
46 | #include <acpi/amlcode.h> | ||
47 | #include <acpi/acnamesp.h> | 46 | #include <acpi/acnamesp.h> |
48 | 47 | ||
49 | #define _COMPONENT ACPI_RESOURCES | 48 | #define _COMPONENT ACPI_RESOURCES |
@@ -310,13 +309,12 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, | |||
310 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 309 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { |
311 | case ACPI_TYPE_LOCAL_REFERENCE: | 310 | case ACPI_TYPE_LOCAL_REFERENCE: |
312 | 311 | ||
313 | if (obj_desc->reference.opcode != | 312 | if (obj_desc->reference.class != |
314 | AML_INT_NAMEPATH_OP) { | 313 | ACPI_REFCLASS_NAME) { |
315 | ACPI_ERROR((AE_INFO, | 314 | ACPI_ERROR((AE_INFO, |
316 | "(PRT[%X].Source) Need name, found reference op %X", | 315 | "(PRT[%X].Source) Need name, found Reference Class %X", |
317 | index, | 316 | index, |
318 | obj_desc->reference. | 317 | obj_desc->reference.class)); |
319 | opcode)); | ||
320 | return_ACPI_STATUS(AE_BAD_DATA); | 318 | return_ACPI_STATUS(AE_BAD_DATA); |
321 | } | 319 | } |
322 | 320 | ||
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 7b011e7e29fe..6050ce481873 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -931,7 +931,7 @@ static int acpi_sbs_add(struct acpi_device *device) | |||
931 | sbs->device = device; | 931 | sbs->device = device; |
932 | strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME); | 932 | strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME); |
933 | strcpy(acpi_device_class(device), ACPI_SBS_CLASS); | 933 | strcpy(acpi_device_class(device), ACPI_SBS_CLASS); |
934 | acpi_driver_data(device) = sbs; | 934 | device->driver_data = sbs; |
935 | 935 | ||
936 | result = acpi_charger_add(sbs); | 936 | result = acpi_charger_add(sbs); |
937 | if (result) | 937 | if (result) |
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index a4e3767b8c64..e53e590252c0 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c | |||
@@ -258,7 +258,7 @@ extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, | |||
258 | static int acpi_smbus_hc_add(struct acpi_device *device) | 258 | static int acpi_smbus_hc_add(struct acpi_device *device) |
259 | { | 259 | { |
260 | int status; | 260 | int status; |
261 | unsigned long val; | 261 | unsigned long long val; |
262 | struct acpi_smb_hc *hc; | 262 | struct acpi_smb_hc *hc; |
263 | 263 | ||
264 | if (!device) | 264 | if (!device) |
@@ -282,7 +282,7 @@ static int acpi_smbus_hc_add(struct acpi_device *device) | |||
282 | hc->ec = acpi_driver_data(device->parent); | 282 | hc->ec = acpi_driver_data(device->parent); |
283 | hc->offset = (val >> 8) & 0xff; | 283 | hc->offset = (val >> 8) & 0xff; |
284 | hc->query_bit = val & 0xff; | 284 | hc->query_bit = val & 0xff; |
285 | acpi_driver_data(device) = hc; | 285 | device->driver_data = hc; |
286 | 286 | ||
287 | acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc); | 287 | acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc); |
288 | printk(KERN_INFO PREFIX "SBS HC: EC = 0x%p, offset = 0x%0x, query_bit = 0x%0x\n", | 288 | printk(KERN_INFO PREFIX "SBS HC: EC = 0x%p, offset = 0x%0x, query_bit = 0x%0x\n", |
@@ -303,7 +303,7 @@ static int acpi_smbus_hc_remove(struct acpi_device *device, int type) | |||
303 | hc = acpi_driver_data(device); | 303 | hc = acpi_driver_data(device); |
304 | acpi_ec_remove_query_handler(hc->ec, hc->query_bit); | 304 | acpi_ec_remove_query_handler(hc->ec, hc->query_bit); |
305 | kfree(hc); | 305 | kfree(hc); |
306 | acpi_driver_data(device) = NULL; | 306 | device->driver_data = NULL; |
307 | return 0; | 307 | return 0; |
308 | } | 308 | } |
309 | 309 | ||
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index f6f52c1a2aba..a9dda8e0f9f9 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -113,16 +113,16 @@ static int acpi_bus_hot_remove_device(void *context) | |||
113 | 113 | ||
114 | 114 | ||
115 | if (acpi_bus_trim(device, 1)) { | 115 | if (acpi_bus_trim(device, 1)) { |
116 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 116 | printk(KERN_ERR PREFIX |
117 | "Removing device failed\n")); | 117 | "Removing device failed\n"); |
118 | return -1; | 118 | return -1; |
119 | } | 119 | } |
120 | 120 | ||
121 | /* power off device */ | 121 | /* power off device */ |
122 | status = acpi_evaluate_object(handle, "_PS3", NULL, NULL); | 122 | status = acpi_evaluate_object(handle, "_PS3", NULL, NULL); |
123 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) | 123 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) |
124 | ACPI_DEBUG_PRINT((ACPI_DB_WARN, | 124 | printk(KERN_WARNING PREFIX |
125 | "Power-off device failed\n")); | 125 | "Power-off device failed\n"); |
126 | 126 | ||
127 | if (device->flags.lockable) { | 127 | if (device->flags.lockable) { |
128 | arg_list.count = 1; | 128 | arg_list.count = 1; |
@@ -276,6 +276,13 @@ int acpi_match_device_ids(struct acpi_device *device, | |||
276 | { | 276 | { |
277 | const struct acpi_device_id *id; | 277 | const struct acpi_device_id *id; |
278 | 278 | ||
279 | /* | ||
280 | * If the device is not present, it is unnecessary to load device | ||
281 | * driver for it. | ||
282 | */ | ||
283 | if (!device->status.present) | ||
284 | return -ENODEV; | ||
285 | |||
279 | if (device->flags.hardware_id) { | 286 | if (device->flags.hardware_id) { |
280 | for (id = ids; id->id[0]; id++) { | 287 | for (id = ids; id->id[0]; id++) { |
281 | if (!strcmp((char*)id->id, device->pnp.hardware_id)) | 288 | if (!strcmp((char*)id->id, device->pnp.hardware_id)) |
@@ -384,7 +391,7 @@ static int acpi_device_remove(struct device * dev) | |||
384 | acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); | 391 | acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); |
385 | } | 392 | } |
386 | acpi_dev->driver = NULL; | 393 | acpi_dev->driver = NULL; |
387 | acpi_driver_data(dev) = NULL; | 394 | acpi_dev->driver_data = NULL; |
388 | 395 | ||
389 | put_device(dev); | 396 | put_device(dev); |
390 | return 0; | 397 | return 0; |
@@ -477,7 +484,7 @@ static int acpi_device_register(struct acpi_device *device, | |||
477 | 484 | ||
478 | result = acpi_device_setup_files(device); | 485 | result = acpi_device_setup_files(device); |
479 | if(result) | 486 | if(result) |
480 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error creating sysfs interface for device %s\n", device->dev.bus_id)); | 487 | printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", device->dev.bus_id); |
481 | 488 | ||
482 | device->removal_type = ACPI_BUS_REMOVAL_NORMAL; | 489 | device->removal_type = ACPI_BUS_REMOVAL_NORMAL; |
483 | return 0; | 490 | return 0; |
@@ -537,7 +544,7 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver) | |||
537 | result = driver->ops.add(device); | 544 | result = driver->ops.add(device); |
538 | if (result) { | 545 | if (result) { |
539 | device->driver = NULL; | 546 | device->driver = NULL; |
540 | acpi_driver_data(device) = NULL; | 547 | device->driver_data = NULL; |
541 | return result; | 548 | return result; |
542 | } | 549 | } |
543 | 550 | ||
@@ -744,6 +751,16 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
744 | if (!acpi_match_device_ids(device, button_device_ids)) | 751 | if (!acpi_match_device_ids(device, button_device_ids)) |
745 | device->wakeup.flags.run_wake = 1; | 752 | device->wakeup.flags.run_wake = 1; |
746 | 753 | ||
754 | /* | ||
755 | * Don't set Power button GPE as run_wake | ||
756 | * if Fixed Power button is used | ||
757 | */ | ||
758 | if (!strcmp(device->pnp.hardware_id, "PNP0C0C") && | ||
759 | !(acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON)) { | ||
760 | device->wakeup.flags.run_wake = 0; | ||
761 | device->wakeup.flags.valid = 0; | ||
762 | } | ||
763 | |||
747 | end: | 764 | end: |
748 | if (ACPI_FAILURE(status)) | 765 | if (ACPI_FAILURE(status)) |
749 | device->flags.wake_capable = 0; | 766 | device->flags.wake_capable = 0; |
@@ -807,6 +824,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) | |||
807 | /* TBD: System wake support and resource requirements. */ | 824 | /* TBD: System wake support and resource requirements. */ |
808 | 825 | ||
809 | device->power.state = ACPI_STATE_UNKNOWN; | 826 | device->power.state = ACPI_STATE_UNKNOWN; |
827 | acpi_bus_get_power(device->handle, &(device->power.state)); | ||
810 | 828 | ||
811 | return 0; | 829 | return 0; |
812 | } | 830 | } |
@@ -1153,20 +1171,6 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) | |||
1153 | } | 1171 | } |
1154 | 1172 | ||
1155 | static int | 1173 | static int |
1156 | acpi_is_child_device(struct acpi_device *device, | ||
1157 | int (*matcher)(struct acpi_device *)) | ||
1158 | { | ||
1159 | int result = -ENODEV; | ||
1160 | |||
1161 | do { | ||
1162 | if (ACPI_SUCCESS(matcher(device))) | ||
1163 | return AE_OK; | ||
1164 | } while ((device = device->parent)); | ||
1165 | |||
1166 | return result; | ||
1167 | } | ||
1168 | |||
1169 | static int | ||
1170 | acpi_add_single_object(struct acpi_device **child, | 1174 | acpi_add_single_object(struct acpi_device **child, |
1171 | struct acpi_device *parent, acpi_handle handle, int type, | 1175 | struct acpi_device *parent, acpi_handle handle, int type, |
1172 | struct acpi_bus_ops *ops) | 1176 | struct acpi_bus_ops *ops) |
@@ -1221,15 +1225,18 @@ acpi_add_single_object(struct acpi_device **child, | |||
1221 | result = -ENODEV; | 1225 | result = -ENODEV; |
1222 | goto end; | 1226 | goto end; |
1223 | } | 1227 | } |
1224 | if (!device->status.present) { | 1228 | /* |
1225 | /* Bay and dock should be handled even if absent */ | 1229 | * When the device is neither present nor functional, the |
1226 | if (!ACPI_SUCCESS( | 1230 | * device should not be added to Linux ACPI device tree. |
1227 | acpi_is_child_device(device, acpi_bay_match)) && | 1231 | * When the status of the device is not present but functinal, |
1228 | !ACPI_SUCCESS( | 1232 | * it should be added to Linux ACPI tree. For example : bay |
1229 | acpi_is_child_device(device, acpi_dock_match))) { | 1233 | * device , dock device. |
1230 | result = -ENODEV; | 1234 | * In such conditions it is unncessary to check whether it is |
1231 | goto end; | 1235 | * bay device or dock device. |
1232 | } | 1236 | */ |
1237 | if (!device->status.present && !device->status.functional) { | ||
1238 | result = -ENODEV; | ||
1239 | goto end; | ||
1233 | } | 1240 | } |
1234 | break; | 1241 | break; |
1235 | default: | 1242 | default: |
@@ -1252,6 +1259,16 @@ acpi_add_single_object(struct acpi_device **child, | |||
1252 | acpi_device_set_id(device, parent, handle, type); | 1259 | acpi_device_set_id(device, parent, handle, type); |
1253 | 1260 | ||
1254 | /* | 1261 | /* |
1262 | * The ACPI device is attached to acpi handle before getting | ||
1263 | * the power/wakeup/peformance flags. Otherwise OS can't get | ||
1264 | * the corresponding ACPI device by the acpi handle in the course | ||
1265 | * of getting the power/wakeup/performance flags. | ||
1266 | */ | ||
1267 | result = acpi_device_set_context(device, type); | ||
1268 | if (result) | ||
1269 | goto end; | ||
1270 | |||
1271 | /* | ||
1255 | * Power Management | 1272 | * Power Management |
1256 | * ---------------- | 1273 | * ---------------- |
1257 | */ | 1274 | */ |
@@ -1281,8 +1298,6 @@ acpi_add_single_object(struct acpi_device **child, | |||
1281 | goto end; | 1298 | goto end; |
1282 | } | 1299 | } |
1283 | 1300 | ||
1284 | if ((result = acpi_device_set_context(device, type))) | ||
1285 | goto end; | ||
1286 | 1301 | ||
1287 | result = acpi_device_register(device, parent); | 1302 | result = acpi_device_register(device, parent); |
1288 | 1303 | ||
@@ -1402,7 +1417,12 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops) | |||
1402 | * TBD: Need notifications and other detection mechanisms | 1417 | * TBD: Need notifications and other detection mechanisms |
1403 | * in place before we can fully implement this. | 1418 | * in place before we can fully implement this. |
1404 | */ | 1419 | */ |
1405 | if (child->status.present) { | 1420 | /* |
1421 | * When the device is not present but functional, it is also | ||
1422 | * necessary to scan the children of this device. | ||
1423 | */ | ||
1424 | if (child->status.present || (!child->status.present && | ||
1425 | child->status.functional)) { | ||
1406 | status = acpi_get_next_object(ACPI_TYPE_ANY, chandle, | 1426 | status = acpi_get_next_object(ACPI_TYPE_ANY, chandle, |
1407 | NULL, NULL); | 1427 | NULL, NULL); |
1408 | if (ACPI_SUCCESS(status)) { | 1428 | if (ACPI_SUCCESS(status)) { |
@@ -1545,7 +1565,6 @@ static int acpi_bus_scan_fixed(struct acpi_device *root) | |||
1545 | return result; | 1565 | return result; |
1546 | } | 1566 | } |
1547 | 1567 | ||
1548 | int __init acpi_boot_ec_enable(void); | ||
1549 | 1568 | ||
1550 | static int __init acpi_scan_init(void) | 1569 | static int __init acpi_scan_init(void) |
1551 | { | 1570 | { |
@@ -1579,9 +1598,6 @@ static int __init acpi_scan_init(void) | |||
1579 | */ | 1598 | */ |
1580 | result = acpi_bus_scan_fixed(acpi_root); | 1599 | result = acpi_bus_scan_fixed(acpi_root); |
1581 | 1600 | ||
1582 | /* EC region might be needed at bus_scan, so enable it now */ | ||
1583 | acpi_boot_ec_enable(); | ||
1584 | |||
1585 | if (!result) | 1601 | if (!result) |
1586 | result = acpi_bus_scan(acpi_root, &ops); | 1602 | result = acpi_bus_scan(acpi_root, &ops); |
1587 | 1603 | ||
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index d13194a031bf..26571bafb158 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/dmi.h> | 15 | #include <linux/dmi.h> |
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/suspend.h> | 17 | #include <linux/suspend.h> |
18 | #include <linux/reboot.h> | ||
18 | 19 | ||
19 | #include <asm/io.h> | 20 | #include <asm/io.h> |
20 | 21 | ||
@@ -24,6 +25,36 @@ | |||
24 | 25 | ||
25 | u8 sleep_states[ACPI_S_STATE_COUNT]; | 26 | u8 sleep_states[ACPI_S_STATE_COUNT]; |
26 | 27 | ||
28 | static void acpi_sleep_tts_switch(u32 acpi_state) | ||
29 | { | ||
30 | union acpi_object in_arg = { ACPI_TYPE_INTEGER }; | ||
31 | struct acpi_object_list arg_list = { 1, &in_arg }; | ||
32 | acpi_status status = AE_OK; | ||
33 | |||
34 | in_arg.integer.value = acpi_state; | ||
35 | status = acpi_evaluate_object(NULL, "\\_TTS", &arg_list, NULL); | ||
36 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
37 | /* | ||
38 | * OS can't evaluate the _TTS object correctly. Some warning | ||
39 | * message will be printed. But it won't break anything. | ||
40 | */ | ||
41 | printk(KERN_NOTICE "Failure in evaluating _TTS object\n"); | ||
42 | } | ||
43 | } | ||
44 | |||
45 | static int tts_notify_reboot(struct notifier_block *this, | ||
46 | unsigned long code, void *x) | ||
47 | { | ||
48 | acpi_sleep_tts_switch(ACPI_STATE_S5); | ||
49 | return NOTIFY_DONE; | ||
50 | } | ||
51 | |||
52 | static struct notifier_block tts_notifier = { | ||
53 | .notifier_call = tts_notify_reboot, | ||
54 | .next = NULL, | ||
55 | .priority = 0, | ||
56 | }; | ||
57 | |||
27 | static int acpi_sleep_prepare(u32 acpi_state) | 58 | static int acpi_sleep_prepare(u32 acpi_state) |
28 | { | 59 | { |
29 | #ifdef CONFIG_ACPI_SLEEP | 60 | #ifdef CONFIG_ACPI_SLEEP |
@@ -45,9 +76,8 @@ static int acpi_sleep_prepare(u32 acpi_state) | |||
45 | return 0; | 76 | return 0; |
46 | } | 77 | } |
47 | 78 | ||
48 | #ifdef CONFIG_PM_SLEEP | 79 | #ifdef CONFIG_ACPI_SLEEP |
49 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | 80 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; |
50 | |||
51 | /* | 81 | /* |
52 | * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the | 82 | * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the |
53 | * user to request that behavior by using the 'acpi_old_suspend_ordering' | 83 | * user to request that behavior by using the 'acpi_old_suspend_ordering' |
@@ -131,8 +161,9 @@ static void acpi_pm_end(void) | |||
131 | * failing transition to a sleep state. | 161 | * failing transition to a sleep state. |
132 | */ | 162 | */ |
133 | acpi_target_sleep_state = ACPI_STATE_S0; | 163 | acpi_target_sleep_state = ACPI_STATE_S0; |
164 | acpi_sleep_tts_switch(acpi_target_sleep_state); | ||
134 | } | 165 | } |
135 | #endif /* CONFIG_PM_SLEEP */ | 166 | #endif /* CONFIG_ACPI_SLEEP */ |
136 | 167 | ||
137 | #ifdef CONFIG_SUSPEND | 168 | #ifdef CONFIG_SUSPEND |
138 | extern void do_suspend_lowlevel(void); | 169 | extern void do_suspend_lowlevel(void); |
@@ -155,6 +186,7 @@ static int acpi_suspend_begin(suspend_state_t pm_state) | |||
155 | 186 | ||
156 | if (sleep_states[acpi_state]) { | 187 | if (sleep_states[acpi_state]) { |
157 | acpi_target_sleep_state = acpi_state; | 188 | acpi_target_sleep_state = acpi_state; |
189 | acpi_sleep_tts_switch(acpi_target_sleep_state); | ||
158 | } else { | 190 | } else { |
159 | printk(KERN_ERR "ACPI does not support this state: %d\n", | 191 | printk(KERN_ERR "ACPI does not support this state: %d\n", |
160 | pm_state); | 192 | pm_state); |
@@ -200,6 +232,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
200 | break; | 232 | break; |
201 | } | 233 | } |
202 | 234 | ||
235 | /* If ACPI is not enabled by the BIOS, we need to enable it here. */ | ||
236 | acpi_enable(); | ||
203 | /* Reprogram control registers and execute _BFS */ | 237 | /* Reprogram control registers and execute _BFS */ |
204 | acpi_leave_sleep_state_prep(acpi_state); | 238 | acpi_leave_sleep_state_prep(acpi_state); |
205 | 239 | ||
@@ -296,6 +330,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
296 | DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"), | 330 | DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"), |
297 | }, | 331 | }, |
298 | }, | 332 | }, |
333 | { | ||
334 | .callback = init_old_suspend_ordering, | ||
335 | .ident = "HP xw4600 Workstation", | ||
336 | .matches = { | ||
337 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
338 | DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"), | ||
339 | }, | ||
340 | }, | ||
299 | {}, | 341 | {}, |
300 | }; | 342 | }; |
301 | #endif /* CONFIG_SUSPEND */ | 343 | #endif /* CONFIG_SUSPEND */ |
@@ -313,6 +355,7 @@ void __init acpi_no_s4_hw_signature(void) | |||
313 | static int acpi_hibernation_begin(void) | 355 | static int acpi_hibernation_begin(void) |
314 | { | 356 | { |
315 | acpi_target_sleep_state = ACPI_STATE_S4; | 357 | acpi_target_sleep_state = ACPI_STATE_S4; |
358 | acpi_sleep_tts_switch(acpi_target_sleep_state); | ||
316 | return 0; | 359 | return 0; |
317 | } | 360 | } |
318 | 361 | ||
@@ -376,7 +419,15 @@ static struct platform_hibernation_ops acpi_hibernation_ops = { | |||
376 | */ | 419 | */ |
377 | static int acpi_hibernation_begin_old(void) | 420 | static int acpi_hibernation_begin_old(void) |
378 | { | 421 | { |
379 | int error = acpi_sleep_prepare(ACPI_STATE_S4); | 422 | int error; |
423 | /* | ||
424 | * The _TTS object should always be evaluated before the _PTS object. | ||
425 | * When the old_suspended_ordering is true, the _PTS object is | ||
426 | * evaluated in the acpi_sleep_prepare. | ||
427 | */ | ||
428 | acpi_sleep_tts_switch(ACPI_STATE_S4); | ||
429 | |||
430 | error = acpi_sleep_prepare(ACPI_STATE_S4); | ||
380 | 431 | ||
381 | if (!error) | 432 | if (!error) |
382 | acpi_target_sleep_state = ACPI_STATE_S4; | 433 | acpi_target_sleep_state = ACPI_STATE_S4; |
@@ -444,7 +495,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) | |||
444 | acpi_handle handle = DEVICE_ACPI_HANDLE(dev); | 495 | acpi_handle handle = DEVICE_ACPI_HANDLE(dev); |
445 | struct acpi_device *adev; | 496 | struct acpi_device *adev; |
446 | char acpi_method[] = "_SxD"; | 497 | char acpi_method[] = "_SxD"; |
447 | unsigned long d_min, d_max; | 498 | unsigned long long d_min, d_max; |
448 | 499 | ||
449 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { | 500 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { |
450 | printk(KERN_DEBUG "ACPI handle has no context!\n"); | 501 | printk(KERN_DEBUG "ACPI handle has no context!\n"); |
@@ -596,5 +647,10 @@ int __init acpi_sleep_init(void) | |||
596 | pm_power_off = acpi_power_off; | 647 | pm_power_off = acpi_power_off; |
597 | } | 648 | } |
598 | printk(")\n"); | 649 | printk(")\n"); |
650 | /* | ||
651 | * Register the tts_notifier to reboot notifier list so that the _TTS | ||
652 | * object can also be evaluated when the system enters S5. | ||
653 | */ | ||
654 | register_reboot_notifier(&tts_notifier); | ||
599 | return 0; | 655 | return 0; |
600 | } | 656 | } |
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 24e80fd927e2..1d74171b7940 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c | |||
@@ -386,8 +386,8 @@ static ssize_t counter_set(struct kobject *kobj, | |||
386 | goto end; | 386 | goto end; |
387 | 387 | ||
388 | if (!(all_counters[index].flags & ACPI_EVENT_VALID)) { | 388 | if (!(all_counters[index].flags & ACPI_EVENT_VALID)) { |
389 | ACPI_DEBUG_PRINT((ACPI_DB_WARN, | 389 | printk(KERN_WARNING PREFIX |
390 | "Can not change Invalid GPE/Fixed Event status\n")); | 390 | "Can not change Invalid GPE/Fixed Event status\n"); |
391 | return -EINVAL; | 391 | return -EINVAL; |
392 | } | 392 | } |
393 | 393 | ||
diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c index a4a41ba2484b..2c7885e7ffba 100644 --- a/drivers/acpi/tables/tbfadt.c +++ b/drivers/acpi/tables/tbfadt.c | |||
@@ -50,7 +50,7 @@ ACPI_MODULE_NAME("tbfadt") | |||
50 | /* Local prototypes */ | 50 | /* Local prototypes */ |
51 | static void inline | 51 | static void inline |
52 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, | 52 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, |
53 | u8 bit_width, u64 address); | 53 | u8 byte_width, u64 address); |
54 | 54 | ||
55 | static void acpi_tb_convert_fadt(void); | 55 | static void acpi_tb_convert_fadt(void); |
56 | 56 | ||
@@ -111,7 +111,7 @@ static struct acpi_fadt_info fadt_info_table[] = { | |||
111 | * FUNCTION: acpi_tb_init_generic_address | 111 | * FUNCTION: acpi_tb_init_generic_address |
112 | * | 112 | * |
113 | * PARAMETERS: generic_address - GAS struct to be initialized | 113 | * PARAMETERS: generic_address - GAS struct to be initialized |
114 | * bit_width - Width of this register | 114 | * byte_width - Width of this register |
115 | * Address - Address of the register | 115 | * Address - Address of the register |
116 | * | 116 | * |
117 | * RETURN: None | 117 | * RETURN: None |
@@ -124,7 +124,7 @@ static struct acpi_fadt_info fadt_info_table[] = { | |||
124 | 124 | ||
125 | static void inline | 125 | static void inline |
126 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, | 126 | acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, |
127 | u8 bit_width, u64 address) | 127 | u8 byte_width, u64 address) |
128 | { | 128 | { |
129 | 129 | ||
130 | /* | 130 | /* |
@@ -136,7 +136,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, | |||
136 | /* All other fields are byte-wide */ | 136 | /* All other fields are byte-wide */ |
137 | 137 | ||
138 | generic_address->space_id = ACPI_ADR_SPACE_SYSTEM_IO; | 138 | generic_address->space_id = ACPI_ADR_SPACE_SYSTEM_IO; |
139 | generic_address->bit_width = bit_width; | 139 | generic_address->bit_width = byte_width << 3; |
140 | generic_address->bit_offset = 0; | 140 | generic_address->bit_offset = 0; |
141 | generic_address->access_width = 0; | 141 | generic_address->access_width = 0; |
142 | } | 142 | } |
@@ -342,9 +342,20 @@ static void acpi_tb_convert_fadt(void) | |||
342 | * useful to calculate them once, here. | 342 | * useful to calculate them once, here. |
343 | * | 343 | * |
344 | * The PM event blocks are split into two register blocks, first is the | 344 | * The PM event blocks are split into two register blocks, first is the |
345 | * PM Status Register block, followed immediately by the PM Enable Register | 345 | * PM Status Register block, followed immediately by the PM Enable |
346 | * block. Each is of length (pm1_event_length/2) | 346 | * Register block. Each is of length (xpm1x_event_block.bit_width/2). |
347 | * | ||
348 | * On various systems the v2 fields (and particularly the bit widths) | ||
349 | * cannot be relied upon, though. Hence resort to using the v1 length | ||
350 | * here (and warn about the inconsistency). | ||
347 | */ | 351 | */ |
352 | if (acpi_gbl_FADT.xpm1a_event_block.bit_width | ||
353 | != acpi_gbl_FADT.pm1_event_length * 8) | ||
354 | printk(KERN_WARNING "FADT: " | ||
355 | "X_PM1a_EVT_BLK.bit_width (%u) does not match" | ||
356 | " PM1_EVT_LEN (%u)\n", | ||
357 | acpi_gbl_FADT.xpm1a_event_block.bit_width, | ||
358 | acpi_gbl_FADT.pm1_event_length); | ||
348 | pm1_register_length = (u8) ACPI_DIV_2(acpi_gbl_FADT.pm1_event_length); | 359 | pm1_register_length = (u8) ACPI_DIV_2(acpi_gbl_FADT.pm1_event_length); |
349 | 360 | ||
350 | /* The PM1A register block is required */ | 361 | /* The PM1A register block is required */ |
@@ -360,13 +371,20 @@ static void acpi_tb_convert_fadt(void) | |||
360 | /* The PM1B register block is optional, ignore if not present */ | 371 | /* The PM1B register block is optional, ignore if not present */ |
361 | 372 | ||
362 | if (acpi_gbl_FADT.xpm1b_event_block.address) { | 373 | if (acpi_gbl_FADT.xpm1b_event_block.address) { |
374 | if (acpi_gbl_FADT.xpm1b_event_block.bit_width | ||
375 | != acpi_gbl_FADT.pm1_event_length * 8) | ||
376 | printk(KERN_WARNING "FADT: " | ||
377 | "X_PM1b_EVT_BLK.bit_width (%u) does not match" | ||
378 | " PM1_EVT_LEN (%u)\n", | ||
379 | acpi_gbl_FADT.xpm1b_event_block.bit_width, | ||
380 | acpi_gbl_FADT.pm1_event_length); | ||
363 | acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, | 381 | acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, |
364 | pm1_register_length, | 382 | pm1_register_length, |
365 | (acpi_gbl_FADT.xpm1b_event_block. | 383 | (acpi_gbl_FADT.xpm1b_event_block. |
366 | address + pm1_register_length)); | 384 | address + pm1_register_length)); |
367 | /* Don't forget to copy space_id of the GAS */ | 385 | /* Don't forget to copy space_id of the GAS */ |
368 | acpi_gbl_xpm1b_enable.space_id = | 386 | acpi_gbl_xpm1b_enable.space_id = |
369 | acpi_gbl_FADT.xpm1a_event_block.space_id; | 387 | acpi_gbl_FADT.xpm1b_event_block.space_id; |
370 | 388 | ||
371 | } | 389 | } |
372 | } | 390 | } |
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index b22185f55a16..18747ce8dd2f 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c | |||
@@ -110,7 +110,6 @@ acpi_status | |||
110 | acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) | 110 | acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) |
111 | { | 111 | { |
112 | u32 i; | 112 | u32 i; |
113 | u32 length; | ||
114 | acpi_status status = AE_OK; | 113 | acpi_status status = AE_OK; |
115 | 114 | ||
116 | ACPI_FUNCTION_TRACE(tb_add_table); | 115 | ACPI_FUNCTION_TRACE(tb_add_table); |
@@ -145,25 +144,64 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) | |||
145 | } | 144 | } |
146 | } | 145 | } |
147 | 146 | ||
148 | length = ACPI_MIN(table_desc->length, | 147 | /* |
149 | acpi_gbl_root_table_list.tables[i].length); | 148 | * Check for a table match on the entire table length, |
149 | * not just the header. | ||
150 | */ | ||
151 | if (table_desc->length != | ||
152 | acpi_gbl_root_table_list.tables[i].length) { | ||
153 | continue; | ||
154 | } | ||
155 | |||
150 | if (ACPI_MEMCMP(table_desc->pointer, | 156 | if (ACPI_MEMCMP(table_desc->pointer, |
151 | acpi_gbl_root_table_list.tables[i].pointer, | 157 | acpi_gbl_root_table_list.tables[i].pointer, |
152 | length)) { | 158 | acpi_gbl_root_table_list.tables[i].length)) { |
153 | continue; | 159 | continue; |
154 | } | 160 | } |
155 | 161 | ||
156 | /* Table is already registered */ | 162 | /* |
157 | 163 | * Note: the current mechanism does not unregister a table if it is | |
164 | * dynamically unloaded. The related namespace entries are deleted, | ||
165 | * but the table remains in the root table list. | ||
166 | * | ||
167 | * The assumption here is that the number of different tables that | ||
168 | * will be loaded is actually small, and there is minimal overhead | ||
169 | * in just keeping the table in case it is needed again. | ||
170 | * | ||
171 | * If this assumption changes in the future (perhaps on large | ||
172 | * machines with many table load/unload operations), tables will | ||
173 | * need to be unregistered when they are unloaded, and slots in the | ||
174 | * root table list should be reused when empty. | ||
175 | */ | ||
176 | |||
177 | /* | ||
178 | * Table is already registered. | ||
179 | * We can delete the table that was passed as a parameter. | ||
180 | */ | ||
158 | acpi_tb_delete_table(table_desc); | 181 | acpi_tb_delete_table(table_desc); |
159 | *table_index = i; | 182 | *table_index = i; |
160 | status = AE_ALREADY_EXISTS; | 183 | |
161 | goto release; | 184 | if (acpi_gbl_root_table_list.tables[i]. |
185 | flags & ACPI_TABLE_IS_LOADED) { | ||
186 | |||
187 | /* Table is still loaded, this is an error */ | ||
188 | |||
189 | status = AE_ALREADY_EXISTS; | ||
190 | goto release; | ||
191 | } else { | ||
192 | /* Table was unloaded, allow it to be reloaded */ | ||
193 | |||
194 | table_desc->pointer = | ||
195 | acpi_gbl_root_table_list.tables[i].pointer; | ||
196 | table_desc->address = | ||
197 | acpi_gbl_root_table_list.tables[i].address; | ||
198 | status = AE_OK; | ||
199 | goto print_header; | ||
200 | } | ||
162 | } | 201 | } |
163 | 202 | ||
164 | /* | 203 | /* Add the table to the global root table list */ |
165 | * Add the table to the global table list | 204 | |
166 | */ | ||
167 | status = acpi_tb_store_table(table_desc->address, table_desc->pointer, | 205 | status = acpi_tb_store_table(table_desc->address, table_desc->pointer, |
168 | table_desc->length, table_desc->flags, | 206 | table_desc->length, table_desc->flags, |
169 | table_index); | 207 | table_index); |
@@ -171,6 +209,7 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) | |||
171 | goto release; | 209 | goto release; |
172 | } | 210 | } |
173 | 211 | ||
212 | print_header: | ||
174 | acpi_tb_print_table_header(table_desc->address, table_desc->pointer); | 213 | acpi_tb_print_table_header(table_desc->address, table_desc->pointer); |
175 | 214 | ||
176 | release: | 215 | release: |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 912703691d36..ad6cae938f0b 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -246,18 +246,18 @@ static const struct file_operations acpi_thermal_polling_fops = { | |||
246 | static int acpi_thermal_get_temperature(struct acpi_thermal *tz) | 246 | static int acpi_thermal_get_temperature(struct acpi_thermal *tz) |
247 | { | 247 | { |
248 | acpi_status status = AE_OK; | 248 | acpi_status status = AE_OK; |
249 | 249 | unsigned long long tmp; | |
250 | 250 | ||
251 | if (!tz) | 251 | if (!tz) |
252 | return -EINVAL; | 252 | return -EINVAL; |
253 | 253 | ||
254 | tz->last_temperature = tz->temperature; | 254 | tz->last_temperature = tz->temperature; |
255 | 255 | ||
256 | status = | 256 | status = acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tmp); |
257 | acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tz->temperature); | ||
258 | if (ACPI_FAILURE(status)) | 257 | if (ACPI_FAILURE(status)) |
259 | return -ENODEV; | 258 | return -ENODEV; |
260 | 259 | ||
260 | tz->temperature = tmp; | ||
261 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n", | 261 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n", |
262 | tz->temperature)); | 262 | tz->temperature)); |
263 | 263 | ||
@@ -267,17 +267,16 @@ static int acpi_thermal_get_temperature(struct acpi_thermal *tz) | |||
267 | static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) | 267 | static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) |
268 | { | 268 | { |
269 | acpi_status status = AE_OK; | 269 | acpi_status status = AE_OK; |
270 | 270 | unsigned long long tmp; | |
271 | 271 | ||
272 | if (!tz) | 272 | if (!tz) |
273 | return -EINVAL; | 273 | return -EINVAL; |
274 | 274 | ||
275 | status = | 275 | status = acpi_evaluate_integer(tz->device->handle, "_TZP", NULL, &tmp); |
276 | acpi_evaluate_integer(tz->device->handle, "_TZP", NULL, | ||
277 | &tz->polling_frequency); | ||
278 | if (ACPI_FAILURE(status)) | 276 | if (ACPI_FAILURE(status)) |
279 | return -ENODEV; | 277 | return -ENODEV; |
280 | 278 | ||
279 | tz->polling_frequency = tmp; | ||
281 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n", | 280 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n", |
282 | tz->polling_frequency)); | 281 | tz->polling_frequency)); |
283 | 282 | ||
@@ -356,6 +355,7 @@ do { \ | |||
356 | static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | 355 | static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) |
357 | { | 356 | { |
358 | acpi_status status = AE_OK; | 357 | acpi_status status = AE_OK; |
358 | unsigned long long tmp; | ||
359 | struct acpi_handle_list devices; | 359 | struct acpi_handle_list devices; |
360 | int valid = 0; | 360 | int valid = 0; |
361 | int i; | 361 | int i; |
@@ -363,7 +363,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
363 | /* Critical Shutdown (required) */ | 363 | /* Critical Shutdown (required) */ |
364 | if (flag & ACPI_TRIPS_CRITICAL) { | 364 | if (flag & ACPI_TRIPS_CRITICAL) { |
365 | status = acpi_evaluate_integer(tz->device->handle, | 365 | status = acpi_evaluate_integer(tz->device->handle, |
366 | "_CRT", NULL, &tz->trips.critical.temperature); | 366 | "_CRT", NULL, &tmp); |
367 | tz->trips.critical.temperature = tmp; | ||
367 | /* | 368 | /* |
368 | * Treat freezing temperatures as invalid as well; some | 369 | * Treat freezing temperatures as invalid as well; some |
369 | * BIOSes return really low values and cause reboots at startup. | 370 | * BIOSes return really low values and cause reboots at startup. |
@@ -388,10 +389,12 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
388 | } else if (crt > 0) { | 389 | } else if (crt > 0) { |
389 | unsigned long crt_k = CELSIUS_TO_KELVIN(crt); | 390 | unsigned long crt_k = CELSIUS_TO_KELVIN(crt); |
390 | /* | 391 | /* |
391 | * Allow override to lower critical threshold | 392 | * Allow override critical threshold |
392 | */ | 393 | */ |
393 | if (crt_k < tz->trips.critical.temperature) | 394 | if (crt_k > tz->trips.critical.temperature) |
394 | tz->trips.critical.temperature = crt_k; | 395 | printk(KERN_WARNING PREFIX |
396 | "Critical threshold %d C\n", crt); | ||
397 | tz->trips.critical.temperature = crt_k; | ||
395 | } | 398 | } |
396 | } | 399 | } |
397 | } | 400 | } |
@@ -399,12 +402,13 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
399 | /* Critical Sleep (optional) */ | 402 | /* Critical Sleep (optional) */ |
400 | if (flag & ACPI_TRIPS_HOT) { | 403 | if (flag & ACPI_TRIPS_HOT) { |
401 | status = acpi_evaluate_integer(tz->device->handle, | 404 | status = acpi_evaluate_integer(tz->device->handle, |
402 | "_HOT", NULL, &tz->trips.hot.temperature); | 405 | "_HOT", NULL, &tmp); |
403 | if (ACPI_FAILURE(status)) { | 406 | if (ACPI_FAILURE(status)) { |
404 | tz->trips.hot.flags.valid = 0; | 407 | tz->trips.hot.flags.valid = 0; |
405 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 408 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
406 | "No hot threshold\n")); | 409 | "No hot threshold\n")); |
407 | } else { | 410 | } else { |
411 | tz->trips.hot.temperature = tmp; | ||
408 | tz->trips.hot.flags.valid = 1; | 412 | tz->trips.hot.flags.valid = 1; |
409 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 413 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
410 | "Found hot threshold [%lu]\n", | 414 | "Found hot threshold [%lu]\n", |
@@ -418,33 +422,40 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
418 | if (psv == -1) { | 422 | if (psv == -1) { |
419 | status = AE_SUPPORT; | 423 | status = AE_SUPPORT; |
420 | } else if (psv > 0) { | 424 | } else if (psv > 0) { |
421 | tz->trips.passive.temperature = CELSIUS_TO_KELVIN(psv); | 425 | tmp = CELSIUS_TO_KELVIN(psv); |
422 | status = AE_OK; | 426 | status = AE_OK; |
423 | } else { | 427 | } else { |
424 | status = acpi_evaluate_integer(tz->device->handle, | 428 | status = acpi_evaluate_integer(tz->device->handle, |
425 | "_PSV", NULL, &tz->trips.passive.temperature); | 429 | "_PSV", NULL, &tmp); |
426 | } | 430 | } |
427 | 431 | ||
428 | if (ACPI_FAILURE(status)) | 432 | if (ACPI_FAILURE(status)) |
429 | tz->trips.passive.flags.valid = 0; | 433 | tz->trips.passive.flags.valid = 0; |
430 | else { | 434 | else { |
435 | tz->trips.passive.temperature = tmp; | ||
431 | tz->trips.passive.flags.valid = 1; | 436 | tz->trips.passive.flags.valid = 1; |
432 | if (flag == ACPI_TRIPS_INIT) { | 437 | if (flag == ACPI_TRIPS_INIT) { |
433 | status = acpi_evaluate_integer( | 438 | status = acpi_evaluate_integer( |
434 | tz->device->handle, "_TC1", | 439 | tz->device->handle, "_TC1", |
435 | NULL, &tz->trips.passive.tc1); | 440 | NULL, &tmp); |
436 | if (ACPI_FAILURE(status)) | 441 | if (ACPI_FAILURE(status)) |
437 | tz->trips.passive.flags.valid = 0; | 442 | tz->trips.passive.flags.valid = 0; |
443 | else | ||
444 | tz->trips.passive.tc1 = tmp; | ||
438 | status = acpi_evaluate_integer( | 445 | status = acpi_evaluate_integer( |
439 | tz->device->handle, "_TC2", | 446 | tz->device->handle, "_TC2", |
440 | NULL, &tz->trips.passive.tc2); | 447 | NULL, &tmp); |
441 | if (ACPI_FAILURE(status)) | 448 | if (ACPI_FAILURE(status)) |
442 | tz->trips.passive.flags.valid = 0; | 449 | tz->trips.passive.flags.valid = 0; |
450 | else | ||
451 | tz->trips.passive.tc2 = tmp; | ||
443 | status = acpi_evaluate_integer( | 452 | status = acpi_evaluate_integer( |
444 | tz->device->handle, "_TSP", | 453 | tz->device->handle, "_TSP", |
445 | NULL, &tz->trips.passive.tsp); | 454 | NULL, &tmp); |
446 | if (ACPI_FAILURE(status)) | 455 | if (ACPI_FAILURE(status)) |
447 | tz->trips.passive.flags.valid = 0; | 456 | tz->trips.passive.flags.valid = 0; |
457 | else | ||
458 | tz->trips.passive.tsp = tmp; | ||
448 | } | 459 | } |
449 | } | 460 | } |
450 | } | 461 | } |
@@ -479,7 +490,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
479 | 490 | ||
480 | if (flag & ACPI_TRIPS_ACTIVE) { | 491 | if (flag & ACPI_TRIPS_ACTIVE) { |
481 | status = acpi_evaluate_integer(tz->device->handle, | 492 | status = acpi_evaluate_integer(tz->device->handle, |
482 | name, NULL, &tz->trips.active[i].temperature); | 493 | name, NULL, &tmp); |
483 | if (ACPI_FAILURE(status)) { | 494 | if (ACPI_FAILURE(status)) { |
484 | tz->trips.active[i].flags.valid = 0; | 495 | tz->trips.active[i].flags.valid = 0; |
485 | if (i == 0) | 496 | if (i == 0) |
@@ -500,8 +511,10 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
500 | tz->trips.active[i - 2].temperature : | 511 | tz->trips.active[i - 2].temperature : |
501 | CELSIUS_TO_KELVIN(act)); | 512 | CELSIUS_TO_KELVIN(act)); |
502 | break; | 513 | break; |
503 | } else | 514 | } else { |
515 | tz->trips.active[i].temperature = tmp; | ||
504 | tz->trips.active[i].flags.valid = 1; | 516 | tz->trips.active[i].flags.valid = 1; |
517 | } | ||
505 | } | 518 | } |
506 | 519 | ||
507 | name[2] = 'L'; | 520 | name[2] = 'L'; |
@@ -1213,8 +1226,8 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) | |||
1213 | acpi_bus_private_data_handler, | 1226 | acpi_bus_private_data_handler, |
1214 | tz->thermal_zone); | 1227 | tz->thermal_zone); |
1215 | if (ACPI_FAILURE(status)) { | 1228 | if (ACPI_FAILURE(status)) { |
1216 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 1229 | printk(KERN_ERR PREFIX |
1217 | "Error attaching device data\n")); | 1230 | "Error attaching device data\n"); |
1218 | return -ENODEV; | 1231 | return -ENODEV; |
1219 | } | 1232 | } |
1220 | 1233 | ||
@@ -1647,7 +1660,7 @@ static int acpi_thermal_add(struct acpi_device *device) | |||
1647 | strcpy(tz->name, device->pnp.bus_id); | 1660 | strcpy(tz->name, device->pnp.bus_id); |
1648 | strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); | 1661 | strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); |
1649 | strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); | 1662 | strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); |
1650 | acpi_driver_data(device) = tz; | 1663 | device->driver_data = tz; |
1651 | mutex_init(&tz->lock); | 1664 | mutex_init(&tz->lock); |
1652 | 1665 | ||
1653 | 1666 | ||
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c index 8a649f40d162..2a632f8b7a05 100644 --- a/drivers/acpi/toshiba_acpi.c +++ b/drivers/acpi/toshiba_acpi.c | |||
@@ -548,7 +548,7 @@ static unsigned long write_video(const char *buffer, unsigned long count) | |||
548 | 548 | ||
549 | hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result); | 549 | hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result); |
550 | if (hci_result == HCI_SUCCESS) { | 550 | if (hci_result == HCI_SUCCESS) { |
551 | int new_video_out = video_out; | 551 | unsigned int new_video_out = video_out; |
552 | if (lcd_out != -1) | 552 | if (lcd_out != -1) |
553 | _set_bit(&new_video_out, HCI_VIDEO_OUT_LCD, lcd_out); | 553 | _set_bit(&new_video_out, HCI_VIDEO_OUT_LCD, lcd_out); |
554 | if (crt_out != -1) | 554 | if (crt_out != -1) |
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c index 7dcb67e0b215..241c535c1753 100644 --- a/drivers/acpi/utilities/utalloc.c +++ b/drivers/acpi/utilities/utalloc.c | |||
@@ -232,7 +232,7 @@ acpi_status acpi_ut_validate_buffer(struct acpi_buffer * buffer) | |||
232 | * RETURN: Status | 232 | * RETURN: Status |
233 | * | 233 | * |
234 | * DESCRIPTION: Validate that the buffer is of the required length or | 234 | * DESCRIPTION: Validate that the buffer is of the required length or |
235 | * allocate a new buffer. Returned buffer is always zeroed. | 235 | * allocate a new buffer. Returned buffer is always zeroed. |
236 | * | 236 | * |
237 | ******************************************************************************/ | 237 | ******************************************************************************/ |
238 | 238 | ||
@@ -240,7 +240,7 @@ acpi_status | |||
240 | acpi_ut_initialize_buffer(struct acpi_buffer * buffer, | 240 | acpi_ut_initialize_buffer(struct acpi_buffer * buffer, |
241 | acpi_size required_length) | 241 | acpi_size required_length) |
242 | { | 242 | { |
243 | acpi_status status = AE_OK; | 243 | acpi_size input_buffer_length; |
244 | 244 | ||
245 | /* Parameter validation */ | 245 | /* Parameter validation */ |
246 | 246 | ||
@@ -248,55 +248,58 @@ acpi_ut_initialize_buffer(struct acpi_buffer * buffer, | |||
248 | return (AE_BAD_PARAMETER); | 248 | return (AE_BAD_PARAMETER); |
249 | } | 249 | } |
250 | 250 | ||
251 | switch (buffer->length) { | 251 | /* |
252 | * Buffer->Length is used as both an input and output parameter. Get the | ||
253 | * input actual length and set the output required buffer length. | ||
254 | */ | ||
255 | input_buffer_length = buffer->length; | ||
256 | buffer->length = required_length; | ||
257 | |||
258 | /* | ||
259 | * The input buffer length contains the actual buffer length, or the type | ||
260 | * of buffer to be allocated by this routine. | ||
261 | */ | ||
262 | switch (input_buffer_length) { | ||
252 | case ACPI_NO_BUFFER: | 263 | case ACPI_NO_BUFFER: |
253 | 264 | ||
254 | /* Set the exception and returned the required length */ | 265 | /* Return the exception (and the required buffer length) */ |
255 | 266 | ||
256 | status = AE_BUFFER_OVERFLOW; | 267 | return (AE_BUFFER_OVERFLOW); |
257 | break; | ||
258 | 268 | ||
259 | case ACPI_ALLOCATE_BUFFER: | 269 | case ACPI_ALLOCATE_BUFFER: |
260 | 270 | ||
261 | /* Allocate a new buffer */ | 271 | /* Allocate a new buffer */ |
262 | 272 | ||
263 | buffer->pointer = acpi_os_allocate(required_length); | 273 | buffer->pointer = acpi_os_allocate(required_length); |
264 | if (!buffer->pointer) { | ||
265 | return (AE_NO_MEMORY); | ||
266 | } | ||
267 | |||
268 | /* Clear the buffer */ | ||
269 | |||
270 | ACPI_MEMSET(buffer->pointer, 0, required_length); | ||
271 | break; | 274 | break; |
272 | 275 | ||
273 | case ACPI_ALLOCATE_LOCAL_BUFFER: | 276 | case ACPI_ALLOCATE_LOCAL_BUFFER: |
274 | 277 | ||
275 | /* Allocate a new buffer with local interface to allow tracking */ | 278 | /* Allocate a new buffer with local interface to allow tracking */ |
276 | 279 | ||
277 | buffer->pointer = ACPI_ALLOCATE_ZEROED(required_length); | 280 | buffer->pointer = ACPI_ALLOCATE(required_length); |
278 | if (!buffer->pointer) { | ||
279 | return (AE_NO_MEMORY); | ||
280 | } | ||
281 | break; | 281 | break; |
282 | 282 | ||
283 | default: | 283 | default: |
284 | 284 | ||
285 | /* Existing buffer: Validate the size of the buffer */ | 285 | /* Existing buffer: Validate the size of the buffer */ |
286 | 286 | ||
287 | if (buffer->length < required_length) { | 287 | if (input_buffer_length < required_length) { |
288 | status = AE_BUFFER_OVERFLOW; | 288 | return (AE_BUFFER_OVERFLOW); |
289 | break; | ||
290 | } | 289 | } |
290 | break; | ||
291 | } | ||
291 | 292 | ||
292 | /* Clear the buffer */ | 293 | /* Validate allocation from above or input buffer pointer */ |
293 | 294 | ||
294 | ACPI_MEMSET(buffer->pointer, 0, required_length); | 295 | if (!buffer->pointer) { |
295 | break; | 296 | return (AE_NO_MEMORY); |
296 | } | 297 | } |
297 | 298 | ||
298 | buffer->length = required_length; | 299 | /* Have a valid buffer, clear it */ |
299 | return (status); | 300 | |
301 | ACPI_MEMSET(buffer->pointer, 0, required_length); | ||
302 | return (AE_OK); | ||
300 | } | 303 | } |
301 | 304 | ||
302 | #ifdef NOT_USED_BY_LINUX | 305 | #ifdef NOT_USED_BY_LINUX |
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c index 53499ac90988..5b2f7c27b705 100644 --- a/drivers/acpi/utilities/utcopy.c +++ b/drivers/acpi/utilities/utcopy.c | |||
@@ -42,7 +42,6 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/amlcode.h> | ||
46 | #include <acpi/acnamesp.h> | 45 | #include <acpi/acnamesp.h> |
47 | 46 | ||
48 | 47 | ||
@@ -176,20 +175,24 @@ acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object, | |||
176 | 175 | ||
177 | /* This is an object reference. */ | 176 | /* This is an object reference. */ |
178 | 177 | ||
179 | switch (internal_object->reference.opcode) { | 178 | switch (internal_object->reference.class) { |
180 | case AML_INT_NAMEPATH_OP: | 179 | case ACPI_REFCLASS_NAME: |
181 | |||
182 | /* For namepath, return the object handle ("reference") */ | ||
183 | |||
184 | default: | ||
185 | |||
186 | /* We are referring to the namespace node */ | ||
187 | 180 | ||
181 | /* | ||
182 | * For namepath, return the object handle ("reference") | ||
183 | * We are referring to the namespace node | ||
184 | */ | ||
188 | external_object->reference.handle = | 185 | external_object->reference.handle = |
189 | internal_object->reference.node; | 186 | internal_object->reference.node; |
190 | external_object->reference.actual_type = | 187 | external_object->reference.actual_type = |
191 | acpi_ns_get_type(internal_object->reference.node); | 188 | acpi_ns_get_type(internal_object->reference.node); |
192 | break; | 189 | break; |
190 | |||
191 | default: | ||
192 | |||
193 | /* All other reference types are unsupported */ | ||
194 | |||
195 | return_ACPI_STATUS(AE_TYPE); | ||
193 | } | 196 | } |
194 | break; | 197 | break; |
195 | 198 | ||
@@ -533,7 +536,7 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object, | |||
533 | 536 | ||
534 | /* TBD: should validate incoming handle */ | 537 | /* TBD: should validate incoming handle */ |
535 | 538 | ||
536 | internal_object->reference.opcode = AML_INT_NAMEPATH_OP; | 539 | internal_object->reference.class = ACPI_REFCLASS_NAME; |
537 | internal_object->reference.node = | 540 | internal_object->reference.node = |
538 | external_object->reference.handle; | 541 | external_object->reference.handle; |
539 | break; | 542 | break; |
@@ -743,11 +746,11 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, | |||
743 | * We copied the reference object, so we now must add a reference | 746 | * We copied the reference object, so we now must add a reference |
744 | * to the object pointed to by the reference | 747 | * to the object pointed to by the reference |
745 | * | 748 | * |
746 | * DDBHandle reference (from Load/load_table is a special reference, | 749 | * DDBHandle reference (from Load/load_table) is a special reference, |
747 | * it's Reference.Object is the table index, so does not need to | 750 | * it does not have a Reference.Object, so does not need to |
748 | * increase the reference count | 751 | * increase the reference count |
749 | */ | 752 | */ |
750 | if (source_desc->reference.opcode == AML_LOAD_OP) { | 753 | if (source_desc->reference.class == ACPI_REFCLASS_TABLE) { |
751 | break; | 754 | break; |
752 | } | 755 | } |
753 | 756 | ||
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c index 42609d3a8aa9..d197c6b29e17 100644 --- a/drivers/acpi/utilities/utdelete.c +++ b/drivers/acpi/utilities/utdelete.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #include <acpi/acinterp.h> | 45 | #include <acpi/acinterp.h> |
46 | #include <acpi/acnamesp.h> | 46 | #include <acpi/acnamesp.h> |
47 | #include <acpi/acevents.h> | 47 | #include <acpi/acevents.h> |
48 | #include <acpi/amlcode.h> | ||
49 | 48 | ||
50 | #define _COMPONENT ACPI_UTILITIES | 49 | #define _COMPONENT ACPI_UTILITIES |
51 | ACPI_MODULE_NAME("utdelete") | 50 | ACPI_MODULE_NAME("utdelete") |
@@ -548,8 +547,8 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action) | |||
548 | * reference must track changes to the ref count of the index or | 547 | * reference must track changes to the ref count of the index or |
549 | * target object. | 548 | * target object. |
550 | */ | 549 | */ |
551 | if ((object->reference.opcode == AML_INDEX_OP) || | 550 | if ((object->reference.class == ACPI_REFCLASS_INDEX) || |
552 | (object->reference.opcode == AML_INT_NAMEPATH_OP)) { | 551 | (object->reference.class == ACPI_REFCLASS_NAME)) { |
553 | next_object = object->reference.object; | 552 | next_object = object->reference.object; |
554 | } | 553 | } |
555 | break; | 554 | break; |
@@ -586,6 +585,13 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action) | |||
586 | ACPI_EXCEPTION((AE_INFO, status, | 585 | ACPI_EXCEPTION((AE_INFO, status, |
587 | "Could not update object reference count")); | 586 | "Could not update object reference count")); |
588 | 587 | ||
588 | /* Free any stacked Update State objects */ | ||
589 | |||
590 | while (state_list) { | ||
591 | state = acpi_ut_pop_generic_state(&state_list); | ||
592 | acpi_ut_delete_generic_state(state); | ||
593 | } | ||
594 | |||
589 | return_ACPI_STATUS(status); | 595 | return_ACPI_STATUS(status); |
590 | } | 596 | } |
591 | 597 | ||
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index a6e71b801d2d..670551b95e56 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c | |||
@@ -281,7 +281,6 @@ struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG] = { | |||
281 | /* ACPI_BITREG_RT_CLOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, | 281 | /* ACPI_BITREG_RT_CLOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, |
282 | ACPI_BITPOSITION_RT_CLOCK_ENABLE, | 282 | ACPI_BITPOSITION_RT_CLOCK_ENABLE, |
283 | ACPI_BITMASK_RT_CLOCK_ENABLE}, | 283 | ACPI_BITMASK_RT_CLOCK_ENABLE}, |
284 | /* ACPI_BITREG_WAKE_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, 0, 0}, | ||
285 | /* ACPI_BITREG_PCIEXP_WAKE_DISABLE */ {ACPI_REGISTER_PM1_ENABLE, | 284 | /* ACPI_BITREG_PCIEXP_WAKE_DISABLE */ {ACPI_REGISTER_PM1_ENABLE, |
286 | ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE, | 285 | ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE, |
287 | ACPI_BITMASK_PCIEXP_WAKE_DISABLE}, | 286 | ACPI_BITMASK_PCIEXP_WAKE_DISABLE}, |
@@ -575,6 +574,47 @@ char *acpi_ut_get_descriptor_name(void *object) | |||
575 | 574 | ||
576 | } | 575 | } |
577 | 576 | ||
577 | /******************************************************************************* | ||
578 | * | ||
579 | * FUNCTION: acpi_ut_get_reference_name | ||
580 | * | ||
581 | * PARAMETERS: Object - An ACPI reference object | ||
582 | * | ||
583 | * RETURN: Pointer to a string | ||
584 | * | ||
585 | * DESCRIPTION: Decode a reference object sub-type to a string. | ||
586 | * | ||
587 | ******************************************************************************/ | ||
588 | |||
589 | /* Printable names of reference object sub-types */ | ||
590 | |||
591 | static const char *acpi_gbl_ref_class_names[] = { | ||
592 | /* 00 */ "Local", | ||
593 | /* 01 */ "Argument", | ||
594 | /* 02 */ "RefOf", | ||
595 | /* 03 */ "Index", | ||
596 | /* 04 */ "DdbHandle", | ||
597 | /* 05 */ "Named Object", | ||
598 | /* 06 */ "Debug" | ||
599 | }; | ||
600 | |||
601 | const char *acpi_ut_get_reference_name(union acpi_operand_object *object) | ||
602 | { | ||
603 | if (!object) | ||
604 | return "NULL Object"; | ||
605 | |||
606 | if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) | ||
607 | return "Not an Operand object"; | ||
608 | |||
609 | if (object->common.type != ACPI_TYPE_LOCAL_REFERENCE) | ||
610 | return "Not a Reference object"; | ||
611 | |||
612 | if (object->reference.class > ACPI_REFCLASS_MAX) | ||
613 | return "Unknown Reference class"; | ||
614 | |||
615 | return acpi_gbl_ref_class_names[object->reference.class]; | ||
616 | } | ||
617 | |||
578 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) | 618 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) |
579 | /* | 619 | /* |
580 | * Strings and procedures used for debug only | 620 | * Strings and procedures used for debug only |
@@ -677,14 +717,14 @@ u8 acpi_ut_valid_object_type(acpi_object_type type) | |||
677 | * | 717 | * |
678 | * PARAMETERS: None | 718 | * PARAMETERS: None |
679 | * | 719 | * |
680 | * RETURN: None | 720 | * RETURN: Status |
681 | * | 721 | * |
682 | * DESCRIPTION: Init library globals. All globals that require specific | 722 | * DESCRIPTION: Init library globals. All globals that require specific |
683 | * initialization should be initialized here! | 723 | * initialization should be initialized here! |
684 | * | 724 | * |
685 | ******************************************************************************/ | 725 | ******************************************************************************/ |
686 | 726 | ||
687 | void acpi_ut_init_globals(void) | 727 | acpi_status acpi_ut_init_globals(void) |
688 | { | 728 | { |
689 | acpi_status status; | 729 | acpi_status status; |
690 | u32 i; | 730 | u32 i; |
@@ -695,7 +735,7 @@ void acpi_ut_init_globals(void) | |||
695 | 735 | ||
696 | status = acpi_ut_create_caches(); | 736 | status = acpi_ut_create_caches(); |
697 | if (ACPI_FAILURE(status)) { | 737 | if (ACPI_FAILURE(status)) { |
698 | return; | 738 | return_ACPI_STATUS(status); |
699 | } | 739 | } |
700 | 740 | ||
701 | /* Mutex locked flags */ | 741 | /* Mutex locked flags */ |
@@ -772,8 +812,8 @@ void acpi_ut_init_globals(void) | |||
772 | acpi_gbl_display_final_mem_stats = FALSE; | 812 | acpi_gbl_display_final_mem_stats = FALSE; |
773 | #endif | 813 | #endif |
774 | 814 | ||
775 | return_VOID; | 815 | return_ACPI_STATUS(AE_OK); |
776 | } | 816 | } |
777 | 817 | ||
778 | ACPI_EXPORT_SYMBOL(acpi_dbg_level) | 818 | ACPI_EXPORT_SYMBOL(acpi_dbg_level) |
779 | ACPI_EXPORT_SYMBOL(acpi_dbg_layer) | 819 | ACPI_EXPORT_SYMBOL(acpi_dbg_layer) |
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index f34be6773556..9089a158a874 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c | |||
@@ -995,6 +995,15 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object, | |||
995 | state->pkg. | 995 | state->pkg. |
996 | this_target_obj, 0); | 996 | this_target_obj, 0); |
997 | if (!state) { | 997 | if (!state) { |
998 | |||
999 | /* Free any stacked Update State objects */ | ||
1000 | |||
1001 | while (state_list) { | ||
1002 | state = | ||
1003 | acpi_ut_pop_generic_state | ||
1004 | (&state_list); | ||
1005 | acpi_ut_delete_generic_state(state); | ||
1006 | } | ||
998 | return_ACPI_STATUS(AE_NO_MEMORY); | 1007 | return_ACPI_STATUS(AE_NO_MEMORY); |
999 | } | 1008 | } |
1000 | } | 1009 | } |
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c index 916eff399eb3..c354e7a42bcd 100644 --- a/drivers/acpi/utilities/utobject.c +++ b/drivers/acpi/utilities/utobject.c | |||
@@ -43,7 +43,6 @@ | |||
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acnamesp.h> | 45 | #include <acpi/acnamesp.h> |
46 | #include <acpi/amlcode.h> | ||
47 | 46 | ||
48 | #define _COMPONENT ACPI_UTILITIES | 47 | #define _COMPONENT ACPI_UTILITIES |
49 | ACPI_MODULE_NAME("utobject") | 48 | ACPI_MODULE_NAME("utobject") |
@@ -478,8 +477,8 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, | |||
478 | 477 | ||
479 | case ACPI_TYPE_LOCAL_REFERENCE: | 478 | case ACPI_TYPE_LOCAL_REFERENCE: |
480 | 479 | ||
481 | switch (internal_object->reference.opcode) { | 480 | switch (internal_object->reference.class) { |
482 | case AML_INT_NAMEPATH_OP: | 481 | case ACPI_REFCLASS_NAME: |
483 | 482 | ||
484 | /* | 483 | /* |
485 | * Get the actual length of the full pathname to this object. | 484 | * Get the actual length of the full pathname to this object. |
@@ -503,8 +502,10 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, | |||
503 | * required eventually. | 502 | * required eventually. |
504 | */ | 503 | */ |
505 | ACPI_ERROR((AE_INFO, | 504 | ACPI_ERROR((AE_INFO, |
506 | "Unsupported Reference opcode=%X in object %p", | 505 | "Cannot convert to external object - " |
507 | internal_object->reference.opcode, | 506 | "unsupported Reference Class [%s] %X in object %p", |
507 | acpi_ut_get_reference_name(internal_object), | ||
508 | internal_object->reference.class, | ||
508 | internal_object)); | 509 | internal_object)); |
509 | status = AE_TYPE; | 510 | status = AE_TYPE; |
510 | break; | 511 | break; |
@@ -513,7 +514,9 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, | |||
513 | 514 | ||
514 | default: | 515 | default: |
515 | 516 | ||
516 | ACPI_ERROR((AE_INFO, "Unsupported type=%X in object %p", | 517 | ACPI_ERROR((AE_INFO, "Cannot convert to external object - " |
518 | "unsupported type [%s] %X in object %p", | ||
519 | acpi_ut_get_object_type_name(internal_object), | ||
517 | ACPI_GET_OBJECT_TYPE(internal_object), | 520 | ACPI_GET_OBJECT_TYPE(internal_object), |
518 | internal_object)); | 521 | internal_object)); |
519 | status = AE_TYPE; | 522 | status = AE_TYPE; |
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c index f8bdadf3c32f..c198a4d40583 100644 --- a/drivers/acpi/utilities/utxface.c +++ b/drivers/acpi/utilities/utxface.c | |||
@@ -81,7 +81,12 @@ acpi_status __init acpi_initialize_subsystem(void) | |||
81 | 81 | ||
82 | /* Initialize all globals used by the subsystem */ | 82 | /* Initialize all globals used by the subsystem */ |
83 | 83 | ||
84 | acpi_ut_init_globals(); | 84 | status = acpi_ut_init_globals(); |
85 | if (ACPI_FAILURE(status)) { | ||
86 | ACPI_EXCEPTION((AE_INFO, status, | ||
87 | "During initialization of globals")); | ||
88 | return_ACPI_STATUS(status); | ||
89 | } | ||
85 | 90 | ||
86 | /* Create the default mutex objects */ | 91 | /* Create the default mutex objects */ |
87 | 92 | ||
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 100926143818..e827be36ee8d 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -256,7 +256,7 @@ EXPORT_SYMBOL(acpi_extract_package); | |||
256 | acpi_status | 256 | acpi_status |
257 | acpi_evaluate_integer(acpi_handle handle, | 257 | acpi_evaluate_integer(acpi_handle handle, |
258 | acpi_string pathname, | 258 | acpi_string pathname, |
259 | struct acpi_object_list *arguments, unsigned long *data) | 259 | struct acpi_object_list *arguments, unsigned long long *data) |
260 | { | 260 | { |
261 | acpi_status status = AE_OK; | 261 | acpi_status status = AE_OK; |
262 | union acpi_object *element; | 262 | union acpi_object *element; |
@@ -288,7 +288,7 @@ acpi_evaluate_integer(acpi_handle handle, | |||
288 | *data = element->integer.value; | 288 | *data = element->integer.value; |
289 | kfree(element); | 289 | kfree(element); |
290 | 290 | ||
291 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%lu]\n", *data)); | 291 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%llu]\n", *data)); |
292 | 292 | ||
293 | return AE_OK; | 293 | return AE_OK; |
294 | } | 294 | } |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index e8a51a1700f7..a29b0ccac65a 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -291,20 +291,20 @@ static int acpi_video_device_lcd_set_level(struct acpi_video_device *device, | |||
291 | int level); | 291 | int level); |
292 | static int acpi_video_device_lcd_get_level_current( | 292 | static int acpi_video_device_lcd_get_level_current( |
293 | struct acpi_video_device *device, | 293 | struct acpi_video_device *device, |
294 | unsigned long *level); | 294 | unsigned long long *level); |
295 | static int acpi_video_get_next_level(struct acpi_video_device *device, | 295 | static int acpi_video_get_next_level(struct acpi_video_device *device, |
296 | u32 level_current, u32 event); | 296 | u32 level_current, u32 event); |
297 | static void acpi_video_switch_brightness(struct acpi_video_device *device, | 297 | static void acpi_video_switch_brightness(struct acpi_video_device *device, |
298 | int event); | 298 | int event); |
299 | static int acpi_video_device_get_state(struct acpi_video_device *device, | 299 | static int acpi_video_device_get_state(struct acpi_video_device *device, |
300 | unsigned long *state); | 300 | unsigned long long *state); |
301 | static int acpi_video_output_get(struct output_device *od); | 301 | static int acpi_video_output_get(struct output_device *od); |
302 | static int acpi_video_device_set_state(struct acpi_video_device *device, int state); | 302 | static int acpi_video_device_set_state(struct acpi_video_device *device, int state); |
303 | 303 | ||
304 | /*backlight device sysfs support*/ | 304 | /*backlight device sysfs support*/ |
305 | static int acpi_video_get_brightness(struct backlight_device *bd) | 305 | static int acpi_video_get_brightness(struct backlight_device *bd) |
306 | { | 306 | { |
307 | unsigned long cur_level; | 307 | unsigned long long cur_level; |
308 | int i; | 308 | int i; |
309 | struct acpi_video_device *vd = | 309 | struct acpi_video_device *vd = |
310 | (struct acpi_video_device *)bl_get_data(bd); | 310 | (struct acpi_video_device *)bl_get_data(bd); |
@@ -336,7 +336,7 @@ static struct backlight_ops acpi_backlight_ops = { | |||
336 | /*video output device sysfs support*/ | 336 | /*video output device sysfs support*/ |
337 | static int acpi_video_output_get(struct output_device *od) | 337 | static int acpi_video_output_get(struct output_device *od) |
338 | { | 338 | { |
339 | unsigned long state; | 339 | unsigned long long state; |
340 | struct acpi_video_device *vd = | 340 | struct acpi_video_device *vd = |
341 | (struct acpi_video_device *)dev_get_drvdata(&od->dev); | 341 | (struct acpi_video_device *)dev_get_drvdata(&od->dev); |
342 | acpi_video_device_get_state(vd, &state); | 342 | acpi_video_device_get_state(vd, &state); |
@@ -370,7 +370,7 @@ static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf) | |||
370 | { | 370 | { |
371 | struct acpi_device *device = cdev->devdata; | 371 | struct acpi_device *device = cdev->devdata; |
372 | struct acpi_video_device *video = acpi_driver_data(device); | 372 | struct acpi_video_device *video = acpi_driver_data(device); |
373 | unsigned long level; | 373 | unsigned long long level; |
374 | int state; | 374 | int state; |
375 | 375 | ||
376 | acpi_video_device_lcd_get_level_current(video, &level); | 376 | acpi_video_device_lcd_get_level_current(video, &level); |
@@ -410,7 +410,7 @@ static struct thermal_cooling_device_ops video_cooling_ops = { | |||
410 | /* device */ | 410 | /* device */ |
411 | 411 | ||
412 | static int | 412 | static int |
413 | acpi_video_device_query(struct acpi_video_device *device, unsigned long *state) | 413 | acpi_video_device_query(struct acpi_video_device *device, unsigned long long *state) |
414 | { | 414 | { |
415 | int status; | 415 | int status; |
416 | 416 | ||
@@ -421,7 +421,7 @@ acpi_video_device_query(struct acpi_video_device *device, unsigned long *state) | |||
421 | 421 | ||
422 | static int | 422 | static int |
423 | acpi_video_device_get_state(struct acpi_video_device *device, | 423 | acpi_video_device_get_state(struct acpi_video_device *device, |
424 | unsigned long *state) | 424 | unsigned long long *state) |
425 | { | 425 | { |
426 | int status; | 426 | int status; |
427 | 427 | ||
@@ -436,7 +436,7 @@ acpi_video_device_set_state(struct acpi_video_device *device, int state) | |||
436 | int status; | 436 | int status; |
437 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | 437 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; |
438 | struct acpi_object_list args = { 1, &arg0 }; | 438 | struct acpi_object_list args = { 1, &arg0 }; |
439 | unsigned long ret; | 439 | unsigned long long ret; |
440 | 440 | ||
441 | 441 | ||
442 | arg0.integer.value = state; | 442 | arg0.integer.value = state; |
@@ -495,7 +495,7 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) | |||
495 | 495 | ||
496 | static int | 496 | static int |
497 | acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, | 497 | acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, |
498 | unsigned long *level) | 498 | unsigned long long *level) |
499 | { | 499 | { |
500 | if (device->cap._BQC) | 500 | if (device->cap._BQC) |
501 | return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL, | 501 | return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL, |
@@ -549,7 +549,7 @@ static int | |||
549 | acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option) | 549 | acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option) |
550 | { | 550 | { |
551 | int status; | 551 | int status; |
552 | unsigned long tmp; | 552 | unsigned long long tmp; |
553 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | 553 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; |
554 | struct acpi_object_list args = { 1, &arg0 }; | 554 | struct acpi_object_list args = { 1, &arg0 }; |
555 | 555 | ||
@@ -564,7 +564,7 @@ acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option) | |||
564 | } | 564 | } |
565 | 565 | ||
566 | static int | 566 | static int |
567 | acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long *id) | 567 | acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id) |
568 | { | 568 | { |
569 | int status; | 569 | int status; |
570 | 570 | ||
@@ -575,7 +575,7 @@ acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long *id) | |||
575 | 575 | ||
576 | static int | 576 | static int |
577 | acpi_video_bus_POST_options(struct acpi_video_bus *video, | 577 | acpi_video_bus_POST_options(struct acpi_video_bus *video, |
578 | unsigned long *options) | 578 | unsigned long long *options) |
579 | { | 579 | { |
580 | int status; | 580 | int status; |
581 | 581 | ||
@@ -918,7 +918,7 @@ static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) | |||
918 | { | 918 | { |
919 | int status; | 919 | int status; |
920 | struct acpi_video_device *dev = seq->private; | 920 | struct acpi_video_device *dev = seq->private; |
921 | unsigned long state; | 921 | unsigned long long state; |
922 | 922 | ||
923 | 923 | ||
924 | if (!dev) | 924 | if (!dev) |
@@ -927,14 +927,14 @@ static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) | |||
927 | status = acpi_video_device_get_state(dev, &state); | 927 | status = acpi_video_device_get_state(dev, &state); |
928 | seq_printf(seq, "state: "); | 928 | seq_printf(seq, "state: "); |
929 | if (ACPI_SUCCESS(status)) | 929 | if (ACPI_SUCCESS(status)) |
930 | seq_printf(seq, "0x%02lx\n", state); | 930 | seq_printf(seq, "0x%02llx\n", state); |
931 | else | 931 | else |
932 | seq_printf(seq, "<not supported>\n"); | 932 | seq_printf(seq, "<not supported>\n"); |
933 | 933 | ||
934 | status = acpi_video_device_query(dev, &state); | 934 | status = acpi_video_device_query(dev, &state); |
935 | seq_printf(seq, "query: "); | 935 | seq_printf(seq, "query: "); |
936 | if (ACPI_SUCCESS(status)) | 936 | if (ACPI_SUCCESS(status)) |
937 | seq_printf(seq, "0x%02lx\n", state); | 937 | seq_printf(seq, "0x%02llx\n", state); |
938 | else | 938 | else |
939 | seq_printf(seq, "<not supported>\n"); | 939 | seq_printf(seq, "<not supported>\n"); |
940 | 940 | ||
@@ -1217,7 +1217,7 @@ static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file) | |||
1217 | static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) | 1217 | static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) |
1218 | { | 1218 | { |
1219 | struct acpi_video_bus *video = seq->private; | 1219 | struct acpi_video_bus *video = seq->private; |
1220 | unsigned long options; | 1220 | unsigned long long options; |
1221 | int status; | 1221 | int status; |
1222 | 1222 | ||
1223 | 1223 | ||
@@ -1232,7 +1232,7 @@ static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) | |||
1232 | printk(KERN_WARNING PREFIX | 1232 | printk(KERN_WARNING PREFIX |
1233 | "This indicates a BIOS bug. Please contact the manufacturer.\n"); | 1233 | "This indicates a BIOS bug. Please contact the manufacturer.\n"); |
1234 | } | 1234 | } |
1235 | printk("%lx\n", options); | 1235 | printk("%llx\n", options); |
1236 | seq_printf(seq, "can POST: <integrated video>"); | 1236 | seq_printf(seq, "can POST: <integrated video>"); |
1237 | if (options & 2) | 1237 | if (options & 2) |
1238 | seq_printf(seq, " <PCI video>"); | 1238 | seq_printf(seq, " <PCI video>"); |
@@ -1256,7 +1256,7 @@ static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) | |||
1256 | { | 1256 | { |
1257 | struct acpi_video_bus *video = seq->private; | 1257 | struct acpi_video_bus *video = seq->private; |
1258 | int status; | 1258 | int status; |
1259 | unsigned long id; | 1259 | unsigned long long id; |
1260 | 1260 | ||
1261 | 1261 | ||
1262 | if (!video) | 1262 | if (!video) |
@@ -1303,7 +1303,7 @@ acpi_video_bus_write_POST(struct file *file, | |||
1303 | struct seq_file *m = file->private_data; | 1303 | struct seq_file *m = file->private_data; |
1304 | struct acpi_video_bus *video = m->private; | 1304 | struct acpi_video_bus *video = m->private; |
1305 | char str[12] = { 0 }; | 1305 | char str[12] = { 0 }; |
1306 | unsigned long opt, options; | 1306 | unsigned long long opt, options; |
1307 | 1307 | ||
1308 | 1308 | ||
1309 | if (!video || count + 1 > sizeof str) | 1309 | if (!video || count + 1 > sizeof str) |
@@ -1473,7 +1473,7 @@ static int | |||
1473 | acpi_video_bus_get_one_device(struct acpi_device *device, | 1473 | acpi_video_bus_get_one_device(struct acpi_device *device, |
1474 | struct acpi_video_bus *video) | 1474 | struct acpi_video_bus *video) |
1475 | { | 1475 | { |
1476 | unsigned long device_id; | 1476 | unsigned long long device_id; |
1477 | int status; | 1477 | int status; |
1478 | struct acpi_video_device *data; | 1478 | struct acpi_video_device *data; |
1479 | struct acpi_video_device_attrib* attribute; | 1479 | struct acpi_video_device_attrib* attribute; |
@@ -1491,7 +1491,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
1491 | 1491 | ||
1492 | strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME); | 1492 | strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME); |
1493 | strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); | 1493 | strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); |
1494 | acpi_driver_data(device) = data; | 1494 | device->driver_data = data; |
1495 | 1495 | ||
1496 | data->device_id = device_id; | 1496 | data->device_id = device_id; |
1497 | data->video = video; | 1497 | data->video = video; |
@@ -1530,8 +1530,8 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
1530 | acpi_video_device_notify, | 1530 | acpi_video_device_notify, |
1531 | data); | 1531 | data); |
1532 | if (ACPI_FAILURE(status)) { | 1532 | if (ACPI_FAILURE(status)) { |
1533 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 1533 | printk(KERN_ERR PREFIX |
1534 | "Error installing notify handler\n")); | 1534 | "Error installing notify handler\n"); |
1535 | if(data->brightness) | 1535 | if(data->brightness) |
1536 | kfree(data->brightness->levels); | 1536 | kfree(data->brightness->levels); |
1537 | kfree(data->brightness); | 1537 | kfree(data->brightness); |
@@ -1724,7 +1724,7 @@ acpi_video_get_next_level(struct acpi_video_device *device, | |||
1724 | static void | 1724 | static void |
1725 | acpi_video_switch_brightness(struct acpi_video_device *device, int event) | 1725 | acpi_video_switch_brightness(struct acpi_video_device *device, int event) |
1726 | { | 1726 | { |
1727 | unsigned long level_current, level_next; | 1727 | unsigned long long level_current, level_next; |
1728 | if (!device->brightness) | 1728 | if (!device->brightness) |
1729 | return; | 1729 | return; |
1730 | acpi_video_device_lcd_get_level_current(device, &level_current); | 1730 | acpi_video_device_lcd_get_level_current(device, &level_current); |
@@ -1745,8 +1745,8 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video, | |||
1745 | 1745 | ||
1746 | status = acpi_video_bus_get_one_device(dev, video); | 1746 | status = acpi_video_bus_get_one_device(dev, video); |
1747 | if (ACPI_FAILURE(status)) { | 1747 | if (ACPI_FAILURE(status)) { |
1748 | ACPI_DEBUG_PRINT((ACPI_DB_WARN, | 1748 | printk(KERN_WARNING PREFIX |
1749 | "Cant attach device")); | 1749 | "Cant attach device"); |
1750 | continue; | 1750 | continue; |
1751 | } | 1751 | } |
1752 | } | 1752 | } |
@@ -1982,7 +1982,7 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
1982 | video->device = device; | 1982 | video->device = device; |
1983 | strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); | 1983 | strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); |
1984 | strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); | 1984 | strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); |
1985 | acpi_driver_data(device) = video; | 1985 | device->driver_data = video; |
1986 | 1986 | ||
1987 | acpi_video_bus_find_cap(video); | 1987 | acpi_video_bus_find_cap(video); |
1988 | error = acpi_video_bus_check(video); | 1988 | error = acpi_video_bus_check(video); |
@@ -2003,8 +2003,8 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
2003 | ACPI_DEVICE_NOTIFY, | 2003 | ACPI_DEVICE_NOTIFY, |
2004 | acpi_video_bus_notify, video); | 2004 | acpi_video_bus_notify, video); |
2005 | if (ACPI_FAILURE(status)) { | 2005 | if (ACPI_FAILURE(status)) { |
2006 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 2006 | printk(KERN_ERR PREFIX |
2007 | "Error installing notify handler\n")); | 2007 | "Error installing notify handler\n"); |
2008 | error = -ENODEV; | 2008 | error = -ENODEV; |
2009 | goto err_stop_video; | 2009 | goto err_stop_video; |
2010 | } | 2010 | } |
@@ -2058,7 +2058,7 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
2058 | acpi_video_bus_remove_fs(device); | 2058 | acpi_video_bus_remove_fs(device); |
2059 | err_free_video: | 2059 | err_free_video: |
2060 | kfree(video); | 2060 | kfree(video); |
2061 | acpi_driver_data(device) = NULL; | 2061 | device->driver_data = NULL; |
2062 | 2062 | ||
2063 | return error; | 2063 | return error; |
2064 | } | 2064 | } |
diff --git a/drivers/acpi/wmi.c b/drivers/acpi/wmi.c index cfe2c833474d..47cd7baf9b1b 100644 --- a/drivers/acpi/wmi.c +++ b/drivers/acpi/wmi.c | |||
@@ -217,6 +217,35 @@ static bool find_guid(const char *guid_string, struct wmi_block **out) | |||
217 | return 0; | 217 | return 0; |
218 | } | 218 | } |
219 | 219 | ||
220 | static acpi_status wmi_method_enable(struct wmi_block *wblock, int enable) | ||
221 | { | ||
222 | struct guid_block *block = NULL; | ||
223 | char method[5]; | ||
224 | struct acpi_object_list input; | ||
225 | union acpi_object params[1]; | ||
226 | acpi_status status; | ||
227 | acpi_handle handle; | ||
228 | |||
229 | block = &wblock->gblock; | ||
230 | handle = wblock->handle; | ||
231 | |||
232 | if (!block) | ||
233 | return AE_NOT_EXIST; | ||
234 | |||
235 | input.count = 1; | ||
236 | input.pointer = params; | ||
237 | params[0].type = ACPI_TYPE_INTEGER; | ||
238 | params[0].integer.value = enable; | ||
239 | |||
240 | snprintf(method, 5, "WE%02X", block->notify_id); | ||
241 | status = acpi_evaluate_object(handle, method, &input, NULL); | ||
242 | |||
243 | if (status != AE_OK && status != AE_NOT_FOUND) | ||
244 | return status; | ||
245 | else | ||
246 | return AE_OK; | ||
247 | } | ||
248 | |||
220 | /* | 249 | /* |
221 | * Exported WMI functions | 250 | * Exported WMI functions |
222 | */ | 251 | */ |
@@ -242,7 +271,7 @@ u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out) | |||
242 | char method[4] = "WM"; | 271 | char method[4] = "WM"; |
243 | 272 | ||
244 | if (!find_guid(guid_string, &wblock)) | 273 | if (!find_guid(guid_string, &wblock)) |
245 | return AE_BAD_ADDRESS; | 274 | return AE_ERROR; |
246 | 275 | ||
247 | block = &wblock->gblock; | 276 | block = &wblock->gblock; |
248 | handle = wblock->handle; | 277 | handle = wblock->handle; |
@@ -304,7 +333,7 @@ struct acpi_buffer *out) | |||
304 | return AE_BAD_PARAMETER; | 333 | return AE_BAD_PARAMETER; |
305 | 334 | ||
306 | if (!find_guid(guid_string, &wblock)) | 335 | if (!find_guid(guid_string, &wblock)) |
307 | return AE_BAD_ADDRESS; | 336 | return AE_ERROR; |
308 | 337 | ||
309 | block = &wblock->gblock; | 338 | block = &wblock->gblock; |
310 | handle = wblock->handle; | 339 | handle = wblock->handle; |
@@ -314,7 +343,7 @@ struct acpi_buffer *out) | |||
314 | 343 | ||
315 | /* Check GUID is a data block */ | 344 | /* Check GUID is a data block */ |
316 | if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD)) | 345 | if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD)) |
317 | return AE_BAD_ADDRESS; | 346 | return AE_ERROR; |
318 | 347 | ||
319 | input.count = 1; | 348 | input.count = 1; |
320 | input.pointer = wq_params; | 349 | input.pointer = wq_params; |
@@ -385,7 +414,7 @@ const struct acpi_buffer *in) | |||
385 | return AE_BAD_DATA; | 414 | return AE_BAD_DATA; |
386 | 415 | ||
387 | if (!find_guid(guid_string, &wblock)) | 416 | if (!find_guid(guid_string, &wblock)) |
388 | return AE_BAD_ADDRESS; | 417 | return AE_ERROR; |
389 | 418 | ||
390 | block = &wblock->gblock; | 419 | block = &wblock->gblock; |
391 | handle = wblock->handle; | 420 | handle = wblock->handle; |
@@ -395,7 +424,7 @@ const struct acpi_buffer *in) | |||
395 | 424 | ||
396 | /* Check GUID is a data block */ | 425 | /* Check GUID is a data block */ |
397 | if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD)) | 426 | if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD)) |
398 | return AE_BAD_ADDRESS; | 427 | return AE_ERROR; |
399 | 428 | ||
400 | input.count = 2; | 429 | input.count = 2; |
401 | input.pointer = params; | 430 | input.pointer = params; |
@@ -427,6 +456,7 @@ acpi_status wmi_install_notify_handler(const char *guid, | |||
427 | wmi_notify_handler handler, void *data) | 456 | wmi_notify_handler handler, void *data) |
428 | { | 457 | { |
429 | struct wmi_block *block; | 458 | struct wmi_block *block; |
459 | acpi_status status; | ||
430 | 460 | ||
431 | if (!guid || !handler) | 461 | if (!guid || !handler) |
432 | return AE_BAD_PARAMETER; | 462 | return AE_BAD_PARAMETER; |
@@ -441,7 +471,9 @@ wmi_notify_handler handler, void *data) | |||
441 | block->handler = handler; | 471 | block->handler = handler; |
442 | block->handler_data = data; | 472 | block->handler_data = data; |
443 | 473 | ||
444 | return AE_OK; | 474 | status = wmi_method_enable(block, 1); |
475 | |||
476 | return status; | ||
445 | } | 477 | } |
446 | EXPORT_SYMBOL_GPL(wmi_install_notify_handler); | 478 | EXPORT_SYMBOL_GPL(wmi_install_notify_handler); |
447 | 479 | ||
@@ -453,6 +485,7 @@ EXPORT_SYMBOL_GPL(wmi_install_notify_handler); | |||
453 | acpi_status wmi_remove_notify_handler(const char *guid) | 485 | acpi_status wmi_remove_notify_handler(const char *guid) |
454 | { | 486 | { |
455 | struct wmi_block *block; | 487 | struct wmi_block *block; |
488 | acpi_status status; | ||
456 | 489 | ||
457 | if (!guid) | 490 | if (!guid) |
458 | return AE_BAD_PARAMETER; | 491 | return AE_BAD_PARAMETER; |
@@ -464,10 +497,12 @@ acpi_status wmi_remove_notify_handler(const char *guid) | |||
464 | if (!block->handler) | 497 | if (!block->handler) |
465 | return AE_NULL_ENTRY; | 498 | return AE_NULL_ENTRY; |
466 | 499 | ||
500 | status = wmi_method_enable(block, 0); | ||
501 | |||
467 | block->handler = NULL; | 502 | block->handler = NULL; |
468 | block->handler_data = NULL; | 503 | block->handler_data = NULL; |
469 | 504 | ||
470 | return AE_OK; | 505 | return status; |
471 | } | 506 | } |
472 | EXPORT_SYMBOL_GPL(wmi_remove_notify_handler); | 507 | EXPORT_SYMBOL_GPL(wmi_remove_notify_handler); |
473 | 508 | ||
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 9330b7922f62..c012307d0ba6 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
@@ -120,21 +120,6 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) | |||
120 | ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; | 120 | ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; |
121 | } | 121 | } |
122 | 122 | ||
123 | static void ata_acpi_eject_device(acpi_handle handle) | ||
124 | { | ||
125 | struct acpi_object_list arg_list; | ||
126 | union acpi_object arg; | ||
127 | |||
128 | arg_list.count = 1; | ||
129 | arg_list.pointer = &arg; | ||
130 | arg.type = ACPI_TYPE_INTEGER; | ||
131 | arg.integer.value = 1; | ||
132 | |||
133 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_EJ0", | ||
134 | &arg_list, NULL))) | ||
135 | printk(KERN_ERR "Failed to evaluate _EJ0!\n"); | ||
136 | } | ||
137 | |||
138 | /* @ap and @dev are the same as ata_acpi_handle_hotplug() */ | 123 | /* @ap and @dev are the same as ata_acpi_handle_hotplug() */ |
139 | static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev) | 124 | static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev) |
140 | { | 125 | { |
@@ -157,7 +142,6 @@ static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev) | |||
157 | * @ap: ATA port ACPI event occurred | 142 | * @ap: ATA port ACPI event occurred |
158 | * @dev: ATA device ACPI event occurred (can be NULL) | 143 | * @dev: ATA device ACPI event occurred (can be NULL) |
159 | * @event: ACPI event which occurred | 144 | * @event: ACPI event which occurred |
160 | * @is_dock_event: boolean indicating whether the event was a dock one | ||
161 | * | 145 | * |
162 | * All ACPI bay / device realted events end up in this function. If | 146 | * All ACPI bay / device realted events end up in this function. If |
163 | * the event is port-wide @dev is NULL. If the event is specific to a | 147 | * the event is port-wide @dev is NULL. If the event is specific to a |
@@ -171,117 +155,100 @@ static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev) | |||
171 | * ACPI notify handler context. May sleep. | 155 | * ACPI notify handler context. May sleep. |
172 | */ | 156 | */ |
173 | static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, | 157 | static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, |
174 | u32 event, int is_dock_event) | 158 | u32 event) |
175 | { | 159 | { |
176 | char event_string[12]; | ||
177 | char *envp[] = { event_string, NULL }; | ||
178 | struct ata_eh_info *ehi = &ap->link.eh_info; | 160 | struct ata_eh_info *ehi = &ap->link.eh_info; |
179 | struct kobject *kobj = NULL; | ||
180 | int wait = 0; | 161 | int wait = 0; |
181 | unsigned long flags; | 162 | unsigned long flags; |
182 | acpi_handle handle, tmphandle; | 163 | acpi_handle handle; |
183 | unsigned long sta; | ||
184 | acpi_status status; | ||
185 | 164 | ||
186 | if (dev) { | 165 | if (dev) |
187 | if (dev->sdev) | ||
188 | kobj = &dev->sdev->sdev_gendev.kobj; | ||
189 | handle = dev->acpi_handle; | 166 | handle = dev->acpi_handle; |
190 | } else { | 167 | else |
191 | kobj = &ap->dev->kobj; | ||
192 | handle = ap->acpi_handle; | 168 | handle = ap->acpi_handle; |
193 | } | ||
194 | |||
195 | status = acpi_get_handle(handle, "_EJ0", &tmphandle); | ||
196 | if (ACPI_FAILURE(status)) | ||
197 | /* This device does not support hotplug */ | ||
198 | return; | ||
199 | |||
200 | if (event == ACPI_NOTIFY_BUS_CHECK || | ||
201 | event == ACPI_NOTIFY_DEVICE_CHECK) | ||
202 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | ||
203 | 169 | ||
204 | spin_lock_irqsave(ap->lock, flags); | 170 | spin_lock_irqsave(ap->lock, flags); |
205 | 171 | /* | |
172 | * When dock driver calls into the routine, it will always use | ||
173 | * ACPI_NOTIFY_BUS_CHECK/ACPI_NOTIFY_DEVICE_CHECK for add and | ||
174 | * ACPI_NOTIFY_EJECT_REQUEST for remove | ||
175 | */ | ||
206 | switch (event) { | 176 | switch (event) { |
207 | case ACPI_NOTIFY_BUS_CHECK: | 177 | case ACPI_NOTIFY_BUS_CHECK: |
208 | case ACPI_NOTIFY_DEVICE_CHECK: | 178 | case ACPI_NOTIFY_DEVICE_CHECK: |
209 | ata_ehi_push_desc(ehi, "ACPI event"); | 179 | ata_ehi_push_desc(ehi, "ACPI event"); |
210 | 180 | ||
211 | if (ACPI_FAILURE(status)) { | 181 | ata_ehi_hotplugged(ehi); |
212 | ata_port_printk(ap, KERN_ERR, | 182 | ata_port_freeze(ap); |
213 | "acpi: failed to determine bay status (0x%x)\n", | ||
214 | status); | ||
215 | break; | ||
216 | } | ||
217 | |||
218 | if (sta) { | ||
219 | ata_ehi_hotplugged(ehi); | ||
220 | ata_port_freeze(ap); | ||
221 | } else { | ||
222 | /* The device has gone - unplug it */ | ||
223 | ata_acpi_detach_device(ap, dev); | ||
224 | wait = 1; | ||
225 | } | ||
226 | break; | 183 | break; |
227 | case ACPI_NOTIFY_EJECT_REQUEST: | 184 | case ACPI_NOTIFY_EJECT_REQUEST: |
228 | ata_ehi_push_desc(ehi, "ACPI event"); | 185 | ata_ehi_push_desc(ehi, "ACPI event"); |
229 | 186 | ||
230 | if (!is_dock_event) | ||
231 | break; | ||
232 | |||
233 | /* undock event - immediate unplug */ | ||
234 | ata_acpi_detach_device(ap, dev); | 187 | ata_acpi_detach_device(ap, dev); |
235 | wait = 1; | 188 | wait = 1; |
236 | break; | 189 | break; |
237 | } | 190 | } |
238 | 191 | ||
239 | /* make sure kobj doesn't go away while ap->lock is released */ | ||
240 | kobject_get(kobj); | ||
241 | |||
242 | spin_unlock_irqrestore(ap->lock, flags); | 192 | spin_unlock_irqrestore(ap->lock, flags); |
243 | 193 | ||
244 | if (wait) { | 194 | if (wait) |
245 | ata_port_wait_eh(ap); | 195 | ata_port_wait_eh(ap); |
246 | ata_acpi_eject_device(handle); | ||
247 | } | ||
248 | |||
249 | if (kobj && !is_dock_event) { | ||
250 | sprintf(event_string, "BAY_EVENT=%d", event); | ||
251 | kobject_uevent_env(kobj, KOBJ_CHANGE, envp); | ||
252 | } | ||
253 | |||
254 | kobject_put(kobj); | ||
255 | } | 196 | } |
256 | 197 | ||
257 | static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data) | 198 | static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data) |
258 | { | 199 | { |
259 | struct ata_device *dev = data; | 200 | struct ata_device *dev = data; |
260 | 201 | ||
261 | ata_acpi_handle_hotplug(dev->link->ap, dev, event, 1); | 202 | ata_acpi_handle_hotplug(dev->link->ap, dev, event); |
262 | } | 203 | } |
263 | 204 | ||
264 | static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data) | 205 | static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data) |
265 | { | 206 | { |
266 | struct ata_port *ap = data; | 207 | struct ata_port *ap = data; |
267 | 208 | ||
268 | ata_acpi_handle_hotplug(ap, NULL, event, 1); | 209 | ata_acpi_handle_hotplug(ap, NULL, event); |
269 | } | 210 | } |
270 | 211 | ||
271 | static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) | 212 | static void ata_acpi_uevent(struct ata_port *ap, struct ata_device *dev, |
213 | u32 event) | ||
272 | { | 214 | { |
273 | struct ata_device *dev = data; | 215 | struct kobject *kobj = NULL; |
216 | char event_string[20]; | ||
217 | char *envp[] = { event_string, NULL }; | ||
218 | |||
219 | if (dev) { | ||
220 | if (dev->sdev) | ||
221 | kobj = &dev->sdev->sdev_gendev.kobj; | ||
222 | } else | ||
223 | kobj = &ap->dev->kobj; | ||
274 | 224 | ||
275 | ata_acpi_handle_hotplug(dev->link->ap, dev, event, 0); | 225 | if (kobj) { |
226 | snprintf(event_string, 20, "BAY_EVENT=%d", event); | ||
227 | kobject_uevent_env(kobj, KOBJ_CHANGE, envp); | ||
228 | } | ||
276 | } | 229 | } |
277 | 230 | ||
278 | static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data) | 231 | static void ata_acpi_ap_uevent(acpi_handle handle, u32 event, void *data) |
279 | { | 232 | { |
280 | struct ata_port *ap = data; | 233 | ata_acpi_uevent(data, NULL, event); |
234 | } | ||
281 | 235 | ||
282 | ata_acpi_handle_hotplug(ap, NULL, event, 0); | 236 | static void ata_acpi_dev_uevent(acpi_handle handle, u32 event, void *data) |
237 | { | ||
238 | struct ata_device *dev = data; | ||
239 | ata_acpi_uevent(dev->link->ap, dev, event); | ||
283 | } | 240 | } |
284 | 241 | ||
242 | static struct acpi_dock_ops ata_acpi_dev_dock_ops = { | ||
243 | .handler = ata_acpi_dev_notify_dock, | ||
244 | .uevent = ata_acpi_dev_uevent, | ||
245 | }; | ||
246 | |||
247 | static struct acpi_dock_ops ata_acpi_ap_dock_ops = { | ||
248 | .handler = ata_acpi_ap_notify_dock, | ||
249 | .uevent = ata_acpi_ap_uevent, | ||
250 | }; | ||
251 | |||
285 | /** | 252 | /** |
286 | * ata_acpi_associate - associate ATA host with ACPI objects | 253 | * ata_acpi_associate - associate ATA host with ACPI objects |
287 | * @host: target ATA host | 254 | * @host: target ATA host |
@@ -315,24 +282,18 @@ void ata_acpi_associate(struct ata_host *host) | |||
315 | ata_acpi_associate_ide_port(ap); | 282 | ata_acpi_associate_ide_port(ap); |
316 | 283 | ||
317 | if (ap->acpi_handle) { | 284 | if (ap->acpi_handle) { |
318 | acpi_install_notify_handler(ap->acpi_handle, | ||
319 | ACPI_SYSTEM_NOTIFY, | ||
320 | ata_acpi_ap_notify, ap); | ||
321 | /* we might be on a docking station */ | 285 | /* we might be on a docking station */ |
322 | register_hotplug_dock_device(ap->acpi_handle, | 286 | register_hotplug_dock_device(ap->acpi_handle, |
323 | ata_acpi_ap_notify_dock, ap); | 287 | &ata_acpi_ap_dock_ops, ap); |
324 | } | 288 | } |
325 | 289 | ||
326 | for (j = 0; j < ata_link_max_devices(&ap->link); j++) { | 290 | for (j = 0; j < ata_link_max_devices(&ap->link); j++) { |
327 | struct ata_device *dev = &ap->link.device[j]; | 291 | struct ata_device *dev = &ap->link.device[j]; |
328 | 292 | ||
329 | if (dev->acpi_handle) { | 293 | if (dev->acpi_handle) { |
330 | acpi_install_notify_handler(dev->acpi_handle, | ||
331 | ACPI_SYSTEM_NOTIFY, | ||
332 | ata_acpi_dev_notify, dev); | ||
333 | /* we might be on a docking station */ | 294 | /* we might be on a docking station */ |
334 | register_hotplug_dock_device(dev->acpi_handle, | 295 | register_hotplug_dock_device(dev->acpi_handle, |
335 | ata_acpi_dev_notify_dock, dev); | 296 | &ata_acpi_dev_dock_ops, dev); |
336 | } | 297 | } |
337 | } | 298 | } |
338 | } | 299 | } |
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 5ce07b517c58..bb6e3b338043 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
@@ -56,7 +56,11 @@ static void cpuidle_idle_call(void) | |||
56 | if (pm_idle_old) | 56 | if (pm_idle_old) |
57 | pm_idle_old(); | 57 | pm_idle_old(); |
58 | else | 58 | else |
59 | #if defined(CONFIG_ARCH_HAS_DEFAULT_IDLE) | ||
60 | default_idle(); | ||
61 | #else | ||
59 | local_irq_enable(); | 62 | local_irq_enable(); |
63 | #endif | ||
60 | return; | 64 | return; |
61 | } | 65 | } |
62 | 66 | ||
@@ -67,8 +71,11 @@ static void cpuidle_idle_call(void) | |||
67 | target_state = &dev->states[next_state]; | 71 | target_state = &dev->states[next_state]; |
68 | 72 | ||
69 | /* enter the state and update stats */ | 73 | /* enter the state and update stats */ |
70 | dev->last_residency = target_state->enter(dev, target_state); | ||
71 | dev->last_state = target_state; | 74 | dev->last_state = target_state; |
75 | dev->last_residency = target_state->enter(dev, target_state); | ||
76 | if (dev->last_state) | ||
77 | target_state = dev->last_state; | ||
78 | |||
72 | target_state->time += (unsigned long long)dev->last_residency; | 79 | target_state->time += (unsigned long long)dev->last_residency; |
73 | target_state->usage++; | 80 | target_state->usage++; |
74 | 81 | ||
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c index 1ef68b315657..43b8cefad2c6 100644 --- a/drivers/dma/ioat_dma.c +++ b/drivers/dma/ioat_dma.c | |||
@@ -171,6 +171,9 @@ static int ioat_dma_enumerate_channels(struct ioatdma_device *device) | |||
171 | xfercap_scale = readb(device->reg_base + IOAT_XFERCAP_OFFSET); | 171 | xfercap_scale = readb(device->reg_base + IOAT_XFERCAP_OFFSET); |
172 | xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale)); | 172 | xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale)); |
173 | 173 | ||
174 | #if CONFIG_I7300_IDLE_IOAT_CHANNEL | ||
175 | device->common.chancnt--; | ||
176 | #endif | ||
174 | for (i = 0; i < device->common.chancnt; i++) { | 177 | for (i = 0; i < device->common.chancnt; i++) { |
175 | ioat_chan = kzalloc(sizeof(*ioat_chan), GFP_KERNEL); | 178 | ioat_chan = kzalloc(sizeof(*ioat_chan), GFP_KERNEL); |
176 | if (!ioat_chan) { | 179 | if (!ioat_chan) { |
diff --git a/drivers/idle/Kconfig b/drivers/idle/Kconfig new file mode 100644 index 000000000000..f5b26dd579e4 --- /dev/null +++ b/drivers/idle/Kconfig | |||
@@ -0,0 +1,16 @@ | |||
1 | |||
2 | menu "Memory power savings" | ||
3 | |||
4 | config I7300_IDLE_IOAT_CHANNEL | ||
5 | bool | ||
6 | |||
7 | config I7300_IDLE | ||
8 | tristate "Intel chipset idle power saving driver" | ||
9 | select I7300_IDLE_IOAT_CHANNEL | ||
10 | depends on X86_64 | ||
11 | help | ||
12 | Enable idle power savings with certain Intel server chipsets. | ||
13 | The chipset must have I/O AT support, such as the Intel 7300. | ||
14 | The power savings depends on the type and quantity of DRAM devices. | ||
15 | |||
16 | endmenu | ||
diff --git a/drivers/idle/Makefile b/drivers/idle/Makefile new file mode 100644 index 000000000000..5f68fc377e21 --- /dev/null +++ b/drivers/idle/Makefile | |||
@@ -0,0 +1,2 @@ | |||
1 | obj-$(CONFIG_I7300_IDLE) += i7300_idle.o | ||
2 | |||
diff --git a/drivers/idle/i7300_idle.c b/drivers/idle/i7300_idle.c new file mode 100644 index 000000000000..59d1bbc3cd3c --- /dev/null +++ b/drivers/idle/i7300_idle.c | |||
@@ -0,0 +1,674 @@ | |||
1 | /* | ||
2 | * (C) Copyright 2008 Intel Corporation | ||
3 | * Authors: | ||
4 | * Andy Henroid <andrew.d.henroid@intel.com> | ||
5 | * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> | ||
6 | */ | ||
7 | |||
8 | /* | ||
9 | * Save DIMM power on Intel 7300-based platforms when all CPUs/cores | ||
10 | * are idle, using the DIMM thermal throttling capability. | ||
11 | * | ||
12 | * This driver depends on the Intel integrated DMA controller (I/O AT). | ||
13 | * If the driver for I/O AT (drivers/dma/ioatdma*) is also enabled, | ||
14 | * this driver should work cooperatively. | ||
15 | */ | ||
16 | |||
17 | /* #define DEBUG */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/pci.h> | ||
21 | #include <linux/sched.h> | ||
22 | #include <linux/notifier.h> | ||
23 | #include <linux/cpumask.h> | ||
24 | #include <linux/ktime.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/debugfs.h> | ||
27 | #include <linux/stop_machine.h> | ||
28 | |||
29 | #include <asm/idle.h> | ||
30 | |||
31 | #include "../dma/ioatdma_hw.h" | ||
32 | #include "../dma/ioatdma_registers.h" | ||
33 | |||
34 | #define I7300_IDLE_DRIVER_VERSION "1.55" | ||
35 | #define I7300_PRINT "i7300_idle:" | ||
36 | |||
37 | static int debug; | ||
38 | module_param_named(debug, debug, uint, 0644); | ||
39 | MODULE_PARM_DESC(debug, "Enable debug printks in this driver"); | ||
40 | |||
41 | #define dprintk(fmt, arg...) \ | ||
42 | do { if (debug) printk(KERN_INFO I7300_PRINT fmt, ##arg); } while (0) | ||
43 | |||
44 | /* | ||
45 | * Value to set THRTLOW to when initiating throttling | ||
46 | * 0 = No throttling | ||
47 | * 1 = Throttle when > 4 activations per eval window (Maximum throttling) | ||
48 | * 2 = Throttle when > 8 activations | ||
49 | * 168 = Throttle when > 168 activations (Minimum throttling) | ||
50 | */ | ||
51 | #define MAX_THRTLWLIMIT 168 | ||
52 | static uint i7300_idle_thrtlowlm = 1; | ||
53 | module_param_named(thrtlwlimit, i7300_idle_thrtlowlm, uint, 0644); | ||
54 | MODULE_PARM_DESC(thrtlwlimit, | ||
55 | "Value for THRTLOWLM activation field " | ||
56 | "(0 = disable throttle, 1 = Max throttle, 168 = Min throttle)"); | ||
57 | |||
58 | /* | ||
59 | * simple invocation and duration statistics | ||
60 | */ | ||
61 | static unsigned long total_starts; | ||
62 | static unsigned long total_us; | ||
63 | |||
64 | #ifdef DEBUG | ||
65 | static unsigned long past_skip; | ||
66 | #endif | ||
67 | |||
68 | static struct pci_dev *fbd_dev; | ||
69 | |||
70 | static spinlock_t i7300_idle_lock; | ||
71 | static int i7300_idle_active; | ||
72 | |||
73 | static u8 i7300_idle_thrtctl_saved; | ||
74 | static u8 i7300_idle_thrtlow_saved; | ||
75 | static u32 i7300_idle_mc_saved; | ||
76 | |||
77 | static cpumask_t idle_cpumask; | ||
78 | static ktime_t start_ktime; | ||
79 | static unsigned long avg_idle_us; | ||
80 | |||
81 | static struct dentry *debugfs_dir; | ||
82 | |||
83 | /* Begin: I/O AT Helper routines */ | ||
84 | |||
85 | #define IOAT_CHANBASE(ioat_ctl, chan) (ioat_ctl + 0x80 + 0x80 * chan) | ||
86 | /* Snoop control (disable snoops when coherency is not important) */ | ||
87 | #define IOAT_DESC_SADDR_SNP_CTL (1UL << 1) | ||
88 | #define IOAT_DESC_DADDR_SNP_CTL (1UL << 2) | ||
89 | |||
90 | static struct pci_dev *ioat_dev; | ||
91 | static struct ioat_dma_descriptor *ioat_desc; /* I/O AT desc & data (1 page) */ | ||
92 | static unsigned long ioat_desc_phys; | ||
93 | static u8 *ioat_iomap; /* I/O AT memory-mapped control regs (aka CB_BAR) */ | ||
94 | static u8 *ioat_chanbase; | ||
95 | |||
96 | /* Start I/O AT memory copy */ | ||
97 | static int i7300_idle_ioat_start(void) | ||
98 | { | ||
99 | u32 err; | ||
100 | /* Clear error (due to circular descriptor pointer) */ | ||
101 | err = readl(ioat_chanbase + IOAT_CHANERR_OFFSET); | ||
102 | if (err) | ||
103 | writel(err, ioat_chanbase + IOAT_CHANERR_OFFSET); | ||
104 | |||
105 | writeb(IOAT_CHANCMD_START, ioat_chanbase + IOAT1_CHANCMD_OFFSET); | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | /* Stop I/O AT memory copy */ | ||
110 | static void i7300_idle_ioat_stop(void) | ||
111 | { | ||
112 | int i; | ||
113 | u8 sts; | ||
114 | |||
115 | for (i = 0; i < 5; i++) { | ||
116 | writeb(IOAT_CHANCMD_RESET, | ||
117 | ioat_chanbase + IOAT1_CHANCMD_OFFSET); | ||
118 | |||
119 | udelay(10); | ||
120 | |||
121 | sts = readq(ioat_chanbase + IOAT1_CHANSTS_OFFSET) & | ||
122 | IOAT_CHANSTS_DMA_TRANSFER_STATUS; | ||
123 | |||
124 | if (sts != IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE) | ||
125 | break; | ||
126 | |||
127 | } | ||
128 | |||
129 | if (i == 5) | ||
130 | dprintk("failed to suspend+reset I/O AT after 5 retries\n"); | ||
131 | |||
132 | } | ||
133 | |||
134 | /* Test I/O AT by copying 1024 byte from 2k to 1k */ | ||
135 | static int __init i7300_idle_ioat_selftest(u8 *ctl, | ||
136 | struct ioat_dma_descriptor *desc, unsigned long desc_phys) | ||
137 | { | ||
138 | u64 chan_sts; | ||
139 | |||
140 | memset(desc, 0, 2048); | ||
141 | memset((u8 *) desc + 2048, 0xab, 1024); | ||
142 | |||
143 | desc[0].size = 1024; | ||
144 | desc[0].ctl = 0; | ||
145 | desc[0].src_addr = desc_phys + 2048; | ||
146 | desc[0].dst_addr = desc_phys + 1024; | ||
147 | desc[0].next = 0; | ||
148 | |||
149 | writeb(IOAT_CHANCMD_RESET, ioat_chanbase + IOAT1_CHANCMD_OFFSET); | ||
150 | writeb(IOAT_CHANCMD_START, ioat_chanbase + IOAT1_CHANCMD_OFFSET); | ||
151 | |||
152 | udelay(1000); | ||
153 | |||
154 | chan_sts = readq(ioat_chanbase + IOAT1_CHANSTS_OFFSET) & | ||
155 | IOAT_CHANSTS_DMA_TRANSFER_STATUS; | ||
156 | |||
157 | if (chan_sts != IOAT_CHANSTS_DMA_TRANSFER_STATUS_DONE) { | ||
158 | /* Not complete, reset the channel */ | ||
159 | writeb(IOAT_CHANCMD_RESET, | ||
160 | ioat_chanbase + IOAT1_CHANCMD_OFFSET); | ||
161 | return -1; | ||
162 | } | ||
163 | |||
164 | if (*(u32 *) ((u8 *) desc + 3068) != 0xabababab || | ||
165 | *(u32 *) ((u8 *) desc + 2044) != 0xabababab) { | ||
166 | dprintk("Data values src 0x%x, dest 0x%x, memset 0x%x\n", | ||
167 | *(u32 *) ((u8 *) desc + 2048), | ||
168 | *(u32 *) ((u8 *) desc + 1024), | ||
169 | *(u32 *) ((u8 *) desc + 3072)); | ||
170 | return -1; | ||
171 | } | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static struct device dummy_dma_dev = { | ||
176 | .bus_id = "fallback device", | ||
177 | .coherent_dma_mask = DMA_64BIT_MASK, | ||
178 | .dma_mask = &dummy_dma_dev.coherent_dma_mask, | ||
179 | }; | ||
180 | |||
181 | /* Setup and initialize I/O AT */ | ||
182 | /* This driver needs I/O AT as the throttling takes effect only when there is | ||
183 | * some memory activity. We use I/O AT to set up a dummy copy, while all CPUs | ||
184 | * go idle and memory is throttled. | ||
185 | */ | ||
186 | static int __init i7300_idle_ioat_init(void) | ||
187 | { | ||
188 | u8 ver, chan_count, ioat_chan; | ||
189 | u16 chan_ctl; | ||
190 | |||
191 | ioat_iomap = (u8 *) ioremap_nocache(pci_resource_start(ioat_dev, 0), | ||
192 | pci_resource_len(ioat_dev, 0)); | ||
193 | |||
194 | if (!ioat_iomap) { | ||
195 | printk(KERN_ERR I7300_PRINT "failed to map I/O AT registers\n"); | ||
196 | goto err_ret; | ||
197 | } | ||
198 | |||
199 | ver = readb(ioat_iomap + IOAT_VER_OFFSET); | ||
200 | if (ver != IOAT_VER_1_2) { | ||
201 | printk(KERN_ERR I7300_PRINT "unknown I/O AT version (%u.%u)\n", | ||
202 | ver >> 4, ver & 0xf); | ||
203 | goto err_unmap; | ||
204 | } | ||
205 | |||
206 | chan_count = readb(ioat_iomap + IOAT_CHANCNT_OFFSET); | ||
207 | if (!chan_count) { | ||
208 | printk(KERN_ERR I7300_PRINT "unexpected # of I/O AT channels " | ||
209 | "(%u)\n", | ||
210 | chan_count); | ||
211 | goto err_unmap; | ||
212 | } | ||
213 | |||
214 | ioat_chan = chan_count - 1; | ||
215 | ioat_chanbase = IOAT_CHANBASE(ioat_iomap, ioat_chan); | ||
216 | |||
217 | chan_ctl = readw(ioat_chanbase + IOAT_CHANCTRL_OFFSET); | ||
218 | if (chan_ctl & IOAT_CHANCTRL_CHANNEL_IN_USE) { | ||
219 | printk(KERN_ERR I7300_PRINT "channel %d in use\n", ioat_chan); | ||
220 | goto err_unmap; | ||
221 | } | ||
222 | |||
223 | writew(IOAT_CHANCTRL_CHANNEL_IN_USE, | ||
224 | ioat_chanbase + IOAT_CHANCTRL_OFFSET); | ||
225 | |||
226 | ioat_desc = (struct ioat_dma_descriptor *)dma_alloc_coherent( | ||
227 | &dummy_dma_dev, 4096, | ||
228 | (dma_addr_t *)&ioat_desc_phys, GFP_KERNEL); | ||
229 | if (!ioat_desc) { | ||
230 | printk(KERN_ERR I7300_PRINT "failed to allocate I/O AT desc\n"); | ||
231 | goto err_mark_unused; | ||
232 | } | ||
233 | |||
234 | writel(ioat_desc_phys & 0xffffffffUL, | ||
235 | ioat_chanbase + IOAT1_CHAINADDR_OFFSET_LOW); | ||
236 | writel(ioat_desc_phys >> 32, | ||
237 | ioat_chanbase + IOAT1_CHAINADDR_OFFSET_HIGH); | ||
238 | |||
239 | if (i7300_idle_ioat_selftest(ioat_iomap, ioat_desc, ioat_desc_phys)) { | ||
240 | printk(KERN_ERR I7300_PRINT "I/O AT self-test failed\n"); | ||
241 | goto err_free; | ||
242 | } | ||
243 | |||
244 | /* Setup circular I/O AT descriptor chain */ | ||
245 | ioat_desc[0].ctl = IOAT_DESC_SADDR_SNP_CTL | IOAT_DESC_DADDR_SNP_CTL; | ||
246 | ioat_desc[0].src_addr = ioat_desc_phys + 2048; | ||
247 | ioat_desc[0].dst_addr = ioat_desc_phys + 3072; | ||
248 | ioat_desc[0].size = 128; | ||
249 | ioat_desc[0].next = ioat_desc_phys + sizeof(struct ioat_dma_descriptor); | ||
250 | |||
251 | ioat_desc[1].ctl = ioat_desc[0].ctl; | ||
252 | ioat_desc[1].src_addr = ioat_desc[0].src_addr; | ||
253 | ioat_desc[1].dst_addr = ioat_desc[0].dst_addr; | ||
254 | ioat_desc[1].size = ioat_desc[0].size; | ||
255 | ioat_desc[1].next = ioat_desc_phys; | ||
256 | |||
257 | return 0; | ||
258 | |||
259 | err_free: | ||
260 | dma_free_coherent(&dummy_dma_dev, 4096, (void *)ioat_desc, 0); | ||
261 | err_mark_unused: | ||
262 | writew(0, ioat_chanbase + IOAT_CHANCTRL_OFFSET); | ||
263 | err_unmap: | ||
264 | iounmap(ioat_iomap); | ||
265 | err_ret: | ||
266 | return -ENODEV; | ||
267 | } | ||
268 | |||
269 | /* Cleanup I/O AT */ | ||
270 | static void __exit i7300_idle_ioat_exit(void) | ||
271 | { | ||
272 | int i; | ||
273 | u64 chan_sts; | ||
274 | |||
275 | i7300_idle_ioat_stop(); | ||
276 | |||
277 | /* Wait for a while for the channel to halt before releasing */ | ||
278 | for (i = 0; i < 10; i++) { | ||
279 | writeb(IOAT_CHANCMD_RESET, | ||
280 | ioat_chanbase + IOAT1_CHANCMD_OFFSET); | ||
281 | |||
282 | chan_sts = readq(ioat_chanbase + IOAT1_CHANSTS_OFFSET) & | ||
283 | IOAT_CHANSTS_DMA_TRANSFER_STATUS; | ||
284 | |||
285 | if (chan_sts != IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE) { | ||
286 | writew(0, ioat_chanbase + IOAT_CHANCTRL_OFFSET); | ||
287 | break; | ||
288 | } | ||
289 | udelay(1000); | ||
290 | } | ||
291 | |||
292 | chan_sts = readq(ioat_chanbase + IOAT1_CHANSTS_OFFSET) & | ||
293 | IOAT_CHANSTS_DMA_TRANSFER_STATUS; | ||
294 | |||
295 | /* | ||
296 | * We tried to reset multiple times. If IO A/T channel is still active | ||
297 | * flag an error and return without cleanup. Memory leak is better | ||
298 | * than random corruption in that extreme error situation. | ||
299 | */ | ||
300 | if (chan_sts == IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE) { | ||
301 | printk(KERN_ERR I7300_PRINT "Unable to stop IO A/T channels." | ||
302 | " Not freeing resources\n"); | ||
303 | return; | ||
304 | } | ||
305 | |||
306 | dma_free_coherent(&dummy_dma_dev, 4096, (void *)ioat_desc, 0); | ||
307 | iounmap(ioat_iomap); | ||
308 | } | ||
309 | |||
310 | /* End: I/O AT Helper routines */ | ||
311 | |||
312 | #define DIMM_THRTLOW 0x64 | ||
313 | #define DIMM_THRTCTL 0x67 | ||
314 | #define DIMM_THRTCTL_THRMHUNT (1UL << 0) | ||
315 | #define DIMM_MC 0x40 | ||
316 | #define DIMM_GTW_MODE (1UL << 17) | ||
317 | #define DIMM_GBLACT 0x60 | ||
318 | |||
319 | /* | ||
320 | * Keep track of an exponential-decaying average of recent idle durations. | ||
321 | * The latest duration gets DURATION_WEIGHT_PCT percentage weight | ||
322 | * in this average, with the old average getting the remaining weight. | ||
323 | * | ||
324 | * High weights emphasize recent history, low weights include long history. | ||
325 | */ | ||
326 | #define DURATION_WEIGHT_PCT 55 | ||
327 | |||
328 | /* | ||
329 | * When the decaying average of recent durations or the predicted duration | ||
330 | * of the next timer interrupt is shorter than duration_threshold, the | ||
331 | * driver will decline to throttle. | ||
332 | */ | ||
333 | #define DURATION_THRESHOLD_US 100 | ||
334 | |||
335 | |||
336 | /* Store DIMM thermal throttle configuration */ | ||
337 | static int i7300_idle_thrt_save(void) | ||
338 | { | ||
339 | u32 new_mc_val; | ||
340 | u8 gblactlm; | ||
341 | |||
342 | pci_read_config_byte(fbd_dev, DIMM_THRTCTL, &i7300_idle_thrtctl_saved); | ||
343 | pci_read_config_byte(fbd_dev, DIMM_THRTLOW, &i7300_idle_thrtlow_saved); | ||
344 | pci_read_config_dword(fbd_dev, DIMM_MC, &i7300_idle_mc_saved); | ||
345 | /* | ||
346 | * Make sure we have Global Throttling Window Mode set to have a | ||
347 | * "short" window. This (mostly) works around an issue where | ||
348 | * throttling persists until the end of the global throttling window | ||
349 | * size. On the tested system, this was resulting in a maximum of | ||
350 | * 64 ms to exit throttling (average 32 ms). The actual numbers | ||
351 | * depends on system frequencies. Setting the short window reduces | ||
352 | * this by a factor of 4096. | ||
353 | * | ||
354 | * We will only do this only if the system is set for | ||
355 | * unlimited-activations while in open-loop throttling (i.e., when | ||
356 | * Global Activation Throttle Limit is zero). | ||
357 | */ | ||
358 | pci_read_config_byte(fbd_dev, DIMM_GBLACT, &gblactlm); | ||
359 | dprintk("thrtctl_saved = 0x%02x, thrtlow_saved = 0x%02x\n", | ||
360 | i7300_idle_thrtctl_saved, | ||
361 | i7300_idle_thrtlow_saved); | ||
362 | dprintk("mc_saved = 0x%08x, gblactlm = 0x%02x\n", | ||
363 | i7300_idle_mc_saved, | ||
364 | gblactlm); | ||
365 | if (gblactlm == 0) { | ||
366 | new_mc_val = i7300_idle_mc_saved | DIMM_GTW_MODE; | ||
367 | pci_write_config_dword(fbd_dev, DIMM_MC, new_mc_val); | ||
368 | return 0; | ||
369 | } else { | ||
370 | dprintk("could not set GTW_MODE = 1 (OLTT enabled)\n"); | ||
371 | return -ENODEV; | ||
372 | } | ||
373 | } | ||
374 | |||
375 | /* Restore DIMM thermal throttle configuration */ | ||
376 | static void i7300_idle_thrt_restore(void) | ||
377 | { | ||
378 | pci_write_config_dword(fbd_dev, DIMM_MC, i7300_idle_mc_saved); | ||
379 | pci_write_config_byte(fbd_dev, DIMM_THRTLOW, i7300_idle_thrtlow_saved); | ||
380 | pci_write_config_byte(fbd_dev, DIMM_THRTCTL, i7300_idle_thrtctl_saved); | ||
381 | } | ||
382 | |||
383 | /* Enable DIMM thermal throttling */ | ||
384 | static void i7300_idle_start(void) | ||
385 | { | ||
386 | u8 new_ctl; | ||
387 | u8 limit; | ||
388 | |||
389 | new_ctl = i7300_idle_thrtctl_saved & ~DIMM_THRTCTL_THRMHUNT; | ||
390 | pci_write_config_byte(fbd_dev, DIMM_THRTCTL, new_ctl); | ||
391 | |||
392 | limit = i7300_idle_thrtlowlm; | ||
393 | if (unlikely(limit > MAX_THRTLWLIMIT)) | ||
394 | limit = MAX_THRTLWLIMIT; | ||
395 | |||
396 | pci_write_config_byte(fbd_dev, DIMM_THRTLOW, limit); | ||
397 | |||
398 | new_ctl = i7300_idle_thrtctl_saved | DIMM_THRTCTL_THRMHUNT; | ||
399 | pci_write_config_byte(fbd_dev, DIMM_THRTCTL, new_ctl); | ||
400 | } | ||
401 | |||
402 | /* Disable DIMM thermal throttling */ | ||
403 | static void i7300_idle_stop(void) | ||
404 | { | ||
405 | u8 new_ctl; | ||
406 | u8 got_ctl; | ||
407 | |||
408 | new_ctl = i7300_idle_thrtctl_saved & ~DIMM_THRTCTL_THRMHUNT; | ||
409 | pci_write_config_byte(fbd_dev, DIMM_THRTCTL, new_ctl); | ||
410 | |||
411 | pci_write_config_byte(fbd_dev, DIMM_THRTLOW, i7300_idle_thrtlow_saved); | ||
412 | pci_write_config_byte(fbd_dev, DIMM_THRTCTL, i7300_idle_thrtctl_saved); | ||
413 | pci_read_config_byte(fbd_dev, DIMM_THRTCTL, &got_ctl); | ||
414 | WARN_ON_ONCE(got_ctl != i7300_idle_thrtctl_saved); | ||
415 | } | ||
416 | |||
417 | |||
418 | /* | ||
419 | * i7300_avg_duration_check() | ||
420 | * return 0 if the decaying average of recent idle durations is | ||
421 | * more than DURATION_THRESHOLD_US | ||
422 | */ | ||
423 | static int i7300_avg_duration_check(void) | ||
424 | { | ||
425 | if (avg_idle_us >= DURATION_THRESHOLD_US) | ||
426 | return 0; | ||
427 | |||
428 | #ifdef DEBUG | ||
429 | past_skip++; | ||
430 | #endif | ||
431 | return 1; | ||
432 | } | ||
433 | |||
434 | /* Idle notifier to look at idle CPUs */ | ||
435 | static int i7300_idle_notifier(struct notifier_block *nb, unsigned long val, | ||
436 | void *data) | ||
437 | { | ||
438 | unsigned long flags; | ||
439 | ktime_t now_ktime; | ||
440 | static ktime_t idle_begin_time; | ||
441 | static int time_init = 1; | ||
442 | |||
443 | if (!i7300_idle_thrtlowlm) | ||
444 | return 0; | ||
445 | |||
446 | if (unlikely(time_init)) { | ||
447 | time_init = 0; | ||
448 | idle_begin_time = ktime_get(); | ||
449 | } | ||
450 | |||
451 | spin_lock_irqsave(&i7300_idle_lock, flags); | ||
452 | if (val == IDLE_START) { | ||
453 | |||
454 | cpu_set(smp_processor_id(), idle_cpumask); | ||
455 | |||
456 | if (cpus_weight(idle_cpumask) != num_online_cpus()) | ||
457 | goto end; | ||
458 | |||
459 | now_ktime = ktime_get(); | ||
460 | idle_begin_time = now_ktime; | ||
461 | |||
462 | if (i7300_avg_duration_check()) | ||
463 | goto end; | ||
464 | |||
465 | i7300_idle_active = 1; | ||
466 | total_starts++; | ||
467 | start_ktime = now_ktime; | ||
468 | |||
469 | i7300_idle_start(); | ||
470 | i7300_idle_ioat_start(); | ||
471 | |||
472 | } else if (val == IDLE_END) { | ||
473 | cpu_clear(smp_processor_id(), idle_cpumask); | ||
474 | if (cpus_weight(idle_cpumask) == (num_online_cpus() - 1)) { | ||
475 | /* First CPU coming out of idle */ | ||
476 | u64 idle_duration_us; | ||
477 | |||
478 | now_ktime = ktime_get(); | ||
479 | |||
480 | idle_duration_us = ktime_to_us(ktime_sub | ||
481 | (now_ktime, idle_begin_time)); | ||
482 | |||
483 | avg_idle_us = | ||
484 | ((100 - DURATION_WEIGHT_PCT) * avg_idle_us + | ||
485 | DURATION_WEIGHT_PCT * idle_duration_us) / 100; | ||
486 | |||
487 | if (i7300_idle_active) { | ||
488 | ktime_t idle_ktime; | ||
489 | |||
490 | idle_ktime = ktime_sub(now_ktime, start_ktime); | ||
491 | total_us += ktime_to_us(idle_ktime); | ||
492 | |||
493 | i7300_idle_ioat_stop(); | ||
494 | i7300_idle_stop(); | ||
495 | i7300_idle_active = 0; | ||
496 | } | ||
497 | } | ||
498 | } | ||
499 | end: | ||
500 | spin_unlock_irqrestore(&i7300_idle_lock, flags); | ||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | static struct notifier_block i7300_idle_nb = { | ||
505 | .notifier_call = i7300_idle_notifier, | ||
506 | }; | ||
507 | |||
508 | /* | ||
509 | * I/O AT controls (PCI bus 0 device 8 function 0) | ||
510 | * DIMM controls (PCI bus 0 device 16 function 1) | ||
511 | */ | ||
512 | #define IOAT_BUS 0 | ||
513 | #define IOAT_DEVFN PCI_DEVFN(8, 0) | ||
514 | #define MEMCTL_BUS 0 | ||
515 | #define MEMCTL_DEVFN PCI_DEVFN(16, 1) | ||
516 | |||
517 | struct fbd_ioat { | ||
518 | unsigned int vendor; | ||
519 | unsigned int ioat_dev; | ||
520 | }; | ||
521 | |||
522 | /* | ||
523 | * The i5000 chip-set has the same hooks as the i7300 | ||
524 | * but support is disabled by default because this driver | ||
525 | * has not been validated on that platform. | ||
526 | */ | ||
527 | #define SUPPORT_I5000 0 | ||
528 | |||
529 | static const struct fbd_ioat fbd_ioat_list[] = { | ||
530 | {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB}, | ||
531 | #if SUPPORT_I5000 | ||
532 | {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT}, | ||
533 | #endif | ||
534 | {0, 0} | ||
535 | }; | ||
536 | |||
537 | /* table of devices that work with this driver */ | ||
538 | static const struct pci_device_id pci_tbl[] = { | ||
539 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_FBD_CNB) }, | ||
540 | #if SUPPORT_I5000 | ||
541 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) }, | ||
542 | #endif | ||
543 | { } /* Terminating entry */ | ||
544 | }; | ||
545 | |||
546 | MODULE_DEVICE_TABLE(pci, pci_tbl); | ||
547 | |||
548 | /* Check for known platforms with I/O-AT */ | ||
549 | static int __init i7300_idle_platform_probe(void) | ||
550 | { | ||
551 | int i; | ||
552 | |||
553 | fbd_dev = pci_get_bus_and_slot(MEMCTL_BUS, MEMCTL_DEVFN); | ||
554 | if (!fbd_dev) | ||
555 | return -ENODEV; | ||
556 | |||
557 | for (i = 0; pci_tbl[i].vendor != 0; i++) { | ||
558 | if (fbd_dev->vendor == pci_tbl[i].vendor && | ||
559 | fbd_dev->device == pci_tbl[i].device) { | ||
560 | break; | ||
561 | } | ||
562 | } | ||
563 | if (pci_tbl[i].vendor == 0) | ||
564 | return -ENODEV; | ||
565 | |||
566 | ioat_dev = pci_get_bus_and_slot(IOAT_BUS, IOAT_DEVFN); | ||
567 | if (!ioat_dev) | ||
568 | return -ENODEV; | ||
569 | |||
570 | for (i = 0; fbd_ioat_list[i].vendor != 0; i++) { | ||
571 | if (ioat_dev->vendor == fbd_ioat_list[i].vendor && | ||
572 | ioat_dev->device == fbd_ioat_list[i].ioat_dev) { | ||
573 | return 0; | ||
574 | } | ||
575 | } | ||
576 | return -ENODEV; | ||
577 | } | ||
578 | |||
579 | int stats_open_generic(struct inode *inode, struct file *fp) | ||
580 | { | ||
581 | fp->private_data = inode->i_private; | ||
582 | return 0; | ||
583 | } | ||
584 | |||
585 | static ssize_t stats_read_ul(struct file *fp, char __user *ubuf, size_t count, | ||
586 | loff_t *off) | ||
587 | { | ||
588 | unsigned long *p = fp->private_data; | ||
589 | char buf[32]; | ||
590 | int len; | ||
591 | |||
592 | len = snprintf(buf, 32, "%lu\n", *p); | ||
593 | return simple_read_from_buffer(ubuf, count, off, buf, len); | ||
594 | } | ||
595 | |||
596 | static const struct file_operations idle_fops = { | ||
597 | .open = stats_open_generic, | ||
598 | .read = stats_read_ul, | ||
599 | }; | ||
600 | |||
601 | struct debugfs_file_info { | ||
602 | void *ptr; | ||
603 | char name[32]; | ||
604 | struct dentry *file; | ||
605 | } debugfs_file_list[] = { | ||
606 | {&total_starts, "total_starts", NULL}, | ||
607 | {&total_us, "total_us", NULL}, | ||
608 | #ifdef DEBUG | ||
609 | {&past_skip, "past_skip", NULL}, | ||
610 | #endif | ||
611 | {NULL, "", NULL} | ||
612 | }; | ||
613 | |||
614 | static int __init i7300_idle_init(void) | ||
615 | { | ||
616 | spin_lock_init(&i7300_idle_lock); | ||
617 | cpus_clear(idle_cpumask); | ||
618 | total_us = 0; | ||
619 | |||
620 | if (i7300_idle_platform_probe()) | ||
621 | return -ENODEV; | ||
622 | |||
623 | if (i7300_idle_thrt_save()) | ||
624 | return -ENODEV; | ||
625 | |||
626 | if (i7300_idle_ioat_init()) | ||
627 | return -ENODEV; | ||
628 | |||
629 | debugfs_dir = debugfs_create_dir("i7300_idle", NULL); | ||
630 | if (debugfs_dir) { | ||
631 | int i = 0; | ||
632 | |||
633 | while (debugfs_file_list[i].ptr != NULL) { | ||
634 | debugfs_file_list[i].file = debugfs_create_file( | ||
635 | debugfs_file_list[i].name, | ||
636 | S_IRUSR, | ||
637 | debugfs_dir, | ||
638 | debugfs_file_list[i].ptr, | ||
639 | &idle_fops); | ||
640 | i++; | ||
641 | } | ||
642 | } | ||
643 | |||
644 | idle_notifier_register(&i7300_idle_nb); | ||
645 | |||
646 | printk(KERN_INFO "i7300_idle: loaded v%s\n", I7300_IDLE_DRIVER_VERSION); | ||
647 | return 0; | ||
648 | } | ||
649 | |||
650 | static void __exit i7300_idle_exit(void) | ||
651 | { | ||
652 | idle_notifier_unregister(&i7300_idle_nb); | ||
653 | |||
654 | if (debugfs_dir) { | ||
655 | int i = 0; | ||
656 | |||
657 | while (debugfs_file_list[i].file != NULL) { | ||
658 | debugfs_remove(debugfs_file_list[i].file); | ||
659 | i++; | ||
660 | } | ||
661 | |||
662 | debugfs_remove(debugfs_dir); | ||
663 | } | ||
664 | i7300_idle_thrt_restore(); | ||
665 | i7300_idle_ioat_exit(); | ||
666 | } | ||
667 | |||
668 | module_init(i7300_idle_init); | ||
669 | module_exit(i7300_idle_exit); | ||
670 | |||
671 | MODULE_AUTHOR("Andy Henroid <andrew.d.henroid@intel.com>"); | ||
672 | MODULE_DESCRIPTION("Intel Chipset DIMM Idle Power Saving Driver v" | ||
673 | I7300_IDLE_DRIVER_VERSION); | ||
674 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index efd3aa08b88b..9494400e8fd0 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -145,6 +145,7 @@ config ACER_WMI | |||
145 | depends on NEW_LEDS | 145 | depends on NEW_LEDS |
146 | depends on BACKLIGHT_CLASS_DEVICE | 146 | depends on BACKLIGHT_CLASS_DEVICE |
147 | depends on SERIO_I8042 | 147 | depends on SERIO_I8042 |
148 | depends on RFKILL | ||
148 | select ACPI_WMI | 149 | select ACPI_WMI |
149 | ---help--- | 150 | ---help--- |
150 | This is a driver for newer Acer (and Wistron) laptops. It adds | 151 | This is a driver for newer Acer (and Wistron) laptops. It adds |
@@ -245,6 +246,17 @@ config MSI_LAPTOP | |||
245 | 246 | ||
246 | If you have an MSI S270 laptop, say Y or M here. | 247 | If you have an MSI S270 laptop, say Y or M here. |
247 | 248 | ||
249 | config PANASONIC_LAPTOP | ||
250 | tristate "Panasonic Laptop Extras" | ||
251 | depends on X86 && INPUT && ACPI | ||
252 | depends on BACKLIGHT_CLASS_DEVICE | ||
253 | ---help--- | ||
254 | This driver adds support for access to backlight control and hotkeys | ||
255 | on Panasonic Let's Note laptops. | ||
256 | |||
257 | If you have a Panasonic Let's note laptop (such as the R1(N variant), | ||
258 | R2, R3, R5, T2, W2 and Y2 series), say Y. | ||
259 | |||
248 | config COMPAL_LAPTOP | 260 | config COMPAL_LAPTOP |
249 | tristate "Compal Laptop Extras" | 261 | tristate "Compal Laptop Extras" |
250 | depends on X86 | 262 | depends on X86 |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index c6c13f60b452..909e2468cdc9 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
@@ -23,6 +23,7 @@ obj-$(CONFIG_SGI_IOC4) += ioc4.o | |||
23 | obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o | 23 | obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o |
24 | obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o | 24 | obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o |
25 | obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o | 25 | obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o |
26 | obj-$(CONFIG_PANASONIC_LAPTOP) += panasonic-laptop.o | ||
26 | obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o | 27 | obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o |
27 | obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o | 28 | obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o |
28 | obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o | 29 | obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o |
diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index d8b0d326e452..0532a2de2ce4 100644 --- a/drivers/misc/acer-wmi.c +++ b/drivers/misc/acer-wmi.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
34 | #include <linux/acpi.h> | 34 | #include <linux/acpi.h> |
35 | #include <linux/i8042.h> | 35 | #include <linux/i8042.h> |
36 | #include <linux/rfkill.h> | ||
37 | #include <linux/workqueue.h> | ||
36 | #include <linux/debugfs.h> | 38 | #include <linux/debugfs.h> |
37 | 39 | ||
38 | #include <acpi/acpi_drivers.h> | 40 | #include <acpi/acpi_drivers.h> |
@@ -123,21 +125,15 @@ enum interface_flags { | |||
123 | 125 | ||
124 | static int max_brightness = 0xF; | 126 | static int max_brightness = 0xF; |
125 | 127 | ||
126 | static int wireless = -1; | ||
127 | static int bluetooth = -1; | ||
128 | static int mailled = -1; | 128 | static int mailled = -1; |
129 | static int brightness = -1; | 129 | static int brightness = -1; |
130 | static int threeg = -1; | 130 | static int threeg = -1; |
131 | static int force_series; | 131 | static int force_series; |
132 | 132 | ||
133 | module_param(mailled, int, 0444); | 133 | module_param(mailled, int, 0444); |
134 | module_param(wireless, int, 0444); | ||
135 | module_param(bluetooth, int, 0444); | ||
136 | module_param(brightness, int, 0444); | 134 | module_param(brightness, int, 0444); |
137 | module_param(threeg, int, 0444); | 135 | module_param(threeg, int, 0444); |
138 | module_param(force_series, int, 0444); | 136 | module_param(force_series, int, 0444); |
139 | MODULE_PARM_DESC(wireless, "Set initial state of Wireless hardware"); | ||
140 | MODULE_PARM_DESC(bluetooth, "Set initial state of Bluetooth hardware"); | ||
141 | MODULE_PARM_DESC(mailled, "Set initial state of Mail LED"); | 137 | MODULE_PARM_DESC(mailled, "Set initial state of Mail LED"); |
142 | MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness"); | 138 | MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness"); |
143 | MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware"); | 139 | MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware"); |
@@ -145,8 +141,6 @@ MODULE_PARM_DESC(force_series, "Force a different laptop series"); | |||
145 | 141 | ||
146 | struct acer_data { | 142 | struct acer_data { |
147 | int mailled; | 143 | int mailled; |
148 | int wireless; | ||
149 | int bluetooth; | ||
150 | int threeg; | 144 | int threeg; |
151 | int brightness; | 145 | int brightness; |
152 | }; | 146 | }; |
@@ -157,6 +151,9 @@ struct acer_debug { | |||
157 | u32 wmid_devices; | 151 | u32 wmid_devices; |
158 | }; | 152 | }; |
159 | 153 | ||
154 | static struct rfkill *wireless_rfkill; | ||
155 | static struct rfkill *bluetooth_rfkill; | ||
156 | |||
160 | /* Each low-level interface must define at least some of the following */ | 157 | /* Each low-level interface must define at least some of the following */ |
161 | struct wmi_interface { | 158 | struct wmi_interface { |
162 | /* The WMI device type */ | 159 | /* The WMI device type */ |
@@ -476,7 +473,7 @@ struct wmi_interface *iface) | |||
476 | } | 473 | } |
477 | break; | 474 | break; |
478 | default: | 475 | default: |
479 | return AE_BAD_ADDRESS; | 476 | return AE_ERROR; |
480 | } | 477 | } |
481 | return AE_OK; | 478 | return AE_OK; |
482 | } | 479 | } |
@@ -514,7 +511,7 @@ static acpi_status AMW0_set_u32(u32 value, u32 cap, struct wmi_interface *iface) | |||
514 | break; | 511 | break; |
515 | } | 512 | } |
516 | default: | 513 | default: |
517 | return AE_BAD_ADDRESS; | 514 | return AE_ERROR; |
518 | } | 515 | } |
519 | 516 | ||
520 | /* Actually do the set */ | 517 | /* Actually do the set */ |
@@ -689,7 +686,7 @@ struct wmi_interface *iface) | |||
689 | return 0; | 686 | return 0; |
690 | } | 687 | } |
691 | default: | 688 | default: |
692 | return AE_BAD_ADDRESS; | 689 | return AE_ERROR; |
693 | } | 690 | } |
694 | status = WMI_execute_u32(method_id, 0, &result); | 691 | status = WMI_execute_u32(method_id, 0, &result); |
695 | 692 | ||
@@ -735,7 +732,7 @@ static acpi_status WMID_set_u32(u32 value, u32 cap, struct wmi_interface *iface) | |||
735 | } | 732 | } |
736 | break; | 733 | break; |
737 | default: | 734 | default: |
738 | return AE_BAD_ADDRESS; | 735 | return AE_ERROR; |
739 | } | 736 | } |
740 | return WMI_execute_u32(method_id, (u32)value, NULL); | 737 | return WMI_execute_u32(method_id, (u32)value, NULL); |
741 | } | 738 | } |
@@ -785,7 +782,7 @@ static struct wmi_interface wmid_interface = { | |||
785 | 782 | ||
786 | static acpi_status get_u32(u32 *value, u32 cap) | 783 | static acpi_status get_u32(u32 *value, u32 cap) |
787 | { | 784 | { |
788 | acpi_status status = AE_BAD_ADDRESS; | 785 | acpi_status status = AE_ERROR; |
789 | 786 | ||
790 | switch (interface->type) { | 787 | switch (interface->type) { |
791 | case ACER_AMW0: | 788 | case ACER_AMW0: |
@@ -846,8 +843,6 @@ static void __init acer_commandline_init(void) | |||
846 | * capability isn't available on the given interface | 843 | * capability isn't available on the given interface |
847 | */ | 844 | */ |
848 | set_u32(mailled, ACER_CAP_MAILLED); | 845 | set_u32(mailled, ACER_CAP_MAILLED); |
849 | set_u32(wireless, ACER_CAP_WIRELESS); | ||
850 | set_u32(bluetooth, ACER_CAP_BLUETOOTH); | ||
851 | set_u32(threeg, ACER_CAP_THREEG); | 846 | set_u32(threeg, ACER_CAP_THREEG); |
852 | set_u32(brightness, ACER_CAP_BRIGHTNESS); | 847 | set_u32(brightness, ACER_CAP_BRIGHTNESS); |
853 | } | 848 | } |
@@ -933,40 +928,135 @@ static void acer_backlight_exit(void) | |||
933 | } | 928 | } |
934 | 929 | ||
935 | /* | 930 | /* |
936 | * Read/ write bool sysfs macro | 931 | * Rfkill devices |
937 | */ | 932 | */ |
938 | #define show_set_bool(value, cap) \ | 933 | static void acer_rfkill_update(struct work_struct *ignored); |
939 | static ssize_t \ | 934 | static DECLARE_DELAYED_WORK(acer_rfkill_work, acer_rfkill_update); |
940 | show_bool_##value(struct device *dev, struct device_attribute *attr, \ | 935 | static void acer_rfkill_update(struct work_struct *ignored) |
941 | char *buf) \ | 936 | { |
942 | { \ | 937 | u32 state; |
943 | u32 result; \ | 938 | acpi_status status; |
944 | acpi_status status = get_u32(&result, cap); \ | 939 | |
945 | if (ACPI_SUCCESS(status)) \ | 940 | status = get_u32(&state, ACER_CAP_WIRELESS); |
946 | return sprintf(buf, "%u\n", result); \ | 941 | if (ACPI_SUCCESS(status)) |
947 | return sprintf(buf, "Read error\n"); \ | 942 | rfkill_force_state(wireless_rfkill, state ? |
948 | } \ | 943 | RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED); |
949 | \ | 944 | |
950 | static ssize_t \ | 945 | if (has_cap(ACER_CAP_BLUETOOTH)) { |
951 | set_bool_##value(struct device *dev, struct device_attribute *attr, \ | 946 | status = get_u32(&state, ACER_CAP_BLUETOOTH); |
952 | const char *buf, size_t count) \ | 947 | if (ACPI_SUCCESS(status)) |
953 | { \ | 948 | rfkill_force_state(bluetooth_rfkill, state ? |
954 | u32 tmp = simple_strtoul(buf, NULL, 10); \ | 949 | RFKILL_STATE_UNBLOCKED : |
955 | acpi_status status = set_u32(tmp, cap); \ | 950 | RFKILL_STATE_SOFT_BLOCKED); |
956 | if (ACPI_FAILURE(status)) \ | 951 | } |
957 | return -EINVAL; \ | 952 | |
958 | return count; \ | 953 | schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ)); |
959 | } \ | 954 | } |
960 | static DEVICE_ATTR(value, S_IWUGO | S_IRUGO | S_IWUSR, \ | 955 | |
961 | show_bool_##value, set_bool_##value); | 956 | static int acer_rfkill_set(void *data, enum rfkill_state state) |
962 | 957 | { | |
963 | show_set_bool(wireless, ACER_CAP_WIRELESS); | 958 | acpi_status status; |
964 | show_set_bool(bluetooth, ACER_CAP_BLUETOOTH); | 959 | u32 *cap = data; |
965 | show_set_bool(threeg, ACER_CAP_THREEG); | 960 | status = set_u32((u32) (state == RFKILL_STATE_UNBLOCKED), *cap); |
961 | if (ACPI_FAILURE(status)) | ||
962 | return -ENODEV; | ||
963 | return 0; | ||
964 | } | ||
965 | |||
966 | static struct rfkill * acer_rfkill_register(struct device *dev, | ||
967 | enum rfkill_type type, char *name, u32 cap) | ||
968 | { | ||
969 | int err; | ||
970 | u32 state; | ||
971 | u32 *data; | ||
972 | struct rfkill *rfkill_dev; | ||
973 | |||
974 | rfkill_dev = rfkill_allocate(dev, type); | ||
975 | if (!rfkill_dev) | ||
976 | return ERR_PTR(-ENOMEM); | ||
977 | rfkill_dev->name = name; | ||
978 | get_u32(&state, cap); | ||
979 | rfkill_dev->state = state ? RFKILL_STATE_UNBLOCKED : | ||
980 | RFKILL_STATE_SOFT_BLOCKED; | ||
981 | data = kzalloc(sizeof(u32), GFP_KERNEL); | ||
982 | if (!data) { | ||
983 | rfkill_free(rfkill_dev); | ||
984 | return ERR_PTR(-ENOMEM); | ||
985 | } | ||
986 | *data = cap; | ||
987 | rfkill_dev->data = data; | ||
988 | rfkill_dev->toggle_radio = acer_rfkill_set; | ||
989 | rfkill_dev->user_claim_unsupported = 1; | ||
990 | |||
991 | err = rfkill_register(rfkill_dev); | ||
992 | if (err) { | ||
993 | kfree(rfkill_dev->data); | ||
994 | rfkill_free(rfkill_dev); | ||
995 | return ERR_PTR(err); | ||
996 | } | ||
997 | return rfkill_dev; | ||
998 | } | ||
999 | |||
1000 | static int acer_rfkill_init(struct device *dev) | ||
1001 | { | ||
1002 | wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN, | ||
1003 | "acer-wireless", ACER_CAP_WIRELESS); | ||
1004 | if (IS_ERR(wireless_rfkill)) | ||
1005 | return PTR_ERR(wireless_rfkill); | ||
1006 | |||
1007 | if (has_cap(ACER_CAP_BLUETOOTH)) { | ||
1008 | bluetooth_rfkill = acer_rfkill_register(dev, | ||
1009 | RFKILL_TYPE_BLUETOOTH, "acer-bluetooth", | ||
1010 | ACER_CAP_BLUETOOTH); | ||
1011 | if (IS_ERR(bluetooth_rfkill)) { | ||
1012 | kfree(wireless_rfkill->data); | ||
1013 | rfkill_unregister(wireless_rfkill); | ||
1014 | return PTR_ERR(bluetooth_rfkill); | ||
1015 | } | ||
1016 | } | ||
1017 | |||
1018 | schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ)); | ||
1019 | |||
1020 | return 0; | ||
1021 | } | ||
1022 | |||
1023 | static void acer_rfkill_exit(void) | ||
1024 | { | ||
1025 | cancel_delayed_work_sync(&acer_rfkill_work); | ||
1026 | kfree(wireless_rfkill->data); | ||
1027 | rfkill_unregister(wireless_rfkill); | ||
1028 | if (has_cap(ACER_CAP_BLUETOOTH)) { | ||
1029 | kfree(wireless_rfkill->data); | ||
1030 | rfkill_unregister(bluetooth_rfkill); | ||
1031 | } | ||
1032 | return; | ||
1033 | } | ||
966 | 1034 | ||
967 | /* | 1035 | /* |
968 | * Read interface sysfs macro | 1036 | * sysfs interface |
969 | */ | 1037 | */ |
1038 | static ssize_t show_bool_threeg(struct device *dev, | ||
1039 | struct device_attribute *attr, char *buf) | ||
1040 | { | ||
1041 | u32 result; \ | ||
1042 | acpi_status status = get_u32(&result, ACER_CAP_THREEG); | ||
1043 | if (ACPI_SUCCESS(status)) | ||
1044 | return sprintf(buf, "%u\n", result); | ||
1045 | return sprintf(buf, "Read error\n"); | ||
1046 | } | ||
1047 | |||
1048 | static ssize_t set_bool_threeg(struct device *dev, | ||
1049 | struct device_attribute *attr, const char *buf, size_t count) | ||
1050 | { | ||
1051 | u32 tmp = simple_strtoul(buf, NULL, 10); | ||
1052 | acpi_status status = set_u32(tmp, ACER_CAP_THREEG); | ||
1053 | if (ACPI_FAILURE(status)) | ||
1054 | return -EINVAL; | ||
1055 | return count; | ||
1056 | } | ||
1057 | static DEVICE_ATTR(threeg, S_IWUGO | S_IRUGO | S_IWUSR, show_bool_threeg, | ||
1058 | set_bool_threeg); | ||
1059 | |||
970 | static ssize_t show_interface(struct device *dev, struct device_attribute *attr, | 1060 | static ssize_t show_interface(struct device *dev, struct device_attribute *attr, |
971 | char *buf) | 1061 | char *buf) |
972 | { | 1062 | { |
@@ -1026,7 +1116,9 @@ static int __devinit acer_platform_probe(struct platform_device *device) | |||
1026 | goto error_brightness; | 1116 | goto error_brightness; |
1027 | } | 1117 | } |
1028 | 1118 | ||
1029 | return 0; | 1119 | err = acer_rfkill_init(&device->dev); |
1120 | |||
1121 | return err; | ||
1030 | 1122 | ||
1031 | error_brightness: | 1123 | error_brightness: |
1032 | acer_led_exit(); | 1124 | acer_led_exit(); |
@@ -1040,6 +1132,8 @@ static int acer_platform_remove(struct platform_device *device) | |||
1040 | acer_led_exit(); | 1132 | acer_led_exit(); |
1041 | if (has_cap(ACER_CAP_BRIGHTNESS)) | 1133 | if (has_cap(ACER_CAP_BRIGHTNESS)) |
1042 | acer_backlight_exit(); | 1134 | acer_backlight_exit(); |
1135 | |||
1136 | acer_rfkill_exit(); | ||
1043 | return 0; | 1137 | return 0; |
1044 | } | 1138 | } |
1045 | 1139 | ||
@@ -1052,16 +1146,6 @@ pm_message_t state) | |||
1052 | if (!data) | 1146 | if (!data) |
1053 | return -ENOMEM; | 1147 | return -ENOMEM; |
1054 | 1148 | ||
1055 | if (has_cap(ACER_CAP_WIRELESS)) { | ||
1056 | get_u32(&value, ACER_CAP_WIRELESS); | ||
1057 | data->wireless = value; | ||
1058 | } | ||
1059 | |||
1060 | if (has_cap(ACER_CAP_BLUETOOTH)) { | ||
1061 | get_u32(&value, ACER_CAP_BLUETOOTH); | ||
1062 | data->bluetooth = value; | ||
1063 | } | ||
1064 | |||
1065 | if (has_cap(ACER_CAP_MAILLED)) { | 1149 | if (has_cap(ACER_CAP_MAILLED)) { |
1066 | get_u32(&value, ACER_CAP_MAILLED); | 1150 | get_u32(&value, ACER_CAP_MAILLED); |
1067 | data->mailled = value; | 1151 | data->mailled = value; |
@@ -1082,15 +1166,6 @@ static int acer_platform_resume(struct platform_device *device) | |||
1082 | if (!data) | 1166 | if (!data) |
1083 | return -ENOMEM; | 1167 | return -ENOMEM; |
1084 | 1168 | ||
1085 | if (has_cap(ACER_CAP_WIRELESS)) | ||
1086 | set_u32(data->wireless, ACER_CAP_WIRELESS); | ||
1087 | |||
1088 | if (has_cap(ACER_CAP_BLUETOOTH)) | ||
1089 | set_u32(data->bluetooth, ACER_CAP_BLUETOOTH); | ||
1090 | |||
1091 | if (has_cap(ACER_CAP_THREEG)) | ||
1092 | set_u32(data->threeg, ACER_CAP_THREEG); | ||
1093 | |||
1094 | if (has_cap(ACER_CAP_MAILLED)) | 1169 | if (has_cap(ACER_CAP_MAILLED)) |
1095 | set_u32(data->mailled, ACER_CAP_MAILLED); | 1170 | set_u32(data->mailled, ACER_CAP_MAILLED); |
1096 | 1171 | ||
@@ -1115,12 +1190,6 @@ static struct platform_device *acer_platform_device; | |||
1115 | 1190 | ||
1116 | static int remove_sysfs(struct platform_device *device) | 1191 | static int remove_sysfs(struct platform_device *device) |
1117 | { | 1192 | { |
1118 | if (has_cap(ACER_CAP_WIRELESS)) | ||
1119 | device_remove_file(&device->dev, &dev_attr_wireless); | ||
1120 | |||
1121 | if (has_cap(ACER_CAP_BLUETOOTH)) | ||
1122 | device_remove_file(&device->dev, &dev_attr_bluetooth); | ||
1123 | |||
1124 | if (has_cap(ACER_CAP_THREEG)) | 1193 | if (has_cap(ACER_CAP_THREEG)) |
1125 | device_remove_file(&device->dev, &dev_attr_threeg); | 1194 | device_remove_file(&device->dev, &dev_attr_threeg); |
1126 | 1195 | ||
@@ -1133,20 +1202,6 @@ static int create_sysfs(void) | |||
1133 | { | 1202 | { |
1134 | int retval = -ENOMEM; | 1203 | int retval = -ENOMEM; |
1135 | 1204 | ||
1136 | if (has_cap(ACER_CAP_WIRELESS)) { | ||
1137 | retval = device_create_file(&acer_platform_device->dev, | ||
1138 | &dev_attr_wireless); | ||
1139 | if (retval) | ||
1140 | goto error_sysfs; | ||
1141 | } | ||
1142 | |||
1143 | if (has_cap(ACER_CAP_BLUETOOTH)) { | ||
1144 | retval = device_create_file(&acer_platform_device->dev, | ||
1145 | &dev_attr_bluetooth); | ||
1146 | if (retval) | ||
1147 | goto error_sysfs; | ||
1148 | } | ||
1149 | |||
1150 | if (has_cap(ACER_CAP_THREEG)) { | 1205 | if (has_cap(ACER_CAP_THREEG)) { |
1151 | retval = device_create_file(&acer_platform_device->dev, | 1206 | retval = device_create_file(&acer_platform_device->dev, |
1152 | &dev_attr_threeg); | 1207 | &dev_attr_threeg); |
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c index 7c6dfd03de9f..a9d5228724a6 100644 --- a/drivers/misc/asus-laptop.c +++ b/drivers/misc/asus-laptop.c | |||
@@ -139,6 +139,7 @@ ASUS_HANDLE(lcd_switch, "\\_SB.PCI0.SBRG.EC0._Q10", /* All new models */ | |||
139 | "\\_SB.PCI0.PX40.ECD0._Q10", /* L3C */ | 139 | "\\_SB.PCI0.PX40.ECD0._Q10", /* L3C */ |
140 | "\\_SB.PCI0.PX40.EC0.Q10", /* M1A */ | 140 | "\\_SB.PCI0.PX40.EC0.Q10", /* M1A */ |
141 | "\\_SB.PCI0.LPCB.EC0._Q10", /* P30 */ | 141 | "\\_SB.PCI0.LPCB.EC0._Q10", /* P30 */ |
142 | "\\_SB.PCI0.LPCB.EC0._Q0E", /* P30/P35 */ | ||
142 | "\\_SB.PCI0.PX40.Q10", /* S1x */ | 143 | "\\_SB.PCI0.PX40.Q10", /* S1x */ |
143 | "\\Q10"); /* A2x, L2D, L3D, M2E */ | 144 | "\\Q10"); /* A2x, L2D, L3D, M2E */ |
144 | 145 | ||
@@ -280,7 +281,7 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val, | |||
280 | 281 | ||
281 | static int read_wireless_status(int mask) | 282 | static int read_wireless_status(int mask) |
282 | { | 283 | { |
283 | ulong status; | 284 | unsigned long long status; |
284 | acpi_status rv = AE_OK; | 285 | acpi_status rv = AE_OK; |
285 | 286 | ||
286 | if (!wireless_status_handle) | 287 | if (!wireless_status_handle) |
@@ -297,7 +298,7 @@ static int read_wireless_status(int mask) | |||
297 | 298 | ||
298 | static int read_gps_status(void) | 299 | static int read_gps_status(void) |
299 | { | 300 | { |
300 | ulong status; | 301 | unsigned long long status; |
301 | acpi_status rv = AE_OK; | 302 | acpi_status rv = AE_OK; |
302 | 303 | ||
303 | rv = acpi_evaluate_integer(gps_status_handle, NULL, NULL, &status); | 304 | rv = acpi_evaluate_integer(gps_status_handle, NULL, NULL, &status); |
@@ -350,7 +351,7 @@ static void write_status(acpi_handle handle, int out, int mask) | |||
350 | static void object##_led_set(struct led_classdev *led_cdev, \ | 351 | static void object##_led_set(struct led_classdev *led_cdev, \ |
351 | enum led_brightness value) \ | 352 | enum led_brightness value) \ |
352 | { \ | 353 | { \ |
353 | object##_led_wk = value; \ | 354 | object##_led_wk = (value > 0) ? 1 : 0; \ |
354 | queue_work(led_workqueue, &object##_led_work); \ | 355 | queue_work(led_workqueue, &object##_led_work); \ |
355 | } \ | 356 | } \ |
356 | static void object##_led_update(struct work_struct *ignored) \ | 357 | static void object##_led_update(struct work_struct *ignored) \ |
@@ -404,7 +405,7 @@ static void lcd_blank(int blank) | |||
404 | 405 | ||
405 | static int read_brightness(struct backlight_device *bd) | 406 | static int read_brightness(struct backlight_device *bd) |
406 | { | 407 | { |
407 | ulong value; | 408 | unsigned long long value; |
408 | acpi_status rv = AE_OK; | 409 | acpi_status rv = AE_OK; |
409 | 410 | ||
410 | rv = acpi_evaluate_integer(brightness_get_handle, NULL, NULL, &value); | 411 | rv = acpi_evaluate_integer(brightness_get_handle, NULL, NULL, &value); |
@@ -455,7 +456,7 @@ static ssize_t show_infos(struct device *dev, | |||
455 | struct device_attribute *attr, char *page) | 456 | struct device_attribute *attr, char *page) |
456 | { | 457 | { |
457 | int len = 0; | 458 | int len = 0; |
458 | ulong temp; | 459 | unsigned long long temp; |
459 | char buf[16]; //enough for all info | 460 | char buf[16]; //enough for all info |
460 | acpi_status rv = AE_OK; | 461 | acpi_status rv = AE_OK; |
461 | 462 | ||
@@ -603,7 +604,7 @@ static void set_display(int value) | |||
603 | 604 | ||
604 | static int read_display(void) | 605 | static int read_display(void) |
605 | { | 606 | { |
606 | ulong value = 0; | 607 | unsigned long long value = 0; |
607 | acpi_status rv = AE_OK; | 608 | acpi_status rv = AE_OK; |
608 | 609 | ||
609 | /* In most of the case, we know how to set the display, but sometime | 610 | /* In most of the case, we know how to set the display, but sometime |
@@ -849,7 +850,7 @@ static int asus_hotk_get_info(void) | |||
849 | { | 850 | { |
850 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 851 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
851 | union acpi_object *model = NULL; | 852 | union acpi_object *model = NULL; |
852 | ulong bsts_result, hwrs_result; | 853 | unsigned long long bsts_result, hwrs_result; |
853 | char *string = NULL; | 854 | char *string = NULL; |
854 | acpi_status status; | 855 | acpi_status status; |
855 | 856 | ||
@@ -996,7 +997,7 @@ static int asus_hotk_add(struct acpi_device *device) | |||
996 | hotk->handle = device->handle; | 997 | hotk->handle = device->handle; |
997 | strcpy(acpi_device_name(device), ASUS_HOTK_DEVICE_NAME); | 998 | strcpy(acpi_device_name(device), ASUS_HOTK_DEVICE_NAME); |
998 | strcpy(acpi_device_class(device), ASUS_HOTK_CLASS); | 999 | strcpy(acpi_device_class(device), ASUS_HOTK_CLASS); |
999 | acpi_driver_data(device) = hotk; | 1000 | device->driver_data = hotk; |
1000 | hotk->device = device; | 1001 | hotk->device = device; |
1001 | 1002 | ||
1002 | result = asus_hotk_check(); | 1003 | result = asus_hotk_check(); |
diff --git a/drivers/misc/eeepc-laptop.c b/drivers/misc/eeepc-laptop.c index 1ee8501e90f1..9ef98b2d5039 100644 --- a/drivers/misc/eeepc-laptop.c +++ b/drivers/misc/eeepc-laptop.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <acpi/acpi_drivers.h> | 28 | #include <acpi/acpi_drivers.h> |
29 | #include <acpi/acpi_bus.h> | 29 | #include <acpi/acpi_bus.h> |
30 | #include <linux/uaccess.h> | 30 | #include <linux/uaccess.h> |
31 | #include <linux/input.h> | ||
32 | #include <linux/rfkill.h> | ||
31 | 33 | ||
32 | #define EEEPC_LAPTOP_VERSION "0.1" | 34 | #define EEEPC_LAPTOP_VERSION "0.1" |
33 | 35 | ||
@@ -125,6 +127,10 @@ struct eeepc_hotk { | |||
125 | by this BIOS */ | 127 | by this BIOS */ |
126 | uint init_flag; /* Init flags */ | 128 | uint init_flag; /* Init flags */ |
127 | u16 event_count[128]; /* count for each event */ | 129 | u16 event_count[128]; /* count for each event */ |
130 | struct input_dev *inputdev; | ||
131 | u16 *keycode_map; | ||
132 | struct rfkill *eeepc_wlan_rfkill; | ||
133 | struct rfkill *eeepc_bluetooth_rfkill; | ||
128 | }; | 134 | }; |
129 | 135 | ||
130 | /* The actual device the driver binds to */ | 136 | /* The actual device the driver binds to */ |
@@ -140,6 +146,27 @@ static struct platform_driver platform_driver = { | |||
140 | 146 | ||
141 | static struct platform_device *platform_device; | 147 | static struct platform_device *platform_device; |
142 | 148 | ||
149 | struct key_entry { | ||
150 | char type; | ||
151 | u8 code; | ||
152 | u16 keycode; | ||
153 | }; | ||
154 | |||
155 | enum { KE_KEY, KE_END }; | ||
156 | |||
157 | static struct key_entry eeepc_keymap[] = { | ||
158 | /* Sleep already handled via generic ACPI code */ | ||
159 | {KE_KEY, 0x10, KEY_WLAN }, | ||
160 | {KE_KEY, 0x12, KEY_PROG1 }, | ||
161 | {KE_KEY, 0x13, KEY_MUTE }, | ||
162 | {KE_KEY, 0x14, KEY_VOLUMEDOWN }, | ||
163 | {KE_KEY, 0x15, KEY_VOLUMEUP }, | ||
164 | {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, | ||
165 | {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, | ||
166 | {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, | ||
167 | {KE_END, 0}, | ||
168 | }; | ||
169 | |||
143 | /* | 170 | /* |
144 | * The hotkey driver declaration | 171 | * The hotkey driver declaration |
145 | */ | 172 | */ |
@@ -204,7 +231,7 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val, | |||
204 | static int read_acpi_int(acpi_handle handle, const char *method, int *val) | 231 | static int read_acpi_int(acpi_handle handle, const char *method, int *val) |
205 | { | 232 | { |
206 | acpi_status status; | 233 | acpi_status status; |
207 | ulong result; | 234 | unsigned long long result; |
208 | 235 | ||
209 | status = acpi_evaluate_integer(handle, (char *)method, NULL, &result); | 236 | status = acpi_evaluate_integer(handle, (char *)method, NULL, &result); |
210 | if (ACPI_FAILURE(status)) { | 237 | if (ACPI_FAILURE(status)) { |
@@ -261,6 +288,44 @@ static int update_bl_status(struct backlight_device *bd) | |||
261 | } | 288 | } |
262 | 289 | ||
263 | /* | 290 | /* |
291 | * Rfkill helpers | ||
292 | */ | ||
293 | |||
294 | static int eeepc_wlan_rfkill_set(void *data, enum rfkill_state state) | ||
295 | { | ||
296 | if (state == RFKILL_STATE_SOFT_BLOCKED) | ||
297 | return set_acpi(CM_ASL_WLAN, 0); | ||
298 | else | ||
299 | return set_acpi(CM_ASL_WLAN, 1); | ||
300 | } | ||
301 | |||
302 | static int eeepc_wlan_rfkill_state(void *data, enum rfkill_state *state) | ||
303 | { | ||
304 | if (get_acpi(CM_ASL_WLAN) == 1) | ||
305 | *state = RFKILL_STATE_UNBLOCKED; | ||
306 | else | ||
307 | *state = RFKILL_STATE_SOFT_BLOCKED; | ||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | static int eeepc_bluetooth_rfkill_set(void *data, enum rfkill_state state) | ||
312 | { | ||
313 | if (state == RFKILL_STATE_SOFT_BLOCKED) | ||
314 | return set_acpi(CM_ASL_BLUETOOTH, 0); | ||
315 | else | ||
316 | return set_acpi(CM_ASL_BLUETOOTH, 1); | ||
317 | } | ||
318 | |||
319 | static int eeepc_bluetooth_rfkill_state(void *data, enum rfkill_state *state) | ||
320 | { | ||
321 | if (get_acpi(CM_ASL_BLUETOOTH) == 1) | ||
322 | *state = RFKILL_STATE_UNBLOCKED; | ||
323 | else | ||
324 | *state = RFKILL_STATE_SOFT_BLOCKED; | ||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | /* | ||
264 | * Sys helpers | 329 | * Sys helpers |
265 | */ | 330 | */ |
266 | static int parse_arg(const char *buf, unsigned long count, int *val) | 331 | static int parse_arg(const char *buf, unsigned long count, int *val) |
@@ -311,13 +376,11 @@ static ssize_t show_sys_acpi(int cm, char *buf) | |||
311 | EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA); | 376 | EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA); |
312 | EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER); | 377 | EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER); |
313 | EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH); | 378 | EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH); |
314 | EEEPC_CREATE_DEVICE_ATTR(wlan, CM_ASL_WLAN); | ||
315 | 379 | ||
316 | static struct attribute *platform_attributes[] = { | 380 | static struct attribute *platform_attributes[] = { |
317 | &dev_attr_camera.attr, | 381 | &dev_attr_camera.attr, |
318 | &dev_attr_cardr.attr, | 382 | &dev_attr_cardr.attr, |
319 | &dev_attr_disp.attr, | 383 | &dev_attr_disp.attr, |
320 | &dev_attr_wlan.attr, | ||
321 | NULL | 384 | NULL |
322 | }; | 385 | }; |
323 | 386 | ||
@@ -328,8 +391,64 @@ static struct attribute_group platform_attribute_group = { | |||
328 | /* | 391 | /* |
329 | * Hotkey functions | 392 | * Hotkey functions |
330 | */ | 393 | */ |
394 | static struct key_entry *eepc_get_entry_by_scancode(int code) | ||
395 | { | ||
396 | struct key_entry *key; | ||
397 | |||
398 | for (key = eeepc_keymap; key->type != KE_END; key++) | ||
399 | if (code == key->code) | ||
400 | return key; | ||
401 | |||
402 | return NULL; | ||
403 | } | ||
404 | |||
405 | static struct key_entry *eepc_get_entry_by_keycode(int code) | ||
406 | { | ||
407 | struct key_entry *key; | ||
408 | |||
409 | for (key = eeepc_keymap; key->type != KE_END; key++) | ||
410 | if (code == key->keycode && key->type == KE_KEY) | ||
411 | return key; | ||
412 | |||
413 | return NULL; | ||
414 | } | ||
415 | |||
416 | static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode) | ||
417 | { | ||
418 | struct key_entry *key = eepc_get_entry_by_scancode(scancode); | ||
419 | |||
420 | if (key && key->type == KE_KEY) { | ||
421 | *keycode = key->keycode; | ||
422 | return 0; | ||
423 | } | ||
424 | |||
425 | return -EINVAL; | ||
426 | } | ||
427 | |||
428 | static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode) | ||
429 | { | ||
430 | struct key_entry *key; | ||
431 | int old_keycode; | ||
432 | |||
433 | if (keycode < 0 || keycode > KEY_MAX) | ||
434 | return -EINVAL; | ||
435 | |||
436 | key = eepc_get_entry_by_scancode(scancode); | ||
437 | if (key && key->type == KE_KEY) { | ||
438 | old_keycode = key->keycode; | ||
439 | key->keycode = keycode; | ||
440 | set_bit(keycode, dev->keybit); | ||
441 | if (!eepc_get_entry_by_keycode(old_keycode)) | ||
442 | clear_bit(old_keycode, dev->keybit); | ||
443 | return 0; | ||
444 | } | ||
445 | |||
446 | return -EINVAL; | ||
447 | } | ||
448 | |||
331 | static int eeepc_hotk_check(void) | 449 | static int eeepc_hotk_check(void) |
332 | { | 450 | { |
451 | const struct key_entry *key; | ||
333 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 452 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
334 | int result; | 453 | int result; |
335 | 454 | ||
@@ -356,6 +475,31 @@ static int eeepc_hotk_check(void) | |||
356 | "Get control methods supported: 0x%x\n", | 475 | "Get control methods supported: 0x%x\n", |
357 | ehotk->cm_supported); | 476 | ehotk->cm_supported); |
358 | } | 477 | } |
478 | ehotk->inputdev = input_allocate_device(); | ||
479 | if (!ehotk->inputdev) { | ||
480 | printk(EEEPC_INFO "Unable to allocate input device\n"); | ||
481 | return 0; | ||
482 | } | ||
483 | ehotk->inputdev->name = "Asus EeePC extra buttons"; | ||
484 | ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0"; | ||
485 | ehotk->inputdev->id.bustype = BUS_HOST; | ||
486 | ehotk->inputdev->getkeycode = eeepc_getkeycode; | ||
487 | ehotk->inputdev->setkeycode = eeepc_setkeycode; | ||
488 | |||
489 | for (key = eeepc_keymap; key->type != KE_END; key++) { | ||
490 | switch (key->type) { | ||
491 | case KE_KEY: | ||
492 | set_bit(EV_KEY, ehotk->inputdev->evbit); | ||
493 | set_bit(key->keycode, ehotk->inputdev->keybit); | ||
494 | break; | ||
495 | } | ||
496 | } | ||
497 | result = input_register_device(ehotk->inputdev); | ||
498 | if (result) { | ||
499 | printk(EEEPC_INFO "Unable to register input device\n"); | ||
500 | input_free_device(ehotk->inputdev); | ||
501 | return 0; | ||
502 | } | ||
359 | } else { | 503 | } else { |
360 | printk(EEEPC_ERR "Hotkey device not present, aborting\n"); | 504 | printk(EEEPC_ERR "Hotkey device not present, aborting\n"); |
361 | return -EINVAL; | 505 | return -EINVAL; |
@@ -363,21 +507,6 @@ static int eeepc_hotk_check(void) | |||
363 | return 0; | 507 | return 0; |
364 | } | 508 | } |
365 | 509 | ||
366 | static void notify_wlan(u32 *event) | ||
367 | { | ||
368 | /* if DISABLE_ASL_WLAN is set, the notify code for fn+f2 | ||
369 | will always be 0x10 */ | ||
370 | if (ehotk->cm_supported & (0x1 << CM_ASL_WLAN)) { | ||
371 | const char *method = cm_getv[CM_ASL_WLAN]; | ||
372 | int value; | ||
373 | if (read_acpi_int(ehotk->handle, method, &value)) | ||
374 | printk(EEEPC_WARNING "Error reading %s\n", | ||
375 | method); | ||
376 | else if (value == 1) | ||
377 | *event = 0x11; | ||
378 | } | ||
379 | } | ||
380 | |||
381 | static void notify_brn(void) | 510 | static void notify_brn(void) |
382 | { | 511 | { |
383 | struct backlight_device *bd = eeepc_backlight_device; | 512 | struct backlight_device *bd = eeepc_backlight_device; |
@@ -386,14 +515,28 @@ static void notify_brn(void) | |||
386 | 515 | ||
387 | static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) | 516 | static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) |
388 | { | 517 | { |
518 | static struct key_entry *key; | ||
389 | if (!ehotk) | 519 | if (!ehotk) |
390 | return; | 520 | return; |
391 | if (event == NOTIFY_WLAN_ON && (DISABLE_ASL_WLAN & ehotk->init_flag)) | ||
392 | notify_wlan(&event); | ||
393 | if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) | 521 | if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) |
394 | notify_brn(); | 522 | notify_brn(); |
395 | acpi_bus_generate_proc_event(ehotk->device, event, | 523 | acpi_bus_generate_proc_event(ehotk->device, event, |
396 | ehotk->event_count[event % 128]++); | 524 | ehotk->event_count[event % 128]++); |
525 | if (ehotk->inputdev) { | ||
526 | key = eepc_get_entry_by_scancode(event); | ||
527 | if (key) { | ||
528 | switch (key->type) { | ||
529 | case KE_KEY: | ||
530 | input_report_key(ehotk->inputdev, key->keycode, | ||
531 | 1); | ||
532 | input_sync(ehotk->inputdev); | ||
533 | input_report_key(ehotk->inputdev, key->keycode, | ||
534 | 0); | ||
535 | input_sync(ehotk->inputdev); | ||
536 | break; | ||
537 | } | ||
538 | } | ||
539 | } | ||
397 | } | 540 | } |
398 | 541 | ||
399 | static int eeepc_hotk_add(struct acpi_device *device) | 542 | static int eeepc_hotk_add(struct acpi_device *device) |
@@ -411,7 +554,7 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
411 | ehotk->handle = device->handle; | 554 | ehotk->handle = device->handle; |
412 | strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME); | 555 | strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME); |
413 | strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS); | 556 | strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS); |
414 | acpi_driver_data(device) = ehotk; | 557 | device->driver_data = ehotk; |
415 | ehotk->device = device; | 558 | ehotk->device = device; |
416 | result = eeepc_hotk_check(); | 559 | result = eeepc_hotk_check(); |
417 | if (result) | 560 | if (result) |
@@ -420,6 +563,47 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
420 | eeepc_hotk_notify, ehotk); | 563 | eeepc_hotk_notify, ehotk); |
421 | if (ACPI_FAILURE(status)) | 564 | if (ACPI_FAILURE(status)) |
422 | printk(EEEPC_ERR "Error installing notify handler\n"); | 565 | printk(EEEPC_ERR "Error installing notify handler\n"); |
566 | |||
567 | if (get_acpi(CM_ASL_WLAN) != -1) { | ||
568 | ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev, | ||
569 | RFKILL_TYPE_WLAN); | ||
570 | |||
571 | if (!ehotk->eeepc_wlan_rfkill) | ||
572 | goto end; | ||
573 | |||
574 | ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan"; | ||
575 | ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set; | ||
576 | ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state; | ||
577 | if (get_acpi(CM_ASL_WLAN) == 1) | ||
578 | ehotk->eeepc_wlan_rfkill->state = | ||
579 | RFKILL_STATE_UNBLOCKED; | ||
580 | else | ||
581 | ehotk->eeepc_wlan_rfkill->state = | ||
582 | RFKILL_STATE_SOFT_BLOCKED; | ||
583 | rfkill_register(ehotk->eeepc_wlan_rfkill); | ||
584 | } | ||
585 | |||
586 | if (get_acpi(CM_ASL_BLUETOOTH) != -1) { | ||
587 | ehotk->eeepc_bluetooth_rfkill = | ||
588 | rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH); | ||
589 | |||
590 | if (!ehotk->eeepc_bluetooth_rfkill) | ||
591 | goto end; | ||
592 | |||
593 | ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth"; | ||
594 | ehotk->eeepc_bluetooth_rfkill->toggle_radio = | ||
595 | eeepc_bluetooth_rfkill_set; | ||
596 | ehotk->eeepc_bluetooth_rfkill->get_state = | ||
597 | eeepc_bluetooth_rfkill_state; | ||
598 | if (get_acpi(CM_ASL_BLUETOOTH) == 1) | ||
599 | ehotk->eeepc_bluetooth_rfkill->state = | ||
600 | RFKILL_STATE_UNBLOCKED; | ||
601 | else | ||
602 | ehotk->eeepc_bluetooth_rfkill->state = | ||
603 | RFKILL_STATE_SOFT_BLOCKED; | ||
604 | rfkill_register(ehotk->eeepc_bluetooth_rfkill); | ||
605 | } | ||
606 | |||
423 | end: | 607 | end: |
424 | if (result) { | 608 | if (result) { |
425 | kfree(ehotk); | 609 | kfree(ehotk); |
@@ -553,6 +737,12 @@ static void eeepc_backlight_exit(void) | |||
553 | { | 737 | { |
554 | if (eeepc_backlight_device) | 738 | if (eeepc_backlight_device) |
555 | backlight_device_unregister(eeepc_backlight_device); | 739 | backlight_device_unregister(eeepc_backlight_device); |
740 | if (ehotk->inputdev) | ||
741 | input_unregister_device(ehotk->inputdev); | ||
742 | if (ehotk->eeepc_wlan_rfkill) | ||
743 | rfkill_unregister(ehotk->eeepc_wlan_rfkill); | ||
744 | if (ehotk->eeepc_bluetooth_rfkill) | ||
745 | rfkill_unregister(ehotk->eeepc_bluetooth_rfkill); | ||
556 | eeepc_backlight_device = NULL; | 746 | eeepc_backlight_device = NULL; |
557 | } | 747 | } |
558 | 748 | ||
diff --git a/drivers/misc/fujitsu-laptop.c b/drivers/misc/fujitsu-laptop.c index 3e56203e4947..d2cf0bfe3163 100644 --- a/drivers/misc/fujitsu-laptop.c +++ b/drivers/misc/fujitsu-laptop.c | |||
@@ -44,8 +44,9 @@ | |||
44 | * Hotkeys present on certain Fujitsu laptops (eg: the S6xxx series) are | 44 | * Hotkeys present on certain Fujitsu laptops (eg: the S6xxx series) are |
45 | * also supported by this driver. | 45 | * also supported by this driver. |
46 | * | 46 | * |
47 | * This driver has been tested on a Fujitsu Lifebook S6410 and S7020. It | 47 | * This driver has been tested on a Fujitsu Lifebook S6410, S7020 and |
48 | * should work on most P-series and S-series Lifebooks, but YMMV. | 48 | * P8010. It should work on most P-series and S-series Lifebooks, but |
49 | * YMMV. | ||
49 | * | 50 | * |
50 | * The module parameter use_alt_lcd_levels switches between different ACPI | 51 | * The module parameter use_alt_lcd_levels switches between different ACPI |
51 | * brightness controls which are used by different Fujitsu laptops. In most | 52 | * brightness controls which are used by different Fujitsu laptops. In most |
@@ -65,7 +66,7 @@ | |||
65 | #include <linux/video_output.h> | 66 | #include <linux/video_output.h> |
66 | #include <linux/platform_device.h> | 67 | #include <linux/platform_device.h> |
67 | 68 | ||
68 | #define FUJITSU_DRIVER_VERSION "0.4.2" | 69 | #define FUJITSU_DRIVER_VERSION "0.4.3" |
69 | 70 | ||
70 | #define FUJITSU_LCD_N_LEVELS 8 | 71 | #define FUJITSU_LCD_N_LEVELS 8 |
71 | 72 | ||
@@ -83,10 +84,10 @@ | |||
83 | #define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87 | 84 | #define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87 |
84 | 85 | ||
85 | /* Hotkey details */ | 86 | /* Hotkey details */ |
86 | #define LOCK_KEY 0x410 /* codes for the keys in the GIRB register */ | 87 | #define KEY1_CODE 0x410 /* codes for the keys in the GIRB register */ |
87 | #define DISPLAY_KEY 0x411 /* keys are mapped to KEY_SCREENLOCK (the key with the key symbol) */ | 88 | #define KEY2_CODE 0x411 |
88 | #define ENERGY_KEY 0x412 /* KEY_MEDIA (the key with the laptop symbol, KEY_EMAIL (E key)) */ | 89 | #define KEY3_CODE 0x412 |
89 | #define REST_KEY 0x413 /* KEY_SUSPEND (R key) */ | 90 | #define KEY4_CODE 0x413 |
90 | 91 | ||
91 | #define MAX_HOTKEY_RINGBUFFER_SIZE 100 | 92 | #define MAX_HOTKEY_RINGBUFFER_SIZE 100 |
92 | #define RINGBUFFERSIZE 40 | 93 | #define RINGBUFFERSIZE 40 |
@@ -123,6 +124,7 @@ struct fujitsu_t { | |||
123 | char phys[32]; | 124 | char phys[32]; |
124 | struct backlight_device *bl_device; | 125 | struct backlight_device *bl_device; |
125 | struct platform_device *pf_device; | 126 | struct platform_device *pf_device; |
127 | int keycode1, keycode2, keycode3, keycode4; | ||
126 | 128 | ||
127 | unsigned int max_brightness; | 129 | unsigned int max_brightness; |
128 | unsigned int brightness_changed; | 130 | unsigned int brightness_changed; |
@@ -224,7 +226,7 @@ static int set_lcd_level_alt(int level) | |||
224 | 226 | ||
225 | static int get_lcd_level(void) | 227 | static int get_lcd_level(void) |
226 | { | 228 | { |
227 | unsigned long state = 0; | 229 | unsigned long long state = 0; |
228 | acpi_status status = AE_OK; | 230 | acpi_status status = AE_OK; |
229 | 231 | ||
230 | vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLL\n"); | 232 | vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLL\n"); |
@@ -246,7 +248,7 @@ static int get_lcd_level(void) | |||
246 | 248 | ||
247 | static int get_max_brightness(void) | 249 | static int get_max_brightness(void) |
248 | { | 250 | { |
249 | unsigned long state = 0; | 251 | unsigned long long state = 0; |
250 | acpi_status status = AE_OK; | 252 | acpi_status status = AE_OK; |
251 | 253 | ||
252 | vdbg_printk(FUJLAPTOP_DBG_TRACE, "get max lcd level via RBLL\n"); | 254 | vdbg_printk(FUJLAPTOP_DBG_TRACE, "get max lcd level via RBLL\n"); |
@@ -263,7 +265,7 @@ static int get_max_brightness(void) | |||
263 | 265 | ||
264 | static int get_lcd_level_alt(void) | 266 | static int get_lcd_level_alt(void) |
265 | { | 267 | { |
266 | unsigned long state = 0; | 268 | unsigned long long state = 0; |
267 | acpi_status status = AE_OK; | 269 | acpi_status status = AE_OK; |
268 | 270 | ||
269 | vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLS\n"); | 271 | vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLS\n"); |
@@ -384,7 +386,7 @@ static ssize_t store_lcd_level(struct device *dev, | |||
384 | 386 | ||
385 | static int get_irb(void) | 387 | static int get_irb(void) |
386 | { | 388 | { |
387 | unsigned long state = 0; | 389 | unsigned long long state = 0; |
388 | acpi_status status = AE_OK; | 390 | acpi_status status = AE_OK; |
389 | 391 | ||
390 | vdbg_printk(FUJLAPTOP_DBG_TRACE, "Get irb\n"); | 392 | vdbg_printk(FUJLAPTOP_DBG_TRACE, "Get irb\n"); |
@@ -430,7 +432,7 @@ static struct platform_driver fujitsupf_driver = { | |||
430 | } | 432 | } |
431 | }; | 433 | }; |
432 | 434 | ||
433 | static int dmi_check_cb_s6410(const struct dmi_system_id *id) | 435 | static void dmi_check_cb_common(const struct dmi_system_id *id) |
434 | { | 436 | { |
435 | acpi_handle handle; | 437 | acpi_handle handle; |
436 | int have_blnf; | 438 | int have_blnf; |
@@ -452,24 +454,40 @@ static int dmi_check_cb_s6410(const struct dmi_system_id *id) | |||
452 | "auto-detecting disable_adjust\n"); | 454 | "auto-detecting disable_adjust\n"); |
453 | disable_brightness_adjust = have_blnf ? 0 : 1; | 455 | disable_brightness_adjust = have_blnf ? 0 : 1; |
454 | } | 456 | } |
457 | } | ||
458 | |||
459 | static int dmi_check_cb_s6410(const struct dmi_system_id *id) | ||
460 | { | ||
461 | dmi_check_cb_common(id); | ||
462 | fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */ | ||
463 | fujitsu->keycode2 = KEY_HELP; /* "Mobility Center" */ | ||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | static int dmi_check_cb_p8010(const struct dmi_system_id *id) | ||
468 | { | ||
469 | dmi_check_cb_common(id); | ||
470 | fujitsu->keycode1 = KEY_HELP; /* "Support" */ | ||
471 | fujitsu->keycode3 = KEY_SWITCHVIDEOMODE; /* "Presentation" */ | ||
472 | fujitsu->keycode4 = KEY_WWW; /* "Internet" */ | ||
455 | return 0; | 473 | return 0; |
456 | } | 474 | } |
457 | 475 | ||
458 | static struct dmi_system_id __initdata fujitsu_dmi_table[] = { | 476 | static struct dmi_system_id __initdata fujitsu_dmi_table[] = { |
459 | { | 477 | { |
460 | .ident = "Fujitsu Siemens", | 478 | .ident = "Fujitsu Siemens S6410", |
461 | .matches = { | 479 | .matches = { |
462 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 480 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
463 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6410"), | 481 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6410"), |
464 | }, | 482 | }, |
465 | .callback = dmi_check_cb_s6410}, | 483 | .callback = dmi_check_cb_s6410}, |
466 | { | 484 | { |
467 | .ident = "FUJITSU LifeBook P8010", | 485 | .ident = "Fujitsu LifeBook P8010", |
468 | .matches = { | 486 | .matches = { |
469 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 487 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
470 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P8010"), | 488 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P8010"), |
471 | }, | 489 | }, |
472 | .callback = dmi_check_cb_s6410}, | 490 | .callback = dmi_check_cb_p8010}, |
473 | {} | 491 | {} |
474 | }; | 492 | }; |
475 | 493 | ||
@@ -490,7 +508,7 @@ static int acpi_fujitsu_add(struct acpi_device *device) | |||
490 | fujitsu->acpi_handle = device->handle; | 508 | fujitsu->acpi_handle = device->handle; |
491 | sprintf(acpi_device_name(device), "%s", ACPI_FUJITSU_DEVICE_NAME); | 509 | sprintf(acpi_device_name(device), "%s", ACPI_FUJITSU_DEVICE_NAME); |
492 | sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS); | 510 | sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS); |
493 | acpi_driver_data(device) = fujitsu; | 511 | device->driver_data = fujitsu; |
494 | 512 | ||
495 | status = acpi_install_notify_handler(device->handle, | 513 | status = acpi_install_notify_handler(device->handle, |
496 | ACPI_DEVICE_NOTIFY, | 514 | ACPI_DEVICE_NOTIFY, |
@@ -547,7 +565,6 @@ static int acpi_fujitsu_add(struct acpi_device *device) | |||
547 | } | 565 | } |
548 | 566 | ||
549 | /* do config (detect defaults) */ | 567 | /* do config (detect defaults) */ |
550 | dmi_check_system(fujitsu_dmi_table); | ||
551 | use_alt_lcd_levels = use_alt_lcd_levels == 1 ? 1 : 0; | 568 | use_alt_lcd_levels = use_alt_lcd_levels == 1 ? 1 : 0; |
552 | disable_brightness_keys = disable_brightness_keys == 1 ? 1 : 0; | 569 | disable_brightness_keys = disable_brightness_keys == 1 ? 1 : 0; |
553 | disable_brightness_adjust = disable_brightness_adjust == 1 ? 1 : 0; | 570 | disable_brightness_adjust = disable_brightness_adjust == 1 ? 1 : 0; |
@@ -623,17 +640,17 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data) | |||
623 | keycode = 0; | 640 | keycode = 0; |
624 | if (disable_brightness_keys != 1) { | 641 | if (disable_brightness_keys != 1) { |
625 | if (oldb == 0) { | 642 | if (oldb == 0) { |
626 | acpi_bus_generate_proc_event(fujitsu-> | 643 | acpi_bus_generate_proc_event |
627 | dev, | 644 | (fujitsu->dev, |
628 | ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS, | 645 | ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS, |
629 | 0); | 646 | 0); |
630 | keycode = KEY_BRIGHTNESSDOWN; | 647 | keycode = KEY_BRIGHTNESSDOWN; |
631 | } else if (oldb == | 648 | } else if (oldb == |
632 | (fujitsu->max_brightness) - 1) { | 649 | (fujitsu->max_brightness) - 1) { |
633 | acpi_bus_generate_proc_event(fujitsu-> | 650 | acpi_bus_generate_proc_event |
634 | dev, | 651 | (fujitsu->dev, |
635 | ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS, | 652 | ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS, |
636 | 0); | 653 | 0); |
637 | keycode = KEY_BRIGHTNESSUP; | 654 | keycode = KEY_BRIGHTNESSUP; |
638 | } | 655 | } |
639 | } | 656 | } |
@@ -646,8 +663,7 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data) | |||
646 | } | 663 | } |
647 | if (disable_brightness_keys != 1) { | 664 | if (disable_brightness_keys != 1) { |
648 | acpi_bus_generate_proc_event(fujitsu->dev, | 665 | acpi_bus_generate_proc_event(fujitsu->dev, |
649 | ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS, | 666 | ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS, 0); |
650 | 0); | ||
651 | keycode = KEY_BRIGHTNESSUP; | 667 | keycode = KEY_BRIGHTNESSUP; |
652 | } | 668 | } |
653 | } else if (oldb > newb) { | 669 | } else if (oldb > newb) { |
@@ -659,8 +675,7 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data) | |||
659 | } | 675 | } |
660 | if (disable_brightness_keys != 1) { | 676 | if (disable_brightness_keys != 1) { |
661 | acpi_bus_generate_proc_event(fujitsu->dev, | 677 | acpi_bus_generate_proc_event(fujitsu->dev, |
662 | ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS, | 678 | ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS, 0); |
663 | 0); | ||
664 | keycode = KEY_BRIGHTNESSDOWN; | 679 | keycode = KEY_BRIGHTNESSDOWN; |
665 | } | 680 | } |
666 | } else { | 681 | } else { |
@@ -703,7 +718,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
703 | sprintf(acpi_device_name(device), "%s", | 718 | sprintf(acpi_device_name(device), "%s", |
704 | ACPI_FUJITSU_HOTKEY_DEVICE_NAME); | 719 | ACPI_FUJITSU_HOTKEY_DEVICE_NAME); |
705 | sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS); | 720 | sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS); |
706 | acpi_driver_data(device) = fujitsu_hotkey; | 721 | device->driver_data = fujitsu_hotkey; |
707 | 722 | ||
708 | status = acpi_install_notify_handler(device->handle, | 723 | status = acpi_install_notify_handler(device->handle, |
709 | ACPI_DEVICE_NOTIFY, | 724 | ACPI_DEVICE_NOTIFY, |
@@ -742,10 +757,10 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
742 | input->id.product = 0x06; | 757 | input->id.product = 0x06; |
743 | input->dev.parent = &device->dev; | 758 | input->dev.parent = &device->dev; |
744 | input->evbit[0] = BIT(EV_KEY); | 759 | input->evbit[0] = BIT(EV_KEY); |
745 | set_bit(KEY_SCREENLOCK, input->keybit); | 760 | set_bit(fujitsu->keycode1, input->keybit); |
746 | set_bit(KEY_MEDIA, input->keybit); | 761 | set_bit(fujitsu->keycode2, input->keybit); |
747 | set_bit(KEY_EMAIL, input->keybit); | 762 | set_bit(fujitsu->keycode3, input->keybit); |
748 | set_bit(KEY_SUSPEND, input->keybit); | 763 | set_bit(fujitsu->keycode4, input->keybit); |
749 | set_bit(KEY_UNKNOWN, input->keybit); | 764 | set_bit(KEY_UNKNOWN, input->keybit); |
750 | 765 | ||
751 | error = input_register_device(input); | 766 | error = input_register_device(input); |
@@ -833,24 +848,24 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event, | |||
833 | irb); | 848 | irb); |
834 | 849 | ||
835 | switch (irb & 0x4ff) { | 850 | switch (irb & 0x4ff) { |
836 | case LOCK_KEY: | 851 | case KEY1_CODE: |
837 | keycode = KEY_SCREENLOCK; | 852 | keycode = fujitsu->keycode1; |
838 | break; | 853 | break; |
839 | case DISPLAY_KEY: | 854 | case KEY2_CODE: |
840 | keycode = KEY_MEDIA; | 855 | keycode = fujitsu->keycode2; |
841 | break; | 856 | break; |
842 | case ENERGY_KEY: | 857 | case KEY3_CODE: |
843 | keycode = KEY_EMAIL; | 858 | keycode = fujitsu->keycode3; |
844 | break; | 859 | break; |
845 | case REST_KEY: | 860 | case KEY4_CODE: |
846 | keycode = KEY_SUSPEND; | 861 | keycode = fujitsu->keycode4; |
847 | break; | 862 | break; |
848 | case 0: | 863 | case 0: |
849 | keycode = 0; | 864 | keycode = 0; |
850 | break; | 865 | break; |
851 | default: | 866 | default: |
852 | vdbg_printk(FUJLAPTOP_DBG_WARN, | 867 | vdbg_printk(FUJLAPTOP_DBG_WARN, |
853 | "Unknown GIRB result [%x]\n", irb); | 868 | "Unknown GIRB result [%x]\n", irb); |
854 | keycode = -1; | 869 | keycode = -1; |
855 | break; | 870 | break; |
856 | } | 871 | } |
@@ -859,12 +874,12 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event, | |||
859 | "Push keycode into ringbuffer [%d]\n", | 874 | "Push keycode into ringbuffer [%d]\n", |
860 | keycode); | 875 | keycode); |
861 | status = kfifo_put(fujitsu_hotkey->fifo, | 876 | status = kfifo_put(fujitsu_hotkey->fifo, |
862 | (unsigned char *)&keycode, | 877 | (unsigned char *)&keycode, |
863 | sizeof(keycode)); | 878 | sizeof(keycode)); |
864 | if (status != sizeof(keycode)) { | 879 | if (status != sizeof(keycode)) { |
865 | vdbg_printk(FUJLAPTOP_DBG_WARN, | 880 | vdbg_printk(FUJLAPTOP_DBG_WARN, |
866 | "Could not push keycode [0x%x]\n", | 881 | "Could not push keycode [0x%x]\n", |
867 | keycode); | 882 | keycode); |
868 | } else { | 883 | } else { |
869 | input_report_key(input, keycode, 1); | 884 | input_report_key(input, keycode, 1); |
870 | input_sync(input); | 885 | input_sync(input); |
@@ -879,8 +894,8 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event, | |||
879 | input_report_key(input, keycode_r, 0); | 894 | input_report_key(input, keycode_r, 0); |
880 | input_sync(input); | 895 | input_sync(input); |
881 | vdbg_printk(FUJLAPTOP_DBG_TRACE, | 896 | vdbg_printk(FUJLAPTOP_DBG_TRACE, |
882 | "Pop keycode from ringbuffer [%d]\n", | 897 | "Pop keycode from ringbuffer [%d]\n", |
883 | keycode_r); | 898 | keycode_r); |
884 | } | 899 | } |
885 | } | 900 | } |
886 | } | 901 | } |
@@ -943,6 +958,11 @@ static int __init fujitsu_init(void) | |||
943 | if (!fujitsu) | 958 | if (!fujitsu) |
944 | return -ENOMEM; | 959 | return -ENOMEM; |
945 | memset(fujitsu, 0, sizeof(struct fujitsu_t)); | 960 | memset(fujitsu, 0, sizeof(struct fujitsu_t)); |
961 | fujitsu->keycode1 = KEY_PROG1; | ||
962 | fujitsu->keycode2 = KEY_PROG2; | ||
963 | fujitsu->keycode3 = KEY_PROG3; | ||
964 | fujitsu->keycode4 = KEY_PROG4; | ||
965 | dmi_check_system(fujitsu_dmi_table); | ||
946 | 966 | ||
947 | result = acpi_bus_register_driver(&acpi_fujitsu_driver); | 967 | result = acpi_bus_register_driver(&acpi_fujitsu_driver); |
948 | if (result < 0) { | 968 | if (result < 0) { |
@@ -1076,15 +1096,14 @@ MODULE_DESCRIPTION("Fujitsu laptop extras support"); | |||
1076 | MODULE_VERSION(FUJITSU_DRIVER_VERSION); | 1096 | MODULE_VERSION(FUJITSU_DRIVER_VERSION); |
1077 | MODULE_LICENSE("GPL"); | 1097 | MODULE_LICENSE("GPL"); |
1078 | 1098 | ||
1079 | MODULE_ALIAS | 1099 | MODULE_ALIAS("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1D3:*:cvrS6410:*"); |
1080 | ("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1D3:*:cvrS6410:*"); | 1100 | MODULE_ALIAS("dmi:*:svnFUJITSU:*:pvr:rvnFUJITSU:rnFJNB19C:*:cvrS7020:*"); |
1081 | MODULE_ALIAS | ||
1082 | ("dmi:*:svnFUJITSU:*:pvr:rvnFUJITSU:rnFJNB19C:*:cvrS7020:*"); | ||
1083 | 1101 | ||
1084 | static struct pnp_device_id pnp_ids[] = { | 1102 | static struct pnp_device_id pnp_ids[] = { |
1085 | { .id = "FUJ02bf" }, | 1103 | {.id = "FUJ02bf"}, |
1086 | { .id = "FUJ02B1" }, | 1104 | {.id = "FUJ02B1"}, |
1087 | { .id = "FUJ02E3" }, | 1105 | {.id = "FUJ02E3"}, |
1088 | { .id = "" } | 1106 | {.id = ""} |
1089 | }; | 1107 | }; |
1108 | |||
1090 | MODULE_DEVICE_TABLE(pnp, pnp_ids); | 1109 | MODULE_DEVICE_TABLE(pnp, pnp_ids); |
diff --git a/drivers/misc/intel_menlow.c b/drivers/misc/intel_menlow.c index 80a136352408..e00a2756e97e 100644 --- a/drivers/misc/intel_menlow.c +++ b/drivers/misc/intel_menlow.c | |||
@@ -57,7 +57,7 @@ static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev, | |||
57 | { | 57 | { |
58 | struct acpi_device *device = cdev->devdata; | 58 | struct acpi_device *device = cdev->devdata; |
59 | acpi_handle handle = device->handle; | 59 | acpi_handle handle = device->handle; |
60 | unsigned long value; | 60 | unsigned long long value; |
61 | struct acpi_object_list arg_list; | 61 | struct acpi_object_list arg_list; |
62 | union acpi_object arg; | 62 | union acpi_object arg; |
63 | acpi_status status = AE_OK; | 63 | acpi_status status = AE_OK; |
@@ -90,7 +90,7 @@ static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev, | |||
90 | { | 90 | { |
91 | struct acpi_device *device = cdev->devdata; | 91 | struct acpi_device *device = cdev->devdata; |
92 | acpi_handle handle = device->handle; | 92 | acpi_handle handle = device->handle; |
93 | unsigned long value; | 93 | unsigned long long value; |
94 | struct acpi_object_list arg_list; | 94 | struct acpi_object_list arg_list; |
95 | union acpi_object arg; | 95 | union acpi_object arg; |
96 | acpi_status status = AE_OK; | 96 | acpi_status status = AE_OK; |
@@ -104,7 +104,7 @@ static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev, | |||
104 | if (ACPI_FAILURE(status)) | 104 | if (ACPI_FAILURE(status)) |
105 | return -EFAULT; | 105 | return -EFAULT; |
106 | 106 | ||
107 | return sprintf(buf, "%ld\n", value); | 107 | return sprintf(buf, "%llu\n", value); |
108 | } | 108 | } |
109 | 109 | ||
110 | static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev, | 110 | static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev, |
@@ -115,7 +115,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev, | |||
115 | struct acpi_object_list arg_list; | 115 | struct acpi_object_list arg_list; |
116 | union acpi_object arg; | 116 | union acpi_object arg; |
117 | acpi_status status; | 117 | acpi_status status; |
118 | int temp; | 118 | unsigned long long temp; |
119 | unsigned long max_state; | 119 | unsigned long max_state; |
120 | 120 | ||
121 | if (memory_get_int_max_bandwidth(cdev, &max_state)) | 121 | if (memory_get_int_max_bandwidth(cdev, &max_state)) |
@@ -131,7 +131,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev, | |||
131 | 131 | ||
132 | status = | 132 | status = |
133 | acpi_evaluate_integer(handle, MEMORY_SET_BANDWIDTH, &arg_list, | 133 | acpi_evaluate_integer(handle, MEMORY_SET_BANDWIDTH, &arg_list, |
134 | (unsigned long *)&temp); | 134 | &temp); |
135 | 135 | ||
136 | printk(KERN_INFO | 136 | printk(KERN_INFO |
137 | "Bandwidth value was %d: status is %d\n", state, status); | 137 | "Bandwidth value was %d: status is %d\n", state, status); |
@@ -175,7 +175,7 @@ static int intel_menlow_memory_add(struct acpi_device *device) | |||
175 | goto end; | 175 | goto end; |
176 | } | 176 | } |
177 | 177 | ||
178 | acpi_driver_data(device) = cdev; | 178 | device->driver_data = cdev; |
179 | result = sysfs_create_link(&device->dev.kobj, | 179 | result = sysfs_create_link(&device->dev.kobj, |
180 | &cdev->device.kobj, "thermal_cooling"); | 180 | &cdev->device.kobj, "thermal_cooling"); |
181 | if (result) | 181 | if (result) |
@@ -252,7 +252,8 @@ static DEFINE_MUTEX(intel_menlow_attr_lock); | |||
252 | * @auxtype : AUX0/AUX1 | 252 | * @auxtype : AUX0/AUX1 |
253 | * @buf: syfs buffer | 253 | * @buf: syfs buffer |
254 | */ | 254 | */ |
255 | static int sensor_get_auxtrip(acpi_handle handle, int index, int *value) | 255 | static int sensor_get_auxtrip(acpi_handle handle, int index, |
256 | unsigned long long *value) | ||
256 | { | 257 | { |
257 | acpi_status status; | 258 | acpi_status status; |
258 | 259 | ||
@@ -260,7 +261,7 @@ static int sensor_get_auxtrip(acpi_handle handle, int index, int *value) | |||
260 | return -EINVAL; | 261 | return -EINVAL; |
261 | 262 | ||
262 | status = acpi_evaluate_integer(handle, index ? GET_AUX1 : GET_AUX0, | 263 | status = acpi_evaluate_integer(handle, index ? GET_AUX1 : GET_AUX0, |
263 | NULL, (unsigned long *)value); | 264 | NULL, value); |
264 | if (ACPI_FAILURE(status)) | 265 | if (ACPI_FAILURE(status)) |
265 | return -EIO; | 266 | return -EIO; |
266 | 267 | ||
@@ -282,13 +283,13 @@ static int sensor_set_auxtrip(acpi_handle handle, int index, int value) | |||
282 | struct acpi_object_list args = { | 283 | struct acpi_object_list args = { |
283 | 1, &arg | 284 | 1, &arg |
284 | }; | 285 | }; |
285 | int temp; | 286 | unsigned long long temp; |
286 | 287 | ||
287 | if (index != 0 && index != 1) | 288 | if (index != 0 && index != 1) |
288 | return -EINVAL; | 289 | return -EINVAL; |
289 | 290 | ||
290 | status = acpi_evaluate_integer(handle, index ? GET_AUX0 : GET_AUX1, | 291 | status = acpi_evaluate_integer(handle, index ? GET_AUX0 : GET_AUX1, |
291 | NULL, (unsigned long *)&temp); | 292 | NULL, &temp); |
292 | if (ACPI_FAILURE(status)) | 293 | if (ACPI_FAILURE(status)) |
293 | return -EIO; | 294 | return -EIO; |
294 | if ((index && value < temp) || (!index && value > temp)) | 295 | if ((index && value < temp) || (!index && value > temp)) |
@@ -296,7 +297,7 @@ static int sensor_set_auxtrip(acpi_handle handle, int index, int value) | |||
296 | 297 | ||
297 | arg.integer.value = value; | 298 | arg.integer.value = value; |
298 | status = acpi_evaluate_integer(handle, index ? SET_AUX1 : SET_AUX0, | 299 | status = acpi_evaluate_integer(handle, index ? SET_AUX1 : SET_AUX0, |
299 | &args, (unsigned long *)&temp); | 300 | &args, &temp); |
300 | if (ACPI_FAILURE(status)) | 301 | if (ACPI_FAILURE(status)) |
301 | return -EIO; | 302 | return -EIO; |
302 | 303 | ||
@@ -312,7 +313,7 @@ static ssize_t aux0_show(struct device *dev, | |||
312 | struct device_attribute *dev_attr, char *buf) | 313 | struct device_attribute *dev_attr, char *buf) |
313 | { | 314 | { |
314 | struct intel_menlow_attribute *attr = to_intel_menlow_attr(dev_attr); | 315 | struct intel_menlow_attribute *attr = to_intel_menlow_attr(dev_attr); |
315 | int value; | 316 | unsigned long long value; |
316 | int result; | 317 | int result; |
317 | 318 | ||
318 | result = sensor_get_auxtrip(attr->handle, 0, &value); | 319 | result = sensor_get_auxtrip(attr->handle, 0, &value); |
@@ -324,7 +325,7 @@ static ssize_t aux1_show(struct device *dev, | |||
324 | struct device_attribute *dev_attr, char *buf) | 325 | struct device_attribute *dev_attr, char *buf) |
325 | { | 326 | { |
326 | struct intel_menlow_attribute *attr = to_intel_menlow_attr(dev_attr); | 327 | struct intel_menlow_attribute *attr = to_intel_menlow_attr(dev_attr); |
327 | int value; | 328 | unsigned long long value; |
328 | int result; | 329 | int result; |
329 | 330 | ||
330 | result = sensor_get_auxtrip(attr->handle, 1, &value); | 331 | result = sensor_get_auxtrip(attr->handle, 1, &value); |
@@ -376,7 +377,7 @@ static ssize_t bios_enabled_show(struct device *dev, | |||
376 | struct device_attribute *attr, char *buf) | 377 | struct device_attribute *attr, char *buf) |
377 | { | 378 | { |
378 | acpi_status status; | 379 | acpi_status status; |
379 | unsigned long bios_enabled; | 380 | unsigned long long bios_enabled; |
380 | 381 | ||
381 | status = acpi_evaluate_integer(NULL, BIOS_ENABLED, NULL, &bios_enabled); | 382 | status = acpi_evaluate_integer(NULL, BIOS_ENABLED, NULL, &bios_enabled); |
382 | if (ACPI_FAILURE(status)) | 383 | if (ACPI_FAILURE(status)) |
@@ -492,7 +493,7 @@ static int __init intel_menlow_module_init(void) | |||
492 | { | 493 | { |
493 | int result = -ENODEV; | 494 | int result = -ENODEV; |
494 | acpi_status status; | 495 | acpi_status status; |
495 | unsigned long enable; | 496 | unsigned long long enable; |
496 | 497 | ||
497 | if (acpi_disabled) | 498 | if (acpi_disabled) |
498 | return result; | 499 | return result; |
diff --git a/drivers/misc/panasonic-laptop.c b/drivers/misc/panasonic-laptop.c new file mode 100644 index 000000000000..a2cb598d8ab5 --- /dev/null +++ b/drivers/misc/panasonic-laptop.c | |||
@@ -0,0 +1,767 @@ | |||
1 | /* | ||
2 | * Panasonic HotKey and LCD brightness control driver | ||
3 | * (C) 2004 Hiroshi Miura <miura@da-cha.org> | ||
4 | * (C) 2004 NTT DATA Intellilink Co. http://www.intellilink.co.jp/ | ||
5 | * (C) YOKOTA Hiroshi <yokota (at) netlab. is. tsukuba. ac. jp> | ||
6 | * (C) 2004 David Bronaugh <dbronaugh> | ||
7 | * (C) 2006-2008 Harald Welte <laforge@gnumonks.org> | ||
8 | * | ||
9 | * derived from toshiba_acpi.c, Copyright (C) 2002-2004 John Belmonte | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * publicshed by the Free Software Foundation. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | * | ||
24 | *--------------------------------------------------------------------------- | ||
25 | * | ||
26 | * ChangeLog: | ||
27 | * Sep.23, 2008 Harald Welte <laforge@gnumonks.org> | ||
28 | * -v0.95 rename driver from drivers/acpi/pcc_acpi.c to | ||
29 | * drivers/misc/panasonic-laptop.c | ||
30 | * | ||
31 | * Jul.04, 2008 Harald Welte <laforge@gnumonks.org> | ||
32 | * -v0.94 replace /proc interface with device attributes | ||
33 | * support {set,get}keycode on th input device | ||
34 | * | ||
35 | * Jun.27, 2008 Harald Welte <laforge@gnumonks.org> | ||
36 | * -v0.92 merge with 2.6.26-rc6 input API changes | ||
37 | * remove broken <= 2.6.15 kernel support | ||
38 | * resolve all compiler warnings | ||
39 | * various coding style fixes (checkpatch.pl) | ||
40 | * add support for backlight api | ||
41 | * major code restructuring | ||
42 | * | ||
43 | * Dac.28, 2007 Harald Welte <laforge@gnumonks.org> | ||
44 | * -v0.91 merge with 2.6.24-rc6 ACPI changes | ||
45 | * | ||
46 | * Nov.04, 2006 Hiroshi Miura <miura@da-cha.org> | ||
47 | * -v0.9 remove warning about section reference. | ||
48 | * remove acpi_os_free | ||
49 | * add /proc/acpi/pcc/brightness interface for HAL access | ||
50 | * merge dbronaugh's enhancement | ||
51 | * Aug.17, 2004 David Bronaugh (dbronaugh) | ||
52 | * - Added screen brightness setting interface | ||
53 | * Thanks to FreeBSD crew (acpi_panasonic.c) | ||
54 | * for the ideas I needed to accomplish it | ||
55 | * | ||
56 | * May.29, 2006 Hiroshi Miura <miura@da-cha.org> | ||
57 | * -v0.8.4 follow to change keyinput structure | ||
58 | * thanks Fabian Yamaguchi <fabs@cs.tu-berlin.de>, | ||
59 | * Jacob Bower <jacob.bower@ic.ac.uk> and | ||
60 | * Hiroshi Yokota for providing solutions. | ||
61 | * | ||
62 | * Oct.02, 2004 Hiroshi Miura <miura@da-cha.org> | ||
63 | * -v0.8.2 merge code of YOKOTA Hiroshi | ||
64 | * <yokota@netlab.is.tsukuba.ac.jp>. | ||
65 | * Add sticky key mode interface. | ||
66 | * Refactoring acpi_pcc_generate_keyinput(). | ||
67 | * | ||
68 | * Sep.15, 2004 Hiroshi Miura <miura@da-cha.org> | ||
69 | * -v0.8 Generate key input event on input subsystem. | ||
70 | * This is based on yet another driver written by | ||
71 | * Ryuta Nakanishi. | ||
72 | * | ||
73 | * Sep.10, 2004 Hiroshi Miura <miura@da-cha.org> | ||
74 | * -v0.7 Change proc interface functions using seq_file | ||
75 | * facility as same as other ACPI drivers. | ||
76 | * | ||
77 | * Aug.28, 2004 Hiroshi Miura <miura@da-cha.org> | ||
78 | * -v0.6.4 Fix a silly error with status checking | ||
79 | * | ||
80 | * Aug.25, 2004 Hiroshi Miura <miura@da-cha.org> | ||
81 | * -v0.6.3 replace read_acpi_int by standard function | ||
82 | * acpi_evaluate_integer | ||
83 | * some clean up and make smart copyright notice. | ||
84 | * fix return value of pcc_acpi_get_key() | ||
85 | * fix checking return value of acpi_bus_register_driver() | ||
86 | * | ||
87 | * Aug.22, 2004 David Bronaugh <dbronaugh@linuxboxen.org> | ||
88 | * -v0.6.2 Add check on ACPI data (num_sifr) | ||
89 | * Coding style cleanups, better error messages/handling | ||
90 | * Fixed an off-by-one error in memory allocation | ||
91 | * | ||
92 | * Aug.21, 2004 David Bronaugh <dbronaugh@linuxboxen.org> | ||
93 | * -v0.6.1 Fix a silly error with status checking | ||
94 | * | ||
95 | * Aug.20, 2004 David Bronaugh <dbronaugh@linuxboxen.org> | ||
96 | * - v0.6 Correct brightness controls to reflect reality | ||
97 | * based on information gleaned by Hiroshi Miura | ||
98 | * and discussions with Hiroshi Miura | ||
99 | * | ||
100 | * Aug.10, 2004 Hiroshi Miura <miura@da-cha.org> | ||
101 | * - v0.5 support LCD brightness control | ||
102 | * based on the disclosed information by MEI. | ||
103 | * | ||
104 | * Jul.25, 2004 Hiroshi Miura <miura@da-cha.org> | ||
105 | * - v0.4 first post version | ||
106 | * add function to retrive SIFR | ||
107 | * | ||
108 | * Jul.24, 2004 Hiroshi Miura <miura@da-cha.org> | ||
109 | * - v0.3 get proper status of hotkey | ||
110 | * | ||
111 | * Jul.22, 2004 Hiroshi Miura <miura@da-cha.org> | ||
112 | * - v0.2 add HotKey handler | ||
113 | * | ||
114 | * Jul.17, 2004 Hiroshi Miura <miura@da-cha.org> | ||
115 | * - v0.1 start from toshiba_acpi driver written by John Belmonte | ||
116 | * | ||
117 | */ | ||
118 | |||
119 | #include <linux/version.h> | ||
120 | #include <linux/kernel.h> | ||
121 | #include <linux/module.h> | ||
122 | #include <linux/init.h> | ||
123 | #include <linux/types.h> | ||
124 | #include <linux/backlight.h> | ||
125 | #include <linux/ctype.h> | ||
126 | #include <linux/seq_file.h> | ||
127 | #include <linux/uaccess.h> | ||
128 | #include <acpi/acpi_bus.h> | ||
129 | #include <acpi/acpi_drivers.h> | ||
130 | #include <linux/input.h> | ||
131 | |||
132 | |||
133 | #ifndef ACPI_HOTKEY_COMPONENT | ||
134 | #define ACPI_HOTKEY_COMPONENT 0x10000000 | ||
135 | #endif | ||
136 | |||
137 | #define _COMPONENT ACPI_HOTKEY_COMPONENT | ||
138 | |||
139 | MODULE_AUTHOR("Hiroshi Miura, David Bronaugh and Harald Welte"); | ||
140 | MODULE_DESCRIPTION("ACPI HotKey driver for Panasonic Let's Note laptops"); | ||
141 | MODULE_LICENSE("GPL"); | ||
142 | |||
143 | #define LOGPREFIX "pcc_acpi: " | ||
144 | |||
145 | /* Define ACPI PATHs */ | ||
146 | /* Lets note hotkeys */ | ||
147 | #define METHOD_HKEY_QUERY "HINF" | ||
148 | #define METHOD_HKEY_SQTY "SQTY" | ||
149 | #define METHOD_HKEY_SINF "SINF" | ||
150 | #define METHOD_HKEY_SSET "SSET" | ||
151 | #define HKEY_NOTIFY 0x80 | ||
152 | |||
153 | #define ACPI_PCC_DRIVER_NAME "Panasonic Laptop Support" | ||
154 | #define ACPI_PCC_DEVICE_NAME "Hotkey" | ||
155 | #define ACPI_PCC_CLASS "pcc" | ||
156 | |||
157 | #define ACPI_PCC_INPUT_PHYS "panasonic/hkey0" | ||
158 | |||
159 | /* LCD_TYPEs: 0 = Normal, 1 = Semi-transparent | ||
160 | ENV_STATEs: Normal temp=0x01, High temp=0x81, N/A=0x00 | ||
161 | */ | ||
162 | enum SINF_BITS { SINF_NUM_BATTERIES = 0, | ||
163 | SINF_LCD_TYPE, | ||
164 | SINF_AC_MAX_BRIGHT, | ||
165 | SINF_AC_MIN_BRIGHT, | ||
166 | SINF_AC_CUR_BRIGHT, | ||
167 | SINF_DC_MAX_BRIGHT, | ||
168 | SINF_DC_MIN_BRIGHT, | ||
169 | SINF_DC_CUR_BRIGHT, | ||
170 | SINF_MUTE, | ||
171 | SINF_RESERVED, | ||
172 | SINF_ENV_STATE, | ||
173 | SINF_STICKY_KEY = 0x80, | ||
174 | }; | ||
175 | /* R1 handles SINF_AC_CUR_BRIGHT as SINF_CUR_BRIGHT, doesn't know AC state */ | ||
176 | |||
177 | static int acpi_pcc_hotkey_add(struct acpi_device *device); | ||
178 | static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type); | ||
179 | static int acpi_pcc_hotkey_resume(struct acpi_device *device); | ||
180 | |||
181 | static const struct acpi_device_id pcc_device_ids[] = { | ||
182 | { "MAT0012", 0}, | ||
183 | { "MAT0013", 0}, | ||
184 | { "MAT0018", 0}, | ||
185 | { "MAT0019", 0}, | ||
186 | { "", 0}, | ||
187 | }; | ||
188 | |||
189 | static struct acpi_driver acpi_pcc_driver = { | ||
190 | .name = ACPI_PCC_DRIVER_NAME, | ||
191 | .class = ACPI_PCC_CLASS, | ||
192 | .ids = pcc_device_ids, | ||
193 | .ops = { | ||
194 | .add = acpi_pcc_hotkey_add, | ||
195 | .remove = acpi_pcc_hotkey_remove, | ||
196 | .resume = acpi_pcc_hotkey_resume, | ||
197 | }, | ||
198 | }; | ||
199 | |||
200 | #define KEYMAP_SIZE 11 | ||
201 | static const int initial_keymap[KEYMAP_SIZE] = { | ||
202 | /* 0 */ KEY_RESERVED, | ||
203 | /* 1 */ KEY_BRIGHTNESSDOWN, | ||
204 | /* 2 */ KEY_BRIGHTNESSUP, | ||
205 | /* 3 */ KEY_DISPLAYTOGGLE, | ||
206 | /* 4 */ KEY_MUTE, | ||
207 | /* 5 */ KEY_VOLUMEDOWN, | ||
208 | /* 6 */ KEY_VOLUMEUP, | ||
209 | /* 7 */ KEY_SLEEP, | ||
210 | /* 8 */ KEY_PROG1, /* Change CPU boost */ | ||
211 | /* 9 */ KEY_BATTERY, | ||
212 | /* 10 */ KEY_SUSPEND, | ||
213 | }; | ||
214 | |||
215 | struct pcc_acpi { | ||
216 | acpi_handle handle; | ||
217 | unsigned long num_sifr; | ||
218 | int sticky_mode; | ||
219 | u32 *sinf; | ||
220 | struct acpi_device *device; | ||
221 | struct input_dev *input_dev; | ||
222 | struct backlight_device *backlight; | ||
223 | int keymap[KEYMAP_SIZE]; | ||
224 | }; | ||
225 | |||
226 | struct pcc_keyinput { | ||
227 | struct acpi_hotkey *hotkey; | ||
228 | }; | ||
229 | |||
230 | /* method access functions */ | ||
231 | static int acpi_pcc_write_sset(struct pcc_acpi *pcc, int func, int val) | ||
232 | { | ||
233 | union acpi_object in_objs[] = { | ||
234 | { .integer.type = ACPI_TYPE_INTEGER, | ||
235 | .integer.value = func, }, | ||
236 | { .integer.type = ACPI_TYPE_INTEGER, | ||
237 | .integer.value = val, }, | ||
238 | }; | ||
239 | struct acpi_object_list params = { | ||
240 | .count = ARRAY_SIZE(in_objs), | ||
241 | .pointer = in_objs, | ||
242 | }; | ||
243 | acpi_status status = AE_OK; | ||
244 | |||
245 | ACPI_FUNCTION_TRACE("acpi_pcc_write_sset"); | ||
246 | |||
247 | status = acpi_evaluate_object(pcc->handle, METHOD_HKEY_SSET, | ||
248 | ¶ms, NULL); | ||
249 | |||
250 | return status == AE_OK; | ||
251 | } | ||
252 | |||
253 | static inline int acpi_pcc_get_sqty(struct acpi_device *device) | ||
254 | { | ||
255 | unsigned long long s; | ||
256 | acpi_status status; | ||
257 | |||
258 | ACPI_FUNCTION_TRACE("acpi_pcc_get_sqty"); | ||
259 | |||
260 | status = acpi_evaluate_integer(device->handle, METHOD_HKEY_SQTY, | ||
261 | NULL, &s); | ||
262 | if (ACPI_SUCCESS(status)) | ||
263 | return s; | ||
264 | else { | ||
265 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
266 | "evaluation error HKEY.SQTY\n")); | ||
267 | return -EINVAL; | ||
268 | } | ||
269 | } | ||
270 | |||
271 | static int acpi_pcc_retrieve_biosdata(struct pcc_acpi *pcc, u32 *sinf) | ||
272 | { | ||
273 | acpi_status status; | ||
274 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
275 | union acpi_object *hkey = NULL; | ||
276 | int i; | ||
277 | |||
278 | ACPI_FUNCTION_TRACE("acpi_pcc_retrieve_biosdata"); | ||
279 | |||
280 | status = acpi_evaluate_object(pcc->handle, METHOD_HKEY_SINF, 0, | ||
281 | &buffer); | ||
282 | if (ACPI_FAILURE(status)) { | ||
283 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
284 | "evaluation error HKEY.SINF\n")); | ||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | hkey = buffer.pointer; | ||
289 | if (!hkey || (hkey->type != ACPI_TYPE_PACKAGE)) { | ||
290 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid HKEY.SINF\n")); | ||
291 | goto end; | ||
292 | } | ||
293 | |||
294 | if (pcc->num_sifr < hkey->package.count) { | ||
295 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
296 | "SQTY reports bad SINF length\n")); | ||
297 | status = AE_ERROR; | ||
298 | goto end; | ||
299 | } | ||
300 | |||
301 | for (i = 0; i < hkey->package.count; i++) { | ||
302 | union acpi_object *element = &(hkey->package.elements[i]); | ||
303 | if (likely(element->type == ACPI_TYPE_INTEGER)) { | ||
304 | sinf[i] = element->integer.value; | ||
305 | } else | ||
306 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
307 | "Invalid HKEY.SINF data\n")); | ||
308 | } | ||
309 | sinf[hkey->package.count] = -1; | ||
310 | |||
311 | end: | ||
312 | kfree(buffer.pointer); | ||
313 | return status == AE_OK; | ||
314 | } | ||
315 | |||
316 | /* backlight API interface functions */ | ||
317 | |||
318 | /* This driver currently treats AC and DC brightness identical, | ||
319 | * since we don't need to invent an interface to the core ACPI | ||
320 | * logic to receive events in case a power supply is plugged in | ||
321 | * or removed */ | ||
322 | |||
323 | static int bl_get(struct backlight_device *bd) | ||
324 | { | ||
325 | struct pcc_acpi *pcc = bl_get_data(bd); | ||
326 | |||
327 | if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) | ||
328 | return -EIO; | ||
329 | |||
330 | return pcc->sinf[SINF_AC_CUR_BRIGHT]; | ||
331 | } | ||
332 | |||
333 | static int bl_set_status(struct backlight_device *bd) | ||
334 | { | ||
335 | struct pcc_acpi *pcc = bl_get_data(bd); | ||
336 | int bright = bd->props.brightness; | ||
337 | int rc; | ||
338 | |||
339 | if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) | ||
340 | return -EIO; | ||
341 | |||
342 | if (bright < pcc->sinf[SINF_AC_MIN_BRIGHT]) | ||
343 | bright = pcc->sinf[SINF_AC_MIN_BRIGHT]; | ||
344 | |||
345 | if (bright < pcc->sinf[SINF_DC_MIN_BRIGHT]) | ||
346 | bright = pcc->sinf[SINF_DC_MIN_BRIGHT]; | ||
347 | |||
348 | if (bright < pcc->sinf[SINF_AC_MIN_BRIGHT] || | ||
349 | bright > pcc->sinf[SINF_AC_MAX_BRIGHT]) | ||
350 | return -EINVAL; | ||
351 | |||
352 | rc = acpi_pcc_write_sset(pcc, SINF_AC_CUR_BRIGHT, bright); | ||
353 | if (rc < 0) | ||
354 | return rc; | ||
355 | |||
356 | return acpi_pcc_write_sset(pcc, SINF_DC_CUR_BRIGHT, bright); | ||
357 | } | ||
358 | |||
359 | static struct backlight_ops pcc_backlight_ops = { | ||
360 | .get_brightness = bl_get, | ||
361 | .update_status = bl_set_status, | ||
362 | }; | ||
363 | |||
364 | |||
365 | /* sysfs user interface functions */ | ||
366 | |||
367 | static ssize_t show_numbatt(struct device *dev, struct device_attribute *attr, | ||
368 | char *buf) | ||
369 | { | ||
370 | struct acpi_device *acpi = to_acpi_device(dev); | ||
371 | struct pcc_acpi *pcc = acpi_driver_data(acpi); | ||
372 | |||
373 | if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) | ||
374 | return -EIO; | ||
375 | |||
376 | return sprintf(buf, "%u\n", pcc->sinf[SINF_NUM_BATTERIES]); | ||
377 | } | ||
378 | |||
379 | static ssize_t show_lcdtype(struct device *dev, struct device_attribute *attr, | ||
380 | char *buf) | ||
381 | { | ||
382 | struct acpi_device *acpi = to_acpi_device(dev); | ||
383 | struct pcc_acpi *pcc = acpi_driver_data(acpi); | ||
384 | |||
385 | if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) | ||
386 | return -EIO; | ||
387 | |||
388 | return sprintf(buf, "%u\n", pcc->sinf[SINF_LCD_TYPE]); | ||
389 | } | ||
390 | |||
391 | static ssize_t show_mute(struct device *dev, struct device_attribute *attr, | ||
392 | char *buf) | ||
393 | { | ||
394 | struct acpi_device *acpi = to_acpi_device(dev); | ||
395 | struct pcc_acpi *pcc = acpi_driver_data(acpi); | ||
396 | |||
397 | if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) | ||
398 | return -EIO; | ||
399 | |||
400 | return sprintf(buf, "%u\n", pcc->sinf[SINF_MUTE]); | ||
401 | } | ||
402 | |||
403 | static ssize_t show_sticky(struct device *dev, struct device_attribute *attr, | ||
404 | char *buf) | ||
405 | { | ||
406 | struct acpi_device *acpi = to_acpi_device(dev); | ||
407 | struct pcc_acpi *pcc = acpi_driver_data(acpi); | ||
408 | |||
409 | if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) | ||
410 | return -EIO; | ||
411 | |||
412 | return sprintf(buf, "%u\n", pcc->sinf[SINF_STICKY_KEY]); | ||
413 | } | ||
414 | |||
415 | static ssize_t set_sticky(struct device *dev, struct device_attribute *attr, | ||
416 | const char *buf, size_t count) | ||
417 | { | ||
418 | struct acpi_device *acpi = to_acpi_device(dev); | ||
419 | struct pcc_acpi *pcc = acpi_driver_data(acpi); | ||
420 | int val; | ||
421 | |||
422 | if (count && sscanf(buf, "%i", &val) == 1 && | ||
423 | (val == 0 || val == 1)) { | ||
424 | acpi_pcc_write_sset(pcc, SINF_STICKY_KEY, val); | ||
425 | pcc->sticky_mode = val; | ||
426 | } | ||
427 | |||
428 | return count; | ||
429 | } | ||
430 | |||
431 | static DEVICE_ATTR(numbatt, S_IRUGO, show_numbatt, NULL); | ||
432 | static DEVICE_ATTR(lcdtype, S_IRUGO, show_lcdtype, NULL); | ||
433 | static DEVICE_ATTR(mute, S_IRUGO, show_mute, NULL); | ||
434 | static DEVICE_ATTR(sticky_key, S_IRUGO | S_IWUSR, show_sticky, set_sticky); | ||
435 | |||
436 | static struct attribute *pcc_sysfs_entries[] = { | ||
437 | &dev_attr_numbatt.attr, | ||
438 | &dev_attr_lcdtype.attr, | ||
439 | &dev_attr_mute.attr, | ||
440 | &dev_attr_sticky_key.attr, | ||
441 | NULL, | ||
442 | }; | ||
443 | |||
444 | static struct attribute_group pcc_attr_group = { | ||
445 | .name = NULL, /* put in device directory */ | ||
446 | .attrs = pcc_sysfs_entries, | ||
447 | }; | ||
448 | |||
449 | |||
450 | /* hotkey input device driver */ | ||
451 | |||
452 | static int pcc_getkeycode(struct input_dev *dev, int scancode, int *keycode) | ||
453 | { | ||
454 | struct pcc_acpi *pcc = input_get_drvdata(dev); | ||
455 | |||
456 | if (scancode >= ARRAY_SIZE(pcc->keymap)) | ||
457 | return -EINVAL; | ||
458 | |||
459 | *keycode = pcc->keymap[scancode]; | ||
460 | |||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | static int keymap_get_by_keycode(struct pcc_acpi *pcc, int keycode) | ||
465 | { | ||
466 | int i; | ||
467 | |||
468 | for (i = 0; i < ARRAY_SIZE(pcc->keymap); i++) { | ||
469 | if (pcc->keymap[i] == keycode) | ||
470 | return i+1; | ||
471 | } | ||
472 | |||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | static int pcc_setkeycode(struct input_dev *dev, int scancode, int keycode) | ||
477 | { | ||
478 | struct pcc_acpi *pcc = input_get_drvdata(dev); | ||
479 | int oldkeycode; | ||
480 | |||
481 | if (scancode >= ARRAY_SIZE(pcc->keymap)) | ||
482 | return -EINVAL; | ||
483 | |||
484 | if (keycode < 0 || keycode > KEY_MAX) | ||
485 | return -EINVAL; | ||
486 | |||
487 | oldkeycode = pcc->keymap[scancode]; | ||
488 | pcc->keymap[scancode] = keycode; | ||
489 | |||
490 | set_bit(keycode, dev->keybit); | ||
491 | |||
492 | if (!keymap_get_by_keycode(pcc, oldkeycode)) | ||
493 | clear_bit(oldkeycode, dev->keybit); | ||
494 | |||
495 | return 0; | ||
496 | } | ||
497 | |||
498 | static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc) | ||
499 | { | ||
500 | struct input_dev *hotk_input_dev = pcc->input_dev; | ||
501 | int rc; | ||
502 | int key_code, hkey_num; | ||
503 | unsigned long long result; | ||
504 | |||
505 | ACPI_FUNCTION_TRACE("acpi_pcc_generate_keyinput"); | ||
506 | |||
507 | rc = acpi_evaluate_integer(pcc->handle, METHOD_HKEY_QUERY, | ||
508 | NULL, &result); | ||
509 | if (!ACPI_SUCCESS(rc)) { | ||
510 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
511 | "error getting hotkey status\n")); | ||
512 | return; | ||
513 | } | ||
514 | |||
515 | acpi_bus_generate_proc_event(pcc->device, HKEY_NOTIFY, result); | ||
516 | |||
517 | hkey_num = result & 0xf; | ||
518 | |||
519 | if (hkey_num < 0 || hkey_num > ARRAY_SIZE(pcc->keymap)) { | ||
520 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
521 | "hotkey number out of range: %d\n", | ||
522 | hkey_num)); | ||
523 | return; | ||
524 | } | ||
525 | |||
526 | key_code = pcc->keymap[hkey_num]; | ||
527 | |||
528 | if (key_code != KEY_RESERVED) { | ||
529 | int pushed = (result & 0x80) ? TRUE : FALSE; | ||
530 | |||
531 | input_report_key(hotk_input_dev, key_code, pushed); | ||
532 | input_sync(hotk_input_dev); | ||
533 | } | ||
534 | |||
535 | return; | ||
536 | } | ||
537 | |||
538 | static void acpi_pcc_hotkey_notify(acpi_handle handle, u32 event, void *data) | ||
539 | { | ||
540 | struct pcc_acpi *pcc = (struct pcc_acpi *) data; | ||
541 | |||
542 | ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_notify"); | ||
543 | |||
544 | switch (event) { | ||
545 | case HKEY_NOTIFY: | ||
546 | acpi_pcc_generate_keyinput(pcc); | ||
547 | break; | ||
548 | default: | ||
549 | /* nothing to do */ | ||
550 | break; | ||
551 | } | ||
552 | } | ||
553 | |||
554 | static int acpi_pcc_init_input(struct pcc_acpi *pcc) | ||
555 | { | ||
556 | int i, rc; | ||
557 | |||
558 | ACPI_FUNCTION_TRACE("acpi_pcc_init_input"); | ||
559 | |||
560 | pcc->input_dev = input_allocate_device(); | ||
561 | if (!pcc->input_dev) { | ||
562 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
563 | "Couldn't allocate input device for hotkey")); | ||
564 | return -ENOMEM; | ||
565 | } | ||
566 | |||
567 | pcc->input_dev->evbit[0] = BIT(EV_KEY); | ||
568 | |||
569 | pcc->input_dev->name = ACPI_PCC_DRIVER_NAME; | ||
570 | pcc->input_dev->phys = ACPI_PCC_INPUT_PHYS; | ||
571 | pcc->input_dev->id.bustype = BUS_HOST; | ||
572 | pcc->input_dev->id.vendor = 0x0001; | ||
573 | pcc->input_dev->id.product = 0x0001; | ||
574 | pcc->input_dev->id.version = 0x0100; | ||
575 | pcc->input_dev->getkeycode = pcc_getkeycode; | ||
576 | pcc->input_dev->setkeycode = pcc_setkeycode; | ||
577 | |||
578 | /* load initial keymap */ | ||
579 | memcpy(pcc->keymap, initial_keymap, sizeof(pcc->keymap)); | ||
580 | |||
581 | for (i = 0; i < ARRAY_SIZE(pcc->keymap); i++) | ||
582 | __set_bit(pcc->keymap[i], pcc->input_dev->keybit); | ||
583 | __clear_bit(KEY_RESERVED, pcc->input_dev->keybit); | ||
584 | |||
585 | input_set_drvdata(pcc->input_dev, pcc); | ||
586 | |||
587 | rc = input_register_device(pcc->input_dev); | ||
588 | if (rc < 0) | ||
589 | input_free_device(pcc->input_dev); | ||
590 | |||
591 | return rc; | ||
592 | } | ||
593 | |||
594 | /* kernel module interface */ | ||
595 | |||
596 | static int acpi_pcc_hotkey_resume(struct acpi_device *device) | ||
597 | { | ||
598 | struct pcc_acpi *pcc = acpi_driver_data(device); | ||
599 | acpi_status status = AE_OK; | ||
600 | |||
601 | ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_resume"); | ||
602 | |||
603 | if (device == NULL || pcc == NULL) | ||
604 | return -EINVAL; | ||
605 | |||
606 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Sticky mode restore: %d\n", | ||
607 | pcc->sticky_mode)); | ||
608 | |||
609 | status = acpi_pcc_write_sset(pcc, SINF_STICKY_KEY, pcc->sticky_mode); | ||
610 | |||
611 | return status == AE_OK ? 0 : -EINVAL; | ||
612 | } | ||
613 | |||
614 | static int acpi_pcc_hotkey_add(struct acpi_device *device) | ||
615 | { | ||
616 | acpi_status status; | ||
617 | struct pcc_acpi *pcc; | ||
618 | int num_sifr, result; | ||
619 | |||
620 | ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_add"); | ||
621 | |||
622 | if (!device) | ||
623 | return -EINVAL; | ||
624 | |||
625 | num_sifr = acpi_pcc_get_sqty(device); | ||
626 | |||
627 | if (num_sifr > 255) { | ||
628 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "num_sifr too large")); | ||
629 | return -ENODEV; | ||
630 | } | ||
631 | |||
632 | pcc = kzalloc(sizeof(struct pcc_acpi), GFP_KERNEL); | ||
633 | if (!pcc) { | ||
634 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
635 | "Couldn't allocate mem for pcc")); | ||
636 | return -ENOMEM; | ||
637 | } | ||
638 | |||
639 | pcc->sinf = kzalloc(sizeof(u32) * (num_sifr + 1), GFP_KERNEL); | ||
640 | if (!pcc->sinf) { | ||
641 | result = -ENOMEM; | ||
642 | goto out_hotkey; | ||
643 | } | ||
644 | |||
645 | pcc->device = device; | ||
646 | pcc->handle = device->handle; | ||
647 | pcc->num_sifr = num_sifr; | ||
648 | device->driver_data = pcc; | ||
649 | strcpy(acpi_device_name(device), ACPI_PCC_DEVICE_NAME); | ||
650 | strcpy(acpi_device_class(device), ACPI_PCC_CLASS); | ||
651 | |||
652 | result = acpi_pcc_init_input(pcc); | ||
653 | if (result) { | ||
654 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
655 | "Error installing keyinput handler\n")); | ||
656 | goto out_sinf; | ||
657 | } | ||
658 | |||
659 | /* initialize hotkey input device */ | ||
660 | status = acpi_install_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY, | ||
661 | acpi_pcc_hotkey_notify, pcc); | ||
662 | |||
663 | if (ACPI_FAILURE(status)) { | ||
664 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
665 | "Error installing notify handler\n")); | ||
666 | result = -ENODEV; | ||
667 | goto out_input; | ||
668 | } | ||
669 | |||
670 | /* initialize backlight */ | ||
671 | pcc->backlight = backlight_device_register("panasonic", NULL, pcc, | ||
672 | &pcc_backlight_ops); | ||
673 | if (IS_ERR(pcc->backlight)) | ||
674 | goto out_notify; | ||
675 | |||
676 | if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) { | ||
677 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
678 | "Couldn't retrieve BIOS data\n")); | ||
679 | goto out_backlight; | ||
680 | } | ||
681 | |||
682 | /* read the initial brightness setting from the hardware */ | ||
683 | pcc->backlight->props.max_brightness = | ||
684 | pcc->sinf[SINF_AC_MAX_BRIGHT]; | ||
685 | pcc->backlight->props.brightness = pcc->sinf[SINF_AC_CUR_BRIGHT]; | ||
686 | |||
687 | /* read the initial sticky key mode from the hardware */ | ||
688 | pcc->sticky_mode = pcc->sinf[SINF_STICKY_KEY]; | ||
689 | |||
690 | /* add sysfs attributes */ | ||
691 | result = sysfs_create_group(&device->dev.kobj, &pcc_attr_group); | ||
692 | if (result) | ||
693 | goto out_backlight; | ||
694 | |||
695 | return 0; | ||
696 | |||
697 | out_backlight: | ||
698 | backlight_device_unregister(pcc->backlight); | ||
699 | out_notify: | ||
700 | acpi_remove_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY, | ||
701 | acpi_pcc_hotkey_notify); | ||
702 | out_input: | ||
703 | input_unregister_device(pcc->input_dev); | ||
704 | /* no need to input_free_device() since core input API refcount and | ||
705 | * free()s the device */ | ||
706 | out_sinf: | ||
707 | kfree(pcc->sinf); | ||
708 | out_hotkey: | ||
709 | kfree(pcc); | ||
710 | |||
711 | return result; | ||
712 | } | ||
713 | |||
714 | static int __init acpi_pcc_init(void) | ||
715 | { | ||
716 | int result = 0; | ||
717 | |||
718 | ACPI_FUNCTION_TRACE("acpi_pcc_init"); | ||
719 | |||
720 | if (acpi_disabled) | ||
721 | return -ENODEV; | ||
722 | |||
723 | result = acpi_bus_register_driver(&acpi_pcc_driver); | ||
724 | if (result < 0) { | ||
725 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
726 | "Error registering hotkey driver\n")); | ||
727 | return -ENODEV; | ||
728 | } | ||
729 | |||
730 | return 0; | ||
731 | } | ||
732 | |||
733 | static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type) | ||
734 | { | ||
735 | struct pcc_acpi *pcc = acpi_driver_data(device); | ||
736 | |||
737 | ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_remove"); | ||
738 | |||
739 | if (!device || !pcc) | ||
740 | return -EINVAL; | ||
741 | |||
742 | sysfs_remove_group(&device->dev.kobj, &pcc_attr_group); | ||
743 | |||
744 | backlight_device_unregister(pcc->backlight); | ||
745 | |||
746 | acpi_remove_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY, | ||
747 | acpi_pcc_hotkey_notify); | ||
748 | |||
749 | input_unregister_device(pcc->input_dev); | ||
750 | /* no need to input_free_device() since core input API refcount and | ||
751 | * free()s the device */ | ||
752 | |||
753 | kfree(pcc->sinf); | ||
754 | kfree(pcc); | ||
755 | |||
756 | return 0; | ||
757 | } | ||
758 | |||
759 | static void __exit acpi_pcc_exit(void) | ||
760 | { | ||
761 | ACPI_FUNCTION_TRACE("acpi_pcc_exit"); | ||
762 | |||
763 | acpi_bus_unregister_driver(&acpi_pcc_driver); | ||
764 | } | ||
765 | |||
766 | module_init(acpi_pcc_init); | ||
767 | module_exit(acpi_pcc_exit); | ||
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 60775be22822..5a97d3a9d745 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c | |||
@@ -970,7 +970,7 @@ static int sony_nc_resume(struct acpi_device *device) | |||
970 | /* set the last requested brightness level */ | 970 | /* set the last requested brightness level */ |
971 | if (sony_backlight_device && | 971 | if (sony_backlight_device && |
972 | !sony_backlight_update_status(sony_backlight_device)) | 972 | !sony_backlight_update_status(sony_backlight_device)) |
973 | printk(KERN_WARNING DRV_PFX "unable to restore brightness level"); | 973 | printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n"); |
974 | 974 | ||
975 | /* re-initialize models with specific requirements */ | 975 | /* re-initialize models with specific requirements */ |
976 | dmi_check_system(sony_nc_ids); | 976 | dmi_check_system(sony_nc_ids); |
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 6b9300779a43..4db1cf9078d9 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c | |||
@@ -159,7 +159,6 @@ enum { | |||
159 | #define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG | 159 | #define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG |
160 | 160 | ||
161 | #define TPACPI_DBG_ALL 0xffff | 161 | #define TPACPI_DBG_ALL 0xffff |
162 | #define TPACPI_DBG_ALL 0xffff | ||
163 | #define TPACPI_DBG_INIT 0x0001 | 162 | #define TPACPI_DBG_INIT 0x0001 |
164 | #define TPACPI_DBG_EXIT 0x0002 | 163 | #define TPACPI_DBG_EXIT 0x0002 |
165 | #define dbg_printk(a_dbg_level, format, arg...) \ | 164 | #define dbg_printk(a_dbg_level, format, arg...) \ |
@@ -543,7 +542,7 @@ static int __init setup_acpi_notify(struct ibm_struct *ibm) | |||
543 | return -ENODEV; | 542 | return -ENODEV; |
544 | } | 543 | } |
545 | 544 | ||
546 | acpi_driver_data(ibm->acpi->device) = ibm; | 545 | ibm->acpi->device->driver_data = ibm; |
547 | sprintf(acpi_device_class(ibm->acpi->device), "%s/%s", | 546 | sprintf(acpi_device_class(ibm->acpi->device), "%s/%s", |
548 | TPACPI_ACPI_EVENT_PREFIX, | 547 | TPACPI_ACPI_EVENT_PREFIX, |
549 | ibm->name); | 548 | ibm->name); |
@@ -582,7 +581,8 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm) | |||
582 | 581 | ||
583 | ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL); | 582 | ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL); |
584 | if (!ibm->acpi->driver) { | 583 | if (!ibm->acpi->driver) { |
585 | printk(TPACPI_ERR "kzalloc(ibm->driver) failed\n"); | 584 | printk(TPACPI_ERR |
585 | "failed to allocate memory for ibm->acpi->driver\n"); | ||
586 | return -ENOMEM; | 586 | return -ENOMEM; |
587 | } | 587 | } |
588 | 588 | ||
@@ -838,6 +838,13 @@ static int parse_strtoul(const char *buf, | |||
838 | return 0; | 838 | return 0; |
839 | } | 839 | } |
840 | 840 | ||
841 | static void tpacpi_disable_brightness_delay(void) | ||
842 | { | ||
843 | if (acpi_evalf(hkey_handle, NULL, "PWMS", "qvd", 0)) | ||
844 | printk(TPACPI_NOTICE | ||
845 | "ACPI backlight control delay disabled\n"); | ||
846 | } | ||
847 | |||
841 | static int __init tpacpi_query_bcl_levels(acpi_handle handle) | 848 | static int __init tpacpi_query_bcl_levels(acpi_handle handle) |
842 | { | 849 | { |
843 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 850 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
@@ -2139,6 +2146,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
2139 | if (!tp_features.hotkey) | 2146 | if (!tp_features.hotkey) |
2140 | return 1; | 2147 | return 1; |
2141 | 2148 | ||
2149 | tpacpi_disable_brightness_delay(); | ||
2150 | |||
2142 | hotkey_dev_attributes = create_attr_set(13, NULL); | 2151 | hotkey_dev_attributes = create_attr_set(13, NULL); |
2143 | if (!hotkey_dev_attributes) | 2152 | if (!hotkey_dev_attributes) |
2144 | return -ENOMEM; | 2153 | return -ENOMEM; |
@@ -2512,6 +2521,8 @@ static void hotkey_suspend(pm_message_t state) | |||
2512 | 2521 | ||
2513 | static void hotkey_resume(void) | 2522 | static void hotkey_resume(void) |
2514 | { | 2523 | { |
2524 | tpacpi_disable_brightness_delay(); | ||
2525 | |||
2515 | if (hotkey_mask_get()) | 2526 | if (hotkey_mask_get()) |
2516 | printk(TPACPI_ERR | 2527 | printk(TPACPI_ERR |
2517 | "error while trying to read hot key mask " | 2528 | "error while trying to read hot key mask " |
@@ -5983,6 +5994,52 @@ static void fan_exit(void) | |||
5983 | flush_workqueue(tpacpi_wq); | 5994 | flush_workqueue(tpacpi_wq); |
5984 | } | 5995 | } |
5985 | 5996 | ||
5997 | static void fan_suspend(pm_message_t state) | ||
5998 | { | ||
5999 | if (!fan_control_allowed) | ||
6000 | return; | ||
6001 | |||
6002 | /* Store fan status in cache */ | ||
6003 | fan_get_status_safe(NULL); | ||
6004 | if (tp_features.fan_ctrl_status_undef) | ||
6005 | fan_control_desired_level = TP_EC_FAN_AUTO; | ||
6006 | } | ||
6007 | |||
6008 | static void fan_resume(void) | ||
6009 | { | ||
6010 | u8 saved_fan_level; | ||
6011 | u8 current_level = 7; | ||
6012 | bool do_set = false; | ||
6013 | |||
6014 | /* DSDT *always* updates status on resume */ | ||
6015 | tp_features.fan_ctrl_status_undef = 0; | ||
6016 | |||
6017 | saved_fan_level = fan_control_desired_level; | ||
6018 | if (!fan_control_allowed || | ||
6019 | (fan_get_status_safe(¤t_level) < 0)) | ||
6020 | return; | ||
6021 | |||
6022 | switch (fan_control_access_mode) { | ||
6023 | case TPACPI_FAN_WR_ACPI_SFAN: | ||
6024 | do_set = (saved_fan_level > current_level); | ||
6025 | break; | ||
6026 | case TPACPI_FAN_WR_ACPI_FANS: | ||
6027 | case TPACPI_FAN_WR_TPEC: | ||
6028 | do_set = ((saved_fan_level & TP_EC_FAN_FULLSPEED) || | ||
6029 | (saved_fan_level == 7 && | ||
6030 | !(current_level & TP_EC_FAN_FULLSPEED))); | ||
6031 | break; | ||
6032 | default: | ||
6033 | return; | ||
6034 | } | ||
6035 | if (do_set) { | ||
6036 | printk(TPACPI_NOTICE | ||
6037 | "restoring fan level to 0x%02x\n", | ||
6038 | saved_fan_level); | ||
6039 | fan_set_level_safe(saved_fan_level); | ||
6040 | } | ||
6041 | } | ||
6042 | |||
5986 | static int fan_read(char *p) | 6043 | static int fan_read(char *p) |
5987 | { | 6044 | { |
5988 | int len = 0; | 6045 | int len = 0; |
@@ -6174,6 +6231,8 @@ static struct ibm_struct fan_driver_data = { | |||
6174 | .read = fan_read, | 6231 | .read = fan_read, |
6175 | .write = fan_write, | 6232 | .write = fan_write, |
6176 | .exit = fan_exit, | 6233 | .exit = fan_exit, |
6234 | .suspend = fan_suspend, | ||
6235 | .resume = fan_resume, | ||
6177 | }; | 6236 | }; |
6178 | 6237 | ||
6179 | /**************************************************************************** | 6238 | /**************************************************************************** |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index a3e4705dd8f0..955aae4071f7 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -169,7 +169,9 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val, | |||
169 | } | 169 | } |
170 | 170 | ||
171 | 171 | ||
172 | 172 | static struct acpi_dock_ops acpiphp_dock_ops = { | |
173 | .handler = handle_hotplug_event_func, | ||
174 | }; | ||
173 | 175 | ||
174 | /* callback routine to register each ACPI PCI slot object */ | 176 | /* callback routine to register each ACPI PCI slot object */ |
175 | static acpi_status | 177 | static acpi_status |
@@ -180,7 +182,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
180 | struct acpiphp_func *newfunc; | 182 | struct acpiphp_func *newfunc; |
181 | acpi_handle tmp; | 183 | acpi_handle tmp; |
182 | acpi_status status = AE_OK; | 184 | acpi_status status = AE_OK; |
183 | unsigned long adr, sun; | 185 | unsigned long long adr, sun; |
184 | int device, function, retval; | 186 | int device, function, retval; |
185 | 187 | ||
186 | status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); | 188 | status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); |
@@ -285,7 +287,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
285 | */ | 287 | */ |
286 | newfunc->flags &= ~FUNC_HAS_EJ0; | 288 | newfunc->flags &= ~FUNC_HAS_EJ0; |
287 | if (register_hotplug_dock_device(handle, | 289 | if (register_hotplug_dock_device(handle, |
288 | handle_hotplug_event_func, newfunc)) | 290 | &acpiphp_dock_ops, newfunc)) |
289 | dbg("failed to register dock device\n"); | 291 | dbg("failed to register dock device\n"); |
290 | 292 | ||
291 | /* we need to be notified when dock events happen | 293 | /* we need to be notified when dock events happen |
@@ -528,7 +530,7 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
528 | { | 530 | { |
529 | acpi_status status; | 531 | acpi_status status; |
530 | acpi_handle dummy_handle; | 532 | acpi_handle dummy_handle; |
531 | unsigned long tmp; | 533 | unsigned long long tmp; |
532 | int device, function; | 534 | int device, function; |
533 | struct pci_dev *dev; | 535 | struct pci_dev *dev; |
534 | struct pci_bus *pci_bus = context; | 536 | struct pci_bus *pci_bus = context; |
@@ -573,7 +575,7 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
573 | static int add_bridge(acpi_handle handle) | 575 | static int add_bridge(acpi_handle handle) |
574 | { | 576 | { |
575 | acpi_status status; | 577 | acpi_status status; |
576 | unsigned long tmp; | 578 | unsigned long long tmp; |
577 | int seg, bus; | 579 | int seg, bus; |
578 | acpi_handle dummy_handle; | 580 | acpi_handle dummy_handle; |
579 | struct pci_bus *pci_bus; | 581 | struct pci_bus *pci_bus; |
@@ -767,7 +769,7 @@ static int get_gsi_base(acpi_handle handle, u32 *gsi_base) | |||
767 | { | 769 | { |
768 | acpi_status status; | 770 | acpi_status status; |
769 | int result = -1; | 771 | int result = -1; |
770 | unsigned long gsb; | 772 | unsigned long long gsb; |
771 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | 773 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; |
772 | union acpi_object *obj; | 774 | union acpi_object *obj; |
773 | void *table; | 775 | void *table; |
@@ -808,7 +810,7 @@ static acpi_status | |||
808 | ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv) | 810 | ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv) |
809 | { | 811 | { |
810 | acpi_status status; | 812 | acpi_status status; |
811 | unsigned long sta; | 813 | unsigned long long sta; |
812 | acpi_handle tmp; | 814 | acpi_handle tmp; |
813 | struct pci_dev *pdev; | 815 | struct pci_dev *pdev; |
814 | u32 gsi_base; | 816 | u32 gsi_base; |
@@ -872,7 +874,7 @@ static acpi_status | |||
872 | ioapic_remove(acpi_handle handle, u32 lvl, void *context, void **rv) | 874 | ioapic_remove(acpi_handle handle, u32 lvl, void *context, void **rv) |
873 | { | 875 | { |
874 | acpi_status status; | 876 | acpi_status status; |
875 | unsigned long sta; | 877 | unsigned long long sta; |
876 | acpi_handle tmp; | 878 | acpi_handle tmp; |
877 | u32 gsi_base; | 879 | u32 gsi_base; |
878 | struct acpiphp_ioapic *pos, *n, *ioapic = NULL; | 880 | struct acpiphp_ioapic *pos, *n, *ioapic = NULL; |
@@ -1264,7 +1266,7 @@ static int disable_device(struct acpiphp_slot *slot) | |||
1264 | static unsigned int get_slot_status(struct acpiphp_slot *slot) | 1266 | static unsigned int get_slot_status(struct acpiphp_slot *slot) |
1265 | { | 1267 | { |
1266 | acpi_status status; | 1268 | acpi_status status; |
1267 | unsigned long sta = 0; | 1269 | unsigned long long sta = 0; |
1268 | u32 dvid; | 1270 | u32 dvid; |
1269 | struct list_head *l; | 1271 | struct list_head *l; |
1270 | struct acpiphp_func *func; | 1272 | struct acpiphp_func *func; |
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 2b7c45e39370..b291ee68b4f1 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c | |||
@@ -183,7 +183,7 @@ static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status) | |||
183 | union acpi_object args[2]; | 183 | union acpi_object args[2]; |
184 | struct acpi_object_list params = { .pointer = args, .count = 2 }; | 184 | struct acpi_object_list params = { .pointer = args, .count = 2 }; |
185 | acpi_status stat; | 185 | acpi_status stat; |
186 | unsigned long rc; | 186 | unsigned long long rc; |
187 | union apci_descriptor *ibm_slot; | 187 | union apci_descriptor *ibm_slot; |
188 | 188 | ||
189 | ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot)); | 189 | ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot)); |
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index d748698e31a2..3eee70928d45 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c | |||
@@ -413,7 +413,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
413 | /* | 413 | /* |
414 | * Add the slot's devices to the ACPI infrastructure */ | 414 | * Add the slot's devices to the ACPI infrastructure */ |
415 | if (SN_ACPI_BASE_SUPPORT() && ssdt) { | 415 | if (SN_ACPI_BASE_SUPPORT() && ssdt) { |
416 | unsigned long adr; | 416 | unsigned long long adr; |
417 | struct acpi_device *pdevice; | 417 | struct acpi_device *pdevice; |
418 | struct acpi_device *device; | 418 | struct acpi_device *device; |
419 | acpi_handle phandle; | 419 | acpi_handle phandle; |
@@ -505,7 +505,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
505 | /* free the ACPI resources for the slot */ | 505 | /* free the ACPI resources for the slot */ |
506 | if (SN_ACPI_BASE_SUPPORT() && | 506 | if (SN_ACPI_BASE_SUPPORT() && |
507 | PCI_CONTROLLER(slot->pci_bus)->acpi_handle) { | 507 | PCI_CONTROLLER(slot->pci_bus)->acpi_handle) { |
508 | unsigned long adr; | 508 | unsigned long long adr; |
509 | struct acpi_device *device; | 509 | struct acpi_device *device; |
510 | acpi_handle phandle; | 510 | acpi_handle phandle; |
511 | acpi_handle chandle = NULL; | 511 | acpi_handle chandle = NULL; |
diff --git a/drivers/pnp/Kconfig b/drivers/pnp/Kconfig index 821933f9aa57..2a37b3fedb8e 100644 --- a/drivers/pnp/Kconfig +++ b/drivers/pnp/Kconfig | |||
@@ -20,13 +20,21 @@ menuconfig PNP | |||
20 | 20 | ||
21 | If unsure, say Y. | 21 | If unsure, say Y. |
22 | 22 | ||
23 | if PNP | 23 | config PNP_DEBUG_MESSAGES |
24 | 24 | default y | |
25 | config PNP_DEBUG | 25 | bool "PNP debugging messages" |
26 | bool "PnP Debug Messages" | 26 | depends on PNP |
27 | help | 27 | help |
28 | Say Y if you want the Plug and Play Layer to print debug messages. | 28 | Say Y here if you want the PNP layer to be able to produce debugging |
29 | This is useful if you are developing a PnP driver or troubleshooting. | 29 | messages if needed. The messages can be enabled at boot-time with |
30 | the pnp.debug kernel parameter. | ||
31 | |||
32 | This option allows you to save a bit of space if you do not want | ||
33 | the messages to even be built into the kernel. | ||
34 | |||
35 | If you have any doubts about this, say Y here. | ||
36 | |||
37 | if PNP | ||
30 | 38 | ||
31 | comment "Protocols" | 39 | comment "Protocols" |
32 | 40 | ||
diff --git a/drivers/pnp/Makefile b/drivers/pnp/Makefile index e83f34f1b5ba..8de3775ec242 100644 --- a/drivers/pnp/Makefile +++ b/drivers/pnp/Makefile | |||
@@ -10,7 +10,3 @@ obj-$(CONFIG_ISAPNP) += isapnp/ | |||
10 | 10 | ||
11 | # pnp_system_init goes after pnpacpi/pnpbios init | 11 | # pnp_system_init goes after pnpacpi/pnpbios init |
12 | obj-y += system.o | 12 | obj-y += system.o |
13 | |||
14 | ifeq ($(CONFIG_PNP_DEBUG),y) | ||
15 | EXTRA_CFLAGS += -DDEBUG | ||
16 | endif | ||
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 3b8b9d3cb03d..0b8d14050efa 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h | |||
@@ -166,3 +166,13 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, | |||
166 | struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, | 166 | struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, |
167 | resource_size_t start, | 167 | resource_size_t start, |
168 | resource_size_t end, int flags); | 168 | resource_size_t end, int flags); |
169 | |||
170 | extern int pnp_debug; | ||
171 | |||
172 | #if defined(CONFIG_PNP_DEBUG_MESSAGES) | ||
173 | #define pnp_dbg(dev, format, arg...) \ | ||
174 | ({ if (pnp_debug) dev_printk(KERN_DEBUG, dev, format, ## arg); 0; }) | ||
175 | #else | ||
176 | #define pnp_dbg(dev, format, arg...) \ | ||
177 | ({ if (0) dev_printk(KERN_DEBUG, dev, format, ## arg); 0; }) | ||
178 | #endif | ||
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c index 817fe626e15b..16c01c6fa7c5 100644 --- a/drivers/pnp/core.c +++ b/drivers/pnp/core.c | |||
@@ -177,6 +177,9 @@ int __pnp_add_device(struct pnp_dev *dev) | |||
177 | int pnp_add_device(struct pnp_dev *dev) | 177 | int pnp_add_device(struct pnp_dev *dev) |
178 | { | 178 | { |
179 | int ret; | 179 | int ret; |
180 | char buf[128]; | ||
181 | int len = 0; | ||
182 | struct pnp_id *id; | ||
180 | 183 | ||
181 | if (dev->card) | 184 | if (dev->card) |
182 | return -EINVAL; | 185 | return -EINVAL; |
@@ -185,17 +188,12 @@ int pnp_add_device(struct pnp_dev *dev) | |||
185 | if (ret) | 188 | if (ret) |
186 | return ret; | 189 | return ret; |
187 | 190 | ||
188 | #ifdef CONFIG_PNP_DEBUG | 191 | buf[0] = '\0'; |
189 | { | 192 | for (id = dev->id; id; id = id->next) |
190 | struct pnp_id *id; | 193 | len += scnprintf(buf + len, sizeof(buf) - len, " %s", id->id); |
191 | 194 | ||
192 | dev_printk(KERN_DEBUG, &dev->dev, "%s device, IDs", | 195 | pnp_dbg(&dev->dev, "%s device, IDs%s (%s)\n", |
193 | dev->protocol->name); | 196 | dev->protocol->name, buf, dev->active ? "active" : "disabled"); |
194 | for (id = dev->id; id; id = id->next) | ||
195 | printk(" %s", id->id); | ||
196 | printk(" (%s)\n", dev->active ? "active" : "disabled"); | ||
197 | } | ||
198 | #endif | ||
199 | return 0; | 197 | return 0; |
200 | } | 198 | } |
201 | 199 | ||
@@ -214,3 +212,14 @@ static int __init pnp_init(void) | |||
214 | } | 212 | } |
215 | 213 | ||
216 | subsys_initcall(pnp_init); | 214 | subsys_initcall(pnp_init); |
215 | |||
216 | int pnp_debug; | ||
217 | |||
218 | #if defined(CONFIG_PNP_DEBUG_MESSAGES) | ||
219 | static int __init pnp_debug_setup(char *__unused) | ||
220 | { | ||
221 | pnp_debug = 1; | ||
222 | return 1; | ||
223 | } | ||
224 | __setup("pnp.debug", pnp_debug_setup); | ||
225 | #endif | ||
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index e3f7e89c4dfb..527ee764c93f 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c | |||
@@ -114,7 +114,6 @@ static int pnp_device_probe(struct device *dev) | |||
114 | } else | 114 | } else |
115 | goto fail; | 115 | goto fail; |
116 | 116 | ||
117 | dev_dbg(dev, "driver attached\n"); | ||
118 | return error; | 117 | return error; |
119 | 118 | ||
120 | fail: | 119 | fail: |
@@ -211,8 +210,6 @@ struct bus_type pnp_bus_type = { | |||
211 | 210 | ||
212 | int pnp_register_driver(struct pnp_driver *drv) | 211 | int pnp_register_driver(struct pnp_driver *drv) |
213 | { | 212 | { |
214 | pnp_dbg("the driver '%s' has been registered", drv->name); | ||
215 | |||
216 | drv->driver.name = drv->name; | 213 | drv->driver.name = drv->name; |
217 | drv->driver.bus = &pnp_bus_type; | 214 | drv->driver.bus = &pnp_bus_type; |
218 | 215 | ||
@@ -222,7 +219,6 @@ int pnp_register_driver(struct pnp_driver *drv) | |||
222 | void pnp_unregister_driver(struct pnp_driver *drv) | 219 | void pnp_unregister_driver(struct pnp_driver *drv) |
223 | { | 220 | { |
224 | driver_unregister(&drv->driver); | 221 | driver_unregister(&drv->driver); |
225 | pnp_dbg("the driver '%s' has been unregistered", drv->name); | ||
226 | } | 222 | } |
227 | 223 | ||
228 | /** | 224 | /** |
diff --git a/drivers/pnp/isapnp/Makefile b/drivers/pnp/isapnp/Makefile index 3e38f06f8d78..cac18bbfb817 100644 --- a/drivers/pnp/isapnp/Makefile +++ b/drivers/pnp/isapnp/Makefile | |||
@@ -5,7 +5,3 @@ | |||
5 | isapnp-proc-$(CONFIG_PROC_FS) = proc.o | 5 | isapnp-proc-$(CONFIG_PROC_FS) = proc.o |
6 | 6 | ||
7 | obj-y := core.o compat.o $(isapnp-proc-y) | 7 | obj-y := core.o compat.o $(isapnp-proc-y) |
8 | |||
9 | ifeq ($(CONFIG_PNP_DEBUG),y) | ||
10 | EXTRA_CFLAGS += -DDEBUG | ||
11 | endif | ||
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index 46455fbab6d5..e851160e14f0 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c | |||
@@ -901,7 +901,7 @@ static int isapnp_get_resources(struct pnp_dev *dev) | |||
901 | { | 901 | { |
902 | int i, ret; | 902 | int i, ret; |
903 | 903 | ||
904 | dev_dbg(&dev->dev, "get resources\n"); | 904 | pnp_dbg(&dev->dev, "get resources\n"); |
905 | pnp_init_resources(dev); | 905 | pnp_init_resources(dev); |
906 | isapnp_cfg_begin(dev->card->number, dev->number); | 906 | isapnp_cfg_begin(dev->card->number, dev->number); |
907 | dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE); | 907 | dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE); |
@@ -939,13 +939,13 @@ static int isapnp_set_resources(struct pnp_dev *dev) | |||
939 | struct resource *res; | 939 | struct resource *res; |
940 | int tmp; | 940 | int tmp; |
941 | 941 | ||
942 | dev_dbg(&dev->dev, "set resources\n"); | 942 | pnp_dbg(&dev->dev, "set resources\n"); |
943 | isapnp_cfg_begin(dev->card->number, dev->number); | 943 | isapnp_cfg_begin(dev->card->number, dev->number); |
944 | dev->active = 1; | 944 | dev->active = 1; |
945 | for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) { | 945 | for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) { |
946 | res = pnp_get_resource(dev, IORESOURCE_IO, tmp); | 946 | res = pnp_get_resource(dev, IORESOURCE_IO, tmp); |
947 | if (pnp_resource_enabled(res)) { | 947 | if (pnp_resource_enabled(res)) { |
948 | dev_dbg(&dev->dev, " set io %d to %#llx\n", | 948 | pnp_dbg(&dev->dev, " set io %d to %#llx\n", |
949 | tmp, (unsigned long long) res->start); | 949 | tmp, (unsigned long long) res->start); |
950 | isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1), | 950 | isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1), |
951 | res->start); | 951 | res->start); |
@@ -957,14 +957,14 @@ static int isapnp_set_resources(struct pnp_dev *dev) | |||
957 | int irq = res->start; | 957 | int irq = res->start; |
958 | if (irq == 2) | 958 | if (irq == 2) |
959 | irq = 9; | 959 | irq = 9; |
960 | dev_dbg(&dev->dev, " set irq %d to %d\n", tmp, irq); | 960 | pnp_dbg(&dev->dev, " set irq %d to %d\n", tmp, irq); |
961 | isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq); | 961 | isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq); |
962 | } | 962 | } |
963 | } | 963 | } |
964 | for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) { | 964 | for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) { |
965 | res = pnp_get_resource(dev, IORESOURCE_DMA, tmp); | 965 | res = pnp_get_resource(dev, IORESOURCE_DMA, tmp); |
966 | if (pnp_resource_enabled(res)) { | 966 | if (pnp_resource_enabled(res)) { |
967 | dev_dbg(&dev->dev, " set dma %d to %lld\n", | 967 | pnp_dbg(&dev->dev, " set dma %d to %lld\n", |
968 | tmp, (unsigned long long) res->start); | 968 | tmp, (unsigned long long) res->start); |
969 | isapnp_write_byte(ISAPNP_CFG_DMA + tmp, res->start); | 969 | isapnp_write_byte(ISAPNP_CFG_DMA + tmp, res->start); |
970 | } | 970 | } |
@@ -972,7 +972,7 @@ static int isapnp_set_resources(struct pnp_dev *dev) | |||
972 | for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) { | 972 | for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) { |
973 | res = pnp_get_resource(dev, IORESOURCE_MEM, tmp); | 973 | res = pnp_get_resource(dev, IORESOURCE_MEM, tmp); |
974 | if (pnp_resource_enabled(res)) { | 974 | if (pnp_resource_enabled(res)) { |
975 | dev_dbg(&dev->dev, " set mem %d to %#llx\n", | 975 | pnp_dbg(&dev->dev, " set mem %d to %#llx\n", |
976 | tmp, (unsigned long long) res->start); | 976 | tmp, (unsigned long long) res->start); |
977 | isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3), | 977 | isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3), |
978 | (res->start >> 8) & 0xffff); | 978 | (res->start >> 8) & 0xffff); |
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index b526eaad3f6c..00fd3577b985 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c | |||
@@ -25,7 +25,7 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) | |||
25 | 25 | ||
26 | res = pnp_get_resource(dev, IORESOURCE_IO, idx); | 26 | res = pnp_get_resource(dev, IORESOURCE_IO, idx); |
27 | if (res) { | 27 | if (res) { |
28 | dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx " | 28 | pnp_dbg(&dev->dev, " io %d already set to %#llx-%#llx " |
29 | "flags %#lx\n", idx, (unsigned long long) res->start, | 29 | "flags %#lx\n", idx, (unsigned long long) res->start, |
30 | (unsigned long long) res->end, res->flags); | 30 | (unsigned long long) res->end, res->flags); |
31 | return 0; | 31 | return 0; |
@@ -38,7 +38,7 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) | |||
38 | 38 | ||
39 | if (!rule->size) { | 39 | if (!rule->size) { |
40 | res->flags |= IORESOURCE_DISABLED; | 40 | res->flags |= IORESOURCE_DISABLED; |
41 | dev_dbg(&dev->dev, " io %d disabled\n", idx); | 41 | pnp_dbg(&dev->dev, " io %d disabled\n", idx); |
42 | goto __add; | 42 | goto __add; |
43 | } | 43 | } |
44 | 44 | ||
@@ -49,7 +49,7 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) | |||
49 | res->start += rule->align; | 49 | res->start += rule->align; |
50 | res->end = res->start + rule->size - 1; | 50 | res->end = res->start + rule->size - 1; |
51 | if (res->start > rule->max || !rule->align) { | 51 | if (res->start > rule->max || !rule->align) { |
52 | dev_dbg(&dev->dev, " couldn't assign io %d " | 52 | pnp_dbg(&dev->dev, " couldn't assign io %d " |
53 | "(min %#llx max %#llx)\n", idx, | 53 | "(min %#llx max %#llx)\n", idx, |
54 | (unsigned long long) rule->min, | 54 | (unsigned long long) rule->min, |
55 | (unsigned long long) rule->max); | 55 | (unsigned long long) rule->max); |
@@ -68,7 +68,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) | |||
68 | 68 | ||
69 | res = pnp_get_resource(dev, IORESOURCE_MEM, idx); | 69 | res = pnp_get_resource(dev, IORESOURCE_MEM, idx); |
70 | if (res) { | 70 | if (res) { |
71 | dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx " | 71 | pnp_dbg(&dev->dev, " mem %d already set to %#llx-%#llx " |
72 | "flags %#lx\n", idx, (unsigned long long) res->start, | 72 | "flags %#lx\n", idx, (unsigned long long) res->start, |
73 | (unsigned long long) res->end, res->flags); | 73 | (unsigned long long) res->end, res->flags); |
74 | return 0; | 74 | return 0; |
@@ -90,7 +90,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) | |||
90 | 90 | ||
91 | if (!rule->size) { | 91 | if (!rule->size) { |
92 | res->flags |= IORESOURCE_DISABLED; | 92 | res->flags |= IORESOURCE_DISABLED; |
93 | dev_dbg(&dev->dev, " mem %d disabled\n", idx); | 93 | pnp_dbg(&dev->dev, " mem %d disabled\n", idx); |
94 | goto __add; | 94 | goto __add; |
95 | } | 95 | } |
96 | 96 | ||
@@ -101,7 +101,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) | |||
101 | res->start += rule->align; | 101 | res->start += rule->align; |
102 | res->end = res->start + rule->size - 1; | 102 | res->end = res->start + rule->size - 1; |
103 | if (res->start > rule->max || !rule->align) { | 103 | if (res->start > rule->max || !rule->align) { |
104 | dev_dbg(&dev->dev, " couldn't assign mem %d " | 104 | pnp_dbg(&dev->dev, " couldn't assign mem %d " |
105 | "(min %#llx max %#llx)\n", idx, | 105 | "(min %#llx max %#llx)\n", idx, |
106 | (unsigned long long) rule->min, | 106 | (unsigned long long) rule->min, |
107 | (unsigned long long) rule->max); | 107 | (unsigned long long) rule->max); |
@@ -126,7 +126,7 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) | |||
126 | 126 | ||
127 | res = pnp_get_resource(dev, IORESOURCE_IRQ, idx); | 127 | res = pnp_get_resource(dev, IORESOURCE_IRQ, idx); |
128 | if (res) { | 128 | if (res) { |
129 | dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n", | 129 | pnp_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n", |
130 | idx, (int) res->start, res->flags); | 130 | idx, (int) res->start, res->flags); |
131 | return 0; | 131 | return 0; |
132 | } | 132 | } |
@@ -138,7 +138,7 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) | |||
138 | 138 | ||
139 | if (bitmap_empty(rule->map.bits, PNP_IRQ_NR)) { | 139 | if (bitmap_empty(rule->map.bits, PNP_IRQ_NR)) { |
140 | res->flags |= IORESOURCE_DISABLED; | 140 | res->flags |= IORESOURCE_DISABLED; |
141 | dev_dbg(&dev->dev, " irq %d disabled\n", idx); | 141 | pnp_dbg(&dev->dev, " irq %d disabled\n", idx); |
142 | goto __add; | 142 | goto __add; |
143 | } | 143 | } |
144 | 144 | ||
@@ -160,11 +160,11 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) | |||
160 | res->start = -1; | 160 | res->start = -1; |
161 | res->end = -1; | 161 | res->end = -1; |
162 | res->flags |= IORESOURCE_DISABLED; | 162 | res->flags |= IORESOURCE_DISABLED; |
163 | dev_dbg(&dev->dev, " irq %d disabled (optional)\n", idx); | 163 | pnp_dbg(&dev->dev, " irq %d disabled (optional)\n", idx); |
164 | goto __add; | 164 | goto __add; |
165 | } | 165 | } |
166 | 166 | ||
167 | dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx); | 167 | pnp_dbg(&dev->dev, " couldn't assign irq %d\n", idx); |
168 | return -EBUSY; | 168 | return -EBUSY; |
169 | 169 | ||
170 | __add: | 170 | __add: |
@@ -184,7 +184,7 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) | |||
184 | 184 | ||
185 | res = pnp_get_resource(dev, IORESOURCE_DMA, idx); | 185 | res = pnp_get_resource(dev, IORESOURCE_DMA, idx); |
186 | if (res) { | 186 | if (res) { |
187 | dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n", | 187 | pnp_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n", |
188 | idx, (int) res->start, res->flags); | 188 | idx, (int) res->start, res->flags); |
189 | return 0; | 189 | return 0; |
190 | } | 190 | } |
@@ -205,7 +205,7 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) | |||
205 | res->start = res->end = MAX_DMA_CHANNELS; | 205 | res->start = res->end = MAX_DMA_CHANNELS; |
206 | #endif | 206 | #endif |
207 | res->flags |= IORESOURCE_DISABLED; | 207 | res->flags |= IORESOURCE_DISABLED; |
208 | dev_dbg(&dev->dev, " disable dma %d\n", idx); | 208 | pnp_dbg(&dev->dev, " disable dma %d\n", idx); |
209 | 209 | ||
210 | __add: | 210 | __add: |
211 | pnp_add_dma_resource(dev, res->start, res->flags); | 211 | pnp_add_dma_resource(dev, res->start, res->flags); |
@@ -238,7 +238,7 @@ static int pnp_assign_resources(struct pnp_dev *dev, int set) | |||
238 | int nport = 0, nmem = 0, nirq = 0, ndma = 0; | 238 | int nport = 0, nmem = 0, nirq = 0, ndma = 0; |
239 | int ret = 0; | 239 | int ret = 0; |
240 | 240 | ||
241 | dev_dbg(&dev->dev, "pnp_assign_resources, try dependent set %d\n", set); | 241 | pnp_dbg(&dev->dev, "pnp_assign_resources, try dependent set %d\n", set); |
242 | mutex_lock(&pnp_res_mutex); | 242 | mutex_lock(&pnp_res_mutex); |
243 | pnp_clean_resource_table(dev); | 243 | pnp_clean_resource_table(dev); |
244 | 244 | ||
@@ -270,7 +270,7 @@ static int pnp_assign_resources(struct pnp_dev *dev, int set) | |||
270 | 270 | ||
271 | mutex_unlock(&pnp_res_mutex); | 271 | mutex_unlock(&pnp_res_mutex); |
272 | if (ret < 0) { | 272 | if (ret < 0) { |
273 | dev_dbg(&dev->dev, "pnp_assign_resources failed (%d)\n", ret); | 273 | pnp_dbg(&dev->dev, "pnp_assign_resources failed (%d)\n", ret); |
274 | pnp_clean_resource_table(dev); | 274 | pnp_clean_resource_table(dev); |
275 | } else | 275 | } else |
276 | dbg_pnp_show_resources(dev, "pnp_assign_resources succeeded"); | 276 | dbg_pnp_show_resources(dev, "pnp_assign_resources succeeded"); |
@@ -286,7 +286,7 @@ int pnp_auto_config_dev(struct pnp_dev *dev) | |||
286 | int i, ret; | 286 | int i, ret; |
287 | 287 | ||
288 | if (!pnp_can_configure(dev)) { | 288 | if (!pnp_can_configure(dev)) { |
289 | dev_dbg(&dev->dev, "configuration not supported\n"); | 289 | pnp_dbg(&dev->dev, "configuration not supported\n"); |
290 | return -ENODEV; | 290 | return -ENODEV; |
291 | } | 291 | } |
292 | 292 | ||
@@ -313,7 +313,7 @@ int pnp_auto_config_dev(struct pnp_dev *dev) | |||
313 | int pnp_start_dev(struct pnp_dev *dev) | 313 | int pnp_start_dev(struct pnp_dev *dev) |
314 | { | 314 | { |
315 | if (!pnp_can_write(dev)) { | 315 | if (!pnp_can_write(dev)) { |
316 | dev_dbg(&dev->dev, "activation not supported\n"); | 316 | pnp_dbg(&dev->dev, "activation not supported\n"); |
317 | return -EINVAL; | 317 | return -EINVAL; |
318 | } | 318 | } |
319 | 319 | ||
@@ -336,7 +336,7 @@ int pnp_start_dev(struct pnp_dev *dev) | |||
336 | int pnp_stop_dev(struct pnp_dev *dev) | 336 | int pnp_stop_dev(struct pnp_dev *dev) |
337 | { | 337 | { |
338 | if (!pnp_can_disable(dev)) { | 338 | if (!pnp_can_disable(dev)) { |
339 | dev_dbg(&dev->dev, "disabling not supported\n"); | 339 | pnp_dbg(&dev->dev, "disabling not supported\n"); |
340 | return -EINVAL; | 340 | return -EINVAL; |
341 | } | 341 | } |
342 | if (dev->protocol->disable(dev) < 0) { | 342 | if (dev->protocol->disable(dev) < 0) { |
diff --git a/drivers/pnp/pnpacpi/Makefile b/drivers/pnp/pnpacpi/Makefile index 2d7a1e6908be..905326fcca85 100644 --- a/drivers/pnp/pnpacpi/Makefile +++ b/drivers/pnp/pnpacpi/Makefile | |||
@@ -3,7 +3,3 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := core.o rsparser.o | 5 | obj-y := core.o rsparser.o |
6 | |||
7 | ifeq ($(CONFIG_PNP_DEBUG),y) | ||
8 | EXTRA_CFLAGS += -DDEBUG | ||
9 | endif | ||
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 53561d72b4ee..383e47c392a4 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -75,7 +75,7 @@ static int __init ispnpidacpi(char *id) | |||
75 | 75 | ||
76 | static int pnpacpi_get_resources(struct pnp_dev *dev) | 76 | static int pnpacpi_get_resources(struct pnp_dev *dev) |
77 | { | 77 | { |
78 | dev_dbg(&dev->dev, "get resources\n"); | 78 | pnp_dbg(&dev->dev, "get resources\n"); |
79 | return pnpacpi_parse_allocated_resource(dev); | 79 | return pnpacpi_parse_allocated_resource(dev); |
80 | } | 80 | } |
81 | 81 | ||
@@ -86,7 +86,7 @@ static int pnpacpi_set_resources(struct pnp_dev *dev) | |||
86 | int ret; | 86 | int ret; |
87 | acpi_status status; | 87 | acpi_status status; |
88 | 88 | ||
89 | dev_dbg(&dev->dev, "set resources\n"); | 89 | pnp_dbg(&dev->dev, "set resources\n"); |
90 | ret = pnpacpi_build_resource_template(dev, &buffer); | 90 | ret = pnpacpi_build_resource_template(dev, &buffer); |
91 | if (ret) | 91 | if (ret) |
92 | return ret; | 92 | return ret; |
@@ -148,9 +148,13 @@ static int __init pnpacpi_add_device(struct acpi_device *device) | |||
148 | acpi_status status; | 148 | acpi_status status; |
149 | struct pnp_dev *dev; | 149 | struct pnp_dev *dev; |
150 | 150 | ||
151 | /* | ||
152 | * If a PnPacpi device is not present , the device | ||
153 | * driver should not be loaded. | ||
154 | */ | ||
151 | status = acpi_get_handle(device->handle, "_CRS", &temp); | 155 | status = acpi_get_handle(device->handle, "_CRS", &temp); |
152 | if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) || | 156 | if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) || |
153 | is_exclusive_device(device)) | 157 | is_exclusive_device(device) || (!device->status.present)) |
154 | return 0; | 158 | return 0; |
155 | 159 | ||
156 | dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device)); | 160 | dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device)); |
@@ -255,14 +259,14 @@ int pnpacpi_disabled __initdata; | |||
255 | static int __init pnpacpi_init(void) | 259 | static int __init pnpacpi_init(void) |
256 | { | 260 | { |
257 | if (acpi_disabled || pnpacpi_disabled) { | 261 | if (acpi_disabled || pnpacpi_disabled) { |
258 | pnp_info("PnP ACPI: disabled"); | 262 | printk(KERN_INFO "pnp: PnP ACPI: disabled\n"); |
259 | return 0; | 263 | return 0; |
260 | } | 264 | } |
261 | pnp_info("PnP ACPI init"); | 265 | printk(KERN_INFO "pnp: PnP ACPI init\n"); |
262 | pnp_register_protocol(&pnpacpi_protocol); | 266 | pnp_register_protocol(&pnpacpi_protocol); |
263 | register_acpi_bus_type(&acpi_pnp_bus); | 267 | register_acpi_bus_type(&acpi_pnp_bus); |
264 | acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL); | 268 | acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL); |
265 | pnp_info("PnP ACPI: found %d devices", num); | 269 | printk(KERN_INFO "pnp: PnP ACPI: found %d devices\n", num); |
266 | unregister_acpi_bus_type(&acpi_pnp_bus); | 270 | unregister_acpi_bus_type(&acpi_pnp_bus); |
267 | pnp_platform_devices = 1; | 271 | pnp_platform_devices = 1; |
268 | return 0; | 272 | return 0; |
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 95015cbfd33f..adf17856bacc 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -132,7 +132,8 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev, | |||
132 | pnp_add_irq_resource(dev, irq, flags); | 132 | pnp_add_irq_resource(dev, irq, flags); |
133 | } | 133 | } |
134 | 134 | ||
135 | static int dma_flags(int type, int bus_master, int transfer) | 135 | static int dma_flags(struct pnp_dev *dev, int type, int bus_master, |
136 | int transfer) | ||
136 | { | 137 | { |
137 | int flags = 0; | 138 | int flags = 0; |
138 | 139 | ||
@@ -154,7 +155,7 @@ static int dma_flags(int type, int bus_master, int transfer) | |||
154 | default: | 155 | default: |
155 | /* Set a default value ? */ | 156 | /* Set a default value ? */ |
156 | flags |= IORESOURCE_DMA_COMPATIBLE; | 157 | flags |= IORESOURCE_DMA_COMPATIBLE; |
157 | pnp_err("Invalid DMA type"); | 158 | dev_err(&dev->dev, "invalid DMA type %d\n", type); |
158 | } | 159 | } |
159 | switch (transfer) { | 160 | switch (transfer) { |
160 | case ACPI_TRANSFER_8: | 161 | case ACPI_TRANSFER_8: |
@@ -169,7 +170,7 @@ static int dma_flags(int type, int bus_master, int transfer) | |||
169 | default: | 170 | default: |
170 | /* Set a default value ? */ | 171 | /* Set a default value ? */ |
171 | flags |= IORESOURCE_DMA_8AND16BIT; | 172 | flags |= IORESOURCE_DMA_8AND16BIT; |
172 | pnp_err("Invalid DMA transfer type"); | 173 | dev_err(&dev->dev, "invalid DMA transfer type %d\n", transfer); |
173 | } | 174 | } |
174 | 175 | ||
175 | return flags; | 176 | return flags; |
@@ -336,7 +337,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
336 | case ACPI_RESOURCE_TYPE_DMA: | 337 | case ACPI_RESOURCE_TYPE_DMA: |
337 | dma = &res->data.dma; | 338 | dma = &res->data.dma; |
338 | if (dma->channel_count > 0 && dma->channels[0] != (u8) -1) | 339 | if (dma->channel_count > 0 && dma->channels[0] != (u8) -1) |
339 | flags = dma_flags(dma->type, dma->bus_master, | 340 | flags = dma_flags(dev, dma->type, dma->bus_master, |
340 | dma->transfer); | 341 | dma->transfer); |
341 | else | 342 | else |
342 | flags = IORESOURCE_DISABLED; | 343 | flags = IORESOURCE_DISABLED; |
@@ -449,7 +450,7 @@ int pnpacpi_parse_allocated_resource(struct pnp_dev *dev) | |||
449 | acpi_handle handle = dev->data; | 450 | acpi_handle handle = dev->data; |
450 | acpi_status status; | 451 | acpi_status status; |
451 | 452 | ||
452 | dev_dbg(&dev->dev, "parse allocated resources\n"); | 453 | pnp_dbg(&dev->dev, "parse allocated resources\n"); |
453 | 454 | ||
454 | pnp_init_resources(dev); | 455 | pnp_init_resources(dev); |
455 | 456 | ||
@@ -477,7 +478,7 @@ static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev, | |||
477 | for (i = 0; i < p->channel_count; i++) | 478 | for (i = 0; i < p->channel_count; i++) |
478 | map |= 1 << p->channels[i]; | 479 | map |= 1 << p->channels[i]; |
479 | 480 | ||
480 | flags = dma_flags(p->type, p->bus_master, p->transfer); | 481 | flags = dma_flags(dev, p->type, p->bus_master, p->transfer); |
481 | pnp_register_dma_resource(dev, option_flags, map, flags); | 482 | pnp_register_dma_resource(dev, option_flags, map, flags); |
482 | } | 483 | } |
483 | 484 | ||
@@ -608,8 +609,8 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev, | |||
608 | unsigned char flags = 0; | 609 | unsigned char flags = 0; |
609 | 610 | ||
610 | status = acpi_resource_to_address64(r, p); | 611 | status = acpi_resource_to_address64(r, p); |
611 | if (!ACPI_SUCCESS(status)) { | 612 | if (ACPI_FAILURE(status)) { |
612 | pnp_warn("PnPACPI: failed to convert resource type %d", | 613 | dev_warn(&dev->dev, "can't convert resource type %d\n", |
613 | r->type); | 614 | r->type); |
614 | return; | 615 | return; |
615 | } | 616 | } |
@@ -735,7 +736,7 @@ int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev) | |||
735 | acpi_status status; | 736 | acpi_status status; |
736 | struct acpipnp_parse_option_s parse_data; | 737 | struct acpipnp_parse_option_s parse_data; |
737 | 738 | ||
738 | dev_dbg(&dev->dev, "parse resource options\n"); | 739 | pnp_dbg(&dev->dev, "parse resource options\n"); |
739 | 740 | ||
740 | parse_data.dev = dev; | 741 | parse_data.dev = dev; |
741 | parse_data.option_flags = 0; | 742 | parse_data.option_flags = 0; |
@@ -843,7 +844,7 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev, | |||
843 | 844 | ||
844 | if (!pnp_resource_enabled(p)) { | 845 | if (!pnp_resource_enabled(p)) { |
845 | irq->interrupt_count = 0; | 846 | irq->interrupt_count = 0; |
846 | dev_dbg(&dev->dev, " encode irq (%s)\n", | 847 | pnp_dbg(&dev->dev, " encode irq (%s)\n", |
847 | p ? "disabled" : "missing"); | 848 | p ? "disabled" : "missing"); |
848 | return; | 849 | return; |
849 | } | 850 | } |
@@ -855,7 +856,7 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev, | |||
855 | irq->interrupt_count = 1; | 856 | irq->interrupt_count = 1; |
856 | irq->interrupts[0] = p->start; | 857 | irq->interrupts[0] = p->start; |
857 | 858 | ||
858 | dev_dbg(&dev->dev, " encode irq %d %s %s %s (%d-byte descriptor)\n", | 859 | pnp_dbg(&dev->dev, " encode irq %d %s %s %s (%d-byte descriptor)\n", |
859 | (int) p->start, | 860 | (int) p->start, |
860 | triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge", | 861 | triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge", |
861 | polarity == ACPI_ACTIVE_LOW ? "low" : "high", | 862 | polarity == ACPI_ACTIVE_LOW ? "low" : "high", |
@@ -872,7 +873,7 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev, | |||
872 | 873 | ||
873 | if (!pnp_resource_enabled(p)) { | 874 | if (!pnp_resource_enabled(p)) { |
874 | extended_irq->interrupt_count = 0; | 875 | extended_irq->interrupt_count = 0; |
875 | dev_dbg(&dev->dev, " encode extended irq (%s)\n", | 876 | pnp_dbg(&dev->dev, " encode extended irq (%s)\n", |
876 | p ? "disabled" : "missing"); | 877 | p ? "disabled" : "missing"); |
877 | return; | 878 | return; |
878 | } | 879 | } |
@@ -885,7 +886,7 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev, | |||
885 | extended_irq->interrupt_count = 1; | 886 | extended_irq->interrupt_count = 1; |
886 | extended_irq->interrupts[0] = p->start; | 887 | extended_irq->interrupts[0] = p->start; |
887 | 888 | ||
888 | dev_dbg(&dev->dev, " encode irq %d %s %s %s\n", (int) p->start, | 889 | pnp_dbg(&dev->dev, " encode irq %d %s %s %s\n", (int) p->start, |
889 | triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge", | 890 | triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge", |
890 | polarity == ACPI_ACTIVE_LOW ? "low" : "high", | 891 | polarity == ACPI_ACTIVE_LOW ? "low" : "high", |
891 | extended_irq->sharable == ACPI_SHARED ? "shared" : "exclusive"); | 892 | extended_irq->sharable == ACPI_SHARED ? "shared" : "exclusive"); |
@@ -899,7 +900,7 @@ static void pnpacpi_encode_dma(struct pnp_dev *dev, | |||
899 | 900 | ||
900 | if (!pnp_resource_enabled(p)) { | 901 | if (!pnp_resource_enabled(p)) { |
901 | dma->channel_count = 0; | 902 | dma->channel_count = 0; |
902 | dev_dbg(&dev->dev, " encode dma (%s)\n", | 903 | pnp_dbg(&dev->dev, " encode dma (%s)\n", |
903 | p ? "disabled" : "missing"); | 904 | p ? "disabled" : "missing"); |
904 | return; | 905 | return; |
905 | } | 906 | } |
@@ -934,7 +935,7 @@ static void pnpacpi_encode_dma(struct pnp_dev *dev, | |||
934 | dma->channel_count = 1; | 935 | dma->channel_count = 1; |
935 | dma->channels[0] = p->start; | 936 | dma->channels[0] = p->start; |
936 | 937 | ||
937 | dev_dbg(&dev->dev, " encode dma %d " | 938 | pnp_dbg(&dev->dev, " encode dma %d " |
938 | "type %#x transfer %#x master %d\n", | 939 | "type %#x transfer %#x master %d\n", |
939 | (int) p->start, dma->type, dma->transfer, dma->bus_master); | 940 | (int) p->start, dma->type, dma->transfer, dma->bus_master); |
940 | } | 941 | } |
@@ -958,7 +959,7 @@ static void pnpacpi_encode_io(struct pnp_dev *dev, | |||
958 | io->address_length = 0; | 959 | io->address_length = 0; |
959 | } | 960 | } |
960 | 961 | ||
961 | dev_dbg(&dev->dev, " encode io %#x-%#x decode %#x\n", io->minimum, | 962 | pnp_dbg(&dev->dev, " encode io %#x-%#x decode %#x\n", io->minimum, |
962 | io->minimum + io->address_length - 1, io->io_decode); | 963 | io->minimum + io->address_length - 1, io->io_decode); |
963 | } | 964 | } |
964 | 965 | ||
@@ -976,7 +977,7 @@ static void pnpacpi_encode_fixed_io(struct pnp_dev *dev, | |||
976 | fixed_io->address_length = 0; | 977 | fixed_io->address_length = 0; |
977 | } | 978 | } |
978 | 979 | ||
979 | dev_dbg(&dev->dev, " encode fixed_io %#x-%#x\n", fixed_io->address, | 980 | pnp_dbg(&dev->dev, " encode fixed_io %#x-%#x\n", fixed_io->address, |
980 | fixed_io->address + fixed_io->address_length - 1); | 981 | fixed_io->address + fixed_io->address_length - 1); |
981 | } | 982 | } |
982 | 983 | ||
@@ -999,7 +1000,7 @@ static void pnpacpi_encode_mem24(struct pnp_dev *dev, | |||
999 | memory24->address_length = 0; | 1000 | memory24->address_length = 0; |
1000 | } | 1001 | } |
1001 | 1002 | ||
1002 | dev_dbg(&dev->dev, " encode mem24 %#x-%#x write_protect %#x\n", | 1003 | pnp_dbg(&dev->dev, " encode mem24 %#x-%#x write_protect %#x\n", |
1003 | memory24->minimum, | 1004 | memory24->minimum, |
1004 | memory24->minimum + memory24->address_length - 1, | 1005 | memory24->minimum + memory24->address_length - 1, |
1005 | memory24->write_protect); | 1006 | memory24->write_protect); |
@@ -1023,7 +1024,7 @@ static void pnpacpi_encode_mem32(struct pnp_dev *dev, | |||
1023 | memory32->alignment = 0; | 1024 | memory32->alignment = 0; |
1024 | } | 1025 | } |
1025 | 1026 | ||
1026 | dev_dbg(&dev->dev, " encode mem32 %#x-%#x write_protect %#x\n", | 1027 | pnp_dbg(&dev->dev, " encode mem32 %#x-%#x write_protect %#x\n", |
1027 | memory32->minimum, | 1028 | memory32->minimum, |
1028 | memory32->minimum + memory32->address_length - 1, | 1029 | memory32->minimum + memory32->address_length - 1, |
1029 | memory32->write_protect); | 1030 | memory32->write_protect); |
@@ -1046,7 +1047,7 @@ static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev, | |||
1046 | fixed_memory32->address_length = 0; | 1047 | fixed_memory32->address_length = 0; |
1047 | } | 1048 | } |
1048 | 1049 | ||
1049 | dev_dbg(&dev->dev, " encode fixed_mem32 %#x-%#x write_protect %#x\n", | 1050 | pnp_dbg(&dev->dev, " encode fixed_mem32 %#x-%#x write_protect %#x\n", |
1050 | fixed_memory32->address, | 1051 | fixed_memory32->address, |
1051 | fixed_memory32->address + fixed_memory32->address_length - 1, | 1052 | fixed_memory32->address + fixed_memory32->address_length - 1, |
1052 | fixed_memory32->write_protect); | 1053 | fixed_memory32->write_protect); |
@@ -1060,7 +1061,7 @@ int pnpacpi_encode_resources(struct pnp_dev *dev, struct acpi_buffer *buffer) | |||
1060 | struct acpi_resource *resource = buffer->pointer; | 1061 | struct acpi_resource *resource = buffer->pointer; |
1061 | int port = 0, irq = 0, dma = 0, mem = 0; | 1062 | int port = 0, irq = 0, dma = 0, mem = 0; |
1062 | 1063 | ||
1063 | dev_dbg(&dev->dev, "encode %d resources\n", res_cnt); | 1064 | pnp_dbg(&dev->dev, "encode %d resources\n", res_cnt); |
1064 | while (i < res_cnt) { | 1065 | while (i < res_cnt) { |
1065 | switch (resource->type) { | 1066 | switch (resource->type) { |
1066 | case ACPI_RESOURCE_TYPE_IRQ: | 1067 | case ACPI_RESOURCE_TYPE_IRQ: |
diff --git a/drivers/pnp/pnpbios/Makefile b/drivers/pnp/pnpbios/Makefile index 310e2b3a7710..3cd3ed760605 100644 --- a/drivers/pnp/pnpbios/Makefile +++ b/drivers/pnp/pnpbios/Makefile | |||
@@ -5,7 +5,3 @@ | |||
5 | pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o | 5 | pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o |
6 | 6 | ||
7 | obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y) | 7 | obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y) |
8 | |||
9 | ifeq ($(CONFIG_PNP_DEBUG),y) | ||
10 | EXTRA_CFLAGS += -DDEBUG | ||
11 | endif | ||
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index 2bfe13369df5..996f64838079 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c | |||
@@ -211,7 +211,7 @@ static int pnpbios_get_resources(struct pnp_dev *dev) | |||
211 | if (!pnpbios_is_dynamic(dev)) | 211 | if (!pnpbios_is_dynamic(dev)) |
212 | return -EPERM; | 212 | return -EPERM; |
213 | 213 | ||
214 | dev_dbg(&dev->dev, "get resources\n"); | 214 | pnp_dbg(&dev->dev, "get resources\n"); |
215 | node = kzalloc(node_info.max_node_size, GFP_KERNEL); | 215 | node = kzalloc(node_info.max_node_size, GFP_KERNEL); |
216 | if (!node) | 216 | if (!node) |
217 | return -1; | 217 | return -1; |
@@ -234,7 +234,7 @@ static int pnpbios_set_resources(struct pnp_dev *dev) | |||
234 | if (!pnpbios_is_dynamic(dev)) | 234 | if (!pnpbios_is_dynamic(dev)) |
235 | return -EPERM; | 235 | return -EPERM; |
236 | 236 | ||
237 | dev_dbg(&dev->dev, "set resources\n"); | 237 | pnp_dbg(&dev->dev, "set resources\n"); |
238 | node = kzalloc(node_info.max_node_size, GFP_KERNEL); | 238 | node = kzalloc(node_info.max_node_size, GFP_KERNEL); |
239 | if (!node) | 239 | if (!node) |
240 | return -1; | 240 | return -1; |
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index ca567671379e..87b4f49a5251 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c | |||
@@ -87,7 +87,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(struct pnp_dev *dev, | |||
87 | if (!p) | 87 | if (!p) |
88 | return NULL; | 88 | return NULL; |
89 | 89 | ||
90 | dev_dbg(&dev->dev, "parse allocated resources\n"); | 90 | pnp_dbg(&dev->dev, "parse allocated resources\n"); |
91 | 91 | ||
92 | pnp_init_resources(dev); | 92 | pnp_init_resources(dev); |
93 | 93 | ||
@@ -324,7 +324,7 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, | |||
324 | if (!p) | 324 | if (!p) |
325 | return NULL; | 325 | return NULL; |
326 | 326 | ||
327 | dev_dbg(&dev->dev, "parse resource options\n"); | 327 | pnp_dbg(&dev->dev, "parse resource options\n"); |
328 | option_flags = 0; | 328 | option_flags = 0; |
329 | while ((char *)p < (char *)end) { | 329 | while ((char *)p < (char *)end) { |
330 | 330 | ||
@@ -519,7 +519,7 @@ static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p, | |||
519 | p[10] = (len >> 8) & 0xff; | 519 | p[10] = (len >> 8) & 0xff; |
520 | p[11] = ((len >> 8) >> 8) & 0xff; | 520 | p[11] = ((len >> 8) >> 8) & 0xff; |
521 | 521 | ||
522 | dev_dbg(&dev->dev, " encode mem %#lx-%#lx\n", base, base + len - 1); | 522 | pnp_dbg(&dev->dev, " encode mem %#lx-%#lx\n", base, base + len - 1); |
523 | } | 523 | } |
524 | 524 | ||
525 | static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p, | 525 | static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p, |
@@ -549,7 +549,7 @@ static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p, | |||
549 | p[18] = (len >> 16) & 0xff; | 549 | p[18] = (len >> 16) & 0xff; |
550 | p[19] = (len >> 24) & 0xff; | 550 | p[19] = (len >> 24) & 0xff; |
551 | 551 | ||
552 | dev_dbg(&dev->dev, " encode mem32 %#lx-%#lx\n", base, base + len - 1); | 552 | pnp_dbg(&dev->dev, " encode mem32 %#lx-%#lx\n", base, base + len - 1); |
553 | } | 553 | } |
554 | 554 | ||
555 | static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p, | 555 | static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p, |
@@ -575,7 +575,7 @@ static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p, | |||
575 | p[10] = (len >> 16) & 0xff; | 575 | p[10] = (len >> 16) & 0xff; |
576 | p[11] = (len >> 24) & 0xff; | 576 | p[11] = (len >> 24) & 0xff; |
577 | 577 | ||
578 | dev_dbg(&dev->dev, " encode fixed_mem32 %#lx-%#lx\n", base, | 578 | pnp_dbg(&dev->dev, " encode fixed_mem32 %#lx-%#lx\n", base, |
579 | base + len - 1); | 579 | base + len - 1); |
580 | } | 580 | } |
581 | 581 | ||
@@ -592,7 +592,7 @@ static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p, | |||
592 | p[1] = map & 0xff; | 592 | p[1] = map & 0xff; |
593 | p[2] = (map >> 8) & 0xff; | 593 | p[2] = (map >> 8) & 0xff; |
594 | 594 | ||
595 | dev_dbg(&dev->dev, " encode irq mask %#lx\n", map); | 595 | pnp_dbg(&dev->dev, " encode irq mask %#lx\n", map); |
596 | } | 596 | } |
597 | 597 | ||
598 | static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p, | 598 | static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p, |
@@ -607,7 +607,7 @@ static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p, | |||
607 | 607 | ||
608 | p[1] = map & 0xff; | 608 | p[1] = map & 0xff; |
609 | 609 | ||
610 | dev_dbg(&dev->dev, " encode dma mask %#lx\n", map); | 610 | pnp_dbg(&dev->dev, " encode dma mask %#lx\n", map); |
611 | } | 611 | } |
612 | 612 | ||
613 | static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p, | 613 | static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p, |
@@ -630,7 +630,7 @@ static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p, | |||
630 | p[5] = (base >> 8) & 0xff; | 630 | p[5] = (base >> 8) & 0xff; |
631 | p[7] = len & 0xff; | 631 | p[7] = len & 0xff; |
632 | 632 | ||
633 | dev_dbg(&dev->dev, " encode io %#lx-%#lx\n", base, base + len - 1); | 633 | pnp_dbg(&dev->dev, " encode io %#lx-%#lx\n", base, base + len - 1); |
634 | } | 634 | } |
635 | 635 | ||
636 | static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p, | 636 | static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p, |
@@ -651,7 +651,7 @@ static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p, | |||
651 | p[2] = (base >> 8) & 0xff; | 651 | p[2] = (base >> 8) & 0xff; |
652 | p[3] = len & 0xff; | 652 | p[3] = len & 0xff; |
653 | 653 | ||
654 | dev_dbg(&dev->dev, " encode fixed_io %#lx-%#lx\n", base, | 654 | pnp_dbg(&dev->dev, " encode fixed_io %#lx-%#lx\n", base, |
655 | base + len - 1); | 655 | base + len - 1); |
656 | } | 656 | } |
657 | 657 | ||
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index c144bd575611..8473fe5ed7ff 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c | |||
@@ -337,9 +337,8 @@ void pnp_fixup_device(struct pnp_dev *dev) | |||
337 | for (f = pnp_fixups; *f->id; f++) { | 337 | for (f = pnp_fixups; *f->id; f++) { |
338 | if (!compare_pnp_id(dev->id, f->id)) | 338 | if (!compare_pnp_id(dev->id, f->id)) |
339 | continue; | 339 | continue; |
340 | #ifdef DEBUG | 340 | pnp_dbg(&dev->dev, "%s: calling %pF\n", f->id, |
341 | dev_dbg(&dev->dev, "%s: calling %pF\n", f->id, f->quirk_function); | 341 | f->quirk_function); |
342 | #endif | ||
343 | f->quirk_function(dev); | 342 | f->quirk_function(dev); |
344 | } | 343 | } |
345 | } | 344 | } |
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index dbae23acdd5b..f604061d2bb0 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c | |||
@@ -294,7 +294,7 @@ static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci, | |||
294 | u8 progif; | 294 | u8 progif; |
295 | 295 | ||
296 | if (pci->irq == irq) { | 296 | if (pci->irq == irq) { |
297 | dev_dbg(&pnp->dev, "device %s using irq %d\n", | 297 | pnp_dbg(&pnp->dev, " device %s using irq %d\n", |
298 | pci_name(pci), irq); | 298 | pci_name(pci), irq); |
299 | return 1; | 299 | return 1; |
300 | } | 300 | } |
@@ -316,7 +316,7 @@ static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci, | |||
316 | if ((progif & 0x5) != 0x5) | 316 | if ((progif & 0x5) != 0x5) |
317 | if (pci_get_legacy_ide_irq(pci, 0) == irq || | 317 | if (pci_get_legacy_ide_irq(pci, 0) == irq || |
318 | pci_get_legacy_ide_irq(pci, 1) == irq) { | 318 | pci_get_legacy_ide_irq(pci, 1) == irq) { |
319 | dev_dbg(&pnp->dev, "legacy IDE device %s " | 319 | pnp_dbg(&pnp->dev, " legacy IDE device %s " |
320 | "using irq %d\n", pci_name(pci), irq); | 320 | "using irq %d\n", pci_name(pci), irq); |
321 | return 1; | 321 | return 1; |
322 | } | 322 | } |
@@ -517,7 +517,7 @@ struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, | |||
517 | res->start = irq; | 517 | res->start = irq; |
518 | res->end = irq; | 518 | res->end = irq; |
519 | 519 | ||
520 | dev_dbg(&dev->dev, " add irq %d flags %#x\n", irq, flags); | 520 | pnp_dbg(&dev->dev, " add irq %d flags %#x\n", irq, flags); |
521 | return pnp_res; | 521 | return pnp_res; |
522 | } | 522 | } |
523 | 523 | ||
@@ -538,7 +538,7 @@ struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, | |||
538 | res->start = dma; | 538 | res->start = dma; |
539 | res->end = dma; | 539 | res->end = dma; |
540 | 540 | ||
541 | dev_dbg(&dev->dev, " add dma %d flags %#x\n", dma, flags); | 541 | pnp_dbg(&dev->dev, " add dma %d flags %#x\n", dma, flags); |
542 | return pnp_res; | 542 | return pnp_res; |
543 | } | 543 | } |
544 | 544 | ||
@@ -562,7 +562,7 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, | |||
562 | res->start = start; | 562 | res->start = start; |
563 | res->end = end; | 563 | res->end = end; |
564 | 564 | ||
565 | dev_dbg(&dev->dev, " add io %#llx-%#llx flags %#x\n", | 565 | pnp_dbg(&dev->dev, " add io %#llx-%#llx flags %#x\n", |
566 | (unsigned long long) start, (unsigned long long) end, flags); | 566 | (unsigned long long) start, (unsigned long long) end, flags); |
567 | return pnp_res; | 567 | return pnp_res; |
568 | } | 568 | } |
@@ -587,7 +587,7 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, | |||
587 | res->start = start; | 587 | res->start = start; |
588 | res->end = end; | 588 | res->end = end; |
589 | 589 | ||
590 | dev_dbg(&dev->dev, " add mem %#llx-%#llx flags %#x\n", | 590 | pnp_dbg(&dev->dev, " add mem %#llx-%#llx flags %#x\n", |
591 | (unsigned long long) start, (unsigned long long) end, flags); | 591 | (unsigned long long) start, (unsigned long long) end, flags); |
592 | return pnp_res; | 592 | return pnp_res; |
593 | } | 593 | } |
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c index b42df1620718..63087d5ce609 100644 --- a/drivers/pnp/support.c +++ b/drivers/pnp/support.c | |||
@@ -75,18 +75,17 @@ char *pnp_resource_type_name(struct resource *res) | |||
75 | 75 | ||
76 | void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) | 76 | void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) |
77 | { | 77 | { |
78 | #ifdef DEBUG | ||
79 | char buf[128]; | 78 | char buf[128]; |
80 | int len; | 79 | int len; |
81 | struct pnp_resource *pnp_res; | 80 | struct pnp_resource *pnp_res; |
82 | struct resource *res; | 81 | struct resource *res; |
83 | 82 | ||
84 | if (list_empty(&dev->resources)) { | 83 | if (list_empty(&dev->resources)) { |
85 | dev_dbg(&dev->dev, "%s: no current resources\n", desc); | 84 | pnp_dbg(&dev->dev, "%s: no current resources\n", desc); |
86 | return; | 85 | return; |
87 | } | 86 | } |
88 | 87 | ||
89 | dev_dbg(&dev->dev, "%s: current resources:\n", desc); | 88 | pnp_dbg(&dev->dev, "%s: current resources:\n", desc); |
90 | list_for_each_entry(pnp_res, &dev->resources, list) { | 89 | list_for_each_entry(pnp_res, &dev->resources, list) { |
91 | res = &pnp_res->res; | 90 | res = &pnp_res->res; |
92 | len = 0; | 91 | len = 0; |
@@ -95,7 +94,7 @@ void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) | |||
95 | pnp_resource_type_name(res)); | 94 | pnp_resource_type_name(res)); |
96 | 95 | ||
97 | if (res->flags & IORESOURCE_DISABLED) { | 96 | if (res->flags & IORESOURCE_DISABLED) { |
98 | dev_dbg(&dev->dev, "%sdisabled\n", buf); | 97 | pnp_dbg(&dev->dev, "%sdisabled\n", buf); |
99 | continue; | 98 | continue; |
100 | } | 99 | } |
101 | 100 | ||
@@ -116,9 +115,8 @@ void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) | |||
116 | res->flags); | 115 | res->flags); |
117 | break; | 116 | break; |
118 | } | 117 | } |
119 | dev_dbg(&dev->dev, "%s\n", buf); | 118 | pnp_dbg(&dev->dev, "%s\n", buf); |
120 | } | 119 | } |
121 | #endif | ||
122 | } | 120 | } |
123 | 121 | ||
124 | char *pnp_option_priority_name(struct pnp_option *option) | 122 | char *pnp_option_priority_name(struct pnp_option *option) |
@@ -136,7 +134,6 @@ char *pnp_option_priority_name(struct pnp_option *option) | |||
136 | 134 | ||
137 | void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option) | 135 | void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option) |
138 | { | 136 | { |
139 | #ifdef DEBUG | ||
140 | char buf[128]; | 137 | char buf[128]; |
141 | int len = 0, i; | 138 | int len = 0, i; |
142 | struct pnp_port *port; | 139 | struct pnp_port *port; |
@@ -208,6 +205,5 @@ void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option) | |||
208 | "flags %#x", dma->map, dma->flags); | 205 | "flags %#x", dma->map, dma->flags); |
209 | break; | 206 | break; |
210 | } | 207 | } |
211 | dev_dbg(&dev->dev, "%s\n", buf); | 208 | pnp_dbg(&dev->dev, "%s\n", buf); |
212 | #endif | ||
213 | } | 209 | } |