diff options
162 files changed, 4739 insertions, 2285 deletions
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index 76cb428435da..01c6c3d8a7e3 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt | |||
@@ -1,7 +1,7 @@ | |||
1 | ThinkPad ACPI Extras Driver | 1 | ThinkPad ACPI Extras Driver |
2 | 2 | ||
3 | Version 0.19 | 3 | Version 0.20 |
4 | January 06th, 2008 | 4 | April 09th, 2008 |
5 | 5 | ||
6 | Borislav Deianov <borislav@users.sf.net> | 6 | Borislav Deianov <borislav@users.sf.net> |
7 | Henrique de Moraes Holschuh <hmh@hmh.eng.br> | 7 | Henrique de Moraes Holschuh <hmh@hmh.eng.br> |
@@ -18,6 +18,11 @@ This driver used to be named ibm-acpi until kernel 2.6.21 and release | |||
18 | moved to the drivers/misc tree and renamed to thinkpad-acpi for kernel | 18 | moved to the drivers/misc tree and renamed to thinkpad-acpi for kernel |
19 | 2.6.22, and release 0.14. | 19 | 2.6.22, and release 0.14. |
20 | 20 | ||
21 | The driver is named "thinkpad-acpi". In some places, like module | ||
22 | names, "thinkpad_acpi" is used because of userspace issues. | ||
23 | |||
24 | "tpacpi" is used as a shorthand where "thinkpad-acpi" would be too | ||
25 | long due to length limitations on some Linux kernel versions. | ||
21 | 26 | ||
22 | Status | 27 | Status |
23 | ------ | 28 | ------ |
@@ -571,6 +576,47 @@ netlink interface and the input layer interface, and don't bother at all | |||
571 | with hotkey_report_mode. | 576 | with hotkey_report_mode. |
572 | 577 | ||
573 | 578 | ||
579 | Brightness hotkey notes: | ||
580 | |||
581 | These are the current sane choices for brightness key mapping in | ||
582 | thinkpad-acpi: | ||
583 | |||
584 | For IBM and Lenovo models *without* ACPI backlight control (the ones on | ||
585 | which thinkpad-acpi will autoload its backlight interface by default, | ||
586 | and on which ACPI video does not export a backlight interface): | ||
587 | |||
588 | 1. Don't enable or map the brightness hotkeys in thinkpad-acpi, as | ||
589 | these older firmware versions unfortunately won't respect the hotkey | ||
590 | mask for brightness keys anyway, and always reacts to them. This | ||
591 | usually work fine, unless X.org drivers are doing something to block | ||
592 | the BIOS. In that case, use (3) below. This is the default mode of | ||
593 | operation. | ||
594 | |||
595 | 2. Enable the hotkeys, but map them to something else that is NOT | ||
596 | KEY_BRIGHTNESS_UP/DOWN or any other keycode that would cause | ||
597 | userspace to try to change the backlight level, and use that as an | ||
598 | on-screen-display hint. | ||
599 | |||
600 | 3. IF AND ONLY IF X.org drivers find a way to block the firmware from | ||
601 | automatically changing the brightness, enable the hotkeys and map | ||
602 | them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN, and feed that to | ||
603 | something that calls xbacklight. thinkpad-acpi will not be able to | ||
604 | change brightness in that case either, so you should disable its | ||
605 | backlight interface. | ||
606 | |||
607 | For Lenovo models *with* ACPI backlight control: | ||
608 | |||
609 | 1. Load up ACPI video and use that. ACPI video will report ACPI | ||
610 | events for brightness change keys. Do not mess with thinkpad-acpi | ||
611 | defaults in this case. thinkpad-acpi should not have anything to do | ||
612 | with backlight events in a scenario where ACPI video is loaded: | ||
613 | brightness hotkeys must be disabled, and the backlight interface is | ||
614 | to be kept disabled as well. This is the default mode of operation. | ||
615 | |||
616 | 2. Do *NOT* load up ACPI video, enable the hotkeys in thinkpad-acpi, | ||
617 | and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN. Process | ||
618 | these keys on userspace somehow (e.g. by calling xbacklight). | ||
619 | |||
574 | Bluetooth | 620 | Bluetooth |
575 | --------- | 621 | --------- |
576 | 622 | ||
@@ -647,16 +693,31 @@ while others are still having problems. For more information: | |||
647 | 693 | ||
648 | https://bugs.freedesktop.org/show_bug.cgi?id=2000 | 694 | https://bugs.freedesktop.org/show_bug.cgi?id=2000 |
649 | 695 | ||
650 | ThinkLight control -- /proc/acpi/ibm/light | 696 | ThinkLight control |
651 | ------------------------------------------ | 697 | ------------------ |
698 | |||
699 | procfs: /proc/acpi/ibm/light | ||
700 | sysfs attributes: as per LED class, for the "tpacpi::thinklight" LED | ||
652 | 701 | ||
653 | The current status of the ThinkLight can be found in this file. A few | 702 | procfs notes: |
654 | models which do not make the status available will show it as | 703 | |
655 | "unknown". The available commands are: | 704 | The ThinkLight status can be read and set through the procfs interface. A |
705 | few models which do not make the status available will show the ThinkLight | ||
706 | status as "unknown". The available commands are: | ||
656 | 707 | ||
657 | echo on > /proc/acpi/ibm/light | 708 | echo on > /proc/acpi/ibm/light |
658 | echo off > /proc/acpi/ibm/light | 709 | echo off > /proc/acpi/ibm/light |
659 | 710 | ||
711 | sysfs notes: | ||
712 | |||
713 | The ThinkLight sysfs interface is documented by the LED class | ||
714 | documentation, in Documentation/leds-class.txt. The ThinkLight LED name | ||
715 | is "tpacpi::thinklight". | ||
716 | |||
717 | Due to limitations in the sysfs LED class, if the status of the thinklight | ||
718 | cannot be read or if it is unknown, thinkpad-acpi will report it as "off". | ||
719 | It is impossible to know if the status returned through sysfs is valid. | ||
720 | |||
660 | Docking / undocking -- /proc/acpi/ibm/dock | 721 | Docking / undocking -- /proc/acpi/ibm/dock |
661 | ------------------------------------------ | 722 | ------------------------------------------ |
662 | 723 | ||
@@ -815,28 +876,63 @@ The cmos command interface is prone to firmware split-brain problems, as | |||
815 | in newer ThinkPads it is just a compatibility layer. Do not use it, it is | 876 | in newer ThinkPads it is just a compatibility layer. Do not use it, it is |
816 | exported just as a debug tool. | 877 | exported just as a debug tool. |
817 | 878 | ||
818 | LED control -- /proc/acpi/ibm/led | 879 | LED control |
819 | --------------------------------- | 880 | ----------- |
881 | |||
882 | procfs: /proc/acpi/ibm/led | ||
883 | sysfs attributes: as per LED class, see below for names | ||
884 | |||
885 | Some of the LED indicators can be controlled through this feature. On | ||
886 | some older ThinkPad models, it is possible to query the status of the | ||
887 | LED indicators as well. Newer ThinkPads cannot query the real status | ||
888 | of the LED indicators. | ||
820 | 889 | ||
821 | Some of the LED indicators can be controlled through this feature. The | 890 | procfs notes: |
822 | available commands are: | 891 | |
892 | The available commands are: | ||
823 | 893 | ||
824 | echo '<led number> on' >/proc/acpi/ibm/led | 894 | echo '<LED number> on' >/proc/acpi/ibm/led |
825 | echo '<led number> off' >/proc/acpi/ibm/led | 895 | echo '<LED number> off' >/proc/acpi/ibm/led |
826 | echo '<led number> blink' >/proc/acpi/ibm/led | 896 | echo '<LED number> blink' >/proc/acpi/ibm/led |
827 | 897 | ||
828 | The <led number> range is 0 to 7. The set of LEDs that can be | 898 | The <LED number> range is 0 to 7. The set of LEDs that can be |
829 | controlled varies from model to model. Here is the mapping on the X40: | 899 | controlled varies from model to model. Here is the common ThinkPad |
900 | mapping: | ||
830 | 901 | ||
831 | 0 - power | 902 | 0 - power |
832 | 1 - battery (orange) | 903 | 1 - battery (orange) |
833 | 2 - battery (green) | 904 | 2 - battery (green) |
834 | 3 - UltraBase | 905 | 3 - UltraBase/dock |
835 | 4 - UltraBay | 906 | 4 - UltraBay |
907 | 5 - UltraBase battery slot | ||
908 | 6 - (unknown) | ||
836 | 7 - standby | 909 | 7 - standby |
837 | 910 | ||
838 | All of the above can be turned on and off and can be made to blink. | 911 | All of the above can be turned on and off and can be made to blink. |
839 | 912 | ||
913 | sysfs notes: | ||
914 | |||
915 | The ThinkPad LED sysfs interface is described in detail by the LED class | ||
916 | documentation, in Documentation/leds-class.txt. | ||
917 | |||
918 | The leds are named (in LED ID order, from 0 to 7): | ||
919 | "tpacpi::power", "tpacpi:orange:batt", "tpacpi:green:batt", | ||
920 | "tpacpi::dock_active", "tpacpi::bay_active", "tpacpi::dock_batt", | ||
921 | "tpacpi::unknown_led", "tpacpi::standby". | ||
922 | |||
923 | Due to limitations in the sysfs LED class, if the status of the LED | ||
924 | indicators cannot be read due to an error, thinkpad-acpi will report it as | ||
925 | a brightness of zero (same as LED off). | ||
926 | |||
927 | If the thinkpad firmware doesn't support reading the current status, | ||
928 | trying to read the current LED brightness will just return whatever | ||
929 | brightness was last written to that attribute. | ||
930 | |||
931 | These LEDs can blink using hardware acceleration. To request that a | ||
932 | ThinkPad indicator LED should blink in hardware accelerated mode, use the | ||
933 | "timer" trigger, and leave the delay_on and delay_off parameters set to | ||
934 | zero (to request hardware acceleration autodetection). | ||
935 | |||
840 | ACPI sounds -- /proc/acpi/ibm/beep | 936 | ACPI sounds -- /proc/acpi/ibm/beep |
841 | ---------------------------------- | 937 | ---------------------------------- |
842 | 938 | ||
@@ -1090,6 +1186,15 @@ it there will be the following attributes: | |||
1090 | dim the display. | 1186 | dim the display. |
1091 | 1187 | ||
1092 | 1188 | ||
1189 | WARNING: | ||
1190 | |||
1191 | Whatever you do, do NOT ever call thinkpad-acpi backlight-level change | ||
1192 | interface and the ACPI-based backlight level change interface | ||
1193 | (available on newer BIOSes, and driven by the Linux ACPI video driver) | ||
1194 | at the same time. The two will interact in bad ways, do funny things, | ||
1195 | and maybe reduce the life of the backlight lamps by needlessly kicking | ||
1196 | its level up and down at every change. | ||
1197 | |||
1093 | Volume control -- /proc/acpi/ibm/volume | 1198 | Volume control -- /proc/acpi/ibm/volume |
1094 | --------------------------------------- | 1199 | --------------------------------------- |
1095 | 1200 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index c1dd1ae7b133..37debda36661 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1531,6 +1531,13 @@ L: bluesmoke-devel@lists.sourceforge.net | |||
1531 | W: bluesmoke.sourceforge.net | 1531 | W: bluesmoke.sourceforge.net |
1532 | S: Maintained | 1532 | S: Maintained |
1533 | 1533 | ||
1534 | EEEPC LAPTOP EXTRAS DRIVER | ||
1535 | P: Corentin Chary | ||
1536 | M: corentincj@iksaif.net | ||
1537 | L: acpi4asus-user@lists.sourceforge.net | ||
1538 | W: http://sourceforge.net/projects/acpi4asus | ||
1539 | S: Maintained | ||
1540 | |||
1534 | EEPRO100 NETWORK DRIVER | 1541 | EEPRO100 NETWORK DRIVER |
1535 | P: Andrey V. Savochkin | 1542 | P: Andrey V. Savochkin |
1536 | M: saw@saw.sw.com.sg | 1543 | M: saw@saw.sw.com.sg |
diff --git a/arch/frv/kernel/pm.c b/arch/frv/kernel/pm.c index c57ce3f1f2e2..73f3aeefd203 100644 --- a/arch/frv/kernel/pm.c +++ b/arch/frv/kernel/pm.c | |||
@@ -163,14 +163,11 @@ static int sysctl_pm_do_suspend(ctl_table *ctl, int write, struct file *filp, | |||
163 | if ((mode != 1) && (mode != 5)) | 163 | if ((mode != 1) && (mode != 5)) |
164 | return -EINVAL; | 164 | return -EINVAL; |
165 | 165 | ||
166 | retval = pm_send_all(PM_SUSPEND, (void *)3); | ||
167 | |||
168 | if (retval == 0) { | 166 | if (retval == 0) { |
169 | if (mode == 5) | 167 | if (mode == 5) |
170 | retval = pm_do_bus_sleep(); | 168 | retval = pm_do_bus_sleep(); |
171 | else | 169 | else |
172 | retval = pm_do_suspend(); | 170 | retval = pm_do_suspend(); |
173 | pm_send_all(PM_RESUME, (void *)0); | ||
174 | } | 171 | } |
175 | 172 | ||
176 | return retval; | 173 | return retval; |
@@ -183,9 +180,6 @@ static int try_set_cmode(int new_cmode) | |||
183 | if (!(clock_cmodes_permitted & (1<<new_cmode))) | 180 | if (!(clock_cmodes_permitted & (1<<new_cmode))) |
184 | return -EINVAL; | 181 | return -EINVAL; |
185 | 182 | ||
186 | /* tell all the drivers we're suspending */ | ||
187 | pm_send_all(PM_SUSPEND, (void *)3); | ||
188 | |||
189 | /* now change cmode */ | 183 | /* now change cmode */ |
190 | local_irq_disable(); | 184 | local_irq_disable(); |
191 | frv_dma_pause_all(); | 185 | frv_dma_pause_all(); |
@@ -201,8 +195,6 @@ static int try_set_cmode(int new_cmode) | |||
201 | frv_dma_resume_all(); | 195 | frv_dma_resume_all(); |
202 | local_irq_enable(); | 196 | local_irq_enable(); |
203 | 197 | ||
204 | /* tell all the drivers we're resuming */ | ||
205 | pm_send_all(PM_RESUME, (void *)0); | ||
206 | return 0; | 198 | return 0; |
207 | } | 199 | } |
208 | 200 | ||
diff --git a/arch/mips/au1000/common/power.c b/arch/mips/au1000/common/power.c index 812a5f8b7d26..a8cd2c1b9e1b 100644 --- a/arch/mips/au1000/common/power.c +++ b/arch/mips/au1000/common/power.c | |||
@@ -251,7 +251,6 @@ int au_sleep(void) | |||
251 | static int pm_do_sleep(ctl_table * ctl, int write, struct file *file, | 251 | static int pm_do_sleep(ctl_table * ctl, int write, struct file *file, |
252 | void __user *buffer, size_t * len, loff_t *ppos) | 252 | void __user *buffer, size_t * len, loff_t *ppos) |
253 | { | 253 | { |
254 | int retval = 0; | ||
255 | #ifdef SLEEP_TEST_TIMEOUT | 254 | #ifdef SLEEP_TEST_TIMEOUT |
256 | #define TMPBUFLEN2 16 | 255 | #define TMPBUFLEN2 16 |
257 | char buf[TMPBUFLEN2], *p; | 256 | char buf[TMPBUFLEN2], *p; |
@@ -271,36 +270,12 @@ static int pm_do_sleep(ctl_table * ctl, int write, struct file *file, | |||
271 | p = buf; | 270 | p = buf; |
272 | sleep_ticks = simple_strtoul(p, &p, 0); | 271 | sleep_ticks = simple_strtoul(p, &p, 0); |
273 | #endif | 272 | #endif |
274 | retval = pm_send_all(PM_SUSPEND, (void *) 2); | ||
275 | |||
276 | if (retval) | ||
277 | return retval; | ||
278 | 273 | ||
279 | au_sleep(); | 274 | au_sleep(); |
280 | retval = pm_send_all(PM_RESUME, (void *) 0); | ||
281 | } | 275 | } |
282 | return retval; | 276 | return 0; |
283 | } | ||
284 | |||
285 | static int pm_do_suspend(ctl_table * ctl, int write, struct file *file, | ||
286 | void __user *buffer, size_t * len, loff_t *ppos) | ||
287 | { | ||
288 | int retval = 0; | ||
289 | |||
290 | if (!write) { | ||
291 | *len = 0; | ||
292 | } else { | ||
293 | retval = pm_send_all(PM_SUSPEND, (void *) 2); | ||
294 | if (retval) | ||
295 | return retval; | ||
296 | suspend_mode = 1; | ||
297 | |||
298 | retval = pm_send_all(PM_RESUME, (void *) 0); | ||
299 | } | ||
300 | return retval; | ||
301 | } | 277 | } |
302 | 278 | ||
303 | |||
304 | static int pm_do_freq(ctl_table * ctl, int write, struct file *file, | 279 | static int pm_do_freq(ctl_table * ctl, int write, struct file *file, |
305 | void __user *buffer, size_t * len, loff_t *ppos) | 280 | void __user *buffer, size_t * len, loff_t *ppos) |
306 | { | 281 | { |
@@ -414,14 +389,6 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file, | |||
414 | 389 | ||
415 | static struct ctl_table pm_table[] = { | 390 | static struct ctl_table pm_table[] = { |
416 | { | 391 | { |
417 | .ctl_name = CTL_UNNUMBERED, | ||
418 | .procname = "suspend", | ||
419 | .data = NULL, | ||
420 | .maxlen = 0, | ||
421 | .mode = 0600, | ||
422 | .proc_handler = &pm_do_suspend | ||
423 | }, | ||
424 | { | ||
425 | .ctl_name = CTL_UNNUMBERED, | 392 | .ctl_name = CTL_UNNUMBERED, |
426 | .procname = "sleep", | 393 | .procname = "sleep", |
427 | .data = NULL, | 394 | .data = NULL, |
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index e4ea362e8480..bf9290e29013 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c | |||
@@ -1192,19 +1192,6 @@ static int suspend(int vetoable) | |||
1192 | int err; | 1192 | int err; |
1193 | struct apm_user *as; | 1193 | struct apm_user *as; |
1194 | 1194 | ||
1195 | if (pm_send_all(PM_SUSPEND, (void *)3)) { | ||
1196 | /* Vetoed */ | ||
1197 | if (vetoable) { | ||
1198 | if (apm_info.connection_version > 0x100) | ||
1199 | set_system_power_state(APM_STATE_REJECT); | ||
1200 | err = -EBUSY; | ||
1201 | ignore_sys_suspend = 0; | ||
1202 | printk(KERN_WARNING "apm: suspend was vetoed.\n"); | ||
1203 | goto out; | ||
1204 | } | ||
1205 | printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n"); | ||
1206 | } | ||
1207 | |||
1208 | device_suspend(PMSG_SUSPEND); | 1195 | device_suspend(PMSG_SUSPEND); |
1209 | local_irq_disable(); | 1196 | local_irq_disable(); |
1210 | device_power_down(PMSG_SUSPEND); | 1197 | device_power_down(PMSG_SUSPEND); |
@@ -1227,9 +1214,7 @@ static int suspend(int vetoable) | |||
1227 | device_power_up(); | 1214 | device_power_up(); |
1228 | local_irq_enable(); | 1215 | local_irq_enable(); |
1229 | device_resume(); | 1216 | device_resume(); |
1230 | pm_send_all(PM_RESUME, (void *)0); | ||
1231 | queue_event(APM_NORMAL_RESUME, NULL); | 1217 | queue_event(APM_NORMAL_RESUME, NULL); |
1232 | out: | ||
1233 | spin_lock(&user_list_lock); | 1218 | spin_lock(&user_list_lock); |
1234 | for (as = user_list; as != NULL; as = as->next) { | 1219 | for (as = user_list; as != NULL; as = as->next) { |
1235 | as->suspend_wait = 0; | 1220 | as->suspend_wait = 0; |
@@ -1340,7 +1325,6 @@ static void check_events(void) | |||
1340 | if ((event != APM_NORMAL_RESUME) | 1325 | if ((event != APM_NORMAL_RESUME) |
1341 | || (ignore_normal_resume == 0)) { | 1326 | || (ignore_normal_resume == 0)) { |
1342 | device_resume(); | 1327 | device_resume(); |
1343 | pm_send_all(PM_RESUME, (void *)0); | ||
1344 | queue_event(event, NULL); | 1328 | queue_event(event, NULL); |
1345 | } | 1329 | } |
1346 | ignore_normal_resume = 0; | 1330 | ignore_normal_resume = 0; |
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c index 1fa86811b8ee..d2fc94161848 100644 --- a/drivers/acpi/bay.c +++ b/drivers/acpi/bay.c | |||
@@ -201,6 +201,7 @@ static int is_ejectable_bay(acpi_handle handle) | |||
201 | return 0; | 201 | return 0; |
202 | } | 202 | } |
203 | 203 | ||
204 | #if 0 | ||
204 | /** | 205 | /** |
205 | * eject_removable_drive - try to eject this drive | 206 | * eject_removable_drive - try to eject this drive |
206 | * @dev : the device structure of the drive | 207 | * @dev : the device structure of the drive |
@@ -225,6 +226,7 @@ int eject_removable_drive(struct device *dev) | |||
225 | return 0; | 226 | return 0; |
226 | } | 227 | } |
227 | EXPORT_SYMBOL_GPL(eject_removable_drive); | 228 | EXPORT_SYMBOL_GPL(eject_removable_drive); |
229 | #endif /* 0 */ | ||
228 | 230 | ||
229 | static int acpi_bay_add_fs(struct bay *bay) | 231 | static int acpi_bay_add_fs(struct bay *bay) |
230 | { | 232 | { |
diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c index f049639bac35..c78078315be9 100644 --- a/drivers/acpi/dispatcher/dsfield.c +++ b/drivers/acpi/dispatcher/dsfield.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -89,12 +89,16 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, | |||
89 | 89 | ||
90 | ACPI_FUNCTION_TRACE(ds_create_buffer_field); | 90 | ACPI_FUNCTION_TRACE(ds_create_buffer_field); |
91 | 91 | ||
92 | /* Get the name_string argument */ | 92 | /* |
93 | 93 | * Get the name_string argument (name of the new buffer_field) | |
94 | */ | ||
94 | if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { | 95 | if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { |
96 | |||
97 | /* For create_field, name is the 4th argument */ | ||
98 | |||
95 | arg = acpi_ps_get_arg(op, 3); | 99 | arg = acpi_ps_get_arg(op, 3); |
96 | } else { | 100 | } else { |
97 | /* Create Bit/Byte/Word/Dword field */ | 101 | /* For all other create_xXXField operators, name is the 3rd argument */ |
98 | 102 | ||
99 | arg = acpi_ps_get_arg(op, 2); | 103 | arg = acpi_ps_get_arg(op, 2); |
100 | } | 104 | } |
@@ -107,26 +111,30 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, | |||
107 | node = walk_state->deferred_node; | 111 | node = walk_state->deferred_node; |
108 | status = AE_OK; | 112 | status = AE_OK; |
109 | } else { | 113 | } else { |
110 | /* | 114 | /* Execute flag should always be set when this function is entered */ |
111 | * During the load phase, we want to enter the name of the field into | 115 | |
112 | * the namespace. During the execute phase (when we evaluate the size | 116 | if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) { |
113 | * operand), we want to lookup the name | 117 | return_ACPI_STATUS(AE_AML_INTERNAL); |
114 | */ | ||
115 | if (walk_state->parse_flags & ACPI_PARSE_EXECUTE) { | ||
116 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE; | ||
117 | } else { | ||
118 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | | ||
119 | ACPI_NS_ERROR_IF_FOUND; | ||
120 | } | 118 | } |
121 | 119 | ||
122 | /* | 120 | /* Creating new namespace node, should not already exist */ |
123 | * Enter the name_string into the namespace | 121 | |
124 | */ | 122 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | |
123 | ACPI_NS_ERROR_IF_FOUND; | ||
124 | |||
125 | /* Mark node temporary if we are executing a method */ | ||
126 | |||
127 | if (walk_state->method_node) { | ||
128 | flags |= ACPI_NS_TEMPORARY; | ||
129 | } | ||
130 | |||
131 | /* Enter the name_string into the namespace */ | ||
132 | |||
125 | status = | 133 | status = |
126 | acpi_ns_lookup(walk_state->scope_info, | 134 | acpi_ns_lookup(walk_state->scope_info, |
127 | arg->common.value.string, ACPI_TYPE_ANY, | 135 | arg->common.value.string, ACPI_TYPE_ANY, |
128 | ACPI_IMODE_LOAD_PASS1, flags, walk_state, | 136 | ACPI_IMODE_LOAD_PASS1, flags, walk_state, |
129 | &(node)); | 137 | &node); |
130 | if (ACPI_FAILURE(status)) { | 138 | if (ACPI_FAILURE(status)) { |
131 | ACPI_ERROR_NAMESPACE(arg->common.value.string, status); | 139 | ACPI_ERROR_NAMESPACE(arg->common.value.string, status); |
132 | return_ACPI_STATUS(status); | 140 | return_ACPI_STATUS(status); |
@@ -136,13 +144,13 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, | |||
136 | /* | 144 | /* |
137 | * We could put the returned object (Node) on the object stack for later, | 145 | * We could put the returned object (Node) on the object stack for later, |
138 | * but for now, we will put it in the "op" object that the parser uses, | 146 | * but for now, we will put it in the "op" object that the parser uses, |
139 | * so we can get it again at the end of this scope | 147 | * so we can get it again at the end of this scope. |
140 | */ | 148 | */ |
141 | op->common.node = node; | 149 | op->common.node = node; |
142 | 150 | ||
143 | /* | 151 | /* |
144 | * If there is no object attached to the node, this node was just created | 152 | * If there is no object attached to the node, this node was just created |
145 | * and we need to create the field object. Otherwise, this was a lookup | 153 | * and we need to create the field object. Otherwise, this was a lookup |
146 | * of an existing node and we don't want to create the field object again. | 154 | * of an existing node and we don't want to create the field object again. |
147 | */ | 155 | */ |
148 | obj_desc = acpi_ns_get_attached_object(node); | 156 | obj_desc = acpi_ns_get_attached_object(node); |
@@ -164,9 +172,8 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, | |||
164 | } | 172 | } |
165 | 173 | ||
166 | /* | 174 | /* |
167 | * Remember location in AML stream of the field unit | 175 | * Remember location in AML stream of the field unit opcode and operands -- |
168 | * opcode and operands -- since the buffer and index | 176 | * since the buffer and index operands must be evaluated. |
169 | * operands must be evaluated. | ||
170 | */ | 177 | */ |
171 | second_desc = obj_desc->common.next_object; | 178 | second_desc = obj_desc->common.next_object; |
172 | second_desc->extra.aml_start = op->named.data; | 179 | second_desc->extra.aml_start = op->named.data; |
@@ -261,7 +268,7 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, | |||
261 | 268 | ||
262 | case AML_INT_NAMEDFIELD_OP: | 269 | case AML_INT_NAMEDFIELD_OP: |
263 | 270 | ||
264 | /* Lookup the name */ | 271 | /* Lookup the name, it should already exist */ |
265 | 272 | ||
266 | status = acpi_ns_lookup(walk_state->scope_info, | 273 | status = acpi_ns_lookup(walk_state->scope_info, |
267 | (char *)&arg->named.name, | 274 | (char *)&arg->named.name, |
@@ -272,20 +279,23 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, | |||
272 | if (ACPI_FAILURE(status)) { | 279 | if (ACPI_FAILURE(status)) { |
273 | ACPI_ERROR_NAMESPACE((char *)&arg->named.name, | 280 | ACPI_ERROR_NAMESPACE((char *)&arg->named.name, |
274 | status); | 281 | status); |
275 | if (status != AE_ALREADY_EXISTS) { | 282 | return_ACPI_STATUS(status); |
276 | return_ACPI_STATUS(status); | ||
277 | } | ||
278 | |||
279 | /* Already exists, ignore error */ | ||
280 | } else { | 283 | } else { |
281 | arg->common.node = info->field_node; | 284 | arg->common.node = info->field_node; |
282 | info->field_bit_length = arg->common.value.size; | 285 | info->field_bit_length = arg->common.value.size; |
283 | 286 | ||
284 | /* Create and initialize an object for the new Field Node */ | 287 | /* |
285 | 288 | * If there is no object attached to the node, this node was | |
286 | status = acpi_ex_prep_field_value(info); | 289 | * just created and we need to create the field object. |
287 | if (ACPI_FAILURE(status)) { | 290 | * Otherwise, this was a lookup of an existing node and we |
288 | return_ACPI_STATUS(status); | 291 | * don't want to create the field object again. |
292 | */ | ||
293 | if (!acpi_ns_get_attached_object | ||
294 | (info->field_node)) { | ||
295 | status = acpi_ex_prep_field_value(info); | ||
296 | if (ACPI_FAILURE(status)) { | ||
297 | return_ACPI_STATUS(status); | ||
298 | } | ||
289 | } | 299 | } |
290 | } | 300 | } |
291 | 301 | ||
@@ -399,9 +409,27 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
399 | union acpi_parse_object *arg = NULL; | 409 | union acpi_parse_object *arg = NULL; |
400 | struct acpi_namespace_node *node; | 410 | struct acpi_namespace_node *node; |
401 | u8 type = 0; | 411 | u8 type = 0; |
412 | u32 flags; | ||
402 | 413 | ||
403 | ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op); | 414 | ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op); |
404 | 415 | ||
416 | /* Execute flag should always be set when this function is entered */ | ||
417 | |||
418 | if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) { | ||
419 | if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) { | ||
420 | |||
421 | /* bank_field Op is deferred, just return OK */ | ||
422 | |||
423 | return_ACPI_STATUS(AE_OK); | ||
424 | } | ||
425 | |||
426 | return_ACPI_STATUS(AE_AML_INTERNAL); | ||
427 | } | ||
428 | |||
429 | /* | ||
430 | * Get the field_list argument for this opcode. This is the start of the | ||
431 | * list of field elements. | ||
432 | */ | ||
405 | switch (walk_state->opcode) { | 433 | switch (walk_state->opcode) { |
406 | case AML_FIELD_OP: | 434 | case AML_FIELD_OP: |
407 | arg = acpi_ps_get_arg(op, 2); | 435 | arg = acpi_ps_get_arg(op, 2); |
@@ -422,20 +450,33 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
422 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 450 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
423 | } | 451 | } |
424 | 452 | ||
453 | if (!arg) { | ||
454 | return_ACPI_STATUS(AE_AML_NO_OPERAND); | ||
455 | } | ||
456 | |||
457 | /* Creating new namespace node(s), should not already exist */ | ||
458 | |||
459 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | | ||
460 | ACPI_NS_ERROR_IF_FOUND; | ||
461 | |||
462 | /* Mark node(s) temporary if we are executing a method */ | ||
463 | |||
464 | if (walk_state->method_node) { | ||
465 | flags |= ACPI_NS_TEMPORARY; | ||
466 | } | ||
467 | |||
425 | /* | 468 | /* |
426 | * Walk the list of entries in the field_list | 469 | * Walk the list of entries in the field_list |
427 | */ | 470 | */ |
428 | while (arg) { | 471 | while (arg) { |
429 | 472 | /* | |
430 | /* Ignore OFFSET and ACCESSAS terms here */ | 473 | * Ignore OFFSET and ACCESSAS terms here; we are only interested in the |
431 | 474 | * field names in order to enter them into the namespace. | |
475 | */ | ||
432 | if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { | 476 | if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { |
433 | status = acpi_ns_lookup(walk_state->scope_info, | 477 | status = acpi_ns_lookup(walk_state->scope_info, |
434 | (char *)&arg->named.name, | 478 | (char *)&arg->named.name, type, |
435 | type, ACPI_IMODE_LOAD_PASS1, | 479 | ACPI_IMODE_LOAD_PASS1, flags, |
436 | ACPI_NS_NO_UPSEARCH | | ||
437 | ACPI_NS_DONT_OPEN_SCOPE | | ||
438 | ACPI_NS_ERROR_IF_FOUND, | ||
439 | walk_state, &node); | 480 | walk_state, &node); |
440 | if (ACPI_FAILURE(status)) { | 481 | if (ACPI_FAILURE(status)) { |
441 | ACPI_ERROR_NAMESPACE((char *)&arg->named.name, | 482 | ACPI_ERROR_NAMESPACE((char *)&arg->named.name, |
@@ -452,7 +493,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
452 | arg->common.node = node; | 493 | arg->common.node = node; |
453 | } | 494 | } |
454 | 495 | ||
455 | /* Move to next field in the list */ | 496 | /* Get the next field element in the list */ |
456 | 497 | ||
457 | arg = arg->common.next; | 498 | arg = arg->common.next; |
458 | } | 499 | } |
@@ -466,7 +507,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
466 | * | 507 | * |
467 | * PARAMETERS: Op - Op containing the Field definition and args | 508 | * PARAMETERS: Op - Op containing the Field definition and args |
468 | * region_node - Object for the containing Operation Region | 509 | * region_node - Object for the containing Operation Region |
469 | * ` walk_state - Current method state | 510 | * walk_state - Current method state |
470 | * | 511 | * |
471 | * RETURN: Status | 512 | * RETURN: Status |
472 | * | 513 | * |
@@ -513,36 +554,13 @@ acpi_ds_create_bank_field(union acpi_parse_object *op, | |||
513 | return_ACPI_STATUS(status); | 554 | return_ACPI_STATUS(status); |
514 | } | 555 | } |
515 | 556 | ||
516 | /* Third arg is the bank_value */ | 557 | /* |
517 | 558 | * Third arg is the bank_value | |
518 | /* TBD: This arg is a term_arg, not a constant, and must be evaluated */ | 559 | * This arg is a term_arg, not a constant |
519 | 560 | * It will be evaluated later, by acpi_ds_eval_bank_field_operands | |
561 | */ | ||
520 | arg = arg->common.next; | 562 | arg = arg->common.next; |
521 | 563 | ||
522 | /* Currently, only the following constants are supported */ | ||
523 | |||
524 | switch (arg->common.aml_opcode) { | ||
525 | case AML_ZERO_OP: | ||
526 | info.bank_value = 0; | ||
527 | break; | ||
528 | |||
529 | case AML_ONE_OP: | ||
530 | info.bank_value = 1; | ||
531 | break; | ||
532 | |||
533 | case AML_BYTE_OP: | ||
534 | case AML_WORD_OP: | ||
535 | case AML_DWORD_OP: | ||
536 | case AML_QWORD_OP: | ||
537 | info.bank_value = (u32) arg->common.value.integer; | ||
538 | break; | ||
539 | |||
540 | default: | ||
541 | info.bank_value = 0; | ||
542 | ACPI_ERROR((AE_INFO, | ||
543 | "Non-constant BankValue for BankField is not implemented")); | ||
544 | } | ||
545 | |||
546 | /* Fourth arg is the field flags */ | 564 | /* Fourth arg is the field flags */ |
547 | 565 | ||
548 | arg = arg->common.next; | 566 | arg = arg->common.next; |
@@ -553,8 +571,17 @@ acpi_ds_create_bank_field(union acpi_parse_object *op, | |||
553 | info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD; | 571 | info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD; |
554 | info.region_node = region_node; | 572 | info.region_node = region_node; |
555 | 573 | ||
556 | status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); | 574 | /* |
575 | * Use Info.data_register_node to store bank_field Op | ||
576 | * It's safe because data_register_node will never be used when create bank field | ||
577 | * We store aml_start and aml_length in the bank_field Op for late evaluation | ||
578 | * Used in acpi_ex_prep_field_value(Info) | ||
579 | * | ||
580 | * TBD: Or, should we add a field in struct acpi_create_field_info, like "void *ParentOp"? | ||
581 | */ | ||
582 | info.data_register_node = (struct acpi_namespace_node *)op; | ||
557 | 583 | ||
584 | status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); | ||
558 | return_ACPI_STATUS(status); | 585 | return_ACPI_STATUS(status); |
559 | } | 586 | } |
560 | 587 | ||
diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c index af923c388520..610b1ee102b0 100644 --- a/drivers/acpi/dispatcher/dsinit.c +++ b/drivers/acpi/dispatcher/dsinit.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index 1cbe61905824..e48a3ea03117 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -42,7 +42,6 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acparser.h> | ||
46 | #include <acpi/amlcode.h> | 45 | #include <acpi/amlcode.h> |
47 | #include <acpi/acdispat.h> | 46 | #include <acpi/acdispat.h> |
48 | #include <acpi/acinterp.h> | 47 | #include <acpi/acinterp.h> |
@@ -102,7 +101,7 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state) | |||
102 | walk_state->opcode, | 101 | walk_state->opcode, |
103 | walk_state->aml_offset, | 102 | walk_state->aml_offset, |
104 | NULL); | 103 | NULL); |
105 | (void)acpi_ex_enter_interpreter(); | 104 | acpi_ex_enter_interpreter(); |
106 | } | 105 | } |
107 | #ifdef ACPI_DISASSEMBLER | 106 | #ifdef ACPI_DISASSEMBLER |
108 | if (ACPI_FAILURE(status)) { | 107 | if (ACPI_FAILURE(status)) { |
@@ -232,9 +231,9 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, | |||
232 | * recursive call. | 231 | * recursive call. |
233 | */ | 232 | */ |
234 | if (!walk_state || | 233 | if (!walk_state || |
235 | !obj_desc->method.mutex->mutex.owner_thread || | 234 | !obj_desc->method.mutex->mutex.thread_id || |
236 | (walk_state->thread != | 235 | (walk_state->thread->thread_id != |
237 | obj_desc->method.mutex->mutex.owner_thread)) { | 236 | obj_desc->method.mutex->mutex.thread_id)) { |
238 | /* | 237 | /* |
239 | * Acquire the method mutex. This releases the interpreter if we | 238 | * Acquire the method mutex. This releases the interpreter if we |
240 | * block (and reacquires it before it returns) | 239 | * block (and reacquires it before it returns) |
@@ -254,8 +253,8 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, | |||
254 | original_sync_level = | 253 | original_sync_level = |
255 | walk_state->thread->current_sync_level; | 254 | walk_state->thread->current_sync_level; |
256 | 255 | ||
257 | obj_desc->method.mutex->mutex.owner_thread = | 256 | obj_desc->method.mutex->mutex.thread_id = |
258 | walk_state->thread; | 257 | walk_state->thread->thread_id; |
259 | walk_state->thread->current_sync_level = | 258 | walk_state->thread->current_sync_level = |
260 | obj_desc->method.sync_level; | 259 | obj_desc->method.sync_level; |
261 | } else { | 260 | } else { |
@@ -535,8 +534,6 @@ void | |||
535 | acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | 534 | acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, |
536 | struct acpi_walk_state *walk_state) | 535 | struct acpi_walk_state *walk_state) |
537 | { | 536 | { |
538 | struct acpi_namespace_node *method_node; | ||
539 | acpi_status status; | ||
540 | 537 | ||
541 | ACPI_FUNCTION_TRACE_PTR(ds_terminate_control_method, walk_state); | 538 | ACPI_FUNCTION_TRACE_PTR(ds_terminate_control_method, walk_state); |
542 | 539 | ||
@@ -551,34 +548,26 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | |||
551 | /* Delete all arguments and locals */ | 548 | /* Delete all arguments and locals */ |
552 | 549 | ||
553 | acpi_ds_method_data_delete_all(walk_state); | 550 | acpi_ds_method_data_delete_all(walk_state); |
554 | } | ||
555 | 551 | ||
556 | /* | 552 | /* |
557 | * If method is serialized, release the mutex and restore the | 553 | * If method is serialized, release the mutex and restore the |
558 | * current sync level for this thread | 554 | * current sync level for this thread |
559 | */ | 555 | */ |
560 | if (method_desc->method.mutex) { | 556 | if (method_desc->method.mutex) { |
561 | 557 | ||
562 | /* Acquisition Depth handles recursive calls */ | 558 | /* Acquisition Depth handles recursive calls */ |
563 | 559 | ||
564 | method_desc->method.mutex->mutex.acquisition_depth--; | 560 | method_desc->method.mutex->mutex.acquisition_depth--; |
565 | if (!method_desc->method.mutex->mutex.acquisition_depth) { | 561 | if (!method_desc->method.mutex->mutex.acquisition_depth) { |
566 | walk_state->thread->current_sync_level = | 562 | walk_state->thread->current_sync_level = |
567 | method_desc->method.mutex->mutex. | 563 | method_desc->method.mutex->mutex. |
568 | original_sync_level; | 564 | original_sync_level; |
569 | 565 | ||
570 | acpi_os_release_mutex(method_desc->method.mutex->mutex. | 566 | acpi_os_release_mutex(method_desc->method. |
571 | os_mutex); | 567 | mutex->mutex.os_mutex); |
572 | method_desc->method.mutex->mutex.owner_thread = NULL; | 568 | method_desc->method.mutex->mutex.thread_id = 0; |
569 | } | ||
573 | } | 570 | } |
574 | } | ||
575 | |||
576 | if (walk_state) { | ||
577 | /* | ||
578 | * Delete any objects created by this method during execution. | ||
579 | * The method Node is stored in the walk state | ||
580 | */ | ||
581 | method_node = walk_state->method_node; | ||
582 | 571 | ||
583 | /* | 572 | /* |
584 | * Delete any namespace objects created anywhere within | 573 | * Delete any namespace objects created anywhere within |
@@ -620,7 +609,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | |||
620 | */ | 609 | */ |
621 | if ((method_desc->method.method_flags & AML_METHOD_SERIALIZED) | 610 | if ((method_desc->method.method_flags & AML_METHOD_SERIALIZED) |
622 | && (!method_desc->method.mutex)) { | 611 | && (!method_desc->method.mutex)) { |
623 | status = acpi_ds_create_method_mutex(method_desc); | 612 | (void)acpi_ds_create_method_mutex(method_desc); |
624 | } | 613 | } |
625 | 614 | ||
626 | /* No more threads, we can free the owner_id */ | 615 | /* No more threads, we can free the owner_id */ |
diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c index ba4626e06a5e..13c43eac35db 100644 --- a/drivers/acpi/dispatcher/dsmthdat.c +++ b/drivers/acpi/dispatcher/dsmthdat.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c index 954ac8ce958a..1022e38994c2 100644 --- a/drivers/acpi/dispatcher/dsobject.c +++ b/drivers/acpi/dispatcher/dsobject.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -157,7 +157,9 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, | |||
157 | * will remain as named references. This behavior is not described | 157 | * will remain as named references. This behavior is not described |
158 | * in the ACPI spec, but it appears to be an oversight. | 158 | * in the ACPI spec, but it appears to be an oversight. |
159 | */ | 159 | */ |
160 | obj_desc = (union acpi_operand_object *)op->common.node; | 160 | obj_desc = |
161 | ACPI_CAST_PTR(union acpi_operand_object, | ||
162 | op->common.node); | ||
161 | 163 | ||
162 | status = | 164 | status = |
163 | acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR | 165 | acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR |
@@ -172,7 +174,19 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, | |||
172 | switch (op->common.node->type) { | 174 | switch (op->common.node->type) { |
173 | /* | 175 | /* |
174 | * For these types, we need the actual node, not the subobject. | 176 | * For these types, we need the actual node, not the subobject. |
175 | * However, the subobject got an extra reference count above. | 177 | * However, the subobject did not get an extra reference count above. |
178 | * | ||
179 | * TBD: should ex_resolve_node_to_value be changed to fix this? | ||
180 | */ | ||
181 | case ACPI_TYPE_DEVICE: | ||
182 | case ACPI_TYPE_THERMAL: | ||
183 | |||
184 | acpi_ut_add_reference(op->common.node->object); | ||
185 | |||
186 | /*lint -fallthrough */ | ||
187 | /* | ||
188 | * For these types, we need the actual node, not the subobject. | ||
189 | * The subobject got an extra reference count in ex_resolve_node_to_value. | ||
176 | */ | 190 | */ |
177 | case ACPI_TYPE_MUTEX: | 191 | case ACPI_TYPE_MUTEX: |
178 | case ACPI_TYPE_METHOD: | 192 | case ACPI_TYPE_METHOD: |
@@ -180,25 +194,15 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, | |||
180 | case ACPI_TYPE_PROCESSOR: | 194 | case ACPI_TYPE_PROCESSOR: |
181 | case ACPI_TYPE_EVENT: | 195 | case ACPI_TYPE_EVENT: |
182 | case ACPI_TYPE_REGION: | 196 | case ACPI_TYPE_REGION: |
183 | case ACPI_TYPE_DEVICE: | ||
184 | case ACPI_TYPE_THERMAL: | ||
185 | 197 | ||
186 | obj_desc = | 198 | /* We will create a reference object for these types below */ |
187 | (union acpi_operand_object *)op->common. | ||
188 | node; | ||
189 | break; | 199 | break; |
190 | 200 | ||
191 | default: | 201 | default: |
192 | break; | 202 | /* |
193 | } | 203 | * All other types - the node was resolved to an actual |
194 | 204 | * object, we are done. | |
195 | /* | 205 | */ |
196 | * If above resolved to an operand object, we are done. Otherwise, | ||
197 | * we have a NS node, we must create the package entry as a named | ||
198 | * reference. | ||
199 | */ | ||
200 | if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != | ||
201 | ACPI_DESC_TYPE_NAMED) { | ||
202 | goto exit; | 206 | goto exit; |
203 | } | 207 | } |
204 | } | 208 | } |
@@ -223,7 +227,7 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, | |||
223 | 227 | ||
224 | exit: | 228 | exit: |
225 | *obj_desc_ptr = obj_desc; | 229 | *obj_desc_ptr = obj_desc; |
226 | return_ACPI_STATUS(AE_OK); | 230 | return_ACPI_STATUS(status); |
227 | } | 231 | } |
228 | 232 | ||
229 | /******************************************************************************* | 233 | /******************************************************************************* |
@@ -369,7 +373,9 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, | |||
369 | union acpi_parse_object *parent; | 373 | union acpi_parse_object *parent; |
370 | union acpi_operand_object *obj_desc = NULL; | 374 | union acpi_operand_object *obj_desc = NULL; |
371 | acpi_status status = AE_OK; | 375 | acpi_status status = AE_OK; |
372 | acpi_native_uint i; | 376 | unsigned i; |
377 | u16 index; | ||
378 | u16 reference_count; | ||
373 | 379 | ||
374 | ACPI_FUNCTION_TRACE(ds_build_internal_package_obj); | 380 | ACPI_FUNCTION_TRACE(ds_build_internal_package_obj); |
375 | 381 | ||
@@ -447,13 +453,60 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, | |||
447 | package. | 453 | package. |
448 | elements[i]); | 454 | elements[i]); |
449 | } | 455 | } |
456 | |||
457 | if (*obj_desc_ptr) { | ||
458 | |||
459 | /* Existing package, get existing reference count */ | ||
460 | |||
461 | reference_count = | ||
462 | (*obj_desc_ptr)->common.reference_count; | ||
463 | if (reference_count > 1) { | ||
464 | |||
465 | /* Make new element ref count match original ref count */ | ||
466 | |||
467 | for (index = 0; index < (reference_count - 1); | ||
468 | index++) { | ||
469 | acpi_ut_add_reference((obj_desc-> | ||
470 | package. | ||
471 | elements[i])); | ||
472 | } | ||
473 | } | ||
474 | } | ||
475 | |||
450 | arg = arg->common.next; | 476 | arg = arg->common.next; |
451 | } | 477 | } |
452 | 478 | ||
453 | if (!arg) { | 479 | /* Check for match between num_elements and actual length of package_list */ |
480 | |||
481 | if (arg) { | ||
482 | /* | ||
483 | * num_elements was exhausted, but there are remaining elements in the | ||
484 | * package_list. | ||
485 | * | ||
486 | * Note: technically, this is an error, from ACPI spec: "It is an error | ||
487 | * for NumElements to be less than the number of elements in the | ||
488 | * PackageList". However, for now, we just print an error message and | ||
489 | * no exception is returned. | ||
490 | */ | ||
491 | while (arg) { | ||
492 | |||
493 | /* Find out how many elements there really are */ | ||
494 | |||
495 | i++; | ||
496 | arg = arg->common.next; | ||
497 | } | ||
498 | |||
499 | ACPI_ERROR((AE_INFO, | ||
500 | "Package List length (%X) larger than NumElements count (%X), truncated\n", | ||
501 | i, element_count)); | ||
502 | } else if (i < element_count) { | ||
503 | /* | ||
504 | * Arg list (elements) was exhausted, but we did not reach num_elements count. | ||
505 | * Note: this is not an error, the package is padded out with NULLs. | ||
506 | */ | ||
454 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 507 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
455 | "Package List length larger than NumElements count (%X), truncated\n", | 508 | "Package List length (%X) smaller than NumElements count (%X), padded with null elements\n", |
456 | element_count)); | 509 | i, element_count)); |
457 | } | 510 | } |
458 | 511 | ||
459 | obj_desc->package.flags |= AOPOBJ_DATA_VALID; | 512 | obj_desc->package.flags |= AOPOBJ_DATA_VALID; |
@@ -721,6 +774,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, | |||
721 | /* Node was saved in Op */ | 774 | /* Node was saved in Op */ |
722 | 775 | ||
723 | obj_desc->reference.node = op->common.node; | 776 | obj_desc->reference.node = op->common.node; |
777 | obj_desc->reference.object = | ||
778 | op->common.node->object; | ||
724 | } | 779 | } |
725 | 780 | ||
726 | obj_desc->reference.opcode = opcode; | 781 | obj_desc->reference.opcode = opcode; |
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c index f501e083aac7..a818e0ddb996 100644 --- a/drivers/acpi/dispatcher/dsopcode.c +++ b/drivers/acpi/dispatcher/dsopcode.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -49,6 +49,7 @@ | |||
49 | #include <acpi/acinterp.h> | 49 | #include <acpi/acinterp.h> |
50 | #include <acpi/acnamesp.h> | 50 | #include <acpi/acnamesp.h> |
51 | #include <acpi/acevents.h> | 51 | #include <acpi/acevents.h> |
52 | #include <acpi/actables.h> | ||
52 | 53 | ||
53 | #define _COMPONENT ACPI_DISPATCHER | 54 | #define _COMPONENT ACPI_DISPATCHER |
54 | ACPI_MODULE_NAME("dsopcode") | 55 | ACPI_MODULE_NAME("dsopcode") |
@@ -219,6 +220,50 @@ acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc) | |||
219 | 220 | ||
220 | /******************************************************************************* | 221 | /******************************************************************************* |
221 | * | 222 | * |
223 | * FUNCTION: acpi_ds_get_bank_field_arguments | ||
224 | * | ||
225 | * PARAMETERS: obj_desc - A valid bank_field object | ||
226 | * | ||
227 | * RETURN: Status. | ||
228 | * | ||
229 | * DESCRIPTION: Get bank_field bank_value. This implements the late | ||
230 | * evaluation of these field attributes. | ||
231 | * | ||
232 | ******************************************************************************/ | ||
233 | |||
234 | acpi_status | ||
235 | acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc) | ||
236 | { | ||
237 | union acpi_operand_object *extra_desc; | ||
238 | struct acpi_namespace_node *node; | ||
239 | acpi_status status; | ||
240 | |||
241 | ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc); | ||
242 | |||
243 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | ||
244 | return_ACPI_STATUS(AE_OK); | ||
245 | } | ||
246 | |||
247 | /* Get the AML pointer (method object) and bank_field node */ | ||
248 | |||
249 | extra_desc = acpi_ns_get_secondary_object(obj_desc); | ||
250 | node = obj_desc->bank_field.node; | ||
251 | |||
252 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname | ||
253 | (ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL)); | ||
254 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n", | ||
255 | acpi_ut_get_node_name(node))); | ||
256 | |||
257 | /* Execute the AML code for the term_arg arguments */ | ||
258 | |||
259 | status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), | ||
260 | extra_desc->extra.aml_length, | ||
261 | extra_desc->extra.aml_start); | ||
262 | return_ACPI_STATUS(status); | ||
263 | } | ||
264 | |||
265 | /******************************************************************************* | ||
266 | * | ||
222 | * FUNCTION: acpi_ds_get_buffer_arguments | 267 | * FUNCTION: acpi_ds_get_buffer_arguments |
223 | * | 268 | * |
224 | * PARAMETERS: obj_desc - A valid Buffer object | 269 | * PARAMETERS: obj_desc - A valid Buffer object |
@@ -770,7 +815,109 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state, | |||
770 | 815 | ||
771 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", | 816 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", |
772 | obj_desc, | 817 | obj_desc, |
773 | ACPI_FORMAT_UINT64(obj_desc->region.address), | 818 | ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address), |
819 | obj_desc->region.length)); | ||
820 | |||
821 | /* Now the address and length are valid for this opregion */ | ||
822 | |||
823 | obj_desc->region.flags |= AOPOBJ_DATA_VALID; | ||
824 | |||
825 | return_ACPI_STATUS(status); | ||
826 | } | ||
827 | |||
828 | /******************************************************************************* | ||
829 | * | ||
830 | * FUNCTION: acpi_ds_eval_table_region_operands | ||
831 | * | ||
832 | * PARAMETERS: walk_state - Current walk | ||
833 | * Op - A valid region Op object | ||
834 | * | ||
835 | * RETURN: Status | ||
836 | * | ||
837 | * DESCRIPTION: Get region address and length | ||
838 | * Called from acpi_ds_exec_end_op during data_table_region parse tree walk | ||
839 | * | ||
840 | ******************************************************************************/ | ||
841 | |||
842 | acpi_status | ||
843 | acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, | ||
844 | union acpi_parse_object *op) | ||
845 | { | ||
846 | acpi_status status; | ||
847 | union acpi_operand_object *obj_desc; | ||
848 | union acpi_operand_object **operand; | ||
849 | struct acpi_namespace_node *node; | ||
850 | union acpi_parse_object *next_op; | ||
851 | acpi_native_uint table_index; | ||
852 | struct acpi_table_header *table; | ||
853 | |||
854 | ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op); | ||
855 | |||
856 | /* | ||
857 | * This is where we evaluate the signature_string and oem_iDString | ||
858 | * and oem_table_iDString of the data_table_region declaration | ||
859 | */ | ||
860 | node = op->common.node; | ||
861 | |||
862 | /* next_op points to signature_string op */ | ||
863 | |||
864 | next_op = op->common.value.arg; | ||
865 | |||
866 | /* | ||
867 | * Evaluate/create the signature_string and oem_iDString | ||
868 | * and oem_table_iDString operands | ||
869 | */ | ||
870 | status = acpi_ds_create_operands(walk_state, next_op); | ||
871 | if (ACPI_FAILURE(status)) { | ||
872 | return_ACPI_STATUS(status); | ||
873 | } | ||
874 | |||
875 | /* | ||
876 | * Resolve the signature_string and oem_iDString | ||
877 | * and oem_table_iDString operands | ||
878 | */ | ||
879 | status = acpi_ex_resolve_operands(op->common.aml_opcode, | ||
880 | ACPI_WALK_OPERANDS, walk_state); | ||
881 | if (ACPI_FAILURE(status)) { | ||
882 | return_ACPI_STATUS(status); | ||
883 | } | ||
884 | |||
885 | ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, | ||
886 | acpi_ps_get_opcode_name(op->common.aml_opcode), | ||
887 | 1, "after AcpiExResolveOperands"); | ||
888 | |||
889 | operand = &walk_state->operands[0]; | ||
890 | |||
891 | /* Find the ACPI table */ | ||
892 | |||
893 | status = acpi_tb_find_table(operand[0]->string.pointer, | ||
894 | operand[1]->string.pointer, | ||
895 | operand[2]->string.pointer, &table_index); | ||
896 | if (ACPI_FAILURE(status)) { | ||
897 | return_ACPI_STATUS(status); | ||
898 | } | ||
899 | |||
900 | acpi_ut_remove_reference(operand[0]); | ||
901 | acpi_ut_remove_reference(operand[1]); | ||
902 | acpi_ut_remove_reference(operand[2]); | ||
903 | |||
904 | status = acpi_get_table_by_index(table_index, &table); | ||
905 | if (ACPI_FAILURE(status)) { | ||
906 | return_ACPI_STATUS(status); | ||
907 | } | ||
908 | |||
909 | obj_desc = acpi_ns_get_attached_object(node); | ||
910 | if (!obj_desc) { | ||
911 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
912 | } | ||
913 | |||
914 | obj_desc->region.address = | ||
915 | (acpi_physical_address) ACPI_TO_INTEGER(table); | ||
916 | obj_desc->region.length = table->length; | ||
917 | |||
918 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", | ||
919 | obj_desc, | ||
920 | ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address), | ||
774 | obj_desc->region.length)); | 921 | obj_desc->region.length)); |
775 | 922 | ||
776 | /* Now the address and length are valid for this opregion */ | 923 | /* Now the address and length are valid for this opregion */ |
@@ -808,6 +955,12 @@ acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state, | |||
808 | 955 | ||
809 | /* The first operand (for all of these data objects) is the length */ | 956 | /* The first operand (for all of these data objects) is the length */ |
810 | 957 | ||
958 | /* | ||
959 | * Set proper index into operand stack for acpi_ds_obj_stack_push | ||
960 | * invoked inside acpi_ds_create_operand. | ||
961 | */ | ||
962 | walk_state->operand_index = walk_state->num_operands; | ||
963 | |||
811 | status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1); | 964 | status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1); |
812 | if (ACPI_FAILURE(status)) { | 965 | if (ACPI_FAILURE(status)) { |
813 | return_ACPI_STATUS(status); | 966 | return_ACPI_STATUS(status); |
@@ -878,6 +1031,106 @@ acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state, | |||
878 | 1031 | ||
879 | /******************************************************************************* | 1032 | /******************************************************************************* |
880 | * | 1033 | * |
1034 | * FUNCTION: acpi_ds_eval_bank_field_operands | ||
1035 | * | ||
1036 | * PARAMETERS: walk_state - Current walk | ||
1037 | * Op - A valid bank_field Op object | ||
1038 | * | ||
1039 | * RETURN: Status | ||
1040 | * | ||
1041 | * DESCRIPTION: Get bank_field bank_value | ||
1042 | * Called from acpi_ds_exec_end_op during bank_field parse tree walk | ||
1043 | * | ||
1044 | ******************************************************************************/ | ||
1045 | |||
1046 | acpi_status | ||
1047 | acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state, | ||
1048 | union acpi_parse_object *op) | ||
1049 | { | ||
1050 | acpi_status status; | ||
1051 | union acpi_operand_object *obj_desc; | ||
1052 | union acpi_operand_object *operand_desc; | ||
1053 | struct acpi_namespace_node *node; | ||
1054 | union acpi_parse_object *next_op; | ||
1055 | union acpi_parse_object *arg; | ||
1056 | |||
1057 | ACPI_FUNCTION_TRACE_PTR(ds_eval_bank_field_operands, op); | ||
1058 | |||
1059 | /* | ||
1060 | * This is where we evaluate the bank_value field of the | ||
1061 | * bank_field declaration | ||
1062 | */ | ||
1063 | |||
1064 | /* next_op points to the op that holds the Region */ | ||
1065 | |||
1066 | next_op = op->common.value.arg; | ||
1067 | |||
1068 | /* next_op points to the op that holds the Bank Register */ | ||
1069 | |||
1070 | next_op = next_op->common.next; | ||
1071 | |||
1072 | /* next_op points to the op that holds the Bank Value */ | ||
1073 | |||
1074 | next_op = next_op->common.next; | ||
1075 | |||
1076 | /* | ||
1077 | * Set proper index into operand stack for acpi_ds_obj_stack_push | ||
1078 | * invoked inside acpi_ds_create_operand. | ||
1079 | * | ||
1080 | * We use walk_state->Operands[0] to store the evaluated bank_value | ||
1081 | */ | ||
1082 | walk_state->operand_index = 0; | ||
1083 | |||
1084 | status = acpi_ds_create_operand(walk_state, next_op, 0); | ||
1085 | if (ACPI_FAILURE(status)) { | ||
1086 | return_ACPI_STATUS(status); | ||
1087 | } | ||
1088 | |||
1089 | status = acpi_ex_resolve_to_value(&walk_state->operands[0], walk_state); | ||
1090 | if (ACPI_FAILURE(status)) { | ||
1091 | return_ACPI_STATUS(status); | ||
1092 | } | ||
1093 | |||
1094 | ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, | ||
1095 | acpi_ps_get_opcode_name(op->common.aml_opcode), | ||
1096 | 1, "after AcpiExResolveOperands"); | ||
1097 | |||
1098 | /* | ||
1099 | * Get the bank_value operand and save it | ||
1100 | * (at Top of stack) | ||
1101 | */ | ||
1102 | operand_desc = walk_state->operands[0]; | ||
1103 | |||
1104 | /* Arg points to the start Bank Field */ | ||
1105 | |||
1106 | arg = acpi_ps_get_arg(op, 4); | ||
1107 | while (arg) { | ||
1108 | |||
1109 | /* Ignore OFFSET and ACCESSAS terms here */ | ||
1110 | |||
1111 | if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { | ||
1112 | node = arg->common.node; | ||
1113 | |||
1114 | obj_desc = acpi_ns_get_attached_object(node); | ||
1115 | if (!obj_desc) { | ||
1116 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
1117 | } | ||
1118 | |||
1119 | obj_desc->bank_field.value = | ||
1120 | (u32) operand_desc->integer.value; | ||
1121 | } | ||
1122 | |||
1123 | /* Move to next field in the list */ | ||
1124 | |||
1125 | arg = arg->common.next; | ||
1126 | } | ||
1127 | |||
1128 | acpi_ut_remove_reference(operand_desc); | ||
1129 | return_ACPI_STATUS(status); | ||
1130 | } | ||
1131 | |||
1132 | /******************************************************************************* | ||
1133 | * | ||
881 | * FUNCTION: acpi_ds_exec_begin_control_op | 1134 | * FUNCTION: acpi_ds_exec_begin_control_op |
882 | * | 1135 | * |
883 | * PARAMETERS: walk_list - The list that owns the walk stack | 1136 | * PARAMETERS: walk_list - The list that owns the walk stack |
@@ -1070,8 +1323,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, | |||
1070 | * is set to anything other than zero! | 1323 | * is set to anything other than zero! |
1071 | */ | 1324 | */ |
1072 | walk_state->return_desc = walk_state->operands[0]; | 1325 | walk_state->return_desc = walk_state->operands[0]; |
1073 | } else if ((walk_state->results) && | 1326 | } else if (walk_state->result_count) { |
1074 | (walk_state->results->results.num_results > 0)) { | ||
1075 | 1327 | ||
1076 | /* Since we have a real Return(), delete any implicit return */ | 1328 | /* Since we have a real Return(), delete any implicit return */ |
1077 | 1329 | ||
diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c index 71503c036f7c..b398982f0d8b 100644 --- a/drivers/acpi/dispatcher/dsutils.c +++ b/drivers/acpi/dispatcher/dsutils.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -278,7 +278,9 @@ acpi_ds_is_result_used(union acpi_parse_object * op, | |||
278 | AML_VAR_PACKAGE_OP) | 278 | AML_VAR_PACKAGE_OP) |
279 | || (op->common.parent->common.aml_opcode == AML_BUFFER_OP) | 279 | || (op->common.parent->common.aml_opcode == AML_BUFFER_OP) |
280 | || (op->common.parent->common.aml_opcode == | 280 | || (op->common.parent->common.aml_opcode == |
281 | AML_INT_EVAL_SUBTREE_OP)) { | 281 | AML_INT_EVAL_SUBTREE_OP) |
282 | || (op->common.parent->common.aml_opcode == | ||
283 | AML_BANK_FIELD_OP)) { | ||
282 | /* | 284 | /* |
283 | * These opcodes allow term_arg(s) as operands and therefore | 285 | * These opcodes allow term_arg(s) as operands and therefore |
284 | * the operands can be method calls. The result is used. | 286 | * the operands can be method calls. The result is used. |
@@ -472,7 +474,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, | |||
472 | /* A valid name must be looked up in the namespace */ | 474 | /* A valid name must be looked up in the namespace */ |
473 | 475 | ||
474 | if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) && | 476 | if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) && |
475 | (arg->common.value.string)) { | 477 | (arg->common.value.string) && |
478 | !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) { | ||
476 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", | 479 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", |
477 | arg)); | 480 | arg)); |
478 | 481 | ||
@@ -595,7 +598,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, | |||
595 | } else { | 598 | } else { |
596 | /* Check for null name case */ | 599 | /* Check for null name case */ |
597 | 600 | ||
598 | if (arg->common.aml_opcode == AML_INT_NAMEPATH_OP) { | 601 | if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) && |
602 | !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) { | ||
599 | /* | 603 | /* |
600 | * If the name is null, this means that this is an | 604 | * If the name is null, this means that this is an |
601 | * optional result parameter that was not specified | 605 | * optional result parameter that was not specified |
@@ -617,7 +621,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, | |||
617 | return_ACPI_STATUS(AE_NOT_IMPLEMENTED); | 621 | return_ACPI_STATUS(AE_NOT_IMPLEMENTED); |
618 | } | 622 | } |
619 | 623 | ||
620 | if (op_info->flags & AML_HAS_RETVAL) { | 624 | if ((op_info->flags & AML_HAS_RETVAL) |
625 | || (arg->common.flags & ACPI_PARSEOP_IN_STACK)) { | ||
621 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 626 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
622 | "Argument previously created, already stacked\n")); | 627 | "Argument previously created, already stacked\n")); |
623 | 628 | ||
@@ -630,9 +635,7 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, | |||
630 | * Use value that was already previously returned | 635 | * Use value that was already previously returned |
631 | * by the evaluation of this argument | 636 | * by the evaluation of this argument |
632 | */ | 637 | */ |
633 | status = | 638 | status = acpi_ds_result_pop(&obj_desc, walk_state); |
634 | acpi_ds_result_pop_from_bottom(&obj_desc, | ||
635 | walk_state); | ||
636 | if (ACPI_FAILURE(status)) { | 639 | if (ACPI_FAILURE(status)) { |
637 | /* | 640 | /* |
638 | * Only error is underflow, and this indicates | 641 | * Only error is underflow, and this indicates |
@@ -698,27 +701,52 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, | |||
698 | { | 701 | { |
699 | acpi_status status = AE_OK; | 702 | acpi_status status = AE_OK; |
700 | union acpi_parse_object *arg; | 703 | union acpi_parse_object *arg; |
704 | union acpi_parse_object *arguments[ACPI_OBJ_NUM_OPERANDS]; | ||
701 | u32 arg_count = 0; | 705 | u32 arg_count = 0; |
706 | u32 index = walk_state->num_operands; | ||
707 | u32 i; | ||
702 | 708 | ||
703 | ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg); | 709 | ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg); |
704 | 710 | ||
705 | /* For all arguments in the list... */ | 711 | /* Get all arguments in the list */ |
706 | 712 | ||
707 | arg = first_arg; | 713 | arg = first_arg; |
708 | while (arg) { | 714 | while (arg) { |
709 | status = acpi_ds_create_operand(walk_state, arg, arg_count); | 715 | if (index >= ACPI_OBJ_NUM_OPERANDS) { |
710 | if (ACPI_FAILURE(status)) { | 716 | return_ACPI_STATUS(AE_BAD_DATA); |
711 | goto cleanup; | ||
712 | } | 717 | } |
713 | 718 | ||
714 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 719 | arguments[index] = arg; |
715 | "Arg #%d (%p) done, Arg1=%p\n", arg_count, | 720 | walk_state->operands[index] = NULL; |
716 | arg, first_arg)); | ||
717 | 721 | ||
718 | /* Move on to next argument, if any */ | 722 | /* Move on to next argument, if any */ |
719 | 723 | ||
720 | arg = arg->common.next; | 724 | arg = arg->common.next; |
721 | arg_count++; | 725 | arg_count++; |
726 | index++; | ||
727 | } | ||
728 | |||
729 | index--; | ||
730 | |||
731 | /* It is the appropriate order to get objects from the Result stack */ | ||
732 | |||
733 | for (i = 0; i < arg_count; i++) { | ||
734 | arg = arguments[index]; | ||
735 | |||
736 | /* Force the filling of the operand stack in inverse order */ | ||
737 | |||
738 | walk_state->operand_index = (u8) index; | ||
739 | |||
740 | status = acpi_ds_create_operand(walk_state, arg, index); | ||
741 | if (ACPI_FAILURE(status)) { | ||
742 | goto cleanup; | ||
743 | } | ||
744 | |||
745 | index--; | ||
746 | |||
747 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
748 | "Arg #%d (%p) done, Arg1=%p\n", index, arg, | ||
749 | first_arg)); | ||
722 | } | 750 | } |
723 | 751 | ||
724 | return_ACPI_STATUS(status); | 752 | return_ACPI_STATUS(status); |
@@ -729,9 +757,112 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, | |||
729 | * pop everything off of the operand stack and delete those | 757 | * pop everything off of the operand stack and delete those |
730 | * objects | 758 | * objects |
731 | */ | 759 | */ |
732 | (void)acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state); | 760 | acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state); |
761 | |||
762 | ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", index)); | ||
763 | return_ACPI_STATUS(status); | ||
764 | } | ||
765 | |||
766 | /***************************************************************************** | ||
767 | * | ||
768 | * FUNCTION: acpi_ds_evaluate_name_path | ||
769 | * | ||
770 | * PARAMETERS: walk_state - Current state of the parse tree walk, | ||
771 | * the opcode of current operation should be | ||
772 | * AML_INT_NAMEPATH_OP | ||
773 | * | ||
774 | * RETURN: Status | ||
775 | * | ||
776 | * DESCRIPTION: Translate the -name_path- parse tree object to the equivalent | ||
777 | * interpreter object, convert it to value, if needed, duplicate | ||
778 | * it, if needed, and push it onto the current result stack. | ||
779 | * | ||
780 | ****************************************************************************/ | ||
781 | |||
782 | acpi_status acpi_ds_evaluate_name_path(struct acpi_walk_state *walk_state) | ||
783 | { | ||
784 | acpi_status status = AE_OK; | ||
785 | union acpi_parse_object *op = walk_state->op; | ||
786 | union acpi_operand_object **operand = &walk_state->operands[0]; | ||
787 | union acpi_operand_object *new_obj_desc; | ||
788 | u8 type; | ||
789 | |||
790 | ACPI_FUNCTION_TRACE_PTR(ds_evaluate_name_path, walk_state); | ||
791 | |||
792 | if (!op->common.parent) { | ||
793 | |||
794 | /* This happens after certain exception processing */ | ||
795 | |||
796 | goto exit; | ||
797 | } | ||
798 | |||
799 | if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) || | ||
800 | (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP) || | ||
801 | (op->common.parent->common.aml_opcode == AML_REF_OF_OP)) { | ||
802 | |||
803 | /* TBD: Should we specify this feature as a bit of op_info->Flags of these opcodes? */ | ||
804 | |||
805 | goto exit; | ||
806 | } | ||
807 | |||
808 | status = acpi_ds_create_operand(walk_state, op, 0); | ||
809 | if (ACPI_FAILURE(status)) { | ||
810 | goto exit; | ||
811 | } | ||
812 | |||
813 | if (op->common.flags & ACPI_PARSEOP_TARGET) { | ||
814 | new_obj_desc = *operand; | ||
815 | goto push_result; | ||
816 | } | ||
817 | |||
818 | type = ACPI_GET_OBJECT_TYPE(*operand); | ||
819 | |||
820 | status = acpi_ex_resolve_to_value(operand, walk_state); | ||
821 | if (ACPI_FAILURE(status)) { | ||
822 | goto exit; | ||
823 | } | ||
824 | |||
825 | if (type == ACPI_TYPE_INTEGER) { | ||
826 | |||
827 | /* It was incremented by acpi_ex_resolve_to_value */ | ||
828 | |||
829 | acpi_ut_remove_reference(*operand); | ||
830 | |||
831 | status = | ||
832 | acpi_ut_copy_iobject_to_iobject(*operand, &new_obj_desc, | ||
833 | walk_state); | ||
834 | if (ACPI_FAILURE(status)) { | ||
835 | goto exit; | ||
836 | } | ||
837 | } else { | ||
838 | /* | ||
839 | * The object either was anew created or is | ||
840 | * a Namespace node - don't decrement it. | ||
841 | */ | ||
842 | new_obj_desc = *operand; | ||
843 | } | ||
844 | |||
845 | /* Cleanup for name-path operand */ | ||
846 | |||
847 | status = acpi_ds_obj_stack_pop(1, walk_state); | ||
848 | if (ACPI_FAILURE(status)) { | ||
849 | walk_state->result_obj = new_obj_desc; | ||
850 | goto exit; | ||
851 | } | ||
852 | |||
853 | push_result: | ||
854 | |||
855 | walk_state->result_obj = new_obj_desc; | ||
856 | |||
857 | status = acpi_ds_result_push(walk_state->result_obj, walk_state); | ||
858 | if (ACPI_SUCCESS(status)) { | ||
859 | |||
860 | /* Force to take it from stack */ | ||
861 | |||
862 | op->common.flags |= ACPI_PARSEOP_IN_STACK; | ||
863 | } | ||
864 | |||
865 | exit: | ||
733 | 866 | ||
734 | ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", | ||
735 | (arg_count + 1))); | ||
736 | return_ACPI_STATUS(status); | 867 | return_ACPI_STATUS(status); |
737 | } | 868 | } |
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c index 69693fa07224..b246b9657ead 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/dispatcher/dswexec.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -285,11 +285,6 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, | |||
285 | switch (opcode_class) { | 285 | switch (opcode_class) { |
286 | case AML_CLASS_CONTROL: | 286 | case AML_CLASS_CONTROL: |
287 | 287 | ||
288 | status = acpi_ds_result_stack_push(walk_state); | ||
289 | if (ACPI_FAILURE(status)) { | ||
290 | goto error_exit; | ||
291 | } | ||
292 | |||
293 | status = acpi_ds_exec_begin_control_op(walk_state, op); | 288 | status = acpi_ds_exec_begin_control_op(walk_state, op); |
294 | break; | 289 | break; |
295 | 290 | ||
@@ -305,20 +300,11 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, | |||
305 | status = acpi_ds_load2_begin_op(walk_state, NULL); | 300 | status = acpi_ds_load2_begin_op(walk_state, NULL); |
306 | } | 301 | } |
307 | 302 | ||
308 | if (op->common.aml_opcode == AML_REGION_OP) { | ||
309 | status = acpi_ds_result_stack_push(walk_state); | ||
310 | } | ||
311 | break; | 303 | break; |
312 | 304 | ||
313 | case AML_CLASS_EXECUTE: | 305 | case AML_CLASS_EXECUTE: |
314 | case AML_CLASS_CREATE: | 306 | case AML_CLASS_CREATE: |
315 | /* | 307 | |
316 | * Most operators with arguments (except create_xxx_field operators) | ||
317 | * Start a new result/operand state | ||
318 | */ | ||
319 | if (walk_state->op_info->object_type != ACPI_TYPE_BUFFER_FIELD) { | ||
320 | status = acpi_ds_result_stack_push(walk_state); | ||
321 | } | ||
322 | break; | 308 | break; |
323 | 309 | ||
324 | default: | 310 | default: |
@@ -374,6 +360,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) | |||
374 | /* Init the walk state */ | 360 | /* Init the walk state */ |
375 | 361 | ||
376 | walk_state->num_operands = 0; | 362 | walk_state->num_operands = 0; |
363 | walk_state->operand_index = 0; | ||
377 | walk_state->return_desc = NULL; | 364 | walk_state->return_desc = NULL; |
378 | walk_state->result_obj = NULL; | 365 | walk_state->result_obj = NULL; |
379 | 366 | ||
@@ -388,10 +375,17 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) | |||
388 | /* Decode the Opcode Class */ | 375 | /* Decode the Opcode Class */ |
389 | 376 | ||
390 | switch (op_class) { | 377 | switch (op_class) { |
391 | case AML_CLASS_ARGUMENT: /* constants, literals, etc. - do nothing */ | 378 | case AML_CLASS_ARGUMENT: /* Constants, literals, etc. */ |
379 | |||
380 | if (walk_state->opcode == AML_INT_NAMEPATH_OP) { | ||
381 | status = acpi_ds_evaluate_name_path(walk_state); | ||
382 | if (ACPI_FAILURE(status)) { | ||
383 | goto cleanup; | ||
384 | } | ||
385 | } | ||
392 | break; | 386 | break; |
393 | 387 | ||
394 | case AML_CLASS_EXECUTE: /* most operators with arguments */ | 388 | case AML_CLASS_EXECUTE: /* Most operators with arguments */ |
395 | 389 | ||
396 | /* Build resolved operand stack */ | 390 | /* Build resolved operand stack */ |
397 | 391 | ||
@@ -400,13 +394,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) | |||
400 | goto cleanup; | 394 | goto cleanup; |
401 | } | 395 | } |
402 | 396 | ||
403 | /* Done with this result state (Now that operand stack is built) */ | ||
404 | |||
405 | status = acpi_ds_result_stack_pop(walk_state); | ||
406 | if (ACPI_FAILURE(status)) { | ||
407 | goto cleanup; | ||
408 | } | ||
409 | |||
410 | /* | 397 | /* |
411 | * All opcodes require operand resolution, with the only exceptions | 398 | * All opcodes require operand resolution, with the only exceptions |
412 | * being the object_type and size_of operators. | 399 | * being the object_type and size_of operators. |
@@ -487,16 +474,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) | |||
487 | 474 | ||
488 | status = acpi_ds_exec_end_control_op(walk_state, op); | 475 | status = acpi_ds_exec_end_control_op(walk_state, op); |
489 | 476 | ||
490 | /* Make sure to properly pop the result stack */ | ||
491 | |||
492 | if (ACPI_SUCCESS(status)) { | ||
493 | status = acpi_ds_result_stack_pop(walk_state); | ||
494 | } else if (status == AE_CTRL_PENDING) { | ||
495 | status = acpi_ds_result_stack_pop(walk_state); | ||
496 | if (ACPI_SUCCESS(status)) { | ||
497 | status = AE_CTRL_PENDING; | ||
498 | } | ||
499 | } | ||
500 | break; | 477 | break; |
501 | 478 | ||
502 | case AML_TYPE_METHOD_CALL: | 479 | case AML_TYPE_METHOD_CALL: |
@@ -516,7 +493,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) | |||
516 | 493 | ||
517 | op->common.node = | 494 | op->common.node = |
518 | (struct acpi_namespace_node *)op->asl.value. | 495 | (struct acpi_namespace_node *)op->asl.value. |
519 | arg->asl.node->object; | 496 | arg->asl.node; |
520 | acpi_ut_add_reference(op->asl.value.arg->asl. | 497 | acpi_ut_add_reference(op->asl.value.arg->asl. |
521 | node->object); | 498 | node->object); |
522 | return_ACPI_STATUS(AE_OK); | 499 | return_ACPI_STATUS(AE_OK); |
@@ -632,13 +609,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) | |||
632 | break; | 609 | break; |
633 | } | 610 | } |
634 | 611 | ||
635 | /* Done with result state (Now that operand stack is built) */ | ||
636 | |||
637 | status = acpi_ds_result_stack_pop(walk_state); | ||
638 | if (ACPI_FAILURE(status)) { | ||
639 | goto cleanup; | ||
640 | } | ||
641 | |||
642 | /* | 612 | /* |
643 | * If a result object was returned from above, push it on the | 613 | * If a result object was returned from above, push it on the |
644 | * current result stack | 614 | * current result stack |
@@ -671,8 +641,28 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) | |||
671 | if (ACPI_FAILURE(status)) { | 641 | if (ACPI_FAILURE(status)) { |
672 | break; | 642 | break; |
673 | } | 643 | } |
644 | } else if (op->common.aml_opcode == AML_DATA_REGION_OP) { | ||
645 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
646 | "Executing DataTableRegion Strings Op=%p\n", | ||
647 | op)); | ||
648 | |||
649 | status = | ||
650 | acpi_ds_eval_table_region_operands | ||
651 | (walk_state, op); | ||
652 | if (ACPI_FAILURE(status)) { | ||
653 | break; | ||
654 | } | ||
655 | } else if (op->common.aml_opcode == AML_BANK_FIELD_OP) { | ||
656 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
657 | "Executing BankField Op=%p\n", | ||
658 | op)); | ||
674 | 659 | ||
675 | status = acpi_ds_result_stack_pop(walk_state); | 660 | status = |
661 | acpi_ds_eval_bank_field_operands(walk_state, | ||
662 | op); | ||
663 | if (ACPI_FAILURE(status)) { | ||
664 | break; | ||
665 | } | ||
676 | } | 666 | } |
677 | break; | 667 | break; |
678 | 668 | ||
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c index 8ab9d1b29a4c..dff7a3e445a8 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/dispatcher/dswload.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -443,6 +443,15 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state) | |||
443 | if (ACPI_FAILURE(status)) { | 443 | if (ACPI_FAILURE(status)) { |
444 | return_ACPI_STATUS(status); | 444 | return_ACPI_STATUS(status); |
445 | } | 445 | } |
446 | } else if (op->common.aml_opcode == AML_DATA_REGION_OP) { | ||
447 | status = | ||
448 | acpi_ex_create_region(op->named.data, | ||
449 | op->named.length, | ||
450 | REGION_DATA_TABLE, | ||
451 | walk_state); | ||
452 | if (ACPI_FAILURE(status)) { | ||
453 | return_ACPI_STATUS(status); | ||
454 | } | ||
446 | } | 455 | } |
447 | } | 456 | } |
448 | #endif | 457 | #endif |
@@ -767,6 +776,12 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, | |||
767 | acpi_ns_lookup(walk_state->scope_info, buffer_ptr, | 776 | acpi_ns_lookup(walk_state->scope_info, buffer_ptr, |
768 | object_type, ACPI_IMODE_LOAD_PASS2, flags, | 777 | object_type, ACPI_IMODE_LOAD_PASS2, flags, |
769 | walk_state, &node); | 778 | walk_state, &node); |
779 | |||
780 | if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) { | ||
781 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
782 | "***New Node [%4.4s] %p is temporary\n", | ||
783 | acpi_ut_get_node_name(node), node)); | ||
784 | } | ||
770 | break; | 785 | break; |
771 | } | 786 | } |
772 | 787 | ||
@@ -823,6 +838,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
823 | struct acpi_namespace_node *new_node; | 838 | struct acpi_namespace_node *new_node; |
824 | #ifndef ACPI_NO_METHOD_EXECUTION | 839 | #ifndef ACPI_NO_METHOD_EXECUTION |
825 | u32 i; | 840 | u32 i; |
841 | u8 region_space; | ||
826 | #endif | 842 | #endif |
827 | 843 | ||
828 | ACPI_FUNCTION_TRACE(ds_load2_end_op); | 844 | ACPI_FUNCTION_TRACE(ds_load2_end_op); |
@@ -1003,11 +1019,6 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
1003 | status = acpi_ex_create_event(walk_state); | 1019 | status = acpi_ex_create_event(walk_state); |
1004 | break; | 1020 | break; |
1005 | 1021 | ||
1006 | case AML_DATA_REGION_OP: | ||
1007 | |||
1008 | status = acpi_ex_create_table_region(walk_state); | ||
1009 | break; | ||
1010 | |||
1011 | case AML_ALIAS_OP: | 1022 | case AML_ALIAS_OP: |
1012 | 1023 | ||
1013 | status = acpi_ex_create_alias(walk_state); | 1024 | status = acpi_ex_create_alias(walk_state); |
@@ -1035,6 +1046,15 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
1035 | switch (op->common.aml_opcode) { | 1046 | switch (op->common.aml_opcode) { |
1036 | #ifndef ACPI_NO_METHOD_EXECUTION | 1047 | #ifndef ACPI_NO_METHOD_EXECUTION |
1037 | case AML_REGION_OP: | 1048 | case AML_REGION_OP: |
1049 | case AML_DATA_REGION_OP: | ||
1050 | |||
1051 | if (op->common.aml_opcode == AML_REGION_OP) { | ||
1052 | region_space = (acpi_adr_space_type) | ||
1053 | ((op->common.value.arg)->common.value. | ||
1054 | integer); | ||
1055 | } else { | ||
1056 | region_space = REGION_DATA_TABLE; | ||
1057 | } | ||
1038 | 1058 | ||
1039 | /* | 1059 | /* |
1040 | * If we are executing a method, initialize the region | 1060 | * If we are executing a method, initialize the region |
@@ -1043,10 +1063,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
1043 | status = | 1063 | status = |
1044 | acpi_ex_create_region(op->named.data, | 1064 | acpi_ex_create_region(op->named.data, |
1045 | op->named.length, | 1065 | op->named.length, |
1046 | (acpi_adr_space_type) | 1066 | region_space, |
1047 | ((op->common.value. | ||
1048 | arg)->common.value. | ||
1049 | integer), | ||
1050 | walk_state); | 1067 | walk_state); |
1051 | if (ACPI_FAILURE(status)) { | 1068 | if (ACPI_FAILURE(status)) { |
1052 | return (status); | 1069 | return (status); |
diff --git a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c index 3927c495e4bf..9e6073265873 100644 --- a/drivers/acpi/dispatcher/dswscope.c +++ b/drivers/acpi/dispatcher/dswscope.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c index 5afcdd9c7449..1386ced332ec 100644 --- a/drivers/acpi/dispatcher/dswstate.c +++ b/drivers/acpi/dispatcher/dswstate.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -49,85 +49,9 @@ | |||
49 | #define _COMPONENT ACPI_DISPATCHER | 49 | #define _COMPONENT ACPI_DISPATCHER |
50 | ACPI_MODULE_NAME("dswstate") | 50 | ACPI_MODULE_NAME("dswstate") |
51 | 51 | ||
52 | /* Local prototypes */ | 52 | /* Local prototypes */ |
53 | #ifdef ACPI_OBSOLETE_FUNCTIONS | 53 | static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *ws); |
54 | acpi_status | 54 | static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *ws); |
55 | acpi_ds_result_insert(void *object, | ||
56 | u32 index, struct acpi_walk_state *walk_state); | ||
57 | |||
58 | acpi_status acpi_ds_obj_stack_delete_all(struct acpi_walk_state *walk_state); | ||
59 | |||
60 | acpi_status | ||
61 | acpi_ds_obj_stack_pop_object(union acpi_operand_object **object, | ||
62 | struct acpi_walk_state *walk_state); | ||
63 | |||
64 | void *acpi_ds_obj_stack_get_value(u32 index, | ||
65 | struct acpi_walk_state *walk_state); | ||
66 | #endif | ||
67 | |||
68 | #ifdef ACPI_FUTURE_USAGE | ||
69 | /******************************************************************************* | ||
70 | * | ||
71 | * FUNCTION: acpi_ds_result_remove | ||
72 | * | ||
73 | * PARAMETERS: Object - Where to return the popped object | ||
74 | * Index - Where to extract the object | ||
75 | * walk_state - Current Walk state | ||
76 | * | ||
77 | * RETURN: Status | ||
78 | * | ||
79 | * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In | ||
80 | * other words, this is a FIFO. | ||
81 | * | ||
82 | ******************************************************************************/ | ||
83 | |||
84 | acpi_status | ||
85 | acpi_ds_result_remove(union acpi_operand_object **object, | ||
86 | u32 index, struct acpi_walk_state *walk_state) | ||
87 | { | ||
88 | union acpi_generic_state *state; | ||
89 | |||
90 | ACPI_FUNCTION_NAME(ds_result_remove); | ||
91 | |||
92 | state = walk_state->results; | ||
93 | if (!state) { | ||
94 | ACPI_ERROR((AE_INFO, "No result object pushed! State=%p", | ||
95 | walk_state)); | ||
96 | return (AE_NOT_EXIST); | ||
97 | } | ||
98 | |||
99 | if (index >= ACPI_OBJ_MAX_OPERAND) { | ||
100 | ACPI_ERROR((AE_INFO, | ||
101 | "Index out of range: %X State=%p Num=%X", | ||
102 | index, walk_state, state->results.num_results)); | ||
103 | } | ||
104 | |||
105 | /* Check for a valid result object */ | ||
106 | |||
107 | if (!state->results.obj_desc[index]) { | ||
108 | ACPI_ERROR((AE_INFO, | ||
109 | "Null operand! State=%p #Ops=%X, Index=%X", | ||
110 | walk_state, state->results.num_results, index)); | ||
111 | return (AE_AML_NO_RETURN_VALUE); | ||
112 | } | ||
113 | |||
114 | /* Remove the object */ | ||
115 | |||
116 | state->results.num_results--; | ||
117 | |||
118 | *object = state->results.obj_desc[index]; | ||
119 | state->results.obj_desc[index] = NULL; | ||
120 | |||
121 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
122 | "Obj=%p [%s] Index=%X State=%p Num=%X\n", | ||
123 | *object, | ||
124 | (*object) ? acpi_ut_get_object_type_name(*object) : | ||
125 | "NULL", index, walk_state, | ||
126 | state->results.num_results)); | ||
127 | |||
128 | return (AE_OK); | ||
129 | } | ||
130 | #endif /* ACPI_FUTURE_USAGE */ | ||
131 | 55 | ||
132 | /******************************************************************************* | 56 | /******************************************************************************* |
133 | * | 57 | * |
@@ -138,122 +62,67 @@ acpi_ds_result_remove(union acpi_operand_object **object, | |||
138 | * | 62 | * |
139 | * RETURN: Status | 63 | * RETURN: Status |
140 | * | 64 | * |
141 | * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In | 65 | * DESCRIPTION: Pop an object off the top of this walk's result stack |
142 | * other words, this is a FIFO. | ||
143 | * | 66 | * |
144 | ******************************************************************************/ | 67 | ******************************************************************************/ |
145 | 68 | ||
146 | acpi_status | 69 | acpi_status |
147 | acpi_ds_result_pop(union acpi_operand_object ** object, | 70 | acpi_ds_result_pop(union acpi_operand_object **object, |
148 | struct acpi_walk_state * walk_state) | 71 | struct acpi_walk_state *walk_state) |
149 | { | 72 | { |
150 | acpi_native_uint index; | 73 | acpi_native_uint index; |
151 | union acpi_generic_state *state; | 74 | union acpi_generic_state *state; |
75 | acpi_status status; | ||
152 | 76 | ||
153 | ACPI_FUNCTION_NAME(ds_result_pop); | 77 | ACPI_FUNCTION_NAME(ds_result_pop); |
154 | 78 | ||
155 | state = walk_state->results; | 79 | state = walk_state->results; |
156 | if (!state) { | ||
157 | return (AE_OK); | ||
158 | } | ||
159 | |||
160 | if (!state->results.num_results) { | ||
161 | ACPI_ERROR((AE_INFO, "Result stack is empty! State=%p", | ||
162 | walk_state)); | ||
163 | return (AE_AML_NO_RETURN_VALUE); | ||
164 | } | ||
165 | 80 | ||
166 | /* Remove top element */ | 81 | /* Incorrect state of result stack */ |
167 | 82 | ||
168 | state->results.num_results--; | 83 | if (state && !walk_state->result_count) { |
169 | 84 | ACPI_ERROR((AE_INFO, "No results on result stack")); | |
170 | for (index = ACPI_OBJ_NUM_OPERANDS; index; index--) { | 85 | return (AE_AML_INTERNAL); |
171 | |||
172 | /* Check for a valid result object */ | ||
173 | |||
174 | if (state->results.obj_desc[index - 1]) { | ||
175 | *object = state->results.obj_desc[index - 1]; | ||
176 | state->results.obj_desc[index - 1] = NULL; | ||
177 | |||
178 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
179 | "Obj=%p [%s] Index=%X State=%p Num=%X\n", | ||
180 | *object, | ||
181 | (*object) ? | ||
182 | acpi_ut_get_object_type_name(*object) | ||
183 | : "NULL", (u32) index - 1, walk_state, | ||
184 | state->results.num_results)); | ||
185 | |||
186 | return (AE_OK); | ||
187 | } | ||
188 | } | 86 | } |
189 | 87 | ||
190 | ACPI_ERROR((AE_INFO, "No result objects! State=%p", walk_state)); | 88 | if (!state && walk_state->result_count) { |
191 | return (AE_AML_NO_RETURN_VALUE); | 89 | ACPI_ERROR((AE_INFO, "No result state for result stack")); |
192 | } | 90 | return (AE_AML_INTERNAL); |
193 | 91 | } | |
194 | /******************************************************************************* | ||
195 | * | ||
196 | * FUNCTION: acpi_ds_result_pop_from_bottom | ||
197 | * | ||
198 | * PARAMETERS: Object - Where to return the popped object | ||
199 | * walk_state - Current Walk state | ||
200 | * | ||
201 | * RETURN: Status | ||
202 | * | ||
203 | * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In | ||
204 | * other words, this is a FIFO. | ||
205 | * | ||
206 | ******************************************************************************/ | ||
207 | |||
208 | acpi_status | ||
209 | acpi_ds_result_pop_from_bottom(union acpi_operand_object ** object, | ||
210 | struct acpi_walk_state * walk_state) | ||
211 | { | ||
212 | acpi_native_uint index; | ||
213 | union acpi_generic_state *state; | ||
214 | 92 | ||
215 | ACPI_FUNCTION_NAME(ds_result_pop_from_bottom); | 93 | /* Empty result stack */ |
216 | 94 | ||
217 | state = walk_state->results; | ||
218 | if (!state) { | 95 | if (!state) { |
219 | ACPI_ERROR((AE_INFO, | 96 | ACPI_ERROR((AE_INFO, "Result stack is empty! State=%p", |
220 | "No result object pushed! State=%p", walk_state)); | ||
221 | return (AE_NOT_EXIST); | ||
222 | } | ||
223 | |||
224 | if (!state->results.num_results) { | ||
225 | ACPI_ERROR((AE_INFO, "No result objects! State=%p", | ||
226 | walk_state)); | 97 | walk_state)); |
227 | return (AE_AML_NO_RETURN_VALUE); | 98 | return (AE_AML_NO_RETURN_VALUE); |
228 | } | 99 | } |
229 | 100 | ||
230 | /* Remove Bottom element */ | 101 | /* Return object of the top element and clean that top element result stack */ |
231 | |||
232 | *object = state->results.obj_desc[0]; | ||
233 | |||
234 | /* Push entire stack down one element */ | ||
235 | |||
236 | for (index = 0; index < state->results.num_results; index++) { | ||
237 | state->results.obj_desc[index] = | ||
238 | state->results.obj_desc[index + 1]; | ||
239 | } | ||
240 | 102 | ||
241 | state->results.num_results--; | 103 | walk_state->result_count--; |
242 | 104 | index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; | |
243 | /* Check for a valid result object */ | ||
244 | 105 | ||
106 | *object = state->results.obj_desc[index]; | ||
245 | if (!*object) { | 107 | if (!*object) { |
246 | ACPI_ERROR((AE_INFO, | 108 | ACPI_ERROR((AE_INFO, |
247 | "Null operand! State=%p #Ops=%X Index=%X", | 109 | "No result objects on result stack, State=%p", |
248 | walk_state, state->results.num_results, | 110 | walk_state)); |
249 | (u32) index)); | ||
250 | return (AE_AML_NO_RETURN_VALUE); | 111 | return (AE_AML_NO_RETURN_VALUE); |
251 | } | 112 | } |
252 | 113 | ||
253 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] Results=%p State=%p\n", | 114 | state->results.obj_desc[index] = NULL; |
254 | *object, | 115 | if (index == 0) { |
255 | (*object) ? acpi_ut_get_object_type_name(*object) : | 116 | status = acpi_ds_result_stack_pop(walk_state); |
256 | "NULL", state, walk_state)); | 117 | if (ACPI_FAILURE(status)) { |
118 | return (status); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
123 | "Obj=%p [%s] Index=%X State=%p Num=%X\n", *object, | ||
124 | acpi_ut_get_object_type_name(*object), | ||
125 | (u32) index, walk_state, walk_state->result_count)); | ||
257 | 126 | ||
258 | return (AE_OK); | 127 | return (AE_OK); |
259 | } | 128 | } |
@@ -276,39 +145,56 @@ acpi_ds_result_push(union acpi_operand_object * object, | |||
276 | struct acpi_walk_state * walk_state) | 145 | struct acpi_walk_state * walk_state) |
277 | { | 146 | { |
278 | union acpi_generic_state *state; | 147 | union acpi_generic_state *state; |
148 | acpi_status status; | ||
149 | acpi_native_uint index; | ||
279 | 150 | ||
280 | ACPI_FUNCTION_NAME(ds_result_push); | 151 | ACPI_FUNCTION_NAME(ds_result_push); |
281 | 152 | ||
153 | if (walk_state->result_count > walk_state->result_size) { | ||
154 | ACPI_ERROR((AE_INFO, "Result stack is full")); | ||
155 | return (AE_AML_INTERNAL); | ||
156 | } else if (walk_state->result_count == walk_state->result_size) { | ||
157 | |||
158 | /* Extend the result stack */ | ||
159 | |||
160 | status = acpi_ds_result_stack_push(walk_state); | ||
161 | if (ACPI_FAILURE(status)) { | ||
162 | ACPI_ERROR((AE_INFO, | ||
163 | "Failed to extend the result stack")); | ||
164 | return (status); | ||
165 | } | ||
166 | } | ||
167 | |||
168 | if (!(walk_state->result_count < walk_state->result_size)) { | ||
169 | ACPI_ERROR((AE_INFO, "No free elements in result stack")); | ||
170 | return (AE_AML_INTERNAL); | ||
171 | } | ||
172 | |||
282 | state = walk_state->results; | 173 | state = walk_state->results; |
283 | if (!state) { | 174 | if (!state) { |
284 | ACPI_ERROR((AE_INFO, "No result stack frame during push")); | 175 | ACPI_ERROR((AE_INFO, "No result stack frame during push")); |
285 | return (AE_AML_INTERNAL); | 176 | return (AE_AML_INTERNAL); |
286 | } | 177 | } |
287 | 178 | ||
288 | if (state->results.num_results == ACPI_OBJ_NUM_OPERANDS) { | ||
289 | ACPI_ERROR((AE_INFO, | ||
290 | "Result stack overflow: Obj=%p State=%p Num=%X", | ||
291 | object, walk_state, state->results.num_results)); | ||
292 | return (AE_STACK_OVERFLOW); | ||
293 | } | ||
294 | |||
295 | if (!object) { | 179 | if (!object) { |
296 | ACPI_ERROR((AE_INFO, | 180 | ACPI_ERROR((AE_INFO, |
297 | "Null Object! Obj=%p State=%p Num=%X", | 181 | "Null Object! Obj=%p State=%p Num=%X", |
298 | object, walk_state, state->results.num_results)); | 182 | object, walk_state, walk_state->result_count)); |
299 | return (AE_BAD_PARAMETER); | 183 | return (AE_BAD_PARAMETER); |
300 | } | 184 | } |
301 | 185 | ||
302 | state->results.obj_desc[state->results.num_results] = object; | 186 | /* Assign the address of object to the top free element of result stack */ |
303 | state->results.num_results++; | 187 | |
188 | index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; | ||
189 | state->results.obj_desc[index] = object; | ||
190 | walk_state->result_count++; | ||
304 | 191 | ||
305 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n", | 192 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n", |
306 | object, | 193 | object, |
307 | object ? | ||
308 | acpi_ut_get_object_type_name((union | 194 | acpi_ut_get_object_type_name((union |
309 | acpi_operand_object *) | 195 | acpi_operand_object *) |
310 | object) : "NULL", | 196 | object), walk_state, |
311 | walk_state, state->results.num_results, | 197 | walk_state->result_count, |
312 | walk_state->current_result)); | 198 | walk_state->current_result)); |
313 | 199 | ||
314 | return (AE_OK); | 200 | return (AE_OK); |
@@ -322,16 +208,25 @@ acpi_ds_result_push(union acpi_operand_object * object, | |||
322 | * | 208 | * |
323 | * RETURN: Status | 209 | * RETURN: Status |
324 | * | 210 | * |
325 | * DESCRIPTION: Push an object onto the walk_state result stack. | 211 | * DESCRIPTION: Push an object onto the walk_state result stack |
326 | * | 212 | * |
327 | ******************************************************************************/ | 213 | ******************************************************************************/ |
328 | 214 | ||
329 | acpi_status acpi_ds_result_stack_push(struct acpi_walk_state * walk_state) | 215 | static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *walk_state) |
330 | { | 216 | { |
331 | union acpi_generic_state *state; | 217 | union acpi_generic_state *state; |
332 | 218 | ||
333 | ACPI_FUNCTION_NAME(ds_result_stack_push); | 219 | ACPI_FUNCTION_NAME(ds_result_stack_push); |
334 | 220 | ||
221 | /* Check for stack overflow */ | ||
222 | |||
223 | if (((u32) walk_state->result_size + ACPI_RESULTS_FRAME_OBJ_NUM) > | ||
224 | ACPI_RESULTS_OBJ_NUM_MAX) { | ||
225 | ACPI_ERROR((AE_INFO, "Result stack overflow: State=%p Num=%X", | ||
226 | walk_state, walk_state->result_size)); | ||
227 | return (AE_STACK_OVERFLOW); | ||
228 | } | ||
229 | |||
335 | state = acpi_ut_create_generic_state(); | 230 | state = acpi_ut_create_generic_state(); |
336 | if (!state) { | 231 | if (!state) { |
337 | return (AE_NO_MEMORY); | 232 | return (AE_NO_MEMORY); |
@@ -340,6 +235,10 @@ acpi_status acpi_ds_result_stack_push(struct acpi_walk_state * walk_state) | |||
340 | state->common.descriptor_type = ACPI_DESC_TYPE_STATE_RESULT; | 235 | state->common.descriptor_type = ACPI_DESC_TYPE_STATE_RESULT; |
341 | acpi_ut_push_generic_state(&walk_state->results, state); | 236 | acpi_ut_push_generic_state(&walk_state->results, state); |
342 | 237 | ||
238 | /* Increase the length of the result stack by the length of frame */ | ||
239 | |||
240 | walk_state->result_size += ACPI_RESULTS_FRAME_OBJ_NUM; | ||
241 | |||
343 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Results=%p State=%p\n", | 242 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Results=%p State=%p\n", |
344 | state, walk_state)); | 243 | state, walk_state)); |
345 | 244 | ||
@@ -354,11 +253,11 @@ acpi_status acpi_ds_result_stack_push(struct acpi_walk_state * walk_state) | |||
354 | * | 253 | * |
355 | * RETURN: Status | 254 | * RETURN: Status |
356 | * | 255 | * |
357 | * DESCRIPTION: Pop an object off of the walk_state result stack. | 256 | * DESCRIPTION: Pop an object off of the walk_state result stack |
358 | * | 257 | * |
359 | ******************************************************************************/ | 258 | ******************************************************************************/ |
360 | 259 | ||
361 | acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state * walk_state) | 260 | static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *walk_state) |
362 | { | 261 | { |
363 | union acpi_generic_state *state; | 262 | union acpi_generic_state *state; |
364 | 263 | ||
@@ -367,18 +266,27 @@ acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state * walk_state) | |||
367 | /* Check for stack underflow */ | 266 | /* Check for stack underflow */ |
368 | 267 | ||
369 | if (walk_state->results == NULL) { | 268 | if (walk_state->results == NULL) { |
370 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Underflow - State=%p\n", | 269 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
270 | "Result stack underflow - State=%p\n", | ||
371 | walk_state)); | 271 | walk_state)); |
372 | return (AE_AML_NO_OPERAND); | 272 | return (AE_AML_NO_OPERAND); |
373 | } | 273 | } |
374 | 274 | ||
275 | if (walk_state->result_size < ACPI_RESULTS_FRAME_OBJ_NUM) { | ||
276 | ACPI_ERROR((AE_INFO, "Insufficient result stack size")); | ||
277 | return (AE_AML_INTERNAL); | ||
278 | } | ||
279 | |||
375 | state = acpi_ut_pop_generic_state(&walk_state->results); | 280 | state = acpi_ut_pop_generic_state(&walk_state->results); |
281 | acpi_ut_delete_generic_state(state); | ||
282 | |||
283 | /* Decrease the length of result stack by the length of frame */ | ||
284 | |||
285 | walk_state->result_size -= ACPI_RESULTS_FRAME_OBJ_NUM; | ||
376 | 286 | ||
377 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 287 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
378 | "Result=%p RemainingResults=%X State=%p\n", | 288 | "Result=%p RemainingResults=%X State=%p\n", |
379 | state, state->results.num_results, walk_state)); | 289 | state, walk_state->result_count, walk_state)); |
380 | |||
381 | acpi_ut_delete_generic_state(state); | ||
382 | 290 | ||
383 | return (AE_OK); | 291 | return (AE_OK); |
384 | } | 292 | } |
@@ -412,9 +320,13 @@ acpi_ds_obj_stack_push(void *object, struct acpi_walk_state * walk_state) | |||
412 | 320 | ||
413 | /* Put the object onto the stack */ | 321 | /* Put the object onto the stack */ |
414 | 322 | ||
415 | walk_state->operands[walk_state->num_operands] = object; | 323 | walk_state->operands[walk_state->operand_index] = object; |
416 | walk_state->num_operands++; | 324 | walk_state->num_operands++; |
417 | 325 | ||
326 | /* For the usual order of filling the operand stack */ | ||
327 | |||
328 | walk_state->operand_index++; | ||
329 | |||
418 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n", | 330 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n", |
419 | object, | 331 | object, |
420 | acpi_ut_get_object_type_name((union | 332 | acpi_ut_get_object_type_name((union |
@@ -484,43 +396,36 @@ acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state * walk_state) | |||
484 | * | 396 | * |
485 | ******************************************************************************/ | 397 | ******************************************************************************/ |
486 | 398 | ||
487 | acpi_status | 399 | void |
488 | acpi_ds_obj_stack_pop_and_delete(u32 pop_count, | 400 | acpi_ds_obj_stack_pop_and_delete(u32 pop_count, |
489 | struct acpi_walk_state * walk_state) | 401 | struct acpi_walk_state *walk_state) |
490 | { | 402 | { |
491 | u32 i; | 403 | acpi_native_int i; |
492 | union acpi_operand_object *obj_desc; | 404 | union acpi_operand_object *obj_desc; |
493 | 405 | ||
494 | ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete); | 406 | ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete); |
495 | 407 | ||
496 | for (i = 0; i < pop_count; i++) { | 408 | if (pop_count == 0) { |
497 | 409 | return; | |
498 | /* Check for stack underflow */ | 410 | } |
499 | 411 | ||
412 | for (i = (acpi_native_int) (pop_count - 1); i >= 0; i--) { | ||
500 | if (walk_state->num_operands == 0) { | 413 | if (walk_state->num_operands == 0) { |
501 | ACPI_ERROR((AE_INFO, | 414 | return; |
502 | "Object stack underflow! Count=%X State=%p #Ops=%X", | ||
503 | pop_count, walk_state, | ||
504 | walk_state->num_operands)); | ||
505 | return (AE_STACK_UNDERFLOW); | ||
506 | } | 415 | } |
507 | 416 | ||
508 | /* Pop the stack and delete an object if present in this stack entry */ | 417 | /* Pop the stack and delete an object if present in this stack entry */ |
509 | 418 | ||
510 | walk_state->num_operands--; | 419 | walk_state->num_operands--; |
511 | obj_desc = walk_state->operands[walk_state->num_operands]; | 420 | obj_desc = walk_state->operands[i]; |
512 | if (obj_desc) { | 421 | if (obj_desc) { |
513 | acpi_ut_remove_reference(walk_state-> | 422 | acpi_ut_remove_reference(walk_state->operands[i]); |
514 | operands[walk_state-> | 423 | walk_state->operands[i] = NULL; |
515 | num_operands]); | ||
516 | walk_state->operands[walk_state->num_operands] = NULL; | ||
517 | } | 424 | } |
518 | } | 425 | } |
519 | 426 | ||
520 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n", | 427 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n", |
521 | pop_count, walk_state, walk_state->num_operands)); | 428 | pop_count, walk_state, walk_state->num_operands)); |
522 | |||
523 | return (AE_OK); | ||
524 | } | 429 | } |
525 | 430 | ||
526 | /******************************************************************************* | 431 | /******************************************************************************* |
@@ -560,7 +465,7 @@ struct acpi_walk_state *acpi_ds_get_current_walk_state(struct acpi_thread_state | |||
560 | * | 465 | * |
561 | * RETURN: None | 466 | * RETURN: None |
562 | * | 467 | * |
563 | * DESCRIPTION: Place the Thread state at the head of the state list. | 468 | * DESCRIPTION: Place the Thread state at the head of the state list |
564 | * | 469 | * |
565 | ******************************************************************************/ | 470 | ******************************************************************************/ |
566 | 471 | ||
@@ -636,7 +541,6 @@ struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union | |||
636 | *thread) | 541 | *thread) |
637 | { | 542 | { |
638 | struct acpi_walk_state *walk_state; | 543 | struct acpi_walk_state *walk_state; |
639 | acpi_status status; | ||
640 | 544 | ||
641 | ACPI_FUNCTION_TRACE(ds_create_walk_state); | 545 | ACPI_FUNCTION_TRACE(ds_create_walk_state); |
642 | 546 | ||
@@ -659,14 +563,6 @@ struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union | |||
659 | acpi_ds_method_data_init(walk_state); | 563 | acpi_ds_method_data_init(walk_state); |
660 | #endif | 564 | #endif |
661 | 565 | ||
662 | /* Create an initial result stack entry */ | ||
663 | |||
664 | status = acpi_ds_result_stack_push(walk_state); | ||
665 | if (ACPI_FAILURE(status)) { | ||
666 | ACPI_FREE(walk_state); | ||
667 | return_PTR(NULL); | ||
668 | } | ||
669 | |||
670 | /* Put the new state at the head of the walk list */ | 566 | /* Put the new state at the head of the walk list */ |
671 | 567 | ||
672 | if (thread) { | 568 | if (thread) { |
@@ -860,190 +756,3 @@ void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state) | |||
860 | ACPI_FREE(walk_state); | 756 | ACPI_FREE(walk_state); |
861 | return_VOID; | 757 | return_VOID; |
862 | } | 758 | } |
863 | |||
864 | #ifdef ACPI_OBSOLETE_FUNCTIONS | ||
865 | /******************************************************************************* | ||
866 | * | ||
867 | * FUNCTION: acpi_ds_result_insert | ||
868 | * | ||
869 | * PARAMETERS: Object - Object to push | ||
870 | * Index - Where to insert the object | ||
871 | * walk_state - Current Walk state | ||
872 | * | ||
873 | * RETURN: Status | ||
874 | * | ||
875 | * DESCRIPTION: Insert an object onto this walk's result stack | ||
876 | * | ||
877 | ******************************************************************************/ | ||
878 | |||
879 | acpi_status | ||
880 | acpi_ds_result_insert(void *object, | ||
881 | u32 index, struct acpi_walk_state *walk_state) | ||
882 | { | ||
883 | union acpi_generic_state *state; | ||
884 | |||
885 | ACPI_FUNCTION_NAME(ds_result_insert); | ||
886 | |||
887 | state = walk_state->results; | ||
888 | if (!state) { | ||
889 | ACPI_ERROR((AE_INFO, "No result object pushed! State=%p", | ||
890 | walk_state)); | ||
891 | return (AE_NOT_EXIST); | ||
892 | } | ||
893 | |||
894 | if (index >= ACPI_OBJ_NUM_OPERANDS) { | ||
895 | ACPI_ERROR((AE_INFO, | ||
896 | "Index out of range: %X Obj=%p State=%p Num=%X", | ||
897 | index, object, walk_state, | ||
898 | state->results.num_results)); | ||
899 | return (AE_BAD_PARAMETER); | ||
900 | } | ||
901 | |||
902 | if (!object) { | ||
903 | ACPI_ERROR((AE_INFO, | ||
904 | "Null Object! Index=%X Obj=%p State=%p Num=%X", | ||
905 | index, object, walk_state, | ||
906 | state->results.num_results)); | ||
907 | return (AE_BAD_PARAMETER); | ||
908 | } | ||
909 | |||
910 | state->results.obj_desc[index] = object; | ||
911 | state->results.num_results++; | ||
912 | |||
913 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
914 | "Obj=%p [%s] State=%p Num=%X Cur=%X\n", | ||
915 | object, | ||
916 | object ? | ||
917 | acpi_ut_get_object_type_name((union | ||
918 | acpi_operand_object *) | ||
919 | object) : "NULL", | ||
920 | walk_state, state->results.num_results, | ||
921 | walk_state->current_result)); | ||
922 | |||
923 | return (AE_OK); | ||
924 | } | ||
925 | |||
926 | /******************************************************************************* | ||
927 | * | ||
928 | * FUNCTION: acpi_ds_obj_stack_delete_all | ||
929 | * | ||
930 | * PARAMETERS: walk_state - Current Walk state | ||
931 | * | ||
932 | * RETURN: Status | ||
933 | * | ||
934 | * DESCRIPTION: Clear the object stack by deleting all objects that are on it. | ||
935 | * Should be used with great care, if at all! | ||
936 | * | ||
937 | ******************************************************************************/ | ||
938 | |||
939 | acpi_status acpi_ds_obj_stack_delete_all(struct acpi_walk_state * walk_state) | ||
940 | { | ||
941 | u32 i; | ||
942 | |||
943 | ACPI_FUNCTION_TRACE_PTR(ds_obj_stack_delete_all, walk_state); | ||
944 | |||
945 | /* The stack size is configurable, but fixed */ | ||
946 | |||
947 | for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++) { | ||
948 | if (walk_state->operands[i]) { | ||
949 | acpi_ut_remove_reference(walk_state->operands[i]); | ||
950 | walk_state->operands[i] = NULL; | ||
951 | } | ||
952 | } | ||
953 | |||
954 | return_ACPI_STATUS(AE_OK); | ||
955 | } | ||
956 | |||
957 | /******************************************************************************* | ||
958 | * | ||
959 | * FUNCTION: acpi_ds_obj_stack_pop_object | ||
960 | * | ||
961 | * PARAMETERS: Object - Where to return the popped object | ||
962 | * walk_state - Current Walk state | ||
963 | * | ||
964 | * RETURN: Status | ||
965 | * | ||
966 | * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT | ||
967 | * deleted by this routine. | ||
968 | * | ||
969 | ******************************************************************************/ | ||
970 | |||
971 | acpi_status | ||
972 | acpi_ds_obj_stack_pop_object(union acpi_operand_object **object, | ||
973 | struct acpi_walk_state *walk_state) | ||
974 | { | ||
975 | ACPI_FUNCTION_NAME(ds_obj_stack_pop_object); | ||
976 | |||
977 | /* Check for stack underflow */ | ||
978 | |||
979 | if (walk_state->num_operands == 0) { | ||
980 | ACPI_ERROR((AE_INFO, | ||
981 | "Missing operand/stack empty! State=%p #Ops=%X", | ||
982 | walk_state, walk_state->num_operands)); | ||
983 | *object = NULL; | ||
984 | return (AE_AML_NO_OPERAND); | ||
985 | } | ||
986 | |||
987 | /* Pop the stack */ | ||
988 | |||
989 | walk_state->num_operands--; | ||
990 | |||
991 | /* Check for a valid operand */ | ||
992 | |||
993 | if (!walk_state->operands[walk_state->num_operands]) { | ||
994 | ACPI_ERROR((AE_INFO, | ||
995 | "Null operand! State=%p #Ops=%X", | ||
996 | walk_state, walk_state->num_operands)); | ||
997 | *object = NULL; | ||
998 | return (AE_AML_NO_OPERAND); | ||
999 | } | ||
1000 | |||
1001 | /* Get operand and set stack entry to null */ | ||
1002 | |||
1003 | *object = walk_state->operands[walk_state->num_operands]; | ||
1004 | walk_state->operands[walk_state->num_operands] = NULL; | ||
1005 | |||
1006 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n", | ||
1007 | *object, acpi_ut_get_object_type_name(*object), | ||
1008 | walk_state, walk_state->num_operands)); | ||
1009 | |||
1010 | return (AE_OK); | ||
1011 | } | ||
1012 | |||
1013 | /******************************************************************************* | ||
1014 | * | ||
1015 | * FUNCTION: acpi_ds_obj_stack_get_value | ||
1016 | * | ||
1017 | * PARAMETERS: Index - Stack index whose value is desired. Based | ||
1018 | * on the top of the stack (index=0 == top) | ||
1019 | * walk_state - Current Walk state | ||
1020 | * | ||
1021 | * RETURN: Pointer to the requested operand | ||
1022 | * | ||
1023 | * DESCRIPTION: Retrieve an object from this walk's operand stack. Index must | ||
1024 | * be within the range of the current stack pointer. | ||
1025 | * | ||
1026 | ******************************************************************************/ | ||
1027 | |||
1028 | void *acpi_ds_obj_stack_get_value(u32 index, struct acpi_walk_state *walk_state) | ||
1029 | { | ||
1030 | |||
1031 | ACPI_FUNCTION_TRACE_PTR(ds_obj_stack_get_value, walk_state); | ||
1032 | |||
1033 | /* Can't do it if the stack is empty */ | ||
1034 | |||
1035 | if (walk_state->num_operands == 0) { | ||
1036 | return_PTR(NULL); | ||
1037 | } | ||
1038 | |||
1039 | /* or if the index is past the top of the stack */ | ||
1040 | |||
1041 | if (index > (walk_state->num_operands - (u32) 1)) { | ||
1042 | return_PTR(NULL); | ||
1043 | } | ||
1044 | |||
1045 | return_PTR(walk_state-> | ||
1046 | operands[(acpi_native_uint) (walk_state->num_operands - 1) - | ||
1047 | index]); | ||
1048 | } | ||
1049 | #endif | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 7222a18a0319..3d9362140831 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -73,38 +73,14 @@ enum ec_event { | |||
73 | 73 | ||
74 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ | 74 | #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 */ | 75 | #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 */ | ||
76 | 77 | ||
77 | enum { | 78 | enum { |
78 | EC_FLAGS_WAIT_GPE = 0, /* Don't check status until GPE arrives */ | 79 | EC_FLAGS_WAIT_GPE = 0, /* Don't check status until GPE arrives */ |
79 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ | 80 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ |
80 | EC_FLAGS_GPE_MODE, /* Expect GPE to be sent for status change */ | 81 | EC_FLAGS_GPE_MODE, /* Expect GPE to be sent for status change */ |
81 | EC_FLAGS_NO_ADDRESS_GPE, /* Expect GPE only for non-address event */ | 82 | EC_FLAGS_NO_GPE, /* Don't use GPE mode */ |
82 | EC_FLAGS_ADDRESS, /* Address is being written */ | 83 | EC_FLAGS_RESCHEDULE_POLL /* Re-schedule poll */ |
83 | EC_FLAGS_NO_WDATA_GPE, /* Don't expect WDATA GPE event */ | ||
84 | EC_FLAGS_WDATA, /* Data is being written */ | ||
85 | EC_FLAGS_NO_OBF1_GPE, /* Don't expect GPE before read */ | ||
86 | }; | ||
87 | |||
88 | static int acpi_ec_remove(struct acpi_device *device, int type); | ||
89 | static int acpi_ec_start(struct acpi_device *device); | ||
90 | static int acpi_ec_stop(struct acpi_device *device, int type); | ||
91 | static int acpi_ec_add(struct acpi_device *device); | ||
92 | |||
93 | static const struct acpi_device_id ec_device_ids[] = { | ||
94 | {"PNP0C09", 0}, | ||
95 | {"", 0}, | ||
96 | }; | ||
97 | |||
98 | static struct acpi_driver acpi_ec_driver = { | ||
99 | .name = "ec", | ||
100 | .class = ACPI_EC_CLASS, | ||
101 | .ids = ec_device_ids, | ||
102 | .ops = { | ||
103 | .add = acpi_ec_add, | ||
104 | .remove = acpi_ec_remove, | ||
105 | .start = acpi_ec_start, | ||
106 | .stop = acpi_ec_stop, | ||
107 | }, | ||
108 | }; | 84 | }; |
109 | 85 | ||
110 | /* 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 */ |
@@ -129,6 +105,8 @@ static struct acpi_ec { | |||
129 | struct mutex lock; | 105 | struct mutex lock; |
130 | wait_queue_head_t wait; | 106 | wait_queue_head_t wait; |
131 | struct list_head list; | 107 | struct list_head list; |
108 | struct delayed_work work; | ||
109 | atomic_t irq_count; | ||
132 | u8 handlers_installed; | 110 | u8 handlers_installed; |
133 | } *boot_ec, *first_ec; | 111 | } *boot_ec, *first_ec; |
134 | 112 | ||
@@ -177,65 +155,52 @@ static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event) | |||
177 | return 0; | 155 | return 0; |
178 | } | 156 | } |
179 | 157 | ||
180 | static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) | 158 | static void ec_schedule_ec_poll(struct acpi_ec *ec) |
181 | { | 159 | { |
182 | int ret = 0; | 160 | if (test_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags)) |
161 | schedule_delayed_work(&ec->work, | ||
162 | msecs_to_jiffies(ACPI_EC_DELAY)); | ||
163 | } | ||
183 | 164 | ||
184 | if (unlikely(event == ACPI_EC_EVENT_OBF_1 && | 165 | static void ec_switch_to_poll_mode(struct acpi_ec *ec) |
185 | test_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags))) | 166 | { |
186 | force_poll = 1; | 167 | set_bit(EC_FLAGS_NO_GPE, &ec->flags); |
187 | if (unlikely(test_bit(EC_FLAGS_ADDRESS, &ec->flags) && | 168 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); |
188 | test_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags))) | 169 | acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); |
189 | force_poll = 1; | 170 | set_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags); |
190 | if (unlikely(test_bit(EC_FLAGS_WDATA, &ec->flags) && | 171 | } |
191 | test_bit(EC_FLAGS_NO_WDATA_GPE, &ec->flags))) | 172 | |
192 | force_poll = 1; | 173 | static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) |
174 | { | ||
175 | atomic_set(&ec->irq_count, 0); | ||
193 | if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) && | 176 | if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) && |
194 | likely(!force_poll)) { | 177 | likely(!force_poll)) { |
195 | if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event), | 178 | if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event), |
196 | msecs_to_jiffies(ACPI_EC_DELAY))) | 179 | msecs_to_jiffies(ACPI_EC_DELAY))) |
197 | goto end; | 180 | return 0; |
198 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | 181 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
199 | if (acpi_ec_check_status(ec, event)) { | 182 | if (acpi_ec_check_status(ec, event)) { |
200 | if (event == ACPI_EC_EVENT_OBF_1) { | 183 | /* missing GPEs, switch back to poll mode */ |
201 | /* miss OBF_1 GPE, don't expect it */ | 184 | if (printk_ratelimit()) |
202 | pr_info(PREFIX "missing OBF confirmation, " | 185 | pr_info(PREFIX "missing confirmations, " |
203 | "don't expect it any longer.\n"); | ||
204 | set_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags); | ||
205 | } else if (test_bit(EC_FLAGS_ADDRESS, &ec->flags)) { | ||
206 | /* miss address GPE, don't expect it anymore */ | ||
207 | pr_info(PREFIX "missing address confirmation, " | ||
208 | "don't expect it any longer.\n"); | ||
209 | set_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags); | ||
210 | } else if (test_bit(EC_FLAGS_WDATA, &ec->flags)) { | ||
211 | /* miss write data GPE, don't expect it */ | ||
212 | pr_info(PREFIX "missing write data confirmation, " | ||
213 | "don't expect it any longer.\n"); | ||
214 | set_bit(EC_FLAGS_NO_WDATA_GPE, &ec->flags); | ||
215 | } else { | ||
216 | /* missing GPEs, switch back to poll mode */ | ||
217 | if (printk_ratelimit()) | ||
218 | pr_info(PREFIX "missing confirmations, " | ||
219 | "switch off interrupt mode.\n"); | 186 | "switch off interrupt mode.\n"); |
220 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | 187 | ec_switch_to_poll_mode(ec); |
221 | } | 188 | ec_schedule_ec_poll(ec); |
222 | goto end; | 189 | return 0; |
223 | } | 190 | } |
224 | } else { | 191 | } else { |
225 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); | 192 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); |
226 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | 193 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
227 | while (time_before(jiffies, delay)) { | 194 | while (time_before(jiffies, delay)) { |
228 | if (acpi_ec_check_status(ec, event)) | 195 | if (acpi_ec_check_status(ec, event)) |
229 | goto end; | 196 | return 0; |
197 | udelay(ACPI_EC_UDELAY); | ||
230 | } | 198 | } |
231 | } | 199 | } |
232 | pr_err(PREFIX "acpi_ec_wait timeout," | 200 | pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n", |
233 | " status = %d, expect_event = %d\n", | 201 | acpi_ec_read_status(ec), |
234 | acpi_ec_read_status(ec), event); | 202 | (event == ACPI_EC_EVENT_OBF_1) ? "\"b0=1\"" : "\"b1=0\""); |
235 | ret = -ETIME; | 203 | return -ETIME; |
236 | end: | ||
237 | clear_bit(EC_FLAGS_ADDRESS, &ec->flags); | ||
238 | return ret; | ||
239 | } | 204 | } |
240 | 205 | ||
241 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, | 206 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, |
@@ -245,8 +210,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, | |||
245 | { | 210 | { |
246 | int result = 0; | 211 | int result = 0; |
247 | set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | 212 | set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
248 | acpi_ec_write_cmd(ec, command); | ||
249 | pr_debug(PREFIX "transaction start\n"); | 213 | pr_debug(PREFIX "transaction start\n"); |
214 | acpi_ec_write_cmd(ec, command); | ||
250 | for (; wdata_len > 0; --wdata_len) { | 215 | for (; wdata_len > 0; --wdata_len) { |
251 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll); | 216 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll); |
252 | if (result) { | 217 | if (result) { |
@@ -254,15 +219,11 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, | |||
254 | "write_cmd timeout, command = %d\n", command); | 219 | "write_cmd timeout, command = %d\n", command); |
255 | goto end; | 220 | goto end; |
256 | } | 221 | } |
257 | /* mark the address byte written to EC */ | ||
258 | if (rdata_len + wdata_len > 1) | ||
259 | set_bit(EC_FLAGS_ADDRESS, &ec->flags); | ||
260 | set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | 222 | set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
261 | acpi_ec_write_data(ec, *(wdata++)); | 223 | acpi_ec_write_data(ec, *(wdata++)); |
262 | } | 224 | } |
263 | 225 | ||
264 | if (!rdata_len) { | 226 | if (!rdata_len) { |
265 | set_bit(EC_FLAGS_WDATA, &ec->flags); | ||
266 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll); | 227 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll); |
267 | if (result) { | 228 | if (result) { |
268 | pr_err(PREFIX | 229 | pr_err(PREFIX |
@@ -527,47 +488,51 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
527 | { | 488 | { |
528 | acpi_status status = AE_OK; | 489 | acpi_status status = AE_OK; |
529 | struct acpi_ec *ec = data; | 490 | struct acpi_ec *ec = data; |
491 | u8 state = acpi_ec_read_status(ec); | ||
530 | 492 | ||
531 | pr_debug(PREFIX "~~~> interrupt\n"); | 493 | pr_debug(PREFIX "~~~> interrupt\n"); |
494 | atomic_inc(&ec->irq_count); | ||
495 | if (atomic_read(&ec->irq_count) > 5) { | ||
496 | pr_err(PREFIX "GPE storm detected, disabling EC GPE\n"); | ||
497 | ec_switch_to_poll_mode(ec); | ||
498 | goto end; | ||
499 | } | ||
532 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | 500 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
533 | if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) | 501 | if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) |
534 | wake_up(&ec->wait); | 502 | wake_up(&ec->wait); |
535 | 503 | ||
536 | if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI) { | 504 | if (state & ACPI_EC_FLAG_SCI) { |
537 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) | 505 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) |
538 | status = acpi_os_execute(OSL_EC_BURST_HANDLER, | 506 | status = acpi_os_execute(OSL_EC_BURST_HANDLER, |
539 | acpi_ec_gpe_query, ec); | 507 | acpi_ec_gpe_query, ec); |
540 | } else if (unlikely(!test_bit(EC_FLAGS_GPE_MODE, &ec->flags))) { | 508 | } else if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && |
509 | !test_bit(EC_FLAGS_NO_GPE, &ec->flags) && | ||
510 | in_interrupt()) { | ||
541 | /* this is non-query, must be confirmation */ | 511 | /* this is non-query, must be confirmation */ |
542 | if (printk_ratelimit()) | 512 | if (printk_ratelimit()) |
543 | pr_info(PREFIX "non-query interrupt received," | 513 | pr_info(PREFIX "non-query interrupt received," |
544 | " switching to interrupt mode\n"); | 514 | " switching to interrupt mode\n"); |
545 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); | 515 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); |
516 | clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags); | ||
546 | } | 517 | } |
547 | 518 | end: | |
519 | ec_schedule_ec_poll(ec); | ||
548 | return ACPI_SUCCESS(status) ? | 520 | return ACPI_SUCCESS(status) ? |
549 | ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; | 521 | ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; |
550 | } | 522 | } |
551 | 523 | ||
524 | static void do_ec_poll(struct work_struct *work) | ||
525 | { | ||
526 | struct acpi_ec *ec = container_of(work, struct acpi_ec, work.work); | ||
527 | atomic_set(&ec->irq_count, 0); | ||
528 | (void)acpi_ec_gpe_handler(ec); | ||
529 | } | ||
530 | |||
552 | /* -------------------------------------------------------------------------- | 531 | /* -------------------------------------------------------------------------- |
553 | Address Space Management | 532 | Address Space Management |
554 | -------------------------------------------------------------------------- */ | 533 | -------------------------------------------------------------------------- */ |
555 | 534 | ||
556 | static acpi_status | 535 | static acpi_status |
557 | acpi_ec_space_setup(acpi_handle region_handle, | ||
558 | u32 function, void *handler_context, void **return_context) | ||
559 | { | ||
560 | /* | ||
561 | * The EC object is in the handler context and is needed | ||
562 | * when calling the acpi_ec_space_handler. | ||
563 | */ | ||
564 | *return_context = (function != ACPI_REGION_DEACTIVATE) ? | ||
565 | handler_context : NULL; | ||
566 | |||
567 | return AE_OK; | ||
568 | } | ||
569 | |||
570 | static acpi_status | ||
571 | acpi_ec_space_handler(u32 function, acpi_physical_address address, | 536 | acpi_ec_space_handler(u32 function, acpi_physical_address address, |
572 | u32 bits, acpi_integer *value, | 537 | u32 bits, acpi_integer *value, |
573 | void *handler_context, void *region_context) | 538 | void *handler_context, void *region_context) |
@@ -709,6 +674,8 @@ static struct acpi_ec *make_acpi_ec(void) | |||
709 | mutex_init(&ec->lock); | 674 | mutex_init(&ec->lock); |
710 | init_waitqueue_head(&ec->wait); | 675 | init_waitqueue_head(&ec->wait); |
711 | INIT_LIST_HEAD(&ec->list); | 676 | INIT_LIST_HEAD(&ec->list); |
677 | INIT_DELAYED_WORK_DEFERRABLE(&ec->work, do_ec_poll); | ||
678 | atomic_set(&ec->irq_count, 0); | ||
712 | return ec; | 679 | return ec; |
713 | } | 680 | } |
714 | 681 | ||
@@ -741,17 +708,21 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) | |||
741 | status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe); | 708 | status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe); |
742 | if (ACPI_FAILURE(status)) | 709 | if (ACPI_FAILURE(status)) |
743 | return status; | 710 | return status; |
744 | /* Find and register all query methods */ | ||
745 | acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1, | ||
746 | acpi_ec_register_query_methods, ec, NULL); | ||
747 | /* Use the global lock for all EC transactions? */ | 711 | /* Use the global lock for all EC transactions? */ |
748 | acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock); | 712 | acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock); |
749 | ec->handle = handle; | 713 | ec->handle = handle; |
750 | return AE_CTRL_TERMINATE; | 714 | return AE_CTRL_TERMINATE; |
751 | } | 715 | } |
752 | 716 | ||
717 | static void ec_poll_stop(struct acpi_ec *ec) | ||
718 | { | ||
719 | clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags); | ||
720 | cancel_delayed_work(&ec->work); | ||
721 | } | ||
722 | |||
753 | static void ec_remove_handlers(struct acpi_ec *ec) | 723 | static void ec_remove_handlers(struct acpi_ec *ec) |
754 | { | 724 | { |
725 | ec_poll_stop(ec); | ||
755 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, | 726 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, |
756 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) | 727 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) |
757 | pr_err(PREFIX "failed to remove space handler\n"); | 728 | pr_err(PREFIX "failed to remove space handler\n"); |
@@ -771,31 +742,28 @@ static int acpi_ec_add(struct acpi_device *device) | |||
771 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); | 742 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); |
772 | 743 | ||
773 | /* Check for boot EC */ | 744 | /* Check for boot EC */ |
774 | if (boot_ec) { | 745 | if (boot_ec && |
775 | if (boot_ec->handle == device->handle) { | 746 | (boot_ec->handle == device->handle || |
776 | /* Pre-loaded EC from DSDT, just move pointer */ | 747 | boot_ec->handle == ACPI_ROOT_OBJECT)) { |
777 | ec = boot_ec; | 748 | ec = boot_ec; |
778 | boot_ec = NULL; | 749 | boot_ec = NULL; |
779 | goto end; | 750 | } else { |
780 | } else if (boot_ec->handle == ACPI_ROOT_OBJECT) { | 751 | ec = make_acpi_ec(); |
781 | /* ECDT-based EC, time to shut it down */ | 752 | if (!ec) |
782 | ec_remove_handlers(boot_ec); | 753 | return -ENOMEM; |
783 | kfree(boot_ec); | 754 | if (ec_parse_device(device->handle, 0, ec, NULL) != |
784 | first_ec = boot_ec = NULL; | 755 | AE_CTRL_TERMINATE) { |
756 | kfree(ec); | ||
757 | return -EINVAL; | ||
785 | } | 758 | } |
786 | } | 759 | } |
787 | 760 | ||
788 | ec = make_acpi_ec(); | ||
789 | if (!ec) | ||
790 | return -ENOMEM; | ||
791 | |||
792 | if (ec_parse_device(device->handle, 0, ec, NULL) != | ||
793 | AE_CTRL_TERMINATE) { | ||
794 | kfree(ec); | ||
795 | return -EINVAL; | ||
796 | } | ||
797 | ec->handle = device->handle; | 761 | ec->handle = device->handle; |
798 | end: | 762 | |
763 | /* Find and register all query methods */ | ||
764 | acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1, | ||
765 | acpi_ec_register_query_methods, ec, NULL); | ||
766 | |||
799 | if (!first_ec) | 767 | if (!first_ec) |
800 | first_ec = ec; | 768 | first_ec = ec; |
801 | acpi_driver_data(device) = ec; | 769 | acpi_driver_data(device) = ec; |
@@ -870,7 +838,7 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
870 | status = acpi_install_address_space_handler(ec->handle, | 838 | status = acpi_install_address_space_handler(ec->handle, |
871 | ACPI_ADR_SPACE_EC, | 839 | ACPI_ADR_SPACE_EC, |
872 | &acpi_ec_space_handler, | 840 | &acpi_ec_space_handler, |
873 | &acpi_ec_space_setup, ec); | 841 | NULL, ec); |
874 | if (ACPI_FAILURE(status)) { | 842 | if (ACPI_FAILURE(status)) { |
875 | acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); | 843 | acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); |
876 | return -ENODEV; | 844 | return -ENODEV; |
@@ -897,6 +865,7 @@ static int acpi_ec_start(struct acpi_device *device) | |||
897 | 865 | ||
898 | /* EC is fully operational, allow queries */ | 866 | /* EC is fully operational, allow queries */ |
899 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 867 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
868 | ec_schedule_ec_poll(ec); | ||
900 | return ret; | 869 | return ret; |
901 | } | 870 | } |
902 | 871 | ||
@@ -924,6 +893,11 @@ int __init acpi_boot_ec_enable(void) | |||
924 | return -EFAULT; | 893 | return -EFAULT; |
925 | } | 894 | } |
926 | 895 | ||
896 | static const struct acpi_device_id ec_device_ids[] = { | ||
897 | {"PNP0C09", 0}, | ||
898 | {"", 0}, | ||
899 | }; | ||
900 | |||
927 | int __init acpi_ec_ecdt_probe(void) | 901 | int __init acpi_ec_ecdt_probe(void) |
928 | { | 902 | { |
929 | int ret; | 903 | int ret; |
@@ -944,6 +918,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
944 | boot_ec->data_addr = ecdt_ptr->data.address; | 918 | boot_ec->data_addr = ecdt_ptr->data.address; |
945 | boot_ec->gpe = ecdt_ptr->gpe; | 919 | boot_ec->gpe = ecdt_ptr->gpe; |
946 | boot_ec->handle = ACPI_ROOT_OBJECT; | 920 | boot_ec->handle = ACPI_ROOT_OBJECT; |
921 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); | ||
947 | } else { | 922 | } else { |
948 | /* This workaround is needed only on some broken machines, | 923 | /* This workaround is needed only on some broken machines, |
949 | * which require early EC, but fail to provide ECDT */ | 924 | * which require early EC, but fail to provide ECDT */ |
@@ -973,6 +948,39 @@ int __init acpi_ec_ecdt_probe(void) | |||
973 | return -ENODEV; | 948 | return -ENODEV; |
974 | } | 949 | } |
975 | 950 | ||
951 | static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state) | ||
952 | { | ||
953 | struct acpi_ec *ec = acpi_driver_data(device); | ||
954 | /* Stop using GPE */ | ||
955 | set_bit(EC_FLAGS_NO_GPE, &ec->flags); | ||
956 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
957 | acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); | ||
958 | return 0; | ||
959 | } | ||
960 | |||
961 | static int acpi_ec_resume(struct acpi_device *device) | ||
962 | { | ||
963 | struct acpi_ec *ec = acpi_driver_data(device); | ||
964 | /* Enable use of GPE back */ | ||
965 | clear_bit(EC_FLAGS_NO_GPE, &ec->flags); | ||
966 | acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); | ||
967 | return 0; | ||
968 | } | ||
969 | |||
970 | static struct acpi_driver acpi_ec_driver = { | ||
971 | .name = "ec", | ||
972 | .class = ACPI_EC_CLASS, | ||
973 | .ids = ec_device_ids, | ||
974 | .ops = { | ||
975 | .add = acpi_ec_add, | ||
976 | .remove = acpi_ec_remove, | ||
977 | .start = acpi_ec_start, | ||
978 | .stop = acpi_ec_stop, | ||
979 | .suspend = acpi_ec_suspend, | ||
980 | .resume = acpi_ec_resume, | ||
981 | }, | ||
982 | }; | ||
983 | |||
976 | static int __init acpi_ec_init(void) | 984 | static int __init acpi_ec_init(void) |
977 | { | 985 | { |
978 | int result = 0; | 986 | int result = 0; |
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c index 3048801a37b5..5d30e5be1b1c 100644 --- a/drivers/acpi/events/evevent.c +++ b/drivers/acpi/events/evevent.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c index 0dadd2adc800..5354be44f876 100644 --- a/drivers/acpi/events/evgpe.c +++ b/drivers/acpi/events/evgpe.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -248,10 +248,6 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
248 | 248 | ||
249 | ACPI_FUNCTION_TRACE(ev_disable_gpe); | 249 | ACPI_FUNCTION_TRACE(ev_disable_gpe); |
250 | 250 | ||
251 | if (!(gpe_event_info->flags & ACPI_GPE_ENABLE_MASK)) { | ||
252 | return_ACPI_STATUS(AE_OK); | ||
253 | } | ||
254 | |||
255 | /* Make sure HW enable masks are updated */ | 251 | /* Make sure HW enable masks are updated */ |
256 | 252 | ||
257 | status = | 253 | status = |
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c index 361ebe6c4a6f..e6c4d4c49e79 100644 --- a/drivers/acpi/events/evgpeblk.c +++ b/drivers/acpi/events/evgpeblk.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index 21cb749d0c75..2113e58e2221 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -49,22 +49,7 @@ | |||
49 | #define _COMPONENT ACPI_EVENTS | 49 | #define _COMPONENT ACPI_EVENTS |
50 | ACPI_MODULE_NAME("evmisc") | 50 | ACPI_MODULE_NAME("evmisc") |
51 | 51 | ||
52 | /* Names for Notify() values, used for debug output */ | ||
53 | #ifdef ACPI_DEBUG_OUTPUT | ||
54 | static const char *acpi_notify_value_names[] = { | ||
55 | "Bus Check", | ||
56 | "Device Check", | ||
57 | "Device Wake", | ||
58 | "Eject Request", | ||
59 | "Device Check Light", | ||
60 | "Frequency Mismatch", | ||
61 | "Bus Mode Mismatch", | ||
62 | "Power Fault" | ||
63 | }; | ||
64 | #endif | ||
65 | |||
66 | /* Pointer to FACS needed for the Global Lock */ | 52 | /* Pointer to FACS needed for the Global Lock */ |
67 | |||
68 | static struct acpi_table_facs *facs = NULL; | 53 | static struct acpi_table_facs *facs = NULL; |
69 | 54 | ||
70 | /* Local prototypes */ | 55 | /* Local prototypes */ |
@@ -94,7 +79,6 @@ u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node) | |||
94 | switch (node->type) { | 79 | switch (node->type) { |
95 | case ACPI_TYPE_DEVICE: | 80 | case ACPI_TYPE_DEVICE: |
96 | case ACPI_TYPE_PROCESSOR: | 81 | case ACPI_TYPE_PROCESSOR: |
97 | case ACPI_TYPE_POWER: | ||
98 | case ACPI_TYPE_THERMAL: | 82 | case ACPI_TYPE_THERMAL: |
99 | /* | 83 | /* |
100 | * These are the ONLY objects that can receive ACPI notifications | 84 | * These are the ONLY objects that can receive ACPI notifications |
@@ -139,17 +123,9 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, | |||
139 | * initiate soft-off or sleep operation? | 123 | * initiate soft-off or sleep operation? |
140 | */ | 124 | */ |
141 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 125 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
142 | "Dispatching Notify(%X) on node %p\n", notify_value, | 126 | "Dispatching Notify on [%4.4s] Node %p Value 0x%2.2X (%s)\n", |
143 | node)); | 127 | acpi_ut_get_node_name(node), node, notify_value, |
144 | 128 | acpi_ut_get_notify_name(notify_value))); | |
145 | if (notify_value <= 7) { | ||
146 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notify value: %s\n", | ||
147 | acpi_notify_value_names[notify_value])); | ||
148 | } else { | ||
149 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
150 | "Notify value: 0x%2.2X **Device Specific**\n", | ||
151 | notify_value)); | ||
152 | } | ||
153 | 129 | ||
154 | /* Get the notify object attached to the NS Node */ | 130 | /* Get the notify object attached to the NS Node */ |
155 | 131 | ||
@@ -159,10 +135,12 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, | |||
159 | /* We have the notify object, Get the right handler */ | 135 | /* We have the notify object, Get the right handler */ |
160 | 136 | ||
161 | switch (node->type) { | 137 | switch (node->type) { |
138 | |||
139 | /* Notify allowed only on these types */ | ||
140 | |||
162 | case ACPI_TYPE_DEVICE: | 141 | case ACPI_TYPE_DEVICE: |
163 | case ACPI_TYPE_THERMAL: | 142 | case ACPI_TYPE_THERMAL: |
164 | case ACPI_TYPE_PROCESSOR: | 143 | case ACPI_TYPE_PROCESSOR: |
165 | case ACPI_TYPE_POWER: | ||
166 | 144 | ||
167 | if (notify_value <= ACPI_MAX_SYS_NOTIFY) { | 145 | if (notify_value <= ACPI_MAX_SYS_NOTIFY) { |
168 | handler_obj = | 146 | handler_obj = |
@@ -179,8 +157,13 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, | |||
179 | } | 157 | } |
180 | } | 158 | } |
181 | 159 | ||
182 | /* If there is any handler to run, schedule the dispatcher */ | 160 | /* |
183 | 161 | * If there is any handler to run, schedule the dispatcher. | |
162 | * Check for: | ||
163 | * 1) Global system notify handler | ||
164 | * 2) Global device notify handler | ||
165 | * 3) Per-device notify handler | ||
166 | */ | ||
184 | if ((acpi_gbl_system_notify.handler | 167 | if ((acpi_gbl_system_notify.handler |
185 | && (notify_value <= ACPI_MAX_SYS_NOTIFY)) | 168 | && (notify_value <= ACPI_MAX_SYS_NOTIFY)) |
186 | || (acpi_gbl_device_notify.handler | 169 | || (acpi_gbl_device_notify.handler |
@@ -190,6 +173,13 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, | |||
190 | return (AE_NO_MEMORY); | 173 | return (AE_NO_MEMORY); |
191 | } | 174 | } |
192 | 175 | ||
176 | if (!handler_obj) { | ||
177 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
178 | "Executing system notify handler for Notify (%4.4s, %X) node %p\n", | ||
179 | acpi_ut_get_node_name(node), | ||
180 | notify_value, node)); | ||
181 | } | ||
182 | |||
193 | notify_info->common.descriptor_type = | 183 | notify_info->common.descriptor_type = |
194 | ACPI_DESC_TYPE_STATE_NOTIFY; | 184 | ACPI_DESC_TYPE_STATE_NOTIFY; |
195 | notify_info->notify.node = node; | 185 | notify_info->notify.node = node; |
@@ -202,15 +192,12 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, | |||
202 | if (ACPI_FAILURE(status)) { | 192 | if (ACPI_FAILURE(status)) { |
203 | acpi_ut_delete_generic_state(notify_info); | 193 | acpi_ut_delete_generic_state(notify_info); |
204 | } | 194 | } |
205 | } | 195 | } else { |
206 | |||
207 | if (!handler_obj) { | ||
208 | /* | 196 | /* |
209 | * There is no per-device notify handler for this device. | 197 | * There is no notify handler (per-device or system) for this device. |
210 | * This may or may not be a problem. | ||
211 | */ | 198 | */ |
212 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 199 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
213 | "No notify handler for Notify(%4.4s, %X) node %p\n", | 200 | "No notify handler for Notify (%4.4s, %X) node %p\n", |
214 | acpi_ut_get_node_name(node), notify_value, | 201 | acpi_ut_get_node_name(node), notify_value, |
215 | node)); | 202 | node)); |
216 | } | 203 | } |
@@ -349,9 +336,10 @@ acpi_status acpi_ev_init_global_lock_handler(void) | |||
349 | 336 | ||
350 | ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); | 337 | ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); |
351 | 338 | ||
352 | status = | 339 | status = acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, |
353 | acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, | 340 | ACPI_CAST_INDIRECT_PTR(struct |
354 | (struct acpi_table_header **)&facs); | 341 | acpi_table_header, |
342 | &facs)); | ||
355 | if (ACPI_FAILURE(status)) { | 343 | if (ACPI_FAILURE(status)) { |
356 | return_ACPI_STATUS(status); | 344 | return_ACPI_STATUS(status); |
357 | } | 345 | } |
@@ -439,7 +427,8 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) | |||
439 | * Only one thread can acquire the GL at a time, the global_lock_mutex | 427 | * Only one thread can acquire the GL at a time, the global_lock_mutex |
440 | * enforces this. This interface releases the interpreter if we must wait. | 428 | * enforces this. This interface releases the interpreter if we must wait. |
441 | */ | 429 | */ |
442 | status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, 0); | 430 | status = acpi_ex_system_wait_mutex( |
431 | acpi_gbl_global_lock_mutex->mutex.os_mutex, 0); | ||
443 | if (status == AE_TIME) { | 432 | if (status == AE_TIME) { |
444 | if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) { | 433 | if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) { |
445 | acpi_ev_global_lock_acquired++; | 434 | acpi_ev_global_lock_acquired++; |
@@ -448,9 +437,9 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) | |||
448 | } | 437 | } |
449 | 438 | ||
450 | if (ACPI_FAILURE(status)) { | 439 | if (ACPI_FAILURE(status)) { |
451 | status = | 440 | status = acpi_ex_system_wait_mutex( |
452 | acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, | 441 | acpi_gbl_global_lock_mutex->mutex.os_mutex, |
453 | timeout); | 442 | timeout); |
454 | } | 443 | } |
455 | if (ACPI_FAILURE(status)) { | 444 | if (ACPI_FAILURE(status)) { |
456 | return_ACPI_STATUS(status); | 445 | return_ACPI_STATUS(status); |
@@ -460,6 +449,19 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) | |||
460 | acpi_ev_global_lock_acquired++; | 449 | acpi_ev_global_lock_acquired++; |
461 | 450 | ||
462 | /* | 451 | /* |
452 | * Update the global lock handle and check for wraparound. The handle is | ||
453 | * only used for the external global lock interfaces, but it is updated | ||
454 | * here to properly handle the case where a single thread may acquire the | ||
455 | * lock via both the AML and the acpi_acquire_global_lock interfaces. The | ||
456 | * handle is therefore updated on the first acquire from a given thread | ||
457 | * regardless of where the acquisition request originated. | ||
458 | */ | ||
459 | acpi_gbl_global_lock_handle++; | ||
460 | if (acpi_gbl_global_lock_handle == 0) { | ||
461 | acpi_gbl_global_lock_handle = 1; | ||
462 | } | ||
463 | |||
464 | /* | ||
463 | * Make sure that a global lock actually exists. If not, just treat | 465 | * Make sure that a global lock actually exists. If not, just treat |
464 | * the lock as a standard mutex. | 466 | * the lock as a standard mutex. |
465 | */ | 467 | */ |
@@ -555,7 +557,7 @@ acpi_status acpi_ev_release_global_lock(void) | |||
555 | /* Release the local GL mutex */ | 557 | /* Release the local GL mutex */ |
556 | acpi_ev_global_lock_thread_id = NULL; | 558 | acpi_ev_global_lock_thread_id = NULL; |
557 | acpi_ev_global_lock_acquired = 0; | 559 | acpi_ev_global_lock_acquired = 0; |
558 | acpi_os_release_mutex(acpi_gbl_global_lock_mutex); | 560 | acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex); |
559 | return_ACPI_STATUS(status); | 561 | return_ACPI_STATUS(status); |
560 | } | 562 | } |
561 | 563 | ||
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c index 58ad09725dd2..1628f5934752 100644 --- a/drivers/acpi/events/evregion.c +++ b/drivers/acpi/events/evregion.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -394,7 +394,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | |||
394 | ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, | 394 | ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, |
395 | "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", | 395 | "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", |
396 | ®ion_obj->region.handler->address_space, handler, | 396 | ®ion_obj->region.handler->address_space, handler, |
397 | ACPI_FORMAT_UINT64(address), | 397 | ACPI_FORMAT_NATIVE_UINT(address), |
398 | acpi_ut_get_region_name(region_obj->region. | 398 | acpi_ut_get_region_name(region_obj->region. |
399 | space_id))); | 399 | space_id))); |
400 | 400 | ||
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c index b1aaa0e84588..2e3d2c5e4f4d 100644 --- a/drivers/acpi/events/evrgnini.c +++ b/drivers/acpi/events/evrgnini.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c index 7e5d15ce2395..2a8b77877610 100644 --- a/drivers/acpi/events/evsci.c +++ b/drivers/acpi/events/evsci.c | |||
@@ -6,7 +6,7 @@ | |||
6 | ******************************************************************************/ | 6 | ******************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c index 6d866a01f5f4..94a6efe020be 100644 --- a/drivers/acpi/events/evxface.c +++ b/drivers/acpi/events/evxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -758,6 +758,12 @@ ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler) | |||
758 | * | 758 | * |
759 | * DESCRIPTION: Acquire the ACPI Global Lock | 759 | * DESCRIPTION: Acquire the ACPI Global Lock |
760 | * | 760 | * |
761 | * Note: Allows callers with the same thread ID to acquire the global lock | ||
762 | * multiple times. In other words, externally, the behavior of the global lock | ||
763 | * is identical to an AML mutex. On the first acquire, a new handle is | ||
764 | * returned. On any subsequent calls to acquire by the same thread, the same | ||
765 | * handle is returned. | ||
766 | * | ||
761 | ******************************************************************************/ | 767 | ******************************************************************************/ |
762 | acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle) | 768 | acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle) |
763 | { | 769 | { |
@@ -770,14 +776,19 @@ acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle) | |||
770 | /* Must lock interpreter to prevent race conditions */ | 776 | /* Must lock interpreter to prevent race conditions */ |
771 | 777 | ||
772 | acpi_ex_enter_interpreter(); | 778 | acpi_ex_enter_interpreter(); |
773 | status = acpi_ev_acquire_global_lock(timeout); | 779 | |
774 | acpi_ex_exit_interpreter(); | 780 | status = acpi_ex_acquire_mutex_object(timeout, |
781 | acpi_gbl_global_lock_mutex, | ||
782 | acpi_os_get_thread_id()); | ||
775 | 783 | ||
776 | if (ACPI_SUCCESS(status)) { | 784 | if (ACPI_SUCCESS(status)) { |
777 | acpi_gbl_global_lock_handle++; | 785 | |
786 | /* Return the global lock handle (updated in acpi_ev_acquire_global_lock) */ | ||
787 | |||
778 | *handle = acpi_gbl_global_lock_handle; | 788 | *handle = acpi_gbl_global_lock_handle; |
779 | } | 789 | } |
780 | 790 | ||
791 | acpi_ex_exit_interpreter(); | ||
781 | return (status); | 792 | return (status); |
782 | } | 793 | } |
783 | 794 | ||
@@ -798,11 +809,11 @@ acpi_status acpi_release_global_lock(u32 handle) | |||
798 | { | 809 | { |
799 | acpi_status status; | 810 | acpi_status status; |
800 | 811 | ||
801 | if (handle != acpi_gbl_global_lock_handle) { | 812 | if (!handle || (handle != acpi_gbl_global_lock_handle)) { |
802 | return (AE_NOT_ACQUIRED); | 813 | return (AE_NOT_ACQUIRED); |
803 | } | 814 | } |
804 | 815 | ||
805 | status = acpi_ev_release_global_lock(); | 816 | status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex); |
806 | return (status); | 817 | return (status); |
807 | } | 818 | } |
808 | 819 | ||
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c index 9cbd3414a574..99a7502e6a87 100644 --- a/drivers/acpi/events/evxfevnt.c +++ b/drivers/acpi/events/evxfevnt.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c index 7bf09c5fb242..e8750807e57d 100644 --- a/drivers/acpi/events/evxfregn.c +++ b/drivers/acpi/events/evxfregn.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index 25802f302ffe..24da921d13e3 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -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/acevents.h> | ||
49 | #include <acpi/actables.h> | 48 | #include <acpi/actables.h> |
50 | #include <acpi/acdispat.h> | 49 | #include <acpi/acdispat.h> |
51 | 50 | ||
@@ -138,6 +137,14 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
138 | 137 | ||
139 | ACPI_FUNCTION_TRACE(ex_load_table_op); | 138 | ACPI_FUNCTION_TRACE(ex_load_table_op); |
140 | 139 | ||
140 | /* Validate lengths for the signature_string, OEMIDString, OEMtable_iD */ | ||
141 | |||
142 | if ((operand[0]->string.length > ACPI_NAME_SIZE) || | ||
143 | (operand[1]->string.length > ACPI_OEM_ID_SIZE) || | ||
144 | (operand[2]->string.length > ACPI_OEM_TABLE_ID_SIZE)) { | ||
145 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
146 | } | ||
147 | |||
141 | /* Find the ACPI table in the RSDT/XSDT */ | 148 | /* Find the ACPI table in the RSDT/XSDT */ |
142 | 149 | ||
143 | status = acpi_tb_find_table(operand[0]->string.pointer, | 150 | status = acpi_tb_find_table(operand[0]->string.pointer, |
@@ -229,11 +236,18 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
229 | status = acpi_get_table_by_index(table_index, &table); | 236 | status = acpi_get_table_by_index(table_index, &table); |
230 | if (ACPI_SUCCESS(status)) { | 237 | if (ACPI_SUCCESS(status)) { |
231 | ACPI_INFO((AE_INFO, | 238 | ACPI_INFO((AE_INFO, |
232 | "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]", | 239 | "Dynamic OEM Table Load - [%.4s] OemId [%.6s] OemTableId [%.8s]", |
233 | table->signature, table->oem_id, | 240 | table->signature, table->oem_id, |
234 | table->oem_table_id)); | 241 | table->oem_table_id)); |
235 | } | 242 | } |
236 | 243 | ||
244 | /* Invoke table handler if present */ | ||
245 | |||
246 | if (acpi_gbl_table_handler) { | ||
247 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, | ||
248 | acpi_gbl_table_handler_context); | ||
249 | } | ||
250 | |||
237 | *return_desc = ddb_handle; | 251 | *return_desc = ddb_handle; |
238 | return_ACPI_STATUS(status); | 252 | return_ACPI_STATUS(status); |
239 | } | 253 | } |
@@ -268,6 +282,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
268 | struct acpi_table_desc table_desc; | 282 | struct acpi_table_desc table_desc; |
269 | acpi_native_uint table_index; | 283 | acpi_native_uint table_index; |
270 | acpi_status status; | 284 | acpi_status status; |
285 | u32 length; | ||
271 | 286 | ||
272 | ACPI_FUNCTION_TRACE(ex_load_op); | 287 | ACPI_FUNCTION_TRACE(ex_load_op); |
273 | 288 | ||
@@ -278,16 +293,16 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
278 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 293 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { |
279 | case ACPI_TYPE_REGION: | 294 | case ACPI_TYPE_REGION: |
280 | 295 | ||
296 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n", | ||
297 | obj_desc, | ||
298 | acpi_ut_get_object_type_name(obj_desc))); | ||
299 | |||
281 | /* Region must be system_memory (from ACPI spec) */ | 300 | /* Region must be system_memory (from ACPI spec) */ |
282 | 301 | ||
283 | if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 302 | if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
284 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 303 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
285 | } | 304 | } |
286 | 305 | ||
287 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n", | ||
288 | obj_desc, | ||
289 | acpi_ut_get_object_type_name(obj_desc))); | ||
290 | |||
291 | /* | 306 | /* |
292 | * If the Region Address and Length have not been previously evaluated, | 307 | * If the Region Address and Length have not been previously evaluated, |
293 | * evaluate them now and save the results. | 308 | * evaluate them now and save the results. |
@@ -299,6 +314,11 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
299 | } | 314 | } |
300 | } | 315 | } |
301 | 316 | ||
317 | /* | ||
318 | * We will simply map the memory region for the table. However, the | ||
319 | * memory region is technically not guaranteed to remain stable and | ||
320 | * we may eventually have to copy the table to a local buffer. | ||
321 | */ | ||
302 | table_desc.address = obj_desc->region.address; | 322 | table_desc.address = obj_desc->region.address; |
303 | table_desc.length = obj_desc->region.length; | 323 | table_desc.length = obj_desc->region.length; |
304 | table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED; | 324 | table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED; |
@@ -306,18 +326,41 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
306 | 326 | ||
307 | case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ | 327 | case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ |
308 | 328 | ||
309 | /* Simply extract the buffer from the buffer object */ | ||
310 | |||
311 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 329 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
312 | "Load from Buffer or Field %p %s\n", obj_desc, | 330 | "Load from Buffer or Field %p %s\n", obj_desc, |
313 | acpi_ut_get_object_type_name(obj_desc))); | 331 | acpi_ut_get_object_type_name(obj_desc))); |
314 | 332 | ||
315 | table_desc.pointer = ACPI_CAST_PTR(struct acpi_table_header, | 333 | length = obj_desc->buffer.length; |
316 | obj_desc->buffer.pointer); | 334 | |
317 | table_desc.length = table_desc.pointer->length; | 335 | /* Must have at least an ACPI table header */ |
318 | table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED; | 336 | |
337 | if (length < sizeof(struct acpi_table_header)) { | ||
338 | return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); | ||
339 | } | ||
340 | |||
341 | /* Validate checksum here. It won't get validated in tb_add_table */ | ||
319 | 342 | ||
320 | obj_desc->buffer.pointer = NULL; | 343 | status = |
344 | acpi_tb_verify_checksum(ACPI_CAST_PTR | ||
345 | (struct acpi_table_header, | ||
346 | obj_desc->buffer.pointer), length); | ||
347 | if (ACPI_FAILURE(status)) { | ||
348 | return_ACPI_STATUS(status); | ||
349 | } | ||
350 | |||
351 | /* | ||
352 | * We need to copy the buffer since the original buffer could be | ||
353 | * changed or deleted in the future | ||
354 | */ | ||
355 | table_desc.pointer = ACPI_ALLOCATE(length); | ||
356 | if (!table_desc.pointer) { | ||
357 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
358 | } | ||
359 | |||
360 | ACPI_MEMCPY(table_desc.pointer, obj_desc->buffer.pointer, | ||
361 | length); | ||
362 | table_desc.length = length; | ||
363 | table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED; | ||
321 | break; | 364 | break; |
322 | 365 | ||
323 | default: | 366 | default: |
@@ -333,7 +376,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
333 | } | 376 | } |
334 | 377 | ||
335 | status = | 378 | status = |
336 | acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle); | 379 | acpi_ex_add_table(table_index, walk_state->scope_info->scope.node, |
380 | &ddb_handle); | ||
337 | if (ACPI_FAILURE(status)) { | 381 | if (ACPI_FAILURE(status)) { |
338 | 382 | ||
339 | /* On error, table_ptr was deallocated above */ | 383 | /* On error, table_ptr was deallocated above */ |
@@ -349,11 +393,23 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
349 | 393 | ||
350 | /* table_ptr was deallocated above */ | 394 | /* table_ptr was deallocated above */ |
351 | 395 | ||
396 | acpi_ut_remove_reference(ddb_handle); | ||
352 | return_ACPI_STATUS(status); | 397 | return_ACPI_STATUS(status); |
353 | } | 398 | } |
354 | 399 | ||
400 | /* Invoke table handler if present */ | ||
401 | |||
402 | if (acpi_gbl_table_handler) { | ||
403 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, | ||
404 | table_desc.pointer, | ||
405 | acpi_gbl_table_handler_context); | ||
406 | } | ||
407 | |||
355 | cleanup: | 408 | cleanup: |
356 | if (ACPI_FAILURE(status)) { | 409 | if (ACPI_FAILURE(status)) { |
410 | |||
411 | /* Delete allocated buffer or mapping */ | ||
412 | |||
357 | acpi_tb_delete_table(&table_desc); | 413 | acpi_tb_delete_table(&table_desc); |
358 | } | 414 | } |
359 | return_ACPI_STATUS(status); | 415 | return_ACPI_STATUS(status); |
@@ -376,6 +432,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
376 | acpi_status status = AE_OK; | 432 | acpi_status status = AE_OK; |
377 | union acpi_operand_object *table_desc = ddb_handle; | 433 | union acpi_operand_object *table_desc = ddb_handle; |
378 | acpi_native_uint table_index; | 434 | acpi_native_uint table_index; |
435 | struct acpi_table_header *table; | ||
379 | 436 | ||
380 | ACPI_FUNCTION_TRACE(ex_unload_table); | 437 | ACPI_FUNCTION_TRACE(ex_unload_table); |
381 | 438 | ||
@@ -395,17 +452,25 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
395 | 452 | ||
396 | table_index = (acpi_native_uint) table_desc->reference.object; | 453 | table_index = (acpi_native_uint) table_desc->reference.object; |
397 | 454 | ||
455 | /* Invoke table handler if present */ | ||
456 | |||
457 | if (acpi_gbl_table_handler) { | ||
458 | status = acpi_get_table_by_index(table_index, &table); | ||
459 | if (ACPI_SUCCESS(status)) { | ||
460 | (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD, | ||
461 | table, | ||
462 | acpi_gbl_table_handler_context); | ||
463 | } | ||
464 | } | ||
465 | |||
398 | /* | 466 | /* |
399 | * Delete the entire namespace under this table Node | 467 | * Delete the entire namespace under this table Node |
400 | * (Offset contains the table_id) | 468 | * (Offset contains the table_id) |
401 | */ | 469 | */ |
402 | acpi_tb_delete_namespace_by_owner(table_index); | 470 | acpi_tb_delete_namespace_by_owner(table_index); |
403 | acpi_tb_release_owner_id(table_index); | 471 | (void)acpi_tb_release_owner_id(table_index); |
404 | 472 | ||
405 | acpi_tb_set_table_loaded_flag(table_index, FALSE); | 473 | acpi_tb_set_table_loaded_flag(table_index, FALSE); |
406 | 474 | ||
407 | /* Delete the table descriptor (ddb_handle) */ | 475 | return_ACPI_STATUS(AE_OK); |
408 | |||
409 | acpi_ut_remove_reference(table_desc); | ||
410 | return_ACPI_STATUS(status); | ||
411 | } | 476 | } |
diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c index 79f2c0d42c06..fd954b4ed83d 100644 --- a/drivers/acpi/executer/exconvrt.c +++ b/drivers/acpi/executer/exconvrt.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c index 6e9a23e47fef..60e62c4f0577 100644 --- a/drivers/acpi/executer/excreate.c +++ b/drivers/acpi/executer/excreate.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -96,6 +96,9 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state) | |||
96 | * to the original Node. | 96 | * to the original Node. |
97 | */ | 97 | */ |
98 | switch (target_node->type) { | 98 | switch (target_node->type) { |
99 | |||
100 | /* For these types, the sub-object can change dynamically via a Store */ | ||
101 | |||
99 | case ACPI_TYPE_INTEGER: | 102 | case ACPI_TYPE_INTEGER: |
100 | case ACPI_TYPE_STRING: | 103 | case ACPI_TYPE_STRING: |
101 | case ACPI_TYPE_BUFFER: | 104 | case ACPI_TYPE_BUFFER: |
@@ -103,9 +106,18 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state) | |||
103 | case ACPI_TYPE_BUFFER_FIELD: | 106 | case ACPI_TYPE_BUFFER_FIELD: |
104 | 107 | ||
105 | /* | 108 | /* |
109 | * These types open a new scope, so we need the NS node in order to access | ||
110 | * any children. | ||
111 | */ | ||
112 | case ACPI_TYPE_DEVICE: | ||
113 | case ACPI_TYPE_POWER: | ||
114 | case ACPI_TYPE_PROCESSOR: | ||
115 | case ACPI_TYPE_THERMAL: | ||
116 | case ACPI_TYPE_LOCAL_SCOPE: | ||
117 | |||
118 | /* | ||
106 | * The new alias has the type ALIAS and points to the original | 119 | * The new alias has the type ALIAS and points to the original |
107 | * NS node, not the object itself. This is because for these | 120 | * NS node, not the object itself. |
108 | * types, the object can change dynamically via a Store. | ||
109 | */ | 121 | */ |
110 | alias_node->type = ACPI_TYPE_LOCAL_ALIAS; | 122 | alias_node->type = ACPI_TYPE_LOCAL_ALIAS; |
111 | alias_node->object = | 123 | alias_node->object = |
@@ -115,9 +127,7 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state) | |||
115 | case ACPI_TYPE_METHOD: | 127 | case ACPI_TYPE_METHOD: |
116 | 128 | ||
117 | /* | 129 | /* |
118 | * The new alias has the type ALIAS and points to the original | 130 | * Control method aliases need to be differentiated |
119 | * NS node, not the object itself. This is because for these | ||
120 | * types, the object can change dynamically via a Store. | ||
121 | */ | 131 | */ |
122 | alias_node->type = ACPI_TYPE_LOCAL_METHOD_ALIAS; | 132 | alias_node->type = ACPI_TYPE_LOCAL_METHOD_ALIAS; |
123 | alias_node->object = | 133 | alias_node->object = |
@@ -342,101 +352,6 @@ acpi_ex_create_region(u8 * aml_start, | |||
342 | 352 | ||
343 | /******************************************************************************* | 353 | /******************************************************************************* |
344 | * | 354 | * |
345 | * FUNCTION: acpi_ex_create_table_region | ||
346 | * | ||
347 | * PARAMETERS: walk_state - Current state | ||
348 | * | ||
349 | * RETURN: Status | ||
350 | * | ||
351 | * DESCRIPTION: Create a new data_table_region object | ||
352 | * | ||
353 | ******************************************************************************/ | ||
354 | |||
355 | acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state) | ||
356 | { | ||
357 | acpi_status status; | ||
358 | union acpi_operand_object **operand = &walk_state->operands[0]; | ||
359 | union acpi_operand_object *obj_desc; | ||
360 | struct acpi_namespace_node *node; | ||
361 | union acpi_operand_object *region_obj2; | ||
362 | acpi_native_uint table_index; | ||
363 | struct acpi_table_header *table; | ||
364 | |||
365 | ACPI_FUNCTION_TRACE(ex_create_table_region); | ||
366 | |||
367 | /* Get the Node from the object stack */ | ||
368 | |||
369 | node = walk_state->op->common.node; | ||
370 | |||
371 | /* | ||
372 | * If the region object is already attached to this node, | ||
373 | * just return | ||
374 | */ | ||
375 | if (acpi_ns_get_attached_object(node)) { | ||
376 | return_ACPI_STATUS(AE_OK); | ||
377 | } | ||
378 | |||
379 | /* Find the ACPI table */ | ||
380 | |||
381 | status = acpi_tb_find_table(operand[1]->string.pointer, | ||
382 | operand[2]->string.pointer, | ||
383 | operand[3]->string.pointer, &table_index); | ||
384 | if (ACPI_FAILURE(status)) { | ||
385 | return_ACPI_STATUS(status); | ||
386 | } | ||
387 | |||
388 | /* Create the region descriptor */ | ||
389 | |||
390 | obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION); | ||
391 | if (!obj_desc) { | ||
392 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
393 | } | ||
394 | |||
395 | region_obj2 = obj_desc->common.next_object; | ||
396 | region_obj2->extra.region_context = NULL; | ||
397 | |||
398 | status = acpi_get_table_by_index(table_index, &table); | ||
399 | if (ACPI_FAILURE(status)) { | ||
400 | return_ACPI_STATUS(status); | ||
401 | } | ||
402 | |||
403 | /* Init the region from the operands */ | ||
404 | |||
405 | obj_desc->region.space_id = REGION_DATA_TABLE; | ||
406 | obj_desc->region.address = | ||
407 | (acpi_physical_address) ACPI_TO_INTEGER(table); | ||
408 | obj_desc->region.length = table->length; | ||
409 | obj_desc->region.node = node; | ||
410 | obj_desc->region.flags = AOPOBJ_DATA_VALID; | ||
411 | |||
412 | /* Install the new region object in the parent Node */ | ||
413 | |||
414 | status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_REGION); | ||
415 | if (ACPI_FAILURE(status)) { | ||
416 | goto cleanup; | ||
417 | } | ||
418 | |||
419 | status = acpi_ev_initialize_region(obj_desc, FALSE); | ||
420 | if (ACPI_FAILURE(status)) { | ||
421 | if (status == AE_NOT_EXIST) { | ||
422 | status = AE_OK; | ||
423 | } else { | ||
424 | goto cleanup; | ||
425 | } | ||
426 | } | ||
427 | |||
428 | obj_desc->region.flags |= AOPOBJ_SETUP_COMPLETE; | ||
429 | |||
430 | cleanup: | ||
431 | |||
432 | /* Remove local reference to the object */ | ||
433 | |||
434 | acpi_ut_remove_reference(obj_desc); | ||
435 | return_ACPI_STATUS(status); | ||
436 | } | ||
437 | |||
438 | /******************************************************************************* | ||
439 | * | ||
440 | * FUNCTION: acpi_ex_create_processor | 355 | * FUNCTION: acpi_ex_create_processor |
441 | * | 356 | * |
442 | * PARAMETERS: walk_state - Current state | 357 | * PARAMETERS: walk_state - Current state |
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 51c9c29987c3..74f1b22601b3 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -500,25 +500,28 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) | |||
500 | acpi_os_printf("Reference: Debug\n"); | 500 | acpi_os_printf("Reference: Debug\n"); |
501 | break; | 501 | break; |
502 | 502 | ||
503 | case AML_NAME_OP: | 503 | case AML_INDEX_OP: |
504 | 504 | ||
505 | ACPI_DUMP_PATHNAME(obj_desc->reference.object, | 505 | acpi_os_printf("Reference: Index %p\n", |
506 | "Reference: Name: ", ACPI_LV_INFO, | 506 | obj_desc->reference.object); |
507 | _COMPONENT); | ||
508 | ACPI_DUMP_ENTRY(obj_desc->reference.object, | ||
509 | ACPI_LV_INFO); | ||
510 | break; | 507 | break; |
511 | 508 | ||
512 | case AML_INDEX_OP: | 509 | case AML_LOAD_OP: |
513 | 510 | ||
514 | acpi_os_printf("Reference: Index %p\n", | 511 | acpi_os_printf("Reference: [DdbHandle] TableIndex %p\n", |
515 | obj_desc->reference.object); | 512 | obj_desc->reference.object); |
516 | break; | 513 | break; |
517 | 514 | ||
518 | case AML_REF_OF_OP: | 515 | case AML_REF_OF_OP: |
519 | 516 | ||
520 | acpi_os_printf("Reference: (RefOf) %p\n", | 517 | acpi_os_printf("Reference: (RefOf) %p [%s]\n", |
521 | obj_desc->reference.object); | 518 | obj_desc->reference.object, |
519 | acpi_ut_get_type_name(((union | ||
520 | acpi_operand_object | ||
521 | *)obj_desc-> | ||
522 | reference. | ||
523 | object)->common. | ||
524 | type)); | ||
522 | break; | 525 | break; |
523 | 526 | ||
524 | case AML_ARG_OP: | 527 | case AML_ARG_OP: |
@@ -559,8 +562,9 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) | |||
559 | 562 | ||
560 | case AML_INT_NAMEPATH_OP: | 563 | case AML_INT_NAMEPATH_OP: |
561 | 564 | ||
562 | acpi_os_printf("Reference.Node->Name %X\n", | 565 | acpi_os_printf("Reference: Namepath %X [%4.4s]\n", |
563 | obj_desc->reference.node->name.integer); | 566 | obj_desc->reference.node->name.integer, |
567 | obj_desc->reference.node->name.ascii); | ||
564 | break; | 568 | break; |
565 | 569 | ||
566 | default: | 570 | default: |
@@ -640,8 +644,8 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) | |||
640 | acpi_os_printf("\n"); | 644 | acpi_os_printf("\n"); |
641 | } else { | 645 | } else { |
642 | acpi_os_printf(" base %8.8X%8.8X Length %X\n", | 646 | acpi_os_printf(" base %8.8X%8.8X Length %X\n", |
643 | ACPI_FORMAT_UINT64(obj_desc->region. | 647 | ACPI_FORMAT_NATIVE_UINT(obj_desc->region. |
644 | address), | 648 | address), |
645 | obj_desc->region.length); | 649 | obj_desc->region.length); |
646 | } | 650 | } |
647 | break; | 651 | break; |
@@ -877,20 +881,43 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc) | |||
877 | ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER; | 881 | ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER; |
878 | 882 | ||
879 | if (obj_desc->reference.opcode == AML_INT_NAMEPATH_OP) { | 883 | if (obj_desc->reference.opcode == AML_INT_NAMEPATH_OP) { |
880 | acpi_os_printf("Named Object %p ", obj_desc->reference.node); | 884 | acpi_os_printf(" Named Object %p ", obj_desc->reference.node); |
881 | 885 | ||
882 | status = | 886 | status = |
883 | acpi_ns_handle_to_pathname(obj_desc->reference.node, | 887 | acpi_ns_handle_to_pathname(obj_desc->reference.node, |
884 | &ret_buf); | 888 | &ret_buf); |
885 | if (ACPI_FAILURE(status)) { | 889 | if (ACPI_FAILURE(status)) { |
886 | acpi_os_printf("Could not convert name to pathname\n"); | 890 | acpi_os_printf(" Could not convert name to pathname\n"); |
887 | } else { | 891 | } else { |
888 | acpi_os_printf("%s\n", (char *)ret_buf.pointer); | 892 | acpi_os_printf("%s\n", (char *)ret_buf.pointer); |
889 | ACPI_FREE(ret_buf.pointer); | 893 | ACPI_FREE(ret_buf.pointer); |
890 | } | 894 | } |
891 | } else if (obj_desc->reference.object) { | 895 | } else if (obj_desc->reference.object) { |
892 | acpi_os_printf("\nReferenced Object: %p\n", | 896 | if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == |
893 | obj_desc->reference.object); | 897 | ACPI_DESC_TYPE_OPERAND) { |
898 | acpi_os_printf(" Target: %p", | ||
899 | obj_desc->reference.object); | ||
900 | if (obj_desc->reference.opcode == AML_LOAD_OP) { | ||
901 | /* | ||
902 | * For DDBHandle reference, | ||
903 | * obj_desc->Reference.Object is the table index | ||
904 | */ | ||
905 | acpi_os_printf(" [DDBHandle]\n"); | ||
906 | } else { | ||
907 | acpi_os_printf(" [%s]\n", | ||
908 | acpi_ut_get_type_name(((union | ||
909 | acpi_operand_object | ||
910 | *) | ||
911 | obj_desc-> | ||
912 | reference. | ||
913 | object)-> | ||
914 | common. | ||
915 | type)); | ||
916 | } | ||
917 | } else { | ||
918 | acpi_os_printf(" Target: %p\n", | ||
919 | obj_desc->reference.object); | ||
920 | } | ||
894 | } | 921 | } |
895 | } | 922 | } |
896 | 923 | ||
@@ -976,7 +1003,9 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc, | |||
976 | 1003 | ||
977 | case ACPI_TYPE_LOCAL_REFERENCE: | 1004 | case ACPI_TYPE_LOCAL_REFERENCE: |
978 | 1005 | ||
979 | acpi_os_printf("[Object Reference] "); | 1006 | acpi_os_printf("[Object Reference] %s", |
1007 | (acpi_ps_get_opcode_info | ||
1008 | (obj_desc->reference.opcode))->name); | ||
980 | acpi_ex_dump_reference_obj(obj_desc); | 1009 | acpi_ex_dump_reference_obj(obj_desc); |
981 | break; | 1010 | break; |
982 | 1011 | ||
diff --git a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c index 2d88a3d8d1ad..3e440d84226a 100644 --- a/drivers/acpi/executer/exfield.c +++ b/drivers/acpi/executer/exfield.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -71,7 +71,6 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | |||
71 | union acpi_operand_object *buffer_desc; | 71 | union acpi_operand_object *buffer_desc; |
72 | acpi_size length; | 72 | acpi_size length; |
73 | void *buffer; | 73 | void *buffer; |
74 | u8 locked; | ||
75 | 74 | ||
76 | ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); | 75 | ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); |
77 | 76 | ||
@@ -111,9 +110,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | |||
111 | 110 | ||
112 | /* Lock entire transaction if requested */ | 111 | /* Lock entire transaction if requested */ |
113 | 112 | ||
114 | locked = | 113 | acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); |
115 | acpi_ex_acquire_global_lock(obj_desc->common_field. | ||
116 | field_flags); | ||
117 | 114 | ||
118 | /* | 115 | /* |
119 | * Perform the read. | 116 | * Perform the read. |
@@ -125,7 +122,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | |||
125 | buffer.pointer), | 122 | buffer.pointer), |
126 | ACPI_READ | (obj_desc->field. | 123 | ACPI_READ | (obj_desc->field. |
127 | attribute << 16)); | 124 | attribute << 16)); |
128 | acpi_ex_release_global_lock(locked); | 125 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); |
129 | goto exit; | 126 | goto exit; |
130 | } | 127 | } |
131 | 128 | ||
@@ -175,13 +172,12 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | |||
175 | 172 | ||
176 | /* Lock entire transaction if requested */ | 173 | /* Lock entire transaction if requested */ |
177 | 174 | ||
178 | locked = | 175 | acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); |
179 | acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); | ||
180 | 176 | ||
181 | /* Read from the field */ | 177 | /* Read from the field */ |
182 | 178 | ||
183 | status = acpi_ex_extract_from_field(obj_desc, buffer, (u32) length); | 179 | status = acpi_ex_extract_from_field(obj_desc, buffer, (u32) length); |
184 | acpi_ex_release_global_lock(locked); | 180 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); |
185 | 181 | ||
186 | exit: | 182 | exit: |
187 | if (ACPI_FAILURE(status)) { | 183 | if (ACPI_FAILURE(status)) { |
@@ -214,10 +210,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
214 | { | 210 | { |
215 | acpi_status status; | 211 | acpi_status status; |
216 | u32 length; | 212 | u32 length; |
217 | u32 required_length; | ||
218 | void *buffer; | 213 | void *buffer; |
219 | void *new_buffer; | ||
220 | u8 locked; | ||
221 | union acpi_operand_object *buffer_desc; | 214 | union acpi_operand_object *buffer_desc; |
222 | 215 | ||
223 | ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); | 216 | ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); |
@@ -278,9 +271,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
278 | 271 | ||
279 | /* Lock entire transaction if requested */ | 272 | /* Lock entire transaction if requested */ |
280 | 273 | ||
281 | locked = | 274 | acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); |
282 | acpi_ex_acquire_global_lock(obj_desc->common_field. | ||
283 | field_flags); | ||
284 | 275 | ||
285 | /* | 276 | /* |
286 | * Perform the write (returns status and perhaps data in the | 277 | * Perform the write (returns status and perhaps data in the |
@@ -291,7 +282,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
291 | (acpi_integer *) buffer, | 282 | (acpi_integer *) buffer, |
292 | ACPI_WRITE | (obj_desc->field. | 283 | ACPI_WRITE | (obj_desc->field. |
293 | attribute << 16)); | 284 | attribute << 16)); |
294 | acpi_ex_release_global_lock(locked); | 285 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); |
295 | 286 | ||
296 | *result_desc = buffer_desc; | 287 | *result_desc = buffer_desc; |
297 | return_ACPI_STATUS(status); | 288 | return_ACPI_STATUS(status); |
@@ -319,35 +310,6 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
319 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 310 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
320 | } | 311 | } |
321 | 312 | ||
322 | /* | ||
323 | * We must have a buffer that is at least as long as the field | ||
324 | * we are writing to. This is because individual fields are | ||
325 | * indivisible and partial writes are not supported -- as per | ||
326 | * the ACPI specification. | ||
327 | */ | ||
328 | new_buffer = NULL; | ||
329 | required_length = | ||
330 | ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length); | ||
331 | |||
332 | if (length < required_length) { | ||
333 | |||
334 | /* We need to create a new buffer */ | ||
335 | |||
336 | new_buffer = ACPI_ALLOCATE_ZEROED(required_length); | ||
337 | if (!new_buffer) { | ||
338 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
339 | } | ||
340 | |||
341 | /* | ||
342 | * Copy the original data to the new buffer, starting | ||
343 | * at Byte zero. All unused (upper) bytes of the | ||
344 | * buffer will be 0. | ||
345 | */ | ||
346 | ACPI_MEMCPY((char *)new_buffer, (char *)buffer, length); | ||
347 | buffer = new_buffer; | ||
348 | length = required_length; | ||
349 | } | ||
350 | |||
351 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 313 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
352 | "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n", | 314 | "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n", |
353 | source_desc, | 315 | source_desc, |
@@ -366,19 +328,12 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
366 | 328 | ||
367 | /* Lock entire transaction if requested */ | 329 | /* Lock entire transaction if requested */ |
368 | 330 | ||
369 | locked = | 331 | acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); |
370 | acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); | ||
371 | 332 | ||
372 | /* Write to the field */ | 333 | /* Write to the field */ |
373 | 334 | ||
374 | status = acpi_ex_insert_into_field(obj_desc, buffer, length); | 335 | status = acpi_ex_insert_into_field(obj_desc, buffer, length); |
375 | acpi_ex_release_global_lock(locked); | 336 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); |
376 | |||
377 | /* Free temporary buffer if we used one */ | ||
378 | |||
379 | if (new_buffer) { | ||
380 | ACPI_FREE(new_buffer); | ||
381 | } | ||
382 | 337 | ||
383 | return_ACPI_STATUS(status); | 338 | return_ACPI_STATUS(status); |
384 | } | 339 | } |
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c index 65a48b6170ee..e336b5dc7a50 100644 --- a/drivers/acpi/executer/exfldio.c +++ b/drivers/acpi/executer/exfldio.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -263,7 +263,8 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, | |||
263 | rgn_desc->region.space_id, | 263 | rgn_desc->region.space_id, |
264 | obj_desc->common_field.access_byte_width, | 264 | obj_desc->common_field.access_byte_width, |
265 | obj_desc->common_field.base_byte_offset, | 265 | obj_desc->common_field.base_byte_offset, |
266 | field_datum_byte_offset, (void *)address)); | 266 | field_datum_byte_offset, ACPI_CAST_PTR(void, |
267 | address))); | ||
267 | 268 | ||
268 | /* Invoke the appropriate address_space/op_region handler */ | 269 | /* Invoke the appropriate address_space/op_region handler */ |
269 | 270 | ||
@@ -805,18 +806,39 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
805 | u32 datum_count; | 806 | u32 datum_count; |
806 | u32 field_datum_count; | 807 | u32 field_datum_count; |
807 | u32 i; | 808 | u32 i; |
809 | u32 required_length; | ||
810 | void *new_buffer; | ||
808 | 811 | ||
809 | ACPI_FUNCTION_TRACE(ex_insert_into_field); | 812 | ACPI_FUNCTION_TRACE(ex_insert_into_field); |
810 | 813 | ||
811 | /* Validate input buffer */ | 814 | /* Validate input buffer */ |
812 | 815 | ||
813 | if (buffer_length < | 816 | new_buffer = NULL; |
814 | ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) { | 817 | required_length = |
815 | ACPI_ERROR((AE_INFO, | 818 | ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length); |
816 | "Field size %X (bits) is too large for buffer (%X)", | 819 | /* |
817 | obj_desc->common_field.bit_length, buffer_length)); | 820 | * We must have a buffer that is at least as long as the field |
821 | * we are writing to. This is because individual fields are | ||
822 | * indivisible and partial writes are not supported -- as per | ||
823 | * the ACPI specification. | ||
824 | */ | ||
825 | if (buffer_length < required_length) { | ||
818 | 826 | ||
819 | return_ACPI_STATUS(AE_BUFFER_OVERFLOW); | 827 | /* We need to create a new buffer */ |
828 | |||
829 | new_buffer = ACPI_ALLOCATE_ZEROED(required_length); | ||
830 | if (!new_buffer) { | ||
831 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
832 | } | ||
833 | |||
834 | /* | ||
835 | * Copy the original data to the new buffer, starting | ||
836 | * at Byte zero. All unused (upper) bytes of the | ||
837 | * buffer will be 0. | ||
838 | */ | ||
839 | ACPI_MEMCPY((char *)new_buffer, (char *)buffer, buffer_length); | ||
840 | buffer = new_buffer; | ||
841 | buffer_length = required_length; | ||
820 | } | 842 | } |
821 | 843 | ||
822 | /* | 844 | /* |
@@ -866,7 +888,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
866 | merged_datum, | 888 | merged_datum, |
867 | field_offset); | 889 | field_offset); |
868 | if (ACPI_FAILURE(status)) { | 890 | if (ACPI_FAILURE(status)) { |
869 | return_ACPI_STATUS(status); | 891 | goto exit; |
870 | } | 892 | } |
871 | 893 | ||
872 | field_offset += obj_desc->common_field.access_byte_width; | 894 | field_offset += obj_desc->common_field.access_byte_width; |
@@ -924,5 +946,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
924 | mask, merged_datum, | 946 | mask, merged_datum, |
925 | field_offset); | 947 | field_offset); |
926 | 948 | ||
949 | exit: | ||
950 | /* Free temporary buffer if we used one */ | ||
951 | |||
952 | if (new_buffer) { | ||
953 | ACPI_FREE(new_buffer); | ||
954 | } | ||
927 | return_ACPI_STATUS(status); | 955 | return_ACPI_STATUS(status); |
928 | } | 956 | } |
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c index f13d1cec2d6d..cc956a5b5267 100644 --- a/drivers/acpi/executer/exmisc.c +++ b/drivers/acpi/executer/exmisc.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c index 6748e3ef0997..c873ab40cd0e 100644 --- a/drivers/acpi/executer/exmutex.c +++ b/drivers/acpi/executer/exmutex.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -126,6 +126,79 @@ acpi_ex_link_mutex(union acpi_operand_object *obj_desc, | |||
126 | 126 | ||
127 | /******************************************************************************* | 127 | /******************************************************************************* |
128 | * | 128 | * |
129 | * FUNCTION: acpi_ex_acquire_mutex_object | ||
130 | * | ||
131 | * PARAMETERS: time_desc - Timeout in milliseconds | ||
132 | * obj_desc - Mutex object | ||
133 | * Thread - Current thread state | ||
134 | * | ||
135 | * RETURN: Status | ||
136 | * | ||
137 | * DESCRIPTION: Acquire an AML mutex, low-level interface. Provides a common | ||
138 | * path that supports multiple acquires by the same thread. | ||
139 | * | ||
140 | * MUTEX: Interpreter must be locked | ||
141 | * | ||
142 | * NOTE: This interface is called from three places: | ||
143 | * 1) From acpi_ex_acquire_mutex, via an AML Acquire() operator | ||
144 | * 2) From acpi_ex_acquire_global_lock when an AML Field access requires the | ||
145 | * global lock | ||
146 | * 3) From the external interface, acpi_acquire_global_lock | ||
147 | * | ||
148 | ******************************************************************************/ | ||
149 | |||
150 | acpi_status | ||
151 | acpi_ex_acquire_mutex_object(u16 timeout, | ||
152 | union acpi_operand_object *obj_desc, | ||
153 | acpi_thread_id thread_id) | ||
154 | { | ||
155 | acpi_status status; | ||
156 | |||
157 | ACPI_FUNCTION_TRACE_PTR(ex_acquire_mutex_object, obj_desc); | ||
158 | |||
159 | if (!obj_desc) { | ||
160 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
161 | } | ||
162 | |||
163 | /* Support for multiple acquires by the owning thread */ | ||
164 | |||
165 | if (obj_desc->mutex.thread_id == thread_id) { | ||
166 | /* | ||
167 | * The mutex is already owned by this thread, just increment the | ||
168 | * acquisition depth | ||
169 | */ | ||
170 | obj_desc->mutex.acquisition_depth++; | ||
171 | return_ACPI_STATUS(AE_OK); | ||
172 | } | ||
173 | |||
174 | /* Acquire the mutex, wait if necessary. Special case for Global Lock */ | ||
175 | |||
176 | if (obj_desc == acpi_gbl_global_lock_mutex) { | ||
177 | status = acpi_ev_acquire_global_lock(timeout); | ||
178 | } else { | ||
179 | status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex, | ||
180 | timeout); | ||
181 | } | ||
182 | |||
183 | if (ACPI_FAILURE(status)) { | ||
184 | |||
185 | /* Includes failure from a timeout on time_desc */ | ||
186 | |||
187 | return_ACPI_STATUS(status); | ||
188 | } | ||
189 | |||
190 | /* Acquired the mutex: update mutex object */ | ||
191 | |||
192 | obj_desc->mutex.thread_id = thread_id; | ||
193 | obj_desc->mutex.acquisition_depth = 1; | ||
194 | obj_desc->mutex.original_sync_level = 0; | ||
195 | obj_desc->mutex.owner_thread = NULL; /* Used only for AML Acquire() */ | ||
196 | |||
197 | return_ACPI_STATUS(AE_OK); | ||
198 | } | ||
199 | |||
200 | /******************************************************************************* | ||
201 | * | ||
129 | * FUNCTION: acpi_ex_acquire_mutex | 202 | * FUNCTION: acpi_ex_acquire_mutex |
130 | * | 203 | * |
131 | * PARAMETERS: time_desc - Timeout integer | 204 | * PARAMETERS: time_desc - Timeout integer |
@@ -151,7 +224,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, | |||
151 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 224 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
152 | } | 225 | } |
153 | 226 | ||
154 | /* Sanity check: we must have a valid thread ID */ | 227 | /* Must have a valid thread ID */ |
155 | 228 | ||
156 | if (!walk_state->thread) { | 229 | if (!walk_state->thread) { |
157 | ACPI_ERROR((AE_INFO, | 230 | ACPI_ERROR((AE_INFO, |
@@ -161,7 +234,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, | |||
161 | } | 234 | } |
162 | 235 | ||
163 | /* | 236 | /* |
164 | * Current Sync must be less than or equal to the sync level of the | 237 | * Current sync level must be less than or equal to the sync level of the |
165 | * mutex. This mechanism provides some deadlock prevention | 238 | * mutex. This mechanism provides some deadlock prevention |
166 | */ | 239 | */ |
167 | if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) { | 240 | if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) { |
@@ -172,51 +245,89 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, | |||
172 | return_ACPI_STATUS(AE_AML_MUTEX_ORDER); | 245 | return_ACPI_STATUS(AE_AML_MUTEX_ORDER); |
173 | } | 246 | } |
174 | 247 | ||
175 | /* Support for multiple acquires by the owning thread */ | 248 | status = acpi_ex_acquire_mutex_object((u16) time_desc->integer.value, |
249 | obj_desc, | ||
250 | walk_state->thread->thread_id); | ||
251 | if (ACPI_SUCCESS(status) && obj_desc->mutex.acquisition_depth == 1) { | ||
176 | 252 | ||
177 | if (obj_desc->mutex.owner_thread) { | 253 | /* Save Thread object, original/current sync levels */ |
178 | if (obj_desc->mutex.owner_thread->thread_id == | 254 | |
179 | walk_state->thread->thread_id) { | 255 | obj_desc->mutex.owner_thread = walk_state->thread; |
180 | /* | 256 | obj_desc->mutex.original_sync_level = |
181 | * The mutex is already owned by this thread, just increment the | 257 | walk_state->thread->current_sync_level; |
182 | * acquisition depth | 258 | walk_state->thread->current_sync_level = |
183 | */ | 259 | obj_desc->mutex.sync_level; |
184 | obj_desc->mutex.acquisition_depth++; | 260 | |
185 | return_ACPI_STATUS(AE_OK); | 261 | /* Link the mutex to the current thread for force-unlock at method exit */ |
186 | } | 262 | |
263 | acpi_ex_link_mutex(obj_desc, walk_state->thread); | ||
187 | } | 264 | } |
188 | 265 | ||
189 | /* Acquire the mutex, wait if necessary. Special case for Global Lock */ | 266 | return_ACPI_STATUS(status); |
267 | } | ||
190 | 268 | ||
191 | if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) { | 269 | /******************************************************************************* |
192 | status = | 270 | * |
193 | acpi_ev_acquire_global_lock((u16) time_desc->integer.value); | 271 | * FUNCTION: acpi_ex_release_mutex_object |
194 | } else { | 272 | * |
195 | status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex, | 273 | * PARAMETERS: obj_desc - The object descriptor for this op |
196 | (u16) time_desc->integer. | 274 | * |
197 | value); | 275 | * RETURN: Status |
276 | * | ||
277 | * DESCRIPTION: Release a previously acquired Mutex, low level interface. | ||
278 | * Provides a common path that supports multiple releases (after | ||
279 | * previous multiple acquires) by the same thread. | ||
280 | * | ||
281 | * MUTEX: Interpreter must be locked | ||
282 | * | ||
283 | * NOTE: This interface is called from three places: | ||
284 | * 1) From acpi_ex_release_mutex, via an AML Acquire() operator | ||
285 | * 2) From acpi_ex_release_global_lock when an AML Field access requires the | ||
286 | * global lock | ||
287 | * 3) From the external interface, acpi_release_global_lock | ||
288 | * | ||
289 | ******************************************************************************/ | ||
290 | |||
291 | acpi_status acpi_ex_release_mutex_object(union acpi_operand_object *obj_desc) | ||
292 | { | ||
293 | acpi_status status = AE_OK; | ||
294 | |||
295 | ACPI_FUNCTION_TRACE(ex_release_mutex_object); | ||
296 | |||
297 | if (obj_desc->mutex.acquisition_depth == 0) { | ||
298 | return (AE_NOT_ACQUIRED); | ||
198 | } | 299 | } |
199 | 300 | ||
200 | if (ACPI_FAILURE(status)) { | 301 | /* Match multiple Acquires with multiple Releases */ |
201 | 302 | ||
202 | /* Includes failure from a timeout on time_desc */ | 303 | obj_desc->mutex.acquisition_depth--; |
304 | if (obj_desc->mutex.acquisition_depth != 0) { | ||
203 | 305 | ||
204 | return_ACPI_STATUS(status); | 306 | /* Just decrement the depth and return */ |
307 | |||
308 | return_ACPI_STATUS(AE_OK); | ||
205 | } | 309 | } |
206 | 310 | ||
207 | /* Have the mutex: update mutex and walk info and save the sync_level */ | 311 | if (obj_desc->mutex.owner_thread) { |
208 | 312 | ||
209 | obj_desc->mutex.owner_thread = walk_state->thread; | 313 | /* Unlink the mutex from the owner's list */ |
210 | obj_desc->mutex.acquisition_depth = 1; | ||
211 | obj_desc->mutex.original_sync_level = | ||
212 | walk_state->thread->current_sync_level; | ||
213 | 314 | ||
214 | walk_state->thread->current_sync_level = obj_desc->mutex.sync_level; | 315 | acpi_ex_unlink_mutex(obj_desc); |
316 | obj_desc->mutex.owner_thread = NULL; | ||
317 | } | ||
215 | 318 | ||
216 | /* Link the mutex to the current thread for force-unlock at method exit */ | 319 | /* Release the mutex, special case for Global Lock */ |
217 | 320 | ||
218 | acpi_ex_link_mutex(obj_desc, walk_state->thread); | 321 | if (obj_desc == acpi_gbl_global_lock_mutex) { |
219 | return_ACPI_STATUS(AE_OK); | 322 | status = acpi_ev_release_global_lock(); |
323 | } else { | ||
324 | acpi_os_release_mutex(obj_desc->mutex.os_mutex); | ||
325 | } | ||
326 | |||
327 | /* Clear mutex info */ | ||
328 | |||
329 | obj_desc->mutex.thread_id = 0; | ||
330 | return_ACPI_STATUS(status); | ||
220 | } | 331 | } |
221 | 332 | ||
222 | /******************************************************************************* | 333 | /******************************************************************************* |
@@ -253,22 +364,13 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
253 | return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED); | 364 | return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED); |
254 | } | 365 | } |
255 | 366 | ||
256 | /* Sanity check: we must have a valid thread ID */ | ||
257 | |||
258 | if (!walk_state->thread) { | ||
259 | ACPI_ERROR((AE_INFO, | ||
260 | "Cannot release Mutex [%4.4s], null thread info", | ||
261 | acpi_ut_get_node_name(obj_desc->mutex.node))); | ||
262 | return_ACPI_STATUS(AE_AML_INTERNAL); | ||
263 | } | ||
264 | |||
265 | /* | 367 | /* |
266 | * The Mutex is owned, but this thread must be the owner. | 368 | * The Mutex is owned, but this thread must be the owner. |
267 | * Special case for Global Lock, any thread can release | 369 | * Special case for Global Lock, any thread can release |
268 | */ | 370 | */ |
269 | if ((obj_desc->mutex.owner_thread->thread_id != | 371 | if ((obj_desc->mutex.owner_thread->thread_id != |
270 | walk_state->thread->thread_id) | 372 | walk_state->thread->thread_id) |
271 | && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) { | 373 | && (obj_desc != acpi_gbl_global_lock_mutex)) { |
272 | ACPI_ERROR((AE_INFO, | 374 | ACPI_ERROR((AE_INFO, |
273 | "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", | 375 | "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", |
274 | (unsigned long)walk_state->thread->thread_id, | 376 | (unsigned long)walk_state->thread->thread_id, |
@@ -278,45 +380,37 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
278 | return_ACPI_STATUS(AE_AML_NOT_OWNER); | 380 | return_ACPI_STATUS(AE_AML_NOT_OWNER); |
279 | } | 381 | } |
280 | 382 | ||
383 | /* Must have a valid thread ID */ | ||
384 | |||
385 | if (!walk_state->thread) { | ||
386 | ACPI_ERROR((AE_INFO, | ||
387 | "Cannot release Mutex [%4.4s], null thread info", | ||
388 | acpi_ut_get_node_name(obj_desc->mutex.node))); | ||
389 | return_ACPI_STATUS(AE_AML_INTERNAL); | ||
390 | } | ||
391 | |||
281 | /* | 392 | /* |
282 | * The sync level of the mutex must be less than or equal to the current | 393 | * The sync level of the mutex must be less than or equal to the current |
283 | * sync level | 394 | * sync level |
284 | */ | 395 | */ |
285 | if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { | 396 | if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { |
286 | ACPI_ERROR((AE_INFO, | 397 | ACPI_ERROR((AE_INFO, |
287 | "Cannot release Mutex [%4.4s], incorrect SyncLevel", | 398 | "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d", |
288 | acpi_ut_get_node_name(obj_desc->mutex.node))); | 399 | acpi_ut_get_node_name(obj_desc->mutex.node), |
400 | obj_desc->mutex.sync_level, | ||
401 | walk_state->thread->current_sync_level)); | ||
289 | return_ACPI_STATUS(AE_AML_MUTEX_ORDER); | 402 | return_ACPI_STATUS(AE_AML_MUTEX_ORDER); |
290 | } | 403 | } |
291 | 404 | ||
292 | /* Match multiple Acquires with multiple Releases */ | 405 | status = acpi_ex_release_mutex_object(obj_desc); |
293 | |||
294 | obj_desc->mutex.acquisition_depth--; | ||
295 | if (obj_desc->mutex.acquisition_depth != 0) { | ||
296 | |||
297 | /* Just decrement the depth and return */ | ||
298 | |||
299 | return_ACPI_STATUS(AE_OK); | ||
300 | } | ||
301 | |||
302 | /* Unlink the mutex from the owner's list */ | ||
303 | 406 | ||
304 | acpi_ex_unlink_mutex(obj_desc); | 407 | if (obj_desc->mutex.acquisition_depth == 0) { |
305 | 408 | ||
306 | /* Release the mutex, special case for Global Lock */ | 409 | /* Restore the original sync_level */ |
307 | 410 | ||
308 | if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) { | 411 | walk_state->thread->current_sync_level = |
309 | status = acpi_ev_release_global_lock(); | 412 | obj_desc->mutex.original_sync_level; |
310 | } else { | ||
311 | acpi_os_release_mutex(obj_desc->mutex.os_mutex); | ||
312 | } | 413 | } |
313 | |||
314 | /* Update the mutex and restore sync_level */ | ||
315 | |||
316 | obj_desc->mutex.owner_thread = NULL; | ||
317 | walk_state->thread->current_sync_level = | ||
318 | obj_desc->mutex.original_sync_level; | ||
319 | |||
320 | return_ACPI_STATUS(status); | 414 | return_ACPI_STATUS(status); |
321 | } | 415 | } |
322 | 416 | ||
@@ -357,7 +451,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread) | |||
357 | 451 | ||
358 | /* Release the mutex, special case for Global Lock */ | 452 | /* Release the mutex, special case for Global Lock */ |
359 | 453 | ||
360 | if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) { | 454 | if (obj_desc == acpi_gbl_global_lock_mutex) { |
361 | 455 | ||
362 | /* Ignore errors */ | 456 | /* Ignore errors */ |
363 | 457 | ||
@@ -369,6 +463,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread) | |||
369 | /* Mark mutex unowned */ | 463 | /* Mark mutex unowned */ |
370 | 464 | ||
371 | obj_desc->mutex.owner_thread = NULL; | 465 | obj_desc->mutex.owner_thread = NULL; |
466 | obj_desc->mutex.thread_id = 0; | ||
372 | 467 | ||
373 | /* Update Thread sync_level (Last mutex is the important one) */ | 468 | /* Update Thread sync_level (Last mutex is the important one) */ |
374 | 469 | ||
diff --git a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c index 308eae52dc05..817e67be3697 100644 --- a/drivers/acpi/executer/exnames.c +++ b/drivers/acpi/executer/exnames.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c index 252f10acbbcc..7c3bea575e02 100644 --- a/drivers/acpi/executer/exoparg1.c +++ b/drivers/acpi/executer/exoparg1.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -121,6 +121,7 @@ acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state) | |||
121 | 121 | ||
122 | if ((ACPI_FAILURE(status)) || walk_state->result_obj) { | 122 | if ((ACPI_FAILURE(status)) || walk_state->result_obj) { |
123 | acpi_ut_remove_reference(return_desc); | 123 | acpi_ut_remove_reference(return_desc); |
124 | walk_state->result_obj = NULL; | ||
124 | } else { | 125 | } else { |
125 | /* Save the return value */ | 126 | /* Save the return value */ |
126 | 127 | ||
@@ -739,26 +740,38 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) | |||
739 | value = acpi_gbl_integer_byte_width; | 740 | value = acpi_gbl_integer_byte_width; |
740 | break; | 741 | break; |
741 | 742 | ||
742 | case ACPI_TYPE_BUFFER: | ||
743 | value = temp_desc->buffer.length; | ||
744 | break; | ||
745 | |||
746 | case ACPI_TYPE_STRING: | 743 | case ACPI_TYPE_STRING: |
747 | value = temp_desc->string.length; | 744 | value = temp_desc->string.length; |
748 | break; | 745 | break; |
749 | 746 | ||
747 | case ACPI_TYPE_BUFFER: | ||
748 | |||
749 | /* Buffer arguments may not be evaluated at this point */ | ||
750 | |||
751 | status = acpi_ds_get_buffer_arguments(temp_desc); | ||
752 | value = temp_desc->buffer.length; | ||
753 | break; | ||
754 | |||
750 | case ACPI_TYPE_PACKAGE: | 755 | case ACPI_TYPE_PACKAGE: |
756 | |||
757 | /* Package arguments may not be evaluated at this point */ | ||
758 | |||
759 | status = acpi_ds_get_package_arguments(temp_desc); | ||
751 | value = temp_desc->package.count; | 760 | value = temp_desc->package.count; |
752 | break; | 761 | break; |
753 | 762 | ||
754 | default: | 763 | default: |
755 | ACPI_ERROR((AE_INFO, | 764 | ACPI_ERROR((AE_INFO, |
756 | "Operand is not Buf/Int/Str/Pkg - found type %s", | 765 | "Operand must be Buffer/Integer/String/Package - found type %s", |
757 | acpi_ut_get_type_name(type))); | 766 | acpi_ut_get_type_name(type))); |
758 | status = AE_AML_OPERAND_TYPE; | 767 | status = AE_AML_OPERAND_TYPE; |
759 | goto cleanup; | 768 | goto cleanup; |
760 | } | 769 | } |
761 | 770 | ||
771 | if (ACPI_FAILURE(status)) { | ||
772 | goto cleanup; | ||
773 | } | ||
774 | |||
762 | /* | 775 | /* |
763 | * Now that we have the size of the object, create a result | 776 | * Now that we have the size of the object, create a result |
764 | * object to hold the value | 777 | * object to hold the value |
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c index 17e652e65379..8e8bbb6ccebd 100644 --- a/drivers/acpi/executer/exoparg2.c +++ b/drivers/acpi/executer/exoparg2.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -241,10 +241,6 @@ acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state) | |||
241 | goto cleanup; | 241 | goto cleanup; |
242 | } | 242 | } |
243 | 243 | ||
244 | /* Return the remainder */ | ||
245 | |||
246 | walk_state->result_obj = return_desc1; | ||
247 | |||
248 | cleanup: | 244 | cleanup: |
249 | /* | 245 | /* |
250 | * Since the remainder is not returned indirectly, remove a reference to | 246 | * Since the remainder is not returned indirectly, remove a reference to |
@@ -259,6 +255,12 @@ acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state) | |||
259 | acpi_ut_remove_reference(return_desc1); | 255 | acpi_ut_remove_reference(return_desc1); |
260 | } | 256 | } |
261 | 257 | ||
258 | /* Save return object (the remainder) on success */ | ||
259 | |||
260 | else { | ||
261 | walk_state->result_obj = return_desc1; | ||
262 | } | ||
263 | |||
262 | return_ACPI_STATUS(status); | 264 | return_ACPI_STATUS(status); |
263 | } | 265 | } |
264 | 266 | ||
@@ -490,6 +492,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) | |||
490 | 492 | ||
491 | if (ACPI_FAILURE(status)) { | 493 | if (ACPI_FAILURE(status)) { |
492 | acpi_ut_remove_reference(return_desc); | 494 | acpi_ut_remove_reference(return_desc); |
495 | walk_state->result_obj = NULL; | ||
493 | } | 496 | } |
494 | 497 | ||
495 | return_ACPI_STATUS(status); | 498 | return_ACPI_STATUS(status); |
@@ -583,8 +586,6 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state) | |||
583 | return_desc->integer.value = ACPI_INTEGER_MAX; | 586 | return_desc->integer.value = ACPI_INTEGER_MAX; |
584 | } | 587 | } |
585 | 588 | ||
586 | walk_state->result_obj = return_desc; | ||
587 | |||
588 | cleanup: | 589 | cleanup: |
589 | 590 | ||
590 | /* Delete return object on error */ | 591 | /* Delete return object on error */ |
@@ -593,5 +594,11 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state) | |||
593 | acpi_ut_remove_reference(return_desc); | 594 | acpi_ut_remove_reference(return_desc); |
594 | } | 595 | } |
595 | 596 | ||
597 | /* Save return object on success */ | ||
598 | |||
599 | else { | ||
600 | walk_state->result_obj = return_desc; | ||
601 | } | ||
602 | |||
596 | return_ACPI_STATUS(status); | 603 | return_ACPI_STATUS(status); |
597 | } | 604 | } |
diff --git a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c index 7fe67cf82cee..9cb4197681af 100644 --- a/drivers/acpi/executer/exoparg3.c +++ b/drivers/acpi/executer/exoparg3.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -260,6 +260,7 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state) | |||
260 | 260 | ||
261 | if (ACPI_FAILURE(status) || walk_state->result_obj) { | 261 | if (ACPI_FAILURE(status) || walk_state->result_obj) { |
262 | acpi_ut_remove_reference(return_desc); | 262 | acpi_ut_remove_reference(return_desc); |
263 | walk_state->result_obj = NULL; | ||
263 | } | 264 | } |
264 | 265 | ||
265 | /* Set the return object and exit */ | 266 | /* Set the return object and exit */ |
diff --git a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c index bd80a9cb3d65..67d48737af53 100644 --- a/drivers/acpi/executer/exoparg6.c +++ b/drivers/acpi/executer/exoparg6.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -322,8 +322,6 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) | |||
322 | goto cleanup; | 322 | goto cleanup; |
323 | } | 323 | } |
324 | 324 | ||
325 | walk_state->result_obj = return_desc; | ||
326 | |||
327 | cleanup: | 325 | cleanup: |
328 | 326 | ||
329 | /* Delete return object on error */ | 327 | /* Delete return object on error */ |
@@ -332,5 +330,11 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) | |||
332 | acpi_ut_remove_reference(return_desc); | 330 | acpi_ut_remove_reference(return_desc); |
333 | } | 331 | } |
334 | 332 | ||
333 | /* Save return object on success */ | ||
334 | |||
335 | else { | ||
336 | walk_state->result_obj = return_desc; | ||
337 | } | ||
338 | |||
335 | return_ACPI_STATUS(status); | 339 | return_ACPI_STATUS(status); |
336 | } | 340 | } |
diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c index efe5d4b461a4..3a2f8cd4c62a 100644 --- a/drivers/acpi/executer/exprep.c +++ b/drivers/acpi/executer/exprep.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -412,6 +412,7 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc, | |||
412 | acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) | 412 | acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) |
413 | { | 413 | { |
414 | union acpi_operand_object *obj_desc; | 414 | union acpi_operand_object *obj_desc; |
415 | union acpi_operand_object *second_desc = NULL; | ||
415 | u32 type; | 416 | u32 type; |
416 | acpi_status status; | 417 | acpi_status status; |
417 | 418 | ||
@@ -494,6 +495,20 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) | |||
494 | obj_desc->field.access_byte_width, | 495 | obj_desc->field.access_byte_width, |
495 | obj_desc->bank_field.region_obj, | 496 | obj_desc->bank_field.region_obj, |
496 | obj_desc->bank_field.bank_obj)); | 497 | obj_desc->bank_field.bank_obj)); |
498 | |||
499 | /* | ||
500 | * Remember location in AML stream of the field unit | ||
501 | * opcode and operands -- since the bank_value | ||
502 | * operands must be evaluated. | ||
503 | */ | ||
504 | second_desc = obj_desc->common.next_object; | ||
505 | second_desc->extra.aml_start = | ||
506 | ((union acpi_parse_object *)(info->data_register_node))-> | ||
507 | named.data; | ||
508 | second_desc->extra.aml_length = | ||
509 | ((union acpi_parse_object *)(info->data_register_node))-> | ||
510 | named.length; | ||
511 | |||
497 | break; | 512 | break; |
498 | 513 | ||
499 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | 514 | case ACPI_TYPE_LOCAL_INDEX_FIELD: |
diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c index 3f51b7e84a17..7cd8bb54fa01 100644 --- a/drivers/acpi/executer/exregion.c +++ b/drivers/acpi/executer/exregion.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -160,7 +160,7 @@ acpi_ex_system_memory_space_handler(u32 function, | |||
160 | if (!mem_info->mapped_logical_address) { | 160 | if (!mem_info->mapped_logical_address) { |
161 | ACPI_ERROR((AE_INFO, | 161 | ACPI_ERROR((AE_INFO, |
162 | "Could not map memory at %8.8X%8.8X, size %X", | 162 | "Could not map memory at %8.8X%8.8X, size %X", |
163 | ACPI_FORMAT_UINT64(address), | 163 | ACPI_FORMAT_NATIVE_UINT(address), |
164 | (u32) window_size)); | 164 | (u32) window_size)); |
165 | mem_info->mapped_length = 0; | 165 | mem_info->mapped_length = 0; |
166 | return_ACPI_STATUS(AE_NO_MEMORY); | 166 | return_ACPI_STATUS(AE_NO_MEMORY); |
@@ -182,7 +182,8 @@ acpi_ex_system_memory_space_handler(u32 function, | |||
182 | 182 | ||
183 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 183 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
184 | "System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n", | 184 | "System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n", |
185 | bit_width, function, ACPI_FORMAT_UINT64(address))); | 185 | bit_width, function, |
186 | ACPI_FORMAT_NATIVE_UINT(address))); | ||
186 | 187 | ||
187 | /* | 188 | /* |
188 | * Perform the memory read or write | 189 | * Perform the memory read or write |
@@ -284,7 +285,8 @@ acpi_ex_system_io_space_handler(u32 function, | |||
284 | 285 | ||
285 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 286 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
286 | "System-IO (width %d) R/W %d Address=%8.8X%8.8X\n", | 287 | "System-IO (width %d) R/W %d Address=%8.8X%8.8X\n", |
287 | bit_width, function, ACPI_FORMAT_UINT64(address))); | 288 | bit_width, function, |
289 | ACPI_FORMAT_NATIVE_UINT(address))); | ||
288 | 290 | ||
289 | /* Decode the function parameter */ | 291 | /* Decode the function parameter */ |
290 | 292 | ||
diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c index 2b3a01cc4929..5596f42c9676 100644 --- a/drivers/acpi/executer/exresnte.c +++ b/drivers/acpi/executer/exresnte.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -116,9 +116,11 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, | |||
116 | * Several object types require no further processing: | 116 | * Several object types require no further processing: |
117 | * 1) Device/Thermal objects don't have a "real" subobject, return the Node | 117 | * 1) Device/Thermal objects don't have a "real" subobject, return the Node |
118 | * 2) Method locals and arguments have a pseudo-Node | 118 | * 2) Method locals and arguments have a pseudo-Node |
119 | * 3) 10/2007: Added method type to assist with Package construction. | ||
119 | */ | 120 | */ |
120 | if ((entry_type == ACPI_TYPE_DEVICE) || | 121 | if ((entry_type == ACPI_TYPE_DEVICE) || |
121 | (entry_type == ACPI_TYPE_THERMAL) || | 122 | (entry_type == ACPI_TYPE_THERMAL) || |
123 | (entry_type == ACPI_TYPE_METHOD) || | ||
122 | (node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) { | 124 | (node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) { |
123 | return_ACPI_STATUS(AE_OK); | 125 | return_ACPI_STATUS(AE_OK); |
124 | } | 126 | } |
@@ -214,7 +216,6 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, | |||
214 | /* For these objects, just return the object attached to the Node */ | 216 | /* For these objects, just return the object attached to the Node */ |
215 | 217 | ||
216 | case ACPI_TYPE_MUTEX: | 218 | case ACPI_TYPE_MUTEX: |
217 | case ACPI_TYPE_METHOD: | ||
218 | case ACPI_TYPE_POWER: | 219 | case ACPI_TYPE_POWER: |
219 | case ACPI_TYPE_PROCESSOR: | 220 | case ACPI_TYPE_PROCESSOR: |
220 | case ACPI_TYPE_EVENT: | 221 | case ACPI_TYPE_EVENT: |
@@ -238,13 +239,12 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, | |||
238 | case ACPI_TYPE_LOCAL_REFERENCE: | 239 | case ACPI_TYPE_LOCAL_REFERENCE: |
239 | 240 | ||
240 | switch (source_desc->reference.opcode) { | 241 | switch (source_desc->reference.opcode) { |
241 | case AML_LOAD_OP: | 242 | case AML_LOAD_OP: /* This is a ddb_handle */ |
243 | case AML_REF_OF_OP: | ||
244 | case AML_INDEX_OP: | ||
242 | 245 | ||
243 | /* This is a ddb_handle */ | ||
244 | /* Return an additional reference to the object */ | 246 | /* Return an additional reference to the object */ |
245 | 247 | ||
246 | case AML_REF_OF_OP: | ||
247 | |||
248 | obj_desc = source_desc; | 248 | obj_desc = source_desc; |
249 | acpi_ut_add_reference(obj_desc); | 249 | acpi_ut_add_reference(obj_desc); |
250 | break; | 250 | break; |
diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c index 6c64e55dab0e..b35f7c817acf 100644 --- a/drivers/acpi/executer/exresolv.c +++ b/drivers/acpi/executer/exresolv.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -140,7 +140,6 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, | |||
140 | { | 140 | { |
141 | acpi_status status = AE_OK; | 141 | acpi_status status = AE_OK; |
142 | union acpi_operand_object *stack_desc; | 142 | union acpi_operand_object *stack_desc; |
143 | void *temp_node; | ||
144 | union acpi_operand_object *obj_desc = NULL; | 143 | union acpi_operand_object *obj_desc = NULL; |
145 | u16 opcode; | 144 | u16 opcode; |
146 | 145 | ||
@@ -156,23 +155,6 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, | |||
156 | opcode = stack_desc->reference.opcode; | 155 | opcode = stack_desc->reference.opcode; |
157 | 156 | ||
158 | switch (opcode) { | 157 | switch (opcode) { |
159 | case AML_NAME_OP: | ||
160 | |||
161 | /* | ||
162 | * Convert name reference to a namespace node | ||
163 | * Then, acpi_ex_resolve_node_to_value can be used to get the value | ||
164 | */ | ||
165 | temp_node = stack_desc->reference.object; | ||
166 | |||
167 | /* Delete the Reference Object */ | ||
168 | |||
169 | acpi_ut_remove_reference(stack_desc); | ||
170 | |||
171 | /* Return the namespace node */ | ||
172 | |||
173 | (*stack_ptr) = temp_node; | ||
174 | break; | ||
175 | |||
176 | case AML_LOCAL_OP: | 158 | case AML_LOCAL_OP: |
177 | case AML_ARG_OP: | 159 | case AML_ARG_OP: |
178 | 160 | ||
@@ -207,15 +189,25 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, | |||
207 | switch (stack_desc->reference.target_type) { | 189 | switch (stack_desc->reference.target_type) { |
208 | case ACPI_TYPE_BUFFER_FIELD: | 190 | case ACPI_TYPE_BUFFER_FIELD: |
209 | 191 | ||
210 | /* Just return - leave the Reference on the stack */ | 192 | /* Just return - do not dereference */ |
211 | break; | 193 | break; |
212 | 194 | ||
213 | case ACPI_TYPE_PACKAGE: | 195 | case ACPI_TYPE_PACKAGE: |
214 | 196 | ||
197 | /* If method call or copy_object - do not dereference */ | ||
198 | |||
199 | if ((walk_state->opcode == | ||
200 | AML_INT_METHODCALL_OP) | ||
201 | || (walk_state->opcode == AML_COPY_OP)) { | ||
202 | break; | ||
203 | } | ||
204 | |||
205 | /* Otherwise, dereference the package_index to a package element */ | ||
206 | |||
215 | obj_desc = *stack_desc->reference.where; | 207 | obj_desc = *stack_desc->reference.where; |
216 | if (obj_desc) { | 208 | if (obj_desc) { |
217 | /* | 209 | /* |
218 | * Valid obj descriptor, copy pointer to return value | 210 | * Valid object descriptor, copy pointer to return value |
219 | * (i.e., dereference the package index) | 211 | * (i.e., dereference the package index) |
220 | * Delete the ref object, increment the returned object | 212 | * Delete the ref object, increment the returned object |
221 | */ | 213 | */ |
@@ -224,11 +216,11 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, | |||
224 | *stack_ptr = obj_desc; | 216 | *stack_ptr = obj_desc; |
225 | } else { | 217 | } else { |
226 | /* | 218 | /* |
227 | * A NULL object descriptor means an unitialized element of | 219 | * A NULL object descriptor means an uninitialized element of |
228 | * the package, can't dereference it | 220 | * the package, can't dereference it |
229 | */ | 221 | */ |
230 | ACPI_ERROR((AE_INFO, | 222 | ACPI_ERROR((AE_INFO, |
231 | "Attempt to deref an Index to NULL pkg element Idx=%p", | 223 | "Attempt to dereference an Index to NULL package element Idx=%p", |
232 | stack_desc)); | 224 | stack_desc)); |
233 | status = AE_AML_UNINITIALIZED_ELEMENT; | 225 | status = AE_AML_UNINITIALIZED_ELEMENT; |
234 | } | 226 | } |
@@ -239,7 +231,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, | |||
239 | /* Invalid reference object */ | 231 | /* Invalid reference object */ |
240 | 232 | ||
241 | ACPI_ERROR((AE_INFO, | 233 | ACPI_ERROR((AE_INFO, |
242 | "Unknown TargetType %X in Index/Reference obj %p", | 234 | "Unknown TargetType %X in Index/Reference object %p", |
243 | stack_desc->reference.target_type, | 235 | stack_desc->reference.target_type, |
244 | stack_desc)); | 236 | stack_desc)); |
245 | status = AE_AML_INTERNAL; | 237 | status = AE_AML_INTERNAL; |
@@ -251,7 +243,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, | |||
251 | case AML_DEBUG_OP: | 243 | case AML_DEBUG_OP: |
252 | case AML_LOAD_OP: | 244 | case AML_LOAD_OP: |
253 | 245 | ||
254 | /* Just leave the object as-is */ | 246 | /* Just leave the object as-is, do not dereference */ |
255 | 247 | ||
256 | break; | 248 | break; |
257 | 249 | ||
@@ -390,10 +382,10 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, | |||
390 | } | 382 | } |
391 | 383 | ||
392 | /* | 384 | /* |
393 | * For reference objects created via the ref_of or Index operators, | 385 | * For reference objects created via the ref_of, Index, or Load/load_table |
394 | * we need to get to the base object (as per the ACPI specification | 386 | * operators, we need to get to the base object (as per the ACPI |
395 | * of the object_type and size_of operators). This means traversing | 387 | * specification of the object_type and size_of operators). This means |
396 | * the list of possibly many nested references. | 388 | * traversing the list of possibly many nested references. |
397 | */ | 389 | */ |
398 | while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) { | 390 | while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) { |
399 | switch (obj_desc->reference.opcode) { | 391 | switch (obj_desc->reference.opcode) { |
@@ -463,6 +455,11 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, | |||
463 | } | 455 | } |
464 | break; | 456 | break; |
465 | 457 | ||
458 | case AML_LOAD_OP: | ||
459 | |||
460 | type = ACPI_TYPE_DDB_HANDLE; | ||
461 | goto exit; | ||
462 | |||
466 | case AML_LOCAL_OP: | 463 | case AML_LOCAL_OP: |
467 | case AML_ARG_OP: | 464 | case AML_ARG_OP: |
468 | 465 | ||
diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c index 09d897b3f6d5..73e29e566a70 100644 --- a/drivers/acpi/executer/exresop.c +++ b/drivers/acpi/executer/exresop.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -137,7 +137,6 @@ acpi_ex_resolve_operands(u16 opcode, | |||
137 | union acpi_operand_object *obj_desc; | 137 | union acpi_operand_object *obj_desc; |
138 | acpi_status status = AE_OK; | 138 | acpi_status status = AE_OK; |
139 | u8 object_type; | 139 | u8 object_type; |
140 | void *temp_node; | ||
141 | u32 arg_types; | 140 | u32 arg_types; |
142 | const struct acpi_opcode_info *op_info; | 141 | const struct acpi_opcode_info *op_info; |
143 | u32 this_arg_type; | 142 | u32 this_arg_type; |
@@ -239,7 +238,6 @@ acpi_ex_resolve_operands(u16 opcode, | |||
239 | 238 | ||
240 | /*lint -fallthrough */ | 239 | /*lint -fallthrough */ |
241 | 240 | ||
242 | case AML_NAME_OP: | ||
243 | case AML_INDEX_OP: | 241 | case AML_INDEX_OP: |
244 | case AML_REF_OF_OP: | 242 | case AML_REF_OF_OP: |
245 | case AML_ARG_OP: | 243 | case AML_ARG_OP: |
@@ -332,15 +330,6 @@ acpi_ex_resolve_operands(u16 opcode, | |||
332 | if (ACPI_FAILURE(status)) { | 330 | if (ACPI_FAILURE(status)) { |
333 | return_ACPI_STATUS(status); | 331 | return_ACPI_STATUS(status); |
334 | } | 332 | } |
335 | |||
336 | if (obj_desc->reference.opcode == AML_NAME_OP) { | ||
337 | |||
338 | /* Convert a named reference to the actual named object */ | ||
339 | |||
340 | temp_node = obj_desc->reference.object; | ||
341 | acpi_ut_remove_reference(obj_desc); | ||
342 | (*stack_ptr) = temp_node; | ||
343 | } | ||
344 | goto next_operand; | 333 | goto next_operand; |
345 | 334 | ||
346 | case ARGI_DATAREFOBJ: /* Store operator only */ | 335 | case ARGI_DATAREFOBJ: /* Store operator only */ |
diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c index f4b69a637820..76c875bc3154 100644 --- a/drivers/acpi/executer/exstore.c +++ b/drivers/acpi/executer/exstore.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -84,8 +84,12 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, | |||
84 | 84 | ||
85 | ACPI_FUNCTION_TRACE_PTR(ex_do_debug_object, source_desc); | 85 | ACPI_FUNCTION_TRACE_PTR(ex_do_debug_object, source_desc); |
86 | 86 | ||
87 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s", | 87 | /* Print line header as long as we are not in the middle of an object display */ |
88 | level, " ")); | 88 | |
89 | if (!((level > 0) && index == 0)) { | ||
90 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s", | ||
91 | level, " ")); | ||
92 | } | ||
89 | 93 | ||
90 | /* Display index for package output only */ | 94 | /* Display index for package output only */ |
91 | 95 | ||
@@ -95,12 +99,12 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, | |||
95 | } | 99 | } |
96 | 100 | ||
97 | if (!source_desc) { | 101 | if (!source_desc) { |
98 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "<Null Object>\n")); | 102 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[Null Object]\n")); |
99 | return_VOID; | 103 | return_VOID; |
100 | } | 104 | } |
101 | 105 | ||
102 | if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_OPERAND) { | 106 | if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_OPERAND) { |
103 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%s: ", | 107 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%s ", |
104 | acpi_ut_get_object_type_name | 108 | acpi_ut_get_object_type_name |
105 | (source_desc))); | 109 | (source_desc))); |
106 | 110 | ||
@@ -123,6 +127,8 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, | |||
123 | return_VOID; | 127 | return_VOID; |
124 | } | 128 | } |
125 | 129 | ||
130 | /* source_desc is of type ACPI_DESC_TYPE_OPERAND */ | ||
131 | |||
126 | switch (ACPI_GET_OBJECT_TYPE(source_desc)) { | 132 | switch (ACPI_GET_OBJECT_TYPE(source_desc)) { |
127 | case ACPI_TYPE_INTEGER: | 133 | case ACPI_TYPE_INTEGER: |
128 | 134 | ||
@@ -147,7 +153,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, | |||
147 | (u32) source_desc->buffer.length)); | 153 | (u32) source_desc->buffer.length)); |
148 | ACPI_DUMP_BUFFER(source_desc->buffer.pointer, | 154 | ACPI_DUMP_BUFFER(source_desc->buffer.pointer, |
149 | (source_desc->buffer.length < | 155 | (source_desc->buffer.length < |
150 | 32) ? source_desc->buffer.length : 32); | 156 | 256) ? source_desc->buffer.length : 256); |
151 | break; | 157 | break; |
152 | 158 | ||
153 | case ACPI_TYPE_STRING: | 159 | case ACPI_TYPE_STRING: |
@@ -160,7 +166,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, | |||
160 | case ACPI_TYPE_PACKAGE: | 166 | case ACPI_TYPE_PACKAGE: |
161 | 167 | ||
162 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, | 168 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, |
163 | "[0x%.2X Elements]\n", | 169 | "[Contains 0x%.2X Elements]\n", |
164 | source_desc->package.count)); | 170 | source_desc->package.count)); |
165 | 171 | ||
166 | /* Output the entire contents of the package */ | 172 | /* Output the entire contents of the package */ |
@@ -180,12 +186,59 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, | |||
180 | (source_desc->reference.opcode), | 186 | (source_desc->reference.opcode), |
181 | source_desc->reference.offset)); | 187 | source_desc->reference.offset)); |
182 | } else { | 188 | } else { |
183 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[%s]\n", | 189 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[%s]", |
184 | acpi_ps_get_opcode_name | 190 | acpi_ps_get_opcode_name |
185 | (source_desc->reference.opcode))); | 191 | (source_desc->reference.opcode))); |
186 | } | 192 | } |
187 | 193 | ||
188 | if (source_desc->reference.object) { | 194 | if (source_desc->reference.opcode == AML_LOAD_OP) { /* Load and load_table */ |
195 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, | ||
196 | " Table OwnerId %p\n", | ||
197 | source_desc->reference.object)); | ||
198 | break; | ||
199 | } | ||
200 | |||
201 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, " ")); | ||
202 | |||
203 | /* Check for valid node first, then valid object */ | ||
204 | |||
205 | if (source_desc->reference.node) { | ||
206 | if (ACPI_GET_DESCRIPTOR_TYPE | ||
207 | (source_desc->reference.node) != | ||
208 | ACPI_DESC_TYPE_NAMED) { | ||
209 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, | ||
210 | " %p - Not a valid namespace node\n", | ||
211 | source_desc->reference. | ||
212 | node)); | ||
213 | } else { | ||
214 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, | ||
215 | "Node %p [%4.4s] ", | ||
216 | source_desc->reference. | ||
217 | node, | ||
218 | (source_desc->reference. | ||
219 | node)->name.ascii)); | ||
220 | |||
221 | switch ((source_desc->reference.node)->type) { | ||
222 | |||
223 | /* These types have no attached object */ | ||
224 | |||
225 | case ACPI_TYPE_DEVICE: | ||
226 | acpi_os_printf("Device\n"); | ||
227 | break; | ||
228 | |||
229 | case ACPI_TYPE_THERMAL: | ||
230 | acpi_os_printf("Thermal Zone\n"); | ||
231 | break; | ||
232 | |||
233 | default: | ||
234 | acpi_ex_do_debug_object((source_desc-> | ||
235 | reference. | ||
236 | node)->object, | ||
237 | level + 4, 0); | ||
238 | break; | ||
239 | } | ||
240 | } | ||
241 | } else if (source_desc->reference.object) { | ||
189 | if (ACPI_GET_DESCRIPTOR_TYPE | 242 | if (ACPI_GET_DESCRIPTOR_TYPE |
190 | (source_desc->reference.object) == | 243 | (source_desc->reference.object) == |
191 | ACPI_DESC_TYPE_NAMED) { | 244 | ACPI_DESC_TYPE_NAMED) { |
@@ -198,18 +251,13 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, | |||
198 | acpi_ex_do_debug_object(source_desc->reference. | 251 | acpi_ex_do_debug_object(source_desc->reference. |
199 | object, level + 4, 0); | 252 | object, level + 4, 0); |
200 | } | 253 | } |
201 | } else if (source_desc->reference.node) { | ||
202 | acpi_ex_do_debug_object((source_desc->reference.node)-> | ||
203 | object, level + 4, 0); | ||
204 | } | 254 | } |
205 | break; | 255 | break; |
206 | 256 | ||
207 | default: | 257 | default: |
208 | 258 | ||
209 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%p %s\n", | 259 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%p\n", |
210 | source_desc, | 260 | source_desc)); |
211 | acpi_ut_get_object_type_name | ||
212 | (source_desc))); | ||
213 | break; | 261 | break; |
214 | } | 262 | } |
215 | 263 | ||
@@ -313,7 +361,6 @@ acpi_ex_store(union acpi_operand_object *source_desc, | |||
313 | * 4) Store to the debug object | 361 | * 4) Store to the debug object |
314 | */ | 362 | */ |
315 | switch (ref_desc->reference.opcode) { | 363 | switch (ref_desc->reference.opcode) { |
316 | case AML_NAME_OP: | ||
317 | case AML_REF_OF_OP: | 364 | case AML_REF_OF_OP: |
318 | 365 | ||
319 | /* Storing an object into a Name "container" */ | 366 | /* Storing an object into a Name "container" */ |
@@ -415,11 +462,24 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, | |||
415 | */ | 462 | */ |
416 | obj_desc = *(index_desc->reference.where); | 463 | obj_desc = *(index_desc->reference.where); |
417 | 464 | ||
418 | status = | 465 | if (ACPI_GET_OBJECT_TYPE(source_desc) == |
419 | acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, | 466 | ACPI_TYPE_LOCAL_REFERENCE |
420 | walk_state); | 467 | && source_desc->reference.opcode == AML_LOAD_OP) { |
421 | if (ACPI_FAILURE(status)) { | 468 | |
422 | return_ACPI_STATUS(status); | 469 | /* This is a DDBHandle, just add a reference to it */ |
470 | |||
471 | acpi_ut_add_reference(source_desc); | ||
472 | new_desc = source_desc; | ||
473 | } else { | ||
474 | /* Normal object, copy it */ | ||
475 | |||
476 | status = | ||
477 | acpi_ut_copy_iobject_to_iobject(source_desc, | ||
478 | &new_desc, | ||
479 | walk_state); | ||
480 | if (ACPI_FAILURE(status)) { | ||
481 | return_ACPI_STATUS(status); | ||
482 | } | ||
423 | } | 483 | } |
424 | 484 | ||
425 | if (obj_desc) { | 485 | if (obj_desc) { |
@@ -571,10 +631,17 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, | |||
571 | 631 | ||
572 | /* If no implicit conversion, drop into the default case below */ | 632 | /* If no implicit conversion, drop into the default case below */ |
573 | 633 | ||
574 | if ((!implicit_conversion) || (walk_state->opcode == AML_COPY_OP)) { | 634 | if ((!implicit_conversion) || |
575 | 635 | ((walk_state->opcode == AML_COPY_OP) && | |
576 | /* Force execution of default (no implicit conversion) */ | 636 | (target_type != ACPI_TYPE_LOCAL_REGION_FIELD) && |
577 | 637 | (target_type != ACPI_TYPE_LOCAL_BANK_FIELD) && | |
638 | (target_type != ACPI_TYPE_LOCAL_INDEX_FIELD))) { | ||
639 | /* | ||
640 | * Force execution of default (no implicit conversion). Note: | ||
641 | * copy_object does not perform an implicit conversion, as per the ACPI | ||
642 | * spec -- except in case of region/bank/index fields -- because these | ||
643 | * objects must retain their original type permanently. | ||
644 | */ | ||
578 | target_type = ACPI_TYPE_ANY; | 645 | target_type = ACPI_TYPE_ANY; |
579 | } | 646 | } |
580 | 647 | ||
diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c index 1d622c625c64..a6d2168b81f9 100644 --- a/drivers/acpi/executer/exstoren.c +++ b/drivers/acpi/executer/exstoren.c | |||
@@ -7,7 +7,7 @@ | |||
7 | *****************************************************************************/ | 7 | *****************************************************************************/ |
8 | 8 | ||
9 | /* | 9 | /* |
10 | * Copyright (C) 2000 - 2007, R. Byron Moore | 10 | * Copyright (C) 2000 - 2008, Intel Corp. |
11 | * All rights reserved. | 11 | * All rights reserved. |
12 | * | 12 | * |
13 | * Redistribution and use in source and binary forms, with or without | 13 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c index 8233d40178ee..9a75ff09fb0c 100644 --- a/drivers/acpi/executer/exstorob.c +++ b/drivers/acpi/executer/exstorob.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c index 9460baff3032..68990f1df371 100644 --- a/drivers/acpi/executer/exsystem.c +++ b/drivers/acpi/executer/exsystem.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -44,7 +44,6 @@ | |||
44 | 44 | ||
45 | #include <acpi/acpi.h> | 45 | #include <acpi/acpi.h> |
46 | #include <acpi/acinterp.h> | 46 | #include <acpi/acinterp.h> |
47 | #include <acpi/acevents.h> | ||
48 | 47 | ||
49 | #define _COMPONENT ACPI_EXECUTER | 48 | #define _COMPONENT ACPI_EXECUTER |
50 | ACPI_MODULE_NAME("exsystem") | 49 | ACPI_MODULE_NAME("exsystem") |
diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c index 6b0aeccbb69b..86c03880b523 100644 --- a/drivers/acpi/executer/exutils.c +++ b/drivers/acpi/executer/exutils.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -61,7 +61,6 @@ | |||
61 | #include <acpi/acpi.h> | 61 | #include <acpi/acpi.h> |
62 | #include <acpi/acinterp.h> | 62 | #include <acpi/acinterp.h> |
63 | #include <acpi/amlcode.h> | 63 | #include <acpi/amlcode.h> |
64 | #include <acpi/acevents.h> | ||
65 | 64 | ||
66 | #define _COMPONENT ACPI_EXECUTER | 65 | #define _COMPONENT ACPI_EXECUTER |
67 | ACPI_MODULE_NAME("exutils") | 66 | ACPI_MODULE_NAME("exutils") |
@@ -217,9 +216,10 @@ void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc) | |||
217 | 216 | ||
218 | /* | 217 | /* |
219 | * Object must be a valid number and we must be executing | 218 | * Object must be a valid number and we must be executing |
220 | * a control method | 219 | * a control method. NS node could be there for AML_INT_NAMEPATH_OP. |
221 | */ | 220 | */ |
222 | if ((!obj_desc) || | 221 | if ((!obj_desc) || |
222 | (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) || | ||
223 | (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) { | 223 | (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) { |
224 | return; | 224 | return; |
225 | } | 225 | } |
@@ -240,72 +240,73 @@ void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc) | |||
240 | * PARAMETERS: field_flags - Flags with Lock rule: | 240 | * PARAMETERS: field_flags - Flags with Lock rule: |
241 | * always_lock or never_lock | 241 | * always_lock or never_lock |
242 | * | 242 | * |
243 | * RETURN: TRUE/FALSE indicating whether the lock was actually acquired | 243 | * RETURN: None |
244 | * | 244 | * |
245 | * DESCRIPTION: Obtain the global lock and keep track of this fact via two | 245 | * DESCRIPTION: Obtain the ACPI hardware Global Lock, only if the field |
246 | * methods. A global variable keeps the state of the lock, and | 246 | * flags specifiy that it is to be obtained before field access. |
247 | * the state is returned to the caller. | ||
248 | * | 247 | * |
249 | ******************************************************************************/ | 248 | ******************************************************************************/ |
250 | 249 | ||
251 | u8 acpi_ex_acquire_global_lock(u32 field_flags) | 250 | void acpi_ex_acquire_global_lock(u32 field_flags) |
252 | { | 251 | { |
253 | u8 locked = FALSE; | ||
254 | acpi_status status; | 252 | acpi_status status; |
255 | 253 | ||
256 | ACPI_FUNCTION_TRACE(ex_acquire_global_lock); | 254 | ACPI_FUNCTION_TRACE(ex_acquire_global_lock); |
257 | 255 | ||
258 | /* Only attempt lock if the always_lock bit is set */ | 256 | /* Only use the lock if the always_lock bit is set */ |
257 | |||
258 | if (!(field_flags & AML_FIELD_LOCK_RULE_MASK)) { | ||
259 | return_VOID; | ||
260 | } | ||
259 | 261 | ||
260 | if (field_flags & AML_FIELD_LOCK_RULE_MASK) { | 262 | /* Attempt to get the global lock, wait forever */ |
261 | 263 | ||
262 | /* We should attempt to get the lock, wait forever */ | 264 | status = acpi_ex_acquire_mutex_object(ACPI_WAIT_FOREVER, |
265 | acpi_gbl_global_lock_mutex, | ||
266 | acpi_os_get_thread_id()); | ||
263 | 267 | ||
264 | status = acpi_ev_acquire_global_lock(ACPI_WAIT_FOREVER); | 268 | if (ACPI_FAILURE(status)) { |
265 | if (ACPI_SUCCESS(status)) { | 269 | ACPI_EXCEPTION((AE_INFO, status, |
266 | locked = TRUE; | 270 | "Could not acquire Global Lock")); |
267 | } else { | ||
268 | ACPI_EXCEPTION((AE_INFO, status, | ||
269 | "Could not acquire Global Lock")); | ||
270 | } | ||
271 | } | 271 | } |
272 | 272 | ||
273 | return_UINT8(locked); | 273 | return_VOID; |
274 | } | 274 | } |
275 | 275 | ||
276 | /******************************************************************************* | 276 | /******************************************************************************* |
277 | * | 277 | * |
278 | * FUNCTION: acpi_ex_release_global_lock | 278 | * FUNCTION: acpi_ex_release_global_lock |
279 | * | 279 | * |
280 | * PARAMETERS: locked_by_me - Return value from corresponding call to | 280 | * PARAMETERS: field_flags - Flags with Lock rule: |
281 | * acquire_global_lock. | 281 | * always_lock or never_lock |
282 | * | 282 | * |
283 | * RETURN: None | 283 | * RETURN: None |
284 | * | 284 | * |
285 | * DESCRIPTION: Release the global lock if it is locked. | 285 | * DESCRIPTION: Release the ACPI hardware Global Lock |
286 | * | 286 | * |
287 | ******************************************************************************/ | 287 | ******************************************************************************/ |
288 | 288 | ||
289 | void acpi_ex_release_global_lock(u8 locked_by_me) | 289 | void acpi_ex_release_global_lock(u32 field_flags) |
290 | { | 290 | { |
291 | acpi_status status; | 291 | acpi_status status; |
292 | 292 | ||
293 | ACPI_FUNCTION_TRACE(ex_release_global_lock); | 293 | ACPI_FUNCTION_TRACE(ex_release_global_lock); |
294 | 294 | ||
295 | /* Only attempt unlock if the caller locked it */ | 295 | /* Only use the lock if the always_lock bit is set */ |
296 | 296 | ||
297 | if (locked_by_me) { | 297 | if (!(field_flags & AML_FIELD_LOCK_RULE_MASK)) { |
298 | return_VOID; | ||
299 | } | ||
298 | 300 | ||
299 | /* OK, now release the lock */ | 301 | /* Release the global lock */ |
300 | 302 | ||
301 | status = acpi_ev_release_global_lock(); | 303 | status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex); |
302 | if (ACPI_FAILURE(status)) { | 304 | if (ACPI_FAILURE(status)) { |
303 | 305 | ||
304 | /* Report the error, but there isn't much else we can do */ | 306 | /* Report the error, but there isn't much else we can do */ |
305 | 307 | ||
306 | ACPI_EXCEPTION((AE_INFO, status, | 308 | ACPI_EXCEPTION((AE_INFO, status, |
307 | "Could not release ACPI Global Lock")); | 309 | "Could not release Global Lock")); |
308 | } | ||
309 | } | 310 | } |
310 | 311 | ||
311 | return_VOID; | 312 | return_VOID; |
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index eda0978b57c6..06f8634fe58b 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -142,6 +142,7 @@ EXPORT_SYMBOL(acpi_get_physical_device); | |||
142 | 142 | ||
143 | static int acpi_bind_one(struct device *dev, acpi_handle handle) | 143 | static int acpi_bind_one(struct device *dev, acpi_handle handle) |
144 | { | 144 | { |
145 | struct acpi_device *acpi_dev; | ||
145 | acpi_status status; | 146 | acpi_status status; |
146 | 147 | ||
147 | if (dev->archdata.acpi_handle) { | 148 | if (dev->archdata.acpi_handle) { |
@@ -157,6 +158,16 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) | |||
157 | } | 158 | } |
158 | dev->archdata.acpi_handle = handle; | 159 | dev->archdata.acpi_handle = handle; |
159 | 160 | ||
161 | status = acpi_bus_get_device(handle, &acpi_dev); | ||
162 | if (!ACPI_FAILURE(status)) { | ||
163 | int ret; | ||
164 | |||
165 | ret = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj, | ||
166 | "firmware_node"); | ||
167 | ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, | ||
168 | "physical_node"); | ||
169 | } | ||
170 | |||
160 | return 0; | 171 | return 0; |
161 | } | 172 | } |
162 | 173 | ||
@@ -165,8 +176,17 @@ static int acpi_unbind_one(struct device *dev) | |||
165 | if (!dev->archdata.acpi_handle) | 176 | if (!dev->archdata.acpi_handle) |
166 | return 0; | 177 | return 0; |
167 | if (dev == acpi_get_physical_device(dev->archdata.acpi_handle)) { | 178 | if (dev == acpi_get_physical_device(dev->archdata.acpi_handle)) { |
179 | struct acpi_device *acpi_dev; | ||
180 | |||
168 | /* acpi_get_physical_device increase refcnt by one */ | 181 | /* acpi_get_physical_device increase refcnt by one */ |
169 | put_device(dev); | 182 | put_device(dev); |
183 | |||
184 | if (!acpi_bus_get_device(dev->archdata.acpi_handle, | ||
185 | &acpi_dev)) { | ||
186 | sysfs_remove_link(&dev->kobj, "firmware_node"); | ||
187 | sysfs_remove_link(&acpi_dev->dev.kobj, "physical_node"); | ||
188 | } | ||
189 | |||
170 | acpi_detach_data(dev->archdata.acpi_handle, | 190 | acpi_detach_data(dev->archdata.acpi_handle, |
171 | acpi_glue_data_handler); | 191 | acpi_glue_data_handler); |
172 | dev->archdata.acpi_handle = NULL; | 192 | dev->archdata.acpi_handle = NULL; |
diff --git a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c index 6031ca13dd2f..816894ea839e 100644 --- a/drivers/acpi/hardware/hwacpi.c +++ b/drivers/acpi/hardware/hwacpi.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c index 117a05cadaaa..14bc4f456ae8 100644 --- a/drivers/acpi/hardware/hwgpe.c +++ b/drivers/acpi/hardware/hwgpe.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c index 73f9c5fb1ba7..ddf792adcf96 100644 --- a/drivers/acpi/hardware/hwregs.c +++ b/drivers/acpi/hardware/hwregs.c | |||
@@ -7,7 +7,7 @@ | |||
7 | ******************************************************************************/ | 7 | ******************************************************************************/ |
8 | 8 | ||
9 | /* | 9 | /* |
10 | * Copyright (C) 2000 - 2007, R. Byron Moore | 10 | * Copyright (C) 2000 - 2008, Intel Corp. |
11 | * All rights reserved. | 11 | * All rights reserved. |
12 | * | 12 | * |
13 | * Redistribution and use in source and binary forms, with or without | 13 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c index 4290e0193097..d9937e05ec6a 100644 --- a/drivers/acpi/hardware/hwsleep.c +++ b/drivers/acpi/hardware/hwsleep.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -70,9 +70,10 @@ acpi_set_firmware_waking_vector(acpi_physical_address physical_address) | |||
70 | 70 | ||
71 | /* Get the FACS */ | 71 | /* Get the FACS */ |
72 | 72 | ||
73 | status = | 73 | status = acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, |
74 | acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, | 74 | ACPI_CAST_INDIRECT_PTR(struct |
75 | (struct acpi_table_header **)&facs); | 75 | acpi_table_header, |
76 | &facs)); | ||
76 | if (ACPI_FAILURE(status)) { | 77 | if (ACPI_FAILURE(status)) { |
77 | return_ACPI_STATUS(status); | 78 | return_ACPI_STATUS(status); |
78 | } | 79 | } |
@@ -124,9 +125,10 @@ acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) | |||
124 | 125 | ||
125 | /* Get the FACS */ | 126 | /* Get the FACS */ |
126 | 127 | ||
127 | status = | 128 | status = acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, |
128 | acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, | 129 | ACPI_CAST_INDIRECT_PTR(struct |
129 | (struct acpi_table_header **)&facs); | 130 | acpi_table_header, |
131 | &facs)); | ||
130 | if (ACPI_FAILURE(status)) { | 132 | if (ACPI_FAILURE(status)) { |
131 | return_ACPI_STATUS(status); | 133 | return_ACPI_STATUS(status); |
132 | } | 134 | } |
diff --git a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c index c32eab696acd..b53d575491b9 100644 --- a/drivers/acpi/hardware/hwtimer.c +++ b/drivers/acpi/hardware/hwtimer.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c index 57faf598bad8..c39a7f68b889 100644 --- a/drivers/acpi/namespace/nsaccess.c +++ b/drivers/acpi/namespace/nsaccess.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -208,8 +208,7 @@ acpi_status acpi_ns_root_initialize(void) | |||
208 | /* Special case for ACPI Global Lock */ | 208 | /* Special case for ACPI Global Lock */ |
209 | 209 | ||
210 | if (ACPI_STRCMP(init_val->name, "_GL_") == 0) { | 210 | if (ACPI_STRCMP(init_val->name, "_GL_") == 0) { |
211 | acpi_gbl_global_lock_mutex = | 211 | acpi_gbl_global_lock_mutex = obj_desc; |
212 | obj_desc->mutex.os_mutex; | ||
213 | 212 | ||
214 | /* Create additional counting semaphore for global lock */ | 213 | /* Create additional counting semaphore for global lock */ |
215 | 214 | ||
@@ -582,44 +581,68 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, | |||
582 | return_ACPI_STATUS(status); | 581 | return_ACPI_STATUS(status); |
583 | } | 582 | } |
584 | 583 | ||
585 | /* | 584 | /* More segments to follow? */ |
586 | * Sanity typecheck of the target object: | 585 | |
587 | * | 586 | if (num_segments > 0) { |
588 | * If 1) This is the last segment (num_segments == 0) | 587 | /* |
589 | * 2) And we are looking for a specific type | 588 | * If we have an alias to an object that opens a scope (such as a |
590 | * (Not checking for TYPE_ANY) | 589 | * device or processor), we need to dereference the alias here so that |
591 | * 3) Which is not an alias | 590 | * we can access any children of the original node (via the remaining |
592 | * 4) Which is not a local type (TYPE_SCOPE) | 591 | * segments). |
593 | * 5) And the type of target object is known (not TYPE_ANY) | 592 | */ |
594 | * 6) And target object does not match what we are looking for | 593 | if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) { |
595 | * | 594 | if (acpi_ns_opens_scope |
596 | * Then we have a type mismatch. Just warn and ignore it. | 595 | (((struct acpi_namespace_node *)this_node-> |
597 | */ | 596 | object)->type)) { |
598 | if ((num_segments == 0) && | 597 | this_node = |
599 | (type_to_check_for != ACPI_TYPE_ANY) && | 598 | (struct acpi_namespace_node *) |
600 | (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) && | 599 | this_node->object; |
601 | (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS) && | 600 | } |
602 | (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE) && | 601 | } |
603 | (this_node->type != ACPI_TYPE_ANY) && | ||
604 | (this_node->type != type_to_check_for)) { | ||
605 | |||
606 | /* Complain about a type mismatch */ | ||
607 | |||
608 | ACPI_WARNING((AE_INFO, | ||
609 | "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)", | ||
610 | ACPI_CAST_PTR(char, &simple_name), | ||
611 | acpi_ut_get_type_name(this_node->type), | ||
612 | acpi_ut_get_type_name | ||
613 | (type_to_check_for))); | ||
614 | } | 602 | } |
615 | 603 | ||
616 | /* | 604 | /* Special handling for the last segment (num_segments == 0) */ |
617 | * If this is the last name segment and we are not looking for a | 605 | |
618 | * specific type, but the type of found object is known, use that type | 606 | else { |
619 | * to see if it opens a scope. | 607 | /* |
620 | */ | 608 | * Sanity typecheck of the target object: |
621 | if ((num_segments == 0) && (type == ACPI_TYPE_ANY)) { | 609 | * |
622 | type = this_node->type; | 610 | * If 1) This is the last segment (num_segments == 0) |
611 | * 2) And we are looking for a specific type | ||
612 | * (Not checking for TYPE_ANY) | ||
613 | * 3) Which is not an alias | ||
614 | * 4) Which is not a local type (TYPE_SCOPE) | ||
615 | * 5) And the type of target object is known (not TYPE_ANY) | ||
616 | * 6) And target object does not match what we are looking for | ||
617 | * | ||
618 | * Then we have a type mismatch. Just warn and ignore it. | ||
619 | */ | ||
620 | if ((type_to_check_for != ACPI_TYPE_ANY) && | ||
621 | (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) && | ||
622 | (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS) | ||
623 | && (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE) | ||
624 | && (this_node->type != ACPI_TYPE_ANY) | ||
625 | && (this_node->type != type_to_check_for)) { | ||
626 | |||
627 | /* Complain about a type mismatch */ | ||
628 | |||
629 | ACPI_WARNING((AE_INFO, | ||
630 | "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)", | ||
631 | ACPI_CAST_PTR(char, &simple_name), | ||
632 | acpi_ut_get_type_name(this_node-> | ||
633 | type), | ||
634 | acpi_ut_get_type_name | ||
635 | (type_to_check_for))); | ||
636 | } | ||
637 | |||
638 | /* | ||
639 | * If this is the last name segment and we are not looking for a | ||
640 | * specific type, but the type of found object is known, use that type | ||
641 | * to (later) see if it opens a scope. | ||
642 | */ | ||
643 | if (type == ACPI_TYPE_ANY) { | ||
644 | type = this_node->type; | ||
645 | } | ||
623 | } | 646 | } |
624 | 647 | ||
625 | /* Point to next name segment and make this node current */ | 648 | /* Point to next name segment and make this node current */ |
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c index 1d693d8ad2d8..3a1740ac2edc 100644 --- a/drivers/acpi/namespace/nsalloc.c +++ b/drivers/acpi/namespace/nsalloc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c index 1fc4f86676e1..5445751b8a3e 100644 --- a/drivers/acpi/namespace/nsdump.c +++ b/drivers/acpi/namespace/nsdump.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -249,7 +249,9 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, | |||
249 | acpi_os_printf("ID %X Len %.4X Addr %p\n", | 249 | acpi_os_printf("ID %X Len %.4X Addr %p\n", |
250 | obj_desc->processor.proc_id, | 250 | obj_desc->processor.proc_id, |
251 | obj_desc->processor.length, | 251 | obj_desc->processor.length, |
252 | (char *)obj_desc->processor.address); | 252 | ACPI_CAST_PTR(void, |
253 | obj_desc->processor. | ||
254 | address)); | ||
253 | break; | 255 | break; |
254 | 256 | ||
255 | case ACPI_TYPE_DEVICE: | 257 | case ACPI_TYPE_DEVICE: |
@@ -320,9 +322,8 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, | |||
320 | space_id)); | 322 | space_id)); |
321 | if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { | 323 | if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { |
322 | acpi_os_printf(" Addr %8.8X%8.8X Len %.4X\n", | 324 | acpi_os_printf(" Addr %8.8X%8.8X Len %.4X\n", |
323 | ACPI_FORMAT_UINT64(obj_desc-> | 325 | ACPI_FORMAT_NATIVE_UINT |
324 | region. | 326 | (obj_desc->region.address), |
325 | address), | ||
326 | obj_desc->region.length); | 327 | obj_desc->region.length); |
327 | } else { | 328 | } else { |
328 | acpi_os_printf | 329 | acpi_os_printf |
diff --git a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c index 5097e167939e..428f50fde11a 100644 --- a/drivers/acpi/namespace/nsdumpdv.c +++ b/drivers/acpi/namespace/nsdumpdv.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index 97b2ac57c16b..14bdfa92bea0 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/namespace/nseval.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c index 33db2241044e..6d6d930c8e18 100644 --- a/drivers/acpi/namespace/nsinit.c +++ b/drivers/acpi/namespace/nsinit.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -244,6 +244,10 @@ acpi_ns_init_one_object(acpi_handle obj_handle, | |||
244 | info->field_count++; | 244 | info->field_count++; |
245 | break; | 245 | break; |
246 | 246 | ||
247 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
248 | info->field_count++; | ||
249 | break; | ||
250 | |||
247 | case ACPI_TYPE_BUFFER: | 251 | case ACPI_TYPE_BUFFER: |
248 | info->buffer_count++; | 252 | info->buffer_count++; |
249 | break; | 253 | break; |
@@ -287,6 +291,12 @@ acpi_ns_init_one_object(acpi_handle obj_handle, | |||
287 | status = acpi_ds_get_buffer_field_arguments(obj_desc); | 291 | status = acpi_ds_get_buffer_field_arguments(obj_desc); |
288 | break; | 292 | break; |
289 | 293 | ||
294 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
295 | |||
296 | info->field_init++; | ||
297 | status = acpi_ds_get_bank_field_arguments(obj_desc); | ||
298 | break; | ||
299 | |||
290 | case ACPI_TYPE_BUFFER: | 300 | case ACPI_TYPE_BUFFER: |
291 | 301 | ||
292 | info->buffer_init++; | 302 | info->buffer_init++; |
diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c index d4f9654fd20f..2c92f6cf5ce1 100644 --- a/drivers/acpi/namespace/nsload.c +++ b/drivers/acpi/namespace/nsload.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -107,11 +107,11 @@ acpi_ns_load_table(acpi_native_uint table_index, | |||
107 | goto unlock; | 107 | goto unlock; |
108 | } | 108 | } |
109 | 109 | ||
110 | status = acpi_ns_parse_table(table_index, node->child); | 110 | status = acpi_ns_parse_table(table_index, node); |
111 | if (ACPI_SUCCESS(status)) { | 111 | if (ACPI_SUCCESS(status)) { |
112 | acpi_tb_set_table_loaded_flag(table_index, TRUE); | 112 | acpi_tb_set_table_loaded_flag(table_index, TRUE); |
113 | } else { | 113 | } else { |
114 | acpi_tb_release_owner_id(table_index); | 114 | (void)acpi_tb_release_owner_id(table_index); |
115 | } | 115 | } |
116 | 116 | ||
117 | unlock: | 117 | unlock: |
diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c index cbd94af08cc5..cffef1bcbdbc 100644 --- a/drivers/acpi/namespace/nsnames.c +++ b/drivers/acpi/namespace/nsnames.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -180,6 +180,12 @@ acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node) | |||
180 | next_node = node; | 180 | next_node = node; |
181 | 181 | ||
182 | while (next_node && (next_node != acpi_gbl_root_node)) { | 182 | while (next_node && (next_node != acpi_gbl_root_node)) { |
183 | if (ACPI_GET_DESCRIPTOR_TYPE(next_node) != ACPI_DESC_TYPE_NAMED) { | ||
184 | ACPI_ERROR((AE_INFO, | ||
185 | "Invalid NS Node (%p) while traversing path", | ||
186 | next_node)); | ||
187 | return 0; | ||
188 | } | ||
183 | size += ACPI_PATH_SEGMENT_LENGTH; | 189 | size += ACPI_PATH_SEGMENT_LENGTH; |
184 | next_node = acpi_ns_get_parent_node(next_node); | 190 | next_node = acpi_ns_get_parent_node(next_node); |
185 | } | 191 | } |
diff --git a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c index d9d7377bc6e6..15fe09e24f71 100644 --- a/drivers/acpi/namespace/nsobject.c +++ b/drivers/acpi/namespace/nsobject.c | |||
@@ -6,7 +6,7 @@ | |||
6 | ******************************************************************************/ | 6 | ******************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c index e696aa847990..46a79b0103b6 100644 --- a/drivers/acpi/namespace/nsparse.c +++ b/drivers/acpi/namespace/nsparse.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -64,7 +64,8 @@ ACPI_MODULE_NAME("nsparse") | |||
64 | ******************************************************************************/ | 64 | ******************************************************************************/ |
65 | acpi_status | 65 | acpi_status |
66 | acpi_ns_one_complete_parse(acpi_native_uint pass_number, | 66 | acpi_ns_one_complete_parse(acpi_native_uint pass_number, |
67 | acpi_native_uint table_index) | 67 | acpi_native_uint table_index, |
68 | struct acpi_namespace_node * start_node) | ||
68 | { | 69 | { |
69 | union acpi_parse_object *parse_root; | 70 | union acpi_parse_object *parse_root; |
70 | acpi_status status; | 71 | acpi_status status; |
@@ -111,14 +112,25 @@ acpi_ns_one_complete_parse(acpi_native_uint pass_number, | |||
111 | aml_start = (u8 *) table + sizeof(struct acpi_table_header); | 112 | aml_start = (u8 *) table + sizeof(struct acpi_table_header); |
112 | aml_length = table->length - sizeof(struct acpi_table_header); | 113 | aml_length = table->length - sizeof(struct acpi_table_header); |
113 | status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, | 114 | status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, |
114 | aml_start, aml_length, NULL, | 115 | aml_start, (u32) aml_length, |
115 | (u8) pass_number); | 116 | NULL, (u8) pass_number); |
116 | } | 117 | } |
117 | 118 | ||
118 | if (ACPI_FAILURE(status)) { | 119 | if (ACPI_FAILURE(status)) { |
119 | acpi_ds_delete_walk_state(walk_state); | 120 | acpi_ds_delete_walk_state(walk_state); |
120 | acpi_ps_delete_parse_tree(parse_root); | 121 | goto cleanup; |
121 | return_ACPI_STATUS(status); | 122 | } |
123 | |||
124 | /* start_node is the default location to load the table */ | ||
125 | |||
126 | if (start_node && start_node != acpi_gbl_root_node) { | ||
127 | status = | ||
128 | acpi_ds_scope_stack_push(start_node, ACPI_TYPE_METHOD, | ||
129 | walk_state); | ||
130 | if (ACPI_FAILURE(status)) { | ||
131 | acpi_ds_delete_walk_state(walk_state); | ||
132 | goto cleanup; | ||
133 | } | ||
122 | } | 134 | } |
123 | 135 | ||
124 | /* Parse the AML */ | 136 | /* Parse the AML */ |
@@ -127,6 +139,7 @@ acpi_ns_one_complete_parse(acpi_native_uint pass_number, | |||
127 | (unsigned)pass_number)); | 139 | (unsigned)pass_number)); |
128 | status = acpi_ps_parse_aml(walk_state); | 140 | status = acpi_ps_parse_aml(walk_state); |
129 | 141 | ||
142 | cleanup: | ||
130 | acpi_ps_delete_parse_tree(parse_root); | 143 | acpi_ps_delete_parse_tree(parse_root); |
131 | return_ACPI_STATUS(status); | 144 | return_ACPI_STATUS(status); |
132 | } | 145 | } |
@@ -163,7 +176,9 @@ acpi_ns_parse_table(acpi_native_uint table_index, | |||
163 | * performs another complete parse of the AML. | 176 | * performs another complete parse of the AML. |
164 | */ | 177 | */ |
165 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); | 178 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); |
166 | status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index); | 179 | status = |
180 | acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index, | ||
181 | start_node); | ||
167 | if (ACPI_FAILURE(status)) { | 182 | if (ACPI_FAILURE(status)) { |
168 | return_ACPI_STATUS(status); | 183 | return_ACPI_STATUS(status); |
169 | } | 184 | } |
@@ -178,7 +193,9 @@ acpi_ns_parse_table(acpi_native_uint table_index, | |||
178 | * parse objects are all cached. | 193 | * parse objects are all cached. |
179 | */ | 194 | */ |
180 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); | 195 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); |
181 | status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index); | 196 | status = |
197 | acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index, | ||
198 | start_node); | ||
182 | if (ACPI_FAILURE(status)) { | 199 | if (ACPI_FAILURE(status)) { |
183 | return_ACPI_STATUS(status); | 200 | return_ACPI_STATUS(status); |
184 | } | 201 | } |
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c index e863be665ce8..8399276cba1e 100644 --- a/drivers/acpi/namespace/nssearch.c +++ b/drivers/acpi/namespace/nssearch.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c index 90fd059615ff..64c039843ed2 100644 --- a/drivers/acpi/namespace/nsutils.c +++ b/drivers/acpi/namespace/nsutils.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/namespace/nswalk.c b/drivers/acpi/namespace/nswalk.c index 280b8357c46c..3c905ce26d7d 100644 --- a/drivers/acpi/namespace/nswalk.c +++ b/drivers/acpi/namespace/nswalk.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -77,9 +77,7 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct | |||
77 | 77 | ||
78 | /* It's really the parent's _scope_ that we want */ | 78 | /* It's really the parent's _scope_ that we want */ |
79 | 79 | ||
80 | if (parent_node->child) { | 80 | next_node = parent_node->child; |
81 | next_node = parent_node->child; | ||
82 | } | ||
83 | } | 81 | } |
84 | 82 | ||
85 | else { | 83 | else { |
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index b92133faf5b7..a8d549187c84 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c | |||
@@ -6,7 +6,7 @@ | |||
6 | ******************************************************************************/ | 6 | ******************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -467,10 +467,13 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, | |||
467 | return (AE_CTRL_DEPTH); | 467 | return (AE_CTRL_DEPTH); |
468 | } | 468 | } |
469 | 469 | ||
470 | if (!(flags & ACPI_STA_DEVICE_PRESENT)) { | 470 | if (!(flags & ACPI_STA_DEVICE_PRESENT) && |
471 | 471 | !(flags & ACPI_STA_DEVICE_FUNCTIONING)) { | |
472 | /* Don't examine children of the device if not present */ | 472 | /* |
473 | 473 | * Don't examine the children of the device only when the | |
474 | * device is neither present nor functional. See ACPI spec, | ||
475 | * description of _STA for more information. | ||
476 | */ | ||
474 | return (AE_CTRL_DEPTH); | 477 | return (AE_CTRL_DEPTH); |
475 | } | 478 | } |
476 | 479 | ||
@@ -539,7 +542,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, | |||
539 | * value is returned to the caller. | 542 | * value is returned to the caller. |
540 | * | 543 | * |
541 | * This is a wrapper for walk_namespace, but the callback performs | 544 | * This is a wrapper for walk_namespace, but the callback performs |
542 | * additional filtering. Please see acpi_get_device_callback. | 545 | * additional filtering. Please see acpi_ns_get_device_callback. |
543 | * | 546 | * |
544 | ******************************************************************************/ | 547 | ******************************************************************************/ |
545 | 548 | ||
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c index b489781b22a8..a287ed550f54 100644 --- a/drivers/acpi/namespace/nsxfname.c +++ b/drivers/acpi/namespace/nsxfname.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c index faa375887201..2b375ee80cef 100644 --- a/drivers/acpi/namespace/nsxfobj.c +++ b/drivers/acpi/namespace/nsxfobj.c | |||
@@ -6,7 +6,7 @@ | |||
6 | ******************************************************************************/ | 6 | ******************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index a498a6cc68fe..235a1386888a 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -742,6 +742,7 @@ EXPORT_SYMBOL(acpi_os_execute); | |||
742 | void acpi_os_wait_events_complete(void *context) | 742 | void acpi_os_wait_events_complete(void *context) |
743 | { | 743 | { |
744 | flush_workqueue(kacpid_wq); | 744 | flush_workqueue(kacpid_wq); |
745 | flush_workqueue(kacpi_notify_wq); | ||
745 | } | 746 | } |
746 | 747 | ||
747 | EXPORT_SYMBOL(acpi_os_wait_events_complete); | 748 | EXPORT_SYMBOL(acpi_os_wait_events_complete); |
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c index c2b9835c890b..f1e8bf65e24e 100644 --- a/drivers/acpi/parser/psargs.c +++ b/drivers/acpi/parser/psargs.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -230,12 +230,12 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, | |||
230 | struct acpi_parse_state *parser_state, | 230 | struct acpi_parse_state *parser_state, |
231 | union acpi_parse_object *arg, u8 possible_method_call) | 231 | union acpi_parse_object *arg, u8 possible_method_call) |
232 | { | 232 | { |
233 | acpi_status status; | ||
233 | char *path; | 234 | char *path; |
234 | union acpi_parse_object *name_op; | 235 | union acpi_parse_object *name_op; |
235 | acpi_status status; | ||
236 | union acpi_operand_object *method_desc; | 236 | union acpi_operand_object *method_desc; |
237 | struct acpi_namespace_node *node; | 237 | struct acpi_namespace_node *node; |
238 | union acpi_generic_state scope_info; | 238 | u8 *start = parser_state->aml; |
239 | 239 | ||
240 | ACPI_FUNCTION_TRACE(ps_get_next_namepath); | 240 | ACPI_FUNCTION_TRACE(ps_get_next_namepath); |
241 | 241 | ||
@@ -249,25 +249,18 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, | |||
249 | return_ACPI_STATUS(AE_OK); | 249 | return_ACPI_STATUS(AE_OK); |
250 | } | 250 | } |
251 | 251 | ||
252 | /* Setup search scope info */ | ||
253 | |||
254 | scope_info.scope.node = NULL; | ||
255 | node = parser_state->start_node; | ||
256 | if (node) { | ||
257 | scope_info.scope.node = node; | ||
258 | } | ||
259 | |||
260 | /* | 252 | /* |
261 | * Lookup the name in the internal namespace. We don't want to add | 253 | * Lookup the name in the internal namespace, starting with the current |
262 | * anything new to the namespace here, however, so we use MODE_EXECUTE. | 254 | * scope. We don't want to add anything new to the namespace here, |
255 | * however, so we use MODE_EXECUTE. | ||
263 | * Allow searching of the parent tree, but don't open a new scope - | 256 | * Allow searching of the parent tree, but don't open a new scope - |
264 | * we just want to lookup the object (must be mode EXECUTE to perform | 257 | * we just want to lookup the object (must be mode EXECUTE to perform |
265 | * the upsearch) | 258 | * the upsearch) |
266 | */ | 259 | */ |
267 | status = | 260 | status = acpi_ns_lookup(walk_state->scope_info, path, |
268 | acpi_ns_lookup(&scope_info, path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, | 261 | ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, |
269 | ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, | 262 | ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, |
270 | NULL, &node); | 263 | NULL, &node); |
271 | 264 | ||
272 | /* | 265 | /* |
273 | * If this name is a control method invocation, we must | 266 | * If this name is a control method invocation, we must |
@@ -275,6 +268,16 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, | |||
275 | */ | 268 | */ |
276 | if (ACPI_SUCCESS(status) && | 269 | if (ACPI_SUCCESS(status) && |
277 | possible_method_call && (node->type == ACPI_TYPE_METHOD)) { | 270 | possible_method_call && (node->type == ACPI_TYPE_METHOD)) { |
271 | if (walk_state->op->common.aml_opcode == AML_UNLOAD_OP) { | ||
272 | /* | ||
273 | * acpi_ps_get_next_namestring has increased the AML pointer, | ||
274 | * so we need to restore the saved AML pointer for method call. | ||
275 | */ | ||
276 | walk_state->parser_state.aml = start; | ||
277 | walk_state->arg_count = 1; | ||
278 | acpi_ps_init_op(arg, AML_INT_METHODCALL_OP); | ||
279 | return_ACPI_STATUS(AE_OK); | ||
280 | } | ||
278 | 281 | ||
279 | /* This name is actually a control method invocation */ | 282 | /* This name is actually a control method invocation */ |
280 | 283 | ||
@@ -686,9 +689,29 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, | |||
686 | return_ACPI_STATUS(AE_NO_MEMORY); | 689 | return_ACPI_STATUS(AE_NO_MEMORY); |
687 | } | 690 | } |
688 | 691 | ||
689 | status = | 692 | /* To support super_name arg of Unload */ |
690 | acpi_ps_get_next_namepath(walk_state, parser_state, | 693 | |
691 | arg, 0); | 694 | if (walk_state->op->common.aml_opcode == AML_UNLOAD_OP) { |
695 | status = | ||
696 | acpi_ps_get_next_namepath(walk_state, | ||
697 | parser_state, arg, | ||
698 | 1); | ||
699 | |||
700 | /* | ||
701 | * If the super_name arg of Unload is a method call, | ||
702 | * we have restored the AML pointer, just free this Arg | ||
703 | */ | ||
704 | if (arg->common.aml_opcode == | ||
705 | AML_INT_METHODCALL_OP) { | ||
706 | acpi_ps_free_op(arg); | ||
707 | arg = NULL; | ||
708 | } | ||
709 | } else { | ||
710 | status = | ||
711 | acpi_ps_get_next_namepath(walk_state, | ||
712 | parser_state, arg, | ||
713 | 0); | ||
714 | } | ||
692 | } else { | 715 | } else { |
693 | /* Single complex argument, nothing returned */ | 716 | /* Single complex argument, nothing returned */ |
694 | 717 | ||
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c index 773aee82fbb8..c06238e55d98 100644 --- a/drivers/acpi/parser/psloop.c +++ b/drivers/acpi/parser/psloop.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -182,6 +182,7 @@ acpi_ps_build_named_op(struct acpi_walk_state *walk_state, | |||
182 | ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state); | 182 | ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state); |
183 | 183 | ||
184 | unnamed_op->common.value.arg = NULL; | 184 | unnamed_op->common.value.arg = NULL; |
185 | unnamed_op->common.arg_list_length = 0; | ||
185 | unnamed_op->common.aml_opcode = walk_state->opcode; | 186 | unnamed_op->common.aml_opcode = walk_state->opcode; |
186 | 187 | ||
187 | /* | 188 | /* |
@@ -241,7 +242,8 @@ acpi_ps_build_named_op(struct acpi_walk_state *walk_state, | |||
241 | acpi_ps_append_arg(*op, unnamed_op->common.value.arg); | 242 | acpi_ps_append_arg(*op, unnamed_op->common.value.arg); |
242 | acpi_gbl_depth++; | 243 | acpi_gbl_depth++; |
243 | 244 | ||
244 | if ((*op)->common.aml_opcode == AML_REGION_OP) { | 245 | if ((*op)->common.aml_opcode == AML_REGION_OP || |
246 | (*op)->common.aml_opcode == AML_DATA_REGION_OP) { | ||
245 | /* | 247 | /* |
246 | * Defer final parsing of an operation_region body, because we don't | 248 | * Defer final parsing of an operation_region body, because we don't |
247 | * have enough info in the first pass to parse it correctly (i.e., | 249 | * have enough info in the first pass to parse it correctly (i.e., |
@@ -280,6 +282,9 @@ acpi_ps_create_op(struct acpi_walk_state *walk_state, | |||
280 | acpi_status status = AE_OK; | 282 | acpi_status status = AE_OK; |
281 | union acpi_parse_object *op; | 283 | union acpi_parse_object *op; |
282 | union acpi_parse_object *named_op = NULL; | 284 | union acpi_parse_object *named_op = NULL; |
285 | union acpi_parse_object *parent_scope; | ||
286 | u8 argument_count; | ||
287 | const struct acpi_opcode_info *op_info; | ||
283 | 288 | ||
284 | ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state); | 289 | ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state); |
285 | 290 | ||
@@ -320,8 +325,32 @@ acpi_ps_create_op(struct acpi_walk_state *walk_state, | |||
320 | op->named.length = 0; | 325 | op->named.length = 0; |
321 | } | 326 | } |
322 | 327 | ||
323 | acpi_ps_append_arg(acpi_ps_get_parent_scope | 328 | if (walk_state->opcode == AML_BANK_FIELD_OP) { |
324 | (&(walk_state->parser_state)), op); | 329 | /* |
330 | * Backup to beginning of bank_field declaration | ||
331 | * body_length is unknown until we parse the body | ||
332 | */ | ||
333 | op->named.data = aml_op_start; | ||
334 | op->named.length = 0; | ||
335 | } | ||
336 | |||
337 | parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state)); | ||
338 | acpi_ps_append_arg(parent_scope, op); | ||
339 | |||
340 | if (parent_scope) { | ||
341 | op_info = | ||
342 | acpi_ps_get_opcode_info(parent_scope->common.aml_opcode); | ||
343 | if (op_info->flags & AML_HAS_TARGET) { | ||
344 | argument_count = | ||
345 | acpi_ps_get_argument_count(op_info->type); | ||
346 | if (parent_scope->common.arg_list_length > | ||
347 | argument_count) { | ||
348 | op->common.flags |= ACPI_PARSEOP_TARGET; | ||
349 | } | ||
350 | } else if (parent_scope->common.aml_opcode == AML_INCREMENT_OP) { | ||
351 | op->common.flags |= ACPI_PARSEOP_TARGET; | ||
352 | } | ||
353 | } | ||
325 | 354 | ||
326 | if (walk_state->descending_callback != NULL) { | 355 | if (walk_state->descending_callback != NULL) { |
327 | /* | 356 | /* |
@@ -603,13 +632,6 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state, | |||
603 | acpi_ps_pop_scope(&(walk_state->parser_state), op, | 632 | acpi_ps_pop_scope(&(walk_state->parser_state), op, |
604 | &walk_state->arg_types, | 633 | &walk_state->arg_types, |
605 | &walk_state->arg_count); | 634 | &walk_state->arg_count); |
606 | |||
607 | if ((*op)->common.aml_opcode != AML_WHILE_OP) { | ||
608 | status2 = acpi_ds_result_stack_pop(walk_state); | ||
609 | if (ACPI_FAILURE(status2)) { | ||
610 | return_ACPI_STATUS(status2); | ||
611 | } | ||
612 | } | ||
613 | } | 635 | } |
614 | 636 | ||
615 | /* Close this iteration of the While loop */ | 637 | /* Close this iteration of the While loop */ |
@@ -640,10 +662,6 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state, | |||
640 | if (ACPI_FAILURE(status2)) { | 662 | if (ACPI_FAILURE(status2)) { |
641 | return_ACPI_STATUS(status2); | 663 | return_ACPI_STATUS(status2); |
642 | } | 664 | } |
643 | status2 = acpi_ds_result_stack_pop(walk_state); | ||
644 | if (ACPI_FAILURE(status2)) { | ||
645 | return_ACPI_STATUS(status2); | ||
646 | } | ||
647 | 665 | ||
648 | acpi_ut_delete_generic_state | 666 | acpi_ut_delete_generic_state |
649 | (acpi_ut_pop_generic_state | 667 | (acpi_ut_pop_generic_state |
@@ -1005,7 +1023,8 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) | |||
1005 | acpi_gbl_depth--; | 1023 | acpi_gbl_depth--; |
1006 | } | 1024 | } |
1007 | 1025 | ||
1008 | if (op->common.aml_opcode == AML_REGION_OP) { | 1026 | if (op->common.aml_opcode == AML_REGION_OP || |
1027 | op->common.aml_opcode == AML_DATA_REGION_OP) { | ||
1009 | /* | 1028 | /* |
1010 | * Skip parsing of control method or opregion body, | 1029 | * Skip parsing of control method or opregion body, |
1011 | * because we don't have enough info in the first pass | 1030 | * because we don't have enough info in the first pass |
@@ -1030,6 +1049,16 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) | |||
1030 | (u32) (parser_state->aml - op->named.data); | 1049 | (u32) (parser_state->aml - op->named.data); |
1031 | } | 1050 | } |
1032 | 1051 | ||
1052 | if (op->common.aml_opcode == AML_BANK_FIELD_OP) { | ||
1053 | /* | ||
1054 | * Backup to beginning of bank_field declaration | ||
1055 | * | ||
1056 | * body_length is unknown until we parse the body | ||
1057 | */ | ||
1058 | op->named.length = | ||
1059 | (u32) (parser_state->aml - op->named.data); | ||
1060 | } | ||
1061 | |||
1033 | /* This op complete, notify the dispatcher */ | 1062 | /* This op complete, notify the dispatcher */ |
1034 | 1063 | ||
1035 | if (walk_state->ascending_callback != NULL) { | 1064 | if (walk_state->ascending_callback != NULL) { |
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c index 9296e86761d7..f425ab30eae8 100644 --- a/drivers/acpi/parser/psopcode.c +++ b/drivers/acpi/parser/psopcode.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -49,6 +49,9 @@ | |||
49 | #define _COMPONENT ACPI_PARSER | 49 | #define _COMPONENT ACPI_PARSER |
50 | ACPI_MODULE_NAME("psopcode") | 50 | ACPI_MODULE_NAME("psopcode") |
51 | 51 | ||
52 | static const u8 acpi_gbl_argument_count[] = | ||
53 | { 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 6 }; | ||
54 | |||
52 | /******************************************************************************* | 55 | /******************************************************************************* |
53 | * | 56 | * |
54 | * NAME: acpi_gbl_aml_op_info | 57 | * NAME: acpi_gbl_aml_op_info |
@@ -59,6 +62,7 @@ ACPI_MODULE_NAME("psopcode") | |||
59 | * the operand type. | 62 | * the operand type. |
60 | * | 63 | * |
61 | ******************************************************************************/ | 64 | ******************************************************************************/ |
65 | |||
62 | /* | 66 | /* |
63 | * Summary of opcode types/flags | 67 | * Summary of opcode types/flags |
64 | * | 68 | * |
@@ -176,6 +180,7 @@ ACPI_MODULE_NAME("psopcode") | |||
176 | AML_CREATE_QWORD_FIELD_OP | 180 | AML_CREATE_QWORD_FIELD_OP |
177 | 181 | ||
178 | ******************************************************************************/ | 182 | ******************************************************************************/ |
183 | |||
179 | /* | 184 | /* |
180 | * Master Opcode information table. A summary of everything we know about each | 185 | * Master Opcode information table. A summary of everything we know about each |
181 | * opcode, all in one place. | 186 | * opcode, all in one place. |
@@ -515,9 +520,10 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = { | |||
515 | AML_TYPE_NAMED_FIELD, | 520 | AML_TYPE_NAMED_FIELD, |
516 | AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD), | 521 | AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD), |
517 | /* 5F */ ACPI_OP("BankField", ARGP_BANK_FIELD_OP, ARGI_BANK_FIELD_OP, | 522 | /* 5F */ ACPI_OP("BankField", ARGP_BANK_FIELD_OP, ARGI_BANK_FIELD_OP, |
518 | ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, | 523 | ACPI_TYPE_LOCAL_BANK_FIELD, AML_CLASS_NAMED_OBJECT, |
519 | AML_TYPE_NAMED_FIELD, | 524 | AML_TYPE_NAMED_FIELD, |
520 | AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD), | 525 | AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD | |
526 | AML_DEFER), | ||
521 | 527 | ||
522 | /* Internal opcodes that map to invalid AML opcodes */ | 528 | /* Internal opcodes that map to invalid AML opcodes */ |
523 | 529 | ||
@@ -619,9 +625,9 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = { | |||
619 | AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R), | 625 | AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R), |
620 | /* 7C */ ACPI_OP("DataTableRegion", ARGP_DATA_REGION_OP, | 626 | /* 7C */ ACPI_OP("DataTableRegion", ARGP_DATA_REGION_OP, |
621 | ARGI_DATA_REGION_OP, ACPI_TYPE_REGION, | 627 | ARGI_DATA_REGION_OP, ACPI_TYPE_REGION, |
622 | AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, | 628 | AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX, |
623 | AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | | 629 | AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | |
624 | AML_NSNODE | AML_NAMED), | 630 | AML_NSNODE | AML_NAMED | AML_DEFER), |
625 | /* 7D */ ACPI_OP("[EvalSubTree]", ARGP_SCOPE_OP, ARGI_SCOPE_OP, | 631 | /* 7D */ ACPI_OP("[EvalSubTree]", ARGP_SCOPE_OP, ARGI_SCOPE_OP, |
626 | ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, | 632 | ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, |
627 | AML_TYPE_NAMED_NO_OBJ, | 633 | AML_TYPE_NAMED_NO_OBJ, |
@@ -779,3 +785,25 @@ char *acpi_ps_get_opcode_name(u16 opcode) | |||
779 | 785 | ||
780 | #endif | 786 | #endif |
781 | } | 787 | } |
788 | |||
789 | /******************************************************************************* | ||
790 | * | ||
791 | * FUNCTION: acpi_ps_get_argument_count | ||
792 | * | ||
793 | * PARAMETERS: op_type - Type associated with the AML opcode | ||
794 | * | ||
795 | * RETURN: Argument count | ||
796 | * | ||
797 | * DESCRIPTION: Obtain the number of expected arguments for an AML opcode | ||
798 | * | ||
799 | ******************************************************************************/ | ||
800 | |||
801 | u8 acpi_ps_get_argument_count(u32 op_type) | ||
802 | { | ||
803 | |||
804 | if (op_type <= AML_TYPE_EXEC_6A_0T_1R) { | ||
805 | return (acpi_gbl_argument_count[op_type]); | ||
806 | } | ||
807 | |||
808 | return (0); | ||
809 | } | ||
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index 5d63f48e56b5..15e1702e48d6 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -205,6 +205,8 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, | |||
205 | || (op->common.parent->common.aml_opcode == | 205 | || (op->common.parent->common.aml_opcode == |
206 | AML_PACKAGE_OP) | 206 | AML_PACKAGE_OP) |
207 | || (op->common.parent->common.aml_opcode == | 207 | || (op->common.parent->common.aml_opcode == |
208 | AML_BANK_FIELD_OP) | ||
209 | || (op->common.parent->common.aml_opcode == | ||
208 | AML_VAR_PACKAGE_OP)) { | 210 | AML_VAR_PACKAGE_OP)) { |
209 | replacement_op = | 211 | replacement_op = |
210 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); | 212 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); |
@@ -349,19 +351,13 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state, | |||
349 | 351 | ||
350 | parser_state->aml = walk_state->aml_last_while; | 352 | parser_state->aml = walk_state->aml_last_while; |
351 | walk_state->control_state->common.value = FALSE; | 353 | walk_state->control_state->common.value = FALSE; |
352 | status = acpi_ds_result_stack_pop(walk_state); | 354 | status = AE_CTRL_BREAK; |
353 | if (ACPI_SUCCESS(status)) { | ||
354 | status = AE_CTRL_BREAK; | ||
355 | } | ||
356 | break; | 355 | break; |
357 | 356 | ||
358 | case AE_CTRL_CONTINUE: | 357 | case AE_CTRL_CONTINUE: |
359 | 358 | ||
360 | parser_state->aml = walk_state->aml_last_while; | 359 | parser_state->aml = walk_state->aml_last_while; |
361 | status = acpi_ds_result_stack_pop(walk_state); | 360 | status = AE_CTRL_CONTINUE; |
362 | if (ACPI_SUCCESS(status)) { | ||
363 | status = AE_CTRL_CONTINUE; | ||
364 | } | ||
365 | break; | 361 | break; |
366 | 362 | ||
367 | case AE_CTRL_PENDING: | 363 | case AE_CTRL_PENDING: |
@@ -383,10 +379,7 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state, | |||
383 | * Just close out this package | 379 | * Just close out this package |
384 | */ | 380 | */ |
385 | parser_state->aml = acpi_ps_get_next_package_end(parser_state); | 381 | parser_state->aml = acpi_ps_get_next_package_end(parser_state); |
386 | status = acpi_ds_result_stack_pop(walk_state); | 382 | status = AE_CTRL_PENDING; |
387 | if (ACPI_SUCCESS(status)) { | ||
388 | status = AE_CTRL_PENDING; | ||
389 | } | ||
390 | break; | 383 | break; |
391 | 384 | ||
392 | case AE_CTRL_FALSE: | 385 | case AE_CTRL_FALSE: |
@@ -541,7 +534,7 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) | |||
541 | if ((status == AE_ALREADY_EXISTS) && | 534 | if ((status == AE_ALREADY_EXISTS) && |
542 | (!walk_state->method_desc->method.mutex)) { | 535 | (!walk_state->method_desc->method.mutex)) { |
543 | ACPI_INFO((AE_INFO, | 536 | ACPI_INFO((AE_INFO, |
544 | "Marking method %4.4s as Serialized", | 537 | "Marking method %4.4s as Serialized because of AE_ALREADY_EXISTS error", |
545 | walk_state->method_node->name. | 538 | walk_state->method_node->name. |
546 | ascii)); | 539 | ascii)); |
547 | 540 | ||
@@ -601,6 +594,30 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) | |||
601 | * The object is deleted | 594 | * The object is deleted |
602 | */ | 595 | */ |
603 | if (!previous_walk_state->return_desc) { | 596 | if (!previous_walk_state->return_desc) { |
597 | /* | ||
598 | * In slack mode execution, if there is no return value | ||
599 | * we should implicitly return zero (0) as a default value. | ||
600 | */ | ||
601 | if (acpi_gbl_enable_interpreter_slack && | ||
602 | !previous_walk_state-> | ||
603 | implicit_return_obj) { | ||
604 | previous_walk_state-> | ||
605 | implicit_return_obj = | ||
606 | acpi_ut_create_internal_object | ||
607 | (ACPI_TYPE_INTEGER); | ||
608 | if (!previous_walk_state-> | ||
609 | implicit_return_obj) { | ||
610 | return_ACPI_STATUS | ||
611 | (AE_NO_MEMORY); | ||
612 | } | ||
613 | |||
614 | previous_walk_state-> | ||
615 | implicit_return_obj-> | ||
616 | integer.value = 0; | ||
617 | } | ||
618 | |||
619 | /* Restart the calling control method */ | ||
620 | |||
604 | status = | 621 | status = |
605 | acpi_ds_restart_control_method | 622 | acpi_ds_restart_control_method |
606 | (walk_state, | 623 | (walk_state, |
diff --git a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c index 77cfa4ed0cfe..ee50e67c9443 100644 --- a/drivers/acpi/parser/psscope.c +++ b/drivers/acpi/parser/psscope.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c index 966e7ea2a0c4..1dd355ddd182 100644 --- a/drivers/acpi/parser/pstree.c +++ b/drivers/acpi/parser/pstree.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -171,6 +171,8 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg) | |||
171 | while (arg) { | 171 | while (arg) { |
172 | arg->common.parent = op; | 172 | arg->common.parent = op; |
173 | arg = arg->common.next; | 173 | arg = arg->common.next; |
174 | |||
175 | op->common.arg_list_length++; | ||
174 | } | 176 | } |
175 | } | 177 | } |
176 | 178 | ||
diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c index 8ca52002db55..7cf1f65cd5bb 100644 --- a/drivers/acpi/parser/psutils.c +++ b/drivers/acpi/parser/psutils.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c index 49f9757434e4..8b86ad5a3201 100644 --- a/drivers/acpi/parser/pswalk.c +++ b/drivers/acpi/parser/pswalk.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c index 94103bced75e..52581454c47c 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/parser/psxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 76bf6d90c700..f2a76acecfcd 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -121,7 +121,7 @@ acpi_power_get_context(acpi_handle handle, | |||
121 | } | 121 | } |
122 | 122 | ||
123 | *resource = acpi_driver_data(device); | 123 | *resource = acpi_driver_data(device); |
124 | if (!resource) | 124 | if (!*resource) |
125 | return -ENODEV; | 125 | return -ENODEV; |
126 | 126 | ||
127 | return 0; | 127 | return 0; |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 0d90ff5fd117..55d69dce47c4 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -847,6 +847,7 @@ static int acpi_processor_get_power_info_default(struct acpi_processor *pr) | |||
847 | /* all processors need to support C1 */ | 847 | /* all processors need to support C1 */ |
848 | pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; | 848 | pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; |
849 | pr->power.states[ACPI_STATE_C1].valid = 1; | 849 | pr->power.states[ACPI_STATE_C1].valid = 1; |
850 | pr->power.states[ACPI_STATE_C1].entry_method = ACPI_CSTATE_HALT; | ||
850 | } | 851 | } |
851 | /* the C0 state only exists as a filler in our array */ | 852 | /* the C0 state only exists as a filler in our array */ |
852 | pr->power.states[ACPI_STATE_C0].valid = 1; | 853 | pr->power.states[ACPI_STATE_C0].valid = 1; |
@@ -959,6 +960,9 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
959 | cx.address); | 960 | cx.address); |
960 | } | 961 | } |
961 | 962 | ||
963 | if (cx.type == ACPI_STATE_C1) { | ||
964 | cx.valid = 1; | ||
965 | } | ||
962 | 966 | ||
963 | obj = &(element->package.elements[2]); | 967 | obj = &(element->package.elements[2]); |
964 | if (obj->type != ACPI_TYPE_INTEGER) | 968 | if (obj->type != ACPI_TYPE_INTEGER) |
@@ -1294,6 +1298,8 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) | |||
1294 | { | 1298 | { |
1295 | int result = 0; | 1299 | int result = 0; |
1296 | 1300 | ||
1301 | if (boot_option_idle_override) | ||
1302 | return 0; | ||
1297 | 1303 | ||
1298 | if (!pr) | 1304 | if (!pr) |
1299 | return -EINVAL; | 1305 | return -EINVAL; |
@@ -1733,6 +1739,9 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) | |||
1733 | { | 1739 | { |
1734 | int ret; | 1740 | int ret; |
1735 | 1741 | ||
1742 | if (boot_option_idle_override) | ||
1743 | return 0; | ||
1744 | |||
1736 | if (!pr) | 1745 | if (!pr) |
1737 | return -EINVAL; | 1746 | return -EINVAL; |
1738 | 1747 | ||
@@ -1763,6 +1772,8 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1763 | struct proc_dir_entry *entry = NULL; | 1772 | struct proc_dir_entry *entry = NULL; |
1764 | unsigned int i; | 1773 | unsigned int i; |
1765 | 1774 | ||
1775 | if (boot_option_idle_override) | ||
1776 | return 0; | ||
1766 | 1777 | ||
1767 | if (!first_run) { | 1778 | if (!first_run) { |
1768 | dmi_check_system(processor_power_dmi_table); | 1779 | dmi_check_system(processor_power_dmi_table); |
@@ -1798,7 +1809,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1798 | * Note that we use previously set idle handler will be used on | 1809 | * Note that we use previously set idle handler will be used on |
1799 | * platforms that only support C1. | 1810 | * platforms that only support C1. |
1800 | */ | 1811 | */ |
1801 | if ((pr->flags.power) && (!boot_option_idle_override)) { | 1812 | if (pr->flags.power) { |
1802 | #ifdef CONFIG_CPU_IDLE | 1813 | #ifdef CONFIG_CPU_IDLE |
1803 | acpi_processor_setup_cpuidle(pr); | 1814 | acpi_processor_setup_cpuidle(pr); |
1804 | pr->power.dev.cpu = pr->id; | 1815 | pr->power.dev.cpu = pr->id; |
@@ -1838,8 +1849,11 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1838 | int acpi_processor_power_exit(struct acpi_processor *pr, | 1849 | int acpi_processor_power_exit(struct acpi_processor *pr, |
1839 | struct acpi_device *device) | 1850 | struct acpi_device *device) |
1840 | { | 1851 | { |
1852 | if (boot_option_idle_override) | ||
1853 | return 0; | ||
1854 | |||
1841 | #ifdef CONFIG_CPU_IDLE | 1855 | #ifdef CONFIG_CPU_IDLE |
1842 | if ((pr->flags.power) && (!boot_option_idle_override)) | 1856 | if (pr->flags.power) |
1843 | cpuidle_unregister_device(&pr->power.dev); | 1857 | cpuidle_unregister_device(&pr->power.dev); |
1844 | #endif | 1858 | #endif |
1845 | pr->flags.power_setup_done = 0; | 1859 | pr->flags.power_setup_done = 0; |
diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c index 271e61509eeb..7f96332822bf 100644 --- a/drivers/acpi/resources/rsaddr.c +++ b/drivers/acpi/resources/rsaddr.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index 0dd2ce8a3475..8a112d11d491 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -73,7 +73,7 @@ acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length); | |||
73 | 73 | ||
74 | static u8 acpi_rs_count_set_bits(u16 bit_field) | 74 | static u8 acpi_rs_count_set_bits(u16 bit_field) |
75 | { | 75 | { |
76 | u8 bits_set; | 76 | acpi_native_uint bits_set; |
77 | 77 | ||
78 | ACPI_FUNCTION_ENTRY(); | 78 | ACPI_FUNCTION_ENTRY(); |
79 | 79 | ||
@@ -81,10 +81,10 @@ static u8 acpi_rs_count_set_bits(u16 bit_field) | |||
81 | 81 | ||
82 | /* Zero the least significant bit that is set */ | 82 | /* Zero the least significant bit that is set */ |
83 | 83 | ||
84 | bit_field &= (bit_field - 1); | 84 | bit_field &= (u16) (bit_field - 1); |
85 | } | 85 | } |
86 | 86 | ||
87 | return (bits_set); | 87 | return ((u8) bits_set); |
88 | } | 88 | } |
89 | 89 | ||
90 | /******************************************************************************* | 90 | /******************************************************************************* |
@@ -211,6 +211,24 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) | |||
211 | * variable-length fields | 211 | * variable-length fields |
212 | */ | 212 | */ |
213 | switch (resource->type) { | 213 | switch (resource->type) { |
214 | case ACPI_RESOURCE_TYPE_IRQ: | ||
215 | |||
216 | /* Length can be 3 or 2 */ | ||
217 | |||
218 | if (resource->data.irq.descriptor_length == 2) { | ||
219 | total_size--; | ||
220 | } | ||
221 | break; | ||
222 | |||
223 | case ACPI_RESOURCE_TYPE_START_DEPENDENT: | ||
224 | |||
225 | /* Length can be 1 or 0 */ | ||
226 | |||
227 | if (resource->data.irq.descriptor_length == 0) { | ||
228 | total_size--; | ||
229 | } | ||
230 | break; | ||
231 | |||
214 | case ACPI_RESOURCE_TYPE_VENDOR: | 232 | case ACPI_RESOURCE_TYPE_VENDOR: |
215 | /* | 233 | /* |
216 | * Vendor Defined Resource: | 234 | * Vendor Defined Resource: |
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c index 50da494c3ee2..faddaee1bc07 100644 --- a/drivers/acpi/resources/rscreate.c +++ b/drivers/acpi/resources/rscreate.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c index 46da116a4030..6bbbb7b8941a 100644 --- a/drivers/acpi/resources/rsdump.c +++ b/drivers/acpi/resources/rsdump.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -87,8 +87,10 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table); | |||
87 | * | 87 | * |
88 | ******************************************************************************/ | 88 | ******************************************************************************/ |
89 | 89 | ||
90 | struct acpi_rsdump_info acpi_rs_dump_irq[6] = { | 90 | struct acpi_rsdump_info acpi_rs_dump_irq[7] = { |
91 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_irq), "IRQ", NULL}, | 91 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_irq), "IRQ", NULL}, |
92 | {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.descriptor_length), | ||
93 | "Descriptor Length", NULL}, | ||
92 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.triggering), "Triggering", | 94 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.triggering), "Triggering", |
93 | acpi_gbl_he_decode}, | 95 | acpi_gbl_he_decode}, |
94 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.polarity), "Polarity", | 96 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.polarity), "Polarity", |
@@ -115,9 +117,11 @@ struct acpi_rsdump_info acpi_rs_dump_dma[6] = { | |||
115 | NULL} | 117 | NULL} |
116 | }; | 118 | }; |
117 | 119 | ||
118 | struct acpi_rsdump_info acpi_rs_dump_start_dpf[3] = { | 120 | struct acpi_rsdump_info acpi_rs_dump_start_dpf[4] = { |
119 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_start_dpf), | 121 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_start_dpf), |
120 | "Start-Dependent-Functions", NULL}, | 122 | "Start-Dependent-Functions", NULL}, |
123 | {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(start_dpf.descriptor_length), | ||
124 | "Descriptor Length", NULL}, | ||
121 | {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.compatibility_priority), | 125 | {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.compatibility_priority), |
122 | "Compatibility Priority", acpi_gbl_config_decode}, | 126 | "Compatibility Priority", acpi_gbl_config_decode}, |
123 | {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.performance_robustness), | 127 | {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.performance_robustness), |
diff --git a/drivers/acpi/resources/rsinfo.c b/drivers/acpi/resources/rsinfo.c index 2c2adb6292c1..3f0a1fedbe0e 100644 --- a/drivers/acpi/resources/rsinfo.c +++ b/drivers/acpi/resources/rsinfo.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c index b297bc3e4419..b66d42e7402e 100644 --- a/drivers/acpi/resources/rsio.c +++ b/drivers/acpi/resources/rsio.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -185,7 +185,7 @@ struct acpi_rsconvert_info acpi_rs_convert_end_tag[2] = { | |||
185 | * | 185 | * |
186 | ******************************************************************************/ | 186 | ******************************************************************************/ |
187 | 187 | ||
188 | struct acpi_rsconvert_info acpi_rs_get_start_dpf[5] = { | 188 | struct acpi_rsconvert_info acpi_rs_get_start_dpf[6] = { |
189 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_START_DEPENDENT, | 189 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_START_DEPENDENT, |
190 | ACPI_RS_SIZE(struct acpi_resource_start_dependent), | 190 | ACPI_RS_SIZE(struct acpi_resource_start_dependent), |
191 | ACPI_RSC_TABLE_SIZE(acpi_rs_get_start_dpf)}, | 191 | ACPI_RSC_TABLE_SIZE(acpi_rs_get_start_dpf)}, |
@@ -196,6 +196,12 @@ struct acpi_rsconvert_info acpi_rs_get_start_dpf[5] = { | |||
196 | ACPI_ACCEPTABLE_CONFIGURATION, | 196 | ACPI_ACCEPTABLE_CONFIGURATION, |
197 | 2}, | 197 | 2}, |
198 | 198 | ||
199 | /* Get the descriptor length (0 or 1 for Start Dpf descriptor) */ | ||
200 | |||
201 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.start_dpf.descriptor_length), | ||
202 | AML_OFFSET(start_dpf.descriptor_type), | ||
203 | 0}, | ||
204 | |||
199 | /* All done if there is no flag byte present in the descriptor */ | 205 | /* All done if there is no flag byte present in the descriptor */ |
200 | 206 | ||
201 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 1}, | 207 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 1}, |
@@ -219,7 +225,9 @@ struct acpi_rsconvert_info acpi_rs_get_start_dpf[5] = { | |||
219 | * | 225 | * |
220 | ******************************************************************************/ | 226 | ******************************************************************************/ |
221 | 227 | ||
222 | struct acpi_rsconvert_info acpi_rs_set_start_dpf[6] = { | 228 | struct acpi_rsconvert_info acpi_rs_set_start_dpf[10] = { |
229 | /* Start with a default descriptor of length 1 */ | ||
230 | |||
223 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_START_DEPENDENT, | 231 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_START_DEPENDENT, |
224 | sizeof(struct aml_resource_start_dependent), | 232 | sizeof(struct aml_resource_start_dependent), |
225 | ACPI_RSC_TABLE_SIZE(acpi_rs_set_start_dpf)}, | 233 | ACPI_RSC_TABLE_SIZE(acpi_rs_set_start_dpf)}, |
@@ -236,6 +244,33 @@ struct acpi_rsconvert_info acpi_rs_set_start_dpf[6] = { | |||
236 | AML_OFFSET(start_dpf.flags), | 244 | AML_OFFSET(start_dpf.flags), |
237 | 2}, | 245 | 2}, |
238 | /* | 246 | /* |
247 | * All done if the output descriptor length is required to be 1 | ||
248 | * (i.e., optimization to 0 bytes cannot be attempted) | ||
249 | */ | ||
250 | {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE, | ||
251 | ACPI_RS_OFFSET(data.start_dpf.descriptor_length), | ||
252 | 1}, | ||
253 | |||
254 | /* Set length to 0 bytes (no flags byte) */ | ||
255 | |||
256 | {ACPI_RSC_LENGTH, 0, 0, | ||
257 | sizeof(struct aml_resource_start_dependent_noprio)}, | ||
258 | |||
259 | /* | ||
260 | * All done if the output descriptor length is required to be 0. | ||
261 | * | ||
262 | * TBD: Perhaps we should check for error if input flags are not | ||
263 | * compatible with a 0-byte descriptor. | ||
264 | */ | ||
265 | {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE, | ||
266 | ACPI_RS_OFFSET(data.start_dpf.descriptor_length), | ||
267 | 0}, | ||
268 | |||
269 | /* Reset length to 1 byte (descriptor with flags byte) */ | ||
270 | |||
271 | {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_start_dependent)}, | ||
272 | |||
273 | /* | ||
239 | * All done if flags byte is necessary -- if either priority value | 274 | * All done if flags byte is necessary -- if either priority value |
240 | * is not ACPI_ACCEPTABLE_CONFIGURATION | 275 | * is not ACPI_ACCEPTABLE_CONFIGURATION |
241 | */ | 276 | */ |
diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c index 5657f7b95039..a8805efc0366 100644 --- a/drivers/acpi/resources/rsirq.c +++ b/drivers/acpi/resources/rsirq.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -52,7 +52,7 @@ ACPI_MODULE_NAME("rsirq") | |||
52 | * acpi_rs_get_irq | 52 | * acpi_rs_get_irq |
53 | * | 53 | * |
54 | ******************************************************************************/ | 54 | ******************************************************************************/ |
55 | struct acpi_rsconvert_info acpi_rs_get_irq[7] = { | 55 | struct acpi_rsconvert_info acpi_rs_get_irq[8] = { |
56 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IRQ, | 56 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IRQ, |
57 | ACPI_RS_SIZE(struct acpi_resource_irq), | 57 | ACPI_RS_SIZE(struct acpi_resource_irq), |
58 | ACPI_RSC_TABLE_SIZE(acpi_rs_get_irq)}, | 58 | ACPI_RSC_TABLE_SIZE(acpi_rs_get_irq)}, |
@@ -69,6 +69,12 @@ struct acpi_rsconvert_info acpi_rs_get_irq[7] = { | |||
69 | ACPI_EDGE_SENSITIVE, | 69 | ACPI_EDGE_SENSITIVE, |
70 | 1}, | 70 | 1}, |
71 | 71 | ||
72 | /* Get the descriptor length (2 or 3 for IRQ descriptor) */ | ||
73 | |||
74 | {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.irq.descriptor_length), | ||
75 | AML_OFFSET(irq.descriptor_type), | ||
76 | 0}, | ||
77 | |||
72 | /* All done if no flag byte present in descriptor */ | 78 | /* All done if no flag byte present in descriptor */ |
73 | 79 | ||
74 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 3}, | 80 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 3}, |
@@ -94,7 +100,9 @@ struct acpi_rsconvert_info acpi_rs_get_irq[7] = { | |||
94 | * | 100 | * |
95 | ******************************************************************************/ | 101 | ******************************************************************************/ |
96 | 102 | ||
97 | struct acpi_rsconvert_info acpi_rs_set_irq[9] = { | 103 | struct acpi_rsconvert_info acpi_rs_set_irq[13] = { |
104 | /* Start with a default descriptor of length 3 */ | ||
105 | |||
98 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IRQ, | 106 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IRQ, |
99 | sizeof(struct aml_resource_irq), | 107 | sizeof(struct aml_resource_irq), |
100 | ACPI_RSC_TABLE_SIZE(acpi_rs_set_irq)}, | 108 | ACPI_RSC_TABLE_SIZE(acpi_rs_set_irq)}, |
@@ -105,7 +113,7 @@ struct acpi_rsconvert_info acpi_rs_set_irq[9] = { | |||
105 | AML_OFFSET(irq.irq_mask), | 113 | AML_OFFSET(irq.irq_mask), |
106 | ACPI_RS_OFFSET(data.irq.interrupt_count)}, | 114 | ACPI_RS_OFFSET(data.irq.interrupt_count)}, |
107 | 115 | ||
108 | /* Set the flags byte by default */ | 116 | /* Set the flags byte */ |
109 | 117 | ||
110 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering), | 118 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering), |
111 | AML_OFFSET(irq.flags), | 119 | AML_OFFSET(irq.flags), |
@@ -118,6 +126,33 @@ struct acpi_rsconvert_info acpi_rs_set_irq[9] = { | |||
118 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable), | 126 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable), |
119 | AML_OFFSET(irq.flags), | 127 | AML_OFFSET(irq.flags), |
120 | 4}, | 128 | 4}, |
129 | |||
130 | /* | ||
131 | * All done if the output descriptor length is required to be 3 | ||
132 | * (i.e., optimization to 2 bytes cannot be attempted) | ||
133 | */ | ||
134 | {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE, | ||
135 | ACPI_RS_OFFSET(data.irq.descriptor_length), | ||
136 | 3}, | ||
137 | |||
138 | /* Set length to 2 bytes (no flags byte) */ | ||
139 | |||
140 | {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)}, | ||
141 | |||
142 | /* | ||
143 | * All done if the output descriptor length is required to be 2. | ||
144 | * | ||
145 | * TBD: Perhaps we should check for error if input flags are not | ||
146 | * compatible with a 2-byte descriptor. | ||
147 | */ | ||
148 | {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE, | ||
149 | ACPI_RS_OFFSET(data.irq.descriptor_length), | ||
150 | 2}, | ||
151 | |||
152 | /* Reset length to 3 bytes (descriptor with flags byte) */ | ||
153 | |||
154 | {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq)}, | ||
155 | |||
121 | /* | 156 | /* |
122 | * Check if the flags byte is necessary. Not needed if the flags are: | 157 | * Check if the flags byte is necessary. Not needed if the flags are: |
123 | * ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH, ACPI_EXCLUSIVE | 158 | * ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH, ACPI_EXCLUSIVE |
@@ -134,7 +169,7 @@ struct acpi_rsconvert_info acpi_rs_set_irq[9] = { | |||
134 | ACPI_RS_OFFSET(data.irq.sharable), | 169 | ACPI_RS_OFFSET(data.irq.sharable), |
135 | ACPI_EXCLUSIVE}, | 170 | ACPI_EXCLUSIVE}, |
136 | 171 | ||
137 | /* irq_no_flags() descriptor can be used */ | 172 | /* We can optimize to a 2-byte irq_no_flags() descriptor */ |
138 | 173 | ||
139 | {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)} | 174 | {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)} |
140 | }; | 175 | }; |
diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index ca21e4660c79..b78c7e797a19 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c index 521eab7dd8df..63b21abd90bb 100644 --- a/drivers/acpi/resources/rsmemory.c +++ b/drivers/acpi/resources/rsmemory.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c index c7081afa893a..de1ac3881b22 100644 --- a/drivers/acpi/resources/rsmisc.c +++ b/drivers/acpi/resources/rsmisc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -497,6 +497,17 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, | |||
497 | } | 497 | } |
498 | break; | 498 | break; |
499 | 499 | ||
500 | case ACPI_RSC_EXIT_EQ: | ||
501 | /* | ||
502 | * Control - Exit conversion if equal | ||
503 | */ | ||
504 | if (*ACPI_ADD_PTR(u8, resource, | ||
505 | COMPARE_TARGET(info)) == | ||
506 | COMPARE_VALUE(info)) { | ||
507 | goto exit; | ||
508 | } | ||
509 | break; | ||
510 | |||
500 | default: | 511 | default: |
501 | 512 | ||
502 | ACPI_ERROR((AE_INFO, "Invalid conversion opcode")); | 513 | ACPI_ERROR((AE_INFO, "Invalid conversion opcode")); |
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c index 11c0bd7b9cfd..befe2302f41b 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/resources/rsutils.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -97,17 +97,17 @@ u8 acpi_rs_decode_bitmask(u16 mask, u8 * list) | |||
97 | u16 acpi_rs_encode_bitmask(u8 * list, u8 count) | 97 | u16 acpi_rs_encode_bitmask(u8 * list, u8 count) |
98 | { | 98 | { |
99 | acpi_native_uint i; | 99 | acpi_native_uint i; |
100 | u16 mask; | 100 | acpi_native_uint mask; |
101 | 101 | ||
102 | ACPI_FUNCTION_ENTRY(); | 102 | ACPI_FUNCTION_ENTRY(); |
103 | 103 | ||
104 | /* Encode the list into a single bitmask */ | 104 | /* Encode the list into a single bitmask */ |
105 | 105 | ||
106 | for (i = 0, mask = 0; i < count; i++) { | 106 | for (i = 0, mask = 0; i < count; i++) { |
107 | mask |= (0x0001 << list[i]); | 107 | mask |= (0x1 << list[i]); |
108 | } | 108 | } |
109 | 109 | ||
110 | return (mask); | 110 | return ((u16) mask); |
111 | } | 111 | } |
112 | 112 | ||
113 | /******************************************************************************* | 113 | /******************************************************************************* |
diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c index 4c3fd4cdaf73..f59f4c4e034c 100644 --- a/drivers/acpi/resources/rsxface.c +++ b/drivers/acpi/resources/rsxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index e6ce262b5d44..6d85289f1c12 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -677,9 +677,8 @@ acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, | |||
677 | device->wakeup.resources.count = package->package.count - 2; | 677 | device->wakeup.resources.count = package->package.count - 2; |
678 | for (i = 0; i < device->wakeup.resources.count; i++) { | 678 | for (i = 0; i < device->wakeup.resources.count; i++) { |
679 | element = &(package->package.elements[i + 2]); | 679 | element = &(package->package.elements[i + 2]); |
680 | if (element->type != ACPI_TYPE_ANY) { | 680 | if (element->type != ACPI_TYPE_LOCAL_REFERENCE) |
681 | return AE_BAD_DATA; | 681 | return AE_BAD_DATA; |
682 | } | ||
683 | 682 | ||
684 | device->wakeup.resources.handles[i] = element->reference.handle; | 683 | device->wakeup.resources.handles[i] = element->reference.handle; |
685 | } | 684 | } |
@@ -692,6 +691,9 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
692 | acpi_status status = 0; | 691 | acpi_status status = 0; |
693 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 692 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
694 | union acpi_object *package = NULL; | 693 | union acpi_object *package = NULL; |
694 | union acpi_object in_arg[3]; | ||
695 | struct acpi_object_list arg_list = { 3, in_arg }; | ||
696 | acpi_status psw_status = AE_OK; | ||
695 | 697 | ||
696 | struct acpi_device_id button_device_ids[] = { | 698 | struct acpi_device_id button_device_ids[] = { |
697 | {"PNP0C0D", 0}, | 699 | {"PNP0C0D", 0}, |
@@ -700,7 +702,6 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
700 | {"", 0}, | 702 | {"", 0}, |
701 | }; | 703 | }; |
702 | 704 | ||
703 | |||
704 | /* _PRW */ | 705 | /* _PRW */ |
705 | status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); | 706 | status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); |
706 | if (ACPI_FAILURE(status)) { | 707 | if (ACPI_FAILURE(status)) { |
@@ -718,6 +719,45 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
718 | kfree(buffer.pointer); | 719 | kfree(buffer.pointer); |
719 | 720 | ||
720 | device->wakeup.flags.valid = 1; | 721 | device->wakeup.flags.valid = 1; |
722 | /* Call _PSW/_DSW object to disable its ability to wake the sleeping | ||
723 | * system for the ACPI device with the _PRW object. | ||
724 | * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. | ||
725 | * So it is necessary to call _DSW object first. Only when it is not | ||
726 | * present will the _PSW object used. | ||
727 | */ | ||
728 | /* | ||
729 | * Three agruments are needed for the _DSW object. | ||
730 | * Argument 0: enable/disable the wake capabilities | ||
731 | * When _DSW object is called to disable the wake capabilities, maybe | ||
732 | * the first argument is filled. The value of the other two agruments | ||
733 | * is meaningless. | ||
734 | */ | ||
735 | in_arg[0].type = ACPI_TYPE_INTEGER; | ||
736 | in_arg[0].integer.value = 0; | ||
737 | in_arg[1].type = ACPI_TYPE_INTEGER; | ||
738 | in_arg[1].integer.value = 0; | ||
739 | in_arg[2].type = ACPI_TYPE_INTEGER; | ||
740 | in_arg[2].integer.value = 0; | ||
741 | psw_status = acpi_evaluate_object(device->handle, "_DSW", | ||
742 | &arg_list, NULL); | ||
743 | if (ACPI_FAILURE(psw_status) && (psw_status != AE_NOT_FOUND)) | ||
744 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "error in evaluate _DSW\n")); | ||
745 | /* | ||
746 | * When the _DSW object is not present, OSPM will call _PSW object. | ||
747 | */ | ||
748 | if (psw_status == AE_NOT_FOUND) { | ||
749 | /* | ||
750 | * Only one agruments is required for the _PSW object. | ||
751 | * agrument 0: enable/disable the wake capabilities | ||
752 | */ | ||
753 | arg_list.count = 1; | ||
754 | in_arg[0].integer.value = 0; | ||
755 | psw_status = acpi_evaluate_object(device->handle, "_PSW", | ||
756 | &arg_list, NULL); | ||
757 | if (ACPI_FAILURE(psw_status) && (psw_status != AE_NOT_FOUND)) | ||
758 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "error in " | ||
759 | "evaluate _PSW\n")); | ||
760 | } | ||
721 | /* Power button, Lid switch always enable wakeup */ | 761 | /* Power button, Lid switch always enable wakeup */ |
722 | if (!acpi_match_device_ids(device, button_device_ids)) | 762 | if (!acpi_match_device_ids(device, button_device_ids)) |
723 | device->wakeup.flags.run_wake = 1; | 763 | device->wakeup.flags.run_wake = 1; |
@@ -882,10 +922,7 @@ static void acpi_device_get_busid(struct acpi_device *device, | |||
882 | static int | 922 | static int |
883 | acpi_video_bus_match(struct acpi_device *device) | 923 | acpi_video_bus_match(struct acpi_device *device) |
884 | { | 924 | { |
885 | acpi_handle h_dummy1; | 925 | acpi_handle h_dummy; |
886 | acpi_handle h_dummy2; | ||
887 | acpi_handle h_dummy3; | ||
888 | |||
889 | 926 | ||
890 | if (!device) | 927 | if (!device) |
891 | return -EINVAL; | 928 | return -EINVAL; |
@@ -895,18 +932,18 @@ acpi_video_bus_match(struct acpi_device *device) | |||
895 | */ | 932 | */ |
896 | 933 | ||
897 | /* Does this device able to support video switching ? */ | 934 | /* Does this device able to support video switching ? */ |
898 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) && | 935 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) && |
899 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2))) | 936 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy))) |
900 | return 0; | 937 | return 0; |
901 | 938 | ||
902 | /* Does this device able to retrieve a video ROM ? */ | 939 | /* Does this device able to retrieve a video ROM ? */ |
903 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1))) | 940 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy))) |
904 | return 0; | 941 | return 0; |
905 | 942 | ||
906 | /* Does this device able to configure which video head to be POSTed ? */ | 943 | /* Does this device able to configure which video head to be POSTed ? */ |
907 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) && | 944 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) && |
908 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) && | 945 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) && |
909 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3))) | 946 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy))) |
910 | return 0; | 947 | return 0; |
911 | 948 | ||
912 | return -ENODEV; | 949 | return -ENODEV; |
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index 71183eea7906..c3b0cd88d09f 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c | |||
@@ -51,7 +51,7 @@ static int acpi_sleep_prepare(u32 acpi_state) | |||
51 | } | 51 | } |
52 | 52 | ||
53 | #ifdef CONFIG_SUSPEND | 53 | #ifdef CONFIG_SUSPEND |
54 | static struct platform_suspend_ops acpi_pm_ops; | 54 | static struct platform_suspend_ops acpi_suspend_ops; |
55 | 55 | ||
56 | extern void do_suspend_lowlevel(void); | 56 | extern void do_suspend_lowlevel(void); |
57 | 57 | ||
@@ -65,11 +65,11 @@ static u32 acpi_suspend_states[] = { | |||
65 | static int init_8259A_after_S1; | 65 | static int init_8259A_after_S1; |
66 | 66 | ||
67 | /** | 67 | /** |
68 | * acpi_pm_begin - Set the target system sleep state to the state | 68 | * acpi_suspend_begin - Set the target system sleep state to the state |
69 | * associated with given @pm_state, if supported. | 69 | * associated with given @pm_state, if supported. |
70 | */ | 70 | */ |
71 | 71 | ||
72 | static int acpi_pm_begin(suspend_state_t pm_state) | 72 | static int acpi_suspend_begin(suspend_state_t pm_state) |
73 | { | 73 | { |
74 | u32 acpi_state = acpi_suspend_states[pm_state]; | 74 | u32 acpi_state = acpi_suspend_states[pm_state]; |
75 | int error = 0; | 75 | int error = 0; |
@@ -85,13 +85,13 @@ static int acpi_pm_begin(suspend_state_t pm_state) | |||
85 | } | 85 | } |
86 | 86 | ||
87 | /** | 87 | /** |
88 | * acpi_pm_prepare - Do preliminary suspend work. | 88 | * acpi_suspend_prepare - Do preliminary suspend work. |
89 | * | 89 | * |
90 | * If necessary, set the firmware waking vector and do arch-specific | 90 | * If necessary, set the firmware waking vector and do arch-specific |
91 | * nastiness to get the wakeup code to the waking vector. | 91 | * nastiness to get the wakeup code to the waking vector. |
92 | */ | 92 | */ |
93 | 93 | ||
94 | static int acpi_pm_prepare(void) | 94 | static int acpi_suspend_prepare(void) |
95 | { | 95 | { |
96 | int error = acpi_sleep_prepare(acpi_target_sleep_state); | 96 | int error = acpi_sleep_prepare(acpi_target_sleep_state); |
97 | 97 | ||
@@ -104,7 +104,7 @@ static int acpi_pm_prepare(void) | |||
104 | } | 104 | } |
105 | 105 | ||
106 | /** | 106 | /** |
107 | * acpi_pm_enter - Actually enter a sleep state. | 107 | * acpi_suspend_enter - Actually enter a sleep state. |
108 | * @pm_state: ignored | 108 | * @pm_state: ignored |
109 | * | 109 | * |
110 | * Flush caches and go to sleep. For STR we have to call arch-specific | 110 | * Flush caches and go to sleep. For STR we have to call arch-specific |
@@ -112,7 +112,7 @@ static int acpi_pm_prepare(void) | |||
112 | * It's unfortunate, but it works. Please fix if you're feeling frisky. | 112 | * It's unfortunate, but it works. Please fix if you're feeling frisky. |
113 | */ | 113 | */ |
114 | 114 | ||
115 | static int acpi_pm_enter(suspend_state_t pm_state) | 115 | static int acpi_suspend_enter(suspend_state_t pm_state) |
116 | { | 116 | { |
117 | acpi_status status = AE_OK; | 117 | acpi_status status = AE_OK; |
118 | unsigned long flags = 0; | 118 | unsigned long flags = 0; |
@@ -169,13 +169,13 @@ static int acpi_pm_enter(suspend_state_t pm_state) | |||
169 | } | 169 | } |
170 | 170 | ||
171 | /** | 171 | /** |
172 | * acpi_pm_finish - Instruct the platform to leave a sleep state. | 172 | * acpi_suspend_finish - Instruct the platform to leave a sleep state. |
173 | * | 173 | * |
174 | * This is called after we wake back up (or if entering the sleep state | 174 | * This is called after we wake back up (or if entering the sleep state |
175 | * failed). | 175 | * failed). |
176 | */ | 176 | */ |
177 | 177 | ||
178 | static void acpi_pm_finish(void) | 178 | static void acpi_suspend_finish(void) |
179 | { | 179 | { |
180 | u32 acpi_state = acpi_target_sleep_state; | 180 | u32 acpi_state = acpi_target_sleep_state; |
181 | 181 | ||
@@ -196,19 +196,19 @@ static void acpi_pm_finish(void) | |||
196 | } | 196 | } |
197 | 197 | ||
198 | /** | 198 | /** |
199 | * acpi_pm_end - Finish up suspend sequence. | 199 | * acpi_suspend_end - Finish up suspend sequence. |
200 | */ | 200 | */ |
201 | 201 | ||
202 | static void acpi_pm_end(void) | 202 | static void acpi_suspend_end(void) |
203 | { | 203 | { |
204 | /* | 204 | /* |
205 | * This is necessary in case acpi_pm_finish() is not called during a | 205 | * This is necessary in case acpi_suspend_finish() is not called during a |
206 | * failing transition to a sleep state. | 206 | * failing transition to a sleep state. |
207 | */ | 207 | */ |
208 | acpi_target_sleep_state = ACPI_STATE_S0; | 208 | acpi_target_sleep_state = ACPI_STATE_S0; |
209 | } | 209 | } |
210 | 210 | ||
211 | static int acpi_pm_state_valid(suspend_state_t pm_state) | 211 | static int acpi_suspend_state_valid(suspend_state_t pm_state) |
212 | { | 212 | { |
213 | u32 acpi_state; | 213 | u32 acpi_state; |
214 | 214 | ||
@@ -224,13 +224,13 @@ static int acpi_pm_state_valid(suspend_state_t pm_state) | |||
224 | } | 224 | } |
225 | } | 225 | } |
226 | 226 | ||
227 | static struct platform_suspend_ops acpi_pm_ops = { | 227 | static struct platform_suspend_ops acpi_suspend_ops = { |
228 | .valid = acpi_pm_state_valid, | 228 | .valid = acpi_suspend_state_valid, |
229 | .begin = acpi_pm_begin, | 229 | .begin = acpi_suspend_begin, |
230 | .prepare = acpi_pm_prepare, | 230 | .prepare = acpi_suspend_prepare, |
231 | .enter = acpi_pm_enter, | 231 | .enter = acpi_suspend_enter, |
232 | .finish = acpi_pm_finish, | 232 | .finish = acpi_suspend_finish, |
233 | .end = acpi_pm_end, | 233 | .end = acpi_suspend_end, |
234 | }; | 234 | }; |
235 | 235 | ||
236 | /* | 236 | /* |
@@ -492,7 +492,7 @@ int __init acpi_sleep_init(void) | |||
492 | } | 492 | } |
493 | } | 493 | } |
494 | 494 | ||
495 | suspend_set_ops(&acpi_pm_ops); | 495 | suspend_set_ops(&acpi_suspend_ops); |
496 | #endif | 496 | #endif |
497 | 497 | ||
498 | #ifdef CONFIG_HIBERNATION | 498 | #ifdef CONFIG_HIBERNATION |
diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c index 002bb33003af..949d4114eb9f 100644 --- a/drivers/acpi/tables/tbfadt.c +++ b/drivers/acpi/tables/tbfadt.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/tables/tbfind.c b/drivers/acpi/tables/tbfind.c index 058c064948e1..9ca3afc98c80 100644 --- a/drivers/acpi/tables/tbfind.c +++ b/drivers/acpi/tables/tbfind.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -70,12 +70,22 @@ acpi_tb_find_table(char *signature, | |||
70 | { | 70 | { |
71 | acpi_native_uint i; | 71 | acpi_native_uint i; |
72 | acpi_status status; | 72 | acpi_status status; |
73 | struct acpi_table_header header; | ||
73 | 74 | ||
74 | ACPI_FUNCTION_TRACE(tb_find_table); | 75 | ACPI_FUNCTION_TRACE(tb_find_table); |
75 | 76 | ||
77 | /* Normalize the input strings */ | ||
78 | |||
79 | ACPI_MEMSET(&header, 0, sizeof(struct acpi_table_header)); | ||
80 | ACPI_STRNCPY(header.signature, signature, ACPI_NAME_SIZE); | ||
81 | ACPI_STRNCPY(header.oem_id, oem_id, ACPI_OEM_ID_SIZE); | ||
82 | ACPI_STRNCPY(header.oem_table_id, oem_table_id, ACPI_OEM_TABLE_ID_SIZE); | ||
83 | |||
84 | /* Search for the table */ | ||
85 | |||
76 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { | 86 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { |
77 | if (ACPI_MEMCMP(&(acpi_gbl_root_table_list.tables[i].signature), | 87 | if (ACPI_MEMCMP(&(acpi_gbl_root_table_list.tables[i].signature), |
78 | signature, ACPI_NAME_SIZE)) { | 88 | header.signature, ACPI_NAME_SIZE)) { |
79 | 89 | ||
80 | /* Not the requested table */ | 90 | /* Not the requested table */ |
81 | 91 | ||
@@ -104,20 +114,24 @@ acpi_tb_find_table(char *signature, | |||
104 | 114 | ||
105 | if (!ACPI_MEMCMP | 115 | if (!ACPI_MEMCMP |
106 | (acpi_gbl_root_table_list.tables[i].pointer->signature, | 116 | (acpi_gbl_root_table_list.tables[i].pointer->signature, |
107 | signature, ACPI_NAME_SIZE) && (!oem_id[0] | 117 | header.signature, ACPI_NAME_SIZE) && (!oem_id[0] |
108 | || | 118 | || |
109 | !ACPI_MEMCMP | 119 | !ACPI_MEMCMP |
110 | (acpi_gbl_root_table_list. | 120 | (acpi_gbl_root_table_list. |
111 | tables[i].pointer->oem_id, | 121 | tables[i].pointer-> |
112 | oem_id, ACPI_OEM_ID_SIZE)) | 122 | oem_id, |
123 | header.oem_id, | ||
124 | ACPI_OEM_ID_SIZE)) | ||
113 | && (!oem_table_id[0] | 125 | && (!oem_table_id[0] |
114 | || !ACPI_MEMCMP(acpi_gbl_root_table_list.tables[i]. | 126 | || !ACPI_MEMCMP(acpi_gbl_root_table_list.tables[i]. |
115 | pointer->oem_table_id, oem_table_id, | 127 | pointer->oem_table_id, |
128 | header.oem_table_id, | ||
116 | ACPI_OEM_TABLE_ID_SIZE))) { | 129 | ACPI_OEM_TABLE_ID_SIZE))) { |
117 | *table_index = i; | 130 | *table_index = i; |
118 | 131 | ||
119 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, | 132 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, |
120 | "Found table [%4.4s]\n", signature)); | 133 | "Found table [%4.4s]\n", |
134 | header.signature)); | ||
121 | return_ACPI_STATUS(AE_OK); | 135 | return_ACPI_STATUS(AE_OK); |
122 | } | 136 | } |
123 | } | 137 | } |
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index 3bc0c67a9283..402f93e1ff20 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -125,13 +125,20 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, | |||
125 | 125 | ||
126 | /* The table must be either an SSDT or a PSDT or an OEMx */ | 126 | /* The table must be either an SSDT or a PSDT or an OEMx */ |
127 | 127 | ||
128 | if ((!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT)) | 128 | if (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT)&& |
129 | && | 129 | !ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)&& |
130 | (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)) | 130 | strncmp(table_desc->pointer->signature, "OEM", 3)) { |
131 | && (strncmp(table_desc->pointer->signature, "OEM", 3))) { | 131 | /* Check for a printable name */ |
132 | ACPI_ERROR((AE_INFO, | 132 | if (acpi_ut_valid_acpi_name( |
133 | "Table has invalid signature [%4.4s], must be SSDT, PSDT or OEMx", | 133 | *(u32 *) table_desc->pointer->signature)) { |
134 | table_desc->pointer->signature)); | 134 | ACPI_ERROR((AE_INFO, "Table has invalid signature " |
135 | "[%4.4s], must be SSDT or PSDT", | ||
136 | table_desc->pointer->signature)); | ||
137 | } else { | ||
138 | ACPI_ERROR((AE_INFO, "Table has invalid signature " | ||
139 | "(0x%8.8X), must be SSDT or PSDT", | ||
140 | *(u32 *) table_desc->pointer->signature)); | ||
141 | } | ||
135 | return_ACPI_STATUS(AE_BAD_SIGNATURE); | 142 | return_ACPI_STATUS(AE_BAD_SIGNATURE); |
136 | } | 143 | } |
137 | 144 | ||
@@ -162,6 +169,7 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, | |||
162 | 169 | ||
163 | acpi_tb_delete_table(table_desc); | 170 | acpi_tb_delete_table(table_desc); |
164 | *table_index = i; | 171 | *table_index = i; |
172 | status = AE_ALREADY_EXISTS; | ||
165 | goto release; | 173 | goto release; |
166 | } | 174 | } |
167 | 175 | ||
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index 010f19652f80..bc019b9b6a68 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -212,7 +212,7 @@ acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length) | |||
212 | 212 | ||
213 | if (checksum) { | 213 | if (checksum) { |
214 | ACPI_WARNING((AE_INFO, | 214 | ACPI_WARNING((AE_INFO, |
215 | "Incorrect checksum in table [%4.4s] - %2.2X, should be %2.2X", | 215 | "Incorrect checksum in table [%4.4s] - %2.2X, should be %2.2X", |
216 | table->signature, table->checksum, | 216 | table->signature, table->checksum, |
217 | (u8) (table->checksum - checksum))); | 217 | (u8) (table->checksum - checksum))); |
218 | 218 | ||
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index a9e3331fee5d..fb57b93c2495 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -635,6 +635,95 @@ acpi_status acpi_load_tables(void) | |||
635 | ACPI_EXPORT_SYMBOL(acpi_load_tables) | 635 | ACPI_EXPORT_SYMBOL(acpi_load_tables) |
636 | 636 | ||
637 | 637 | ||
638 | /******************************************************************************* | ||
639 | * | ||
640 | * FUNCTION: acpi_install_table_handler | ||
641 | * | ||
642 | * PARAMETERS: Handler - Table event handler | ||
643 | * Context - Value passed to the handler on each event | ||
644 | * | ||
645 | * RETURN: Status | ||
646 | * | ||
647 | * DESCRIPTION: Install table event handler | ||
648 | * | ||
649 | ******************************************************************************/ | ||
650 | acpi_status | ||
651 | acpi_install_table_handler(acpi_tbl_handler handler, void *context) | ||
652 | { | ||
653 | acpi_status status; | ||
654 | |||
655 | ACPI_FUNCTION_TRACE(acpi_install_table_handler); | ||
656 | |||
657 | if (!handler) { | ||
658 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
659 | } | ||
660 | |||
661 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
662 | if (ACPI_FAILURE(status)) { | ||
663 | return_ACPI_STATUS(status); | ||
664 | } | ||
665 | |||
666 | /* Don't allow more than one handler */ | ||
667 | |||
668 | if (acpi_gbl_table_handler) { | ||
669 | status = AE_ALREADY_EXISTS; | ||
670 | goto cleanup; | ||
671 | } | ||
672 | |||
673 | /* Install the handler */ | ||
674 | |||
675 | acpi_gbl_table_handler = handler; | ||
676 | acpi_gbl_table_handler_context = context; | ||
677 | |||
678 | cleanup: | ||
679 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
680 | return_ACPI_STATUS(status); | ||
681 | } | ||
682 | |||
683 | ACPI_EXPORT_SYMBOL(acpi_install_table_handler) | ||
684 | |||
685 | /******************************************************************************* | ||
686 | * | ||
687 | * FUNCTION: acpi_remove_table_handler | ||
688 | * | ||
689 | * PARAMETERS: Handler - Table event handler that was installed | ||
690 | * previously. | ||
691 | * | ||
692 | * RETURN: Status | ||
693 | * | ||
694 | * DESCRIPTION: Remove table event handler | ||
695 | * | ||
696 | ******************************************************************************/ | ||
697 | acpi_status acpi_remove_table_handler(acpi_tbl_handler handler) | ||
698 | { | ||
699 | acpi_status status; | ||
700 | |||
701 | ACPI_FUNCTION_TRACE(acpi_remove_table_handler); | ||
702 | |||
703 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
704 | if (ACPI_FAILURE(status)) { | ||
705 | return_ACPI_STATUS(status); | ||
706 | } | ||
707 | |||
708 | /* Make sure that the installed handler is the same */ | ||
709 | |||
710 | if (!handler || handler != acpi_gbl_table_handler) { | ||
711 | status = AE_BAD_PARAMETER; | ||
712 | goto cleanup; | ||
713 | } | ||
714 | |||
715 | /* Remove the handler */ | ||
716 | |||
717 | acpi_gbl_table_handler = NULL; | ||
718 | |||
719 | cleanup: | ||
720 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
721 | return_ACPI_STATUS(status); | ||
722 | } | ||
723 | |||
724 | ACPI_EXPORT_SYMBOL(acpi_remove_table_handler) | ||
725 | |||
726 | |||
638 | static int __init acpi_no_auto_ssdt_setup(char *s) { | 727 | static int __init acpi_no_auto_ssdt_setup(char *s) { |
639 | 728 | ||
640 | printk(KERN_NOTICE "ACPI: SSDT auto-load disabled\n"); | 729 | printk(KERN_NOTICE "ACPI: SSDT auto-load disabled\n"); |
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c index 9ecb4b6c1e7d..b8c0dfa084f6 100644 --- a/drivers/acpi/tables/tbxfroot.c +++ b/drivers/acpi/tables/tbxfroot.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c index 6e56d5f7c43a..ede084829a70 100644 --- a/drivers/acpi/utilities/utalloc.c +++ b/drivers/acpi/utilities/utalloc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -147,7 +147,7 @@ acpi_status acpi_ut_delete_caches(void) | |||
147 | 147 | ||
148 | if (acpi_gbl_display_final_mem_stats) { | 148 | if (acpi_gbl_display_final_mem_stats) { |
149 | ACPI_STRCPY(buffer, "MEMORY"); | 149 | ACPI_STRCPY(buffer, "MEMORY"); |
150 | acpi_db_display_statistics(buffer); | 150 | (void)acpi_db_display_statistics(buffer); |
151 | } | 151 | } |
152 | #endif | 152 | #endif |
153 | 153 | ||
diff --git a/drivers/acpi/utilities/utcache.c b/drivers/acpi/utilities/utcache.c index 285a0f531760..245fa80cf600 100644 --- a/drivers/acpi/utilities/utcache.c +++ b/drivers/acpi/utilities/utcache.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c index 879eaa10d3ae..655c290aca7b 100644 --- a/drivers/acpi/utilities/utcopy.c +++ b/drivers/acpi/utilities/utcopy.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -43,6 +43,8 @@ | |||
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/amlcode.h> | 45 | #include <acpi/amlcode.h> |
46 | #include <acpi/acnamesp.h> | ||
47 | |||
46 | 48 | ||
47 | #define _COMPONENT ACPI_UTILITIES | 49 | #define _COMPONENT ACPI_UTILITIES |
48 | ACPI_MODULE_NAME("utcopy") | 50 | ACPI_MODULE_NAME("utcopy") |
@@ -172,22 +174,21 @@ acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object, | |||
172 | 174 | ||
173 | case ACPI_TYPE_LOCAL_REFERENCE: | 175 | case ACPI_TYPE_LOCAL_REFERENCE: |
174 | 176 | ||
175 | /* | 177 | /* This is an object reference. */ |
176 | * This is an object reference. Attempt to dereference it. | 178 | |
177 | */ | ||
178 | switch (internal_object->reference.opcode) { | 179 | switch (internal_object->reference.opcode) { |
179 | case AML_INT_NAMEPATH_OP: | 180 | case AML_INT_NAMEPATH_OP: |
180 | 181 | ||
181 | /* For namepath, return the object handle ("reference") */ | 182 | /* For namepath, return the object handle ("reference") */ |
182 | 183 | ||
183 | default: | 184 | default: |
184 | /* | 185 | |
185 | * Use the object type of "Any" to indicate a reference | 186 | /* We are referring to the namespace node */ |
186 | * to object containing a handle to an ACPI named object. | 187 | |
187 | */ | ||
188 | external_object->type = ACPI_TYPE_ANY; | ||
189 | external_object->reference.handle = | 188 | external_object->reference.handle = |
190 | internal_object->reference.node; | 189 | internal_object->reference.node; |
190 | external_object->reference.actual_type = | ||
191 | acpi_ns_get_type(internal_object->reference.node); | ||
191 | break; | 192 | break; |
192 | } | 193 | } |
193 | break; | 194 | break; |
@@ -215,6 +216,11 @@ acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object, | |||
215 | /* | 216 | /* |
216 | * There is no corresponding external object type | 217 | * There is no corresponding external object type |
217 | */ | 218 | */ |
219 | ACPI_ERROR((AE_INFO, | ||
220 | "Unsupported object type, cannot convert to external object: %s", | ||
221 | acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE | ||
222 | (internal_object)))); | ||
223 | |||
218 | return_ACPI_STATUS(AE_SUPPORT); | 224 | return_ACPI_STATUS(AE_SUPPORT); |
219 | } | 225 | } |
220 | 226 | ||
@@ -455,6 +461,7 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object, | |||
455 | case ACPI_TYPE_STRING: | 461 | case ACPI_TYPE_STRING: |
456 | case ACPI_TYPE_BUFFER: | 462 | case ACPI_TYPE_BUFFER: |
457 | case ACPI_TYPE_INTEGER: | 463 | case ACPI_TYPE_INTEGER: |
464 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
458 | 465 | ||
459 | internal_object = acpi_ut_create_internal_object((u8) | 466 | internal_object = acpi_ut_create_internal_object((u8) |
460 | external_object-> | 467 | external_object-> |
@@ -464,9 +471,18 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object, | |||
464 | } | 471 | } |
465 | break; | 472 | break; |
466 | 473 | ||
474 | case ACPI_TYPE_ANY: /* This is the case for a NULL object */ | ||
475 | |||
476 | *ret_internal_object = NULL; | ||
477 | return_ACPI_STATUS(AE_OK); | ||
478 | |||
467 | default: | 479 | default: |
468 | /* All other types are not supported */ | 480 | /* All other types are not supported */ |
469 | 481 | ||
482 | ACPI_ERROR((AE_INFO, | ||
483 | "Unsupported object type, cannot convert to internal object: %s", | ||
484 | acpi_ut_get_type_name(external_object->type))); | ||
485 | |||
470 | return_ACPI_STATUS(AE_SUPPORT); | 486 | return_ACPI_STATUS(AE_SUPPORT); |
471 | } | 487 | } |
472 | 488 | ||
@@ -502,6 +518,10 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object, | |||
502 | external_object->buffer.length); | 518 | external_object->buffer.length); |
503 | 519 | ||
504 | internal_object->buffer.length = external_object->buffer.length; | 520 | internal_object->buffer.length = external_object->buffer.length; |
521 | |||
522 | /* Mark buffer data valid */ | ||
523 | |||
524 | internal_object->buffer.flags |= AOPOBJ_DATA_VALID; | ||
505 | break; | 525 | break; |
506 | 526 | ||
507 | case ACPI_TYPE_INTEGER: | 527 | case ACPI_TYPE_INTEGER: |
@@ -509,6 +529,15 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object, | |||
509 | internal_object->integer.value = external_object->integer.value; | 529 | internal_object->integer.value = external_object->integer.value; |
510 | break; | 530 | break; |
511 | 531 | ||
532 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
533 | |||
534 | /* TBD: should validate incoming handle */ | ||
535 | |||
536 | internal_object->reference.opcode = AML_INT_NAMEPATH_OP; | ||
537 | internal_object->reference.node = | ||
538 | external_object->reference.handle; | ||
539 | break; | ||
540 | |||
512 | default: | 541 | default: |
513 | /* Other types can't get here */ | 542 | /* Other types can't get here */ |
514 | break; | 543 | break; |
@@ -570,13 +599,17 @@ acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object, | |||
570 | 599 | ||
571 | /* Truncate package and delete it */ | 600 | /* Truncate package and delete it */ |
572 | 601 | ||
573 | package_object->package.count = i; | 602 | package_object->package.count = (u32) i; |
574 | package_elements[i] = NULL; | 603 | package_elements[i] = NULL; |
575 | acpi_ut_remove_reference(package_object); | 604 | acpi_ut_remove_reference(package_object); |
576 | return_ACPI_STATUS(status); | 605 | return_ACPI_STATUS(status); |
577 | } | 606 | } |
578 | } | 607 | } |
579 | 608 | ||
609 | /* Mark package data valid */ | ||
610 | |||
611 | package_object->package.flags |= AOPOBJ_DATA_VALID; | ||
612 | |||
580 | *internal_object = package_object; | 613 | *internal_object = package_object; |
581 | return_ACPI_STATUS(status); | 614 | return_ACPI_STATUS(status); |
582 | } | 615 | } |
@@ -709,7 +742,15 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, | |||
709 | /* | 742 | /* |
710 | * We copied the reference object, so we now must add a reference | 743 | * We copied the reference object, so we now must add a reference |
711 | * to the object pointed to by the reference | 744 | * to the object pointed to by the reference |
745 | * | ||
746 | * DDBHandle reference (from Load/load_table is a special reference, | ||
747 | * it's Reference.Object is the table index, so does not need to | ||
748 | * increase the reference count | ||
712 | */ | 749 | */ |
750 | if (source_desc->reference.opcode == AML_LOAD_OP) { | ||
751 | break; | ||
752 | } | ||
753 | |||
713 | acpi_ut_add_reference(source_desc->reference.object); | 754 | acpi_ut_add_reference(source_desc->reference.object); |
714 | break; | 755 | break; |
715 | 756 | ||
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c index 7361204b1eef..f938f465efa4 100644 --- a/drivers/acpi/utilities/utdebug.c +++ b/drivers/acpi/utilities/utdebug.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -68,9 +68,9 @@ static const char *acpi_ut_trim_function_name(const char *function_name); | |||
68 | 68 | ||
69 | void acpi_ut_init_stack_ptr_trace(void) | 69 | void acpi_ut_init_stack_ptr_trace(void) |
70 | { | 70 | { |
71 | u32 current_sp; | 71 | acpi_size current_sp; |
72 | 72 | ||
73 | acpi_gbl_entry_stack_pointer = ACPI_PTR_DIFF(¤t_sp, NULL); | 73 | acpi_gbl_entry_stack_pointer = ¤t_sp; |
74 | } | 74 | } |
75 | 75 | ||
76 | /******************************************************************************* | 76 | /******************************************************************************* |
@@ -89,10 +89,8 @@ void acpi_ut_track_stack_ptr(void) | |||
89 | { | 89 | { |
90 | acpi_size current_sp; | 90 | acpi_size current_sp; |
91 | 91 | ||
92 | current_sp = ACPI_PTR_DIFF(¤t_sp, NULL); | 92 | if (¤t_sp < acpi_gbl_lowest_stack_pointer) { |
93 | 93 | acpi_gbl_lowest_stack_pointer = ¤t_sp; | |
94 | if (current_sp < acpi_gbl_lowest_stack_pointer) { | ||
95 | acpi_gbl_lowest_stack_pointer = current_sp; | ||
96 | } | 94 | } |
97 | 95 | ||
98 | if (acpi_gbl_nesting_level > acpi_gbl_deepest_nesting) { | 96 | if (acpi_gbl_nesting_level > acpi_gbl_deepest_nesting) { |
@@ -203,6 +201,7 @@ acpi_ut_debug_print(u32 requested_debug_level, | |||
203 | 201 | ||
204 | va_start(args, format); | 202 | va_start(args, format); |
205 | acpi_os_vprintf(format, args); | 203 | acpi_os_vprintf(format, args); |
204 | va_end(args); | ||
206 | } | 205 | } |
207 | 206 | ||
208 | ACPI_EXPORT_SYMBOL(acpi_ut_debug_print) | 207 | ACPI_EXPORT_SYMBOL(acpi_ut_debug_print) |
@@ -240,6 +239,7 @@ acpi_ut_debug_print_raw(u32 requested_debug_level, | |||
240 | 239 | ||
241 | va_start(args, format); | 240 | va_start(args, format); |
242 | acpi_os_vprintf(format, args); | 241 | acpi_os_vprintf(format, args); |
242 | va_end(args); | ||
243 | } | 243 | } |
244 | 244 | ||
245 | ACPI_EXPORT_SYMBOL(acpi_ut_debug_print_raw) | 245 | ACPI_EXPORT_SYMBOL(acpi_ut_debug_print_raw) |
@@ -524,6 +524,11 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) | |||
524 | u32 temp32; | 524 | u32 temp32; |
525 | u8 buf_char; | 525 | u8 buf_char; |
526 | 526 | ||
527 | if (!buffer) { | ||
528 | acpi_os_printf("Null Buffer Pointer in DumpBuffer!\n"); | ||
529 | return; | ||
530 | } | ||
531 | |||
527 | if ((count < 4) || (count & 0x01)) { | 532 | if ((count < 4) || (count & 0x01)) { |
528 | display = DB_BYTE_DISPLAY; | 533 | display = DB_BYTE_DISPLAY; |
529 | } | 534 | } |
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c index f777cebdc46d..1fbc35139e84 100644 --- a/drivers/acpi/utilities/utdelete.c +++ b/drivers/acpi/utilities/utdelete.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -158,7 +158,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) | |||
158 | "***** Mutex %p, OS Mutex %p\n", | 158 | "***** Mutex %p, OS Mutex %p\n", |
159 | object, object->mutex.os_mutex)); | 159 | object, object->mutex.os_mutex)); |
160 | 160 | ||
161 | if (object->mutex.os_mutex == acpi_gbl_global_lock_mutex) { | 161 | if (object == acpi_gbl_global_lock_mutex) { |
162 | 162 | ||
163 | /* Global Lock has extra semaphore */ | 163 | /* Global Lock has extra semaphore */ |
164 | 164 | ||
@@ -252,6 +252,17 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) | |||
252 | } | 252 | } |
253 | break; | 253 | break; |
254 | 254 | ||
255 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
256 | |||
257 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
258 | "***** Bank Field %p\n", object)); | ||
259 | |||
260 | second_desc = acpi_ns_get_secondary_object(object); | ||
261 | if (second_desc) { | ||
262 | acpi_ut_delete_object_desc(second_desc); | ||
263 | } | ||
264 | break; | ||
265 | |||
255 | default: | 266 | default: |
256 | break; | 267 | break; |
257 | } | 268 | } |
@@ -524,10 +535,12 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action) | |||
524 | 535 | ||
525 | case ACPI_TYPE_LOCAL_REFERENCE: | 536 | case ACPI_TYPE_LOCAL_REFERENCE: |
526 | /* | 537 | /* |
527 | * The target of an Index (a package, string, or buffer) must track | 538 | * The target of an Index (a package, string, or buffer) or a named |
528 | * changes to the ref count of the index. | 539 | * reference must track changes to the ref count of the index or |
540 | * target object. | ||
529 | */ | 541 | */ |
530 | if (object->reference.opcode == AML_INDEX_OP) { | 542 | if ((object->reference.opcode == AML_INDEX_OP) || |
543 | (object->reference.opcode == AML_INT_NAMEPATH_OP)) { | ||
531 | next_object = object->reference.object; | 544 | next_object = object->reference.object; |
532 | } | 545 | } |
533 | break; | 546 | break; |
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c index 0042b7e78b26..05e61be267d5 100644 --- a/drivers/acpi/utilities/uteval.c +++ b/drivers/acpi/utilities/uteval.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index 630c9a2c5b7b..a6e71b801d2d 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -602,6 +602,48 @@ char *acpi_ut_get_mutex_name(u32 mutex_id) | |||
602 | 602 | ||
603 | return (acpi_gbl_mutex_names[mutex_id]); | 603 | return (acpi_gbl_mutex_names[mutex_id]); |
604 | } | 604 | } |
605 | |||
606 | /******************************************************************************* | ||
607 | * | ||
608 | * FUNCTION: acpi_ut_get_notify_name | ||
609 | * | ||
610 | * PARAMETERS: notify_value - Value from the Notify() request | ||
611 | * | ||
612 | * RETURN: String corresponding to the Notify Value. | ||
613 | * | ||
614 | * DESCRIPTION: Translate a Notify Value to a notify namestring. | ||
615 | * | ||
616 | ******************************************************************************/ | ||
617 | |||
618 | /* Names for Notify() values, used for debug output */ | ||
619 | |||
620 | static const char *acpi_gbl_notify_value_names[] = { | ||
621 | "Bus Check", | ||
622 | "Device Check", | ||
623 | "Device Wake", | ||
624 | "Eject Request", | ||
625 | "Device Check Light", | ||
626 | "Frequency Mismatch", | ||
627 | "Bus Mode Mismatch", | ||
628 | "Power Fault", | ||
629 | "Capabilities Check", | ||
630 | "Device PLD Check", | ||
631 | "Reserved", | ||
632 | "System Locality Update" | ||
633 | }; | ||
634 | |||
635 | const char *acpi_ut_get_notify_name(u32 notify_value) | ||
636 | { | ||
637 | |||
638 | if (notify_value <= ACPI_NOTIFY_MAX) { | ||
639 | return (acpi_gbl_notify_value_names[notify_value]); | ||
640 | } else if (notify_value <= ACPI_MAX_SYS_NOTIFY) { | ||
641 | return ("Reserved"); | ||
642 | } else { /* Greater or equal to 0x80 */ | ||
643 | |||
644 | return ("**Device Specific**"); | ||
645 | } | ||
646 | } | ||
605 | #endif | 647 | #endif |
606 | 648 | ||
607 | /******************************************************************************* | 649 | /******************************************************************************* |
@@ -675,12 +717,13 @@ void acpi_ut_init_globals(void) | |||
675 | acpi_gbl_gpe_fadt_blocks[0] = NULL; | 717 | acpi_gbl_gpe_fadt_blocks[0] = NULL; |
676 | acpi_gbl_gpe_fadt_blocks[1] = NULL; | 718 | acpi_gbl_gpe_fadt_blocks[1] = NULL; |
677 | 719 | ||
678 | /* Global notify handlers */ | 720 | /* Global handlers */ |
679 | 721 | ||
680 | acpi_gbl_system_notify.handler = NULL; | 722 | acpi_gbl_system_notify.handler = NULL; |
681 | acpi_gbl_device_notify.handler = NULL; | 723 | acpi_gbl_device_notify.handler = NULL; |
682 | acpi_gbl_exception_handler = NULL; | 724 | acpi_gbl_exception_handler = NULL; |
683 | acpi_gbl_init_handler = NULL; | 725 | acpi_gbl_init_handler = NULL; |
726 | acpi_gbl_table_handler = NULL; | ||
684 | 727 | ||
685 | /* Global Lock support */ | 728 | /* Global Lock support */ |
686 | 729 | ||
@@ -722,7 +765,7 @@ void acpi_ut_init_globals(void) | |||
722 | acpi_gbl_root_node_struct.flags = ANOBJ_END_OF_PEER_LIST; | 765 | acpi_gbl_root_node_struct.flags = ANOBJ_END_OF_PEER_LIST; |
723 | 766 | ||
724 | #ifdef ACPI_DEBUG_OUTPUT | 767 | #ifdef ACPI_DEBUG_OUTPUT |
725 | acpi_gbl_lowest_stack_pointer = ACPI_SIZE_MAX; | 768 | acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX); |
726 | #endif | 769 | #endif |
727 | 770 | ||
728 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | 771 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS |
diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c index ad3c0d0a5cf8..cae515fc02d3 100644 --- a/drivers/acpi/utilities/utinit.c +++ b/drivers/acpi/utilities/utinit.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -125,9 +125,12 @@ void acpi_ut_subsystem_shutdown(void) | |||
125 | acpi_gbl_startup_flags = 0; | 125 | acpi_gbl_startup_flags = 0; |
126 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n")); | 126 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n")); |
127 | 127 | ||
128 | #ifndef ACPI_ASL_COMPILER | ||
129 | |||
128 | /* Close the acpi_event Handling */ | 130 | /* Close the acpi_event Handling */ |
129 | 131 | ||
130 | acpi_ev_terminate(); | 132 | acpi_ev_terminate(); |
133 | #endif | ||
131 | 134 | ||
132 | /* Close the Namespace */ | 135 | /* Close the Namespace */ |
133 | 136 | ||
diff --git a/drivers/acpi/utilities/utmath.c b/drivers/acpi/utilities/utmath.c index 0c56a0d20b29..c927324fdd26 100644 --- a/drivers/acpi/utilities/utmath.c +++ b/drivers/acpi/utilities/utmath.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -276,7 +276,7 @@ acpi_ut_short_divide(acpi_integer in_dividend, | |||
276 | *out_quotient = in_dividend / divisor; | 276 | *out_quotient = in_dividend / divisor; |
277 | } | 277 | } |
278 | if (out_remainder) { | 278 | if (out_remainder) { |
279 | *out_remainder = (u32) in_dividend % divisor; | 279 | *out_remainder = (u32) (in_dividend % divisor); |
280 | } | 280 | } |
281 | 281 | ||
282 | return_ACPI_STATUS(AE_OK); | 282 | return_ACPI_STATUS(AE_OK); |
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index 2d19f71e9cfa..e4ba7192cd15 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -1033,6 +1033,7 @@ acpi_ut_error(char *module_name, u32 line_number, char *format, ...) | |||
1033 | va_start(args, format); | 1033 | va_start(args, format); |
1034 | acpi_os_vprintf(format, args); | 1034 | acpi_os_vprintf(format, args); |
1035 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); | 1035 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); |
1036 | va_end(args); | ||
1036 | } | 1037 | } |
1037 | 1038 | ||
1038 | void ACPI_INTERNAL_VAR_XFACE | 1039 | void ACPI_INTERNAL_VAR_XFACE |
@@ -1061,6 +1062,8 @@ acpi_ut_warning(char *module_name, u32 line_number, char *format, ...) | |||
1061 | va_start(args, format); | 1062 | va_start(args, format); |
1062 | acpi_os_vprintf(format, args); | 1063 | acpi_os_vprintf(format, args); |
1063 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); | 1064 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); |
1065 | va_end(args); | ||
1066 | va_end(args); | ||
1064 | } | 1067 | } |
1065 | 1068 | ||
1066 | void ACPI_INTERNAL_VAR_XFACE | 1069 | void ACPI_INTERNAL_VAR_XFACE |
@@ -1077,4 +1080,5 @@ acpi_ut_info(char *module_name, u32 line_number, char *format, ...) | |||
1077 | va_start(args, format); | 1080 | va_start(args, format); |
1078 | acpi_os_vprintf(format, args); | 1081 | acpi_os_vprintf(format, args); |
1079 | acpi_os_printf("\n"); | 1082 | acpi_os_printf("\n"); |
1083 | va_end(args); | ||
1080 | } | 1084 | } |
diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c index 4820bc86d1f5..f7d602b1a894 100644 --- a/drivers/acpi/utilities/utmutex.c +++ b/drivers/acpi/utilities/utmutex.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c index e08b3fa6639f..e68466de8044 100644 --- a/drivers/acpi/utilities/utobject.c +++ b/drivers/acpi/utilities/utobject.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -107,6 +107,7 @@ union acpi_operand_object *acpi_ut_create_internal_object_dbg(char *module_name, | |||
107 | switch (type) { | 107 | switch (type) { |
108 | case ACPI_TYPE_REGION: | 108 | case ACPI_TYPE_REGION: |
109 | case ACPI_TYPE_BUFFER_FIELD: | 109 | case ACPI_TYPE_BUFFER_FIELD: |
110 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
110 | 111 | ||
111 | /* These types require a secondary object */ | 112 | /* These types require a secondary object */ |
112 | 113 | ||
@@ -469,9 +470,8 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, | |||
469 | case ACPI_TYPE_PROCESSOR: | 470 | case ACPI_TYPE_PROCESSOR: |
470 | case ACPI_TYPE_POWER: | 471 | case ACPI_TYPE_POWER: |
471 | 472 | ||
472 | /* | 473 | /* No extra data for these types */ |
473 | * No extra data for these types | 474 | |
474 | */ | ||
475 | break; | 475 | break; |
476 | 476 | ||
477 | case ACPI_TYPE_LOCAL_REFERENCE: | 477 | case ACPI_TYPE_LOCAL_REFERENCE: |
diff --git a/drivers/acpi/utilities/utresrc.c b/drivers/acpi/utilities/utresrc.c index b630ee137ee1..c3e3e1308edc 100644 --- a/drivers/acpi/utilities/utresrc.c +++ b/drivers/acpi/utilities/utresrc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/utilities/utstate.c b/drivers/acpi/utilities/utstate.c index edcaafad0a31..63a6d3d77d88 100644 --- a/drivers/acpi/utilities/utstate.c +++ b/drivers/acpi/utilities/utstate.c | |||
@@ -5,7 +5,7 @@ | |||
5 | ******************************************************************************/ | 5 | ******************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c index 2d496918b3cd..f8bdadf3c32f 100644 --- a/drivers/acpi/utilities/utxface.c +++ b/drivers/acpi/utilities/utxface.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -49,6 +49,7 @@ | |||
49 | #define _COMPONENT ACPI_UTILITIES | 49 | #define _COMPONENT ACPI_UTILITIES |
50 | ACPI_MODULE_NAME("utxface") | 50 | ACPI_MODULE_NAME("utxface") |
51 | 51 | ||
52 | #ifndef ACPI_ASL_COMPILER | ||
52 | /******************************************************************************* | 53 | /******************************************************************************* |
53 | * | 54 | * |
54 | * FUNCTION: acpi_initialize_subsystem | 55 | * FUNCTION: acpi_initialize_subsystem |
@@ -192,24 +193,6 @@ acpi_status acpi_enable_subsystem(u32 flags) | |||
192 | } | 193 | } |
193 | } | 194 | } |
194 | 195 | ||
195 | /* | ||
196 | * Complete the GPE initialization for the GPE blocks defined in the FADT | ||
197 | * (GPE block 0 and 1). | ||
198 | * | ||
199 | * Note1: This is where the _PRW methods are executed for the GPEs. These | ||
200 | * methods can only be executed after the SCI and Global Lock handlers are | ||
201 | * installed and initialized. | ||
202 | * | ||
203 | * Note2: Currently, there seems to be no need to run the _REG methods | ||
204 | * before execution of the _PRW methods and enabling of the GPEs. | ||
205 | */ | ||
206 | if (!(flags & ACPI_NO_EVENT_INIT)) { | ||
207 | status = acpi_ev_install_fadt_gpes(); | ||
208 | if (ACPI_FAILURE(status)) { | ||
209 | return (status); | ||
210 | } | ||
211 | } | ||
212 | |||
213 | return_ACPI_STATUS(status); | 196 | return_ACPI_STATUS(status); |
214 | } | 197 | } |
215 | 198 | ||
@@ -280,6 +263,23 @@ acpi_status acpi_initialize_objects(u32 flags) | |||
280 | } | 263 | } |
281 | 264 | ||
282 | /* | 265 | /* |
266 | * Complete the GPE initialization for the GPE blocks defined in the FADT | ||
267 | * (GPE block 0 and 1). | ||
268 | * | ||
269 | * Note1: This is where the _PRW methods are executed for the GPEs. These | ||
270 | * methods can only be executed after the SCI and Global Lock handlers are | ||
271 | * installed and initialized. | ||
272 | * | ||
273 | * Note2: Currently, there seems to be no need to run the _REG methods | ||
274 | * before execution of the _PRW methods and enabling of the GPEs. | ||
275 | */ | ||
276 | if (!(flags & ACPI_NO_EVENT_INIT)) { | ||
277 | status = acpi_ev_install_fadt_gpes(); | ||
278 | if (ACPI_FAILURE(status)) | ||
279 | return (status); | ||
280 | } | ||
281 | |||
282 | /* | ||
283 | * Empty the caches (delete the cached objects) on the assumption that | 283 | * Empty the caches (delete the cached objects) on the assumption that |
284 | * the table load filled them up more than they will be at runtime -- | 284 | * the table load filled them up more than they will be at runtime -- |
285 | * thus wasting non-paged memory. | 285 | * thus wasting non-paged memory. |
@@ -292,6 +292,7 @@ acpi_status acpi_initialize_objects(u32 flags) | |||
292 | 292 | ||
293 | ACPI_EXPORT_SYMBOL(acpi_initialize_objects) | 293 | ACPI_EXPORT_SYMBOL(acpi_initialize_objects) |
294 | 294 | ||
295 | #endif | ||
295 | /******************************************************************************* | 296 | /******************************************************************************* |
296 | * | 297 | * |
297 | * FUNCTION: acpi_terminate | 298 | * FUNCTION: acpi_terminate |
@@ -335,6 +336,7 @@ acpi_status acpi_terminate(void) | |||
335 | } | 336 | } |
336 | 337 | ||
337 | ACPI_EXPORT_SYMBOL(acpi_terminate) | 338 | ACPI_EXPORT_SYMBOL(acpi_terminate) |
339 | #ifndef ACPI_ASL_COMPILER | ||
338 | #ifdef ACPI_FUTURE_USAGE | 340 | #ifdef ACPI_FUTURE_USAGE |
339 | /******************************************************************************* | 341 | /******************************************************************************* |
340 | * | 342 | * |
@@ -490,3 +492,4 @@ acpi_status acpi_purge_cached_objects(void) | |||
490 | } | 492 | } |
491 | 493 | ||
492 | ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects) | 494 | ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects) |
495 | #endif | ||
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 44ea60cf21c0..100926143818 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -398,7 +398,7 @@ acpi_evaluate_reference(acpi_handle handle, | |||
398 | 398 | ||
399 | element = &(package->package.elements[i]); | 399 | element = &(package->package.elements[i]); |
400 | 400 | ||
401 | if (element->type != ACPI_TYPE_ANY) { | 401 | if (element->type != ACPI_TYPE_LOCAL_REFERENCE) { |
402 | status = AE_BAD_DATA; | 402 | status = AE_BAD_DATA; |
403 | printk(KERN_ERR PREFIX | 403 | printk(KERN_ERR PREFIX |
404 | "Expecting a [Reference] package element, found type %X\n", | 404 | "Expecting a [Reference] package element, found type %X\n", |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 55c095619379..33c502e56026 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -57,8 +57,6 @@ | |||
57 | #define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88 | 57 | #define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88 |
58 | #define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89 | 58 | #define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89 |
59 | 59 | ||
60 | #define ACPI_VIDEO_HEAD_INVALID (~0u - 1) | ||
61 | #define ACPI_VIDEO_HEAD_END (~0u) | ||
62 | #define MAX_NAME_LEN 20 | 60 | #define MAX_NAME_LEN 20 |
63 | 61 | ||
64 | #define ACPI_VIDEO_DISPLAY_CRT 1 | 62 | #define ACPI_VIDEO_DISPLAY_CRT 1 |
@@ -1048,87 +1046,90 @@ acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file) | |||
1048 | 1046 | ||
1049 | static int acpi_video_device_add_fs(struct acpi_device *device) | 1047 | static int acpi_video_device_add_fs(struct acpi_device *device) |
1050 | { | 1048 | { |
1051 | struct proc_dir_entry *entry = NULL; | 1049 | struct proc_dir_entry *entry, *device_dir; |
1052 | struct acpi_video_device *vid_dev; | 1050 | struct acpi_video_device *vid_dev; |
1053 | 1051 | ||
1054 | |||
1055 | if (!device) | ||
1056 | return -ENODEV; | ||
1057 | |||
1058 | vid_dev = acpi_driver_data(device); | 1052 | vid_dev = acpi_driver_data(device); |
1059 | if (!vid_dev) | 1053 | if (!vid_dev) |
1060 | return -ENODEV; | 1054 | return -ENODEV; |
1061 | 1055 | ||
1062 | if (!acpi_device_dir(device)) { | 1056 | device_dir = proc_mkdir(acpi_device_bid(device), |
1063 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | 1057 | vid_dev->video->dir); |
1064 | vid_dev->video->dir); | 1058 | if (!device_dir) |
1065 | if (!acpi_device_dir(device)) | 1059 | return -ENOMEM; |
1066 | return -ENODEV; | 1060 | |
1067 | acpi_device_dir(device)->owner = THIS_MODULE; | 1061 | device_dir->owner = THIS_MODULE; |
1068 | } | ||
1069 | 1062 | ||
1070 | /* 'info' [R] */ | 1063 | /* 'info' [R] */ |
1071 | entry = create_proc_entry("info", S_IRUGO, acpi_device_dir(device)); | 1064 | entry = create_proc_entry("info", S_IRUGO, device_dir); |
1072 | if (!entry) | 1065 | if (!entry) |
1073 | return -ENODEV; | 1066 | goto err_remove_dir; |
1074 | else { | 1067 | |
1075 | entry->proc_fops = &acpi_video_device_info_fops; | 1068 | entry->proc_fops = &acpi_video_device_info_fops; |
1076 | entry->data = acpi_driver_data(device); | 1069 | entry->data = acpi_driver_data(device); |
1077 | entry->owner = THIS_MODULE; | 1070 | entry->owner = THIS_MODULE; |
1078 | } | ||
1079 | 1071 | ||
1080 | /* 'state' [R/W] */ | 1072 | /* 'state' [R/W] */ |
1081 | entry = | 1073 | entry = create_proc_entry("state", S_IFREG | S_IRUGO | S_IWUSR, |
1082 | create_proc_entry("state", S_IFREG | S_IRUGO | S_IWUSR, | 1074 | device_dir); |
1083 | acpi_device_dir(device)); | ||
1084 | if (!entry) | 1075 | if (!entry) |
1085 | return -ENODEV; | 1076 | goto err_remove_info; |
1086 | else { | 1077 | |
1087 | acpi_video_device_state_fops.write = acpi_video_device_write_state; | 1078 | acpi_video_device_state_fops.write = acpi_video_device_write_state; |
1088 | entry->proc_fops = &acpi_video_device_state_fops; | 1079 | entry->proc_fops = &acpi_video_device_state_fops; |
1089 | entry->data = acpi_driver_data(device); | 1080 | entry->data = acpi_driver_data(device); |
1090 | entry->owner = THIS_MODULE; | 1081 | entry->owner = THIS_MODULE; |
1091 | } | ||
1092 | 1082 | ||
1093 | /* 'brightness' [R/W] */ | 1083 | /* 'brightness' [R/W] */ |
1094 | entry = | 1084 | entry = create_proc_entry("brightness", S_IFREG | S_IRUGO | S_IWUSR, |
1095 | create_proc_entry("brightness", S_IFREG | S_IRUGO | S_IWUSR, | 1085 | device_dir); |
1096 | acpi_device_dir(device)); | ||
1097 | if (!entry) | 1086 | if (!entry) |
1098 | return -ENODEV; | 1087 | goto err_remove_state; |
1099 | else { | 1088 | |
1100 | acpi_video_device_brightness_fops.write = acpi_video_device_write_brightness; | 1089 | acpi_video_device_brightness_fops.write = |
1101 | entry->proc_fops = &acpi_video_device_brightness_fops; | 1090 | acpi_video_device_write_brightness; |
1102 | entry->data = acpi_driver_data(device); | 1091 | entry->proc_fops = &acpi_video_device_brightness_fops; |
1103 | entry->owner = THIS_MODULE; | 1092 | entry->data = acpi_driver_data(device); |
1104 | } | 1093 | entry->owner = THIS_MODULE; |
1105 | 1094 | ||
1106 | /* 'EDID' [R] */ | 1095 | /* 'EDID' [R] */ |
1107 | entry = create_proc_entry("EDID", S_IRUGO, acpi_device_dir(device)); | 1096 | entry = create_proc_entry("EDID", S_IRUGO, device_dir); |
1108 | if (!entry) | 1097 | if (!entry) |
1109 | return -ENODEV; | 1098 | goto err_remove_brightness; |
1110 | else { | 1099 | |
1111 | entry->proc_fops = &acpi_video_device_EDID_fops; | 1100 | entry->proc_fops = &acpi_video_device_EDID_fops; |
1112 | entry->data = acpi_driver_data(device); | 1101 | entry->data = acpi_driver_data(device); |
1113 | entry->owner = THIS_MODULE; | 1102 | entry->owner = THIS_MODULE; |
1114 | } | ||
1115 | 1103 | ||
1104 | acpi_device_dir(device) = device_dir; | ||
1116 | return 0; | 1105 | return 0; |
1106 | |||
1107 | err_remove_brightness: | ||
1108 | remove_proc_entry("brightness", device_dir); | ||
1109 | err_remove_state: | ||
1110 | remove_proc_entry("state", device_dir); | ||
1111 | err_remove_info: | ||
1112 | remove_proc_entry("info", device_dir); | ||
1113 | err_remove_dir: | ||
1114 | remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir); | ||
1115 | return -ENOMEM; | ||
1117 | } | 1116 | } |
1118 | 1117 | ||
1119 | static int acpi_video_device_remove_fs(struct acpi_device *device) | 1118 | static int acpi_video_device_remove_fs(struct acpi_device *device) |
1120 | { | 1119 | { |
1121 | struct acpi_video_device *vid_dev; | 1120 | struct acpi_video_device *vid_dev; |
1121 | struct proc_dir_entry *device_dir; | ||
1122 | 1122 | ||
1123 | vid_dev = acpi_driver_data(device); | 1123 | vid_dev = acpi_driver_data(device); |
1124 | if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) | 1124 | if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) |
1125 | return -ENODEV; | 1125 | return -ENODEV; |
1126 | 1126 | ||
1127 | if (acpi_device_dir(device)) { | 1127 | device_dir = acpi_device_dir(device); |
1128 | remove_proc_entry("info", acpi_device_dir(device)); | 1128 | if (device_dir) { |
1129 | remove_proc_entry("state", acpi_device_dir(device)); | 1129 | remove_proc_entry("info", device_dir); |
1130 | remove_proc_entry("brightness", acpi_device_dir(device)); | 1130 | remove_proc_entry("state", device_dir); |
1131 | remove_proc_entry("EDID", acpi_device_dir(device)); | 1131 | remove_proc_entry("brightness", device_dir); |
1132 | remove_proc_entry("EDID", device_dir); | ||
1132 | remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir); | 1133 | remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir); |
1133 | acpi_device_dir(device) = NULL; | 1134 | acpi_device_dir(device) = NULL; |
1134 | } | 1135 | } |
@@ -1335,94 +1336,91 @@ acpi_video_bus_write_DOS(struct file *file, | |||
1335 | 1336 | ||
1336 | static int acpi_video_bus_add_fs(struct acpi_device *device) | 1337 | static int acpi_video_bus_add_fs(struct acpi_device *device) |
1337 | { | 1338 | { |
1338 | struct proc_dir_entry *entry = NULL; | 1339 | struct acpi_video_bus *video = acpi_driver_data(device); |
1339 | struct acpi_video_bus *video; | 1340 | struct proc_dir_entry *device_dir; |
1341 | struct proc_dir_entry *entry; | ||
1340 | 1342 | ||
1343 | device_dir = proc_mkdir(acpi_device_bid(device), acpi_video_dir); | ||
1344 | if (!device_dir) | ||
1345 | return -ENOMEM; | ||
1341 | 1346 | ||
1342 | video = acpi_driver_data(device); | 1347 | device_dir->owner = THIS_MODULE; |
1343 | |||
1344 | if (!acpi_device_dir(device)) { | ||
1345 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | ||
1346 | acpi_video_dir); | ||
1347 | if (!acpi_device_dir(device)) | ||
1348 | return -ENODEV; | ||
1349 | video->dir = acpi_device_dir(device); | ||
1350 | acpi_device_dir(device)->owner = THIS_MODULE; | ||
1351 | } | ||
1352 | 1348 | ||
1353 | /* 'info' [R] */ | 1349 | /* 'info' [R] */ |
1354 | entry = create_proc_entry("info", S_IRUGO, acpi_device_dir(device)); | 1350 | entry = create_proc_entry("info", S_IRUGO, device_dir); |
1355 | if (!entry) | 1351 | if (!entry) |
1356 | return -ENODEV; | 1352 | goto err_remove_dir; |
1357 | else { | 1353 | |
1358 | entry->proc_fops = &acpi_video_bus_info_fops; | 1354 | entry->proc_fops = &acpi_video_bus_info_fops; |
1359 | entry->data = acpi_driver_data(device); | 1355 | entry->data = acpi_driver_data(device); |
1360 | entry->owner = THIS_MODULE; | 1356 | entry->owner = THIS_MODULE; |
1361 | } | ||
1362 | 1357 | ||
1363 | /* 'ROM' [R] */ | 1358 | /* 'ROM' [R] */ |
1364 | entry = create_proc_entry("ROM", S_IRUGO, acpi_device_dir(device)); | 1359 | entry = create_proc_entry("ROM", S_IRUGO, device_dir); |
1365 | if (!entry) | 1360 | if (!entry) |
1366 | return -ENODEV; | 1361 | goto err_remove_info; |
1367 | else { | 1362 | |
1368 | entry->proc_fops = &acpi_video_bus_ROM_fops; | 1363 | entry->proc_fops = &acpi_video_bus_ROM_fops; |
1369 | entry->data = acpi_driver_data(device); | 1364 | entry->data = acpi_driver_data(device); |
1370 | entry->owner = THIS_MODULE; | 1365 | entry->owner = THIS_MODULE; |
1371 | } | ||
1372 | 1366 | ||
1373 | /* 'POST_info' [R] */ | 1367 | /* 'POST_info' [R] */ |
1374 | entry = | 1368 | entry = create_proc_entry("POST_info", S_IRUGO, device_dir); |
1375 | create_proc_entry("POST_info", S_IRUGO, acpi_device_dir(device)); | ||
1376 | if (!entry) | 1369 | if (!entry) |
1377 | return -ENODEV; | 1370 | goto err_remove_rom; |
1378 | else { | 1371 | |
1379 | entry->proc_fops = &acpi_video_bus_POST_info_fops; | 1372 | entry->proc_fops = &acpi_video_bus_POST_info_fops; |
1380 | entry->data = acpi_driver_data(device); | 1373 | entry->data = acpi_driver_data(device); |
1381 | entry->owner = THIS_MODULE; | 1374 | entry->owner = THIS_MODULE; |
1382 | } | ||
1383 | 1375 | ||
1384 | /* 'POST' [R/W] */ | 1376 | /* 'POST' [R/W] */ |
1385 | entry = | 1377 | entry = create_proc_entry("POST", S_IFREG | S_IRUGO | S_IWUSR, |
1386 | create_proc_entry("POST", S_IFREG | S_IRUGO | S_IRUSR, | 1378 | device_dir); |
1387 | acpi_device_dir(device)); | ||
1388 | if (!entry) | 1379 | if (!entry) |
1389 | return -ENODEV; | 1380 | goto err_remove_post_info; |
1390 | else { | 1381 | |
1391 | acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST; | 1382 | acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST; |
1392 | entry->proc_fops = &acpi_video_bus_POST_fops; | 1383 | entry->proc_fops = &acpi_video_bus_POST_fops; |
1393 | entry->data = acpi_driver_data(device); | 1384 | entry->data = acpi_driver_data(device); |
1394 | entry->owner = THIS_MODULE; | 1385 | entry->owner = THIS_MODULE; |
1395 | } | ||
1396 | 1386 | ||
1397 | /* 'DOS' [R/W] */ | 1387 | /* 'DOS' [R/W] */ |
1398 | entry = | 1388 | entry = create_proc_entry("DOS", S_IFREG | S_IRUGO | S_IWUSR, |
1399 | create_proc_entry("DOS", S_IFREG | S_IRUGO | S_IRUSR, | 1389 | device_dir); |
1400 | acpi_device_dir(device)); | ||
1401 | if (!entry) | 1390 | if (!entry) |
1402 | return -ENODEV; | 1391 | goto err_remove_post; |
1403 | else { | 1392 | |
1404 | acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS; | 1393 | acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS; |
1405 | entry->proc_fops = &acpi_video_bus_DOS_fops; | 1394 | entry->proc_fops = &acpi_video_bus_DOS_fops; |
1406 | entry->data = acpi_driver_data(device); | 1395 | entry->data = acpi_driver_data(device); |
1407 | entry->owner = THIS_MODULE; | 1396 | entry->owner = THIS_MODULE; |
1408 | } | ||
1409 | 1397 | ||
1398 | video->dir = acpi_device_dir(device) = device_dir; | ||
1410 | return 0; | 1399 | return 0; |
1400 | |||
1401 | err_remove_post: | ||
1402 | remove_proc_entry("POST", device_dir); | ||
1403 | err_remove_post_info: | ||
1404 | remove_proc_entry("POST_info", device_dir); | ||
1405 | err_remove_rom: | ||
1406 | remove_proc_entry("ROM", device_dir); | ||
1407 | err_remove_info: | ||
1408 | remove_proc_entry("info", device_dir); | ||
1409 | err_remove_dir: | ||
1410 | remove_proc_entry(acpi_device_bid(device), acpi_video_dir); | ||
1411 | return -ENOMEM; | ||
1411 | } | 1412 | } |
1412 | 1413 | ||
1413 | static int acpi_video_bus_remove_fs(struct acpi_device *device) | 1414 | static int acpi_video_bus_remove_fs(struct acpi_device *device) |
1414 | { | 1415 | { |
1415 | struct acpi_video_bus *video; | 1416 | struct proc_dir_entry *device_dir = acpi_device_dir(device); |
1416 | |||
1417 | |||
1418 | video = acpi_driver_data(device); | ||
1419 | 1417 | ||
1420 | if (acpi_device_dir(device)) { | 1418 | if (device_dir) { |
1421 | remove_proc_entry("info", acpi_device_dir(device)); | 1419 | remove_proc_entry("info", device_dir); |
1422 | remove_proc_entry("ROM", acpi_device_dir(device)); | 1420 | remove_proc_entry("ROM", device_dir); |
1423 | remove_proc_entry("POST_info", acpi_device_dir(device)); | 1421 | remove_proc_entry("POST_info", device_dir); |
1424 | remove_proc_entry("POST", acpi_device_dir(device)); | 1422 | remove_proc_entry("POST", device_dir); |
1425 | remove_proc_entry("DOS", acpi_device_dir(device)); | 1423 | remove_proc_entry("DOS", device_dir); |
1426 | remove_proc_entry(acpi_device_bid(device), acpi_video_dir); | 1424 | remove_proc_entry(acpi_device_bid(device), acpi_video_dir); |
1427 | acpi_device_dir(device) = NULL; | 1425 | acpi_device_dir(device) = NULL; |
1428 | } | 1426 | } |
@@ -1438,11 +1436,15 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device) | |||
1438 | static struct acpi_video_device_attrib* | 1436 | static struct acpi_video_device_attrib* |
1439 | acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id) | 1437 | acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id) |
1440 | { | 1438 | { |
1441 | int count; | 1439 | struct acpi_video_enumerated_device *ids; |
1440 | int i; | ||
1441 | |||
1442 | for (i = 0; i < video->attached_count; i++) { | ||
1443 | ids = &video->attached_array[i]; | ||
1444 | if ((ids->value.int_val & 0xffff) == device_id) | ||
1445 | return &ids->value.attrib; | ||
1446 | } | ||
1442 | 1447 | ||
1443 | for(count = 0; count < video->attached_count; count++) | ||
1444 | if((video->attached_array[count].value.int_val & 0xffff) == device_id) | ||
1445 | return &(video->attached_array[count].value.attrib); | ||
1446 | return NULL; | 1448 | return NULL; |
1447 | } | 1449 | } |
1448 | 1450 | ||
@@ -1569,20 +1571,16 @@ static void | |||
1569 | acpi_video_device_bind(struct acpi_video_bus *video, | 1571 | acpi_video_device_bind(struct acpi_video_bus *video, |
1570 | struct acpi_video_device *device) | 1572 | struct acpi_video_device *device) |
1571 | { | 1573 | { |
1574 | struct acpi_video_enumerated_device *ids; | ||
1572 | int i; | 1575 | int i; |
1573 | 1576 | ||
1574 | #define IDS_VAL(i) video->attached_array[i].value.int_val | 1577 | for (i = 0; i < video->attached_count; i++) { |
1575 | #define IDS_BIND(i) video->attached_array[i].bind_info | 1578 | ids = &video->attached_array[i]; |
1576 | 1579 | if (device->device_id == (ids->value.int_val & 0xffff)) { | |
1577 | for (i = 0; IDS_VAL(i) != ACPI_VIDEO_HEAD_INVALID && | 1580 | ids->bind_info = device; |
1578 | i < video->attached_count; i++) { | ||
1579 | if (device->device_id == (IDS_VAL(i) & 0xffff)) { | ||
1580 | IDS_BIND(i) = device; | ||
1581 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i)); | 1581 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i)); |
1582 | } | 1582 | } |
1583 | } | 1583 | } |
1584 | #undef IDS_VAL | ||
1585 | #undef IDS_BIND | ||
1586 | } | 1584 | } |
1587 | 1585 | ||
1588 | /* | 1586 | /* |
@@ -1601,7 +1599,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) | |||
1601 | int status; | 1599 | int status; |
1602 | int count; | 1600 | int count; |
1603 | int i; | 1601 | int i; |
1604 | struct acpi_video_enumerated_device *active_device_list; | 1602 | struct acpi_video_enumerated_device *active_list; |
1605 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 1603 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
1606 | union acpi_object *dod = NULL; | 1604 | union acpi_object *dod = NULL; |
1607 | union acpi_object *obj; | 1605 | union acpi_object *obj; |
@@ -1622,13 +1620,10 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) | |||
1622 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n", | 1620 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n", |
1623 | dod->package.count)); | 1621 | dod->package.count)); |
1624 | 1622 | ||
1625 | active_device_list = kmalloc((1 + | 1623 | active_list = kcalloc(1 + dod->package.count, |
1626 | dod->package.count) * | 1624 | sizeof(struct acpi_video_enumerated_device), |
1627 | sizeof(struct | 1625 | GFP_KERNEL); |
1628 | acpi_video_enumerated_device), | 1626 | if (!active_list) { |
1629 | GFP_KERNEL); | ||
1630 | |||
1631 | if (!active_device_list) { | ||
1632 | status = -ENOMEM; | 1627 | status = -ENOMEM; |
1633 | goto out; | 1628 | goto out; |
1634 | } | 1629 | } |
@@ -1638,23 +1633,24 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) | |||
1638 | obj = &dod->package.elements[i]; | 1633 | obj = &dod->package.elements[i]; |
1639 | 1634 | ||
1640 | if (obj->type != ACPI_TYPE_INTEGER) { | 1635 | if (obj->type != ACPI_TYPE_INTEGER) { |
1641 | printk(KERN_ERR PREFIX "Invalid _DOD data\n"); | 1636 | printk(KERN_ERR PREFIX |
1642 | active_device_list[i].value.int_val = | 1637 | "Invalid _DOD data in element %d\n", i); |
1643 | ACPI_VIDEO_HEAD_INVALID; | 1638 | continue; |
1644 | } | 1639 | } |
1645 | active_device_list[i].value.int_val = obj->integer.value; | 1640 | |
1646 | active_device_list[i].bind_info = NULL; | 1641 | active_list[count].value.int_val = obj->integer.value; |
1642 | active_list[count].bind_info = NULL; | ||
1647 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i, | 1643 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i, |
1648 | (int)obj->integer.value)); | 1644 | (int)obj->integer.value)); |
1649 | count++; | 1645 | count++; |
1650 | } | 1646 | } |
1651 | active_device_list[count].value.int_val = ACPI_VIDEO_HEAD_END; | ||
1652 | 1647 | ||
1653 | kfree(video->attached_array); | 1648 | kfree(video->attached_array); |
1654 | 1649 | ||
1655 | video->attached_array = active_device_list; | 1650 | video->attached_array = active_list; |
1656 | video->attached_count = count; | 1651 | video->attached_count = count; |
1657 | out: | 1652 | |
1653 | out: | ||
1658 | kfree(buffer.pointer); | 1654 | kfree(buffer.pointer); |
1659 | return status; | 1655 | return status; |
1660 | } | 1656 | } |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 08f35d76dcd9..636af2862308 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -140,6 +140,7 @@ config ACER_WMI | |||
140 | depends on EXPERIMENTAL | 140 | depends on EXPERIMENTAL |
141 | depends on ACPI | 141 | depends on ACPI |
142 | depends on LEDS_CLASS | 142 | depends on LEDS_CLASS |
143 | depends on NEW_LEDS | ||
143 | depends on BACKLIGHT_CLASS_DEVICE | 144 | depends on BACKLIGHT_CLASS_DEVICE |
144 | depends on SERIO_I8042 | 145 | depends on SERIO_I8042 |
145 | select ACPI_WMI | 146 | select ACPI_WMI |
@@ -160,6 +161,7 @@ config ASUS_LAPTOP | |||
160 | depends on ACPI | 161 | depends on ACPI |
161 | depends on EXPERIMENTAL && !ACPI_ASUS | 162 | depends on EXPERIMENTAL && !ACPI_ASUS |
162 | depends on LEDS_CLASS | 163 | depends on LEDS_CLASS |
164 | depends on NEW_LEDS | ||
163 | depends on BACKLIGHT_CLASS_DEVICE | 165 | depends on BACKLIGHT_CLASS_DEVICE |
164 | ---help--- | 166 | ---help--- |
165 | This is the new Linux driver for Asus laptops. It may also support some | 167 | This is the new Linux driver for Asus laptops. It may also support some |
@@ -241,10 +243,13 @@ config SONYPI_COMPAT | |||
241 | config THINKPAD_ACPI | 243 | config THINKPAD_ACPI |
242 | tristate "ThinkPad ACPI Laptop Extras" | 244 | tristate "ThinkPad ACPI Laptop Extras" |
243 | depends on X86 && ACPI | 245 | depends on X86 && ACPI |
246 | select BACKLIGHT_LCD_SUPPORT | ||
244 | select BACKLIGHT_CLASS_DEVICE | 247 | select BACKLIGHT_CLASS_DEVICE |
245 | select HWMON | 248 | select HWMON |
246 | select NVRAM | 249 | select NVRAM |
247 | depends on INPUT | 250 | select INPUT |
251 | select NEW_LEDS | ||
252 | select LEDS_CLASS | ||
248 | ---help--- | 253 | ---help--- |
249 | This is a driver for the IBM and Lenovo ThinkPad laptops. It adds | 254 | This is a driver for the IBM and Lenovo ThinkPad laptops. It adds |
250 | support for Fn-Fx key combinations, Bluetooth control, video | 255 | support for Fn-Fx key combinations, Bluetooth control, video |
@@ -352,6 +357,19 @@ config INTEL_MENLOW | |||
352 | 357 | ||
353 | If unsure, say N. | 358 | If unsure, say N. |
354 | 359 | ||
360 | config EEEPC_LAPTOP | ||
361 | tristate "Eee PC Hotkey Driver (EXPERIMENTAL)" | ||
362 | depends on X86 | ||
363 | depends on ACPI | ||
364 | depends on BACKLIGHT_CLASS_DEVICE | ||
365 | depends on HWMON | ||
366 | depends on EXPERIMENTAL | ||
367 | ---help--- | ||
368 | This driver supports the Fn-Fx keys on Eee PC laptops. | ||
369 | It also adds the ability to switch camera/wlan on/off. | ||
370 | |||
371 | If you have an Eee PC laptop, say Y or M here. | ||
372 | |||
355 | config ENCLOSURE_SERVICES | 373 | config ENCLOSURE_SERVICES |
356 | tristate "Enclosure Services" | 374 | tristate "Enclosure Services" |
357 | default n | 375 | default n |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 5914da434854..1952875a272e 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
@@ -7,7 +7,8 @@ obj-$(CONFIG_IBM_ASM) += ibmasm/ | |||
7 | obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ | 7 | obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ |
8 | obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o | 8 | obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o |
9 | obj-$(CONFIG_ACER_WMI) += acer-wmi.o | 9 | obj-$(CONFIG_ACER_WMI) += acer-wmi.o |
10 | obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o | 10 | obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o |
11 | obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o | ||
11 | obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o | 12 | obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o |
12 | obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o | 13 | obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o |
13 | obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o | 14 | obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o |
diff --git a/drivers/misc/eeepc-laptop.c b/drivers/misc/eeepc-laptop.c new file mode 100644 index 000000000000..6d727609097f --- /dev/null +++ b/drivers/misc/eeepc-laptop.c | |||
@@ -0,0 +1,666 @@ | |||
1 | /* | ||
2 | * eepc-laptop.c - Asus Eee PC extras | ||
3 | * | ||
4 | * Based on asus_acpi.c as patched for the Eee PC by Asus: | ||
5 | * ftp://ftp.asus.com/pub/ASUS/EeePC/701/ASUS_ACPI_071126.rar | ||
6 | * Based on eee.c from eeepc-linux | ||
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 | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/types.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/backlight.h> | ||
25 | #include <linux/fb.h> | ||
26 | #include <linux/hwmon.h> | ||
27 | #include <linux/hwmon-sysfs.h> | ||
28 | #include <acpi/acpi_drivers.h> | ||
29 | #include <acpi/acpi_bus.h> | ||
30 | #include <linux/uaccess.h> | ||
31 | |||
32 | #define EEEPC_LAPTOP_VERSION "0.1" | ||
33 | |||
34 | #define EEEPC_HOTK_NAME "Eee PC Hotkey Driver" | ||
35 | #define EEEPC_HOTK_FILE "eeepc" | ||
36 | #define EEEPC_HOTK_CLASS "hotkey" | ||
37 | #define EEEPC_HOTK_DEVICE_NAME "Hotkey" | ||
38 | #define EEEPC_HOTK_HID "ASUS010" | ||
39 | |||
40 | #define EEEPC_LOG EEEPC_HOTK_FILE ": " | ||
41 | #define EEEPC_ERR KERN_ERR EEEPC_LOG | ||
42 | #define EEEPC_WARNING KERN_WARNING EEEPC_LOG | ||
43 | #define EEEPC_NOTICE KERN_NOTICE EEEPC_LOG | ||
44 | #define EEEPC_INFO KERN_INFO EEEPC_LOG | ||
45 | |||
46 | /* | ||
47 | * Definitions for Asus EeePC | ||
48 | */ | ||
49 | #define NOTIFY_WLAN_ON 0x10 | ||
50 | #define NOTIFY_BRN_MIN 0x20 | ||
51 | #define NOTIFY_BRN_MAX 0x2f | ||
52 | |||
53 | enum { | ||
54 | DISABLE_ASL_WLAN = 0x0001, | ||
55 | DISABLE_ASL_BLUETOOTH = 0x0002, | ||
56 | DISABLE_ASL_IRDA = 0x0004, | ||
57 | DISABLE_ASL_CAMERA = 0x0008, | ||
58 | DISABLE_ASL_TV = 0x0010, | ||
59 | DISABLE_ASL_GPS = 0x0020, | ||
60 | DISABLE_ASL_DISPLAYSWITCH = 0x0040, | ||
61 | DISABLE_ASL_MODEM = 0x0080, | ||
62 | DISABLE_ASL_CARDREADER = 0x0100 | ||
63 | }; | ||
64 | |||
65 | enum { | ||
66 | CM_ASL_WLAN = 0, | ||
67 | CM_ASL_BLUETOOTH, | ||
68 | CM_ASL_IRDA, | ||
69 | CM_ASL_1394, | ||
70 | CM_ASL_CAMERA, | ||
71 | CM_ASL_TV, | ||
72 | CM_ASL_GPS, | ||
73 | CM_ASL_DVDROM, | ||
74 | CM_ASL_DISPLAYSWITCH, | ||
75 | CM_ASL_PANELBRIGHT, | ||
76 | CM_ASL_BIOSFLASH, | ||
77 | CM_ASL_ACPIFLASH, | ||
78 | CM_ASL_CPUFV, | ||
79 | CM_ASL_CPUTEMPERATURE, | ||
80 | CM_ASL_FANCPU, | ||
81 | CM_ASL_FANCHASSIS, | ||
82 | CM_ASL_USBPORT1, | ||
83 | CM_ASL_USBPORT2, | ||
84 | CM_ASL_USBPORT3, | ||
85 | CM_ASL_MODEM, | ||
86 | CM_ASL_CARDREADER, | ||
87 | CM_ASL_LID | ||
88 | }; | ||
89 | |||
90 | const char *cm_getv[] = { | ||
91 | "WLDG", NULL, NULL, NULL, | ||
92 | "CAMG", NULL, NULL, NULL, | ||
93 | NULL, "PBLG", NULL, NULL, | ||
94 | "CFVG", NULL, NULL, NULL, | ||
95 | "USBG", NULL, NULL, "MODG", | ||
96 | "CRDG", "LIDG" | ||
97 | }; | ||
98 | |||
99 | const char *cm_setv[] = { | ||
100 | "WLDS", NULL, NULL, NULL, | ||
101 | "CAMS", NULL, NULL, NULL, | ||
102 | "SDSP", "PBLS", "HDPS", NULL, | ||
103 | "CFVS", NULL, NULL, NULL, | ||
104 | "USBG", NULL, NULL, "MODS", | ||
105 | "CRDS", NULL | ||
106 | }; | ||
107 | |||
108 | #define EEEPC_EC "\\_SB.PCI0.SBRG.EC0." | ||
109 | |||
110 | #define EEEPC_EC_FAN_PWM EEEPC_EC "SC02" /* Fan PWM duty cycle (%) */ | ||
111 | #define EEEPC_EC_SC02 0x63 | ||
112 | #define EEEPC_EC_FAN_HRPM EEEPC_EC "SC05" /* High byte, fan speed (RPM) */ | ||
113 | #define EEEPC_EC_FAN_LRPM EEEPC_EC "SC06" /* Low byte, fan speed (RPM) */ | ||
114 | #define EEEPC_EC_FAN_CTRL EEEPC_EC "SFB3" /* Byte containing SF25 */ | ||
115 | #define EEEPC_EC_SFB3 0xD3 | ||
116 | |||
117 | /* | ||
118 | * This is the main structure, we can use it to store useful information | ||
119 | * about the hotk device | ||
120 | */ | ||
121 | struct eeepc_hotk { | ||
122 | struct acpi_device *device; /* the device we are in */ | ||
123 | acpi_handle handle; /* the handle of the hotk device */ | ||
124 | u32 cm_supported; /* the control methods supported | ||
125 | by this BIOS */ | ||
126 | uint init_flag; /* Init flags */ | ||
127 | u16 event_count[128]; /* count for each event */ | ||
128 | }; | ||
129 | |||
130 | /* The actual device the driver binds to */ | ||
131 | static struct eeepc_hotk *ehotk; | ||
132 | |||
133 | /* Platform device/driver */ | ||
134 | static struct platform_driver platform_driver = { | ||
135 | .driver = { | ||
136 | .name = EEEPC_HOTK_FILE, | ||
137 | .owner = THIS_MODULE, | ||
138 | } | ||
139 | }; | ||
140 | |||
141 | static struct platform_device *platform_device; | ||
142 | |||
143 | /* | ||
144 | * The hotkey driver declaration | ||
145 | */ | ||
146 | static int eeepc_hotk_add(struct acpi_device *device); | ||
147 | static int eeepc_hotk_remove(struct acpi_device *device, int type); | ||
148 | |||
149 | static const struct acpi_device_id eeepc_device_ids[] = { | ||
150 | {EEEPC_HOTK_HID, 0}, | ||
151 | {"", 0}, | ||
152 | }; | ||
153 | MODULE_DEVICE_TABLE(acpi, eeepc_device_ids); | ||
154 | |||
155 | static struct acpi_driver eeepc_hotk_driver = { | ||
156 | .name = EEEPC_HOTK_NAME, | ||
157 | .class = EEEPC_HOTK_CLASS, | ||
158 | .ids = eeepc_device_ids, | ||
159 | .ops = { | ||
160 | .add = eeepc_hotk_add, | ||
161 | .remove = eeepc_hotk_remove, | ||
162 | }, | ||
163 | }; | ||
164 | |||
165 | /* The backlight device /sys/class/backlight */ | ||
166 | static struct backlight_device *eeepc_backlight_device; | ||
167 | |||
168 | /* The hwmon device */ | ||
169 | static struct device *eeepc_hwmon_device; | ||
170 | |||
171 | /* | ||
172 | * The backlight class declaration | ||
173 | */ | ||
174 | static int read_brightness(struct backlight_device *bd); | ||
175 | static int update_bl_status(struct backlight_device *bd); | ||
176 | static struct backlight_ops eeepcbl_ops = { | ||
177 | .get_brightness = read_brightness, | ||
178 | .update_status = update_bl_status, | ||
179 | }; | ||
180 | |||
181 | MODULE_AUTHOR("Corentin Chary, Eric Cooper"); | ||
182 | MODULE_DESCRIPTION(EEEPC_HOTK_NAME); | ||
183 | MODULE_LICENSE("GPL"); | ||
184 | |||
185 | /* | ||
186 | * ACPI Helpers | ||
187 | */ | ||
188 | static int write_acpi_int(acpi_handle handle, const char *method, int val, | ||
189 | struct acpi_buffer *output) | ||
190 | { | ||
191 | struct acpi_object_list params; | ||
192 | union acpi_object in_obj; | ||
193 | acpi_status status; | ||
194 | |||
195 | params.count = 1; | ||
196 | params.pointer = &in_obj; | ||
197 | in_obj.type = ACPI_TYPE_INTEGER; | ||
198 | in_obj.integer.value = val; | ||
199 | |||
200 | status = acpi_evaluate_object(handle, (char *)method, ¶ms, output); | ||
201 | return (status == AE_OK ? 0 : -1); | ||
202 | } | ||
203 | |||
204 | static int read_acpi_int(acpi_handle handle, const char *method, int *val) | ||
205 | { | ||
206 | acpi_status status; | ||
207 | ulong result; | ||
208 | |||
209 | status = acpi_evaluate_integer(handle, (char *)method, NULL, &result); | ||
210 | if (ACPI_FAILURE(status)) { | ||
211 | *val = -1; | ||
212 | return -1; | ||
213 | } else { | ||
214 | *val = result; | ||
215 | return 0; | ||
216 | } | ||
217 | } | ||
218 | |||
219 | static int set_acpi(int cm, int value) | ||
220 | { | ||
221 | if (ehotk->cm_supported & (0x1 << cm)) { | ||
222 | const char *method = cm_setv[cm]; | ||
223 | if (method == NULL) | ||
224 | return -ENODEV; | ||
225 | if (write_acpi_int(ehotk->handle, method, value, NULL)) | ||
226 | printk(EEEPC_WARNING "Error writing %s\n", method); | ||
227 | } | ||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static int get_acpi(int cm) | ||
232 | { | ||
233 | int value = -1; | ||
234 | if ((ehotk->cm_supported & (0x1 << cm))) { | ||
235 | const char *method = cm_getv[cm]; | ||
236 | if (method == NULL) | ||
237 | return -ENODEV; | ||
238 | if (read_acpi_int(ehotk->handle, method, &value)) | ||
239 | printk(EEEPC_WARNING "Error reading %s\n", method); | ||
240 | } | ||
241 | return value; | ||
242 | } | ||
243 | |||
244 | /* | ||
245 | * Backlight | ||
246 | */ | ||
247 | static int read_brightness(struct backlight_device *bd) | ||
248 | { | ||
249 | return get_acpi(CM_ASL_PANELBRIGHT); | ||
250 | } | ||
251 | |||
252 | static int set_brightness(struct backlight_device *bd, int value) | ||
253 | { | ||
254 | value = max(0, min(15, value)); | ||
255 | return set_acpi(CM_ASL_PANELBRIGHT, value); | ||
256 | } | ||
257 | |||
258 | static int update_bl_status(struct backlight_device *bd) | ||
259 | { | ||
260 | return set_brightness(bd, bd->props.brightness); | ||
261 | } | ||
262 | |||
263 | /* | ||
264 | * Sys helpers | ||
265 | */ | ||
266 | static int parse_arg(const char *buf, unsigned long count, int *val) | ||
267 | { | ||
268 | if (!count) | ||
269 | return 0; | ||
270 | if (sscanf(buf, "%i", val) != 1) | ||
271 | return -EINVAL; | ||
272 | return count; | ||
273 | } | ||
274 | |||
275 | static ssize_t store_sys_acpi(int cm, const char *buf, size_t count) | ||
276 | { | ||
277 | int rv, value; | ||
278 | |||
279 | rv = parse_arg(buf, count, &value); | ||
280 | if (rv > 0) | ||
281 | set_acpi(cm, value); | ||
282 | return rv; | ||
283 | } | ||
284 | |||
285 | static ssize_t show_sys_acpi(int cm, char *buf) | ||
286 | { | ||
287 | return sprintf(buf, "%d\n", get_acpi(cm)); | ||
288 | } | ||
289 | |||
290 | #define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \ | ||
291 | static ssize_t show_##_name(struct device *dev, \ | ||
292 | struct device_attribute *attr, \ | ||
293 | char *buf) \ | ||
294 | { \ | ||
295 | return show_sys_acpi(_cm, buf); \ | ||
296 | } \ | ||
297 | static ssize_t store_##_name(struct device *dev, \ | ||
298 | struct device_attribute *attr, \ | ||
299 | const char *buf, size_t count) \ | ||
300 | { \ | ||
301 | return store_sys_acpi(_cm, buf, count); \ | ||
302 | } \ | ||
303 | static struct device_attribute dev_attr_##_name = { \ | ||
304 | .attr = { \ | ||
305 | .name = __stringify(_name), \ | ||
306 | .mode = 0644 }, \ | ||
307 | .show = show_##_name, \ | ||
308 | .store = store_##_name, \ | ||
309 | } | ||
310 | |||
311 | EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA); | ||
312 | EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER); | ||
313 | EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH); | ||
314 | EEEPC_CREATE_DEVICE_ATTR(wlan, CM_ASL_WLAN); | ||
315 | |||
316 | static struct attribute *platform_attributes[] = { | ||
317 | &dev_attr_camera.attr, | ||
318 | &dev_attr_cardr.attr, | ||
319 | &dev_attr_disp.attr, | ||
320 | &dev_attr_wlan.attr, | ||
321 | NULL | ||
322 | }; | ||
323 | |||
324 | static struct attribute_group platform_attribute_group = { | ||
325 | .attrs = platform_attributes | ||
326 | }; | ||
327 | |||
328 | /* | ||
329 | * Hotkey functions | ||
330 | */ | ||
331 | static int eeepc_hotk_check(void) | ||
332 | { | ||
333 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
334 | int result; | ||
335 | |||
336 | result = acpi_bus_get_status(ehotk->device); | ||
337 | if (result) | ||
338 | return result; | ||
339 | if (ehotk->device->status.present) { | ||
340 | if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag, | ||
341 | &buffer)) { | ||
342 | printk(EEEPC_ERR "Hotkey initialization failed\n"); | ||
343 | return -ENODEV; | ||
344 | } else { | ||
345 | printk(EEEPC_NOTICE "Hotkey init flags 0x%x\n", | ||
346 | ehotk->init_flag); | ||
347 | } | ||
348 | /* get control methods supported */ | ||
349 | if (read_acpi_int(ehotk->handle, "CMSG" | ||
350 | , &ehotk->cm_supported)) { | ||
351 | printk(EEEPC_ERR | ||
352 | "Get control methods supported failed\n"); | ||
353 | return -ENODEV; | ||
354 | } else { | ||
355 | printk(EEEPC_INFO | ||
356 | "Get control methods supported: 0x%x\n", | ||
357 | ehotk->cm_supported); | ||
358 | } | ||
359 | } else { | ||
360 | printk(EEEPC_ERR "Hotkey device not present, aborting\n"); | ||
361 | return -EINVAL; | ||
362 | } | ||
363 | return 0; | ||
364 | } | ||
365 | |||
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) | ||
382 | { | ||
383 | struct backlight_device *bd = eeepc_backlight_device; | ||
384 | bd->props.brightness = read_brightness(bd); | ||
385 | } | ||
386 | |||
387 | static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) | ||
388 | { | ||
389 | if (!ehotk) | ||
390 | 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) | ||
394 | notify_brn(); | ||
395 | acpi_bus_generate_proc_event(ehotk->device, event, | ||
396 | ehotk->event_count[event % 128]++); | ||
397 | } | ||
398 | |||
399 | static int eeepc_hotk_add(struct acpi_device *device) | ||
400 | { | ||
401 | acpi_status status = AE_OK; | ||
402 | int result; | ||
403 | |||
404 | if (!device) | ||
405 | return -EINVAL; | ||
406 | printk(EEEPC_NOTICE EEEPC_HOTK_NAME "\n"); | ||
407 | ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL); | ||
408 | if (!ehotk) | ||
409 | return -ENOMEM; | ||
410 | ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH; | ||
411 | ehotk->handle = device->handle; | ||
412 | strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME); | ||
413 | strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS); | ||
414 | acpi_driver_data(device) = ehotk; | ||
415 | ehotk->device = device; | ||
416 | result = eeepc_hotk_check(); | ||
417 | if (result) | ||
418 | goto end; | ||
419 | status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY, | ||
420 | eeepc_hotk_notify, ehotk); | ||
421 | if (ACPI_FAILURE(status)) | ||
422 | printk(EEEPC_ERR "Error installing notify handler\n"); | ||
423 | end: | ||
424 | if (result) { | ||
425 | kfree(ehotk); | ||
426 | ehotk = NULL; | ||
427 | } | ||
428 | return result; | ||
429 | } | ||
430 | |||
431 | static int eeepc_hotk_remove(struct acpi_device *device, int type) | ||
432 | { | ||
433 | acpi_status status = 0; | ||
434 | |||
435 | if (!device || !acpi_driver_data(device)) | ||
436 | return -EINVAL; | ||
437 | status = acpi_remove_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY, | ||
438 | eeepc_hotk_notify); | ||
439 | if (ACPI_FAILURE(status)) | ||
440 | printk(EEEPC_ERR "Error removing notify handler\n"); | ||
441 | kfree(ehotk); | ||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | /* | ||
446 | * Hwmon | ||
447 | */ | ||
448 | static int eeepc_get_fan_pwm(void) | ||
449 | { | ||
450 | int value = 0; | ||
451 | |||
452 | read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value); | ||
453 | return (value); | ||
454 | } | ||
455 | |||
456 | static void eeepc_set_fan_pwm(int value) | ||
457 | { | ||
458 | value = SENSORS_LIMIT(value, 0, 100); | ||
459 | ec_write(EEEPC_EC_SC02, value); | ||
460 | } | ||
461 | |||
462 | static int eeepc_get_fan_rpm(void) | ||
463 | { | ||
464 | int high = 0; | ||
465 | int low = 0; | ||
466 | |||
467 | read_acpi_int(NULL, EEEPC_EC_FAN_HRPM, &high); | ||
468 | read_acpi_int(NULL, EEEPC_EC_FAN_LRPM, &low); | ||
469 | return (high << 8 | low); | ||
470 | } | ||
471 | |||
472 | static int eeepc_get_fan_ctrl(void) | ||
473 | { | ||
474 | int value = 0; | ||
475 | |||
476 | read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value); | ||
477 | return ((value & 0x02 ? 1 : 0)); | ||
478 | } | ||
479 | |||
480 | static void eeepc_set_fan_ctrl(int manual) | ||
481 | { | ||
482 | int value = 0; | ||
483 | |||
484 | read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value); | ||
485 | if (manual) | ||
486 | value |= 0x02; | ||
487 | else | ||
488 | value &= ~0x02; | ||
489 | ec_write(EEEPC_EC_SFB3, value); | ||
490 | } | ||
491 | |||
492 | static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count) | ||
493 | { | ||
494 | int rv, value; | ||
495 | |||
496 | rv = parse_arg(buf, count, &value); | ||
497 | if (rv > 0) | ||
498 | set(value); | ||
499 | return rv; | ||
500 | } | ||
501 | |||
502 | static ssize_t show_sys_hwmon(int (*get)(void), char *buf) | ||
503 | { | ||
504 | return sprintf(buf, "%d\n", get()); | ||
505 | } | ||
506 | |||
507 | #define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \ | ||
508 | static ssize_t show_##_name(struct device *dev, \ | ||
509 | struct device_attribute *attr, \ | ||
510 | char *buf) \ | ||
511 | { \ | ||
512 | return show_sys_hwmon(_set, buf); \ | ||
513 | } \ | ||
514 | static ssize_t store_##_name(struct device *dev, \ | ||
515 | struct device_attribute *attr, \ | ||
516 | const char *buf, size_t count) \ | ||
517 | { \ | ||
518 | return store_sys_hwmon(_get, buf, count); \ | ||
519 | } \ | ||
520 | static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0); | ||
521 | |||
522 | EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL); | ||
523 | EEEPC_CREATE_SENSOR_ATTR(fan1_pwm, S_IRUGO | S_IWUSR, | ||
524 | eeepc_get_fan_pwm, eeepc_set_fan_pwm); | ||
525 | EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, | ||
526 | eeepc_get_fan_ctrl, eeepc_set_fan_ctrl); | ||
527 | |||
528 | static struct attribute *hwmon_attributes[] = { | ||
529 | &sensor_dev_attr_fan1_pwm.dev_attr.attr, | ||
530 | &sensor_dev_attr_fan1_input.dev_attr.attr, | ||
531 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
532 | NULL | ||
533 | }; | ||
534 | |||
535 | static struct attribute_group hwmon_attribute_group = { | ||
536 | .attrs = hwmon_attributes | ||
537 | }; | ||
538 | |||
539 | /* | ||
540 | * exit/init | ||
541 | */ | ||
542 | static void eeepc_backlight_exit(void) | ||
543 | { | ||
544 | if (eeepc_backlight_device) | ||
545 | backlight_device_unregister(eeepc_backlight_device); | ||
546 | eeepc_backlight_device = NULL; | ||
547 | } | ||
548 | |||
549 | static void eeepc_hwmon_exit(void) | ||
550 | { | ||
551 | struct device *hwmon; | ||
552 | |||
553 | hwmon = eeepc_hwmon_device; | ||
554 | if (!hwmon) | ||
555 | return ; | ||
556 | hwmon_device_unregister(hwmon); | ||
557 | sysfs_remove_group(&hwmon->kobj, | ||
558 | &hwmon_attribute_group); | ||
559 | eeepc_hwmon_device = NULL; | ||
560 | } | ||
561 | |||
562 | static void __exit eeepc_laptop_exit(void) | ||
563 | { | ||
564 | eeepc_backlight_exit(); | ||
565 | eeepc_hwmon_exit(); | ||
566 | acpi_bus_unregister_driver(&eeepc_hotk_driver); | ||
567 | sysfs_remove_group(&platform_device->dev.kobj, | ||
568 | &platform_attribute_group); | ||
569 | platform_device_unregister(platform_device); | ||
570 | platform_driver_unregister(&platform_driver); | ||
571 | } | ||
572 | |||
573 | static int eeepc_backlight_init(struct device *dev) | ||
574 | { | ||
575 | struct backlight_device *bd; | ||
576 | |||
577 | bd = backlight_device_register(EEEPC_HOTK_FILE, dev, | ||
578 | NULL, &eeepcbl_ops); | ||
579 | if (IS_ERR(bd)) { | ||
580 | printk(EEEPC_ERR | ||
581 | "Could not register eeepc backlight device\n"); | ||
582 | eeepc_backlight_device = NULL; | ||
583 | return PTR_ERR(bd); | ||
584 | } | ||
585 | eeepc_backlight_device = bd; | ||
586 | bd->props.max_brightness = 15; | ||
587 | bd->props.brightness = read_brightness(NULL); | ||
588 | bd->props.power = FB_BLANK_UNBLANK; | ||
589 | backlight_update_status(bd); | ||
590 | return 0; | ||
591 | } | ||
592 | |||
593 | static int eeepc_hwmon_init(struct device *dev) | ||
594 | { | ||
595 | struct device *hwmon; | ||
596 | int result; | ||
597 | |||
598 | hwmon = hwmon_device_register(dev); | ||
599 | if (IS_ERR(hwmon)) { | ||
600 | printk(EEEPC_ERR | ||
601 | "Could not register eeepc hwmon device\n"); | ||
602 | eeepc_hwmon_device = NULL; | ||
603 | return PTR_ERR(hwmon); | ||
604 | } | ||
605 | eeepc_hwmon_device = hwmon; | ||
606 | result = sysfs_create_group(&hwmon->kobj, | ||
607 | &hwmon_attribute_group); | ||
608 | if (result) | ||
609 | eeepc_hwmon_exit(); | ||
610 | return result; | ||
611 | } | ||
612 | |||
613 | static int __init eeepc_laptop_init(void) | ||
614 | { | ||
615 | struct device *dev; | ||
616 | int result; | ||
617 | |||
618 | if (acpi_disabled) | ||
619 | return -ENODEV; | ||
620 | result = acpi_bus_register_driver(&eeepc_hotk_driver); | ||
621 | if (result < 0) | ||
622 | return result; | ||
623 | if (!ehotk) { | ||
624 | acpi_bus_unregister_driver(&eeepc_hotk_driver); | ||
625 | return -ENODEV; | ||
626 | } | ||
627 | dev = acpi_get_physical_device(ehotk->device->handle); | ||
628 | result = eeepc_backlight_init(dev); | ||
629 | if (result) | ||
630 | goto fail_backlight; | ||
631 | result = eeepc_hwmon_init(dev); | ||
632 | if (result) | ||
633 | goto fail_hwmon; | ||
634 | /* Register platform stuff */ | ||
635 | result = platform_driver_register(&platform_driver); | ||
636 | if (result) | ||
637 | goto fail_platform_driver; | ||
638 | platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1); | ||
639 | if (!platform_device) { | ||
640 | result = -ENOMEM; | ||
641 | goto fail_platform_device1; | ||
642 | } | ||
643 | result = platform_device_add(platform_device); | ||
644 | if (result) | ||
645 | goto fail_platform_device2; | ||
646 | result = sysfs_create_group(&platform_device->dev.kobj, | ||
647 | &platform_attribute_group); | ||
648 | if (result) | ||
649 | goto fail_sysfs; | ||
650 | return 0; | ||
651 | fail_sysfs: | ||
652 | platform_device_del(platform_device); | ||
653 | fail_platform_device2: | ||
654 | platform_device_put(platform_device); | ||
655 | fail_platform_device1: | ||
656 | platform_driver_unregister(&platform_driver); | ||
657 | fail_platform_driver: | ||
658 | eeepc_hwmon_exit(); | ||
659 | fail_hwmon: | ||
660 | eeepc_backlight_exit(); | ||
661 | fail_backlight: | ||
662 | return result; | ||
663 | } | ||
664 | |||
665 | module_init(eeepc_laptop_init); | ||
666 | module_exit(eeepc_laptop_exit); | ||
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 6cb781262f94..3f28f6eabdbf 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c | |||
@@ -21,7 +21,7 @@ | |||
21 | * 02110-1301, USA. | 21 | * 02110-1301, USA. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #define TPACPI_VERSION "0.19" | 24 | #define TPACPI_VERSION "0.20" |
25 | #define TPACPI_SYSFS_VERSION 0x020200 | 25 | #define TPACPI_SYSFS_VERSION 0x020200 |
26 | 26 | ||
27 | /* | 27 | /* |
@@ -67,6 +67,7 @@ | |||
67 | #include <linux/hwmon.h> | 67 | #include <linux/hwmon.h> |
68 | #include <linux/hwmon-sysfs.h> | 68 | #include <linux/hwmon-sysfs.h> |
69 | #include <linux/input.h> | 69 | #include <linux/input.h> |
70 | #include <linux/leds.h> | ||
70 | #include <asm/uaccess.h> | 71 | #include <asm/uaccess.h> |
71 | 72 | ||
72 | #include <linux/dmi.h> | 73 | #include <linux/dmi.h> |
@@ -85,6 +86,8 @@ | |||
85 | #define TP_CMOS_VOLUME_MUTE 2 | 86 | #define TP_CMOS_VOLUME_MUTE 2 |
86 | #define TP_CMOS_BRIGHTNESS_UP 4 | 87 | #define TP_CMOS_BRIGHTNESS_UP 4 |
87 | #define TP_CMOS_BRIGHTNESS_DOWN 5 | 88 | #define TP_CMOS_BRIGHTNESS_DOWN 5 |
89 | #define TP_CMOS_THINKLIGHT_ON 12 | ||
90 | #define TP_CMOS_THINKLIGHT_OFF 13 | ||
88 | 91 | ||
89 | /* NVRAM Addresses */ | 92 | /* NVRAM Addresses */ |
90 | enum tp_nvram_addr { | 93 | enum tp_nvram_addr { |
@@ -133,8 +136,12 @@ enum { | |||
133 | #define TPACPI_PROC_DIR "ibm" | 136 | #define TPACPI_PROC_DIR "ibm" |
134 | #define TPACPI_ACPI_EVENT_PREFIX "ibm" | 137 | #define TPACPI_ACPI_EVENT_PREFIX "ibm" |
135 | #define TPACPI_DRVR_NAME TPACPI_FILE | 138 | #define TPACPI_DRVR_NAME TPACPI_FILE |
139 | #define TPACPI_DRVR_SHORTNAME "tpacpi" | ||
136 | #define TPACPI_HWMON_DRVR_NAME TPACPI_NAME "_hwmon" | 140 | #define TPACPI_HWMON_DRVR_NAME TPACPI_NAME "_hwmon" |
137 | 141 | ||
142 | #define TPACPI_NVRAM_KTHREAD_NAME "ktpacpi_nvramd" | ||
143 | #define TPACPI_WORKQUEUE_NAME "ktpacpid" | ||
144 | |||
138 | #define TPACPI_MAX_ACPI_ARGS 3 | 145 | #define TPACPI_MAX_ACPI_ARGS 3 |
139 | 146 | ||
140 | /* Debugging */ | 147 | /* Debugging */ |
@@ -225,6 +232,7 @@ static struct { | |||
225 | u32 light:1; | 232 | u32 light:1; |
226 | u32 light_status:1; | 233 | u32 light_status:1; |
227 | u32 bright_16levels:1; | 234 | u32 bright_16levels:1; |
235 | u32 bright_acpimode:1; | ||
228 | u32 wan:1; | 236 | u32 wan:1; |
229 | u32 fan_ctrl_status_undef:1; | 237 | u32 fan_ctrl_status_undef:1; |
230 | u32 input_device_registered:1; | 238 | u32 input_device_registered:1; |
@@ -236,6 +244,11 @@ static struct { | |||
236 | u32 hotkey_poll_active:1; | 244 | u32 hotkey_poll_active:1; |
237 | } tp_features; | 245 | } tp_features; |
238 | 246 | ||
247 | static struct { | ||
248 | u16 hotkey_mask_ff:1; | ||
249 | u16 bright_cmos_ec_unsync:1; | ||
250 | } tp_warned; | ||
251 | |||
239 | struct thinkpad_id_data { | 252 | struct thinkpad_id_data { |
240 | unsigned int vendor; /* ThinkPad vendor: | 253 | unsigned int vendor; /* ThinkPad vendor: |
241 | * PCI_VENDOR_ID_IBM/PCI_VENDOR_ID_LENOVO */ | 254 | * PCI_VENDOR_ID_IBM/PCI_VENDOR_ID_LENOVO */ |
@@ -246,7 +259,8 @@ struct thinkpad_id_data { | |||
246 | u16 bios_model; /* Big Endian, TP-1Y = 0x5931, 0 = unknown */ | 259 | u16 bios_model; /* Big Endian, TP-1Y = 0x5931, 0 = unknown */ |
247 | u16 ec_model; | 260 | u16 ec_model; |
248 | 261 | ||
249 | char *model_str; | 262 | char *model_str; /* ThinkPad T43 */ |
263 | char *nummodel_str; /* 9384A9C for a 9384-A9C model */ | ||
250 | }; | 264 | }; |
251 | static struct thinkpad_id_data thinkpad_id; | 265 | static struct thinkpad_id_data thinkpad_id; |
252 | 266 | ||
@@ -259,6 +273,16 @@ static enum { | |||
259 | static int experimental; | 273 | static int experimental; |
260 | static u32 dbg_level; | 274 | static u32 dbg_level; |
261 | 275 | ||
276 | static struct workqueue_struct *tpacpi_wq; | ||
277 | |||
278 | /* Special LED class that can defer work */ | ||
279 | struct tpacpi_led_classdev { | ||
280 | struct led_classdev led_classdev; | ||
281 | struct work_struct work; | ||
282 | enum led_brightness new_brightness; | ||
283 | unsigned int led; | ||
284 | }; | ||
285 | |||
262 | /**************************************************************************** | 286 | /**************************************************************************** |
263 | **************************************************************************** | 287 | **************************************************************************** |
264 | * | 288 | * |
@@ -807,6 +831,80 @@ static int parse_strtoul(const char *buf, | |||
807 | return 0; | 831 | return 0; |
808 | } | 832 | } |
809 | 833 | ||
834 | static int __init tpacpi_query_bcl_levels(acpi_handle handle) | ||
835 | { | ||
836 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
837 | union acpi_object *obj; | ||
838 | int rc; | ||
839 | |||
840 | if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) { | ||
841 | obj = (union acpi_object *)buffer.pointer; | ||
842 | if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { | ||
843 | printk(TPACPI_ERR "Unknown _BCL data, " | ||
844 | "please report this to %s\n", TPACPI_MAIL); | ||
845 | rc = 0; | ||
846 | } else { | ||
847 | rc = obj->package.count; | ||
848 | } | ||
849 | } else { | ||
850 | return 0; | ||
851 | } | ||
852 | |||
853 | kfree(buffer.pointer); | ||
854 | return rc; | ||
855 | } | ||
856 | |||
857 | static acpi_status __init tpacpi_acpi_walk_find_bcl(acpi_handle handle, | ||
858 | u32 lvl, void *context, void **rv) | ||
859 | { | ||
860 | char name[ACPI_PATH_SEGMENT_LENGTH]; | ||
861 | struct acpi_buffer buffer = { sizeof(name), &name }; | ||
862 | |||
863 | if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) && | ||
864 | !strncmp("_BCL", name, sizeof(name) - 1)) { | ||
865 | BUG_ON(!rv || !*rv); | ||
866 | **(int **)rv = tpacpi_query_bcl_levels(handle); | ||
867 | return AE_CTRL_TERMINATE; | ||
868 | } else { | ||
869 | return AE_OK; | ||
870 | } | ||
871 | } | ||
872 | |||
873 | /* | ||
874 | * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map | ||
875 | */ | ||
876 | static int __init tpacpi_check_std_acpi_brightness_support(void) | ||
877 | { | ||
878 | int status; | ||
879 | int bcl_levels = 0; | ||
880 | void *bcl_ptr = &bcl_levels; | ||
881 | |||
882 | if (!vid_handle) { | ||
883 | TPACPI_ACPIHANDLE_INIT(vid); | ||
884 | } | ||
885 | if (!vid_handle) | ||
886 | return 0; | ||
887 | |||
888 | /* | ||
889 | * Search for a _BCL method, and execute it. This is safe on all | ||
890 | * ThinkPads, and as a side-effect, _BCL will place a Lenovo Vista | ||
891 | * BIOS in ACPI backlight control mode. We do NOT have to care | ||
892 | * about calling the _BCL method in an enabled video device, any | ||
893 | * will do for our purposes. | ||
894 | */ | ||
895 | |||
896 | status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3, | ||
897 | tpacpi_acpi_walk_find_bcl, NULL, | ||
898 | &bcl_ptr); | ||
899 | |||
900 | if (ACPI_SUCCESS(status) && bcl_levels > 2) { | ||
901 | tp_features.bright_acpimode = 1; | ||
902 | return (bcl_levels - 2); | ||
903 | } | ||
904 | |||
905 | return 0; | ||
906 | } | ||
907 | |||
810 | /************************************************************************* | 908 | /************************************************************************* |
811 | * thinkpad-acpi driver attributes | 909 | * thinkpad-acpi driver attributes |
812 | */ | 910 | */ |
@@ -909,12 +1007,14 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm) | |||
909 | thinkpad_id.ec_version_str : "unknown"); | 1007 | thinkpad_id.ec_version_str : "unknown"); |
910 | 1008 | ||
911 | if (thinkpad_id.vendor && thinkpad_id.model_str) | 1009 | if (thinkpad_id.vendor && thinkpad_id.model_str) |
912 | printk(TPACPI_INFO "%s %s\n", | 1010 | printk(TPACPI_INFO "%s %s, model %s\n", |
913 | (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ? | 1011 | (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ? |
914 | "IBM" : ((thinkpad_id.vendor == | 1012 | "IBM" : ((thinkpad_id.vendor == |
915 | PCI_VENDOR_ID_LENOVO) ? | 1013 | PCI_VENDOR_ID_LENOVO) ? |
916 | "Lenovo" : "Unknown vendor"), | 1014 | "Lenovo" : "Unknown vendor"), |
917 | thinkpad_id.model_str); | 1015 | thinkpad_id.model_str, |
1016 | (thinkpad_id.nummodel_str) ? | ||
1017 | thinkpad_id.nummodel_str : "unknown"); | ||
918 | 1018 | ||
919 | return 0; | 1019 | return 0; |
920 | } | 1020 | } |
@@ -1107,6 +1207,19 @@ static int hotkey_mask_set(u32 mask) | |||
1107 | int rc = 0; | 1207 | int rc = 0; |
1108 | 1208 | ||
1109 | if (tp_features.hotkey_mask) { | 1209 | if (tp_features.hotkey_mask) { |
1210 | if (!tp_warned.hotkey_mask_ff && | ||
1211 | (mask == 0xffff || mask == 0xffffff || | ||
1212 | mask == 0xffffffff)) { | ||
1213 | tp_warned.hotkey_mask_ff = 1; | ||
1214 | printk(TPACPI_NOTICE | ||
1215 | "setting the hotkey mask to 0x%08x is likely " | ||
1216 | "not the best way to go about it\n", mask); | ||
1217 | printk(TPACPI_NOTICE | ||
1218 | "please consider using the driver defaults, " | ||
1219 | "and refer to up-to-date thinkpad-acpi " | ||
1220 | "documentation\n"); | ||
1221 | } | ||
1222 | |||
1110 | HOTKEY_CONFIG_CRITICAL_START | 1223 | HOTKEY_CONFIG_CRITICAL_START |
1111 | for (i = 0; i < 32; i++) { | 1224 | for (i = 0; i < 32; i++) { |
1112 | u32 m = 1 << i; | 1225 | u32 m = 1 << i; |
@@ -1427,8 +1540,7 @@ static void hotkey_poll_setup(int may_warn) | |||
1427 | (tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) { | 1540 | (tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) { |
1428 | if (!tpacpi_hotkey_task) { | 1541 | if (!tpacpi_hotkey_task) { |
1429 | tpacpi_hotkey_task = kthread_run(hotkey_kthread, | 1542 | tpacpi_hotkey_task = kthread_run(hotkey_kthread, |
1430 | NULL, | 1543 | NULL, TPACPI_NVRAM_KTHREAD_NAME); |
1431 | TPACPI_FILE "d"); | ||
1432 | if (IS_ERR(tpacpi_hotkey_task)) { | 1544 | if (IS_ERR(tpacpi_hotkey_task)) { |
1433 | tpacpi_hotkey_task = NULL; | 1545 | tpacpi_hotkey_task = NULL; |
1434 | printk(TPACPI_ERR | 1546 | printk(TPACPI_ERR |
@@ -1887,6 +1999,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
1887 | KEY_UNKNOWN, /* 0x0D: FN+INSERT */ | 1999 | KEY_UNKNOWN, /* 0x0D: FN+INSERT */ |
1888 | KEY_UNKNOWN, /* 0x0E: FN+DELETE */ | 2000 | KEY_UNKNOWN, /* 0x0E: FN+DELETE */ |
1889 | 2001 | ||
2002 | /* These either have to go through ACPI video, or | ||
2003 | * act like in the IBM ThinkPads, so don't ever | ||
2004 | * enable them by default */ | ||
1890 | KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ | 2005 | KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ |
1891 | KEY_RESERVED, /* 0x10: FN+END (brightness down) */ | 2006 | KEY_RESERVED, /* 0x10: FN+END (brightness down) */ |
1892 | 2007 | ||
@@ -2091,6 +2206,32 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
2091 | set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit); | 2206 | set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit); |
2092 | } | 2207 | } |
2093 | 2208 | ||
2209 | /* Do not issue duplicate brightness change events to | ||
2210 | * userspace */ | ||
2211 | if (!tp_features.bright_acpimode) | ||
2212 | /* update bright_acpimode... */ | ||
2213 | tpacpi_check_std_acpi_brightness_support(); | ||
2214 | |||
2215 | if (tp_features.bright_acpimode) { | ||
2216 | printk(TPACPI_INFO | ||
2217 | "This ThinkPad has standard ACPI backlight " | ||
2218 | "brightness control, supported by the ACPI " | ||
2219 | "video driver\n"); | ||
2220 | printk(TPACPI_NOTICE | ||
2221 | "Disabling thinkpad-acpi brightness events " | ||
2222 | "by default...\n"); | ||
2223 | |||
2224 | /* The hotkey_reserved_mask change below is not | ||
2225 | * necessary while the keys are at KEY_RESERVED in the | ||
2226 | * default map, but better safe than sorry, leave it | ||
2227 | * here as a marker of what we have to do, especially | ||
2228 | * when we finally become able to set this at runtime | ||
2229 | * on response to X.org requests */ | ||
2230 | hotkey_reserved_mask |= | ||
2231 | (1 << TP_ACPI_HOTKEYSCAN_FNHOME) | ||
2232 | | (1 << TP_ACPI_HOTKEYSCAN_FNEND); | ||
2233 | } | ||
2234 | |||
2094 | dbg_printk(TPACPI_DBG_INIT, | 2235 | dbg_printk(TPACPI_DBG_INIT, |
2095 | "enabling hot key handling\n"); | 2236 | "enabling hot key handling\n"); |
2096 | res = hotkey_status_set(1); | 2237 | res = hotkey_status_set(1); |
@@ -3110,13 +3251,82 @@ static struct ibm_struct video_driver_data = { | |||
3110 | TPACPI_HANDLE(lght, root, "\\LGHT"); /* A21e, A2xm/p, T20-22, X20-21 */ | 3251 | TPACPI_HANDLE(lght, root, "\\LGHT"); /* A21e, A2xm/p, T20-22, X20-21 */ |
3111 | TPACPI_HANDLE(ledb, ec, "LEDB"); /* G4x */ | 3252 | TPACPI_HANDLE(ledb, ec, "LEDB"); /* G4x */ |
3112 | 3253 | ||
3254 | static int light_get_status(void) | ||
3255 | { | ||
3256 | int status = 0; | ||
3257 | |||
3258 | if (tp_features.light_status) { | ||
3259 | if (!acpi_evalf(ec_handle, &status, "KBLT", "d")) | ||
3260 | return -EIO; | ||
3261 | return (!!status); | ||
3262 | } | ||
3263 | |||
3264 | return -ENXIO; | ||
3265 | } | ||
3266 | |||
3267 | static int light_set_status(int status) | ||
3268 | { | ||
3269 | int rc; | ||
3270 | |||
3271 | if (tp_features.light) { | ||
3272 | if (cmos_handle) { | ||
3273 | rc = acpi_evalf(cmos_handle, NULL, NULL, "vd", | ||
3274 | (status)? | ||
3275 | TP_CMOS_THINKLIGHT_ON : | ||
3276 | TP_CMOS_THINKLIGHT_OFF); | ||
3277 | } else { | ||
3278 | rc = acpi_evalf(lght_handle, NULL, NULL, "vd", | ||
3279 | (status)? 1 : 0); | ||
3280 | } | ||
3281 | return (rc)? 0 : -EIO; | ||
3282 | } | ||
3283 | |||
3284 | return -ENXIO; | ||
3285 | } | ||
3286 | |||
3287 | static void light_set_status_worker(struct work_struct *work) | ||
3288 | { | ||
3289 | struct tpacpi_led_classdev *data = | ||
3290 | container_of(work, struct tpacpi_led_classdev, work); | ||
3291 | |||
3292 | if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) | ||
3293 | light_set_status((data->new_brightness != LED_OFF)); | ||
3294 | } | ||
3295 | |||
3296 | static void light_sysfs_set(struct led_classdev *led_cdev, | ||
3297 | enum led_brightness brightness) | ||
3298 | { | ||
3299 | struct tpacpi_led_classdev *data = | ||
3300 | container_of(led_cdev, | ||
3301 | struct tpacpi_led_classdev, | ||
3302 | led_classdev); | ||
3303 | data->new_brightness = brightness; | ||
3304 | queue_work(tpacpi_wq, &data->work); | ||
3305 | } | ||
3306 | |||
3307 | static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev) | ||
3308 | { | ||
3309 | return (light_get_status() == 1)? LED_FULL : LED_OFF; | ||
3310 | } | ||
3311 | |||
3312 | static struct tpacpi_led_classdev tpacpi_led_thinklight = { | ||
3313 | .led_classdev = { | ||
3314 | .name = "tpacpi::thinklight", | ||
3315 | .brightness_set = &light_sysfs_set, | ||
3316 | .brightness_get = &light_sysfs_get, | ||
3317 | } | ||
3318 | }; | ||
3319 | |||
3113 | static int __init light_init(struct ibm_init_struct *iibm) | 3320 | static int __init light_init(struct ibm_init_struct *iibm) |
3114 | { | 3321 | { |
3322 | int rc = 0; | ||
3323 | |||
3115 | vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n"); | 3324 | vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n"); |
3116 | 3325 | ||
3117 | TPACPI_ACPIHANDLE_INIT(ledb); | 3326 | TPACPI_ACPIHANDLE_INIT(ledb); |
3118 | TPACPI_ACPIHANDLE_INIT(lght); | 3327 | TPACPI_ACPIHANDLE_INIT(lght); |
3119 | TPACPI_ACPIHANDLE_INIT(cmos); | 3328 | TPACPI_ACPIHANDLE_INIT(cmos); |
3329 | INIT_WORK(&tpacpi_led_thinklight.work, light_set_status_worker); | ||
3120 | 3330 | ||
3121 | /* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */ | 3331 | /* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */ |
3122 | tp_features.light = (cmos_handle || lght_handle) && !ledb_handle; | 3332 | tp_features.light = (cmos_handle || lght_handle) && !ledb_handle; |
@@ -3130,13 +3340,31 @@ static int __init light_init(struct ibm_init_struct *iibm) | |||
3130 | vdbg_printk(TPACPI_DBG_INIT, "light is %s\n", | 3340 | vdbg_printk(TPACPI_DBG_INIT, "light is %s\n", |
3131 | str_supported(tp_features.light)); | 3341 | str_supported(tp_features.light)); |
3132 | 3342 | ||
3133 | return (tp_features.light)? 0 : 1; | 3343 | if (tp_features.light) { |
3344 | rc = led_classdev_register(&tpacpi_pdev->dev, | ||
3345 | &tpacpi_led_thinklight.led_classdev); | ||
3346 | } | ||
3347 | |||
3348 | if (rc < 0) { | ||
3349 | tp_features.light = 0; | ||
3350 | tp_features.light_status = 0; | ||
3351 | } else { | ||
3352 | rc = (tp_features.light)? 0 : 1; | ||
3353 | } | ||
3354 | return rc; | ||
3355 | } | ||
3356 | |||
3357 | static void light_exit(void) | ||
3358 | { | ||
3359 | led_classdev_unregister(&tpacpi_led_thinklight.led_classdev); | ||
3360 | if (work_pending(&tpacpi_led_thinklight.work)) | ||
3361 | flush_workqueue(tpacpi_wq); | ||
3134 | } | 3362 | } |
3135 | 3363 | ||
3136 | static int light_read(char *p) | 3364 | static int light_read(char *p) |
3137 | { | 3365 | { |
3138 | int len = 0; | 3366 | int len = 0; |
3139 | int status = 0; | 3367 | int status; |
3140 | 3368 | ||
3141 | if (!tp_features.light) { | 3369 | if (!tp_features.light) { |
3142 | len += sprintf(p + len, "status:\t\tnot supported\n"); | 3370 | len += sprintf(p + len, "status:\t\tnot supported\n"); |
@@ -3144,8 +3372,9 @@ static int light_read(char *p) | |||
3144 | len += sprintf(p + len, "status:\t\tunknown\n"); | 3372 | len += sprintf(p + len, "status:\t\tunknown\n"); |
3145 | len += sprintf(p + len, "commands:\ton, off\n"); | 3373 | len += sprintf(p + len, "commands:\ton, off\n"); |
3146 | } else { | 3374 | } else { |
3147 | if (!acpi_evalf(ec_handle, &status, "KBLT", "d")) | 3375 | status = light_get_status(); |
3148 | return -EIO; | 3376 | if (status < 0) |
3377 | return status; | ||
3149 | len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0)); | 3378 | len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0)); |
3150 | len += sprintf(p + len, "commands:\ton, off\n"); | 3379 | len += sprintf(p + len, "commands:\ton, off\n"); |
3151 | } | 3380 | } |
@@ -3155,37 +3384,29 @@ static int light_read(char *p) | |||
3155 | 3384 | ||
3156 | static int light_write(char *buf) | 3385 | static int light_write(char *buf) |
3157 | { | 3386 | { |
3158 | int cmos_cmd, lght_cmd; | ||
3159 | char *cmd; | 3387 | char *cmd; |
3160 | int success; | 3388 | int newstatus = 0; |
3161 | 3389 | ||
3162 | if (!tp_features.light) | 3390 | if (!tp_features.light) |
3163 | return -ENODEV; | 3391 | return -ENODEV; |
3164 | 3392 | ||
3165 | while ((cmd = next_cmd(&buf))) { | 3393 | while ((cmd = next_cmd(&buf))) { |
3166 | if (strlencmp(cmd, "on") == 0) { | 3394 | if (strlencmp(cmd, "on") == 0) { |
3167 | cmos_cmd = 0x0c; | 3395 | newstatus = 1; |
3168 | lght_cmd = 1; | ||
3169 | } else if (strlencmp(cmd, "off") == 0) { | 3396 | } else if (strlencmp(cmd, "off") == 0) { |
3170 | cmos_cmd = 0x0d; | 3397 | newstatus = 0; |
3171 | lght_cmd = 0; | ||
3172 | } else | 3398 | } else |
3173 | return -EINVAL; | 3399 | return -EINVAL; |
3174 | |||
3175 | success = cmos_handle ? | ||
3176 | acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd) : | ||
3177 | acpi_evalf(lght_handle, NULL, NULL, "vd", lght_cmd); | ||
3178 | if (!success) | ||
3179 | return -EIO; | ||
3180 | } | 3400 | } |
3181 | 3401 | ||
3182 | return 0; | 3402 | return light_set_status(newstatus); |
3183 | } | 3403 | } |
3184 | 3404 | ||
3185 | static struct ibm_struct light_driver_data = { | 3405 | static struct ibm_struct light_driver_data = { |
3186 | .name = "light", | 3406 | .name = "light", |
3187 | .read = light_read, | 3407 | .read = light_read, |
3188 | .write = light_write, | 3408 | .write = light_write, |
3409 | .exit = light_exit, | ||
3189 | }; | 3410 | }; |
3190 | 3411 | ||
3191 | /************************************************************************* | 3412 | /************************************************************************* |
@@ -3583,6 +3804,12 @@ enum { /* For TPACPI_LED_OLD */ | |||
3583 | TPACPI_LED_EC_HLMS = 0x0e, /* EC reg to select led to command */ | 3804 | TPACPI_LED_EC_HLMS = 0x0e, /* EC reg to select led to command */ |
3584 | }; | 3805 | }; |
3585 | 3806 | ||
3807 | enum led_status_t { | ||
3808 | TPACPI_LED_OFF = 0, | ||
3809 | TPACPI_LED_ON, | ||
3810 | TPACPI_LED_BLINK, | ||
3811 | }; | ||
3812 | |||
3586 | static enum led_access_mode led_supported; | 3813 | static enum led_access_mode led_supported; |
3587 | 3814 | ||
3588 | TPACPI_HANDLE(led, ec, "SLED", /* 570 */ | 3815 | TPACPI_HANDLE(led, ec, "SLED", /* 570 */ |
@@ -3591,8 +3818,174 @@ TPACPI_HANDLE(led, ec, "SLED", /* 570 */ | |||
3591 | "LED", /* all others */ | 3818 | "LED", /* all others */ |
3592 | ); /* R30, R31 */ | 3819 | ); /* R30, R31 */ |
3593 | 3820 | ||
3821 | #define TPACPI_LED_NUMLEDS 8 | ||
3822 | static struct tpacpi_led_classdev *tpacpi_leds; | ||
3823 | static enum led_status_t tpacpi_led_state_cache[TPACPI_LED_NUMLEDS]; | ||
3824 | static const char const *tpacpi_led_names[TPACPI_LED_NUMLEDS] = { | ||
3825 | /* there's a limit of 19 chars + NULL before 2.6.26 */ | ||
3826 | "tpacpi::power", | ||
3827 | "tpacpi:orange:batt", | ||
3828 | "tpacpi:green:batt", | ||
3829 | "tpacpi::dock_active", | ||
3830 | "tpacpi::bay_active", | ||
3831 | "tpacpi::dock_batt", | ||
3832 | "tpacpi::unknown_led", | ||
3833 | "tpacpi::standby", | ||
3834 | }; | ||
3835 | |||
3836 | static int led_get_status(unsigned int led) | ||
3837 | { | ||
3838 | int status; | ||
3839 | enum led_status_t led_s; | ||
3840 | |||
3841 | switch (led_supported) { | ||
3842 | case TPACPI_LED_570: | ||
3843 | if (!acpi_evalf(ec_handle, | ||
3844 | &status, "GLED", "dd", 1 << led)) | ||
3845 | return -EIO; | ||
3846 | led_s = (status == 0)? | ||
3847 | TPACPI_LED_OFF : | ||
3848 | ((status == 1)? | ||
3849 | TPACPI_LED_ON : | ||
3850 | TPACPI_LED_BLINK); | ||
3851 | tpacpi_led_state_cache[led] = led_s; | ||
3852 | return led_s; | ||
3853 | default: | ||
3854 | return -ENXIO; | ||
3855 | } | ||
3856 | |||
3857 | /* not reached */ | ||
3858 | } | ||
3859 | |||
3860 | static int led_set_status(unsigned int led, enum led_status_t ledstatus) | ||
3861 | { | ||
3862 | /* off, on, blink. Index is led_status_t */ | ||
3863 | static const int const led_sled_arg1[] = { 0, 1, 3 }; | ||
3864 | static const int const led_exp_hlbl[] = { 0, 0, 1 }; /* led# * */ | ||
3865 | static const int const led_exp_hlcl[] = { 0, 1, 1 }; /* led# * */ | ||
3866 | static const int const led_led_arg1[] = { 0, 0x80, 0xc0 }; | ||
3867 | |||
3868 | int rc = 0; | ||
3869 | |||
3870 | switch (led_supported) { | ||
3871 | case TPACPI_LED_570: | ||
3872 | /* 570 */ | ||
3873 | led = 1 << led; | ||
3874 | if (!acpi_evalf(led_handle, NULL, NULL, "vdd", | ||
3875 | led, led_sled_arg1[ledstatus])) | ||
3876 | rc = -EIO; | ||
3877 | break; | ||
3878 | case TPACPI_LED_OLD: | ||
3879 | /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ | ||
3880 | led = 1 << led; | ||
3881 | rc = ec_write(TPACPI_LED_EC_HLMS, led); | ||
3882 | if (rc >= 0) | ||
3883 | rc = ec_write(TPACPI_LED_EC_HLBL, | ||
3884 | led * led_exp_hlbl[ledstatus]); | ||
3885 | if (rc >= 0) | ||
3886 | rc = ec_write(TPACPI_LED_EC_HLCL, | ||
3887 | led * led_exp_hlcl[ledstatus]); | ||
3888 | break; | ||
3889 | case TPACPI_LED_NEW: | ||
3890 | /* all others */ | ||
3891 | if (!acpi_evalf(led_handle, NULL, NULL, "vdd", | ||
3892 | led, led_led_arg1[ledstatus])) | ||
3893 | rc = -EIO; | ||
3894 | break; | ||
3895 | default: | ||
3896 | rc = -ENXIO; | ||
3897 | } | ||
3898 | |||
3899 | if (!rc) | ||
3900 | tpacpi_led_state_cache[led] = ledstatus; | ||
3901 | |||
3902 | return rc; | ||
3903 | } | ||
3904 | |||
3905 | static void led_sysfs_set_status(unsigned int led, | ||
3906 | enum led_brightness brightness) | ||
3907 | { | ||
3908 | led_set_status(led, | ||
3909 | (brightness == LED_OFF) ? | ||
3910 | TPACPI_LED_OFF : | ||
3911 | (tpacpi_led_state_cache[led] == TPACPI_LED_BLINK) ? | ||
3912 | TPACPI_LED_BLINK : TPACPI_LED_ON); | ||
3913 | } | ||
3914 | |||
3915 | static void led_set_status_worker(struct work_struct *work) | ||
3916 | { | ||
3917 | struct tpacpi_led_classdev *data = | ||
3918 | container_of(work, struct tpacpi_led_classdev, work); | ||
3919 | |||
3920 | if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) | ||
3921 | led_sysfs_set_status(data->led, data->new_brightness); | ||
3922 | } | ||
3923 | |||
3924 | static void led_sysfs_set(struct led_classdev *led_cdev, | ||
3925 | enum led_brightness brightness) | ||
3926 | { | ||
3927 | struct tpacpi_led_classdev *data = container_of(led_cdev, | ||
3928 | struct tpacpi_led_classdev, led_classdev); | ||
3929 | |||
3930 | data->new_brightness = brightness; | ||
3931 | queue_work(tpacpi_wq, &data->work); | ||
3932 | } | ||
3933 | |||
3934 | static int led_sysfs_blink_set(struct led_classdev *led_cdev, | ||
3935 | unsigned long *delay_on, unsigned long *delay_off) | ||
3936 | { | ||
3937 | struct tpacpi_led_classdev *data = container_of(led_cdev, | ||
3938 | struct tpacpi_led_classdev, led_classdev); | ||
3939 | |||
3940 | /* Can we choose the flash rate? */ | ||
3941 | if (*delay_on == 0 && *delay_off == 0) { | ||
3942 | /* yes. set them to the hardware blink rate (1 Hz) */ | ||
3943 | *delay_on = 500; /* ms */ | ||
3944 | *delay_off = 500; /* ms */ | ||
3945 | } else if ((*delay_on != 500) || (*delay_off != 500)) | ||
3946 | return -EINVAL; | ||
3947 | |||
3948 | data->new_brightness = TPACPI_LED_BLINK; | ||
3949 | queue_work(tpacpi_wq, &data->work); | ||
3950 | |||
3951 | return 0; | ||
3952 | } | ||
3953 | |||
3954 | static enum led_brightness led_sysfs_get(struct led_classdev *led_cdev) | ||
3955 | { | ||
3956 | int rc; | ||
3957 | |||
3958 | struct tpacpi_led_classdev *data = container_of(led_cdev, | ||
3959 | struct tpacpi_led_classdev, led_classdev); | ||
3960 | |||
3961 | rc = led_get_status(data->led); | ||
3962 | |||
3963 | if (rc == TPACPI_LED_OFF || rc < 0) | ||
3964 | rc = LED_OFF; /* no error handling in led class :( */ | ||
3965 | else | ||
3966 | rc = LED_FULL; | ||
3967 | |||
3968 | return rc; | ||
3969 | } | ||
3970 | |||
3971 | static void led_exit(void) | ||
3972 | { | ||
3973 | unsigned int i; | ||
3974 | |||
3975 | for (i = 0; i < TPACPI_LED_NUMLEDS; i++) { | ||
3976 | if (tpacpi_leds[i].led_classdev.name) | ||
3977 | led_classdev_unregister(&tpacpi_leds[i].led_classdev); | ||
3978 | } | ||
3979 | |||
3980 | kfree(tpacpi_leds); | ||
3981 | tpacpi_leds = NULL; | ||
3982 | } | ||
3983 | |||
3594 | static int __init led_init(struct ibm_init_struct *iibm) | 3984 | static int __init led_init(struct ibm_init_struct *iibm) |
3595 | { | 3985 | { |
3986 | unsigned int i; | ||
3987 | int rc; | ||
3988 | |||
3596 | vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n"); | 3989 | vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n"); |
3597 | 3990 | ||
3598 | TPACPI_ACPIHANDLE_INIT(led); | 3991 | TPACPI_ACPIHANDLE_INIT(led); |
@@ -3613,10 +4006,41 @@ static int __init led_init(struct ibm_init_struct *iibm) | |||
3613 | vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n", | 4006 | vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n", |
3614 | str_supported(led_supported), led_supported); | 4007 | str_supported(led_supported), led_supported); |
3615 | 4008 | ||
4009 | tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS, | ||
4010 | GFP_KERNEL); | ||
4011 | if (!tpacpi_leds) { | ||
4012 | printk(TPACPI_ERR "Out of memory for LED data\n"); | ||
4013 | return -ENOMEM; | ||
4014 | } | ||
4015 | |||
4016 | for (i = 0; i < TPACPI_LED_NUMLEDS; i++) { | ||
4017 | tpacpi_leds[i].led = i; | ||
4018 | |||
4019 | tpacpi_leds[i].led_classdev.brightness_set = &led_sysfs_set; | ||
4020 | tpacpi_leds[i].led_classdev.blink_set = &led_sysfs_blink_set; | ||
4021 | if (led_supported == TPACPI_LED_570) | ||
4022 | tpacpi_leds[i].led_classdev.brightness_get = | ||
4023 | &led_sysfs_get; | ||
4024 | |||
4025 | tpacpi_leds[i].led_classdev.name = tpacpi_led_names[i]; | ||
4026 | |||
4027 | INIT_WORK(&tpacpi_leds[i].work, led_set_status_worker); | ||
4028 | |||
4029 | rc = led_classdev_register(&tpacpi_pdev->dev, | ||
4030 | &tpacpi_leds[i].led_classdev); | ||
4031 | if (rc < 0) { | ||
4032 | tpacpi_leds[i].led_classdev.name = NULL; | ||
4033 | led_exit(); | ||
4034 | return rc; | ||
4035 | } | ||
4036 | } | ||
4037 | |||
3616 | return (led_supported != TPACPI_LED_NONE)? 0 : 1; | 4038 | return (led_supported != TPACPI_LED_NONE)? 0 : 1; |
3617 | } | 4039 | } |
3618 | 4040 | ||
3619 | #define led_status(s) ((s) == 0 ? "off" : ((s) == 1 ? "on" : "blinking")) | 4041 | #define str_led_status(s) \ |
4042 | ((s) == TPACPI_LED_OFF ? "off" : \ | ||
4043 | ((s) == TPACPI_LED_ON ? "on" : "blinking")) | ||
3620 | 4044 | ||
3621 | static int led_read(char *p) | 4045 | static int led_read(char *p) |
3622 | { | 4046 | { |
@@ -3632,11 +4056,11 @@ static int led_read(char *p) | |||
3632 | /* 570 */ | 4056 | /* 570 */ |
3633 | int i, status; | 4057 | int i, status; |
3634 | for (i = 0; i < 8; i++) { | 4058 | for (i = 0; i < 8; i++) { |
3635 | if (!acpi_evalf(ec_handle, | 4059 | status = led_get_status(i); |
3636 | &status, "GLED", "dd", 1 << i)) | 4060 | if (status < 0) |
3637 | return -EIO; | 4061 | return -EIO; |
3638 | len += sprintf(p + len, "%d:\t\t%s\n", | 4062 | len += sprintf(p + len, "%d:\t\t%s\n", |
3639 | i, led_status(status)); | 4063 | i, str_led_status(status)); |
3640 | } | 4064 | } |
3641 | } | 4065 | } |
3642 | 4066 | ||
@@ -3646,16 +4070,11 @@ static int led_read(char *p) | |||
3646 | return len; | 4070 | return len; |
3647 | } | 4071 | } |
3648 | 4072 | ||
3649 | /* off, on, blink */ | ||
3650 | static const int led_sled_arg1[] = { 0, 1, 3 }; | ||
3651 | static const int led_exp_hlbl[] = { 0, 0, 1 }; /* led# * */ | ||
3652 | static const int led_exp_hlcl[] = { 0, 1, 1 }; /* led# * */ | ||
3653 | static const int led_led_arg1[] = { 0, 0x80, 0xc0 }; | ||
3654 | |||
3655 | static int led_write(char *buf) | 4073 | static int led_write(char *buf) |
3656 | { | 4074 | { |
3657 | char *cmd; | 4075 | char *cmd; |
3658 | int led, ind, ret; | 4076 | int led, rc; |
4077 | enum led_status_t s; | ||
3659 | 4078 | ||
3660 | if (!led_supported) | 4079 | if (!led_supported) |
3661 | return -ENODEV; | 4080 | return -ENODEV; |
@@ -3665,38 +4084,18 @@ static int led_write(char *buf) | |||
3665 | return -EINVAL; | 4084 | return -EINVAL; |
3666 | 4085 | ||
3667 | if (strstr(cmd, "off")) { | 4086 | if (strstr(cmd, "off")) { |
3668 | ind = 0; | 4087 | s = TPACPI_LED_OFF; |
3669 | } else if (strstr(cmd, "on")) { | 4088 | } else if (strstr(cmd, "on")) { |
3670 | ind = 1; | 4089 | s = TPACPI_LED_ON; |
3671 | } else if (strstr(cmd, "blink")) { | 4090 | } else if (strstr(cmd, "blink")) { |
3672 | ind = 2; | 4091 | s = TPACPI_LED_BLINK; |
3673 | } else | ||
3674 | return -EINVAL; | ||
3675 | |||
3676 | if (led_supported == TPACPI_LED_570) { | ||
3677 | /* 570 */ | ||
3678 | led = 1 << led; | ||
3679 | if (!acpi_evalf(led_handle, NULL, NULL, "vdd", | ||
3680 | led, led_sled_arg1[ind])) | ||
3681 | return -EIO; | ||
3682 | } else if (led_supported == TPACPI_LED_OLD) { | ||
3683 | /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ | ||
3684 | led = 1 << led; | ||
3685 | ret = ec_write(TPACPI_LED_EC_HLMS, led); | ||
3686 | if (ret >= 0) | ||
3687 | ret = ec_write(TPACPI_LED_EC_HLBL, | ||
3688 | led * led_exp_hlbl[ind]); | ||
3689 | if (ret >= 0) | ||
3690 | ret = ec_write(TPACPI_LED_EC_HLCL, | ||
3691 | led * led_exp_hlcl[ind]); | ||
3692 | if (ret < 0) | ||
3693 | return ret; | ||
3694 | } else { | 4092 | } else { |
3695 | /* all others */ | 4093 | return -EINVAL; |
3696 | if (!acpi_evalf(led_handle, NULL, NULL, "vdd", | ||
3697 | led, led_led_arg1[ind])) | ||
3698 | return -EIO; | ||
3699 | } | 4094 | } |
4095 | |||
4096 | rc = led_set_status(led, s); | ||
4097 | if (rc < 0) | ||
4098 | return rc; | ||
3700 | } | 4099 | } |
3701 | 4100 | ||
3702 | return 0; | 4101 | return 0; |
@@ -3706,6 +4105,7 @@ static struct ibm_struct led_driver_data = { | |||
3706 | .name = "led", | 4105 | .name = "led", |
3707 | .read = led_read, | 4106 | .read = led_read, |
3708 | .write = led_write, | 4107 | .write = led_write, |
4108 | .exit = led_exit, | ||
3709 | }; | 4109 | }; |
3710 | 4110 | ||
3711 | /************************************************************************* | 4111 | /************************************************************************* |
@@ -4170,8 +4570,16 @@ static struct ibm_struct ecdump_driver_data = { | |||
4170 | 4570 | ||
4171 | #define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen" | 4571 | #define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen" |
4172 | 4572 | ||
4573 | enum { | ||
4574 | TP_EC_BACKLIGHT = 0x31, | ||
4575 | |||
4576 | /* TP_EC_BACKLIGHT bitmasks */ | ||
4577 | TP_EC_BACKLIGHT_LVLMSK = 0x1F, | ||
4578 | TP_EC_BACKLIGHT_CMDMSK = 0xE0, | ||
4579 | TP_EC_BACKLIGHT_MAPSW = 0x20, | ||
4580 | }; | ||
4581 | |||
4173 | static struct backlight_device *ibm_backlight_device; | 4582 | static struct backlight_device *ibm_backlight_device; |
4174 | static int brightness_offset = 0x31; | ||
4175 | static int brightness_mode; | 4583 | static int brightness_mode; |
4176 | static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */ | 4584 | static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */ |
4177 | 4585 | ||
@@ -4180,16 +4588,24 @@ static struct mutex brightness_mutex; | |||
4180 | /* | 4588 | /* |
4181 | * ThinkPads can read brightness from two places: EC 0x31, or | 4589 | * ThinkPads can read brightness from two places: EC 0x31, or |
4182 | * CMOS NVRAM byte 0x5E, bits 0-3. | 4590 | * CMOS NVRAM byte 0x5E, bits 0-3. |
4591 | * | ||
4592 | * EC 0x31 has the following layout | ||
4593 | * Bit 7: unknown function | ||
4594 | * Bit 6: unknown function | ||
4595 | * Bit 5: Z: honour scale changes, NZ: ignore scale changes | ||
4596 | * Bit 4: must be set to zero to avoid problems | ||
4597 | * Bit 3-0: backlight brightness level | ||
4598 | * | ||
4599 | * brightness_get_raw returns status data in the EC 0x31 layout | ||
4183 | */ | 4600 | */ |
4184 | static int brightness_get(struct backlight_device *bd) | 4601 | static int brightness_get_raw(int *status) |
4185 | { | 4602 | { |
4186 | u8 lec = 0, lcmos = 0, level = 0; | 4603 | u8 lec = 0, lcmos = 0, level = 0; |
4187 | 4604 | ||
4188 | if (brightness_mode & 1) { | 4605 | if (brightness_mode & 1) { |
4189 | if (!acpi_ec_read(brightness_offset, &lec)) | 4606 | if (!acpi_ec_read(TP_EC_BACKLIGHT, &lec)) |
4190 | return -EIO; | 4607 | return -EIO; |
4191 | lec &= (tp_features.bright_16levels)? 0x0f : 0x07; | 4608 | level = lec & TP_EC_BACKLIGHT_LVLMSK; |
4192 | level = lec; | ||
4193 | }; | 4609 | }; |
4194 | if (brightness_mode & 2) { | 4610 | if (brightness_mode & 2) { |
4195 | lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS) | 4611 | lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS) |
@@ -4199,16 +4615,27 @@ static int brightness_get(struct backlight_device *bd) | |||
4199 | level = lcmos; | 4615 | level = lcmos; |
4200 | } | 4616 | } |
4201 | 4617 | ||
4202 | if (brightness_mode == 3 && lec != lcmos) { | 4618 | if (brightness_mode == 3) { |
4203 | printk(TPACPI_ERR | 4619 | *status = lec; /* Prefer EC, CMOS is just a backing store */ |
4204 | "CMOS NVRAM (%u) and EC (%u) do not agree " | 4620 | lec &= TP_EC_BACKLIGHT_LVLMSK; |
4205 | "on display brightness level\n", | 4621 | if (lec == lcmos) |
4206 | (unsigned int) lcmos, | 4622 | tp_warned.bright_cmos_ec_unsync = 0; |
4207 | (unsigned int) lec); | 4623 | else { |
4208 | return -EIO; | 4624 | if (!tp_warned.bright_cmos_ec_unsync) { |
4625 | printk(TPACPI_ERR | ||
4626 | "CMOS NVRAM (%u) and EC (%u) do not " | ||
4627 | "agree on display brightness level\n", | ||
4628 | (unsigned int) lcmos, | ||
4629 | (unsigned int) lec); | ||
4630 | tp_warned.bright_cmos_ec_unsync = 1; | ||
4631 | } | ||
4632 | return -EIO; | ||
4633 | } | ||
4634 | } else { | ||
4635 | *status = level; | ||
4209 | } | 4636 | } |
4210 | 4637 | ||
4211 | return level; | 4638 | return 0; |
4212 | } | 4639 | } |
4213 | 4640 | ||
4214 | /* May return EINTR which can always be mapped to ERESTARTSYS */ | 4641 | /* May return EINTR which can always be mapped to ERESTARTSYS */ |
@@ -4216,19 +4643,22 @@ static int brightness_set(int value) | |||
4216 | { | 4643 | { |
4217 | int cmos_cmd, inc, i, res; | 4644 | int cmos_cmd, inc, i, res; |
4218 | int current_value; | 4645 | int current_value; |
4646 | int command_bits; | ||
4219 | 4647 | ||
4220 | if (value > ((tp_features.bright_16levels)? 15 : 7)) | 4648 | if (value > ((tp_features.bright_16levels)? 15 : 7) || |
4649 | value < 0) | ||
4221 | return -EINVAL; | 4650 | return -EINVAL; |
4222 | 4651 | ||
4223 | res = mutex_lock_interruptible(&brightness_mutex); | 4652 | res = mutex_lock_interruptible(&brightness_mutex); |
4224 | if (res < 0) | 4653 | if (res < 0) |
4225 | return res; | 4654 | return res; |
4226 | 4655 | ||
4227 | current_value = brightness_get(NULL); | 4656 | res = brightness_get_raw(¤t_value); |
4228 | if (current_value < 0) { | 4657 | if (res < 0) |
4229 | res = current_value; | ||
4230 | goto errout; | 4658 | goto errout; |
4231 | } | 4659 | |
4660 | command_bits = current_value & TP_EC_BACKLIGHT_CMDMSK; | ||
4661 | current_value &= TP_EC_BACKLIGHT_LVLMSK; | ||
4232 | 4662 | ||
4233 | cmos_cmd = value > current_value ? | 4663 | cmos_cmd = value > current_value ? |
4234 | TP_CMOS_BRIGHTNESS_UP : | 4664 | TP_CMOS_BRIGHTNESS_UP : |
@@ -4243,7 +4673,8 @@ static int brightness_set(int value) | |||
4243 | goto errout; | 4673 | goto errout; |
4244 | } | 4674 | } |
4245 | if ((brightness_mode & 1) && | 4675 | if ((brightness_mode & 1) && |
4246 | !acpi_ec_write(brightness_offset, i + inc)) { | 4676 | !acpi_ec_write(TP_EC_BACKLIGHT, |
4677 | (i + inc) | command_bits)) { | ||
4247 | res = -EIO; | 4678 | res = -EIO; |
4248 | goto errout;; | 4679 | goto errout;; |
4249 | } | 4680 | } |
@@ -4266,106 +4697,23 @@ static int brightness_update_status(struct backlight_device *bd) | |||
4266 | bd->props.brightness : 0); | 4697 | bd->props.brightness : 0); |
4267 | } | 4698 | } |
4268 | 4699 | ||
4269 | static struct backlight_ops ibm_backlight_data = { | 4700 | static int brightness_get(struct backlight_device *bd) |
4270 | .get_brightness = brightness_get, | ||
4271 | .update_status = brightness_update_status, | ||
4272 | }; | ||
4273 | |||
4274 | /* --------------------------------------------------------------------- */ | ||
4275 | |||
4276 | static int __init tpacpi_query_bcll_levels(acpi_handle handle) | ||
4277 | { | ||
4278 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
4279 | union acpi_object *obj; | ||
4280 | int rc; | ||
4281 | |||
4282 | if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) { | ||
4283 | obj = (union acpi_object *)buffer.pointer; | ||
4284 | if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { | ||
4285 | printk(TPACPI_ERR "Unknown BCLL data, " | ||
4286 | "please report this to %s\n", TPACPI_MAIL); | ||
4287 | rc = 0; | ||
4288 | } else { | ||
4289 | rc = obj->package.count; | ||
4290 | } | ||
4291 | } else { | ||
4292 | return 0; | ||
4293 | } | ||
4294 | |||
4295 | kfree(buffer.pointer); | ||
4296 | return rc; | ||
4297 | } | ||
4298 | |||
4299 | static acpi_status __init brightness_find_bcll(acpi_handle handle, u32 lvl, | ||
4300 | void *context, void **rv) | ||
4301 | { | ||
4302 | char name[ACPI_PATH_SEGMENT_LENGTH]; | ||
4303 | struct acpi_buffer buffer = { sizeof(name), &name }; | ||
4304 | |||
4305 | if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) && | ||
4306 | !strncmp("BCLL", name, sizeof(name) - 1)) { | ||
4307 | if (tpacpi_query_bcll_levels(handle) == 16) { | ||
4308 | *rv = handle; | ||
4309 | return AE_CTRL_TERMINATE; | ||
4310 | } else { | ||
4311 | return AE_OK; | ||
4312 | } | ||
4313 | } else { | ||
4314 | return AE_OK; | ||
4315 | } | ||
4316 | } | ||
4317 | |||
4318 | static int __init brightness_check_levels(void) | ||
4319 | { | 4701 | { |
4320 | int status; | 4702 | int status, res; |
4321 | void *found_node = NULL; | ||
4322 | 4703 | ||
4323 | if (!vid_handle) { | 4704 | res = brightness_get_raw(&status); |
4324 | TPACPI_ACPIHANDLE_INIT(vid); | 4705 | if (res < 0) |
4325 | } | 4706 | return 0; /* FIXME: teach backlight about error handling */ |
4326 | if (!vid_handle) | ||
4327 | return 0; | ||
4328 | |||
4329 | /* Search for a BCLL package with 16 levels */ | ||
4330 | status = acpi_walk_namespace(ACPI_TYPE_PACKAGE, vid_handle, 3, | ||
4331 | brightness_find_bcll, NULL, | ||
4332 | &found_node); | ||
4333 | |||
4334 | return (ACPI_SUCCESS(status) && found_node != NULL); | ||
4335 | } | ||
4336 | |||
4337 | static acpi_status __init brightness_find_bcl(acpi_handle handle, u32 lvl, | ||
4338 | void *context, void **rv) | ||
4339 | { | ||
4340 | char name[ACPI_PATH_SEGMENT_LENGTH]; | ||
4341 | struct acpi_buffer buffer = { sizeof(name), &name }; | ||
4342 | 4707 | ||
4343 | if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) && | 4708 | return status & TP_EC_BACKLIGHT_LVLMSK; |
4344 | !strncmp("_BCL", name, sizeof(name) - 1)) { | ||
4345 | *rv = handle; | ||
4346 | return AE_CTRL_TERMINATE; | ||
4347 | } else { | ||
4348 | return AE_OK; | ||
4349 | } | ||
4350 | } | 4709 | } |
4351 | 4710 | ||
4352 | static int __init brightness_check_std_acpi_support(void) | 4711 | static struct backlight_ops ibm_backlight_data = { |
4353 | { | 4712 | .get_brightness = brightness_get, |
4354 | int status; | 4713 | .update_status = brightness_update_status, |
4355 | void *found_node = NULL; | 4714 | }; |
4356 | |||
4357 | if (!vid_handle) { | ||
4358 | TPACPI_ACPIHANDLE_INIT(vid); | ||
4359 | } | ||
4360 | if (!vid_handle) | ||
4361 | return 0; | ||
4362 | |||
4363 | /* Search for a _BCL method, but don't execute it */ | ||
4364 | status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3, | ||
4365 | brightness_find_bcl, NULL, &found_node); | ||
4366 | 4715 | ||
4367 | return (ACPI_SUCCESS(status) && found_node != NULL); | 4716 | /* --------------------------------------------------------------------- */ |
4368 | } | ||
4369 | 4717 | ||
4370 | static int __init brightness_init(struct ibm_init_struct *iibm) | 4718 | static int __init brightness_init(struct ibm_init_struct *iibm) |
4371 | { | 4719 | { |
@@ -4375,13 +4723,19 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
4375 | 4723 | ||
4376 | mutex_init(&brightness_mutex); | 4724 | mutex_init(&brightness_mutex); |
4377 | 4725 | ||
4378 | if (!brightness_enable) { | 4726 | /* |
4379 | dbg_printk(TPACPI_DBG_INIT, | 4727 | * We always attempt to detect acpi support, so as to switch |
4380 | "brightness support disabled by " | 4728 | * Lenovo Vista BIOS to ACPI brightness mode even if we are not |
4381 | "module parameter\n"); | 4729 | * going to publish a backlight interface |
4382 | return 1; | 4730 | */ |
4383 | } else if (brightness_enable > 1) { | 4731 | b = tpacpi_check_std_acpi_brightness_support(); |
4384 | if (brightness_check_std_acpi_support()) { | 4732 | if (b > 0) { |
4733 | if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { | ||
4734 | printk(TPACPI_NOTICE | ||
4735 | "Lenovo BIOS switched to ACPI backlight " | ||
4736 | "control mode\n"); | ||
4737 | } | ||
4738 | if (brightness_enable > 1) { | ||
4385 | printk(TPACPI_NOTICE | 4739 | printk(TPACPI_NOTICE |
4386 | "standard ACPI backlight interface " | 4740 | "standard ACPI backlight interface " |
4387 | "available, not loading native one...\n"); | 4741 | "available, not loading native one...\n"); |
@@ -4389,6 +4743,22 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
4389 | } | 4743 | } |
4390 | } | 4744 | } |
4391 | 4745 | ||
4746 | if (!brightness_enable) { | ||
4747 | dbg_printk(TPACPI_DBG_INIT, | ||
4748 | "brightness support disabled by " | ||
4749 | "module parameter\n"); | ||
4750 | return 1; | ||
4751 | } | ||
4752 | |||
4753 | if (b > 16) { | ||
4754 | printk(TPACPI_ERR | ||
4755 | "Unsupported brightness interface, " | ||
4756 | "please contact %s\n", TPACPI_MAIL); | ||
4757 | return 1; | ||
4758 | } | ||
4759 | if (b == 16) | ||
4760 | tp_features.bright_16levels = 1; | ||
4761 | |||
4392 | if (!brightness_mode) { | 4762 | if (!brightness_mode) { |
4393 | if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) | 4763 | if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) |
4394 | brightness_mode = 2; | 4764 | brightness_mode = 2; |
@@ -4402,12 +4772,7 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
4402 | if (brightness_mode > 3) | 4772 | if (brightness_mode > 3) |
4403 | return -EINVAL; | 4773 | return -EINVAL; |
4404 | 4774 | ||
4405 | tp_features.bright_16levels = | 4775 | if (brightness_get_raw(&b) < 0) |
4406 | thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO && | ||
4407 | brightness_check_levels(); | ||
4408 | |||
4409 | b = brightness_get(NULL); | ||
4410 | if (b < 0) | ||
4411 | return 1; | 4776 | return 1; |
4412 | 4777 | ||
4413 | if (tp_features.bright_16levels) | 4778 | if (tp_features.bright_16levels) |
@@ -4425,7 +4790,7 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
4425 | 4790 | ||
4426 | ibm_backlight_device->props.max_brightness = | 4791 | ibm_backlight_device->props.max_brightness = |
4427 | (tp_features.bright_16levels)? 15 : 7; | 4792 | (tp_features.bright_16levels)? 15 : 7; |
4428 | ibm_backlight_device->props.brightness = b; | 4793 | ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK; |
4429 | backlight_update_status(ibm_backlight_device); | 4794 | backlight_update_status(ibm_backlight_device); |
4430 | 4795 | ||
4431 | return 0; | 4796 | return 0; |
@@ -5046,11 +5411,11 @@ static void fan_watchdog_reset(void) | |||
5046 | if (fan_watchdog_maxinterval > 0 && | 5411 | if (fan_watchdog_maxinterval > 0 && |
5047 | tpacpi_lifecycle != TPACPI_LIFE_EXITING) { | 5412 | tpacpi_lifecycle != TPACPI_LIFE_EXITING) { |
5048 | fan_watchdog_active = 1; | 5413 | fan_watchdog_active = 1; |
5049 | if (!schedule_delayed_work(&fan_watchdog_task, | 5414 | if (!queue_delayed_work(tpacpi_wq, &fan_watchdog_task, |
5050 | msecs_to_jiffies(fan_watchdog_maxinterval | 5415 | msecs_to_jiffies(fan_watchdog_maxinterval |
5051 | * 1000))) { | 5416 | * 1000))) { |
5052 | printk(TPACPI_ERR | 5417 | printk(TPACPI_ERR |
5053 | "failed to schedule the fan watchdog, " | 5418 | "failed to queue the fan watchdog, " |
5054 | "watchdog will not trigger\n"); | 5419 | "watchdog will not trigger\n"); |
5055 | } | 5420 | } |
5056 | } else | 5421 | } else |
@@ -5420,7 +5785,7 @@ static void fan_exit(void) | |||
5420 | &driver_attr_fan_watchdog); | 5785 | &driver_attr_fan_watchdog); |
5421 | 5786 | ||
5422 | cancel_delayed_work(&fan_watchdog_task); | 5787 | cancel_delayed_work(&fan_watchdog_task); |
5423 | flush_scheduled_work(); | 5788 | flush_workqueue(tpacpi_wq); |
5424 | } | 5789 | } |
5425 | 5790 | ||
5426 | static int fan_read(char *p) | 5791 | static int fan_read(char *p) |
@@ -5826,10 +6191,13 @@ static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp) | |||
5826 | 6191 | ||
5827 | tp->model_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_VERSION), | 6192 | tp->model_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_VERSION), |
5828 | GFP_KERNEL); | 6193 | GFP_KERNEL); |
5829 | if (strnicmp(tp->model_str, "ThinkPad", 8) != 0) { | 6194 | if (tp->model_str && strnicmp(tp->model_str, "ThinkPad", 8) != 0) { |
5830 | kfree(tp->model_str); | 6195 | kfree(tp->model_str); |
5831 | tp->model_str = NULL; | 6196 | tp->model_str = NULL; |
5832 | } | 6197 | } |
6198 | |||
6199 | tp->nummodel_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_NAME), | ||
6200 | GFP_KERNEL); | ||
5833 | } | 6201 | } |
5834 | 6202 | ||
5835 | static int __init probe_for_thinkpad(void) | 6203 | static int __init probe_for_thinkpad(void) |
@@ -6071,6 +6439,9 @@ static void thinkpad_acpi_module_exit(void) | |||
6071 | if (proc_dir) | 6439 | if (proc_dir) |
6072 | remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir); | 6440 | remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir); |
6073 | 6441 | ||
6442 | if (tpacpi_wq) | ||
6443 | destroy_workqueue(tpacpi_wq); | ||
6444 | |||
6074 | kfree(thinkpad_id.bios_version_str); | 6445 | kfree(thinkpad_id.bios_version_str); |
6075 | kfree(thinkpad_id.ec_version_str); | 6446 | kfree(thinkpad_id.ec_version_str); |
6076 | kfree(thinkpad_id.model_str); | 6447 | kfree(thinkpad_id.model_str); |
@@ -6101,6 +6472,12 @@ static int __init thinkpad_acpi_module_init(void) | |||
6101 | TPACPI_ACPIHANDLE_INIT(ecrd); | 6472 | TPACPI_ACPIHANDLE_INIT(ecrd); |
6102 | TPACPI_ACPIHANDLE_INIT(ecwr); | 6473 | TPACPI_ACPIHANDLE_INIT(ecwr); |
6103 | 6474 | ||
6475 | tpacpi_wq = create_singlethread_workqueue(TPACPI_WORKQUEUE_NAME); | ||
6476 | if (!tpacpi_wq) { | ||
6477 | thinkpad_acpi_module_exit(); | ||
6478 | return -ENOMEM; | ||
6479 | } | ||
6480 | |||
6104 | proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir); | 6481 | proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir); |
6105 | if (!proc_dir) { | 6482 | if (!proc_dir) { |
6106 | printk(TPACPI_ERR | 6483 | printk(TPACPI_ERR |
@@ -6223,6 +6600,8 @@ static int __init thinkpad_acpi_module_init(void) | |||
6223 | /* Please remove this in year 2009 */ | 6600 | /* Please remove this in year 2009 */ |
6224 | MODULE_ALIAS("ibm_acpi"); | 6601 | MODULE_ALIAS("ibm_acpi"); |
6225 | 6602 | ||
6603 | MODULE_ALIAS(TPACPI_DRVR_SHORTNAME); | ||
6604 | |||
6226 | /* | 6605 | /* |
6227 | * DMI matching for module autoloading | 6606 | * DMI matching for module autoloading |
6228 | * | 6607 | * |
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index c283a9a70d83..63e64ef39fb7 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -44,7 +44,7 @@ static struct acpi_device_id excluded_id_list[] __initdata = { | |||
44 | {"", 0}, | 44 | {"", 0}, |
45 | }; | 45 | }; |
46 | 46 | ||
47 | static inline int is_exclusive_device(struct acpi_device *dev) | 47 | static inline int __init is_exclusive_device(struct acpi_device *dev) |
48 | { | 48 | { |
49 | return (!acpi_match_device_ids(dev, excluded_id_list)); | 49 | return (!acpi_match_device_ids(dev, excluded_id_list)); |
50 | } | 50 | } |
diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index 422f29c06c77..28fe8bae1037 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -63,7 +63,7 @@ | |||
63 | 63 | ||
64 | /* Current ACPICA subsystem version in YYYYMMDD format */ | 64 | /* Current ACPICA subsystem version in YYYYMMDD format */ |
65 | 65 | ||
66 | #define ACPI_CA_VERSION 0x20070126 | 66 | #define ACPI_CA_VERSION 0x20080321 |
67 | 67 | ||
68 | /* | 68 | /* |
69 | * OS name, used for the _OS object. The _OS object is essentially obsolete, | 69 | * OS name, used for the _OS object. The _OS object is essentially obsolete, |
@@ -150,6 +150,17 @@ | |||
150 | #define ACPI_OBJ_NUM_OPERANDS 8 | 150 | #define ACPI_OBJ_NUM_OPERANDS 8 |
151 | #define ACPI_OBJ_MAX_OPERAND 7 | 151 | #define ACPI_OBJ_MAX_OPERAND 7 |
152 | 152 | ||
153 | /* Number of elements in the Result Stack frame, can be an arbitrary value */ | ||
154 | |||
155 | #define ACPI_RESULTS_FRAME_OBJ_NUM 8 | ||
156 | |||
157 | /* | ||
158 | * Maximal number of elements the Result Stack can contain, | ||
159 | * it may be an arbitray value not exceeding the types of | ||
160 | * result_size and result_count (now u8). | ||
161 | */ | ||
162 | #define ACPI_RESULTS_OBJ_NUM_MAX 255 | ||
163 | |||
153 | /* Names within the namespace are 4 bytes long */ | 164 | /* Names within the namespace are 4 bytes long */ |
154 | 165 | ||
155 | #define ACPI_NAME_SIZE 4 | 166 | #define ACPI_NAME_SIZE 4 |
diff --git a/include/acpi/acdebug.h b/include/acpi/acdebug.h index d626bb1d2973..c5a1b50d8d94 100644 --- a/include/acpi/acdebug.h +++ b/include/acpi/acdebug.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h index 389d772c7d5b..788f88782012 100644 --- a/include/acpi/acdisasm.h +++ b/include/acpi/acdisasm.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -97,19 +97,23 @@ typedef const struct acpi_dmtable_info { | |||
97 | #define ACPI_DMT_CHKSUM 20 | 97 | #define ACPI_DMT_CHKSUM 20 |
98 | #define ACPI_DMT_SPACEID 21 | 98 | #define ACPI_DMT_SPACEID 21 |
99 | #define ACPI_DMT_GAS 22 | 99 | #define ACPI_DMT_GAS 22 |
100 | #define ACPI_DMT_DMAR 23 | 100 | #define ACPI_DMT_ASF 23 |
101 | #define ACPI_DMT_MADT 24 | 101 | #define ACPI_DMT_DMAR 24 |
102 | #define ACPI_DMT_SRAT 25 | 102 | #define ACPI_DMT_HEST 25 |
103 | #define ACPI_DMT_EXIT 26 | 103 | #define ACPI_DMT_HESTNTFY 26 |
104 | #define ACPI_DMT_SIG 27 | 104 | #define ACPI_DMT_HESTNTYP 27 |
105 | #define ACPI_DMT_MADT 28 | ||
106 | #define ACPI_DMT_SRAT 29 | ||
107 | #define ACPI_DMT_EXIT 30 | ||
108 | #define ACPI_DMT_SIG 31 | ||
105 | 109 | ||
106 | typedef | 110 | typedef |
107 | void (*ACPI_TABLE_HANDLER) (struct acpi_table_header * table); | 111 | void (*acpi_dmtable_handler) (struct acpi_table_header * table); |
108 | 112 | ||
109 | struct acpi_dmtable_data { | 113 | struct acpi_dmtable_data { |
110 | char *signature; | 114 | char *signature; |
111 | struct acpi_dmtable_info *table_info; | 115 | struct acpi_dmtable_info *table_info; |
112 | ACPI_TABLE_HANDLER table_handler; | 116 | acpi_dmtable_handler table_handler; |
113 | char *name; | 117 | char *name; |
114 | }; | 118 | }; |
115 | 119 | ||
@@ -149,6 +153,7 @@ extern struct acpi_dmtable_info acpi_dm_table_info_asf3[]; | |||
149 | extern struct acpi_dmtable_info acpi_dm_table_info_asf4[]; | 153 | extern struct acpi_dmtable_info acpi_dm_table_info_asf4[]; |
150 | extern struct acpi_dmtable_info acpi_dm_table_info_asf_hdr[]; | 154 | extern struct acpi_dmtable_info acpi_dm_table_info_asf_hdr[]; |
151 | extern struct acpi_dmtable_info acpi_dm_table_info_boot[]; | 155 | extern struct acpi_dmtable_info acpi_dm_table_info_boot[]; |
156 | extern struct acpi_dmtable_info acpi_dm_table_info_bert[]; | ||
152 | extern struct acpi_dmtable_info acpi_dm_table_info_cpep[]; | 157 | extern struct acpi_dmtable_info acpi_dm_table_info_cpep[]; |
153 | extern struct acpi_dmtable_info acpi_dm_table_info_cpep0[]; | 158 | extern struct acpi_dmtable_info acpi_dm_table_info_cpep0[]; |
154 | extern struct acpi_dmtable_info acpi_dm_table_info_dbgp[]; | 159 | extern struct acpi_dmtable_info acpi_dm_table_info_dbgp[]; |
@@ -158,11 +163,17 @@ extern struct acpi_dmtable_info acpi_dm_table_info_dmar_scope[]; | |||
158 | extern struct acpi_dmtable_info acpi_dm_table_info_dmar0[]; | 163 | extern struct acpi_dmtable_info acpi_dm_table_info_dmar0[]; |
159 | extern struct acpi_dmtable_info acpi_dm_table_info_dmar1[]; | 164 | extern struct acpi_dmtable_info acpi_dm_table_info_dmar1[]; |
160 | extern struct acpi_dmtable_info acpi_dm_table_info_ecdt[]; | 165 | extern struct acpi_dmtable_info acpi_dm_table_info_ecdt[]; |
166 | extern struct acpi_dmtable_info acpi_dm_table_info_einj[]; | ||
167 | extern struct acpi_dmtable_info acpi_dm_table_info_einj0[]; | ||
168 | extern struct acpi_dmtable_info acpi_dm_table_info_erst[]; | ||
161 | extern struct acpi_dmtable_info acpi_dm_table_info_facs[]; | 169 | extern struct acpi_dmtable_info acpi_dm_table_info_facs[]; |
162 | extern struct acpi_dmtable_info acpi_dm_table_info_fadt1[]; | 170 | extern struct acpi_dmtable_info acpi_dm_table_info_fadt1[]; |
163 | extern struct acpi_dmtable_info acpi_dm_table_info_fadt2[]; | 171 | extern struct acpi_dmtable_info acpi_dm_table_info_fadt2[]; |
164 | extern struct acpi_dmtable_info acpi_dm_table_info_gas[]; | 172 | extern struct acpi_dmtable_info acpi_dm_table_info_gas[]; |
165 | extern struct acpi_dmtable_info acpi_dm_table_info_header[]; | 173 | extern struct acpi_dmtable_info acpi_dm_table_info_header[]; |
174 | extern struct acpi_dmtable_info acpi_dm_table_info_hest[]; | ||
175 | extern struct acpi_dmtable_info acpi_dm_table_info_hest9[]; | ||
176 | extern struct acpi_dmtable_info acpi_dm_table_info_hest_notify[]; | ||
166 | extern struct acpi_dmtable_info acpi_dm_table_info_hpet[]; | 177 | extern struct acpi_dmtable_info acpi_dm_table_info_hpet[]; |
167 | extern struct acpi_dmtable_info acpi_dm_table_info_madt[]; | 178 | extern struct acpi_dmtable_info acpi_dm_table_info_madt[]; |
168 | extern struct acpi_dmtable_info acpi_dm_table_info_madt0[]; | 179 | extern struct acpi_dmtable_info acpi_dm_table_info_madt0[]; |
@@ -180,6 +191,7 @@ extern struct acpi_dmtable_info acpi_dm_table_info_mcfg0[]; | |||
180 | extern struct acpi_dmtable_info acpi_dm_table_info_rsdp1[]; | 191 | extern struct acpi_dmtable_info acpi_dm_table_info_rsdp1[]; |
181 | extern struct acpi_dmtable_info acpi_dm_table_info_rsdp2[]; | 192 | extern struct acpi_dmtable_info acpi_dm_table_info_rsdp2[]; |
182 | extern struct acpi_dmtable_info acpi_dm_table_info_sbst[]; | 193 | extern struct acpi_dmtable_info acpi_dm_table_info_sbst[]; |
194 | extern struct acpi_dmtable_info acpi_dm_table_info_slic[]; | ||
183 | extern struct acpi_dmtable_info acpi_dm_table_info_slit[]; | 195 | extern struct acpi_dmtable_info acpi_dm_table_info_slit[]; |
184 | extern struct acpi_dmtable_info acpi_dm_table_info_spcr[]; | 196 | extern struct acpi_dmtable_info acpi_dm_table_info_spcr[]; |
185 | extern struct acpi_dmtable_info acpi_dm_table_info_spmi[]; | 197 | extern struct acpi_dmtable_info acpi_dm_table_info_spmi[]; |
@@ -194,7 +206,7 @@ extern struct acpi_dmtable_info acpi_dm_table_info_wdrt[]; | |||
194 | */ | 206 | */ |
195 | void acpi_dm_dump_data_table(struct acpi_table_header *table); | 207 | void acpi_dm_dump_data_table(struct acpi_table_header *table); |
196 | 208 | ||
197 | void | 209 | acpi_status |
198 | acpi_dm_dump_table(u32 table_length, | 210 | acpi_dm_dump_table(u32 table_length, |
199 | u32 table_offset, | 211 | u32 table_offset, |
200 | void *table, | 212 | void *table, |
@@ -213,9 +225,13 @@ void acpi_dm_dump_cpep(struct acpi_table_header *table); | |||
213 | 225 | ||
214 | void acpi_dm_dump_dmar(struct acpi_table_header *table); | 226 | void acpi_dm_dump_dmar(struct acpi_table_header *table); |
215 | 227 | ||
228 | void acpi_dm_dump_einj(struct acpi_table_header *table); | ||
229 | |||
230 | void acpi_dm_dump_erst(struct acpi_table_header *table); | ||
231 | |||
216 | void acpi_dm_dump_fadt(struct acpi_table_header *table); | 232 | void acpi_dm_dump_fadt(struct acpi_table_header *table); |
217 | 233 | ||
218 | void acpi_dm_dump_srat(struct acpi_table_header *table); | 234 | void acpi_dm_dump_hest(struct acpi_table_header *table); |
219 | 235 | ||
220 | void acpi_dm_dump_mcfg(struct acpi_table_header *table); | 236 | void acpi_dm_dump_mcfg(struct acpi_table_header *table); |
221 | 237 | ||
@@ -227,6 +243,8 @@ void acpi_dm_dump_rsdt(struct acpi_table_header *table); | |||
227 | 243 | ||
228 | void acpi_dm_dump_slit(struct acpi_table_header *table); | 244 | void acpi_dm_dump_slit(struct acpi_table_header *table); |
229 | 245 | ||
246 | void acpi_dm_dump_srat(struct acpi_table_header *table); | ||
247 | |||
230 | void acpi_dm_dump_xsdt(struct acpi_table_header *table); | 248 | void acpi_dm_dump_xsdt(struct acpi_table_header *table); |
231 | 249 | ||
232 | /* | 250 | /* |
diff --git a/include/acpi/acdispat.h b/include/acpi/acdispat.h index 7f690bb0f02f..910f018d92c7 100644 --- a/include/acpi/acdispat.h +++ b/include/acpi/acdispat.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -53,6 +53,9 @@ | |||
53 | acpi_status | 53 | acpi_status |
54 | acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc); | 54 | acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc); |
55 | 55 | ||
56 | acpi_status | ||
57 | acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc); | ||
58 | |||
56 | acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *rgn_desc); | 59 | acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *rgn_desc); |
57 | 60 | ||
58 | acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc); | 61 | acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc); |
@@ -68,10 +71,18 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state, | |||
68 | union acpi_parse_object *op); | 71 | union acpi_parse_object *op); |
69 | 72 | ||
70 | acpi_status | 73 | acpi_status |
74 | acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, | ||
75 | union acpi_parse_object *op); | ||
76 | |||
77 | acpi_status | ||
71 | acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state, | 78 | acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state, |
72 | union acpi_parse_object *op, | 79 | union acpi_parse_object *op, |
73 | union acpi_operand_object *obj_desc); | 80 | union acpi_operand_object *obj_desc); |
74 | 81 | ||
82 | acpi_status | ||
83 | acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state, | ||
84 | union acpi_parse_object *op); | ||
85 | |||
75 | acpi_status acpi_ds_initialize_region(acpi_handle obj_handle); | 86 | acpi_status acpi_ds_initialize_region(acpi_handle obj_handle); |
76 | 87 | ||
77 | /* | 88 | /* |
@@ -269,6 +280,8 @@ acpi_status acpi_ds_resolve_operands(struct acpi_walk_state *walk_state); | |||
269 | 280 | ||
270 | void acpi_ds_clear_operands(struct acpi_walk_state *walk_state); | 281 | void acpi_ds_clear_operands(struct acpi_walk_state *walk_state); |
271 | 282 | ||
283 | acpi_status acpi_ds_evaluate_name_path(struct acpi_walk_state *walk_state); | ||
284 | |||
272 | /* | 285 | /* |
273 | * dswscope - Scope Stack manipulation | 286 | * dswscope - Scope Stack manipulation |
274 | */ | 287 | */ |
@@ -303,7 +316,7 @@ acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state, | |||
303 | u32 aml_length, | 316 | u32 aml_length, |
304 | struct acpi_evaluate_info *info, u8 pass_number); | 317 | struct acpi_evaluate_info *info, u8 pass_number); |
305 | 318 | ||
306 | acpi_status | 319 | void |
307 | acpi_ds_obj_stack_pop_and_delete(u32 pop_count, | 320 | acpi_ds_obj_stack_pop_and_delete(u32 pop_count, |
308 | struct acpi_walk_state *walk_state); | 321 | struct acpi_walk_state *walk_state); |
309 | 322 | ||
@@ -316,21 +329,11 @@ void | |||
316 | acpi_ds_push_walk_state(struct acpi_walk_state *walk_state, | 329 | acpi_ds_push_walk_state(struct acpi_walk_state *walk_state, |
317 | struct acpi_thread_state *thread); | 330 | struct acpi_thread_state *thread); |
318 | 331 | ||
319 | acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *walk_state); | ||
320 | |||
321 | acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *walk_state); | ||
322 | |||
323 | acpi_status acpi_ds_result_stack_clear(struct acpi_walk_state *walk_state); | 332 | acpi_status acpi_ds_result_stack_clear(struct acpi_walk_state *walk_state); |
324 | 333 | ||
325 | struct acpi_walk_state *acpi_ds_get_current_walk_state(struct acpi_thread_state | 334 | struct acpi_walk_state *acpi_ds_get_current_walk_state(struct acpi_thread_state |
326 | *thread); | 335 | *thread); |
327 | 336 | ||
328 | #ifdef ACPI_FUTURE_USAGE | ||
329 | acpi_status | ||
330 | acpi_ds_result_remove(union acpi_operand_object **object, | ||
331 | u32 index, struct acpi_walk_state *walk_state); | ||
332 | #endif | ||
333 | |||
334 | acpi_status | 337 | acpi_status |
335 | acpi_ds_result_pop(union acpi_operand_object **object, | 338 | acpi_ds_result_pop(union acpi_operand_object **object, |
336 | struct acpi_walk_state *walk_state); | 339 | struct acpi_walk_state *walk_state); |
@@ -339,8 +342,4 @@ acpi_status | |||
339 | acpi_ds_result_push(union acpi_operand_object *object, | 342 | acpi_ds_result_push(union acpi_operand_object *object, |
340 | struct acpi_walk_state *walk_state); | 343 | struct acpi_walk_state *walk_state); |
341 | 344 | ||
342 | acpi_status | ||
343 | acpi_ds_result_pop_from_bottom(union acpi_operand_object **object, | ||
344 | struct acpi_walk_state *walk_state); | ||
345 | |||
346 | #endif /* _ACDISPAT_H_ */ | 345 | #endif /* _ACDISPAT_H_ */ |
diff --git a/include/acpi/acevents.h b/include/acpi/acevents.h index d23cdf326808..d5d099bf349c 100644 --- a/include/acpi/acevents.h +++ b/include/acpi/acevents.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h index b73f18a48785..1f591171bf31 100644 --- a/include/acpi/acexcep.h +++ b/include/acpi/acexcep.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h index 47a1fd8f2d8a..74ad971241db 100644 --- a/include/acpi/acglobal.h +++ b/include/acpi/acglobal.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -170,10 +170,14 @@ ACPI_EXTERN u8 acpi_gbl_integer_nybble_width; | |||
170 | ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[ACPI_NUM_MUTEX]; | 170 | ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[ACPI_NUM_MUTEX]; |
171 | 171 | ||
172 | /* | 172 | /* |
173 | * Global lock semaphore works in conjunction with the actual HW global lock | 173 | * Global lock mutex is an actual AML mutex object |
174 | * Global lock semaphore works in conjunction with the HW global lock | ||
174 | */ | 175 | */ |
175 | ACPI_EXTERN acpi_mutex acpi_gbl_global_lock_mutex; | 176 | ACPI_EXTERN union acpi_operand_object *acpi_gbl_global_lock_mutex; |
176 | ACPI_EXTERN acpi_semaphore acpi_gbl_global_lock_semaphore; | 177 | ACPI_EXTERN acpi_semaphore acpi_gbl_global_lock_semaphore; |
178 | ACPI_EXTERN u16 acpi_gbl_global_lock_handle; | ||
179 | ACPI_EXTERN u8 acpi_gbl_global_lock_acquired; | ||
180 | ACPI_EXTERN u8 acpi_gbl_global_lock_present; | ||
177 | 181 | ||
178 | /* | 182 | /* |
179 | * Spinlocks are used for interfaces that can be possibly called at | 183 | * Spinlocks are used for interfaces that can be possibly called at |
@@ -213,27 +217,33 @@ ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_device_notify; | |||
213 | ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_system_notify; | 217 | ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_system_notify; |
214 | ACPI_EXTERN acpi_exception_handler acpi_gbl_exception_handler; | 218 | ACPI_EXTERN acpi_exception_handler acpi_gbl_exception_handler; |
215 | ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler; | 219 | ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler; |
220 | ACPI_EXTERN acpi_tbl_handler acpi_gbl_table_handler; | ||
221 | ACPI_EXTERN void *acpi_gbl_table_handler_context; | ||
216 | ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk; | 222 | ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk; |
217 | 223 | ||
224 | /* Owner ID support */ | ||
225 | |||
226 | ACPI_EXTERN u32 acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS]; | ||
227 | ACPI_EXTERN u8 acpi_gbl_last_owner_id_index; | ||
228 | ACPI_EXTERN u8 acpi_gbl_next_owner_id_offset; | ||
229 | |||
218 | /* Misc */ | 230 | /* Misc */ |
219 | 231 | ||
220 | ACPI_EXTERN u32 acpi_gbl_original_mode; | 232 | ACPI_EXTERN u32 acpi_gbl_original_mode; |
221 | ACPI_EXTERN u32 acpi_gbl_rsdp_original_location; | 233 | ACPI_EXTERN u32 acpi_gbl_rsdp_original_location; |
222 | ACPI_EXTERN u32 acpi_gbl_ns_lookup_count; | 234 | ACPI_EXTERN u32 acpi_gbl_ns_lookup_count; |
223 | ACPI_EXTERN u32 acpi_gbl_ps_find_count; | 235 | ACPI_EXTERN u32 acpi_gbl_ps_find_count; |
224 | ACPI_EXTERN u32 acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS]; | ||
225 | ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save; | 236 | ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save; |
226 | ACPI_EXTERN u16 acpi_gbl_global_lock_handle; | ||
227 | ACPI_EXTERN u8 acpi_gbl_last_owner_id_index; | ||
228 | ACPI_EXTERN u8 acpi_gbl_next_owner_id_offset; | ||
229 | ACPI_EXTERN u8 acpi_gbl_debugger_configuration; | 237 | ACPI_EXTERN u8 acpi_gbl_debugger_configuration; |
230 | ACPI_EXTERN u8 acpi_gbl_global_lock_acquired; | ||
231 | ACPI_EXTERN u8 acpi_gbl_step_to_next_call; | 238 | ACPI_EXTERN u8 acpi_gbl_step_to_next_call; |
232 | ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; | 239 | ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; |
233 | ACPI_EXTERN u8 acpi_gbl_global_lock_present; | ||
234 | ACPI_EXTERN u8 acpi_gbl_events_initialized; | 240 | ACPI_EXTERN u8 acpi_gbl_events_initialized; |
235 | ACPI_EXTERN u8 acpi_gbl_system_awake_and_running; | 241 | ACPI_EXTERN u8 acpi_gbl_system_awake_and_running; |
236 | 242 | ||
243 | #ifndef DEFINE_ACPI_GLOBALS | ||
244 | |||
245 | /* Other miscellaneous */ | ||
246 | |||
237 | extern u8 acpi_gbl_shutdown; | 247 | extern u8 acpi_gbl_shutdown; |
238 | extern u32 acpi_gbl_startup_flags; | 248 | extern u32 acpi_gbl_startup_flags; |
239 | extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT]; | 249 | extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT]; |
@@ -241,6 +251,8 @@ extern const char *acpi_gbl_highest_dstate_names[4]; | |||
241 | extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; | 251 | extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; |
242 | extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; | 252 | extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; |
243 | 253 | ||
254 | #endif | ||
255 | |||
244 | /* Exception codes */ | 256 | /* Exception codes */ |
245 | 257 | ||
246 | extern char const *acpi_gbl_exception_names_env[]; | 258 | extern char const *acpi_gbl_exception_names_env[]; |
@@ -255,8 +267,6 @@ extern char const *acpi_gbl_exception_names_ctrl[]; | |||
255 | * | 267 | * |
256 | ****************************************************************************/ | 268 | ****************************************************************************/ |
257 | 269 | ||
258 | #define NUM_NS_TYPES ACPI_TYPE_INVALID+1 | ||
259 | |||
260 | #if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) | 270 | #if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) |
261 | #define NUM_PREDEFINED_NAMES 10 | 271 | #define NUM_PREDEFINED_NAMES 10 |
262 | #else | 272 | #else |
@@ -267,7 +277,7 @@ ACPI_EXTERN struct acpi_namespace_node acpi_gbl_root_node_struct; | |||
267 | ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_root_node; | 277 | ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_root_node; |
268 | ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_fadt_gpe_device; | 278 | ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_fadt_gpe_device; |
269 | 279 | ||
270 | extern const u8 acpi_gbl_ns_properties[NUM_NS_TYPES]; | 280 | extern const u8 acpi_gbl_ns_properties[ACPI_NUM_NS_TYPES]; |
271 | extern const struct acpi_predefined_names | 281 | extern const struct acpi_predefined_names |
272 | acpi_gbl_pre_defined_names[NUM_PREDEFINED_NAMES]; | 282 | acpi_gbl_pre_defined_names[NUM_PREDEFINED_NAMES]; |
273 | 283 | ||
@@ -275,8 +285,8 @@ extern const struct acpi_predefined_names | |||
275 | ACPI_EXTERN u32 acpi_gbl_current_node_count; | 285 | ACPI_EXTERN u32 acpi_gbl_current_node_count; |
276 | ACPI_EXTERN u32 acpi_gbl_current_node_size; | 286 | ACPI_EXTERN u32 acpi_gbl_current_node_size; |
277 | ACPI_EXTERN u32 acpi_gbl_max_concurrent_node_count; | 287 | ACPI_EXTERN u32 acpi_gbl_max_concurrent_node_count; |
278 | ACPI_EXTERN acpi_size acpi_gbl_entry_stack_pointer; | 288 | ACPI_EXTERN acpi_size *acpi_gbl_entry_stack_pointer; |
279 | ACPI_EXTERN acpi_size acpi_gbl_lowest_stack_pointer; | 289 | ACPI_EXTERN acpi_size *acpi_gbl_lowest_stack_pointer; |
280 | ACPI_EXTERN u32 acpi_gbl_deepest_nesting; | 290 | ACPI_EXTERN u32 acpi_gbl_deepest_nesting; |
281 | #endif | 291 | #endif |
282 | 292 | ||
diff --git a/include/acpi/achware.h b/include/acpi/achware.h index 4053df943453..d4fb9bbc903c 100644 --- a/include/acpi/achware.h +++ b/include/acpi/achware.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h index ce7c9d653910..e249ce5d3300 100644 --- a/include/acpi/acinterp.h +++ b/include/acpi/acinterp.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -215,8 +215,6 @@ acpi_ex_create_region(u8 * aml_start, | |||
215 | u32 aml_length, | 215 | u32 aml_length, |
216 | u8 region_space, struct acpi_walk_state *walk_state); | 216 | u8 region_space, struct acpi_walk_state *walk_state); |
217 | 217 | ||
218 | acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state); | ||
219 | |||
220 | acpi_status acpi_ex_create_event(struct acpi_walk_state *walk_state); | 218 | acpi_status acpi_ex_create_event(struct acpi_walk_state *walk_state); |
221 | 219 | ||
222 | acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state); | 220 | acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state); |
@@ -248,9 +246,16 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, | |||
248 | struct acpi_walk_state *walk_state); | 246 | struct acpi_walk_state *walk_state); |
249 | 247 | ||
250 | acpi_status | 248 | acpi_status |
249 | acpi_ex_acquire_mutex_object(u16 timeout, | ||
250 | union acpi_operand_object *obj_desc, | ||
251 | acpi_thread_id thread_id); | ||
252 | |||
253 | acpi_status | ||
251 | acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | 254 | acpi_ex_release_mutex(union acpi_operand_object *obj_desc, |
252 | struct acpi_walk_state *walk_state); | 255 | struct acpi_walk_state *walk_state); |
253 | 256 | ||
257 | acpi_status acpi_ex_release_mutex_object(union acpi_operand_object *obj_desc); | ||
258 | |||
254 | void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread); | 259 | void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread); |
255 | 260 | ||
256 | void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc); | 261 | void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc); |
@@ -455,9 +460,9 @@ void acpi_ex_relinquish_interpreter(void); | |||
455 | 460 | ||
456 | void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc); | 461 | void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc); |
457 | 462 | ||
458 | u8 acpi_ex_acquire_global_lock(u32 rule); | 463 | void acpi_ex_acquire_global_lock(u32 rule); |
459 | 464 | ||
460 | void acpi_ex_release_global_lock(u8 locked); | 465 | void acpi_ex_release_global_lock(u32 rule); |
461 | 466 | ||
462 | void acpi_ex_eisa_id_to_string(u32 numeric_id, char *out_string); | 467 | void acpi_ex_eisa_id_to_string(u32 numeric_id, char *out_string); |
463 | 468 | ||
diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h index 202cd4242ba1..c5cdc32ac2f8 100644 --- a/include/acpi/aclocal.h +++ b/include/acpi/aclocal.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -522,9 +522,8 @@ struct acpi_thread_state { | |||
522 | * AML arguments | 522 | * AML arguments |
523 | */ | 523 | */ |
524 | struct acpi_result_values { | 524 | struct acpi_result_values { |
525 | ACPI_STATE_COMMON u8 num_results; | 525 | ACPI_STATE_COMMON |
526 | u8 last_insert; | 526 | union acpi_operand_object *obj_desc[ACPI_RESULTS_FRAME_OBJ_NUM]; |
527 | union acpi_operand_object *obj_desc[ACPI_OBJ_NUM_OPERANDS]; | ||
528 | }; | 527 | }; |
529 | 528 | ||
530 | typedef | 529 | typedef |
@@ -604,6 +603,7 @@ union acpi_parse_value { | |||
604 | union acpi_parse_object *next; /* Next op */\ | 603 | union acpi_parse_object *next; /* Next op */\ |
605 | struct acpi_namespace_node *node; /* For use by interpreter */\ | 604 | struct acpi_namespace_node *node; /* For use by interpreter */\ |
606 | union acpi_parse_value value; /* Value or args associated with the opcode */\ | 605 | union acpi_parse_value value; /* Value or args associated with the opcode */\ |
606 | u8 arg_list_length; /* Number of elements in the arg list */\ | ||
607 | ACPI_DISASM_ONLY_MEMBERS (\ | 607 | ACPI_DISASM_ONLY_MEMBERS (\ |
608 | u8 disasm_flags; /* Used during AML disassembly */\ | 608 | u8 disasm_flags; /* Used during AML disassembly */\ |
609 | u8 disasm_opcode; /* Subtype used for disassembly */\ | 609 | u8 disasm_opcode; /* Subtype used for disassembly */\ |
@@ -696,6 +696,8 @@ struct acpi_parse_state { | |||
696 | #define ACPI_PARSEOP_NAMED 0x02 | 696 | #define ACPI_PARSEOP_NAMED 0x02 |
697 | #define ACPI_PARSEOP_DEFERRED 0x04 | 697 | #define ACPI_PARSEOP_DEFERRED 0x04 |
698 | #define ACPI_PARSEOP_BYTELIST 0x08 | 698 | #define ACPI_PARSEOP_BYTELIST 0x08 |
699 | #define ACPI_PARSEOP_IN_STACK 0x10 | ||
700 | #define ACPI_PARSEOP_TARGET 0x20 | ||
699 | #define ACPI_PARSEOP_IN_CACHE 0x80 | 701 | #define ACPI_PARSEOP_IN_CACHE 0x80 |
700 | 702 | ||
701 | /* Parse object disasm_flags */ | 703 | /* Parse object disasm_flags */ |
diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h index 99d171c87c84..fb41a3b802fc 100644 --- a/include/acpi/acmacros.h +++ b/include/acpi/acmacros.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -61,30 +61,6 @@ | |||
61 | 61 | ||
62 | #define ACPI_ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0])) | 62 | #define ACPI_ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0])) |
63 | 63 | ||
64 | #ifdef ACPI_NO_INTEGER64_SUPPORT | ||
65 | /* | ||
66 | * acpi_integer is 32-bits, no 64-bit support on this platform | ||
67 | */ | ||
68 | #define ACPI_LODWORD(l) ((u32)(l)) | ||
69 | #define ACPI_HIDWORD(l) ((u32)(0)) | ||
70 | |||
71 | #else | ||
72 | |||
73 | /* | ||
74 | * Full 64-bit address/integer on both 32-bit and 64-bit platforms | ||
75 | */ | ||
76 | #define ACPI_LODWORD(l) ((u32)(u64)(l)) | ||
77 | #define ACPI_HIDWORD(l) ((u32)(((*(struct uint64_struct *)(void *)(&l))).hi)) | ||
78 | #endif | ||
79 | |||
80 | /* | ||
81 | * printf() format helpers | ||
82 | */ | ||
83 | |||
84 | /* Split 64-bit integer into two 32-bit values. Use with %8.8_x%8.8_x */ | ||
85 | |||
86 | #define ACPI_FORMAT_UINT64(i) ACPI_HIDWORD(i),ACPI_LODWORD(i) | ||
87 | |||
88 | /* | 64 | /* |
89 | * Extract data using a pointer. Any more than a byte and we | 65 | * Extract data using a pointer. Any more than a byte and we |
90 | * get into potential aligment issues -- see the STORE macros below. | 66 | * get into potential aligment issues -- see the STORE macros below. |
@@ -122,6 +98,31 @@ | |||
122 | #endif | 98 | #endif |
123 | 99 | ||
124 | /* | 100 | /* |
101 | * Full 64-bit integer must be available on both 32-bit and 64-bit platforms | ||
102 | */ | ||
103 | struct acpi_integer_overlay { | ||
104 | u32 lo_dword; | ||
105 | u32 hi_dword; | ||
106 | }; | ||
107 | |||
108 | #define ACPI_LODWORD(integer) (ACPI_CAST_PTR (struct acpi_integer_overlay, &integer)->lo_dword) | ||
109 | #define ACPI_HIDWORD(integer) (ACPI_CAST_PTR (struct acpi_integer_overlay, &integer)->hi_dword) | ||
110 | |||
111 | /* | ||
112 | * printf() format helpers | ||
113 | */ | ||
114 | |||
115 | /* Split 64-bit integer into two 32-bit values. Use with %8.8_x%8.8_x */ | ||
116 | |||
117 | #define ACPI_FORMAT_UINT64(i) ACPI_HIDWORD(i),ACPI_LODWORD(i) | ||
118 | |||
119 | #if ACPI_MACHINE_WIDTH == 64 | ||
120 | #define ACPI_FORMAT_NATIVE_UINT(i) ACPI_FORMAT_UINT64(i) | ||
121 | #else | ||
122 | #define ACPI_FORMAT_NATIVE_UINT(i) 0, (i) | ||
123 | #endif | ||
124 | |||
125 | /* | ||
125 | * Macros for moving data around to/from buffers that are possibly unaligned. | 126 | * Macros for moving data around to/from buffers that are possibly unaligned. |
126 | * If the hardware supports the transfer of unaligned data, just do the store. | 127 | * If the hardware supports the transfer of unaligned data, just do the store. |
127 | * Otherwise, we have to move one byte at a time. | 128 | * Otherwise, we have to move one byte at a time. |
@@ -137,29 +138,29 @@ | |||
137 | 138 | ||
138 | /* These macros reverse the bytes during the move, converting little-endian to big endian */ | 139 | /* These macros reverse the bytes during the move, converting little-endian to big endian */ |
139 | 140 | ||
140 | /* Big Endian <== Little Endian */ | 141 | /* Big Endian <== Little Endian */ |
141 | /* Hi...Lo Lo...Hi */ | 142 | /* Hi...Lo Lo...Hi */ |
142 | /* 16-bit source, 16/32/64 destination */ | 143 | /* 16-bit source, 16/32/64 destination */ |
143 | 144 | ||
144 | #define ACPI_MOVE_16_TO_16(d,s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[1];\ | 145 | #define ACPI_MOVE_16_TO_16(d,s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[1];\ |
145 | (( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[0];} | 146 | (( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[0];} |
146 | 147 | ||
147 | #define ACPI_MOVE_16_TO_32(d,s) {(*(u32 *)(void *)(d))=0;\ | 148 | #define ACPI_MOVE_16_TO_32(d,s) {(*(u32 *)(void *)(d))=0;\ |
148 | ((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[1];\ | 149 | ((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[1];\ |
149 | ((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[0];} | 150 | ((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[0];} |
150 | 151 | ||
151 | #define ACPI_MOVE_16_TO_64(d,s) {(*(u64 *)(void *)(d))=0;\ | 152 | #define ACPI_MOVE_16_TO_64(d,s) {(*(u64 *)(void *)(d))=0;\ |
152 | ((u8 *)(void *)(d))[6] = ((u8 *)(void *)(s))[1];\ | 153 | ((u8 *)(void *)(d))[6] = ((u8 *)(void *)(s))[1];\ |
153 | ((u8 *)(void *)(d))[7] = ((u8 *)(void *)(s))[0];} | 154 | ((u8 *)(void *)(d))[7] = ((u8 *)(void *)(s))[0];} |
154 | 155 | ||
155 | /* 32-bit source, 16/32/64 destination */ | 156 | /* 32-bit source, 16/32/64 destination */ |
156 | 157 | ||
157 | #define ACPI_MOVE_32_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */ | 158 | #define ACPI_MOVE_32_TO_16(d,s) ACPI_MOVE_16_TO_16(d,s) /* Truncate to 16 */ |
158 | 159 | ||
159 | #define ACPI_MOVE_32_TO_32(d,s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[3];\ | 160 | #define ACPI_MOVE_32_TO_32(d,s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[3];\ |
160 | (( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[2];\ | 161 | (( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[2];\ |
161 | (( u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[1];\ | 162 | (( u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[1];\ |
162 | (( u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[0];} | 163 | (( u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[0];} |
163 | 164 | ||
164 | #define ACPI_MOVE_32_TO_64(d,s) {(*(u64 *)(void *)(d))=0;\ | 165 | #define ACPI_MOVE_32_TO_64(d,s) {(*(u64 *)(void *)(d))=0;\ |
165 | ((u8 *)(void *)(d))[4] = ((u8 *)(void *)(s))[3];\ | 166 | ((u8 *)(void *)(d))[4] = ((u8 *)(void *)(s))[3];\ |
diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h index 34bfae8a05f3..c1343a9265fa 100644 --- a/include/acpi/acnames.h +++ b/include/acpi/acnames.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/acnamesp.h b/include/acpi/acnamesp.h index 5ef38a6c8a61..713b30903fe5 100644 --- a/include/acpi/acnamesp.h +++ b/include/acpi/acnamesp.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -113,7 +113,8 @@ acpi_ns_parse_table(acpi_native_uint table_index, | |||
113 | 113 | ||
114 | acpi_status | 114 | acpi_status |
115 | acpi_ns_one_complete_parse(acpi_native_uint pass_number, | 115 | acpi_ns_one_complete_parse(acpi_native_uint pass_number, |
116 | acpi_native_uint table_index); | 116 | acpi_native_uint table_index, |
117 | struct acpi_namespace_node *start_node); | ||
117 | 118 | ||
118 | /* | 119 | /* |
119 | * nsaccess - Top-level namespace access | 120 | * nsaccess - Top-level namespace access |
diff --git a/include/acpi/acobject.h b/include/acpi/acobject.h index 7e1211a8b8fa..e9657dac69b7 100644 --- a/include/acpi/acobject.h +++ b/include/acpi/acobject.h | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -155,8 +155,9 @@ struct acpi_object_event { | |||
155 | struct acpi_object_mutex { | 155 | struct acpi_object_mutex { |
156 | ACPI_OBJECT_COMMON_HEADER u8 sync_level; /* 0-15, specified in Mutex() call */ | 156 | ACPI_OBJECT_COMMON_HEADER u8 sync_level; /* 0-15, specified in Mutex() call */ |
157 | u16 acquisition_depth; /* Allow multiple Acquires, same thread */ | 157 | u16 acquisition_depth; /* Allow multiple Acquires, same thread */ |
158 | struct acpi_thread_state *owner_thread; /* Current owner of the mutex */ | ||
159 | acpi_mutex os_mutex; /* Actual OS synchronization object */ | 158 | acpi_mutex os_mutex; /* Actual OS synchronization object */ |
159 | acpi_thread_id thread_id; /* Current owner of the mutex */ | ||
160 | struct acpi_thread_state *owner_thread; /* Current owner of the mutex */ | ||
160 | union acpi_operand_object *prev; /* Link for list of acquired mutexes */ | 161 | union acpi_operand_object *prev; /* Link for list of acquired mutexes */ |
161 | union acpi_operand_object *next; /* Link for list of acquired mutexes */ | 162 | union acpi_operand_object *next; /* Link for list of acquired mutexes */ |
162 | struct acpi_namespace_node *node; /* Containing namespace node */ | 163 | struct acpi_namespace_node *node; /* Containing namespace node */ |
diff --git a/include/acpi/acopcode.h b/include/acpi/acopcode.h index e6f76a280a94..dfdf63327885 100644 --- a/include/acpi/acopcode.h +++ b/include/acpi/acopcode.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -233,7 +233,7 @@ | |||
233 | #define ARGI_CREATE_WORD_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE) | 233 | #define ARGI_CREATE_WORD_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE) |
234 | #define ARGI_DATA_REGION_OP ARGI_LIST3 (ARGI_STRING, ARGI_STRING, ARGI_STRING) | 234 | #define ARGI_DATA_REGION_OP ARGI_LIST3 (ARGI_STRING, ARGI_STRING, ARGI_STRING) |
235 | #define ARGI_DEBUG_OP ARG_NONE | 235 | #define ARGI_DEBUG_OP ARG_NONE |
236 | #define ARGI_DECREMENT_OP ARGI_LIST1 (ARGI_INTEGER_REF) | 236 | #define ARGI_DECREMENT_OP ARGI_LIST1 (ARGI_TARGETREF) |
237 | #define ARGI_DEREF_OF_OP ARGI_LIST1 (ARGI_REF_OR_STRING) | 237 | #define ARGI_DEREF_OF_OP ARGI_LIST1 (ARGI_REF_OR_STRING) |
238 | #define ARGI_DEVICE_OP ARGI_INVALID_OPCODE | 238 | #define ARGI_DEVICE_OP ARGI_INVALID_OPCODE |
239 | #define ARGI_DIVIDE_OP ARGI_LIST4 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF, ARGI_TARGETREF) | 239 | #define ARGI_DIVIDE_OP ARGI_LIST4 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF, ARGI_TARGETREF) |
@@ -246,7 +246,7 @@ | |||
246 | #define ARGI_FIND_SET_RIGHT_BIT_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF) | 246 | #define ARGI_FIND_SET_RIGHT_BIT_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF) |
247 | #define ARGI_FROM_BCD_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_FIXED_TARGET) | 247 | #define ARGI_FROM_BCD_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_FIXED_TARGET) |
248 | #define ARGI_IF_OP ARGI_INVALID_OPCODE | 248 | #define ARGI_IF_OP ARGI_INVALID_OPCODE |
249 | #define ARGI_INCREMENT_OP ARGI_LIST1 (ARGI_INTEGER_REF) | 249 | #define ARGI_INCREMENT_OP ARGI_LIST1 (ARGI_TARGETREF) |
250 | #define ARGI_INDEX_FIELD_OP ARGI_INVALID_OPCODE | 250 | #define ARGI_INDEX_FIELD_OP ARGI_INVALID_OPCODE |
251 | #define ARGI_INDEX_OP ARGI_LIST3 (ARGI_COMPLEXOBJ, ARGI_INTEGER, ARGI_TARGETREF) | 251 | #define ARGI_INDEX_OP ARGI_LIST3 (ARGI_COMPLEXOBJ, ARGI_INTEGER, ARGI_TARGETREF) |
252 | #define ARGI_LAND_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER) | 252 | #define ARGI_LAND_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER) |
diff --git a/include/acpi/acoutput.h b/include/acpi/acoutput.h index c090a8b0bc99..e17873defcec 100644 --- a/include/acpi/acoutput.h +++ b/include/acpi/acoutput.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/acparser.h b/include/acpi/acparser.h index 85c358e21014..23ee0fbf5619 100644 --- a/include/acpi/acparser.h +++ b/include/acpi/acparser.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -109,6 +109,8 @@ const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode); | |||
109 | 109 | ||
110 | char *acpi_ps_get_opcode_name(u16 opcode); | 110 | char *acpi_ps_get_opcode_name(u16 opcode); |
111 | 111 | ||
112 | u8 acpi_ps_get_argument_count(u32 op_type); | ||
113 | |||
112 | /* | 114 | /* |
113 | * psparse - top level parsing routines | 115 | * psparse - top level parsing routines |
114 | */ | 116 | */ |
diff --git a/include/acpi/acpi.h b/include/acpi/acpi.h index 2e5f00d3ea0d..c515ef6cc89e 100644 --- a/include/acpi/acpi.h +++ b/include/acpi/acpi.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 4839f2af94c3..d4a560d2deb6 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h | |||
@@ -8,7 +8,7 @@ | |||
8 | *****************************************************************************/ | 8 | *****************************************************************************/ |
9 | 9 | ||
10 | /* | 10 | /* |
11 | * Copyright (C) 2000 - 2007, R. Byron Moore | 11 | * Copyright (C) 2000 - 2008, Intel Corp. |
12 | * All rights reserved. | 12 | * All rights reserved. |
13 | * | 13 | * |
14 | * Redistribution and use in source and binary forms, with or without | 14 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index d970f7f99549..2c3806e6546f 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -119,6 +119,11 @@ acpi_status | |||
119 | acpi_get_table_by_index(acpi_native_uint table_index, | 119 | acpi_get_table_by_index(acpi_native_uint table_index, |
120 | struct acpi_table_header **out_table); | 120 | struct acpi_table_header **out_table); |
121 | 121 | ||
122 | acpi_status | ||
123 | acpi_install_table_handler(acpi_tbl_handler handler, void *context); | ||
124 | |||
125 | acpi_status acpi_remove_table_handler(acpi_tbl_handler handler); | ||
126 | |||
122 | /* | 127 | /* |
123 | * Namespace and name interfaces | 128 | * Namespace and name interfaces |
124 | */ | 129 | */ |
diff --git a/include/acpi/acresrc.h b/include/acpi/acresrc.h index 9486ab266a5e..eef5bd7a59fa 100644 --- a/include/acpi/acresrc.h +++ b/include/acpi/acresrc.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -94,6 +94,7 @@ typedef const struct acpi_rsconvert_info { | |||
94 | #define ACPI_RSC_BITMASK16 18 | 94 | #define ACPI_RSC_BITMASK16 18 |
95 | #define ACPI_RSC_EXIT_NE 19 | 95 | #define ACPI_RSC_EXIT_NE 19 |
96 | #define ACPI_RSC_EXIT_LE 20 | 96 | #define ACPI_RSC_EXIT_LE 20 |
97 | #define ACPI_RSC_EXIT_EQ 21 | ||
97 | 98 | ||
98 | /* Resource Conversion sub-opcodes */ | 99 | /* Resource Conversion sub-opcodes */ |
99 | 100 | ||
diff --git a/include/acpi/acstruct.h b/include/acpi/acstruct.h index 88482655407f..a907c67d651e 100644 --- a/include/acpi/acstruct.h +++ b/include/acpi/acstruct.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -80,12 +80,15 @@ struct acpi_walk_state { | |||
80 | u16 opcode; /* Current AML opcode */ | 80 | u16 opcode; /* Current AML opcode */ |
81 | u8 next_op_info; /* Info about next_op */ | 81 | u8 next_op_info; /* Info about next_op */ |
82 | u8 num_operands; /* Stack pointer for Operands[] array */ | 82 | u8 num_operands; /* Stack pointer for Operands[] array */ |
83 | u8 operand_index; /* Index into operand stack, to be used by acpi_ds_obj_stack_push */ | ||
83 | acpi_owner_id owner_id; /* Owner of objects created during the walk */ | 84 | acpi_owner_id owner_id; /* Owner of objects created during the walk */ |
84 | u8 last_predicate; /* Result of last predicate */ | 85 | u8 last_predicate; /* Result of last predicate */ |
85 | u8 current_result; | 86 | u8 current_result; |
86 | u8 return_used; | 87 | u8 return_used; |
87 | u8 scope_depth; | 88 | u8 scope_depth; |
88 | u8 pass_number; /* Parse pass during table load */ | 89 | u8 pass_number; /* Parse pass during table load */ |
90 | u8 result_size; /* Total elements for the result stack */ | ||
91 | u8 result_count; /* Current number of occupied elements of result stack */ | ||
89 | u32 aml_offset; | 92 | u32 aml_offset; |
90 | u32 arg_types; | 93 | u32 arg_types; |
91 | u32 method_breakpoint; /* For single stepping */ | 94 | u32 method_breakpoint; /* For single stepping */ |
diff --git a/include/acpi/actables.h b/include/acpi/actables.h index 2b9f46f9da4d..4b36a55b0b3b 100644 --- a/include/acpi/actables.h +++ b/include/acpi/actables.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index 955adfb8d64c..1ebbe883f786 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index a1b1b2ee3e51..9af239bd1153 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -58,20 +58,28 @@ | |||
58 | * it more difficult to inadvertently type in the wrong signature. | 58 | * it more difficult to inadvertently type in the wrong signature. |
59 | */ | 59 | */ |
60 | #define ACPI_SIG_ASF "ASF!" /* Alert Standard Format table */ | 60 | #define ACPI_SIG_ASF "ASF!" /* Alert Standard Format table */ |
61 | #define ACPI_SIG_BERT "BERT" /* Boot Error Record Table */ | ||
61 | #define ACPI_SIG_BOOT "BOOT" /* Simple Boot Flag Table */ | 62 | #define ACPI_SIG_BOOT "BOOT" /* Simple Boot Flag Table */ |
62 | #define ACPI_SIG_CPEP "CPEP" /* Corrected Platform Error Polling table */ | 63 | #define ACPI_SIG_CPEP "CPEP" /* Corrected Platform Error Polling table */ |
63 | #define ACPI_SIG_DBGP "DBGP" /* Debug Port table */ | 64 | #define ACPI_SIG_DBGP "DBGP" /* Debug Port table */ |
64 | #define ACPI_SIG_DMAR "DMAR" /* DMA Remapping table */ | 65 | #define ACPI_SIG_DMAR "DMAR" /* DMA Remapping table */ |
65 | #define ACPI_SIG_ECDT "ECDT" /* Embedded Controller Boot Resources Table */ | 66 | #define ACPI_SIG_ECDT "ECDT" /* Embedded Controller Boot Resources Table */ |
67 | #define ACPI_SIG_EINJ "EINJ" /* Error Injection table */ | ||
68 | #define ACPI_SIG_ERST "ERST" /* Error Record Serialization Table */ | ||
69 | #define ACPI_SIG_HEST "HEST" /* Hardware Error Source Table */ | ||
66 | #define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */ | 70 | #define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */ |
71 | #define ACPI_SIG_IBFT "IBFT" /* i_sCSI Boot Firmware Table */ | ||
67 | #define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */ | 72 | #define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */ |
68 | #define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */ | 73 | #define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */ |
69 | #define ACPI_SIG_SBST "SBST" /* Smart Battery Specification Table */ | 74 | #define ACPI_SIG_SBST "SBST" /* Smart Battery Specification Table */ |
75 | #define ACPI_SIG_SLIC "SLIC" /* Software Licensing Description Table */ | ||
70 | #define ACPI_SIG_SLIT "SLIT" /* System Locality Distance Information Table */ | 76 | #define ACPI_SIG_SLIT "SLIT" /* System Locality Distance Information Table */ |
71 | #define ACPI_SIG_SPCR "SPCR" /* Serial Port Console Redirection table */ | 77 | #define ACPI_SIG_SPCR "SPCR" /* Serial Port Console Redirection table */ |
72 | #define ACPI_SIG_SPMI "SPMI" /* Server Platform Management Interface table */ | 78 | #define ACPI_SIG_SPMI "SPMI" /* Server Platform Management Interface table */ |
73 | #define ACPI_SIG_SRAT "SRAT" /* System Resource Affinity Table */ | 79 | #define ACPI_SIG_SRAT "SRAT" /* System Resource Affinity Table */ |
74 | #define ACPI_SIG_TCPA "TCPA" /* Trusted Computing Platform Alliance table */ | 80 | #define ACPI_SIG_TCPA "TCPA" /* Trusted Computing Platform Alliance table */ |
81 | #define ACPI_SIG_UEFI "UEFI" /* Uefi Boot Optimization Table */ | ||
82 | #define ACPI_SIG_WDAT "WDAT" /* Watchdog Action Table */ | ||
75 | #define ACPI_SIG_WDRT "WDRT" /* Watchdog Resource Table */ | 83 | #define ACPI_SIG_WDRT "WDRT" /* Watchdog Resource Table */ |
76 | 84 | ||
77 | /* | 85 | /* |
@@ -86,13 +94,25 @@ | |||
86 | * portable, so do not use any other bitfield types. | 94 | * portable, so do not use any other bitfield types. |
87 | */ | 95 | */ |
88 | 96 | ||
89 | /* Common Sub-table header (used in MADT, SRAT, etc.) */ | 97 | /* Common Subtable header (used in MADT, SRAT, etc.) */ |
90 | 98 | ||
91 | struct acpi_subtable_header { | 99 | struct acpi_subtable_header { |
92 | u8 type; | 100 | u8 type; |
93 | u8 length; | 101 | u8 length; |
94 | }; | 102 | }; |
95 | 103 | ||
104 | /* Common Subtable header for WHEA tables (EINJ, ERST, WDAT) */ | ||
105 | |||
106 | struct acpi_whea_header { | ||
107 | u8 action; | ||
108 | u8 instruction; | ||
109 | u8 flags; | ||
110 | u8 reserved; | ||
111 | struct acpi_generic_address register_region; | ||
112 | u64 value; /* Value used with Read/Write register */ | ||
113 | u64 mask; /* Bitmask required for this register instruction */ | ||
114 | }; | ||
115 | |||
96 | /******************************************************************************* | 116 | /******************************************************************************* |
97 | * | 117 | * |
98 | * ASF - Alert Standard Format table (Signature "ASF!") | 118 | * ASF - Alert Standard Format table (Signature "ASF!") |
@@ -204,6 +224,35 @@ struct acpi_asf_address { | |||
204 | 224 | ||
205 | /******************************************************************************* | 225 | /******************************************************************************* |
206 | * | 226 | * |
227 | * BERT - Boot Error Record Table | ||
228 | * | ||
229 | ******************************************************************************/ | ||
230 | |||
231 | struct acpi_table_bert { | ||
232 | struct acpi_table_header header; /* Common ACPI table header */ | ||
233 | u32 region_length; /* Length of the boot error region */ | ||
234 | u64 address; /* Physical addresss of the error region */ | ||
235 | }; | ||
236 | |||
237 | /* Boot Error Region */ | ||
238 | |||
239 | struct acpi_bert_region { | ||
240 | u32 block_status; | ||
241 | u32 raw_data_offset; | ||
242 | u32 raw_data_length; | ||
243 | u32 data_length; | ||
244 | u32 error_severity; | ||
245 | }; | ||
246 | |||
247 | /* block_status Flags */ | ||
248 | |||
249 | #define ACPI_BERT_UNCORRECTABLE (1) | ||
250 | #define ACPI_BERT_CORRECTABLE (2) | ||
251 | #define ACPI_BERT_MULTIPLE_UNCORRECTABLE (4) | ||
252 | #define ACPI_BERT_MULTIPLE_CORRECTABLE (8) | ||
253 | |||
254 | /******************************************************************************* | ||
255 | * | ||
207 | * BOOT - Simple Boot Flag Table | 256 | * BOOT - Simple Boot Flag Table |
208 | * | 257 | * |
209 | ******************************************************************************/ | 258 | ******************************************************************************/ |
@@ -350,6 +399,352 @@ struct acpi_table_ecdt { | |||
350 | 399 | ||
351 | /******************************************************************************* | 400 | /******************************************************************************* |
352 | * | 401 | * |
402 | * EINJ - Error Injection Table | ||
403 | * | ||
404 | ******************************************************************************/ | ||
405 | |||
406 | struct acpi_table_einj { | ||
407 | struct acpi_table_header header; /* Common ACPI table header */ | ||
408 | u32 header_length; | ||
409 | u32 reserved; | ||
410 | u32 entries; | ||
411 | }; | ||
412 | |||
413 | /* EINJ Injection Instruction Entries (actions) */ | ||
414 | |||
415 | struct acpi_einj_entry { | ||
416 | struct acpi_whea_header whea_header; /* Common header for WHEA tables */ | ||
417 | }; | ||
418 | |||
419 | /* Values for Action field above */ | ||
420 | |||
421 | enum acpi_einj_actions { | ||
422 | ACPI_EINJ_BEGIN_OPERATION = 0, | ||
423 | ACPI_EINJ_GET_TRIGGER_TABLE = 1, | ||
424 | ACPI_EINJ_SET_ERROR_TYPE = 2, | ||
425 | ACPI_EINJ_GET_ERROR_TYPE = 3, | ||
426 | ACPI_EINJ_END_OPERATION = 4, | ||
427 | ACPI_EINJ_EXECUTE_OPERATION = 5, | ||
428 | ACPI_EINJ_CHECK_BUSY_STATUS = 6, | ||
429 | ACPI_EINJ_GET_COMMAND_STATUS = 7, | ||
430 | ACPI_EINJ_ACTION_RESERVED = 8, /* 8 and greater are reserved */ | ||
431 | ACPI_EINJ_TRIGGER_ERROR = 0xFF /* Except for this value */ | ||
432 | }; | ||
433 | |||
434 | /* Values for Instruction field above */ | ||
435 | |||
436 | enum acpi_einj_instructions { | ||
437 | ACPI_EINJ_READ_REGISTER = 0, | ||
438 | ACPI_EINJ_READ_REGISTER_VALUE = 1, | ||
439 | ACPI_EINJ_WRITE_REGISTER = 2, | ||
440 | ACPI_EINJ_WRITE_REGISTER_VALUE = 3, | ||
441 | ACPI_EINJ_NOOP = 4, | ||
442 | ACPI_EINJ_INSTRUCTION_RESERVED = 5 /* 5 and greater are reserved */ | ||
443 | }; | ||
444 | |||
445 | /* EINJ Trigger Error Action Table */ | ||
446 | |||
447 | struct acpi_einj_trigger { | ||
448 | u32 header_size; | ||
449 | u32 revision; | ||
450 | u32 table_size; | ||
451 | u32 entry_count; | ||
452 | }; | ||
453 | |||
454 | /******************************************************************************* | ||
455 | * | ||
456 | * ERST - Error Record Serialization Table | ||
457 | * | ||
458 | ******************************************************************************/ | ||
459 | |||
460 | struct acpi_table_erst { | ||
461 | struct acpi_table_header header; /* Common ACPI table header */ | ||
462 | u32 header_length; | ||
463 | u32 reserved; | ||
464 | u32 entries; | ||
465 | }; | ||
466 | |||
467 | /* ERST Serialization Entries (actions) */ | ||
468 | |||
469 | struct acpi_erst_entry { | ||
470 | struct acpi_whea_header whea_header; /* Common header for WHEA tables */ | ||
471 | }; | ||
472 | |||
473 | /* Values for Action field above */ | ||
474 | |||
475 | enum acpi_erst_actions { | ||
476 | ACPI_ERST_BEGIN_WRITE_OPERATION = 0, | ||
477 | ACPI_ERST_BEGIN_READ_OPERATION = 1, | ||
478 | ACPI_ERST_BETGIN_CLEAR_OPERATION = 2, | ||
479 | ACPI_ERST_END_OPERATION = 3, | ||
480 | ACPI_ERST_SET_RECORD_OFFSET = 4, | ||
481 | ACPI_ERST_EXECUTE_OPERATION = 5, | ||
482 | ACPI_ERST_CHECK_BUSY_STATUS = 6, | ||
483 | ACPI_ERST_GET_COMMAND_STATUS = 7, | ||
484 | ACPI_ERST_GET_RECORD_IDENTIFIER = 8, | ||
485 | ACPI_ERST_SET_RECORD_IDENTIFIER = 9, | ||
486 | ACPI_ERST_GET_RECORD_COUNT = 10, | ||
487 | ACPI_ERST_BEGIN_DUMMY_WRIITE = 11, | ||
488 | ACPI_ERST_NOT_USED = 12, | ||
489 | ACPI_ERST_GET_ERROR_RANGE = 13, | ||
490 | ACPI_ERST_GET_ERROR_LENGTH = 14, | ||
491 | ACPI_ERST_GET_ERROR_ATTRIBUTES = 15, | ||
492 | ACPI_ERST_ACTION_RESERVED = 16 /* 16 and greater are reserved */ | ||
493 | }; | ||
494 | |||
495 | /* Values for Instruction field above */ | ||
496 | |||
497 | enum acpi_erst_instructions { | ||
498 | ACPI_ERST_READ_REGISTER = 0, | ||
499 | ACPI_ERST_READ_REGISTER_VALUE = 1, | ||
500 | ACPI_ERST_WRITE_REGISTER = 2, | ||
501 | ACPI_ERST_WRITE_REGISTER_VALUE = 3, | ||
502 | ACPI_ERST_NOOP = 4, | ||
503 | ACPI_ERST_LOAD_VAR1 = 5, | ||
504 | ACPI_ERST_LOAD_VAR2 = 6, | ||
505 | ACPI_ERST_STORE_VAR1 = 7, | ||
506 | ACPI_ERST_ADD = 8, | ||
507 | ACPI_ERST_SUBTRACT = 9, | ||
508 | ACPI_ERST_ADD_VALUE = 10, | ||
509 | ACPI_ERST_SUBTRACT_VALUE = 11, | ||
510 | ACPI_ERST_STALL = 12, | ||
511 | ACPI_ERST_STALL_WHILE_TRUE = 13, | ||
512 | ACPI_ERST_SKIP_NEXT_IF_TRUE = 14, | ||
513 | ACPI_ERST_GOTO = 15, | ||
514 | ACPI_ERST_SET_SRC_ADDRESS_BASE = 16, | ||
515 | ACPI_ERST_SET_DST_ADDRESS_BASE = 17, | ||
516 | ACPI_ERST_MOVE_DATA = 18, | ||
517 | ACPI_ERST_INSTRUCTION_RESERVED = 19 /* 19 and greater are reserved */ | ||
518 | }; | ||
519 | |||
520 | /******************************************************************************* | ||
521 | * | ||
522 | * HEST - Hardware Error Source Table | ||
523 | * | ||
524 | ******************************************************************************/ | ||
525 | |||
526 | struct acpi_table_hest { | ||
527 | struct acpi_table_header header; /* Common ACPI table header */ | ||
528 | u32 error_source_count; | ||
529 | }; | ||
530 | |||
531 | /* HEST subtable header */ | ||
532 | |||
533 | struct acpi_hest_header { | ||
534 | u16 type; | ||
535 | }; | ||
536 | |||
537 | /* Values for Type field above for subtables */ | ||
538 | |||
539 | enum acpi_hest_types { | ||
540 | ACPI_HEST_TYPE_XPF_MACHINE_CHECK = 0, | ||
541 | ACPI_HEST_TYPE_XPF_CORRECTED_MACHINE_CHECK = 1, | ||
542 | ACPI_HEST_TYPE_XPF_UNUSED = 2, | ||
543 | ACPI_HEST_TYPE_XPF_NON_MASKABLE_INTERRUPT = 3, | ||
544 | ACPI_HEST_TYPE_IPF_CORRECTED_MACHINE_CHECK = 4, | ||
545 | ACPI_HEST_TYPE_IPF_CORRECTED_PLATFORM_ERROR = 5, | ||
546 | ACPI_HEST_TYPE_AER_ROOT_PORT = 6, | ||
547 | ACPI_HEST_TYPE_AER_ENDPOINT = 7, | ||
548 | ACPI_HEST_TYPE_AER_BRIDGE = 8, | ||
549 | ACPI_HEST_TYPE_GENERIC_HARDWARE_ERROR_SOURCE = 9, | ||
550 | ACPI_HEST_TYPE_RESERVED = 10 /* 10 and greater are reserved */ | ||
551 | }; | ||
552 | |||
553 | /* | ||
554 | * HEST Sub-subtables | ||
555 | */ | ||
556 | |||
557 | /* XPF Machine Check Error Bank */ | ||
558 | |||
559 | struct acpi_hest_xpf_error_bank { | ||
560 | u8 bank_number; | ||
561 | u8 clear_status_on_init; | ||
562 | u8 status_format; | ||
563 | u8 config_write_enable; | ||
564 | u32 control_register; | ||
565 | u64 control_init_data; | ||
566 | u32 status_register; | ||
567 | u32 address_register; | ||
568 | u32 misc_register; | ||
569 | }; | ||
570 | |||
571 | /* Generic Error Status */ | ||
572 | |||
573 | struct acpi_hest_generic_status { | ||
574 | u32 block_status; | ||
575 | u32 raw_data_offset; | ||
576 | u32 raw_data_length; | ||
577 | u32 data_length; | ||
578 | u32 error_severity; | ||
579 | }; | ||
580 | |||
581 | /* Generic Error Data */ | ||
582 | |||
583 | struct acpi_hest_generic_data { | ||
584 | u8 section_type[16]; | ||
585 | u32 error_severity; | ||
586 | u16 revision; | ||
587 | u8 validation_bits; | ||
588 | u8 flags; | ||
589 | u32 error_data_length; | ||
590 | u8 fru_id[16]; | ||
591 | u8 fru_text[20]; | ||
592 | }; | ||
593 | |||
594 | /* Common HEST structure for PCI/AER types below (6,7,8) */ | ||
595 | |||
596 | struct acpi_hest_aer_common { | ||
597 | u16 source_id; | ||
598 | u16 config_write_enable; | ||
599 | u8 flags; | ||
600 | u8 enabled; | ||
601 | u32 records_to_pre_allocate; | ||
602 | u32 max_sections_per_record; | ||
603 | u32 bus; | ||
604 | u16 device; | ||
605 | u16 function; | ||
606 | u16 device_control; | ||
607 | u16 reserved; | ||
608 | u32 uncorrectable_error_mask; | ||
609 | u32 uncorrectable_error_severity; | ||
610 | u32 correctable_error_mask; | ||
611 | u32 advanced_error_cababilities; | ||
612 | }; | ||
613 | |||
614 | /* Hardware Error Notification */ | ||
615 | |||
616 | struct acpi_hest_notify { | ||
617 | u8 type; | ||
618 | u8 length; | ||
619 | u16 config_write_enable; | ||
620 | u32 poll_interval; | ||
621 | u32 vector; | ||
622 | u32 polling_threshold_value; | ||
623 | u32 polling_threshold_window; | ||
624 | u32 error_threshold_value; | ||
625 | u32 error_threshold_window; | ||
626 | }; | ||
627 | |||
628 | /* Values for Notify Type field above */ | ||
629 | |||
630 | enum acpi_hest_notify_types { | ||
631 | ACPI_HEST_NOTIFY_POLLED = 0, | ||
632 | ACPI_HEST_NOTIFY_EXTERNAL = 1, | ||
633 | ACPI_HEST_NOTIFY_LOCAL = 2, | ||
634 | ACPI_HEST_NOTIFY_SCI = 3, | ||
635 | ACPI_HEST_NOTIFY_NMI = 4, | ||
636 | ACPI_HEST_NOTIFY_RESERVED = 5 /* 5 and greater are reserved */ | ||
637 | }; | ||
638 | |||
639 | /* | ||
640 | * HEST subtables | ||
641 | * | ||
642 | * From WHEA Design Document, 16 May 2007. | ||
643 | * Note: There is no subtable type 2 in this version of the document, | ||
644 | * and there are two different subtable type 3s. | ||
645 | */ | ||
646 | |||
647 | /* 0: XPF Machine Check Exception */ | ||
648 | |||
649 | struct acpi_hest_xpf_machine_check { | ||
650 | struct acpi_hest_header header; | ||
651 | u16 source_id; | ||
652 | u16 config_write_enable; | ||
653 | u8 flags; | ||
654 | u8 reserved1; | ||
655 | u32 records_to_pre_allocate; | ||
656 | u32 max_sections_per_record; | ||
657 | u64 global_capability_data; | ||
658 | u64 global_control_data; | ||
659 | u8 num_hardware_banks; | ||
660 | u8 reserved2[7]; | ||
661 | }; | ||
662 | |||
663 | /* 1: XPF Corrected Machine Check */ | ||
664 | |||
665 | struct acpi_table_hest_xpf_corrected { | ||
666 | struct acpi_hest_header header; | ||
667 | u16 source_id; | ||
668 | u16 config_write_enable; | ||
669 | u8 flags; | ||
670 | u8 enabled; | ||
671 | u32 records_to_pre_allocate; | ||
672 | u32 max_sections_per_record; | ||
673 | struct acpi_hest_notify notify; | ||
674 | u8 num_hardware_banks; | ||
675 | u8 reserved[3]; | ||
676 | }; | ||
677 | |||
678 | /* 3: XPF Non-Maskable Interrupt */ | ||
679 | |||
680 | struct acpi_hest_xpf_nmi { | ||
681 | struct acpi_hest_header header; | ||
682 | u16 source_id; | ||
683 | u32 reserved; | ||
684 | u32 records_to_pre_allocate; | ||
685 | u32 max_sections_per_record; | ||
686 | u32 max_raw_data_length; | ||
687 | }; | ||
688 | |||
689 | /* 4: IPF Corrected Machine Check */ | ||
690 | |||
691 | struct acpi_hest_ipf_corrected { | ||
692 | struct acpi_hest_header header; | ||
693 | u8 enabled; | ||
694 | u8 reserved; | ||
695 | }; | ||
696 | |||
697 | /* 5: IPF Corrected Platform Error */ | ||
698 | |||
699 | struct acpi_hest_ipf_corrected_platform { | ||
700 | struct acpi_hest_header header; | ||
701 | u8 enabled; | ||
702 | u8 reserved; | ||
703 | }; | ||
704 | |||
705 | /* 6: PCI Express Root Port AER */ | ||
706 | |||
707 | struct acpi_hest_aer_root { | ||
708 | struct acpi_hest_header header; | ||
709 | struct acpi_hest_aer_common aer; | ||
710 | u32 root_error_command; | ||
711 | }; | ||
712 | |||
713 | /* 7: PCI Express AER (AER Endpoint) */ | ||
714 | |||
715 | struct acpi_hest_aer { | ||
716 | struct acpi_hest_header header; | ||
717 | struct acpi_hest_aer_common aer; | ||
718 | }; | ||
719 | |||
720 | /* 8: PCI Express/PCI-X Bridge AER */ | ||
721 | |||
722 | struct acpi_hest_aer_bridge { | ||
723 | struct acpi_hest_header header; | ||
724 | struct acpi_hest_aer_common aer; | ||
725 | u32 secondary_uncorrectable_error_mask; | ||
726 | u32 secondary_uncorrectable_error_severity; | ||
727 | u32 secondary_advanced_capabilities; | ||
728 | }; | ||
729 | |||
730 | /* 9: Generic Hardware Error Source */ | ||
731 | |||
732 | struct acpi_hest_generic { | ||
733 | struct acpi_hest_header header; | ||
734 | u16 source_id; | ||
735 | u16 related_source_id; | ||
736 | u8 config_write_enable; | ||
737 | u8 enabled; | ||
738 | u32 records_to_pre_allocate; | ||
739 | u32 max_sections_per_record; | ||
740 | u32 max_raw_data_length; | ||
741 | struct acpi_generic_address error_status_address; | ||
742 | struct acpi_hest_notify notify; | ||
743 | u32 error_status_block_length; | ||
744 | }; | ||
745 | |||
746 | /******************************************************************************* | ||
747 | * | ||
353 | * HPET - High Precision Event Timer table | 748 | * HPET - High Precision Event Timer table |
354 | * | 749 | * |
355 | ******************************************************************************/ | 750 | ******************************************************************************/ |
@@ -373,6 +768,96 @@ struct acpi_table_hpet { | |||
373 | 768 | ||
374 | /******************************************************************************* | 769 | /******************************************************************************* |
375 | * | 770 | * |
771 | * IBFT - Boot Firmware Table | ||
772 | * | ||
773 | ******************************************************************************/ | ||
774 | |||
775 | struct acpi_table_ibft { | ||
776 | struct acpi_table_header header; /* Common ACPI table header */ | ||
777 | u8 reserved[12]; | ||
778 | }; | ||
779 | |||
780 | /* IBFT common subtable header */ | ||
781 | |||
782 | struct acpi_ibft_header { | ||
783 | u8 type; | ||
784 | u8 version; | ||
785 | u16 length; | ||
786 | u8 index; | ||
787 | u8 flags; | ||
788 | }; | ||
789 | |||
790 | /* Values for Type field above */ | ||
791 | |||
792 | enum acpi_ibft_type { | ||
793 | ACPI_IBFT_TYPE_NOT_USED = 0, | ||
794 | ACPI_IBFT_TYPE_CONTROL = 1, | ||
795 | ACPI_IBFT_TYPE_INITIATOR = 2, | ||
796 | ACPI_IBFT_TYPE_NIC = 3, | ||
797 | ACPI_IBFT_TYPE_TARGET = 4, | ||
798 | ACPI_IBFT_TYPE_EXTENSIONS = 5, | ||
799 | ACPI_IBFT_TYPE_RESERVED = 6 /* 6 and greater are reserved */ | ||
800 | }; | ||
801 | |||
802 | /* IBFT subtables */ | ||
803 | |||
804 | struct acpi_ibft_control { | ||
805 | struct acpi_ibft_header header; | ||
806 | u16 extensions; | ||
807 | u16 initiator_offset; | ||
808 | u16 nic0_offset; | ||
809 | u16 target0_offset; | ||
810 | u16 nic1_offset; | ||
811 | u16 target1_offset; | ||
812 | }; | ||
813 | |||
814 | struct acpi_ibft_initiator { | ||
815 | struct acpi_ibft_header header; | ||
816 | u8 sns_server[16]; | ||
817 | u8 slp_server[16]; | ||
818 | u8 primary_server[16]; | ||
819 | u8 secondary_server[16]; | ||
820 | u16 name_length; | ||
821 | u16 name_offset; | ||
822 | }; | ||
823 | |||
824 | struct acpi_ibft_nic { | ||
825 | struct acpi_ibft_header header; | ||
826 | u8 ip_address[16]; | ||
827 | u8 subnet_mask_prefix; | ||
828 | u8 origin; | ||
829 | u8 gateway[16]; | ||
830 | u8 primary_dns[16]; | ||
831 | u8 secondary_dns[16]; | ||
832 | u8 dhcp[16]; | ||
833 | u16 vlan; | ||
834 | u8 mac_address[6]; | ||
835 | u16 pci_address; | ||
836 | u16 name_length; | ||
837 | u16 name_offset; | ||
838 | }; | ||
839 | |||
840 | struct acpi_ibft_target { | ||
841 | struct acpi_ibft_header header; | ||
842 | u8 target_ip_address[16]; | ||
843 | u16 target_ip_socket; | ||
844 | u8 target_boot_lun[8]; | ||
845 | u8 chap_type; | ||
846 | u8 nic_association; | ||
847 | u16 target_name_length; | ||
848 | u16 target_name_offset; | ||
849 | u16 chap_name_length; | ||
850 | u16 chap_name_offset; | ||
851 | u16 chap_secret_length; | ||
852 | u16 chap_secret_offset; | ||
853 | u16 reverse_chap_name_length; | ||
854 | u16 reverse_chap_name_offset; | ||
855 | u16 reverse_chap_secret_length; | ||
856 | u16 reverse_chap_secret_offset; | ||
857 | }; | ||
858 | |||
859 | /******************************************************************************* | ||
860 | * | ||
376 | * MADT - Multiple APIC Description Table | 861 | * MADT - Multiple APIC Description Table |
377 | * | 862 | * |
378 | ******************************************************************************/ | 863 | ******************************************************************************/ |
@@ -697,6 +1182,78 @@ struct acpi_table_tcpa { | |||
697 | 1182 | ||
698 | /******************************************************************************* | 1183 | /******************************************************************************* |
699 | * | 1184 | * |
1185 | * UEFI - UEFI Boot optimization Table | ||
1186 | * | ||
1187 | ******************************************************************************/ | ||
1188 | |||
1189 | struct acpi_table_uefi { | ||
1190 | struct acpi_table_header header; /* Common ACPI table header */ | ||
1191 | u8 identifier[16]; /* UUID identifier */ | ||
1192 | u16 data_offset; /* Offset of remaining data in table */ | ||
1193 | u8 data; | ||
1194 | }; | ||
1195 | |||
1196 | /******************************************************************************* | ||
1197 | * | ||
1198 | * WDAT - Watchdog Action Table | ||
1199 | * | ||
1200 | ******************************************************************************/ | ||
1201 | |||
1202 | struct acpi_table_wdat { | ||
1203 | struct acpi_table_header header; /* Common ACPI table header */ | ||
1204 | u32 header_length; /* Watchdog Header Length */ | ||
1205 | u16 pci_segment; /* PCI Segment number */ | ||
1206 | u8 pci_bus; /* PCI Bus number */ | ||
1207 | u8 pci_device; /* PCI Device number */ | ||
1208 | u8 pci_function; /* PCI Function number */ | ||
1209 | u8 reserved[3]; | ||
1210 | u32 timer_period; /* Period of one timer count (msec) */ | ||
1211 | u32 max_count; /* Maximum counter value supported */ | ||
1212 | u32 min_count; /* Minimum counter value */ | ||
1213 | u8 flags; | ||
1214 | u8 reserved2[3]; | ||
1215 | u32 entries; /* Number of watchdog entries that follow */ | ||
1216 | }; | ||
1217 | |||
1218 | /* WDAT Instruction Entries (actions) */ | ||
1219 | |||
1220 | struct acpi_wdat_entry { | ||
1221 | struct acpi_whea_header whea_header; /* Common header for WHEA tables */ | ||
1222 | }; | ||
1223 | |||
1224 | /* Values for Action field above */ | ||
1225 | |||
1226 | enum acpi_wdat_actions { | ||
1227 | ACPI_WDAT_RESET = 1, | ||
1228 | ACPI_WDAT_GET_CURRENT_COUNTDOWN = 4, | ||
1229 | ACPI_WDAT_GET_COUNTDOWN = 5, | ||
1230 | ACPI_WDAT_SET_COUNTDOWN = 6, | ||
1231 | ACPI_WDAT_GET_RUNNING_STATE = 8, | ||
1232 | ACPI_WDAT_SET_RUNNING_STATE = 9, | ||
1233 | ACPI_WDAT_GET_STOPPED_STATE = 10, | ||
1234 | ACPI_WDAT_SET_STOPPED_STATE = 11, | ||
1235 | ACPI_WDAT_GET_REBOOT = 16, | ||
1236 | ACPI_WDAT_SET_REBOOT = 17, | ||
1237 | ACPI_WDAT_GET_SHUTDOWN = 18, | ||
1238 | ACPI_WDAT_SET_SHUTDOWN = 19, | ||
1239 | ACPI_WDAT_GET_STATUS = 32, | ||
1240 | ACPI_WDAT_SET_STATUS = 33, | ||
1241 | ACPI_WDAT_ACTION_RESERVED = 34 /* 34 and greater are reserved */ | ||
1242 | }; | ||
1243 | |||
1244 | /* Values for Instruction field above */ | ||
1245 | |||
1246 | enum acpi_wdat_instructions { | ||
1247 | ACPI_WDAT_READ_VALUE = 0, | ||
1248 | ACPI_WDAT_READ_COUNTDOWN = 1, | ||
1249 | ACPI_WDAT_WRITE_VALUE = 2, | ||
1250 | ACPI_WDAT_WRITE_COUNTDOWN = 3, | ||
1251 | ACPI_WDAT_INSTRUCTION_RESERVED = 4, /* 4 and greater are reserved */ | ||
1252 | ACPI_WDAT_PRESERVE_REGISTER = 0x80 /* Except for this value */ | ||
1253 | }; | ||
1254 | |||
1255 | /******************************************************************************* | ||
1256 | * | ||
700 | * WDRT - Watchdog Resource Table | 1257 | * WDRT - Watchdog Resource Table |
701 | * | 1258 | * |
702 | ******************************************************************************/ | 1259 | ******************************************************************************/ |
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index e73a38939120..dfea2d440488 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -323,27 +323,11 @@ struct uint32_struct { | |||
323 | #define acpi_semaphore void * | 323 | #define acpi_semaphore void * |
324 | 324 | ||
325 | /* | 325 | /* |
326 | * Acpi integer width. In ACPI version 1, integers are | 326 | * Acpi integer width. In ACPI version 1, integers are 32 bits. In ACPI |
327 | * 32 bits. In ACPI version 2, integers are 64 bits. | 327 | * version 2, integers are 64 bits. Note that this pertains to the ACPI integer |
328 | * Note that this pertains to the ACPI integer type only, not | 328 | * type only, not other integers used in the implementation of the ACPI CA |
329 | * other integers used in the implementation of the ACPI CA | ||
330 | * subsystem. | 329 | * subsystem. |
331 | */ | 330 | */ |
332 | #ifdef ACPI_NO_INTEGER64_SUPPORT | ||
333 | |||
334 | /* 32-bit integers only, no 64-bit support */ | ||
335 | |||
336 | typedef u32 acpi_integer; | ||
337 | #define ACPI_INTEGER_MAX ACPI_UINT32_MAX | ||
338 | #define ACPI_INTEGER_BIT_SIZE 32 | ||
339 | #define ACPI_MAX_DECIMAL_DIGITS 10 /* 2^32 = 4,294,967,296 */ | ||
340 | |||
341 | #define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 32-bit divide */ | ||
342 | |||
343 | #else | ||
344 | |||
345 | /* 64-bit integers */ | ||
346 | |||
347 | typedef unsigned long long acpi_integer; | 331 | typedef unsigned long long acpi_integer; |
348 | #define ACPI_INTEGER_MAX ACPI_UINT64_MAX | 332 | #define ACPI_INTEGER_MAX ACPI_UINT64_MAX |
349 | #define ACPI_INTEGER_BIT_SIZE 64 | 333 | #define ACPI_INTEGER_BIT_SIZE 64 |
@@ -352,7 +336,6 @@ typedef unsigned long long acpi_integer; | |||
352 | #if ACPI_MACHINE_WIDTH == 64 | 336 | #if ACPI_MACHINE_WIDTH == 64 |
353 | #define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 64-bit divide */ | 337 | #define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 64-bit divide */ |
354 | #endif | 338 | #endif |
355 | #endif | ||
356 | 339 | ||
357 | #define ACPI_MAX64_DECIMAL_DIGITS 20 | 340 | #define ACPI_MAX64_DECIMAL_DIGITS 20 |
358 | #define ACPI_MAX32_DECIMAL_DIGITS 10 | 341 | #define ACPI_MAX32_DECIMAL_DIGITS 10 |
@@ -419,14 +402,20 @@ typedef unsigned long long acpi_integer; | |||
419 | /* | 402 | /* |
420 | * Standard notify values | 403 | * Standard notify values |
421 | */ | 404 | */ |
422 | #define ACPI_NOTIFY_BUS_CHECK (u8) 0 | 405 | #define ACPI_NOTIFY_BUS_CHECK (u8) 0x00 |
423 | #define ACPI_NOTIFY_DEVICE_CHECK (u8) 1 | 406 | #define ACPI_NOTIFY_DEVICE_CHECK (u8) 0x01 |
424 | #define ACPI_NOTIFY_DEVICE_WAKE (u8) 2 | 407 | #define ACPI_NOTIFY_DEVICE_WAKE (u8) 0x02 |
425 | #define ACPI_NOTIFY_EJECT_REQUEST (u8) 3 | 408 | #define ACPI_NOTIFY_EJECT_REQUEST (u8) 0x03 |
426 | #define ACPI_NOTIFY_DEVICE_CHECK_LIGHT (u8) 4 | 409 | #define ACPI_NOTIFY_DEVICE_CHECK_LIGHT (u8) 0x04 |
427 | #define ACPI_NOTIFY_FREQUENCY_MISMATCH (u8) 5 | 410 | #define ACPI_NOTIFY_FREQUENCY_MISMATCH (u8) 0x05 |
428 | #define ACPI_NOTIFY_BUS_MODE_MISMATCH (u8) 6 | 411 | #define ACPI_NOTIFY_BUS_MODE_MISMATCH (u8) 0x06 |
429 | #define ACPI_NOTIFY_POWER_FAULT (u8) 7 | 412 | #define ACPI_NOTIFY_POWER_FAULT (u8) 0x07 |
413 | #define ACPI_NOTIFY_CAPABILITIES_CHECK (u8) 0x08 | ||
414 | #define ACPI_NOTIFY_DEVICE_PLD_CHECK (u8) 0x09 | ||
415 | #define ACPI_NOTIFY_RESERVED (u8) 0x0A | ||
416 | #define ACPI_NOTIFY_LOCALITY_UPDATE (u8) 0x0B | ||
417 | |||
418 | #define ACPI_NOTIFY_MAX 0x0B | ||
430 | 419 | ||
431 | /* | 420 | /* |
432 | * Types associated with ACPI names and objects. The first group of | 421 | * Types associated with ACPI names and objects. The first group of |
@@ -494,6 +483,8 @@ typedef u32 acpi_object_type; | |||
494 | #define ACPI_TYPE_INVALID 0x1E | 483 | #define ACPI_TYPE_INVALID 0x1E |
495 | #define ACPI_TYPE_NOT_FOUND 0xFF | 484 | #define ACPI_TYPE_NOT_FOUND 0xFF |
496 | 485 | ||
486 | #define ACPI_NUM_NS_TYPES (ACPI_TYPE_INVALID + 1) | ||
487 | |||
497 | /* | 488 | /* |
498 | * All I/O | 489 | * All I/O |
499 | */ | 490 | */ |
@@ -599,7 +590,7 @@ typedef u32 acpi_event_status; | |||
599 | 590 | ||
600 | #define ACPI_SYSTEM_NOTIFY 0x1 | 591 | #define ACPI_SYSTEM_NOTIFY 0x1 |
601 | #define ACPI_DEVICE_NOTIFY 0x2 | 592 | #define ACPI_DEVICE_NOTIFY 0x2 |
602 | #define ACPI_ALL_NOTIFY 0x3 | 593 | #define ACPI_ALL_NOTIFY (ACPI_SYSTEM_NOTIFY | ACPI_DEVICE_NOTIFY) |
603 | #define ACPI_MAX_NOTIFY_HANDLER_TYPE 0x3 | 594 | #define ACPI_MAX_NOTIFY_HANDLER_TYPE 0x3 |
604 | 595 | ||
605 | #define ACPI_MAX_SYS_NOTIFY 0x7f | 596 | #define ACPI_MAX_SYS_NOTIFY 0x7f |
@@ -654,46 +645,51 @@ typedef u8 acpi_adr_space_type; | |||
654 | /* | 645 | /* |
655 | * External ACPI object definition | 646 | * External ACPI object definition |
656 | */ | 647 | */ |
648 | |||
649 | /* | ||
650 | * Note: Type == ACPI_TYPE_ANY (0) is used to indicate a NULL package element | ||
651 | * or an unresolved named reference. | ||
652 | */ | ||
657 | union acpi_object { | 653 | union acpi_object { |
658 | acpi_object_type type; /* See definition of acpi_ns_type for values */ | 654 | acpi_object_type type; /* See definition of acpi_ns_type for values */ |
659 | struct { | 655 | struct { |
660 | acpi_object_type type; | 656 | acpi_object_type type; /* ACPI_TYPE_INTEGER */ |
661 | acpi_integer value; /* The actual number */ | 657 | acpi_integer value; /* The actual number */ |
662 | } integer; | 658 | } integer; |
663 | 659 | ||
664 | struct { | 660 | struct { |
665 | acpi_object_type type; | 661 | acpi_object_type type; /* ACPI_TYPE_STRING */ |
666 | u32 length; /* # of bytes in string, excluding trailing null */ | 662 | u32 length; /* # of bytes in string, excluding trailing null */ |
667 | char *pointer; /* points to the string value */ | 663 | char *pointer; /* points to the string value */ |
668 | } string; | 664 | } string; |
669 | 665 | ||
670 | struct { | 666 | struct { |
671 | acpi_object_type type; | 667 | acpi_object_type type; /* ACPI_TYPE_BUFFER */ |
672 | u32 length; /* # of bytes in buffer */ | 668 | u32 length; /* # of bytes in buffer */ |
673 | u8 *pointer; /* points to the buffer */ | 669 | u8 *pointer; /* points to the buffer */ |
674 | } buffer; | 670 | } buffer; |
675 | 671 | ||
676 | struct { | 672 | struct { |
677 | acpi_object_type type; | 673 | acpi_object_type type; /* ACPI_TYPE_PACKAGE */ |
678 | u32 fill1; | ||
679 | acpi_handle handle; /* object reference */ | ||
680 | } reference; | ||
681 | |||
682 | struct { | ||
683 | acpi_object_type type; | ||
684 | u32 count; /* # of elements in package */ | 674 | u32 count; /* # of elements in package */ |
685 | union acpi_object *elements; /* Pointer to an array of ACPI_OBJECTs */ | 675 | union acpi_object *elements; /* Pointer to an array of ACPI_OBJECTs */ |
686 | } package; | 676 | } package; |
687 | 677 | ||
688 | struct { | 678 | struct { |
689 | acpi_object_type type; | 679 | acpi_object_type type; /* ACPI_TYPE_LOCAL_REFERENCE */ |
680 | acpi_object_type actual_type; /* Type associated with the Handle */ | ||
681 | acpi_handle handle; /* object reference */ | ||
682 | } reference; | ||
683 | |||
684 | struct { | ||
685 | acpi_object_type type; /* ACPI_TYPE_PROCESSOR */ | ||
690 | u32 proc_id; | 686 | u32 proc_id; |
691 | acpi_io_address pblk_address; | 687 | acpi_io_address pblk_address; |
692 | u32 pblk_length; | 688 | u32 pblk_length; |
693 | } processor; | 689 | } processor; |
694 | 690 | ||
695 | struct { | 691 | struct { |
696 | acpi_object_type type; | 692 | acpi_object_type type; /* ACPI_TYPE_POWER */ |
697 | u32 system_level; | 693 | u32 system_level; |
698 | u32 resource_order; | 694 | u32 resource_order; |
699 | } power_resource; | 695 | } power_resource; |
@@ -747,6 +743,12 @@ struct acpi_system_info { | |||
747 | u32 debug_layer; | 743 | u32 debug_layer; |
748 | }; | 744 | }; |
749 | 745 | ||
746 | /* Table Event Types */ | ||
747 | |||
748 | #define ACPI_TABLE_EVENT_LOAD 0x0 | ||
749 | #define ACPI_TABLE_EVENT_UNLOAD 0x1 | ||
750 | #define ACPI_NUM_TABLE_EVENTS 2 | ||
751 | |||
750 | /* | 752 | /* |
751 | * Types specific to the OS service interfaces | 753 | * Types specific to the OS service interfaces |
752 | */ | 754 | */ |
@@ -776,6 +778,11 @@ acpi_status(*acpi_exception_handler) (acpi_status aml_status, | |||
776 | u16 opcode, | 778 | u16 opcode, |
777 | u32 aml_offset, void *context); | 779 | u32 aml_offset, void *context); |
778 | 780 | ||
781 | /* Table Event handler (Load, load_table etc) and types */ | ||
782 | |||
783 | typedef | ||
784 | acpi_status(*acpi_tbl_handler) (u32 event, void *table, void *context); | ||
785 | |||
779 | /* Address Spaces (For Operation Regions) */ | 786 | /* Address Spaces (For Operation Regions) */ |
780 | 787 | ||
781 | typedef | 788 | typedef |
@@ -990,6 +997,7 @@ struct acpi_vendor_uuid { | |||
990 | * Structures used to describe device resources | 997 | * Structures used to describe device resources |
991 | */ | 998 | */ |
992 | struct acpi_resource_irq { | 999 | struct acpi_resource_irq { |
1000 | u8 descriptor_length; | ||
993 | u8 triggering; | 1001 | u8 triggering; |
994 | u8 polarity; | 1002 | u8 polarity; |
995 | u8 sharable; | 1003 | u8 sharable; |
@@ -1006,6 +1014,7 @@ struct acpi_resource_dma { | |||
1006 | }; | 1014 | }; |
1007 | 1015 | ||
1008 | struct acpi_resource_start_dependent { | 1016 | struct acpi_resource_start_dependent { |
1017 | u8 descriptor_length; | ||
1009 | u8 compatibility_priority; | 1018 | u8 compatibility_priority; |
1010 | u8 performance_robustness; | 1019 | u8 performance_robustness; |
1011 | }; | 1020 | }; |
diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h index a2918547c73f..b42cadf07302 100644 --- a/include/acpi/acutils.h +++ b/include/acpi/acutils.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -116,6 +116,8 @@ void acpi_ut_init_globals(void); | |||
116 | 116 | ||
117 | char *acpi_ut_get_mutex_name(u32 mutex_id); | 117 | char *acpi_ut_get_mutex_name(u32 mutex_id); |
118 | 118 | ||
119 | const char *acpi_ut_get_notify_name(u32 notify_value); | ||
120 | |||
119 | #endif | 121 | #endif |
120 | 122 | ||
121 | char *acpi_ut_get_type_name(acpi_object_type type); | 123 | char *acpi_ut_get_type_name(acpi_object_type type); |
diff --git a/include/acpi/amlcode.h b/include/acpi/amlcode.h index da53a4ef287a..ff851c5df698 100644 --- a/include/acpi/amlcode.h +++ b/include/acpi/amlcode.h | |||
@@ -7,7 +7,7 @@ | |||
7 | *****************************************************************************/ | 7 | *****************************************************************************/ |
8 | 8 | ||
9 | /* | 9 | /* |
10 | * Copyright (C) 2000 - 2007, R. Byron Moore | 10 | * Copyright (C) 2000 - 2008, Intel Corp. |
11 | * All rights reserved. | 11 | * All rights reserved. |
12 | * | 12 | * |
13 | * Redistribution and use in source and binary forms, with or without | 13 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/amlresrc.h b/include/acpi/amlresrc.h index f7d541239da4..7b070e42b7c5 100644 --- a/include/acpi/amlresrc.h +++ b/include/acpi/amlresrc.h | |||
@@ -6,7 +6,7 @@ | |||
6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2007, R. Byron Moore | 9 | * Copyright (C) 2000 - 2008, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index c785485e62a6..fcd2572e428c 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h index 3bb50494a38a..8996dba90cd9 100644 --- a/include/acpi/platform/acgcc.h +++ b/include/acpi/platform/acgcc.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index 6ed15a0978eb..9af464598682 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2007, R. Byron Moore | 8 | * Copyright (C) 2000 - 2008, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 6233f3b4ae66..b45da40e8d25 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig | |||
@@ -19,16 +19,6 @@ config PM | |||
19 | will issue the hlt instruction if nothing is to be done, thereby | 19 | will issue the hlt instruction if nothing is to be done, thereby |
20 | sending the processor to sleep and saving power. | 20 | sending the processor to sleep and saving power. |
21 | 21 | ||
22 | config PM_LEGACY | ||
23 | bool "Legacy Power Management API (DEPRECATED)" | ||
24 | depends on PM | ||
25 | default n | ||
26 | ---help--- | ||
27 | Support for pm_register() and friends. This old API is obsoleted | ||
28 | by the driver model. | ||
29 | |||
30 | If unsure, say N. | ||
31 | |||
32 | config PM_DEBUG | 22 | config PM_DEBUG |
33 | bool "Power Management Debug Support" | 23 | bool "Power Management Debug Support" |
34 | depends on PM | 24 | depends on PM |
diff --git a/kernel/power/Makefile b/kernel/power/Makefile index f7dfff28ecdb..597823b5b700 100644 --- a/kernel/power/Makefile +++ b/kernel/power/Makefile | |||
@@ -4,7 +4,6 @@ EXTRA_CFLAGS += -DDEBUG | |||
4 | endif | 4 | endif |
5 | 5 | ||
6 | obj-y := main.o | 6 | obj-y := main.o |
7 | obj-$(CONFIG_PM_LEGACY) += pm.o | ||
8 | obj-$(CONFIG_PM_SLEEP) += process.o console.o | 7 | obj-$(CONFIG_PM_SLEEP) += process.o console.o |
9 | obj-$(CONFIG_HIBERNATION) += swsusp.o disk.o snapshot.o swap.o user.o | 8 | obj-$(CONFIG_HIBERNATION) += swsusp.o disk.o snapshot.o swap.o user.o |
10 | 9 | ||
diff --git a/kernel/power/pm.c b/kernel/power/pm.c deleted file mode 100644 index 60c73fa670d5..000000000000 --- a/kernel/power/pm.c +++ /dev/null | |||
@@ -1,205 +0,0 @@ | |||
1 | /* | ||
2 | * pm.c - Power management interface | ||
3 | * | ||
4 | * Copyright (C) 2000 Andrew Henroid | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | #include <linux/mm.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/pm.h> | ||
26 | #include <linux/pm_legacy.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/mutex.h> | ||
29 | |||
30 | /* | ||
31 | * Locking notes: | ||
32 | * pm_devs_lock can be a semaphore providing pm ops are not called | ||
33 | * from an interrupt handler (already a bad idea so no change here). Each | ||
34 | * change must be protected so that an unlink of an entry doesn't clash | ||
35 | * with a pm send - which is permitted to sleep in the current architecture | ||
36 | * | ||
37 | * Module unloads clashing with pm events now work out safely, the module | ||
38 | * unload path will block until the event has been sent. It may well block | ||
39 | * until a resume but that will be fine. | ||
40 | */ | ||
41 | |||
42 | static DEFINE_MUTEX(pm_devs_lock); | ||
43 | static LIST_HEAD(pm_devs); | ||
44 | |||
45 | /** | ||
46 | * pm_register - register a device with power management | ||
47 | * @type: device type | ||
48 | * @id: device ID | ||
49 | * @callback: callback function | ||
50 | * | ||
51 | * Add a device to the list of devices that wish to be notified about | ||
52 | * power management events. A &pm_dev structure is returned on success, | ||
53 | * on failure the return is %NULL. | ||
54 | * | ||
55 | * The callback function will be called in process context and | ||
56 | * it may sleep. | ||
57 | */ | ||
58 | |||
59 | struct pm_dev *pm_register(pm_dev_t type, | ||
60 | unsigned long id, | ||
61 | pm_callback callback) | ||
62 | { | ||
63 | struct pm_dev *dev = kzalloc(sizeof(struct pm_dev), GFP_KERNEL); | ||
64 | if (dev) { | ||
65 | dev->type = type; | ||
66 | dev->id = id; | ||
67 | dev->callback = callback; | ||
68 | |||
69 | mutex_lock(&pm_devs_lock); | ||
70 | list_add(&dev->entry, &pm_devs); | ||
71 | mutex_unlock(&pm_devs_lock); | ||
72 | } | ||
73 | return dev; | ||
74 | } | ||
75 | |||
76 | /** | ||
77 | * pm_send - send request to a single device | ||
78 | * @dev: device to send to | ||
79 | * @rqst: power management request | ||
80 | * @data: data for the callback | ||
81 | * | ||
82 | * Issue a power management request to a given device. The | ||
83 | * %PM_SUSPEND and %PM_RESUME events are handled specially. The | ||
84 | * data field must hold the intended next state. No call is made | ||
85 | * if the state matches. | ||
86 | * | ||
87 | * BUGS: what stops two power management requests occurring in parallel | ||
88 | * and conflicting. | ||
89 | * | ||
90 | * WARNING: Calling pm_send directly is not generally recommended, in | ||
91 | * particular there is no locking against the pm_dev going away. The | ||
92 | * caller must maintain all needed locking or have 'inside knowledge' | ||
93 | * on the safety. Also remember that this function is not locked against | ||
94 | * pm_unregister. This means that you must handle SMP races on callback | ||
95 | * execution and unload yourself. | ||
96 | */ | ||
97 | |||
98 | static int pm_send(struct pm_dev *dev, pm_request_t rqst, void *data) | ||
99 | { | ||
100 | int status = 0; | ||
101 | unsigned long prev_state, next_state; | ||
102 | |||
103 | if (in_interrupt()) | ||
104 | BUG(); | ||
105 | |||
106 | switch (rqst) { | ||
107 | case PM_SUSPEND: | ||
108 | case PM_RESUME: | ||
109 | prev_state = dev->state; | ||
110 | next_state = (unsigned long) data; | ||
111 | if (prev_state != next_state) { | ||
112 | if (dev->callback) | ||
113 | status = (*dev->callback)(dev, rqst, data); | ||
114 | if (!status) { | ||
115 | dev->state = next_state; | ||
116 | dev->prev_state = prev_state; | ||
117 | } | ||
118 | } | ||
119 | else { | ||
120 | dev->prev_state = prev_state; | ||
121 | } | ||
122 | break; | ||
123 | default: | ||
124 | if (dev->callback) | ||
125 | status = (*dev->callback)(dev, rqst, data); | ||
126 | break; | ||
127 | } | ||
128 | return status; | ||
129 | } | ||
130 | |||
131 | /* | ||
132 | * Undo incomplete request | ||
133 | */ | ||
134 | static void pm_undo_all(struct pm_dev *last) | ||
135 | { | ||
136 | struct list_head *entry = last->entry.prev; | ||
137 | while (entry != &pm_devs) { | ||
138 | struct pm_dev *dev = list_entry(entry, struct pm_dev, entry); | ||
139 | if (dev->state != dev->prev_state) { | ||
140 | /* previous state was zero (running) resume or | ||
141 | * previous state was non-zero (suspended) suspend | ||
142 | */ | ||
143 | pm_request_t undo = (dev->prev_state | ||
144 | ? PM_SUSPEND:PM_RESUME); | ||
145 | pm_send(dev, undo, (void*) dev->prev_state); | ||
146 | } | ||
147 | entry = entry->prev; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | /** | ||
152 | * pm_send_all - send request to all managed devices | ||
153 | * @rqst: power management request | ||
154 | * @data: data for the callback | ||
155 | * | ||
156 | * Issue a power management request to a all devices. The | ||
157 | * %PM_SUSPEND events are handled specially. Any device is | ||
158 | * permitted to fail a suspend by returning a non zero (error) | ||
159 | * value from its callback function. If any device vetoes a | ||
160 | * suspend request then all other devices that have suspended | ||
161 | * during the processing of this request are restored to their | ||
162 | * previous state. | ||
163 | * | ||
164 | * WARNING: This function takes the pm_devs_lock. The lock is not dropped until | ||
165 | * the callbacks have completed. This prevents races against pm locking | ||
166 | * functions, races against module unload pm_unregister code. It does | ||
167 | * mean however that you must not issue pm_ functions within the callback | ||
168 | * or you will deadlock and users will hate you. | ||
169 | * | ||
170 | * Zero is returned on success. If a suspend fails then the status | ||
171 | * from the device that vetoes the suspend is returned. | ||
172 | * | ||
173 | * BUGS: what stops two power management requests occurring in parallel | ||
174 | * and conflicting. | ||
175 | */ | ||
176 | |||
177 | int pm_send_all(pm_request_t rqst, void *data) | ||
178 | { | ||
179 | struct list_head *entry; | ||
180 | |||
181 | mutex_lock(&pm_devs_lock); | ||
182 | entry = pm_devs.next; | ||
183 | while (entry != &pm_devs) { | ||
184 | struct pm_dev *dev = list_entry(entry, struct pm_dev, entry); | ||
185 | if (dev->callback) { | ||
186 | int status = pm_send(dev, rqst, data); | ||
187 | if (status) { | ||
188 | /* return devices to previous state on | ||
189 | * failed suspend request | ||
190 | */ | ||
191 | if (rqst == PM_SUSPEND) | ||
192 | pm_undo_all(dev); | ||
193 | mutex_unlock(&pm_devs_lock); | ||
194 | return status; | ||
195 | } | ||
196 | } | ||
197 | entry = entry->next; | ||
198 | } | ||
199 | mutex_unlock(&pm_devs_lock); | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | EXPORT_SYMBOL(pm_register); | ||
204 | EXPORT_SYMBOL(pm_send_all); | ||
205 | |||