diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 12:32:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 12:32:11 -0400 |
commit | c11f6c82581e8be4e1829c677db54e7f55cebece (patch) | |
tree | 1a116241b0831ded998aabe800bdc24104cbd826 | |
parent | 40aba218969914d1b225e742617adb921cf94eae (diff) | |
parent | 193a6dec1c0246a80b6d0101e4f351ccf877bcac (diff) |
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (119 commits)
ACPI: don't pass handle for fixed hardware notifications
ACPI: remove null pointer checks in deferred execution path
ACPI: simplify deferred execution path
acerhdf: additional BIOS versions
acerhdf: convert to dev_pm_ops
acerhdf: fix fan control for AOA150 model
thermal: add missing Kconfig dependency
acpi: switch /proc/acpi/{debug_layer,debug_level} to seq_file
hp-wmi: fix rfkill memory leak on unload
ACPI: remove unnecessary #ifdef CONFIG_DMI
ACPI: linux/acpi.h should not include linux/dmi.h
hwmon driver for ACPI 4.0 power meters
topstar-laptop: add new driver for hotkeys support on Topstar N01
thinkpad_acpi: fix rfkill memory leak on unload
thinkpad-acpi: report brightness events when required
thinkpad-acpi: don't poll by default any of the reserved hotkeys
thinkpad-acpi: Fix procfs hotkey reset command
thinkpad-acpi: deprecate hotkey_bios_mask
thinkpad-acpi: hotkey poll fixes
thinkpad-acpi: be more strict when detecting a ThinkPad
...
130 files changed, 7227 insertions, 3015 deletions
diff --git a/Documentation/ABI/stable/sysfs-class-backlight b/Documentation/ABI/stable/sysfs-class-backlight new file mode 100644 index 000000000000..4d637e1c4ff7 --- /dev/null +++ b/Documentation/ABI/stable/sysfs-class-backlight | |||
@@ -0,0 +1,36 @@ | |||
1 | What: /sys/class/backlight/<backlight>/bl_power | ||
2 | Date: April 2005 | ||
3 | KernelVersion: 2.6.12 | ||
4 | Contact: Richard Purdie <rpurdie@rpsys.net> | ||
5 | Description: | ||
6 | Control BACKLIGHT power, values are FB_BLANK_* from fb.h | ||
7 | - FB_BLANK_UNBLANK (0) : power on. | ||
8 | - FB_BLANK_POWERDOWN (4) : power off | ||
9 | Users: HAL | ||
10 | |||
11 | What: /sys/class/backlight/<backlight>/brightness | ||
12 | Date: April 2005 | ||
13 | KernelVersion: 2.6.12 | ||
14 | Contact: Richard Purdie <rpurdie@rpsys.net> | ||
15 | Description: | ||
16 | Control the brightness for this <backlight>. Values | ||
17 | are between 0 and max_brightness. This file will also | ||
18 | show the brightness level stored in the driver, which | ||
19 | may not be the actual brightness (see actual_brightness). | ||
20 | Users: HAL | ||
21 | |||
22 | What: /sys/class/backlight/<backlight>/actual_brightness | ||
23 | Date: March 2006 | ||
24 | KernelVersion: 2.6.17 | ||
25 | Contact: Richard Purdie <rpurdie@rpsys.net> | ||
26 | Description: | ||
27 | Show the actual brightness by querying the hardware. | ||
28 | Users: HAL | ||
29 | |||
30 | What: /sys/class/backlight/<backlight>/max_brightness | ||
31 | Date: April 2005 | ||
32 | KernelVersion: 2.6.12 | ||
33 | Contact: Richard Purdie <rpurdie@rpsys.net> | ||
34 | Description: | ||
35 | Maximum brightness for <backlight>. | ||
36 | Users: HAL | ||
diff --git a/Documentation/ABI/testing/sysfs-class-lcd b/Documentation/ABI/testing/sysfs-class-lcd new file mode 100644 index 000000000000..35906bf7aa70 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-lcd | |||
@@ -0,0 +1,23 @@ | |||
1 | What: /sys/class/lcd/<lcd>/lcd_power | ||
2 | Date: April 2005 | ||
3 | KernelVersion: 2.6.12 | ||
4 | Contact: Richard Purdie <rpurdie@rpsys.net> | ||
5 | Description: | ||
6 | Control LCD power, values are FB_BLANK_* from fb.h | ||
7 | - FB_BLANK_UNBLANK (0) : power on. | ||
8 | - FB_BLANK_POWERDOWN (4) : power off | ||
9 | |||
10 | What: /sys/class/lcd/<lcd>/contrast | ||
11 | Date: April 2005 | ||
12 | KernelVersion: 2.6.12 | ||
13 | Contact: Richard Purdie <rpurdie@rpsys.net> | ||
14 | Description: | ||
15 | Current contrast of this LCD device. Value is between 0 and | ||
16 | /sys/class/lcd/<lcd>/max_contrast. | ||
17 | |||
18 | What: /sys/class/lcd/<lcd>/max_contrast | ||
19 | Date: April 2005 | ||
20 | KernelVersion: 2.6.12 | ||
21 | Contact: Richard Purdie <rpurdie@rpsys.net> | ||
22 | Description: | ||
23 | Maximum contrast for this LCD device. | ||
diff --git a/Documentation/ABI/testing/sysfs-class-led b/Documentation/ABI/testing/sysfs-class-led new file mode 100644 index 000000000000..9e4541d71cb6 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-led | |||
@@ -0,0 +1,28 @@ | |||
1 | What: /sys/class/leds/<led>/brightness | ||
2 | Date: March 2006 | ||
3 | KernelVersion: 2.6.17 | ||
4 | Contact: Richard Purdie <rpurdie@rpsys.net> | ||
5 | Description: | ||
6 | Set the brightness of the LED. Most LEDs don't | ||
7 | have hardware brightness support so will just be turned on for | ||
8 | non-zero brightness settings. The value is between 0 and | ||
9 | /sys/class/leds/<led>/max_brightness. | ||
10 | |||
11 | What: /sys/class/leds/<led>/max_brightness | ||
12 | Date: March 2006 | ||
13 | KernelVersion: 2.6.17 | ||
14 | Contact: Richard Purdie <rpurdie@rpsys.net> | ||
15 | Description: | ||
16 | Maximum brightness level for this led, default is 255 (LED_FULL). | ||
17 | |||
18 | What: /sys/class/leds/<led>/trigger | ||
19 | Date: March 2006 | ||
20 | KernelVersion: 2.6.17 | ||
21 | Contact: Richard Purdie <rpurdie@rpsys.net> | ||
22 | Description: | ||
23 | Set the trigger for this LED. A trigger is a kernel based source | ||
24 | of led events. | ||
25 | You can change triggers in a similar manner to the way an IO | ||
26 | scheduler is chosen. Trigger specific parameters can appear in | ||
27 | /sys/class/leds/<led> once a given trigger is selected. | ||
28 | |||
diff --git a/Documentation/ABI/testing/sysfs-platform-asus-laptop b/Documentation/ABI/testing/sysfs-platform-asus-laptop new file mode 100644 index 000000000000..a1cb660c50cf --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-asus-laptop | |||
@@ -0,0 +1,52 @@ | |||
1 | What: /sys/devices/platform/asus-laptop/display | ||
2 | Date: January 2007 | ||
3 | KernelVersion: 2.6.20 | ||
4 | Contact: "Corentin Chary" <corentincj@iksaif.net> | ||
5 | Description: | ||
6 | This file allows display switching. The value | ||
7 | is composed by 4 bits and defined as follow: | ||
8 | 4321 | ||
9 | |||`- LCD | ||
10 | ||`-- CRT | ||
11 | |`--- TV | ||
12 | `---- DVI | ||
13 | Ex: - 0 (0000b) means no display | ||
14 | - 3 (0011b) CRT+LCD. | ||
15 | |||
16 | What: /sys/devices/platform/asus-laptop/gps | ||
17 | Date: January 2007 | ||
18 | KernelVersion: 2.6.20 | ||
19 | Contact: "Corentin Chary" <corentincj@iksaif.net> | ||
20 | Description: | ||
21 | Control the gps device. 1 means on, 0 means off. | ||
22 | Users: Lapsus | ||
23 | |||
24 | What: /sys/devices/platform/asus-laptop/ledd | ||
25 | Date: January 2007 | ||
26 | KernelVersion: 2.6.20 | ||
27 | Contact: "Corentin Chary" <corentincj@iksaif.net> | ||
28 | Description: | ||
29 | Some models like the W1N have a LED display that can be | ||
30 | used to display several informations. | ||
31 | To control the LED display, use the following : | ||
32 | echo 0x0T000DDD > /sys/devices/platform/asus-laptop/ | ||
33 | where T control the 3 letters display, and DDD the 3 digits display. | ||
34 | The DDD table can be found in Documentation/laptops/asus-laptop.txt | ||
35 | |||
36 | What: /sys/devices/platform/asus-laptop/bluetooth | ||
37 | Date: January 2007 | ||
38 | KernelVersion: 2.6.20 | ||
39 | Contact: "Corentin Chary" <corentincj@iksaif.net> | ||
40 | Description: | ||
41 | Control the bluetooth device. 1 means on, 0 means off. | ||
42 | This may control the led, the device or both. | ||
43 | Users: Lapsus | ||
44 | |||
45 | What: /sys/devices/platform/asus-laptop/wlan | ||
46 | Date: January 2007 | ||
47 | KernelVersion: 2.6.20 | ||
48 | Contact: "Corentin Chary" <corentincj@iksaif.net> | ||
49 | Description: | ||
50 | Control the bluetooth device. 1 means on, 0 means off. | ||
51 | This may control the led, the device or both. | ||
52 | Users: Lapsus | ||
diff --git a/Documentation/ABI/testing/sysfs-platform-eeepc-laptop b/Documentation/ABI/testing/sysfs-platform-eeepc-laptop new file mode 100644 index 000000000000..7445dfb321b5 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-eeepc-laptop | |||
@@ -0,0 +1,50 @@ | |||
1 | What: /sys/devices/platform/eeepc-laptop/disp | ||
2 | Date: May 2008 | ||
3 | KernelVersion: 2.6.26 | ||
4 | Contact: "Corentin Chary" <corentincj@iksaif.net> | ||
5 | Description: | ||
6 | This file allows display switching. | ||
7 | - 1 = LCD | ||
8 | - 2 = CRT | ||
9 | - 3 = LCD+CRT | ||
10 | If you run X11, you should use xrandr instead. | ||
11 | |||
12 | What: /sys/devices/platform/eeepc-laptop/camera | ||
13 | Date: May 2008 | ||
14 | KernelVersion: 2.6.26 | ||
15 | Contact: "Corentin Chary" <corentincj@iksaif.net> | ||
16 | Description: | ||
17 | Control the camera. 1 means on, 0 means off. | ||
18 | |||
19 | What: /sys/devices/platform/eeepc-laptop/cardr | ||
20 | Date: May 2008 | ||
21 | KernelVersion: 2.6.26 | ||
22 | Contact: "Corentin Chary" <corentincj@iksaif.net> | ||
23 | Description: | ||
24 | Control the card reader. 1 means on, 0 means off. | ||
25 | |||
26 | What: /sys/devices/platform/eeepc-laptop/cpufv | ||
27 | Date: Jun 2009 | ||
28 | KernelVersion: 2.6.31 | ||
29 | Contact: "Corentin Chary" <corentincj@iksaif.net> | ||
30 | Description: | ||
31 | Change CPU clock configuration. | ||
32 | On the Eee PC 1000H there are three available clock configuration: | ||
33 | * 0 -> Super Performance Mode | ||
34 | * 1 -> High Performance Mode | ||
35 | * 2 -> Power Saving Mode | ||
36 | On Eee PC 701 there is only 2 available clock configurations. | ||
37 | Available configuration are listed in available_cpufv file. | ||
38 | Reading this file will show the raw hexadecimal value which | ||
39 | is defined as follow: | ||
40 | | 8 bit | 8 bit | | ||
41 | | `---- Current mode | ||
42 | `------------ Availables modes | ||
43 | For example, 0x301 means: mode 1 selected, 3 available modes. | ||
44 | |||
45 | What: /sys/devices/platform/eeepc-laptop/available_cpufv | ||
46 | Date: Jun 2009 | ||
47 | KernelVersion: 2.6.31 | ||
48 | Contact: "Corentin Chary" <corentincj@iksaif.net> | ||
49 | Description: | ||
50 | List available cpufv modes. | ||
diff --git a/Documentation/hwmon/acpi_power_meter b/Documentation/hwmon/acpi_power_meter new file mode 100644 index 000000000000..c80399a00c50 --- /dev/null +++ b/Documentation/hwmon/acpi_power_meter | |||
@@ -0,0 +1,51 @@ | |||
1 | Kernel driver power_meter | ||
2 | ========================= | ||
3 | |||
4 | This driver talks to ACPI 4.0 power meters. | ||
5 | |||
6 | Supported systems: | ||
7 | * Any recent system with ACPI 4.0. | ||
8 | Prefix: 'power_meter' | ||
9 | Datasheet: http://acpi.info/, section 10.4. | ||
10 | |||
11 | Author: Darrick J. Wong | ||
12 | |||
13 | Description | ||
14 | ----------- | ||
15 | |||
16 | This driver implements sensor reading support for the power meters exposed in | ||
17 | the ACPI 4.0 spec (Chapter 10.4). These devices have a simple set of | ||
18 | features--a power meter that returns average power use over a configurable | ||
19 | interval, an optional capping mechanism, and a couple of trip points. The | ||
20 | sysfs interface conforms with the specification outlined in the "Power" section | ||
21 | of Documentation/hwmon/sysfs-interface. | ||
22 | |||
23 | Special Features | ||
24 | ---------------- | ||
25 | |||
26 | The power[1-*]_is_battery knob indicates if the power supply is a battery. | ||
27 | Both power[1-*]_average_{min,max} must be set before the trip points will work. | ||
28 | When both of them are set, an ACPI event will be broadcast on the ACPI netlink | ||
29 | socket and a poll notification will be sent to the appropriate | ||
30 | power[1-*]_average sysfs file. | ||
31 | |||
32 | The power[1-*]_{model_number, serial_number, oem_info} fields display arbitrary | ||
33 | strings that ACPI provides with the meter. The measures/ directory contains | ||
34 | symlinks to the devices that this meter measures. | ||
35 | |||
36 | Some computers have the ability to enforce a power cap in hardware. If this is | ||
37 | the case, the power[1-*]_cap and related sysfs files will appear. When the | ||
38 | average power consumption exceeds the cap, an ACPI event will be broadcast on | ||
39 | the netlink event socket and a poll notification will be sent to the | ||
40 | appropriate power[1-*]_alarm file to indicate that capping has begun, and the | ||
41 | hardware has taken action to reduce power consumption. Most likely this will | ||
42 | result in reduced performance. | ||
43 | |||
44 | There are a few other ACPI notifications that can be sent by the firmware. In | ||
45 | all cases the ACPI event will be broadcast on the ACPI netlink event socket as | ||
46 | well as sent as a poll notification to a sysfs file. The events are as | ||
47 | follows: | ||
48 | |||
49 | power[1-*]_cap will be notified if the firmware changes the power cap. | ||
50 | power[1-*]_interval will be notified if the firmware changes the averaging | ||
51 | interval. | ||
diff --git a/Documentation/laptops/asus-laptop.txt b/Documentation/laptops/asus-laptop.txt new file mode 100644 index 000000000000..c1c5be84e4b1 --- /dev/null +++ b/Documentation/laptops/asus-laptop.txt | |||
@@ -0,0 +1,258 @@ | |||
1 | Asus Laptop Extras | ||
2 | |||
3 | Version 0.1 | ||
4 | August 6, 2009 | ||
5 | |||
6 | Corentin Chary <corentincj@iksaif.net> | ||
7 | http://acpi4asus.sf.net/ | ||
8 | |||
9 | This driver provides support for extra features of ACPI-compatible ASUS laptops. | ||
10 | It may also support some MEDION, JVC or VICTOR laptops (such as MEDION 9675 or | ||
11 | VICTOR XP7210 for example). It makes all the extra buttons generate standard | ||
12 | ACPI events that go through /proc/acpi/events and input events (like keyboards). | ||
13 | On some models adds support for changing the display brightness and output, | ||
14 | switching the LCD backlight on and off, and most importantly, allows you to | ||
15 | blink those fancy LEDs intended for reporting mail and wireless status. | ||
16 | |||
17 | This driver supercedes the old asus_acpi driver. | ||
18 | |||
19 | Requirements | ||
20 | ------------ | ||
21 | |||
22 | Kernel 2.6.X sources, configured for your computer, with ACPI support. | ||
23 | You also need CONFIG_INPUT and CONFIG_ACPI. | ||
24 | |||
25 | Status | ||
26 | ------ | ||
27 | |||
28 | The features currently supported are the following (see below for | ||
29 | detailed description): | ||
30 | |||
31 | - Fn key combinations | ||
32 | - Bluetooth enable and disable | ||
33 | - Wlan enable and disable | ||
34 | - GPS enable and disable | ||
35 | - Video output switching | ||
36 | - Ambient Light Sensor on and off | ||
37 | - LED control | ||
38 | - LED Display control | ||
39 | - LCD brightness control | ||
40 | - LCD on and off | ||
41 | |||
42 | A compatibility table by model and feature is maintained on the web | ||
43 | site, http://acpi4asus.sf.net/. | ||
44 | |||
45 | Usage | ||
46 | ----- | ||
47 | |||
48 | Try "modprobe asus_acpi". Check your dmesg (simply type dmesg). You should | ||
49 | see some lines like this : | ||
50 | |||
51 | Asus Laptop Extras version 0.42 | ||
52 | L2D model detected. | ||
53 | |||
54 | If it is not the output you have on your laptop, send it (and the laptop's | ||
55 | DSDT) to me. | ||
56 | |||
57 | That's all, now, all the events generated by the hotkeys of your laptop | ||
58 | should be reported in your /proc/acpi/event entry. You can check with | ||
59 | "acpi_listen". | ||
60 | |||
61 | Hotkeys are also reported as input keys (like keyboards) you can check | ||
62 | which key are supported using "xev" under X11. | ||
63 | |||
64 | You can get informations on the version of your DSDT table by reading the | ||
65 | /sys/devices/platform/asus-laptop/infos entry. If you have a question or a | ||
66 | bug report to do, please include the output of this entry. | ||
67 | |||
68 | LEDs | ||
69 | ---- | ||
70 | |||
71 | You can modify LEDs be echoing values to /sys/class/leds/asus::*/brightness : | ||
72 | echo 1 > /sys/class/leds/asus::mail/brightness | ||
73 | will switch the mail LED on. | ||
74 | You can also know if they are on/off by reading their content and use | ||
75 | kernel triggers like ide-disk or heartbeat. | ||
76 | |||
77 | Backlight | ||
78 | --------- | ||
79 | |||
80 | You can control lcd backlight power and brightness with | ||
81 | /sys/class/backlight/asus-laptop/. Brightness Values are between 0 and 15. | ||
82 | |||
83 | Wireless devices | ||
84 | --------------- | ||
85 | |||
86 | You can turn the internal Bluetooth adapter on/off with the bluetooth entry | ||
87 | (only on models with Bluetooth). This usually controls the associated LED. | ||
88 | Same for Wlan adapter. | ||
89 | |||
90 | Display switching | ||
91 | ----------------- | ||
92 | |||
93 | Note: the display switching code is currently considered EXPERIMENTAL. | ||
94 | |||
95 | Switching works for the following models: | ||
96 | L3800C | ||
97 | A2500H | ||
98 | L5800C | ||
99 | M5200N | ||
100 | W1000N (albeit with some glitches) | ||
101 | M6700R | ||
102 | A6JC | ||
103 | F3J | ||
104 | |||
105 | Switching doesn't work for the following: | ||
106 | M3700N | ||
107 | L2X00D (locks the laptop under certain conditions) | ||
108 | |||
109 | To switch the displays, echo values from 0 to 15 to | ||
110 | /sys/devices/platform/asus-laptop/display. The significance of those values | ||
111 | is as follows: | ||
112 | |||
113 | +-------+-----+-----+-----+-----+-----+ | ||
114 | | Bin | Val | DVI | TV | CRT | LCD | | ||
115 | +-------+-----+-----+-----+-----+-----+ | ||
116 | + 0000 + 0 + + + + + | ||
117 | +-------+-----+-----+-----+-----+-----+ | ||
118 | + 0001 + 1 + + + + X + | ||
119 | +-------+-----+-----+-----+-----+-----+ | ||
120 | + 0010 + 2 + + + X + + | ||
121 | +-------+-----+-----+-----+-----+-----+ | ||
122 | + 0011 + 3 + + + X + X + | ||
123 | +-------+-----+-----+-----+-----+-----+ | ||
124 | + 0100 + 4 + + X + + + | ||
125 | +-------+-----+-----+-----+-----+-----+ | ||
126 | + 0101 + 5 + + X + + X + | ||
127 | +-------+-----+-----+-----+-----+-----+ | ||
128 | + 0110 + 6 + + X + X + + | ||
129 | +-------+-----+-----+-----+-----+-----+ | ||
130 | + 0111 + 7 + + X + X + X + | ||
131 | +-------+-----+-----+-----+-----+-----+ | ||
132 | + 1000 + 8 + X + + + + | ||
133 | +-------+-----+-----+-----+-----+-----+ | ||
134 | + 1001 + 9 + X + + + X + | ||
135 | +-------+-----+-----+-----+-----+-----+ | ||
136 | + 1010 + 10 + X + + X + + | ||
137 | +-------+-----+-----+-----+-----+-----+ | ||
138 | + 1011 + 11 + X + + X + X + | ||
139 | +-------+-----+-----+-----+-----+-----+ | ||
140 | + 1100 + 12 + X + X + + + | ||
141 | +-------+-----+-----+-----+-----+-----+ | ||
142 | + 1101 + 13 + X + X + + X + | ||
143 | +-------+-----+-----+-----+-----+-----+ | ||
144 | + 1110 + 14 + X + X + X + + | ||
145 | +-------+-----+-----+-----+-----+-----+ | ||
146 | + 1111 + 15 + X + X + X + X + | ||
147 | +-------+-----+-----+-----+-----+-----+ | ||
148 | |||
149 | In most cases, the appropriate displays must be plugged in for the above | ||
150 | combinations to work. TV-Out may need to be initialized at boot time. | ||
151 | |||
152 | Debugging: | ||
153 | 1) Check whether the Fn+F8 key: | ||
154 | a) does not lock the laptop (try disabling CONFIG_X86_UP_APIC or boot with | ||
155 | noapic / nolapic if it does) | ||
156 | b) generates events (0x6n, where n is the value corresponding to the | ||
157 | configuration above) | ||
158 | c) actually works | ||
159 | Record the disp value at every configuration. | ||
160 | 2) Echo values from 0 to 15 to /sys/devices/platform/asus-laptop/display. | ||
161 | Record its value, note any change. If nothing changes, try a broader range, | ||
162 | up to 65535. | ||
163 | 3) Send ANY output (both positive and negative reports are needed, unless your | ||
164 | machine is already listed above) to the acpi4asus-user mailing list. | ||
165 | |||
166 | Note: on some machines (e.g. L3C), after the module has been loaded, only 0x6n | ||
167 | events are generated and no actual switching occurs. In such a case, a line | ||
168 | like: | ||
169 | |||
170 | echo $((10#$arg-60)) > /sys/devices/platform/asus-laptop/display | ||
171 | |||
172 | will usually do the trick ($arg is the 0000006n-like event passed to acpid). | ||
173 | |||
174 | Note: there is currently no reliable way to read display status on xxN | ||
175 | (Centrino) models. | ||
176 | |||
177 | LED display | ||
178 | ----------- | ||
179 | |||
180 | Some models like the W1N have a LED display that can be used to display | ||
181 | several informations. | ||
182 | |||
183 | LED display works for the following models: | ||
184 | W1000N | ||
185 | W1J | ||
186 | |||
187 | To control the LED display, use the following : | ||
188 | |||
189 | echo 0x0T000DDD > /sys/devices/platform/asus-laptop/ | ||
190 | |||
191 | where T control the 3 letters display, and DDD the 3 digits display, | ||
192 | according to the tables below. | ||
193 | |||
194 | DDD (digits) | ||
195 | 000 to 999 = display digits | ||
196 | AAA = --- | ||
197 | BBB to FFF = turn-off | ||
198 | |||
199 | T (type) | ||
200 | 0 = off | ||
201 | 1 = dvd | ||
202 | 2 = vcd | ||
203 | 3 = mp3 | ||
204 | 4 = cd | ||
205 | 5 = tv | ||
206 | 6 = cpu | ||
207 | 7 = vol | ||
208 | |||
209 | For example "echo 0x01000001 >/sys/devices/platform/asus-laptop/ledd" | ||
210 | would display "DVD001". | ||
211 | |||
212 | Driver options: | ||
213 | --------------- | ||
214 | |||
215 | Options can be passed to the asus-laptop driver using the standard | ||
216 | module argument syntax (<param>=<value> when passing the option to the | ||
217 | module or asus-laptop.<param>=<value> on the kernel boot line when | ||
218 | asus-laptop is statically linked into the kernel). | ||
219 | |||
220 | wapf: WAPF defines the behavior of the Fn+Fx wlan key | ||
221 | The significance of values is yet to be found, but | ||
222 | most of the time: | ||
223 | - 0x0 should do nothing | ||
224 | - 0x1 should allow to control the device with Fn+Fx key. | ||
225 | - 0x4 should send an ACPI event (0x88) while pressing the Fn+Fx key | ||
226 | - 0x5 like 0x1 or 0x4 | ||
227 | |||
228 | The default value is 0x1. | ||
229 | |||
230 | Unsupported models | ||
231 | ------------------ | ||
232 | |||
233 | These models will never be supported by this module, as they use a completely | ||
234 | different mechanism to handle LEDs and extra stuff (meaning we have no clue | ||
235 | how it works): | ||
236 | |||
237 | - ASUS A1300 (A1B), A1370D | ||
238 | - ASUS L7300G | ||
239 | - ASUS L8400 | ||
240 | |||
241 | Patches, Errors, Questions: | ||
242 | -------------------------- | ||
243 | |||
244 | I appreciate any success or failure | ||
245 | reports, especially if they add to or correct the compatibility table. | ||
246 | Please include the following information in your report: | ||
247 | |||
248 | - Asus model name | ||
249 | - a copy of your ACPI tables, using the "acpidump" utility | ||
250 | - a copy of /sys/devices/platform/asus-laptop/infos | ||
251 | - which driver features work and which don't | ||
252 | - the observed behavior of non-working features | ||
253 | |||
254 | Any other comments or patches are also more than welcome. | ||
255 | |||
256 | acpi4asus-user@lists.sourceforge.net | ||
257 | http://sourceforge.net/projects/acpi4asus | ||
258 | |||
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index e2ddcdeb61b6..6d03487ef1c7 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt | |||
@@ -219,7 +219,7 @@ The following commands can be written to the /proc/acpi/ibm/hotkey file: | |||
219 | echo 0xffffffff > /proc/acpi/ibm/hotkey -- enable all hot keys | 219 | echo 0xffffffff > /proc/acpi/ibm/hotkey -- enable all hot keys |
220 | echo 0 > /proc/acpi/ibm/hotkey -- disable all possible hot keys | 220 | echo 0 > /proc/acpi/ibm/hotkey -- disable all possible hot keys |
221 | ... any other 8-hex-digit mask ... | 221 | ... any other 8-hex-digit mask ... |
222 | echo reset > /proc/acpi/ibm/hotkey -- restore the original mask | 222 | echo reset > /proc/acpi/ibm/hotkey -- restore the recommended mask |
223 | 223 | ||
224 | The following commands have been deprecated and will cause the kernel | 224 | The following commands have been deprecated and will cause the kernel |
225 | to log a warning: | 225 | to log a warning: |
@@ -240,9 +240,13 @@ sysfs notes: | |||
240 | Returns 0. | 240 | Returns 0. |
241 | 241 | ||
242 | hotkey_bios_mask: | 242 | hotkey_bios_mask: |
243 | DEPRECATED, DON'T USE, WILL BE REMOVED IN THE FUTURE. | ||
244 | |||
243 | Returns the hot keys mask when thinkpad-acpi was loaded. | 245 | Returns the hot keys mask when thinkpad-acpi was loaded. |
244 | Upon module unload, the hot keys mask will be restored | 246 | Upon module unload, the hot keys mask will be restored |
245 | to this value. | 247 | to this value. This is always 0x80c, because those are |
248 | the hotkeys that were supported by ancient firmware | ||
249 | without mask support. | ||
246 | 250 | ||
247 | hotkey_enable: | 251 | hotkey_enable: |
248 | DEPRECATED, WILL BE REMOVED SOON. | 252 | DEPRECATED, WILL BE REMOVED SOON. |
diff --git a/Documentation/leds-class.txt b/Documentation/leds-class.txt index 6399557cdab3..8fd5ca2ae32d 100644 --- a/Documentation/leds-class.txt +++ b/Documentation/leds-class.txt | |||
@@ -1,3 +1,4 @@ | |||
1 | |||
1 | LED handling under Linux | 2 | LED handling under Linux |
2 | ======================== | 3 | ======================== |
3 | 4 | ||
@@ -5,10 +6,10 @@ If you're reading this and thinking about keyboard leds, these are | |||
5 | handled by the input subsystem and the led class is *not* needed. | 6 | handled by the input subsystem and the led class is *not* needed. |
6 | 7 | ||
7 | In its simplest form, the LED class just allows control of LEDs from | 8 | In its simplest form, the LED class just allows control of LEDs from |
8 | userspace. LEDs appear in /sys/class/leds/. The brightness file will | 9 | userspace. LEDs appear in /sys/class/leds/. The maximum brightness of the |
9 | set the brightness of the LED (taking a value 0-255). Most LEDs don't | 10 | LED is defined in max_brightness file. The brightness file will set the brightness |
10 | have hardware brightness support so will just be turned on for non-zero | 11 | of the LED (taking a value 0-max_brightness). Most LEDs don't have hardware |
11 | brightness settings. | 12 | brightness support so will just be turned on for non-zero brightness settings. |
12 | 13 | ||
13 | The class also introduces the optional concept of an LED trigger. A trigger | 14 | The class also introduces the optional concept of an LED trigger. A trigger |
14 | is a kernel based source of led events. Triggers can either be simple or | 15 | is a kernel based source of led events. Triggers can either be simple or |
diff --git a/MAINTAINERS b/MAINTAINERS index b9a8a365418c..a44ea122f2ad 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -5069,6 +5069,11 @@ T: quilt http://svn.sourceforge.jp/svnroot/tomoyo/trunk/2.2.x/tomoyo-lsm/patches | |||
5069 | S: Maintained | 5069 | S: Maintained |
5070 | F: security/tomoyo/ | 5070 | F: security/tomoyo/ |
5071 | 5071 | ||
5072 | TOPSTAR LAPTOP EXTRAS DRIVER | ||
5073 | M: Herton Ronaldo Krzesinski <herton@mandriva.com.br> | ||
5074 | S: Maintained | ||
5075 | F: drivers/platform/x86/topstar-laptop.c | ||
5076 | |||
5072 | TOSHIBA ACPI EXTRAS DRIVER | 5077 | TOSHIBA ACPI EXTRAS DRIVER |
5073 | S: Orphan | 5078 | S: Orphan |
5074 | F: drivers/platform/x86/toshiba_acpi.c | 5079 | F: drivers/platform/x86/toshiba_acpi.c |
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 8cfb001092ab..674a8374c6d9 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c | |||
@@ -2026,24 +2026,21 @@ acpi_sba_ioc_add(struct acpi_device *device) | |||
2026 | struct ioc *ioc; | 2026 | struct ioc *ioc; |
2027 | acpi_status status; | 2027 | acpi_status status; |
2028 | u64 hpa, length; | 2028 | u64 hpa, length; |
2029 | struct acpi_buffer buffer; | ||
2030 | struct acpi_device_info *dev_info; | 2029 | struct acpi_device_info *dev_info; |
2031 | 2030 | ||
2032 | status = hp_acpi_csr_space(device->handle, &hpa, &length); | 2031 | status = hp_acpi_csr_space(device->handle, &hpa, &length); |
2033 | if (ACPI_FAILURE(status)) | 2032 | if (ACPI_FAILURE(status)) |
2034 | return 1; | 2033 | return 1; |
2035 | 2034 | ||
2036 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | 2035 | status = acpi_get_object_info(device->handle, &dev_info); |
2037 | status = acpi_get_object_info(device->handle, &buffer); | ||
2038 | if (ACPI_FAILURE(status)) | 2036 | if (ACPI_FAILURE(status)) |
2039 | return 1; | 2037 | return 1; |
2040 | dev_info = buffer.pointer; | ||
2041 | 2038 | ||
2042 | /* | 2039 | /* |
2043 | * For HWP0001, only SBA appears in ACPI namespace. It encloses the PCI | 2040 | * For HWP0001, only SBA appears in ACPI namespace. It encloses the PCI |
2044 | * root bridges, and its CSR space includes the IOC function. | 2041 | * root bridges, and its CSR space includes the IOC function. |
2045 | */ | 2042 | */ |
2046 | if (strncmp("HWP0001", dev_info->hardware_id.value, 7) == 0) { | 2043 | if (strncmp("HWP0001", dev_info->hardware_id.string, 7) == 0) { |
2047 | hpa += ZX1_IOC_OFFSET; | 2044 | hpa += ZX1_IOC_OFFSET; |
2048 | /* zx1 based systems default to kernel page size iommu pages */ | 2045 | /* zx1 based systems default to kernel page size iommu pages */ |
2049 | if (!iovp_shift) | 2046 | if (!iovp_shift) |
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 20d1465a2ab0..4518dc500903 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h | |||
@@ -144,7 +144,6 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate) | |||
144 | 144 | ||
145 | #else /* !CONFIG_ACPI */ | 145 | #else /* !CONFIG_ACPI */ |
146 | 146 | ||
147 | #define acpi_disabled 1 | ||
148 | #define acpi_lapic 0 | 147 | #define acpi_lapic 0 |
149 | #define acpi_ioapic 0 | 148 | #define acpi_ioapic 0 |
150 | static inline void acpi_noirq_set(void) { } | 149 | static inline void acpi_noirq_set(void) { } |
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 712443ec6d43..b707a0141d3b 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <asm/e820.h> | 18 | #include <asm/e820.h> |
19 | #include <asm/pci_x86.h> | 19 | #include <asm/pci_x86.h> |
20 | 20 | ||
21 | #define PREFIX "PCI: " | ||
22 | |||
21 | /* aperture is up to 256MB but BIOS may reserve less */ | 23 | /* aperture is up to 256MB but BIOS may reserve less */ |
22 | #define MMCONFIG_APER_MIN (2 * 1024*1024) | 24 | #define MMCONFIG_APER_MIN (2 * 1024*1024) |
23 | #define MMCONFIG_APER_MAX (256 * 1024*1024) | 25 | #define MMCONFIG_APER_MAX (256 * 1024*1024) |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 7ec7d88c5999..dd8729d674e5 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -60,7 +60,11 @@ config ACPI_PROCFS | |||
60 | /proc/acpi/fadt (/sys/firmware/acpi/tables/FACP) | 60 | /proc/acpi/fadt (/sys/firmware/acpi/tables/FACP) |
61 | /proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer) | 61 | /proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer) |
62 | /proc/acpi/debug_level (/sys/module/acpi/parameters/debug_level) | 62 | /proc/acpi/debug_level (/sys/module/acpi/parameters/debug_level) |
63 | 63 | /proc/acpi/processor/*/power (/sys/devices/system/cpu/*/cpuidle/*) | |
64 | /proc/acpi/processor/*/performance (/sys/devices/system/cpu/*/ | ||
65 | cpufreq/*) | ||
66 | /proc/acpi/processor/*/throttling (/sys/class/thermal/ | ||
67 | cooling_device*/*) | ||
64 | This option has no effect on /proc/acpi/ files | 68 | This option has no effect on /proc/acpi/ files |
65 | and functions which do not yet exist in /sys. | 69 | and functions which do not yet exist in /sys. |
66 | 70 | ||
@@ -82,6 +86,17 @@ config ACPI_PROCFS_POWER | |||
82 | 86 | ||
83 | Say N to delete power /proc/acpi/ directories that have moved to /sys/ | 87 | Say N to delete power /proc/acpi/ directories that have moved to /sys/ |
84 | 88 | ||
89 | config ACPI_POWER_METER | ||
90 | tristate "ACPI 4.0 power meter" | ||
91 | depends on HWMON | ||
92 | help | ||
93 | This driver exposes ACPI 4.0 power meters as hardware monitoring | ||
94 | devices. Say Y (or M) if you have a computer with ACPI 4.0 firmware | ||
95 | and a power meter. | ||
96 | |||
97 | To compile this driver as a module, choose M here: | ||
98 | the module will be called power-meter. | ||
99 | |||
85 | config ACPI_SYSFS_POWER | 100 | config ACPI_SYSFS_POWER |
86 | bool "Future power /sys interface" | 101 | bool "Future power /sys interface" |
87 | select POWER_SUPPLY | 102 | select POWER_SUPPLY |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 03a985be3fe3..82cd49dc603b 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -56,6 +56,7 @@ obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o | |||
56 | obj-$(CONFIG_ACPI_BATTERY) += battery.o | 56 | obj-$(CONFIG_ACPI_BATTERY) += battery.o |
57 | obj-$(CONFIG_ACPI_SBS) += sbshc.o | 57 | obj-$(CONFIG_ACPI_SBS) += sbshc.o |
58 | obj-$(CONFIG_ACPI_SBS) += sbs.o | 58 | obj-$(CONFIG_ACPI_SBS) += sbs.o |
59 | obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o | ||
59 | 60 | ||
60 | # processor has its own "processor." module_param namespace | 61 | # processor has its own "processor." module_param namespace |
61 | processor-y := processor_core.o processor_throttling.o | 62 | processor-y := processor_core.o processor_throttling.o |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 0df8fcb687d6..98b9690b0159 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #include <acpi/acpi_bus.h> | 37 | #include <acpi/acpi_bus.h> |
38 | #include <acpi/acpi_drivers.h> | 38 | #include <acpi/acpi_drivers.h> |
39 | 39 | ||
40 | #define PREFIX "ACPI: " | ||
41 | |||
40 | #define ACPI_AC_CLASS "ac_adapter" | 42 | #define ACPI_AC_CLASS "ac_adapter" |
41 | #define ACPI_AC_DEVICE_NAME "AC Adapter" | 43 | #define ACPI_AC_DEVICE_NAME "AC Adapter" |
42 | #define ACPI_AC_FILE_STATE "state" | 44 | #define ACPI_AC_FILE_STATE "state" |
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 9a62224cc278..28ccdbc05ac8 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c | |||
@@ -53,7 +53,6 @@ MODULE_LICENSE("GPL"); | |||
53 | 53 | ||
54 | static int acpi_memory_device_add(struct acpi_device *device); | 54 | static int acpi_memory_device_add(struct acpi_device *device); |
55 | static int acpi_memory_device_remove(struct acpi_device *device, int type); | 55 | static int acpi_memory_device_remove(struct acpi_device *device, int type); |
56 | static int acpi_memory_device_start(struct acpi_device *device); | ||
57 | 56 | ||
58 | static const struct acpi_device_id memory_device_ids[] = { | 57 | static const struct acpi_device_id memory_device_ids[] = { |
59 | {ACPI_MEMORY_DEVICE_HID, 0}, | 58 | {ACPI_MEMORY_DEVICE_HID, 0}, |
@@ -68,7 +67,6 @@ static struct acpi_driver acpi_memory_device_driver = { | |||
68 | .ops = { | 67 | .ops = { |
69 | .add = acpi_memory_device_add, | 68 | .add = acpi_memory_device_add, |
70 | .remove = acpi_memory_device_remove, | 69 | .remove = acpi_memory_device_remove, |
71 | .start = acpi_memory_device_start, | ||
72 | }, | 70 | }, |
73 | }; | 71 | }; |
74 | 72 | ||
@@ -431,28 +429,6 @@ static int acpi_memory_device_add(struct acpi_device *device) | |||
431 | 429 | ||
432 | printk(KERN_DEBUG "%s \n", acpi_device_name(device)); | 430 | printk(KERN_DEBUG "%s \n", acpi_device_name(device)); |
433 | 431 | ||
434 | return result; | ||
435 | } | ||
436 | |||
437 | static int acpi_memory_device_remove(struct acpi_device *device, int type) | ||
438 | { | ||
439 | struct acpi_memory_device *mem_device = NULL; | ||
440 | |||
441 | |||
442 | if (!device || !acpi_driver_data(device)) | ||
443 | return -EINVAL; | ||
444 | |||
445 | mem_device = acpi_driver_data(device); | ||
446 | kfree(mem_device); | ||
447 | |||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | static int acpi_memory_device_start (struct acpi_device *device) | ||
452 | { | ||
453 | struct acpi_memory_device *mem_device; | ||
454 | int result = 0; | ||
455 | |||
456 | /* | 432 | /* |
457 | * Early boot code has recognized memory area by EFI/E820. | 433 | * Early boot code has recognized memory area by EFI/E820. |
458 | * If DSDT shows these memory devices on boot, hotplug is not necessary | 434 | * If DSDT shows these memory devices on boot, hotplug is not necessary |
@@ -462,8 +438,6 @@ static int acpi_memory_device_start (struct acpi_device *device) | |||
462 | if (!acpi_hotmem_initialized) | 438 | if (!acpi_hotmem_initialized) |
463 | return 0; | 439 | return 0; |
464 | 440 | ||
465 | mem_device = acpi_driver_data(device); | ||
466 | |||
467 | if (!acpi_memory_check_device(mem_device)) { | 441 | if (!acpi_memory_check_device(mem_device)) { |
468 | /* call add_memory func */ | 442 | /* call add_memory func */ |
469 | result = acpi_memory_enable_device(mem_device); | 443 | result = acpi_memory_enable_device(mem_device); |
@@ -474,6 +448,20 @@ static int acpi_memory_device_start (struct acpi_device *device) | |||
474 | return result; | 448 | return result; |
475 | } | 449 | } |
476 | 450 | ||
451 | static int acpi_memory_device_remove(struct acpi_device *device, int type) | ||
452 | { | ||
453 | struct acpi_memory_device *mem_device = NULL; | ||
454 | |||
455 | |||
456 | if (!device || !acpi_driver_data(device)) | ||
457 | return -EINVAL; | ||
458 | |||
459 | mem_device = acpi_driver_data(device); | ||
460 | kfree(mem_device); | ||
461 | |||
462 | return 0; | ||
463 | } | ||
464 | |||
477 | /* | 465 | /* |
478 | * Helper function to check for memory device | 466 | * Helper function to check for memory device |
479 | */ | 467 | */ |
@@ -481,26 +469,23 @@ static acpi_status is_memory_device(acpi_handle handle) | |||
481 | { | 469 | { |
482 | char *hardware_id; | 470 | char *hardware_id; |
483 | acpi_status status; | 471 | acpi_status status; |
484 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
485 | struct acpi_device_info *info; | 472 | struct acpi_device_info *info; |
486 | 473 | ||
487 | 474 | status = acpi_get_object_info(handle, &info); | |
488 | status = acpi_get_object_info(handle, &buffer); | ||
489 | if (ACPI_FAILURE(status)) | 475 | if (ACPI_FAILURE(status)) |
490 | return status; | 476 | return status; |
491 | 477 | ||
492 | info = buffer.pointer; | ||
493 | if (!(info->valid & ACPI_VALID_HID)) { | 478 | if (!(info->valid & ACPI_VALID_HID)) { |
494 | kfree(buffer.pointer); | 479 | kfree(info); |
495 | return AE_ERROR; | 480 | return AE_ERROR; |
496 | } | 481 | } |
497 | 482 | ||
498 | hardware_id = info->hardware_id.value; | 483 | hardware_id = info->hardware_id.string; |
499 | if ((hardware_id == NULL) || | 484 | if ((hardware_id == NULL) || |
500 | (strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID))) | 485 | (strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID))) |
501 | status = AE_ERROR; | 486 | status = AE_ERROR; |
502 | 487 | ||
503 | kfree(buffer.pointer); | 488 | kfree(info); |
504 | return status; | 489 | return status; |
505 | } | 490 | } |
506 | 491 | ||
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 72ac28da14e3..e7973bc16846 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile | |||
@@ -28,7 +28,7 @@ acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o | |||
28 | acpi-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \ | 28 | acpi-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \ |
29 | nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \ | 29 | nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \ |
30 | nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \ | 30 | nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \ |
31 | nsparse.o nspredef.o | 31 | nsparse.o nspredef.o nsrepair.o |
32 | 32 | ||
33 | acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o | 33 | acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o |
34 | 34 | ||
@@ -44,4 +44,4 @@ acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o | |||
44 | 44 | ||
45 | acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ | 45 | acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ |
46 | utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ | 46 | utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ |
47 | utstate.o utmutex.o utobject.o utresrc.o utlock.o | 47 | utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o |
diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h index e6777fb883d2..8e679ef5b231 100644 --- a/drivers/acpi/acpica/acconfig.h +++ b/drivers/acpi/acpica/acconfig.h | |||
@@ -183,7 +183,7 @@ | |||
183 | 183 | ||
184 | /* Operation regions */ | 184 | /* Operation regions */ |
185 | 185 | ||
186 | #define ACPI_NUM_PREDEFINED_REGIONS 8 | 186 | #define ACPI_NUM_PREDEFINED_REGIONS 9 |
187 | #define ACPI_USER_REGION_BEGIN 0x80 | 187 | #define ACPI_USER_REGION_BEGIN 0x80 |
188 | 188 | ||
189 | /* Maximum space_ids for Operation Regions */ | 189 | /* Maximum space_ids for Operation Regions */ |
@@ -199,9 +199,15 @@ | |||
199 | #define ACPI_RSDP_CHECKSUM_LENGTH 20 | 199 | #define ACPI_RSDP_CHECKSUM_LENGTH 20 |
200 | #define ACPI_RSDP_XCHECKSUM_LENGTH 36 | 200 | #define ACPI_RSDP_XCHECKSUM_LENGTH 36 |
201 | 201 | ||
202 | /* SMBus bidirectional buffer size */ | 202 | /* SMBus and IPMI bidirectional buffer size */ |
203 | 203 | ||
204 | #define ACPI_SMBUS_BUFFER_SIZE 34 | 204 | #define ACPI_SMBUS_BUFFER_SIZE 34 |
205 | #define ACPI_IPMI_BUFFER_SIZE 66 | ||
206 | |||
207 | /* _sx_d and _sx_w control methods */ | ||
208 | |||
209 | #define ACPI_NUM_sx_d_METHODS 4 | ||
210 | #define ACPI_NUM_sx_w_METHODS 5 | ||
205 | 211 | ||
206 | /****************************************************************************** | 212 | /****************************************************************************** |
207 | * | 213 | * |
diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index 62c59df3b86c..a4fb001d96f1 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h | |||
@@ -154,10 +154,6 @@ void | |||
154 | acpi_db_display_argument_object(union acpi_operand_object *obj_desc, | 154 | acpi_db_display_argument_object(union acpi_operand_object *obj_desc, |
155 | struct acpi_walk_state *walk_state); | 155 | struct acpi_walk_state *walk_state); |
156 | 156 | ||
157 | void acpi_db_check_predefined_names(void); | ||
158 | |||
159 | void acpi_db_batch_execute(void); | ||
160 | |||
161 | /* | 157 | /* |
162 | * dbexec - debugger control method execution | 158 | * dbexec - debugger control method execution |
163 | */ | 159 | */ |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 3d87362d17ed..29ba66d5a790 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -58,6 +58,10 @@ | |||
58 | #define ACPI_INIT_GLOBAL(a,b) a | 58 | #define ACPI_INIT_GLOBAL(a,b) a |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | #ifdef DEFINE_ACPI_GLOBALS | ||
62 | |||
63 | /* Public globals, available from outside ACPICA subsystem */ | ||
64 | |||
61 | /***************************************************************************** | 65 | /***************************************************************************** |
62 | * | 66 | * |
63 | * Runtime configuration (static defaults that can be overriden at runtime) | 67 | * Runtime configuration (static defaults that can be overriden at runtime) |
@@ -78,7 +82,7 @@ | |||
78 | * 5) Allow unresolved references (invalid target name) in package objects | 82 | * 5) Allow unresolved references (invalid target name) in package objects |
79 | * 6) Enable warning messages for behavior that is not ACPI spec compliant | 83 | * 6) Enable warning messages for behavior that is not ACPI spec compliant |
80 | */ | 84 | */ |
81 | ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_interpreter_slack, FALSE); | 85 | u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_interpreter_slack, FALSE); |
82 | 86 | ||
83 | /* | 87 | /* |
84 | * Automatically serialize ALL control methods? Default is FALSE, meaning | 88 | * Automatically serialize ALL control methods? Default is FALSE, meaning |
@@ -86,27 +90,36 @@ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_interpreter_slack, FALSE); | |||
86 | * Only change this if the ASL code is poorly written and cannot handle | 90 | * Only change this if the ASL code is poorly written and cannot handle |
87 | * reentrancy even though methods are marked "NotSerialized". | 91 | * reentrancy even though methods are marked "NotSerialized". |
88 | */ | 92 | */ |
89 | ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_all_methods_serialized, FALSE); | 93 | u8 ACPI_INIT_GLOBAL(acpi_gbl_all_methods_serialized, FALSE); |
90 | 94 | ||
91 | /* | 95 | /* |
92 | * Create the predefined _OSI method in the namespace? Default is TRUE | 96 | * Create the predefined _OSI method in the namespace? Default is TRUE |
93 | * because ACPI CA is fully compatible with other ACPI implementations. | 97 | * because ACPI CA is fully compatible with other ACPI implementations. |
94 | * Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior. | 98 | * Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior. |
95 | */ | 99 | */ |
96 | ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_create_osi_method, TRUE); | 100 | u8 ACPI_INIT_GLOBAL(acpi_gbl_create_osi_method, TRUE); |
97 | 101 | ||
98 | /* | 102 | /* |
99 | * Disable wakeup GPEs during runtime? Default is TRUE because WAKE and | 103 | * Disable wakeup GPEs during runtime? Default is TRUE because WAKE and |
100 | * RUNTIME GPEs should never be shared, and WAKE GPEs should typically only | 104 | * RUNTIME GPEs should never be shared, and WAKE GPEs should typically only |
101 | * be enabled just before going to sleep. | 105 | * be enabled just before going to sleep. |
102 | */ | 106 | */ |
103 | ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_leave_wake_gpes_disabled, TRUE); | 107 | u8 ACPI_INIT_GLOBAL(acpi_gbl_leave_wake_gpes_disabled, TRUE); |
104 | 108 | ||
105 | /* | 109 | /* |
106 | * Optionally use default values for the ACPI register widths. Set this to | 110 | * Optionally use default values for the ACPI register widths. Set this to |
107 | * TRUE to use the defaults, if an FADT contains incorrect widths/lengths. | 111 | * TRUE to use the defaults, if an FADT contains incorrect widths/lengths. |
108 | */ | 112 | */ |
109 | ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_use_default_register_widths, TRUE); | 113 | u8 ACPI_INIT_GLOBAL(acpi_gbl_use_default_register_widths, TRUE); |
114 | |||
115 | /* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ | ||
116 | |||
117 | struct acpi_table_fadt acpi_gbl_FADT; | ||
118 | u32 acpi_current_gpe_count; | ||
119 | u32 acpi_gbl_trace_flags; | ||
120 | acpi_name acpi_gbl_trace_method_name; | ||
121 | |||
122 | #endif | ||
110 | 123 | ||
111 | /***************************************************************************** | 124 | /***************************************************************************** |
112 | * | 125 | * |
@@ -114,11 +127,6 @@ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_use_default_register_widths, TRUE); | |||
114 | * | 127 | * |
115 | ****************************************************************************/ | 128 | ****************************************************************************/ |
116 | 129 | ||
117 | /* Runtime configuration of debug print levels */ | ||
118 | |||
119 | extern u32 acpi_dbg_level; | ||
120 | extern u32 acpi_dbg_layer; | ||
121 | |||
122 | /* Procedure nesting level for debug output */ | 130 | /* Procedure nesting level for debug output */ |
123 | 131 | ||
124 | extern u32 acpi_gbl_nesting_level; | 132 | extern u32 acpi_gbl_nesting_level; |
@@ -127,10 +135,8 @@ extern u32 acpi_gbl_nesting_level; | |||
127 | 135 | ||
128 | ACPI_EXTERN u32 acpi_gbl_original_dbg_level; | 136 | ACPI_EXTERN u32 acpi_gbl_original_dbg_level; |
129 | ACPI_EXTERN u32 acpi_gbl_original_dbg_layer; | 137 | ACPI_EXTERN u32 acpi_gbl_original_dbg_layer; |
130 | ACPI_EXTERN acpi_name acpi_gbl_trace_method_name; | ||
131 | ACPI_EXTERN u32 acpi_gbl_trace_dbg_level; | 138 | ACPI_EXTERN u32 acpi_gbl_trace_dbg_level; |
132 | ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer; | 139 | ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer; |
133 | ACPI_EXTERN u32 acpi_gbl_trace_flags; | ||
134 | 140 | ||
135 | /***************************************************************************** | 141 | /***************************************************************************** |
136 | * | 142 | * |
@@ -142,10 +148,8 @@ ACPI_EXTERN u32 acpi_gbl_trace_flags; | |||
142 | * acpi_gbl_root_table_list is the master list of ACPI tables found in the | 148 | * acpi_gbl_root_table_list is the master list of ACPI tables found in the |
143 | * RSDT/XSDT. | 149 | * RSDT/XSDT. |
144 | * | 150 | * |
145 | * acpi_gbl_FADT is a local copy of the FADT, converted to a common format. | ||
146 | */ | 151 | */ |
147 | ACPI_EXTERN struct acpi_internal_rsdt acpi_gbl_root_table_list; | 152 | ACPI_EXTERN struct acpi_internal_rsdt acpi_gbl_root_table_list; |
148 | ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT; | ||
149 | ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS; | 153 | ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS; |
150 | 154 | ||
151 | /* These addresses are calculated from the FADT Event Block addresses */ | 155 | /* These addresses are calculated from the FADT Event Block addresses */ |
@@ -261,7 +265,8 @@ ACPI_EXTERN u8 acpi_gbl_osi_data; | |||
261 | extern u8 acpi_gbl_shutdown; | 265 | extern u8 acpi_gbl_shutdown; |
262 | extern u32 acpi_gbl_startup_flags; | 266 | extern u32 acpi_gbl_startup_flags; |
263 | extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT]; | 267 | extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT]; |
264 | extern const char *acpi_gbl_highest_dstate_names[4]; | 268 | extern const char *acpi_gbl_lowest_dstate_names[ACPI_NUM_sx_w_METHODS]; |
269 | extern const char *acpi_gbl_highest_dstate_names[ACPI_NUM_sx_d_METHODS]; | ||
265 | extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; | 270 | extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; |
266 | extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; | 271 | extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; |
267 | 272 | ||
@@ -290,6 +295,7 @@ extern char const *acpi_gbl_exception_names_ctrl[]; | |||
290 | ACPI_EXTERN struct acpi_namespace_node acpi_gbl_root_node_struct; | 295 | ACPI_EXTERN struct acpi_namespace_node acpi_gbl_root_node_struct; |
291 | ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_root_node; | 296 | ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_root_node; |
292 | ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_fadt_gpe_device; | 297 | ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_fadt_gpe_device; |
298 | ACPI_EXTERN union acpi_operand_object *acpi_gbl_module_code_list; | ||
293 | 299 | ||
294 | extern const u8 acpi_gbl_ns_properties[ACPI_NUM_NS_TYPES]; | 300 | extern const u8 acpi_gbl_ns_properties[ACPI_NUM_NS_TYPES]; |
295 | extern const struct acpi_predefined_names | 301 | extern const struct acpi_predefined_names |
@@ -340,7 +346,6 @@ ACPI_EXTERN struct acpi_fixed_event_handler | |||
340 | ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; | 346 | ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; |
341 | ACPI_EXTERN struct acpi_gpe_block_info | 347 | ACPI_EXTERN struct acpi_gpe_block_info |
342 | *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; | 348 | *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; |
343 | ACPI_EXTERN u32 acpi_current_gpe_count; | ||
344 | 349 | ||
345 | /***************************************************************************** | 350 | /***************************************************************************** |
346 | * | 351 | * |
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 4afa3d8e0efb..36192f142fbb 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h | |||
@@ -62,6 +62,14 @@ u32 acpi_hw_get_mode(void); | |||
62 | /* | 62 | /* |
63 | * hwregs - ACPI Register I/O | 63 | * hwregs - ACPI Register I/O |
64 | */ | 64 | */ |
65 | acpi_status | ||
66 | acpi_hw_validate_register(struct acpi_generic_address *reg, | ||
67 | u8 max_bit_width, u64 *address); | ||
68 | |||
69 | acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg); | ||
70 | |||
71 | acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg); | ||
72 | |||
65 | struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id); | 73 | struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id); |
66 | 74 | ||
67 | acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control); | 75 | acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control); |
diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h index e8db7a3143a5..5db9f2916f7c 100644 --- a/drivers/acpi/acpica/acinterp.h +++ b/drivers/acpi/acpica/acinterp.h | |||
@@ -461,9 +461,9 @@ void acpi_ex_acquire_global_lock(u32 rule); | |||
461 | 461 | ||
462 | void acpi_ex_release_global_lock(u32 rule); | 462 | void acpi_ex_release_global_lock(u32 rule); |
463 | 463 | ||
464 | void acpi_ex_eisa_id_to_string(u32 numeric_id, char *out_string); | 464 | void acpi_ex_eisa_id_to_string(char *dest, acpi_integer compressed_id); |
465 | 465 | ||
466 | void acpi_ex_unsigned_integer_to_string(acpi_integer value, char *out_string); | 466 | void acpi_ex_integer_to_string(char *dest, acpi_integer value); |
467 | 467 | ||
468 | /* | 468 | /* |
469 | * exregion - default op_region handlers | 469 | * exregion - default op_region handlers |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index ee986edfa0da..81e64f478679 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -369,6 +369,19 @@ union acpi_predefined_info { | |||
369 | struct acpi_package_info3 ret_info3; | 369 | struct acpi_package_info3 ret_info3; |
370 | }; | 370 | }; |
371 | 371 | ||
372 | /* Data block used during object validation */ | ||
373 | |||
374 | struct acpi_predefined_data { | ||
375 | char *pathname; | ||
376 | const union acpi_predefined_info *predefined; | ||
377 | u32 flags; | ||
378 | u8 node_flags; | ||
379 | }; | ||
380 | |||
381 | /* Defines for Flags field above */ | ||
382 | |||
383 | #define ACPI_OBJECT_REPAIRED 1 | ||
384 | |||
372 | /* | 385 | /* |
373 | * Bitmapped return value types | 386 | * Bitmapped return value types |
374 | * Note: the actual data types must be contiguous, a loop in nspredef.c | 387 | * Note: the actual data types must be contiguous, a loop in nspredef.c |
@@ -885,6 +898,9 @@ struct acpi_bit_register_info { | |||
885 | #define ACPI_OSI_WIN_XP_SP2 0x05 | 898 | #define ACPI_OSI_WIN_XP_SP2 0x05 |
886 | #define ACPI_OSI_WINSRV_2003_SP1 0x06 | 899 | #define ACPI_OSI_WINSRV_2003_SP1 0x06 |
887 | #define ACPI_OSI_WIN_VISTA 0x07 | 900 | #define ACPI_OSI_WIN_VISTA 0x07 |
901 | #define ACPI_OSI_WINSRV_2008 0x08 | ||
902 | #define ACPI_OSI_WIN_VISTA_SP1 0x09 | ||
903 | #define ACPI_OSI_WIN_7 0x0A | ||
888 | 904 | ||
889 | #define ACPI_ALWAYS_ILLEGAL 0x00 | 905 | #define ACPI_ALWAYS_ILLEGAL 0x00 |
890 | 906 | ||
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 91ac7d7b4402..3acd9c6760ea 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h | |||
@@ -340,6 +340,7 @@ | |||
340 | */ | 340 | */ |
341 | #define ACPI_ERROR_NAMESPACE(s, e) acpi_ns_report_error (AE_INFO, s, e); | 341 | #define ACPI_ERROR_NAMESPACE(s, e) acpi_ns_report_error (AE_INFO, s, e); |
342 | #define ACPI_ERROR_METHOD(s, n, p, e) acpi_ns_report_method_error (AE_INFO, s, n, p, e); | 342 | #define ACPI_ERROR_METHOD(s, n, p, e) acpi_ns_report_method_error (AE_INFO, s, n, p, e); |
343 | #define ACPI_WARN_PREDEFINED(plist) acpi_ut_predefined_warning plist | ||
343 | 344 | ||
344 | #else | 345 | #else |
345 | 346 | ||
@@ -347,6 +348,7 @@ | |||
347 | 348 | ||
348 | #define ACPI_ERROR_NAMESPACE(s, e) | 349 | #define ACPI_ERROR_NAMESPACE(s, e) |
349 | #define ACPI_ERROR_METHOD(s, n, p, e) | 350 | #define ACPI_ERROR_METHOD(s, n, p, e) |
351 | #define ACPI_WARN_PREDEFINED(plist) | ||
350 | #endif /* ACPI_NO_ERROR_MESSAGES */ | 352 | #endif /* ACPI_NO_ERROR_MESSAGES */ |
351 | 353 | ||
352 | /* | 354 | /* |
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 94cdc2b8cb93..09a2764c734b 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h | |||
@@ -73,6 +73,14 @@ | |||
73 | #define ACPI_NS_WALK_UNLOCK 0x01 | 73 | #define ACPI_NS_WALK_UNLOCK 0x01 |
74 | #define ACPI_NS_WALK_TEMP_NODES 0x02 | 74 | #define ACPI_NS_WALK_TEMP_NODES 0x02 |
75 | 75 | ||
76 | /* Object is not a package element */ | ||
77 | |||
78 | #define ACPI_NOT_PACKAGE_ELEMENT ACPI_UINT32_MAX | ||
79 | |||
80 | /* Always emit warning message, not dependent on node flags */ | ||
81 | |||
82 | #define ACPI_WARN_ALWAYS 0 | ||
83 | |||
76 | /* | 84 | /* |
77 | * nsinit - Namespace initialization | 85 | * nsinit - Namespace initialization |
78 | */ | 86 | */ |
@@ -144,6 +152,8 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name); | |||
144 | 152 | ||
145 | void acpi_ns_delete_node(struct acpi_namespace_node *node); | 153 | void acpi_ns_delete_node(struct acpi_namespace_node *node); |
146 | 154 | ||
155 | void acpi_ns_remove_node(struct acpi_namespace_node *node); | ||
156 | |||
147 | void | 157 | void |
148 | acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_handle); | 158 | acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_handle); |
149 | 159 | ||
@@ -186,6 +196,8 @@ acpi_ns_dump_objects(acpi_object_type type, | |||
186 | */ | 196 | */ |
187 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info); | 197 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info); |
188 | 198 | ||
199 | void acpi_ns_exec_module_code_list(void); | ||
200 | |||
189 | /* | 201 | /* |
190 | * nspredef - Support for predefined/reserved names | 202 | * nspredef - Support for predefined/reserved names |
191 | */ | 203 | */ |
@@ -260,6 +272,19 @@ acpi_ns_get_attached_data(struct acpi_namespace_node *node, | |||
260 | acpi_object_handler handler, void **data); | 272 | acpi_object_handler handler, void **data); |
261 | 273 | ||
262 | /* | 274 | /* |
275 | * nsrepair - return object repair for predefined methods/objects | ||
276 | */ | ||
277 | acpi_status | ||
278 | acpi_ns_repair_object(struct acpi_predefined_data *data, | ||
279 | u32 expected_btypes, | ||
280 | u32 package_index, | ||
281 | union acpi_operand_object **return_object_ptr); | ||
282 | |||
283 | acpi_status | ||
284 | acpi_ns_repair_package_list(struct acpi_predefined_data *data, | ||
285 | union acpi_operand_object **obj_desc_ptr); | ||
286 | |||
287 | /* | ||
263 | * nssearch - Namespace searching and entry | 288 | * nssearch - Namespace searching and entry |
264 | */ | 289 | */ |
265 | acpi_status | 290 | acpi_status |
diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index eb6f038b03d9..b39d682a2140 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h | |||
@@ -98,6 +98,7 @@ | |||
98 | #define AOPOBJ_SETUP_COMPLETE 0x10 | 98 | #define AOPOBJ_SETUP_COMPLETE 0x10 |
99 | #define AOPOBJ_SINGLE_DATUM 0x20 | 99 | #define AOPOBJ_SINGLE_DATUM 0x20 |
100 | #define AOPOBJ_INVALID 0x40 /* Used if host OS won't allow an op_region address */ | 100 | #define AOPOBJ_INVALID 0x40 /* Used if host OS won't allow an op_region address */ |
101 | #define AOPOBJ_MODULE_LEVEL 0x80 | ||
101 | 102 | ||
102 | /****************************************************************************** | 103 | /****************************************************************************** |
103 | * | 104 | * |
diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h index 23ee0fbf5619..22881e8ce229 100644 --- a/drivers/acpi/acpica/acparser.h +++ b/drivers/acpi/acpica/acparser.h | |||
@@ -62,6 +62,8 @@ | |||
62 | #define ACPI_PARSE_DEFERRED_OP 0x0100 | 62 | #define ACPI_PARSE_DEFERRED_OP 0x0100 |
63 | #define ACPI_PARSE_DISASSEMBLE 0x0200 | 63 | #define ACPI_PARSE_DISASSEMBLE 0x0200 |
64 | 64 | ||
65 | #define ACPI_PARSE_MODULE_LEVEL 0x0400 | ||
66 | |||
65 | /****************************************************************************** | 67 | /****************************************************************************** |
66 | * | 68 | * |
67 | * Parser interfaces | 69 | * Parser interfaces |
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index 63f656ae3604..cd80d1dd1950 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h | |||
@@ -64,8 +64,8 @@ | |||
64 | * (Used for _PRW) | 64 | * (Used for _PRW) |
65 | * | 65 | * |
66 | * | 66 | * |
67 | * 2) PTYPE2 packages contain a variable number of sub-packages. Each of the | 67 | * 2) PTYPE2 packages contain a Variable-length number of sub-packages. Each |
68 | * different types describe the contents of each of the sub-packages. | 68 | * of the different types describe the contents of each of the sub-packages. |
69 | * | 69 | * |
70 | * ACPI_PTYPE2: Each subpackage contains 1 or 2 object types: | 70 | * ACPI_PTYPE2: Each subpackage contains 1 or 2 object types: |
71 | * object type | 71 | * object type |
@@ -91,6 +91,9 @@ | |||
91 | * ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length | 91 | * ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length |
92 | * (Used for _HPX) | 92 | * (Used for _HPX) |
93 | * | 93 | * |
94 | * ACPI_PTYPE2_REV_FIXED: Revision at start, each subpackage is Fixed-length | ||
95 | * (Used for _ART, _FPS) | ||
96 | * | ||
94 | *****************************************************************************/ | 97 | *****************************************************************************/ |
95 | 98 | ||
96 | enum acpi_return_package_types { | 99 | enum acpi_return_package_types { |
@@ -101,9 +104,11 @@ enum acpi_return_package_types { | |||
101 | ACPI_PTYPE2_COUNT = 5, | 104 | ACPI_PTYPE2_COUNT = 5, |
102 | ACPI_PTYPE2_PKG_COUNT = 6, | 105 | ACPI_PTYPE2_PKG_COUNT = 6, |
103 | ACPI_PTYPE2_FIXED = 7, | 106 | ACPI_PTYPE2_FIXED = 7, |
104 | ACPI_PTYPE2_MIN = 8 | 107 | ACPI_PTYPE2_MIN = 8, |
108 | ACPI_PTYPE2_REV_FIXED = 9 | ||
105 | }; | 109 | }; |
106 | 110 | ||
111 | #ifdef ACPI_CREATE_PREDEFINED_TABLE | ||
107 | /* | 112 | /* |
108 | * Predefined method/object information table. | 113 | * Predefined method/object information table. |
109 | * | 114 | * |
@@ -136,239 +141,384 @@ enum acpi_return_package_types { | |||
136 | * is saved here (rather than in a separate table) in order to minimize the | 141 | * is saved here (rather than in a separate table) in order to minimize the |
137 | * overall size of the stored data. | 142 | * overall size of the stored data. |
138 | */ | 143 | */ |
139 | static const union acpi_predefined_info predefined_names[] = { | 144 | static const union acpi_predefined_info predefined_names[] = |
140 | {.info = {"_AC0", 0, ACPI_RTYPE_INTEGER}}, | 145 | { |
141 | {.info = {"_AC1", 0, ACPI_RTYPE_INTEGER}}, | 146 | {{"_AC0", 0, ACPI_RTYPE_INTEGER}}, |
142 | {.info = {"_AC2", 0, ACPI_RTYPE_INTEGER}}, | 147 | {{"_AC1", 0, ACPI_RTYPE_INTEGER}}, |
143 | {.info = {"_AC3", 0, ACPI_RTYPE_INTEGER}}, | 148 | {{"_AC2", 0, ACPI_RTYPE_INTEGER}}, |
144 | {.info = {"_AC4", 0, ACPI_RTYPE_INTEGER}}, | 149 | {{"_AC3", 0, ACPI_RTYPE_INTEGER}}, |
145 | {.info = {"_AC5", 0, ACPI_RTYPE_INTEGER}}, | 150 | {{"_AC4", 0, ACPI_RTYPE_INTEGER}}, |
146 | {.info = {"_AC6", 0, ACPI_RTYPE_INTEGER}}, | 151 | {{"_AC5", 0, ACPI_RTYPE_INTEGER}}, |
147 | {.info = {"_AC7", 0, ACPI_RTYPE_INTEGER}}, | 152 | {{"_AC6", 0, ACPI_RTYPE_INTEGER}}, |
148 | {.info = {"_AC8", 0, ACPI_RTYPE_INTEGER}}, | 153 | {{"_AC7", 0, ACPI_RTYPE_INTEGER}}, |
149 | {.info = {"_AC9", 0, ACPI_RTYPE_INTEGER}}, | 154 | {{"_AC8", 0, ACPI_RTYPE_INTEGER}}, |
150 | {.info = {"_ADR", 0, ACPI_RTYPE_INTEGER}}, | 155 | {{"_AC9", 0, ACPI_RTYPE_INTEGER}}, |
151 | {.info = {"_AL0", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 156 | {{"_ADR", 0, ACPI_RTYPE_INTEGER}}, |
152 | {.info = {"_AL1", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 157 | {{"_AL0", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
153 | {.info = {"_AL2", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 158 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
154 | {.info = {"_AL3", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 159 | |
155 | {.info = {"_AL4", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 160 | {{"_AL1", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
156 | {.info = {"_AL5", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 161 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
157 | {.info = {"_AL6", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 162 | |
158 | {.info = {"_AL7", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 163 | {{"_AL2", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
159 | {.info = {"_AL8", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 164 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
160 | {.info = {"_AL9", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 165 | |
161 | {.info = {"_ALC", 0, ACPI_RTYPE_INTEGER}}, | 166 | {{"_AL3", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
162 | {.info = {"_ALI", 0, ACPI_RTYPE_INTEGER}}, | 167 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
163 | {.info = {"_ALP", 0, ACPI_RTYPE_INTEGER}}, | 168 | |
164 | {.info = {"_ALR", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 2, 0, 0, 0}}, /* variable (Pkgs) each 2 (Ints) */ | 169 | {{"_AL4", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
165 | {.info = {"_ALT", 0, ACPI_RTYPE_INTEGER}}, | 170 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
166 | {.info = {"_BBN", 0, ACPI_RTYPE_INTEGER}}, | 171 | |
167 | {.info = {"_BCL", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}}, /* variable (Ints) */ | 172 | {{"_AL5", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
168 | {.info = {"_BCM", 1, 0}}, | 173 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
169 | {.info = {"_BDN", 0, ACPI_RTYPE_INTEGER}}, | 174 | |
170 | {.info = {"_BFS", 1, 0}}, | 175 | {{"_AL6", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
171 | {.info = {"_BIF", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, | 176 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
172 | 9, | 177 | |
173 | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER, 4, 0}}, /* fixed (9 Int),(4 Str) */ | 178 | {{"_AL7", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
174 | {.info = {"_BLT", 3, 0}}, | 179 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
175 | {.info = {"_BMC", 1, 0}}, | 180 | |
176 | {.info = {"_BMD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 5, 0, 0, 0}}, /* fixed (5 Int) */ | 181 | {{"_AL8", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
177 | {.info = {"_BQC", 0, ACPI_RTYPE_INTEGER}}, | 182 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
178 | {.info = {"_BST", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4, 0, 0, 0}}, /* fixed (4 Int) */ | 183 | |
179 | {.info = {"_BTM", 1, ACPI_RTYPE_INTEGER}}, | 184 | {{"_AL9", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
180 | {.info = {"_BTP", 1, 0}}, | 185 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
181 | {.info = {"_CBA", 0, ACPI_RTYPE_INTEGER}}, /* see PCI firmware spec 3.0 */ | 186 | |
182 | {.info = {"_CID", 0, | 187 | {{"_ALC", 0, ACPI_RTYPE_INTEGER}}, |
183 | ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_PACKAGE}}, | 188 | {{"_ALI", 0, ACPI_RTYPE_INTEGER}}, |
184 | {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING, 0, 0, 0, 0}}, /* variable (Ints/Strs) */ | 189 | {{"_ALP", 0, ACPI_RTYPE_INTEGER}}, |
185 | {.info = {"_CRS", 0, ACPI_RTYPE_BUFFER}}, | 190 | {{"_ALR", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each 2 (Ints) */ |
186 | {.info = {"_CRT", 0, ACPI_RTYPE_INTEGER}}, | 191 | {{{ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 2,0}, 0,0}}, |
187 | {.info = {"_CSD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}}, /* variable (1 Int(n), n-1 Int) */ | 192 | |
188 | {.info = {"_CST", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_PKG_COUNT, | 193 | {{"_ALT", 0, ACPI_RTYPE_INTEGER}}, |
189 | ACPI_RTYPE_BUFFER, 1, | 194 | {{"_ART", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (1 Int(rev), n Pkg (2 Ref/11 Int) */ |
190 | ACPI_RTYPE_INTEGER, 3, 0}}, /* variable (1 Int(n), n Pkg (1 Buf/3 Int) */ | 195 | {{{ACPI_PTYPE2_REV_FIXED, ACPI_RTYPE_REFERENCE, 2, ACPI_RTYPE_INTEGER}, |
191 | {.info = {"_DCK", 1, ACPI_RTYPE_INTEGER}}, | 196 | 11, 0}}, |
192 | {.info = {"_DCS", 0, ACPI_RTYPE_INTEGER}}, | 197 | |
193 | {.info = {"_DDC", 1, ACPI_RTYPE_INTEGER | ACPI_RTYPE_BUFFER}}, | 198 | {{"_BBN", 0, ACPI_RTYPE_INTEGER}}, |
194 | {.info = {"_DDN", 0, ACPI_RTYPE_STRING}}, | 199 | {{"_BCL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints) */ |
195 | {.info = {"_DGS", 0, ACPI_RTYPE_INTEGER}}, | 200 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0,0}, 0,0}}, |
196 | {.info = {"_DIS", 0, 0}}, | 201 | |
197 | {.info = {"_DMA", 0, ACPI_RTYPE_BUFFER}}, | 202 | {{"_BCM", 1, 0}}, |
198 | {.info = {"_DOD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}}, /* variable (Ints) */ | 203 | {{"_BCT", 1, ACPI_RTYPE_INTEGER}}, |
199 | {.info = {"_DOS", 1, 0}}, | 204 | {{"_BDN", 0, ACPI_RTYPE_INTEGER}}, |
200 | {.info = {"_DSM", 4, ACPI_RTYPE_ALL}}, /* Must return a type, but it can be of any type */ | 205 | {{"_BFS", 1, 0}}, |
201 | {.info = {"_DSS", 1, 0}}, | 206 | {{"_BIF", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (9 Int),(4 Str) */ |
202 | {.info = {"_DSW", 3, 0}}, | 207 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 9, ACPI_RTYPE_STRING}, 4,0}}, |
203 | {.info = {"_EC_", 0, ACPI_RTYPE_INTEGER}}, | 208 | |
204 | {.info = {"_EDL", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 209 | {{"_BIX", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (16 Int),(4 Str) */ |
205 | {.info = {"_EJ0", 1, 0}}, | 210 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16, ACPI_RTYPE_STRING}, 4, |
206 | {.info = {"_EJ1", 1, 0}}, | 211 | 0}}, |
207 | {.info = {"_EJ2", 1, 0}}, | 212 | |
208 | {.info = {"_EJ3", 1, 0}}, | 213 | {{"_BLT", 3, 0}}, |
209 | {.info = {"_EJ4", 1, 0}}, | 214 | {{"_BMA", 1, ACPI_RTYPE_INTEGER}}, |
210 | {.info = {"_EJD", 0, ACPI_RTYPE_STRING}}, | 215 | {{"_BMC", 1, 0}}, |
211 | {.info = {"_FDE", 0, ACPI_RTYPE_BUFFER}}, | 216 | {{"_BMD", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (5 Int) */ |
212 | {.info = {"_FDI", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16, 0, 0, 0}}, /* fixed (16 Int) */ | 217 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 5,0}, 0,0}}, |
213 | {.info = {"_FDM", 1, 0}}, | 218 | |
214 | {.info = {"_FIX", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}}, /* variable (Ints) */ | 219 | {{"_BMS", 1, ACPI_RTYPE_INTEGER}}, |
215 | {.info = {"_GLK", 0, ACPI_RTYPE_INTEGER}}, | 220 | {{"_BQC", 0, ACPI_RTYPE_INTEGER}}, |
216 | {.info = {"_GPD", 0, ACPI_RTYPE_INTEGER}}, | 221 | {{"_BST", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (4 Int) */ |
217 | {.info = {"_GPE", 0, ACPI_RTYPE_INTEGER}}, /* _GPE method, not _GPE scope */ | 222 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4,0}, 0,0}}, |
218 | {.info = {"_GSB", 0, ACPI_RTYPE_INTEGER}}, | 223 | |
219 | {.info = {"_GTF", 0, ACPI_RTYPE_BUFFER}}, | 224 | {{"_BTM", 1, ACPI_RTYPE_INTEGER}}, |
220 | {.info = {"_GTM", 0, ACPI_RTYPE_BUFFER}}, | 225 | {{"_BTP", 1, 0}}, |
221 | {.info = {"_GTS", 1, 0}}, | 226 | {{"_CBA", 0, ACPI_RTYPE_INTEGER}}, /* See PCI firmware spec 3.0 */ |
222 | {.info = {"_HID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING}}, | 227 | {{"_CDM", 0, ACPI_RTYPE_INTEGER}}, |
223 | {.info = {"_HOT", 0, ACPI_RTYPE_INTEGER}}, | 228 | {{"_CID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints/Strs) */ |
224 | {.info = {"_HPP", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4, 0, 0, 0}}, /* fixed (4 Int) */ | 229 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING, 0,0}, 0,0}}, |
230 | |||
231 | {{"_CRS", 0, ACPI_RTYPE_BUFFER}}, | ||
232 | {{"_CRT", 0, ACPI_RTYPE_INTEGER}}, | ||
233 | {{"_CSD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (1 Int(n), n-1 Int) */ | ||
234 | {{{ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER, 0,0}, 0,0}}, | ||
235 | |||
236 | {{"_CST", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (1 Int(n), n Pkg (1 Buf/3 Int) */ | ||
237 | {{{ACPI_PTYPE2_PKG_COUNT,ACPI_RTYPE_BUFFER, 1, ACPI_RTYPE_INTEGER}, 3,0}}, | ||
238 | |||
239 | {{"_DCK", 1, ACPI_RTYPE_INTEGER}}, | ||
240 | {{"_DCS", 0, ACPI_RTYPE_INTEGER}}, | ||
241 | {{"_DDC", 1, ACPI_RTYPE_INTEGER | ACPI_RTYPE_BUFFER}}, | ||
242 | {{"_DDN", 0, ACPI_RTYPE_STRING}}, | ||
243 | {{"_DGS", 0, ACPI_RTYPE_INTEGER}}, | ||
244 | {{"_DIS", 0, 0}}, | ||
245 | {{"_DMA", 0, ACPI_RTYPE_BUFFER}}, | ||
246 | {{"_DOD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints) */ | ||
247 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0,0}, 0,0}}, | ||
248 | |||
249 | {{"_DOS", 1, 0}}, | ||
250 | {{"_DSM", 4, ACPI_RTYPE_ALL}}, /* Must return a type, but it can be of any type */ | ||
251 | {{"_DSS", 1, 0}}, | ||
252 | {{"_DSW", 3, 0}}, | ||
253 | {{"_DTI", 1, 0}}, | ||
254 | {{"_EC_", 0, ACPI_RTYPE_INTEGER}}, | ||
255 | {{"_EDL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs)*/ | ||
256 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, | ||
257 | |||
258 | {{"_EJ0", 1, 0}}, | ||
259 | {{"_EJ1", 1, 0}}, | ||
260 | {{"_EJ2", 1, 0}}, | ||
261 | {{"_EJ3", 1, 0}}, | ||
262 | {{"_EJ4", 1, 0}}, | ||
263 | {{"_EJD", 0, ACPI_RTYPE_STRING}}, | ||
264 | {{"_FDE", 0, ACPI_RTYPE_BUFFER}}, | ||
265 | {{"_FDI", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (16 Int) */ | ||
266 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16,0}, 0,0}}, | ||
267 | |||
268 | {{"_FDM", 1, 0}}, | ||
269 | {{"_FIF", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (4 Int) */ | ||
270 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4, 0}, 0, 0}}, | ||
271 | |||
272 | {{"_FIX", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints) */ | ||
273 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0,0}, 0,0}}, | ||
274 | |||
275 | {{"_FPS", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (1 Int(rev), n Pkg (5 Int) */ | ||
276 | {{{ACPI_PTYPE2_REV_FIXED, ACPI_RTYPE_INTEGER, 5, 0}, 0, 0}}, | ||
277 | |||
278 | {{"_FSL", 1, 0}}, | ||
279 | {{"_FST", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (3 Int) */ | ||
280 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 3, 0}, 0, 0}}, | ||
281 | |||
282 | {{"_GAI", 0, ACPI_RTYPE_INTEGER}}, | ||
283 | {{"_GHL", 0, ACPI_RTYPE_INTEGER}}, | ||
284 | {{"_GLK", 0, ACPI_RTYPE_INTEGER}}, | ||
285 | {{"_GPD", 0, ACPI_RTYPE_INTEGER}}, | ||
286 | {{"_GPE", 0, ACPI_RTYPE_INTEGER}}, /* _GPE method, not _GPE scope */ | ||
287 | {{"_GSB", 0, ACPI_RTYPE_INTEGER}}, | ||
288 | {{"_GTF", 0, ACPI_RTYPE_BUFFER}}, | ||
289 | {{"_GTM", 0, ACPI_RTYPE_BUFFER}}, | ||
290 | {{"_GTS", 1, 0}}, | ||
291 | {{"_HID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING}}, | ||
292 | {{"_HOT", 0, ACPI_RTYPE_INTEGER}}, | ||
293 | {{"_HPP", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (4 Int) */ | ||
294 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4,0}, 0,0}}, | ||
225 | 295 | ||
226 | /* | 296 | /* |
227 | * For _HPX, a single package is returned, containing a variable number of sub-packages. | 297 | * For _HPX, a single package is returned, containing a Variable-length number |
228 | * Each sub-package contains a PCI record setting. There are several different type of | 298 | * of sub-packages. Each sub-package contains a PCI record setting. |
229 | * record settings, of different lengths, but all elements of all settings are Integers. | 299 | * There are several different type of record settings, of different |
300 | * lengths, but all elements of all settings are Integers. | ||
230 | */ | 301 | */ |
231 | {.info = {"_HPX", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_MIN, ACPI_RTYPE_INTEGER, 5, 0, 0, 0}}, /* variable (Pkgs) each (var Ints) */ | 302 | {{"_HPX", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (var Ints) */ |
232 | {.info = {"_IFT", 0, ACPI_RTYPE_INTEGER}}, /* see IPMI spec */ | 303 | {{{ACPI_PTYPE2_MIN, ACPI_RTYPE_INTEGER, 5,0}, 0,0}}, |
233 | {.info = {"_INI", 0, 0}}, | 304 | |
234 | {.info = {"_IRC", 0, 0}}, | 305 | {{"_IFT", 0, ACPI_RTYPE_INTEGER}}, /* See IPMI spec */ |
235 | {.info = {"_LCK", 1, 0}}, | 306 | {{"_INI", 0, 0}}, |
236 | {.info = {"_LID", 0, ACPI_RTYPE_INTEGER}}, | 307 | {{"_IRC", 0, 0}}, |
237 | {.info = {"_MAT", 0, ACPI_RTYPE_BUFFER}}, | 308 | {{"_LCK", 1, 0}}, |
238 | {.info = {"_MLS", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_STRING, 2, 0, 0, 0}}, /* variable (Pkgs) each (2 Str) */ | 309 | {{"_LID", 0, ACPI_RTYPE_INTEGER}}, |
239 | {.info = {"_MSG", 1, 0}}, | 310 | {{"_MAT", 0, ACPI_RTYPE_BUFFER}}, |
240 | {.info = {"_OFF", 0, 0}}, | 311 | {{"_MBM", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (8 Int) */ |
241 | {.info = {"_ON_", 0, 0}}, | 312 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 8, 0}, 0, 0}}, |
242 | {.info = {"_OS_", 0, ACPI_RTYPE_STRING}}, | 313 | |
243 | {.info = {"_OSC", 4, ACPI_RTYPE_BUFFER}}, | 314 | {{"_MLS", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (2 Str) */ |
244 | {.info = {"_OST", 3, 0}}, | 315 | {{{ACPI_PTYPE2, ACPI_RTYPE_STRING, 2,0}, 0,0}}, |
245 | {.info = {"_PCL", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 316 | |
246 | {.info = {"_PCT", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2, 0, 0, 0}}, /* fixed (2 Buf) */ | 317 | {{"_MSG", 1, 0}}, |
247 | {.info = {"_PDC", 1, 0}}, | 318 | {{"_MSM", 4, ACPI_RTYPE_INTEGER}}, |
248 | {.info = {"_PIC", 1, 0}}, | 319 | {{"_NTT", 0, ACPI_RTYPE_INTEGER}}, |
249 | {.info = {"_PLD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_BUFFER, 0, 0, 0, 0}}, /* variable (Bufs) */ | 320 | {{"_OFF", 0, 0}}, |
250 | {.info = {"_PPC", 0, ACPI_RTYPE_INTEGER}}, | 321 | {{"_ON_", 0, 0}}, |
251 | {.info = {"_PPE", 0, ACPI_RTYPE_INTEGER}}, /* see dig64 spec */ | 322 | {{"_OS_", 0, ACPI_RTYPE_STRING}}, |
252 | {.info = {"_PR0", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 323 | {{"_OSC", 4, ACPI_RTYPE_BUFFER}}, |
253 | {.info = {"_PR1", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 324 | {{"_OST", 3, 0}}, |
254 | {.info = {"_PR2", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 325 | {{"_PAI", 1, ACPI_RTYPE_INTEGER}}, |
255 | {.info = {"_PRS", 0, ACPI_RTYPE_BUFFER}}, | 326 | {{"_PCL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
327 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, | ||
328 | |||
329 | {{"_PCT", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (2 Buf) */ | ||
330 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2,0}, 0,0}}, | ||
331 | |||
332 | {{"_PDC", 1, 0}}, | ||
333 | {{"_PDL", 0, ACPI_RTYPE_INTEGER}}, | ||
334 | {{"_PIC", 1, 0}}, | ||
335 | {{"_PIF", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (3 Int),(3 Str) */ | ||
336 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 3, ACPI_RTYPE_STRING}, 3, 0}}, | ||
337 | |||
338 | {{"_PLD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Bufs) */ | ||
339 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_BUFFER, 0,0}, 0,0}}, | ||
340 | |||
341 | {{"_PMC", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (11 Int),(3 Str) */ | ||
342 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 11, ACPI_RTYPE_STRING}, 3, | ||
343 | 0}}, | ||
344 | |||
345 | {{"_PMD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ | ||
346 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0}, 0, 0}}, | ||
347 | |||
348 | {{"_PMM", 0, ACPI_RTYPE_INTEGER}}, | ||
349 | {{"_PPC", 0, ACPI_RTYPE_INTEGER}}, | ||
350 | {{"_PPE", 0, ACPI_RTYPE_INTEGER}}, /* See dig64 spec */ | ||
351 | {{"_PR0", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ | ||
352 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, | ||
353 | |||
354 | {{"_PR1", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ | ||
355 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, | ||
356 | |||
357 | {{"_PR2", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ | ||
358 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, | ||
359 | |||
360 | {{"_PR3", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ | ||
361 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0}, 0, 0}}, | ||
362 | |||
363 | {{"_PRL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ | ||
364 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0}, 0, 0}}, | ||
365 | |||
366 | {{"_PRS", 0, ACPI_RTYPE_BUFFER}}, | ||
256 | 367 | ||
257 | /* | 368 | /* |
258 | * For _PRT, many BIOSs reverse the 2nd and 3rd Package elements. This bug is so prevalent that there | 369 | * For _PRT, many BIOSs reverse the 3rd and 4th Package elements (Source |
259 | * is code in the ACPICA Resource Manager to detect this and switch them back. For now, do not allow | 370 | * and source_index). This bug is so prevalent that there is code in the |
260 | * and issue a warning. To allow this and eliminate the warning, add the ACPI_RTYPE_REFERENCE | 371 | * ACPICA Resource Manager to detect this and switch them back. For now, |
261 | * type to the 2nd element (index 1) in the statement below. | 372 | * do not allow and issue a warning. To allow this and eliminate the |
373 | * warning, add the ACPI_RTYPE_REFERENCE type to the 4th element (index 3) | ||
374 | * in the statement below. | ||
262 | */ | 375 | */ |
263 | {.info = {"_PRT", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_FIXED, 4, | 376 | {{"_PRT", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (4): Int,Int,Int/Ref,Int */ |
264 | ACPI_RTYPE_INTEGER, | 377 | {{{ACPI_PTYPE2_FIXED, 4, ACPI_RTYPE_INTEGER,ACPI_RTYPE_INTEGER}, |
265 | ACPI_RTYPE_INTEGER, | 378 | ACPI_RTYPE_INTEGER | ACPI_RTYPE_REFERENCE, |
266 | ACPI_RTYPE_INTEGER | ACPI_RTYPE_REFERENCE, ACPI_RTYPE_INTEGER}}, /* variable (Pkgs) each (4): Int,Int,Int/Ref,Int */ | 379 | ACPI_RTYPE_INTEGER}}, |
267 | 380 | ||
268 | {.info = {"_PRW", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_OPTION, 2, | 381 | {{"_PRW", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each: Pkg/Int,Int,[Variable-length Refs] (Pkg is Ref/Int) */ |
269 | ACPI_RTYPE_INTEGER | | 382 | {{{ACPI_PTYPE1_OPTION, 2, ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE, |
270 | ACPI_RTYPE_PACKAGE, | 383 | ACPI_RTYPE_INTEGER}, ACPI_RTYPE_REFERENCE,0}}, |
271 | ACPI_RTYPE_INTEGER, ACPI_RTYPE_REFERENCE, 0}}, /* variable (Pkgs) each: Pkg/Int,Int,[variable Refs] (Pkg is Ref/Int) */ | 384 | |
272 | 385 | {{"_PS0", 0, 0}}, | |
273 | {.info = {"_PS0", 0, 0}}, | 386 | {{"_PS1", 0, 0}}, |
274 | {.info = {"_PS1", 0, 0}}, | 387 | {{"_PS2", 0, 0}}, |
275 | {.info = {"_PS2", 0, 0}}, | 388 | {{"_PS3", 0, 0}}, |
276 | {.info = {"_PS3", 0, 0}}, | 389 | {{"_PSC", 0, ACPI_RTYPE_INTEGER}}, |
277 | {.info = {"_PSC", 0, ACPI_RTYPE_INTEGER}}, | 390 | {{"_PSD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (5 Int) with count */ |
278 | {.info = {"_PSD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}}, /* variable (Pkgs) each (5 Int) with count */ | 391 | {{{ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER,0,0}, 0,0}}, |
279 | {.info = {"_PSL", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 392 | |
280 | {.info = {"_PSR", 0, ACPI_RTYPE_INTEGER}}, | 393 | {{"_PSL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
281 | {.info = {"_PSS", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 6, 0, 0, 0}}, /* variable (Pkgs) each (6 Int) */ | 394 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
282 | {.info = {"_PSV", 0, ACPI_RTYPE_INTEGER}}, | 395 | |
283 | {.info = {"_PSW", 1, 0}}, | 396 | {{"_PSR", 0, ACPI_RTYPE_INTEGER}}, |
284 | {.info = {"_PTC", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2, 0, 0, 0}}, /* fixed (2 Buf) */ | 397 | {{"_PSS", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (6 Int) */ |
285 | {.info = {"_PTS", 1, 0}}, | 398 | {{{ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 6,0}, 0,0}}, |
286 | {.info = {"_PXM", 0, ACPI_RTYPE_INTEGER}}, | 399 | |
287 | {.info = {"_REG", 2, 0}}, | 400 | {{"_PSV", 0, ACPI_RTYPE_INTEGER}}, |
288 | {.info = {"_REV", 0, ACPI_RTYPE_INTEGER}}, | 401 | {{"_PSW", 1, 0}}, |
289 | {.info = {"_RMV", 0, ACPI_RTYPE_INTEGER}}, | 402 | {{"_PTC", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (2 Buf) */ |
290 | {.info = {"_ROM", 2, ACPI_RTYPE_BUFFER}}, | 403 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2,0}, 0,0}}, |
291 | {.info = {"_RTV", 0, ACPI_RTYPE_INTEGER}}, | 404 | |
405 | {{"_PTP", 2, ACPI_RTYPE_INTEGER}}, | ||
406 | {{"_PTS", 1, 0}}, | ||
407 | {{"_PUR", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (2 Int) */ | ||
408 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2, 0}, 0, 0}}, | ||
409 | |||
410 | {{"_PXM", 0, ACPI_RTYPE_INTEGER}}, | ||
411 | {{"_REG", 2, 0}}, | ||
412 | {{"_REV", 0, ACPI_RTYPE_INTEGER}}, | ||
413 | {{"_RMV", 0, ACPI_RTYPE_INTEGER}}, | ||
414 | {{"_ROM", 2, ACPI_RTYPE_BUFFER}}, | ||
415 | {{"_RTV", 0, ACPI_RTYPE_INTEGER}}, | ||
292 | 416 | ||
293 | /* | 417 | /* |
294 | * For _S0_ through _S5_, the ACPI spec defines a return Package containing 1 Integer, | 418 | * For _S0_ through _S5_, the ACPI spec defines a return Package |
295 | * but most DSDTs have it wrong - 2,3, or 4 integers. Allow this by making the objects "variable length", | 419 | * containing 1 Integer, but most DSDTs have it wrong - 2,3, or 4 integers. |
296 | * but all elements must be Integers. | 420 | * Allow this by making the objects "Variable-length length", but all elements |
421 | * must be Integers. | ||
297 | */ | 422 | */ |
298 | {.info = {"_S0_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}}, /* fixed (1 Int) */ | 423 | {{"_S0_", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (1 Int) */ |
299 | {.info = {"_S1_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}}, /* fixed (1 Int) */ | 424 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0}, 0,0}}, |
300 | {.info = {"_S2_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}}, /* fixed (1 Int) */ | 425 | |
301 | {.info = {"_S3_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}}, /* fixed (1 Int) */ | 426 | {{"_S1_", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (1 Int) */ |
302 | {.info = {"_S4_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}}, /* fixed (1 Int) */ | 427 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0}, 0,0}}, |
303 | {.info = {"_S5_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}}, /* fixed (1 Int) */ | 428 | |
304 | 429 | {{"_S2_", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (1 Int) */ | |
305 | {.info = {"_S1D", 0, ACPI_RTYPE_INTEGER}}, | 430 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0}, 0,0}}, |
306 | {.info = {"_S2D", 0, ACPI_RTYPE_INTEGER}}, | 431 | |
307 | {.info = {"_S3D", 0, ACPI_RTYPE_INTEGER}}, | 432 | {{"_S3_", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (1 Int) */ |
308 | {.info = {"_S4D", 0, ACPI_RTYPE_INTEGER}}, | 433 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0}, 0,0}}, |
309 | {.info = {"_S0W", 0, ACPI_RTYPE_INTEGER}}, | 434 | |
310 | {.info = {"_S1W", 0, ACPI_RTYPE_INTEGER}}, | 435 | {{"_S4_", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (1 Int) */ |
311 | {.info = {"_S2W", 0, ACPI_RTYPE_INTEGER}}, | 436 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0}, 0,0}}, |
312 | {.info = {"_S3W", 0, ACPI_RTYPE_INTEGER}}, | 437 | |
313 | {.info = {"_S4W", 0, ACPI_RTYPE_INTEGER}}, | 438 | {{"_S5_", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (1 Int) */ |
314 | {.info = {"_SBS", 0, ACPI_RTYPE_INTEGER}}, | 439 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0}, 0,0}}, |
315 | {.info = {"_SCP", 0x13, 0}}, /* Acpi 1.0 allowed 1 arg. Acpi 3.0 expanded to 3 args. Allow both. */ | 440 | |
316 | /* Note: the 3-arg definition may be removed for ACPI 4.0 */ | 441 | {{"_S1D", 0, ACPI_RTYPE_INTEGER}}, |
317 | {.info = {"_SDD", 1, 0}}, | 442 | {{"_S2D", 0, ACPI_RTYPE_INTEGER}}, |
318 | {.info = {"_SEG", 0, ACPI_RTYPE_INTEGER}}, | 443 | {{"_S3D", 0, ACPI_RTYPE_INTEGER}}, |
319 | {.info = {"_SLI", 0, ACPI_RTYPE_BUFFER}}, | 444 | {{"_S4D", 0, ACPI_RTYPE_INTEGER}}, |
320 | {.info = {"_SPD", 1, ACPI_RTYPE_INTEGER}}, | 445 | {{"_S0W", 0, ACPI_RTYPE_INTEGER}}, |
321 | {.info = {"_SRS", 1, 0}}, | 446 | {{"_S1W", 0, ACPI_RTYPE_INTEGER}}, |
322 | {.info = {"_SRV", 0, ACPI_RTYPE_INTEGER}}, /* see IPMI spec */ | 447 | {{"_S2W", 0, ACPI_RTYPE_INTEGER}}, |
323 | {.info = {"_SST", 1, 0}}, | 448 | {{"_S3W", 0, ACPI_RTYPE_INTEGER}}, |
324 | {.info = {"_STA", 0, ACPI_RTYPE_INTEGER}}, | 449 | {{"_S4W", 0, ACPI_RTYPE_INTEGER}}, |
325 | {.info = {"_STM", 3, 0}}, | 450 | {{"_SBS", 0, ACPI_RTYPE_INTEGER}}, |
326 | {.info = {"_STR", 0, ACPI_RTYPE_BUFFER}}, | 451 | {{"_SCP", 0x13, 0}}, /* Acpi 1.0 allowed 1 arg. Acpi 3.0 expanded to 3 args. Allow both. */ |
327 | {.info = {"_SUN", 0, ACPI_RTYPE_INTEGER}}, | 452 | /* Note: the 3-arg definition may be removed for ACPI 4.0 */ |
328 | {.info = {"_SWS", 0, ACPI_RTYPE_INTEGER}}, | 453 | {{"_SDD", 1, 0}}, |
329 | {.info = {"_TC1", 0, ACPI_RTYPE_INTEGER}}, | 454 | {{"_SEG", 0, ACPI_RTYPE_INTEGER}}, |
330 | {.info = {"_TC2", 0, ACPI_RTYPE_INTEGER}}, | 455 | {{"_SHL", 1, ACPI_RTYPE_INTEGER}}, |
331 | {.info = {"_TMP", 0, ACPI_RTYPE_INTEGER}}, | 456 | {{"_SLI", 0, ACPI_RTYPE_BUFFER}}, |
332 | {.info = {"_TPC", 0, ACPI_RTYPE_INTEGER}}, | 457 | {{"_SPD", 1, ACPI_RTYPE_INTEGER}}, |
333 | {.info = {"_TPT", 1, 0}}, | 458 | {{"_SRS", 1, 0}}, |
334 | {.info = {"_TRT", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_REFERENCE, 2, | 459 | {{"_SRV", 0, ACPI_RTYPE_INTEGER}}, /* See IPMI spec */ |
335 | ACPI_RTYPE_INTEGER, 6, 0}}, /* variable (Pkgs) each 2_ref/6_int */ | 460 | {{"_SST", 1, 0}}, |
336 | {.info = {"_TSD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER, 5, 0, 0, 0}}, /* variable (Pkgs) each 5_int with count */ | 461 | {{"_STA", 0, ACPI_RTYPE_INTEGER}}, |
337 | {.info = {"_TSP", 0, ACPI_RTYPE_INTEGER}}, | 462 | {{"_STM", 3, 0}}, |
338 | {.info = {"_TSS", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 5, 0, 0, 0}}, /* variable (Pkgs) each 5_int */ | 463 | {{"_STP", 2, ACPI_RTYPE_INTEGER}}, |
339 | {.info = {"_TST", 0, ACPI_RTYPE_INTEGER}}, | 464 | {{"_STR", 0, ACPI_RTYPE_BUFFER}}, |
340 | {.info = {"_TTS", 1, 0}}, | 465 | {{"_STV", 2, ACPI_RTYPE_INTEGER}}, |
341 | {.info = {"_TZD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 466 | {{"_SUN", 0, ACPI_RTYPE_INTEGER}}, |
342 | {.info = {"_TZM", 0, ACPI_RTYPE_REFERENCE}}, | 467 | {{"_SWS", 0, ACPI_RTYPE_INTEGER}}, |
343 | {.info = {"_TZP", 0, ACPI_RTYPE_INTEGER}}, | 468 | {{"_TC1", 0, ACPI_RTYPE_INTEGER}}, |
344 | {.info = {"_UID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING}}, | 469 | {{"_TC2", 0, ACPI_RTYPE_INTEGER}}, |
345 | {.info = {"_UPC", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4, 0, 0, 0}}, /* fixed (4 Int) */ | 470 | {{"_TIP", 1, ACPI_RTYPE_INTEGER}}, |
346 | {.info = {"_UPD", 0, ACPI_RTYPE_INTEGER}}, | 471 | {{"_TIV", 1, ACPI_RTYPE_INTEGER}}, |
347 | {.info = {"_UPP", 0, ACPI_RTYPE_INTEGER}}, | 472 | {{"_TMP", 0, ACPI_RTYPE_INTEGER}}, |
348 | {.info = {"_VPO", 0, ACPI_RTYPE_INTEGER}}, | 473 | {{"_TPC", 0, ACPI_RTYPE_INTEGER}}, |
474 | {{"_TPT", 1, 0}}, | ||
475 | {{"_TRT", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each 2_ref/6_int */ | ||
476 | {{{ACPI_PTYPE2, ACPI_RTYPE_REFERENCE, 2, ACPI_RTYPE_INTEGER}, 6, 0}}, | ||
477 | |||
478 | {{"_TSD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each 5_int with count */ | ||
479 | {{{ACPI_PTYPE2_COUNT,ACPI_RTYPE_INTEGER, 5,0}, 0,0}}, | ||
480 | |||
481 | {{"_TSP", 0, ACPI_RTYPE_INTEGER}}, | ||
482 | {{"_TSS", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each 5_int */ | ||
483 | {{{ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 5,0}, 0,0}}, | ||
484 | |||
485 | {{"_TST", 0, ACPI_RTYPE_INTEGER}}, | ||
486 | {{"_TTS", 1, 0}}, | ||
487 | {{"_TZD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ | ||
488 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, | ||
489 | |||
490 | {{"_TZM", 0, ACPI_RTYPE_REFERENCE}}, | ||
491 | {{"_TZP", 0, ACPI_RTYPE_INTEGER}}, | ||
492 | {{"_UID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING}}, | ||
493 | {{"_UPC", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (4 Int) */ | ||
494 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4,0}, 0,0}}, | ||
495 | |||
496 | {{"_UPD", 0, ACPI_RTYPE_INTEGER}}, | ||
497 | {{"_UPP", 0, ACPI_RTYPE_INTEGER}}, | ||
498 | {{"_VPO", 0, ACPI_RTYPE_INTEGER}}, | ||
349 | 499 | ||
350 | /* Acpi 1.0 defined _WAK with no return value. Later, it was changed to return a package */ | 500 | /* Acpi 1.0 defined _WAK with no return value. Later, it was changed to return a package */ |
351 | 501 | ||
352 | {.info = {"_WAK", 1, ACPI_RTYPE_NONE | ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE}}, | 502 | {{"_WAK", 1, ACPI_RTYPE_NONE | ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE}}, |
353 | {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2, 0, 0, 0}}, /* fixed (2 Int), but is optional */ | 503 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2,0}, 0,0}}, /* Fixed-length (2 Int), but is optional */ |
354 | {.ret_info = {0, 0, 0, 0, 0, 0}} /* Table terminator */ | 504 | |
505 | {{{0,0,0,0}, 0,0}} /* Table terminator */ | ||
355 | }; | 506 | }; |
356 | 507 | ||
357 | #if 0 | 508 | #if 0 |
358 | /* Not implemented */ | 509 | /* Not implemented */ |
359 | 510 | ||
360 | { | 511 | {{"_WDG", 0, ACPI_RTYPE_BUFFER}}, /* MS Extension */ |
361 | "_WDG", 0, ACPI_RTYPE_BUFFER}, /* MS Extension */ | 512 | {{"_WED", 1, ACPI_RTYPE_PACKAGE}}, /* MS Extension */ |
362 | 513 | ||
363 | { | 514 | /* This is an internally implemented control method, no need to check */ |
364 | "_WED", 1, ACPI_RTYPE_PACKAGE}, /* MS Extension */ | 515 | {{"_OSI", 1, ACPI_RTYPE_INTEGER}}, |
365 | 516 | ||
366 | /* This is an internally implemented control method, no need to check */ | 517 | /* TBD: */ |
367 | { | 518 | |
368 | "_OSI", 1, ACPI_RTYPE_INTEGER}, | 519 | _PRT - currently ignore reversed entries. attempt to fix here? |
520 | think about possibly fixing package elements like _BIF, etc. | ||
521 | #endif | ||
369 | 522 | ||
370 | /* TBD: */ | ||
371 | _PRT - currently ignore reversed entries.attempt to fix here ? | ||
372 | think about code that attempts to fix package elements like _BIF, etc. | ||
373 | #endif | 523 | #endif |
374 | #endif | 524 | #endif |
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 897810ba0ccc..863a264b829e 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h | |||
@@ -324,26 +324,30 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
324 | acpi_status | 324 | acpi_status |
325 | acpi_ut_evaluate_numeric_object(char *object_name, | 325 | acpi_ut_evaluate_numeric_object(char *object_name, |
326 | struct acpi_namespace_node *device_node, | 326 | struct acpi_namespace_node *device_node, |
327 | acpi_integer * address); | 327 | acpi_integer *value); |
328 | 328 | ||
329 | acpi_status | 329 | acpi_status |
330 | acpi_ut_execute_HID(struct acpi_namespace_node *device_node, | 330 | acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 *status_flags); |
331 | struct acpica_device_id *hid); | ||
332 | 331 | ||
333 | acpi_status | 332 | acpi_status |
334 | acpi_ut_execute_CID(struct acpi_namespace_node *device_node, | 333 | acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node, |
335 | struct acpi_compatible_id_list **return_cid_list); | 334 | const char **method_names, |
335 | u8 method_count, u8 *out_values); | ||
336 | 336 | ||
337 | /* | ||
338 | * utids - device ID support | ||
339 | */ | ||
337 | acpi_status | 340 | acpi_status |
338 | acpi_ut_execute_STA(struct acpi_namespace_node *device_node, | 341 | acpi_ut_execute_HID(struct acpi_namespace_node *device_node, |
339 | u32 * status_flags); | 342 | struct acpica_device_id **return_id); |
340 | 343 | ||
341 | acpi_status | 344 | acpi_status |
342 | acpi_ut_execute_UID(struct acpi_namespace_node *device_node, | 345 | acpi_ut_execute_UID(struct acpi_namespace_node *device_node, |
343 | struct acpica_device_id *uid); | 346 | struct acpica_device_id **return_id); |
344 | 347 | ||
345 | acpi_status | 348 | acpi_status |
346 | acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest); | 349 | acpi_ut_execute_CID(struct acpi_namespace_node *device_node, |
350 | struct acpica_device_id_list **return_cid_list); | ||
347 | 351 | ||
348 | /* | 352 | /* |
349 | * utlock - reader/writer locks | 353 | * utlock - reader/writer locks |
@@ -445,6 +449,8 @@ acpi_ut_short_divide(acpi_integer in_dividend, | |||
445 | */ | 449 | */ |
446 | const char *acpi_ut_validate_exception(acpi_status status); | 450 | const char *acpi_ut_validate_exception(acpi_status status); |
447 | 451 | ||
452 | u8 acpi_ut_is_pci_root_bridge(char *id); | ||
453 | |||
448 | u8 acpi_ut_is_aml_table(struct acpi_table_header *table); | 454 | u8 acpi_ut_is_aml_table(struct acpi_table_header *table); |
449 | 455 | ||
450 | acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id); | 456 | acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id); |
@@ -469,6 +475,12 @@ u8 acpi_ut_valid_acpi_char(char character, u32 position); | |||
469 | acpi_status | 475 | acpi_status |
470 | acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer); | 476 | acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer); |
471 | 477 | ||
478 | void ACPI_INTERNAL_VAR_XFACE | ||
479 | acpi_ut_predefined_warning(const char *module_name, | ||
480 | u32 line_number, | ||
481 | char *pathname, | ||
482 | u8 node_flags, const char *format, ...); | ||
483 | |||
472 | /* Values for Base above (16=Hex, 10=Decimal) */ | 484 | /* Values for Base above (16=Hex, 10=Decimal) */ |
473 | 485 | ||
474 | #define ACPI_ANY_BASE 0 | 486 | #define ACPI_ANY_BASE 0 |
diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h index 067f967eb389..4940249f2524 100644 --- a/drivers/acpi/acpica/amlcode.h +++ b/drivers/acpi/acpica/amlcode.h | |||
@@ -404,6 +404,7 @@ typedef enum { | |||
404 | REGION_SMBUS, | 404 | REGION_SMBUS, |
405 | REGION_CMOS, | 405 | REGION_CMOS, |
406 | REGION_PCI_BAR, | 406 | REGION_PCI_BAR, |
407 | REGION_IPMI, | ||
407 | REGION_DATA_TABLE, /* Internal use only */ | 408 | REGION_DATA_TABLE, /* Internal use only */ |
408 | REGION_FIXED_HW = 0x7F | 409 | REGION_FIXED_HW = 0x7F |
409 | } AML_REGION_TYPES; | 410 | } AML_REGION_TYPES; |
diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c index 53e27bc5a734..54a225e56a64 100644 --- a/drivers/acpi/acpica/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c | |||
@@ -123,9 +123,12 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, | |||
123 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | | 123 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | |
124 | ACPI_NS_ERROR_IF_FOUND; | 124 | ACPI_NS_ERROR_IF_FOUND; |
125 | 125 | ||
126 | /* Mark node temporary if we are executing a method */ | 126 | /* |
127 | 127 | * Mark node temporary if we are executing a normal control | |
128 | if (walk_state->method_node) { | 128 | * method. (Don't mark if this is a module-level code method) |
129 | */ | ||
130 | if (walk_state->method_node && | ||
131 | !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) { | ||
129 | flags |= ACPI_NS_TEMPORARY; | 132 | flags |= ACPI_NS_TEMPORARY; |
130 | } | 133 | } |
131 | 134 | ||
@@ -456,9 +459,12 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
456 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | | 459 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | |
457 | ACPI_NS_ERROR_IF_FOUND; | 460 | ACPI_NS_ERROR_IF_FOUND; |
458 | 461 | ||
459 | /* Mark node(s) temporary if we are executing a method */ | 462 | /* |
460 | 463 | * Mark node(s) temporary if we are executing a normal control | |
461 | if (walk_state->method_node) { | 464 | * method. (Don't mark if this is a module-level code method) |
465 | */ | ||
466 | if (walk_state->method_node && | ||
467 | !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) { | ||
462 | flags |= ACPI_NS_TEMPORARY; | 468 | flags |= ACPI_NS_TEMPORARY; |
463 | } | 469 | } |
464 | 470 | ||
diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index 14b8b8ed8023..567a4899a018 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c | |||
@@ -578,10 +578,15 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | |||
578 | } | 578 | } |
579 | 579 | ||
580 | /* | 580 | /* |
581 | * Delete any namespace objects created anywhere within | 581 | * Delete any namespace objects created anywhere within the |
582 | * the namespace by the execution of this method | 582 | * namespace by the execution of this method. Unless this method |
583 | * is a module-level executable code method, in which case we | ||
584 | * want make the objects permanent. | ||
583 | */ | 585 | */ |
584 | acpi_ns_delete_namespace_by_owner(method_desc->method.owner_id); | 586 | if (!(method_desc->method.flags & AOPOBJ_MODULE_LEVEL)) { |
587 | acpi_ns_delete_namespace_by_owner(method_desc->method. | ||
588 | owner_id); | ||
589 | } | ||
585 | } | 590 | } |
586 | 591 | ||
587 | /* Decrement the thread count on the method */ | 592 | /* Decrement the thread count on the method */ |
@@ -622,7 +627,9 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | |||
622 | 627 | ||
623 | /* No more threads, we can free the owner_id */ | 628 | /* No more threads, we can free the owner_id */ |
624 | 629 | ||
625 | acpi_ut_release_owner_id(&method_desc->method.owner_id); | 630 | if (!(method_desc->method.flags & AOPOBJ_MODULE_LEVEL)) { |
631 | acpi_ut_release_owner_id(&method_desc->method.owner_id); | ||
632 | } | ||
626 | } | 633 | } |
627 | 634 | ||
628 | return_VOID; | 635 | return_VOID; |
diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c index 22b1a3ce2c94..7d077bb2f525 100644 --- a/drivers/acpi/acpica/dsmthdat.c +++ b/drivers/acpi/acpica/dsmthdat.c | |||
@@ -433,10 +433,10 @@ acpi_ds_method_data_get_value(u8 type, | |||
433 | 433 | ||
434 | case ACPI_REFCLASS_LOCAL: | 434 | case ACPI_REFCLASS_LOCAL: |
435 | 435 | ||
436 | ACPI_ERROR((AE_INFO, | 436 | /* |
437 | "Uninitialized Local[%d] at node %p", | 437 | * No error message for this case, will be trapped again later to |
438 | index, node)); | 438 | * detect and ignore cases of Store(local_x,local_x) |
439 | 439 | */ | |
440 | return_ACPI_STATUS(AE_AML_UNINITIALIZED_LOCAL); | 440 | return_ACPI_STATUS(AE_AML_UNINITIALIZED_LOCAL); |
441 | 441 | ||
442 | default: | 442 | default: |
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index 02e6caad4a76..507e1f0bbdfd 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c | |||
@@ -482,14 +482,27 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, | |||
482 | if (arg) { | 482 | if (arg) { |
483 | /* | 483 | /* |
484 | * num_elements was exhausted, but there are remaining elements in the | 484 | * num_elements was exhausted, but there are remaining elements in the |
485 | * package_list. | 485 | * package_list. Truncate the package to num_elements. |
486 | * | 486 | * |
487 | * Note: technically, this is an error, from ACPI spec: "It is an error | 487 | * Note: technically, this is an error, from ACPI spec: "It is an error |
488 | * for NumElements to be less than the number of elements in the | 488 | * for NumElements to be less than the number of elements in the |
489 | * PackageList". However, for now, we just print an error message and | 489 | * PackageList". However, we just print an error message and |
490 | * no exception is returned. | 490 | * no exception is returned. This provides Windows compatibility. Some |
491 | * BIOSs will alter the num_elements on the fly, creating this type | ||
492 | * of ill-formed package object. | ||
491 | */ | 493 | */ |
492 | while (arg) { | 494 | while (arg) { |
495 | /* | ||
496 | * We must delete any package elements that were created earlier | ||
497 | * and are not going to be used because of the package truncation. | ||
498 | */ | ||
499 | if (arg->common.node) { | ||
500 | acpi_ut_remove_reference(ACPI_CAST_PTR | ||
501 | (union | ||
502 | acpi_operand_object, | ||
503 | arg->common.node)); | ||
504 | arg->common.node = NULL; | ||
505 | } | ||
493 | 506 | ||
494 | /* Find out how many elements there really are */ | 507 | /* Find out how many elements there really are */ |
495 | 508 | ||
@@ -498,7 +511,7 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, | |||
498 | } | 511 | } |
499 | 512 | ||
500 | ACPI_WARNING((AE_INFO, | 513 | ACPI_WARNING((AE_INFO, |
501 | "Package List length (%X) larger than NumElements count (%X), truncated\n", | 514 | "Package List length (0x%X) larger than NumElements count (0x%X), truncated\n", |
502 | i, element_count)); | 515 | i, element_count)); |
503 | } else if (i < element_count) { | 516 | } else if (i < element_count) { |
504 | /* | 517 | /* |
@@ -506,7 +519,7 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, | |||
506 | * Note: this is not an error, the package is padded out with NULLs. | 519 | * Note: this is not an error, the package is padded out with NULLs. |
507 | */ | 520 | */ |
508 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 521 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
509 | "Package List length (%X) smaller than NumElements count (%X), padded with null elements\n", | 522 | "Package List length (0x%X) smaller than NumElements count (0x%X), padded with null elements\n", |
510 | i, element_count)); | 523 | i, element_count)); |
511 | } | 524 | } |
512 | 525 | ||
diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c index 3023ceaa8d54..6de3a99d4cd4 100644 --- a/drivers/acpi/acpica/dswload.c +++ b/drivers/acpi/acpica/dswload.c | |||
@@ -581,21 +581,6 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, | |||
581 | if ((!(walk_state->op_info->flags & AML_NSOPCODE) && | 581 | if ((!(walk_state->op_info->flags & AML_NSOPCODE) && |
582 | (walk_state->opcode != AML_INT_NAMEPATH_OP)) || | 582 | (walk_state->opcode != AML_INT_NAMEPATH_OP)) || |
583 | (!(walk_state->op_info->flags & AML_NAMED))) { | 583 | (!(walk_state->op_info->flags & AML_NAMED))) { |
584 | #ifdef ACPI_ENABLE_MODULE_LEVEL_CODE | ||
585 | if ((walk_state->op_info->class == AML_CLASS_EXECUTE) || | ||
586 | (walk_state->op_info->class == AML_CLASS_CONTROL)) { | ||
587 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
588 | "Begin/EXEC: %s (fl %8.8X)\n", | ||
589 | walk_state->op_info->name, | ||
590 | walk_state->op_info->flags)); | ||
591 | |||
592 | /* Executing a type1 or type2 opcode outside of a method */ | ||
593 | |||
594 | status = | ||
595 | acpi_ds_exec_begin_op(walk_state, out_op); | ||
596 | return_ACPI_STATUS(status); | ||
597 | } | ||
598 | #endif | ||
599 | return_ACPI_STATUS(AE_OK); | 584 | return_ACPI_STATUS(AE_OK); |
600 | } | 585 | } |
601 | 586 | ||
@@ -768,7 +753,13 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, | |||
768 | 753 | ||
769 | /* Execution mode, node cannot already exist, node is temporary */ | 754 | /* Execution mode, node cannot already exist, node is temporary */ |
770 | 755 | ||
771 | flags |= (ACPI_NS_ERROR_IF_FOUND | ACPI_NS_TEMPORARY); | 756 | flags |= ACPI_NS_ERROR_IF_FOUND; |
757 | |||
758 | if (! | ||
759 | (walk_state-> | ||
760 | parse_flags & ACPI_PARSE_MODULE_LEVEL)) { | ||
761 | flags |= ACPI_NS_TEMPORARY; | ||
762 | } | ||
772 | } | 763 | } |
773 | 764 | ||
774 | /* Add new entry or lookup existing entry */ | 765 | /* Add new entry or lookup existing entry */ |
@@ -851,24 +842,6 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
851 | /* Check if opcode had an associated namespace object */ | 842 | /* Check if opcode had an associated namespace object */ |
852 | 843 | ||
853 | if (!(walk_state->op_info->flags & AML_NSOBJECT)) { | 844 | if (!(walk_state->op_info->flags & AML_NSOBJECT)) { |
854 | #ifndef ACPI_NO_METHOD_EXECUTION | ||
855 | #ifdef ACPI_ENABLE_MODULE_LEVEL_CODE | ||
856 | /* No namespace object. Executable opcode? */ | ||
857 | |||
858 | if ((walk_state->op_info->class == AML_CLASS_EXECUTE) || | ||
859 | (walk_state->op_info->class == AML_CLASS_CONTROL)) { | ||
860 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
861 | "End/EXEC: %s (fl %8.8X)\n", | ||
862 | walk_state->op_info->name, | ||
863 | walk_state->op_info->flags)); | ||
864 | |||
865 | /* Executing a type1 or type2 opcode outside of a method */ | ||
866 | |||
867 | status = acpi_ds_exec_end_op(walk_state); | ||
868 | return_ACPI_STATUS(status); | ||
869 | } | ||
870 | #endif | ||
871 | #endif | ||
872 | return_ACPI_STATUS(AE_OK); | 845 | return_ACPI_STATUS(AE_OK); |
873 | } | 846 | } |
874 | 847 | ||
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index b9d8ee69ca6c..afacf4416c73 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
@@ -424,8 +424,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
424 | /* Read the Status Register */ | 424 | /* Read the Status Register */ |
425 | 425 | ||
426 | status = | 426 | status = |
427 | acpi_read(&status_reg, | 427 | acpi_hw_read(&status_reg, |
428 | &gpe_register_info->status_address); | 428 | &gpe_register_info->status_address); |
429 | if (ACPI_FAILURE(status)) { | 429 | if (ACPI_FAILURE(status)) { |
430 | goto unlock_and_exit; | 430 | goto unlock_and_exit; |
431 | } | 431 | } |
@@ -433,8 +433,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
433 | /* Read the Enable Register */ | 433 | /* Read the Enable Register */ |
434 | 434 | ||
435 | status = | 435 | status = |
436 | acpi_read(&enable_reg, | 436 | acpi_hw_read(&enable_reg, |
437 | &gpe_register_info->enable_address); | 437 | &gpe_register_info->enable_address); |
438 | if (ACPI_FAILURE(status)) { | 438 | if (ACPI_FAILURE(status)) { |
439 | goto unlock_and_exit; | 439 | goto unlock_and_exit; |
440 | } | 440 | } |
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 7b3463639422..a60aaa7635f3 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c | |||
@@ -843,14 +843,14 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) | |||
843 | 843 | ||
844 | /* Disable all GPEs within this register */ | 844 | /* Disable all GPEs within this register */ |
845 | 845 | ||
846 | status = acpi_write(0x00, &this_register->enable_address); | 846 | status = acpi_hw_write(0x00, &this_register->enable_address); |
847 | if (ACPI_FAILURE(status)) { | 847 | if (ACPI_FAILURE(status)) { |
848 | goto error_exit; | 848 | goto error_exit; |
849 | } | 849 | } |
850 | 850 | ||
851 | /* Clear any pending GPE events within this register */ | 851 | /* Clear any pending GPE events within this register */ |
852 | 852 | ||
853 | status = acpi_write(0xFF, &this_register->status_address); | 853 | status = acpi_hw_write(0xFF, &this_register->status_address); |
854 | if (ACPI_FAILURE(status)) { | 854 | if (ACPI_FAILURE(status)) { |
855 | goto error_exit; | 855 | goto error_exit; |
856 | } | 856 | } |
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 284a7becbe96..cf29c4953028 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c | |||
@@ -50,8 +50,6 @@ | |||
50 | ACPI_MODULE_NAME("evrgnini") | 50 | ACPI_MODULE_NAME("evrgnini") |
51 | 51 | ||
52 | /* Local prototypes */ | 52 | /* Local prototypes */ |
53 | static u8 acpi_ev_match_pci_root_bridge(char *id); | ||
54 | |||
55 | static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node); | 53 | static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node); |
56 | 54 | ||
57 | /******************************************************************************* | 55 | /******************************************************************************* |
@@ -332,37 +330,6 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, | |||
332 | 330 | ||
333 | /******************************************************************************* | 331 | /******************************************************************************* |
334 | * | 332 | * |
335 | * FUNCTION: acpi_ev_match_pci_root_bridge | ||
336 | * | ||
337 | * PARAMETERS: Id - The HID/CID in string format | ||
338 | * | ||
339 | * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge | ||
340 | * | ||
341 | * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. | ||
342 | * | ||
343 | ******************************************************************************/ | ||
344 | |||
345 | static u8 acpi_ev_match_pci_root_bridge(char *id) | ||
346 | { | ||
347 | |||
348 | /* | ||
349 | * Check if this is a PCI root. | ||
350 | * ACPI 3.0+: check for a PCI Express root also. | ||
351 | */ | ||
352 | if (!(ACPI_STRNCMP(id, | ||
353 | PCI_ROOT_HID_STRING, | ||
354 | sizeof(PCI_ROOT_HID_STRING))) || | ||
355 | !(ACPI_STRNCMP(id, | ||
356 | PCI_EXPRESS_ROOT_HID_STRING, | ||
357 | sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) { | ||
358 | return (TRUE); | ||
359 | } | ||
360 | |||
361 | return (FALSE); | ||
362 | } | ||
363 | |||
364 | /******************************************************************************* | ||
365 | * | ||
366 | * FUNCTION: acpi_ev_is_pci_root_bridge | 333 | * FUNCTION: acpi_ev_is_pci_root_bridge |
367 | * | 334 | * |
368 | * PARAMETERS: Node - Device node being examined | 335 | * PARAMETERS: Node - Device node being examined |
@@ -377,9 +344,10 @@ static u8 acpi_ev_match_pci_root_bridge(char *id) | |||
377 | static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) | 344 | static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) |
378 | { | 345 | { |
379 | acpi_status status; | 346 | acpi_status status; |
380 | struct acpica_device_id hid; | 347 | struct acpica_device_id *hid; |
381 | struct acpi_compatible_id_list *cid; | 348 | struct acpica_device_id_list *cid; |
382 | u32 i; | 349 | u32 i; |
350 | u8 match; | ||
383 | 351 | ||
384 | /* Get the _HID and check for a PCI Root Bridge */ | 352 | /* Get the _HID and check for a PCI Root Bridge */ |
385 | 353 | ||
@@ -388,7 +356,10 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) | |||
388 | return (FALSE); | 356 | return (FALSE); |
389 | } | 357 | } |
390 | 358 | ||
391 | if (acpi_ev_match_pci_root_bridge(hid.value)) { | 359 | match = acpi_ut_is_pci_root_bridge(hid->string); |
360 | ACPI_FREE(hid); | ||
361 | |||
362 | if (match) { | ||
392 | return (TRUE); | 363 | return (TRUE); |
393 | } | 364 | } |
394 | 365 | ||
@@ -402,7 +373,7 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) | |||
402 | /* Check all _CIDs in the returned list */ | 373 | /* Check all _CIDs in the returned list */ |
403 | 374 | ||
404 | for (i = 0; i < cid->count; i++) { | 375 | for (i = 0; i < cid->count; i++) { |
405 | if (acpi_ev_match_pci_root_bridge(cid->id[i].value)) { | 376 | if (acpi_ut_is_pci_root_bridge(cid->ids[i].string)) { |
406 | ACPI_FREE(cid); | 377 | ACPI_FREE(cid); |
407 | return (TRUE); | 378 | return (TRUE); |
408 | } | 379 | } |
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 277fd609611a..24afef81af39 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c | |||
@@ -110,8 +110,15 @@ acpi_ex_add_table(u32 table_index, | |||
110 | if (ACPI_FAILURE(status)) { | 110 | if (ACPI_FAILURE(status)) { |
111 | acpi_ut_remove_reference(obj_desc); | 111 | acpi_ut_remove_reference(obj_desc); |
112 | *ddb_handle = NULL; | 112 | *ddb_handle = NULL; |
113 | return_ACPI_STATUS(status); | ||
113 | } | 114 | } |
114 | 115 | ||
116 | /* Execute any module-level code that was found in the table */ | ||
117 | |||
118 | acpi_ex_exit_interpreter(); | ||
119 | acpi_ns_exec_module_code_list(); | ||
120 | acpi_ex_enter_interpreter(); | ||
121 | |||
115 | return_ACPI_STATUS(status); | 122 | return_ACPI_STATUS(status); |
116 | } | 123 | } |
117 | 124 | ||
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index ec524614e708..de3446372ddc 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c | |||
@@ -418,9 +418,9 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, | |||
418 | case ACPI_EXD_REFERENCE: | 418 | case ACPI_EXD_REFERENCE: |
419 | 419 | ||
420 | acpi_ex_out_string("Class Name", | 420 | acpi_ex_out_string("Class Name", |
421 | (char *) | 421 | ACPI_CAST_PTR(char, |
422 | acpi_ut_get_reference_name | 422 | acpi_ut_get_reference_name |
423 | (obj_desc)); | 423 | (obj_desc))); |
424 | acpi_ex_dump_reference_obj(obj_desc); | 424 | acpi_ex_dump_reference_obj(obj_desc); |
425 | break; | 425 | break; |
426 | 426 | ||
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index 546dcdd86785..0b33d6c887b9 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c | |||
@@ -72,6 +72,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | |||
72 | union acpi_operand_object *buffer_desc; | 72 | union acpi_operand_object *buffer_desc; |
73 | acpi_size length; | 73 | acpi_size length; |
74 | void *buffer; | 74 | void *buffer; |
75 | u32 function; | ||
75 | 76 | ||
76 | ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); | 77 | ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); |
77 | 78 | ||
@@ -97,13 +98,27 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | |||
97 | } | 98 | } |
98 | } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) && | 99 | } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) && |
99 | (obj_desc->field.region_obj->region.space_id == | 100 | (obj_desc->field.region_obj->region.space_id == |
100 | ACPI_ADR_SPACE_SMBUS)) { | 101 | ACPI_ADR_SPACE_SMBUS |
102 | || obj_desc->field.region_obj->region.space_id == | ||
103 | ACPI_ADR_SPACE_IPMI)) { | ||
101 | /* | 104 | /* |
102 | * This is an SMBus read. We must create a buffer to hold the data | 105 | * This is an SMBus or IPMI read. We must create a buffer to hold |
103 | * and directly access the region handler. | 106 | * the data and then directly access the region handler. |
107 | * | ||
108 | * Note: Smbus protocol value is passed in upper 16-bits of Function | ||
104 | */ | 109 | */ |
105 | buffer_desc = | 110 | if (obj_desc->field.region_obj->region.space_id == |
106 | acpi_ut_create_buffer_object(ACPI_SMBUS_BUFFER_SIZE); | 111 | ACPI_ADR_SPACE_SMBUS) { |
112 | length = ACPI_SMBUS_BUFFER_SIZE; | ||
113 | function = | ||
114 | ACPI_READ | (obj_desc->field.attribute << 16); | ||
115 | } else { /* IPMI */ | ||
116 | |||
117 | length = ACPI_IPMI_BUFFER_SIZE; | ||
118 | function = ACPI_READ; | ||
119 | } | ||
120 | |||
121 | buffer_desc = acpi_ut_create_buffer_object(length); | ||
107 | if (!buffer_desc) { | 122 | if (!buffer_desc) { |
108 | return_ACPI_STATUS(AE_NO_MEMORY); | 123 | return_ACPI_STATUS(AE_NO_MEMORY); |
109 | } | 124 | } |
@@ -112,16 +127,13 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | |||
112 | 127 | ||
113 | acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); | 128 | acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); |
114 | 129 | ||
115 | /* | 130 | /* Call the region handler for the read */ |
116 | * Perform the read. | 131 | |
117 | * Note: Smbus protocol value is passed in upper 16-bits of Function | ||
118 | */ | ||
119 | status = acpi_ex_access_region(obj_desc, 0, | 132 | status = acpi_ex_access_region(obj_desc, 0, |
120 | ACPI_CAST_PTR(acpi_integer, | 133 | ACPI_CAST_PTR(acpi_integer, |
121 | buffer_desc-> | 134 | buffer_desc-> |
122 | buffer.pointer), | 135 | buffer.pointer), |
123 | ACPI_READ | (obj_desc->field. | 136 | function); |
124 | attribute << 16)); | ||
125 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); | 137 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); |
126 | goto exit; | 138 | goto exit; |
127 | } | 139 | } |
@@ -212,6 +224,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
212 | u32 length; | 224 | u32 length; |
213 | void *buffer; | 225 | void *buffer; |
214 | union acpi_operand_object *buffer_desc; | 226 | union acpi_operand_object *buffer_desc; |
227 | u32 function; | ||
215 | 228 | ||
216 | ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); | 229 | ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); |
217 | 230 | ||
@@ -234,39 +247,56 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
234 | } | 247 | } |
235 | } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) && | 248 | } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) && |
236 | (obj_desc->field.region_obj->region.space_id == | 249 | (obj_desc->field.region_obj->region.space_id == |
237 | ACPI_ADR_SPACE_SMBUS)) { | 250 | ACPI_ADR_SPACE_SMBUS |
251 | || obj_desc->field.region_obj->region.space_id == | ||
252 | ACPI_ADR_SPACE_IPMI)) { | ||
238 | /* | 253 | /* |
239 | * This is an SMBus write. We will bypass the entire field mechanism | 254 | * This is an SMBus or IPMI write. We will bypass the entire field |
240 | * and handoff the buffer directly to the handler. | 255 | * mechanism and handoff the buffer directly to the handler. For |
256 | * these address spaces, the buffer is bi-directional; on a write, | ||
257 | * return data is returned in the same buffer. | ||
258 | * | ||
259 | * Source must be a buffer of sufficient size: | ||
260 | * ACPI_SMBUS_BUFFER_SIZE or ACPI_IPMI_BUFFER_SIZE. | ||
241 | * | 261 | * |
242 | * Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE). | 262 | * Note: SMBus protocol type is passed in upper 16-bits of Function |
243 | */ | 263 | */ |
244 | if (source_desc->common.type != ACPI_TYPE_BUFFER) { | 264 | if (source_desc->common.type != ACPI_TYPE_BUFFER) { |
245 | ACPI_ERROR((AE_INFO, | 265 | ACPI_ERROR((AE_INFO, |
246 | "SMBus write requires Buffer, found type %s", | 266 | "SMBus or IPMI write requires Buffer, found type %s", |
247 | acpi_ut_get_object_type_name(source_desc))); | 267 | acpi_ut_get_object_type_name(source_desc))); |
248 | 268 | ||
249 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 269 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
250 | } | 270 | } |
251 | 271 | ||
252 | if (source_desc->buffer.length < ACPI_SMBUS_BUFFER_SIZE) { | 272 | if (obj_desc->field.region_obj->region.space_id == |
273 | ACPI_ADR_SPACE_SMBUS) { | ||
274 | length = ACPI_SMBUS_BUFFER_SIZE; | ||
275 | function = | ||
276 | ACPI_WRITE | (obj_desc->field.attribute << 16); | ||
277 | } else { /* IPMI */ | ||
278 | |||
279 | length = ACPI_IPMI_BUFFER_SIZE; | ||
280 | function = ACPI_WRITE; | ||
281 | } | ||
282 | |||
283 | if (source_desc->buffer.length < length) { | ||
253 | ACPI_ERROR((AE_INFO, | 284 | ACPI_ERROR((AE_INFO, |
254 | "SMBus write requires Buffer of length %X, found length %X", | 285 | "SMBus or IPMI write requires Buffer of length %X, found length %X", |
255 | ACPI_SMBUS_BUFFER_SIZE, | 286 | length, source_desc->buffer.length)); |
256 | source_desc->buffer.length)); | ||
257 | 287 | ||
258 | return_ACPI_STATUS(AE_AML_BUFFER_LIMIT); | 288 | return_ACPI_STATUS(AE_AML_BUFFER_LIMIT); |
259 | } | 289 | } |
260 | 290 | ||
261 | buffer_desc = | 291 | /* Create the bi-directional buffer */ |
262 | acpi_ut_create_buffer_object(ACPI_SMBUS_BUFFER_SIZE); | 292 | |
293 | buffer_desc = acpi_ut_create_buffer_object(length); | ||
263 | if (!buffer_desc) { | 294 | if (!buffer_desc) { |
264 | return_ACPI_STATUS(AE_NO_MEMORY); | 295 | return_ACPI_STATUS(AE_NO_MEMORY); |
265 | } | 296 | } |
266 | 297 | ||
267 | buffer = buffer_desc->buffer.pointer; | 298 | buffer = buffer_desc->buffer.pointer; |
268 | ACPI_MEMCPY(buffer, source_desc->buffer.pointer, | 299 | ACPI_MEMCPY(buffer, source_desc->buffer.pointer, length); |
269 | ACPI_SMBUS_BUFFER_SIZE); | ||
270 | 300 | ||
271 | /* Lock entire transaction if requested */ | 301 | /* Lock entire transaction if requested */ |
272 | 302 | ||
@@ -275,12 +305,10 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
275 | /* | 305 | /* |
276 | * Perform the write (returns status and perhaps data in the | 306 | * Perform the write (returns status and perhaps data in the |
277 | * same buffer) | 307 | * same buffer) |
278 | * Note: SMBus protocol type is passed in upper 16-bits of Function. | ||
279 | */ | 308 | */ |
280 | status = acpi_ex_access_region(obj_desc, 0, | 309 | status = acpi_ex_access_region(obj_desc, 0, |
281 | (acpi_integer *) buffer, | 310 | (acpi_integer *) buffer, |
282 | ACPI_WRITE | (obj_desc->field. | 311 | function); |
283 | attribute << 16)); | ||
284 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); | 312 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); |
285 | 313 | ||
286 | *result_desc = buffer_desc; | 314 | *result_desc = buffer_desc; |
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index 6687be167f5f..d7b3b418fb45 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c | |||
@@ -120,12 +120,13 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, | |||
120 | } | 120 | } |
121 | 121 | ||
122 | /* | 122 | /* |
123 | * Exit now for SMBus address space, it has a non-linear address space | 123 | * Exit now for SMBus or IPMI address space, it has a non-linear address space |
124 | * and the request cannot be directly validated | 124 | * and the request cannot be directly validated |
125 | */ | 125 | */ |
126 | if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS) { | 126 | if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS || |
127 | rgn_desc->region.space_id == ACPI_ADR_SPACE_IPMI) { | ||
127 | 128 | ||
128 | /* SMBus has a non-linear address space */ | 129 | /* SMBus or IPMI has a non-linear address space */ |
129 | 130 | ||
130 | return_ACPI_STATUS(AE_OK); | 131 | return_ACPI_STATUS(AE_OK); |
131 | } | 132 | } |
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 87730e944132..7d41f99f7052 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c | |||
@@ -358,50 +358,67 @@ static u32 acpi_ex_digits_needed(acpi_integer value, u32 base) | |||
358 | * | 358 | * |
359 | * FUNCTION: acpi_ex_eisa_id_to_string | 359 | * FUNCTION: acpi_ex_eisa_id_to_string |
360 | * | 360 | * |
361 | * PARAMETERS: numeric_id - EISA ID to be converted | 361 | * PARAMETERS: compressed_id - EISAID to be converted |
362 | * out_string - Where to put the converted string (8 bytes) | 362 | * out_string - Where to put the converted string (8 bytes) |
363 | * | 363 | * |
364 | * RETURN: None | 364 | * RETURN: None |
365 | * | 365 | * |
366 | * DESCRIPTION: Convert a numeric EISA ID to string representation | 366 | * DESCRIPTION: Convert a numeric EISAID to string representation. Return |
367 | * buffer must be large enough to hold the string. The string | ||
368 | * returned is always exactly of length ACPI_EISAID_STRING_SIZE | ||
369 | * (includes null terminator). The EISAID is always 32 bits. | ||
367 | * | 370 | * |
368 | ******************************************************************************/ | 371 | ******************************************************************************/ |
369 | 372 | ||
370 | void acpi_ex_eisa_id_to_string(u32 numeric_id, char *out_string) | 373 | void acpi_ex_eisa_id_to_string(char *out_string, acpi_integer compressed_id) |
371 | { | 374 | { |
372 | u32 eisa_id; | 375 | u32 swapped_id; |
373 | 376 | ||
374 | ACPI_FUNCTION_ENTRY(); | 377 | ACPI_FUNCTION_ENTRY(); |
375 | 378 | ||
379 | /* The EISAID should be a 32-bit integer */ | ||
380 | |||
381 | if (compressed_id > ACPI_UINT32_MAX) { | ||
382 | ACPI_WARNING((AE_INFO, | ||
383 | "Expected EISAID is larger than 32 bits: 0x%8.8X%8.8X, truncating", | ||
384 | ACPI_FORMAT_UINT64(compressed_id))); | ||
385 | } | ||
386 | |||
376 | /* Swap ID to big-endian to get contiguous bits */ | 387 | /* Swap ID to big-endian to get contiguous bits */ |
377 | 388 | ||
378 | eisa_id = acpi_ut_dword_byte_swap(numeric_id); | 389 | swapped_id = acpi_ut_dword_byte_swap((u32)compressed_id); |
379 | 390 | ||
380 | out_string[0] = (char)('@' + (((unsigned long)eisa_id >> 26) & 0x1f)); | 391 | /* First 3 bytes are uppercase letters. Next 4 bytes are hexadecimal */ |
381 | out_string[1] = (char)('@' + ((eisa_id >> 21) & 0x1f)); | 392 | |
382 | out_string[2] = (char)('@' + ((eisa_id >> 16) & 0x1f)); | 393 | out_string[0] = |
383 | out_string[3] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 12); | 394 | (char)(0x40 + (((unsigned long)swapped_id >> 26) & 0x1F)); |
384 | out_string[4] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 8); | 395 | out_string[1] = (char)(0x40 + ((swapped_id >> 21) & 0x1F)); |
385 | out_string[5] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 4); | 396 | out_string[2] = (char)(0x40 + ((swapped_id >> 16) & 0x1F)); |
386 | out_string[6] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 0); | 397 | out_string[3] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 12); |
398 | out_string[4] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 8); | ||
399 | out_string[5] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 4); | ||
400 | out_string[6] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 0); | ||
387 | out_string[7] = 0; | 401 | out_string[7] = 0; |
388 | } | 402 | } |
389 | 403 | ||
390 | /******************************************************************************* | 404 | /******************************************************************************* |
391 | * | 405 | * |
392 | * FUNCTION: acpi_ex_unsigned_integer_to_string | 406 | * FUNCTION: acpi_ex_integer_to_string |
393 | * | 407 | * |
394 | * PARAMETERS: Value - Value to be converted | 408 | * PARAMETERS: out_string - Where to put the converted string. At least |
395 | * out_string - Where to put the converted string (8 bytes) | 409 | * 21 bytes are needed to hold the largest |
410 | * possible 64-bit integer. | ||
411 | * Value - Value to be converted | ||
396 | * | 412 | * |
397 | * RETURN: None, string | 413 | * RETURN: None, string |
398 | * | 414 | * |
399 | * DESCRIPTION: Convert a number to string representation. Assumes string | 415 | * DESCRIPTION: Convert a 64-bit integer to decimal string representation. |
400 | * buffer is large enough to hold the string. | 416 | * Assumes string buffer is large enough to hold the string. The |
417 | * largest string is (ACPI_MAX64_DECIMAL_DIGITS + 1). | ||
401 | * | 418 | * |
402 | ******************************************************************************/ | 419 | ******************************************************************************/ |
403 | 420 | ||
404 | void acpi_ex_unsigned_integer_to_string(acpi_integer value, char *out_string) | 421 | void acpi_ex_integer_to_string(char *out_string, acpi_integer value) |
405 | { | 422 | { |
406 | u32 count; | 423 | u32 count; |
407 | u32 digits_needed; | 424 | u32 digits_needed; |
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index d3b7e37c9eed..c28c41b3180b 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c | |||
@@ -82,7 +82,7 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
82 | 82 | ||
83 | /* Get current value of the enable register that contains this GPE */ | 83 | /* Get current value of the enable register that contains this GPE */ |
84 | 84 | ||
85 | status = acpi_read(&enable_mask, &gpe_register_info->enable_address); | 85 | status = acpi_hw_read(&enable_mask, &gpe_register_info->enable_address); |
86 | if (ACPI_FAILURE(status)) { | 86 | if (ACPI_FAILURE(status)) { |
87 | return (status); | 87 | return (status); |
88 | } | 88 | } |
@@ -95,7 +95,7 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
95 | 95 | ||
96 | /* Write the updated enable mask */ | 96 | /* Write the updated enable mask */ |
97 | 97 | ||
98 | status = acpi_write(enable_mask, &gpe_register_info->enable_address); | 98 | status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address); |
99 | return (status); | 99 | return (status); |
100 | } | 100 | } |
101 | 101 | ||
@@ -130,8 +130,8 @@ acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) | |||
130 | 130 | ||
131 | /* Write the entire GPE (runtime) enable register */ | 131 | /* Write the entire GPE (runtime) enable register */ |
132 | 132 | ||
133 | status = acpi_write(gpe_register_info->enable_for_run, | 133 | status = acpi_hw_write(gpe_register_info->enable_for_run, |
134 | &gpe_register_info->enable_address); | 134 | &gpe_register_info->enable_address); |
135 | 135 | ||
136 | return (status); | 136 | return (status); |
137 | } | 137 | } |
@@ -163,8 +163,8 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) | |||
163 | * Write a one to the appropriate bit in the status register to | 163 | * Write a one to the appropriate bit in the status register to |
164 | * clear this GPE. | 164 | * clear this GPE. |
165 | */ | 165 | */ |
166 | status = acpi_write(register_bit, | 166 | status = acpi_hw_write(register_bit, |
167 | &gpe_event_info->register_info->status_address); | 167 | &gpe_event_info->register_info->status_address); |
168 | 168 | ||
169 | return (status); | 169 | return (status); |
170 | } | 170 | } |
@@ -222,7 +222,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, | |||
222 | 222 | ||
223 | /* GPE currently active (status bit == 1)? */ | 223 | /* GPE currently active (status bit == 1)? */ |
224 | 224 | ||
225 | status = acpi_read(&in_byte, &gpe_register_info->status_address); | 225 | status = acpi_hw_read(&in_byte, &gpe_register_info->status_address); |
226 | if (ACPI_FAILURE(status)) { | 226 | if (ACPI_FAILURE(status)) { |
227 | goto unlock_and_exit; | 227 | goto unlock_and_exit; |
228 | } | 228 | } |
@@ -266,8 +266,8 @@ acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
266 | /* Disable all GPEs in this register */ | 266 | /* Disable all GPEs in this register */ |
267 | 267 | ||
268 | status = | 268 | status = |
269 | acpi_write(0x00, | 269 | acpi_hw_write(0x00, |
270 | &gpe_block->register_info[i].enable_address); | 270 | &gpe_block->register_info[i].enable_address); |
271 | if (ACPI_FAILURE(status)) { | 271 | if (ACPI_FAILURE(status)) { |
272 | return (status); | 272 | return (status); |
273 | } | 273 | } |
@@ -303,8 +303,8 @@ acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
303 | /* Clear status on all GPEs in this register */ | 303 | /* Clear status on all GPEs in this register */ |
304 | 304 | ||
305 | status = | 305 | status = |
306 | acpi_write(0xFF, | 306 | acpi_hw_write(0xFF, |
307 | &gpe_block->register_info[i].status_address); | 307 | &gpe_block->register_info[i].status_address); |
308 | if (ACPI_FAILURE(status)) { | 308 | if (ACPI_FAILURE(status)) { |
309 | return (status); | 309 | return (status); |
310 | } | 310 | } |
@@ -345,9 +345,9 @@ acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
345 | 345 | ||
346 | /* Enable all "runtime" GPEs in this register */ | 346 | /* Enable all "runtime" GPEs in this register */ |
347 | 347 | ||
348 | status = acpi_write(gpe_block->register_info[i].enable_for_run, | 348 | status = |
349 | &gpe_block->register_info[i]. | 349 | acpi_hw_write(gpe_block->register_info[i].enable_for_run, |
350 | enable_address); | 350 | &gpe_block->register_info[i].enable_address); |
351 | if (ACPI_FAILURE(status)) { | 351 | if (ACPI_FAILURE(status)) { |
352 | return (status); | 352 | return (status); |
353 | } | 353 | } |
@@ -387,9 +387,9 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
387 | 387 | ||
388 | /* Enable all "wake" GPEs in this register */ | 388 | /* Enable all "wake" GPEs in this register */ |
389 | 389 | ||
390 | status = acpi_write(gpe_block->register_info[i].enable_for_wake, | 390 | status = |
391 | &gpe_block->register_info[i]. | 391 | acpi_hw_write(gpe_block->register_info[i].enable_for_wake, |
392 | enable_address); | 392 | &gpe_block->register_info[i].enable_address); |
393 | if (ACPI_FAILURE(status)) { | 393 | if (ACPI_FAILURE(status)) { |
394 | return (status); | 394 | return (status); |
395 | } | 395 | } |
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 23d5505cb1f7..15c9ed2be853 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c | |||
@@ -62,6 +62,184 @@ acpi_hw_write_multiple(u32 value, | |||
62 | struct acpi_generic_address *register_a, | 62 | struct acpi_generic_address *register_a, |
63 | struct acpi_generic_address *register_b); | 63 | struct acpi_generic_address *register_b); |
64 | 64 | ||
65 | /****************************************************************************** | ||
66 | * | ||
67 | * FUNCTION: acpi_hw_validate_register | ||
68 | * | ||
69 | * PARAMETERS: Reg - GAS register structure | ||
70 | * max_bit_width - Max bit_width supported (32 or 64) | ||
71 | * Address - Pointer to where the gas->address | ||
72 | * is returned | ||
73 | * | ||
74 | * RETURN: Status | ||
75 | * | ||
76 | * DESCRIPTION: Validate the contents of a GAS register. Checks the GAS | ||
77 | * pointer, Address, space_id, bit_width, and bit_offset. | ||
78 | * | ||
79 | ******************************************************************************/ | ||
80 | |||
81 | acpi_status | ||
82 | acpi_hw_validate_register(struct acpi_generic_address *reg, | ||
83 | u8 max_bit_width, u64 *address) | ||
84 | { | ||
85 | |||
86 | /* Must have a valid pointer to a GAS structure */ | ||
87 | |||
88 | if (!reg) { | ||
89 | return (AE_BAD_PARAMETER); | ||
90 | } | ||
91 | |||
92 | /* | ||
93 | * Copy the target address. This handles possible alignment issues. | ||
94 | * Address must not be null. A null address also indicates an optional | ||
95 | * ACPI register that is not supported, so no error message. | ||
96 | */ | ||
97 | ACPI_MOVE_64_TO_64(address, ®->address); | ||
98 | if (!(*address)) { | ||
99 | return (AE_BAD_ADDRESS); | ||
100 | } | ||
101 | |||
102 | /* Validate the space_iD */ | ||
103 | |||
104 | if ((reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) && | ||
105 | (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) { | ||
106 | ACPI_ERROR((AE_INFO, | ||
107 | "Unsupported address space: 0x%X", reg->space_id)); | ||
108 | return (AE_SUPPORT); | ||
109 | } | ||
110 | |||
111 | /* Validate the bit_width */ | ||
112 | |||
113 | if ((reg->bit_width != 8) && | ||
114 | (reg->bit_width != 16) && | ||
115 | (reg->bit_width != 32) && (reg->bit_width != max_bit_width)) { | ||
116 | ACPI_ERROR((AE_INFO, | ||
117 | "Unsupported register bit width: 0x%X", | ||
118 | reg->bit_width)); | ||
119 | return (AE_SUPPORT); | ||
120 | } | ||
121 | |||
122 | /* Validate the bit_offset. Just a warning for now. */ | ||
123 | |||
124 | if (reg->bit_offset != 0) { | ||
125 | ACPI_WARNING((AE_INFO, | ||
126 | "Unsupported register bit offset: 0x%X", | ||
127 | reg->bit_offset)); | ||
128 | } | ||
129 | |||
130 | return (AE_OK); | ||
131 | } | ||
132 | |||
133 | /****************************************************************************** | ||
134 | * | ||
135 | * FUNCTION: acpi_hw_read | ||
136 | * | ||
137 | * PARAMETERS: Value - Where the value is returned | ||
138 | * Reg - GAS register structure | ||
139 | * | ||
140 | * RETURN: Status | ||
141 | * | ||
142 | * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max | ||
143 | * version of acpi_read, used internally since the overhead of | ||
144 | * 64-bit values is not needed. | ||
145 | * | ||
146 | * LIMITATIONS: <These limitations also apply to acpi_hw_write> | ||
147 | * bit_width must be exactly 8, 16, or 32. | ||
148 | * space_iD must be system_memory or system_iO. | ||
149 | * bit_offset and access_width are currently ignored, as there has | ||
150 | * not been a need to implement these. | ||
151 | * | ||
152 | ******************************************************************************/ | ||
153 | |||
154 | acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | ||
155 | { | ||
156 | u64 address; | ||
157 | acpi_status status; | ||
158 | |||
159 | ACPI_FUNCTION_NAME(hw_read); | ||
160 | |||
161 | /* Validate contents of the GAS register */ | ||
162 | |||
163 | status = acpi_hw_validate_register(reg, 32, &address); | ||
164 | if (ACPI_FAILURE(status)) { | ||
165 | return (status); | ||
166 | } | ||
167 | |||
168 | /* Initialize entire 32-bit return value to zero */ | ||
169 | |||
170 | *value = 0; | ||
171 | |||
172 | /* | ||
173 | * Two address spaces supported: Memory or IO. PCI_Config is | ||
174 | * not supported here because the GAS structure is insufficient | ||
175 | */ | ||
176 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | ||
177 | status = acpi_os_read_memory((acpi_physical_address) | ||
178 | address, value, reg->bit_width); | ||
179 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | ||
180 | |||
181 | status = acpi_hw_read_port((acpi_io_address) | ||
182 | address, value, reg->bit_width); | ||
183 | } | ||
184 | |||
185 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | ||
186 | "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", | ||
187 | *value, reg->bit_width, ACPI_FORMAT_UINT64(address), | ||
188 | acpi_ut_get_region_name(reg->space_id))); | ||
189 | |||
190 | return (status); | ||
191 | } | ||
192 | |||
193 | /****************************************************************************** | ||
194 | * | ||
195 | * FUNCTION: acpi_hw_write | ||
196 | * | ||
197 | * PARAMETERS: Value - Value to be written | ||
198 | * Reg - GAS register structure | ||
199 | * | ||
200 | * RETURN: Status | ||
201 | * | ||
202 | * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max | ||
203 | * version of acpi_write, used internally since the overhead of | ||
204 | * 64-bit values is not needed. | ||
205 | * | ||
206 | ******************************************************************************/ | ||
207 | |||
208 | acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) | ||
209 | { | ||
210 | u64 address; | ||
211 | acpi_status status; | ||
212 | |||
213 | ACPI_FUNCTION_NAME(hw_write); | ||
214 | |||
215 | /* Validate contents of the GAS register */ | ||
216 | |||
217 | status = acpi_hw_validate_register(reg, 32, &address); | ||
218 | if (ACPI_FAILURE(status)) { | ||
219 | return (status); | ||
220 | } | ||
221 | |||
222 | /* | ||
223 | * Two address spaces supported: Memory or IO. PCI_Config is | ||
224 | * not supported here because the GAS structure is insufficient | ||
225 | */ | ||
226 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | ||
227 | status = acpi_os_write_memory((acpi_physical_address) | ||
228 | address, value, reg->bit_width); | ||
229 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | ||
230 | |||
231 | status = acpi_hw_write_port((acpi_io_address) | ||
232 | address, value, reg->bit_width); | ||
233 | } | ||
234 | |||
235 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | ||
236 | "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", | ||
237 | value, reg->bit_width, ACPI_FORMAT_UINT64(address), | ||
238 | acpi_ut_get_region_name(reg->space_id))); | ||
239 | |||
240 | return (status); | ||
241 | } | ||
242 | |||
65 | /******************************************************************************* | 243 | /******************************************************************************* |
66 | * | 244 | * |
67 | * FUNCTION: acpi_hw_clear_acpi_status | 245 | * FUNCTION: acpi_hw_clear_acpi_status |
@@ -152,15 +330,16 @@ acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control) | |||
152 | 330 | ||
153 | ACPI_FUNCTION_TRACE(hw_write_pm1_control); | 331 | ACPI_FUNCTION_TRACE(hw_write_pm1_control); |
154 | 332 | ||
155 | status = acpi_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block); | 333 | status = |
334 | acpi_hw_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block); | ||
156 | if (ACPI_FAILURE(status)) { | 335 | if (ACPI_FAILURE(status)) { |
157 | return_ACPI_STATUS(status); | 336 | return_ACPI_STATUS(status); |
158 | } | 337 | } |
159 | 338 | ||
160 | if (acpi_gbl_FADT.xpm1b_control_block.address) { | 339 | if (acpi_gbl_FADT.xpm1b_control_block.address) { |
161 | status = | 340 | status = |
162 | acpi_write(pm1b_control, | 341 | acpi_hw_write(pm1b_control, |
163 | &acpi_gbl_FADT.xpm1b_control_block); | 342 | &acpi_gbl_FADT.xpm1b_control_block); |
164 | } | 343 | } |
165 | return_ACPI_STATUS(status); | 344 | return_ACPI_STATUS(status); |
166 | } | 345 | } |
@@ -218,12 +397,13 @@ acpi_hw_register_read(u32 register_id, u32 * return_value) | |||
218 | 397 | ||
219 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ | 398 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ |
220 | 399 | ||
221 | status = acpi_read(&value, &acpi_gbl_FADT.xpm2_control_block); | 400 | status = |
401 | acpi_hw_read(&value, &acpi_gbl_FADT.xpm2_control_block); | ||
222 | break; | 402 | break; |
223 | 403 | ||
224 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ | 404 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ |
225 | 405 | ||
226 | status = acpi_read(&value, &acpi_gbl_FADT.xpm_timer_block); | 406 | status = acpi_hw_read(&value, &acpi_gbl_FADT.xpm_timer_block); |
227 | break; | 407 | break; |
228 | 408 | ||
229 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ | 409 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ |
@@ -340,7 +520,8 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) | |||
340 | * as per the ACPI spec. | 520 | * as per the ACPI spec. |
341 | */ | 521 | */ |
342 | status = | 522 | status = |
343 | acpi_read(&read_value, &acpi_gbl_FADT.xpm2_control_block); | 523 | acpi_hw_read(&read_value, |
524 | &acpi_gbl_FADT.xpm2_control_block); | ||
344 | if (ACPI_FAILURE(status)) { | 525 | if (ACPI_FAILURE(status)) { |
345 | goto exit; | 526 | goto exit; |
346 | } | 527 | } |
@@ -350,12 +531,13 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) | |||
350 | ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS, | 531 | ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS, |
351 | read_value); | 532 | read_value); |
352 | 533 | ||
353 | status = acpi_write(value, &acpi_gbl_FADT.xpm2_control_block); | 534 | status = |
535 | acpi_hw_write(value, &acpi_gbl_FADT.xpm2_control_block); | ||
354 | break; | 536 | break; |
355 | 537 | ||
356 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ | 538 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ |
357 | 539 | ||
358 | status = acpi_write(value, &acpi_gbl_FADT.xpm_timer_block); | 540 | status = acpi_hw_write(value, &acpi_gbl_FADT.xpm_timer_block); |
359 | break; | 541 | break; |
360 | 542 | ||
361 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ | 543 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ |
@@ -401,7 +583,7 @@ acpi_hw_read_multiple(u32 *value, | |||
401 | 583 | ||
402 | /* The first register is always required */ | 584 | /* The first register is always required */ |
403 | 585 | ||
404 | status = acpi_read(&value_a, register_a); | 586 | status = acpi_hw_read(&value_a, register_a); |
405 | if (ACPI_FAILURE(status)) { | 587 | if (ACPI_FAILURE(status)) { |
406 | return (status); | 588 | return (status); |
407 | } | 589 | } |
@@ -409,7 +591,7 @@ acpi_hw_read_multiple(u32 *value, | |||
409 | /* Second register is optional */ | 591 | /* Second register is optional */ |
410 | 592 | ||
411 | if (register_b->address) { | 593 | if (register_b->address) { |
412 | status = acpi_read(&value_b, register_b); | 594 | status = acpi_hw_read(&value_b, register_b); |
413 | if (ACPI_FAILURE(status)) { | 595 | if (ACPI_FAILURE(status)) { |
414 | return (status); | 596 | return (status); |
415 | } | 597 | } |
@@ -452,7 +634,7 @@ acpi_hw_write_multiple(u32 value, | |||
452 | 634 | ||
453 | /* The first register is always required */ | 635 | /* The first register is always required */ |
454 | 636 | ||
455 | status = acpi_write(value, register_a); | 637 | status = acpi_hw_write(value, register_a); |
456 | if (ACPI_FAILURE(status)) { | 638 | if (ACPI_FAILURE(status)) { |
457 | return (status); | 639 | return (status); |
458 | } | 640 | } |
@@ -470,7 +652,7 @@ acpi_hw_write_multiple(u32 value, | |||
470 | * and writes have no side effects" | 652 | * and writes have no side effects" |
471 | */ | 653 | */ |
472 | if (register_b->address) { | 654 | if (register_b->address) { |
473 | status = acpi_write(value, register_b); | 655 | status = acpi_hw_write(value, register_b); |
474 | } | 656 | } |
475 | 657 | ||
476 | return (status); | 658 | return (status); |
diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index b7f522c8f023..6b282e85d039 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c | |||
@@ -100,7 +100,7 @@ acpi_status acpi_get_timer(u32 * ticks) | |||
100 | } | 100 | } |
101 | 101 | ||
102 | status = | 102 | status = |
103 | acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT.xpm_timer_block); | 103 | acpi_hw_read(ticks, &acpi_gbl_FADT.xpm_timer_block); |
104 | 104 | ||
105 | return_ACPI_STATUS(status); | 105 | return_ACPI_STATUS(status); |
106 | } | 106 | } |
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index 9829979f2bdd..647c7b6e6756 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c | |||
@@ -78,9 +78,22 @@ acpi_status acpi_reset(void) | |||
78 | return_ACPI_STATUS(AE_NOT_EXIST); | 78 | return_ACPI_STATUS(AE_NOT_EXIST); |
79 | } | 79 | } |
80 | 80 | ||
81 | /* Write the reset value to the reset register */ | 81 | if (reset_reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { |
82 | /* | ||
83 | * For I/O space, write directly to the OSL. This bypasses the port | ||
84 | * validation mechanism, which may block a valid write to the reset | ||
85 | * register. | ||
86 | */ | ||
87 | status = | ||
88 | acpi_os_write_port((acpi_io_address) reset_reg->address, | ||
89 | acpi_gbl_FADT.reset_value, | ||
90 | reset_reg->bit_width); | ||
91 | } else { | ||
92 | /* Write the reset value to the reset register */ | ||
93 | |||
94 | status = acpi_hw_write(acpi_gbl_FADT.reset_value, reset_reg); | ||
95 | } | ||
82 | 96 | ||
83 | status = acpi_write(acpi_gbl_FADT.reset_value, reset_reg); | ||
84 | return_ACPI_STATUS(status); | 97 | return_ACPI_STATUS(status); |
85 | } | 98 | } |
86 | 99 | ||
@@ -97,67 +110,92 @@ ACPI_EXPORT_SYMBOL(acpi_reset) | |||
97 | * | 110 | * |
98 | * DESCRIPTION: Read from either memory or IO space. | 111 | * DESCRIPTION: Read from either memory or IO space. |
99 | * | 112 | * |
113 | * LIMITATIONS: <These limitations also apply to acpi_write> | ||
114 | * bit_width must be exactly 8, 16, 32, or 64. | ||
115 | * space_iD must be system_memory or system_iO. | ||
116 | * bit_offset and access_width are currently ignored, as there has | ||
117 | * not been a need to implement these. | ||
118 | * | ||
100 | ******************************************************************************/ | 119 | ******************************************************************************/ |
101 | acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg) | 120 | acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) |
102 | { | 121 | { |
122 | u32 value; | ||
103 | u32 width; | 123 | u32 width; |
104 | u64 address; | 124 | u64 address; |
105 | acpi_status status; | 125 | acpi_status status; |
106 | 126 | ||
107 | ACPI_FUNCTION_NAME(acpi_read); | 127 | ACPI_FUNCTION_NAME(acpi_read); |
108 | 128 | ||
109 | /* | 129 | if (!return_value) { |
110 | * Must have a valid pointer to a GAS structure, and a non-zero address | ||
111 | * within. | ||
112 | */ | ||
113 | if (!reg) { | ||
114 | return (AE_BAD_PARAMETER); | 130 | return (AE_BAD_PARAMETER); |
115 | } | 131 | } |
116 | 132 | ||
117 | /* Get a local copy of the address. Handles possible alignment issues */ | 133 | /* Validate contents of the GAS register. Allow 64-bit transfers */ |
118 | 134 | ||
119 | ACPI_MOVE_64_TO_64(&address, ®->address); | 135 | status = acpi_hw_validate_register(reg, 64, &address); |
120 | if (!address) { | 136 | if (ACPI_FAILURE(status)) { |
121 | return (AE_BAD_ADDRESS); | 137 | return (status); |
122 | } | 138 | } |
123 | 139 | ||
124 | /* Supported widths are 8/16/32 */ | ||
125 | |||
126 | width = reg->bit_width; | 140 | width = reg->bit_width; |
127 | if ((width != 8) && (width != 16) && (width != 32)) { | 141 | if (width == 64) { |
128 | return (AE_SUPPORT); | 142 | width = 32; /* Break into two 32-bit transfers */ |
129 | } | 143 | } |
130 | 144 | ||
131 | /* Initialize entire 32-bit return value to zero */ | 145 | /* Initialize entire 64-bit return value to zero */ |
132 | 146 | ||
133 | *value = 0; | 147 | *return_value = 0; |
148 | value = 0; | ||
134 | 149 | ||
135 | /* | 150 | /* |
136 | * Two address spaces supported: Memory or IO. PCI_Config is | 151 | * Two address spaces supported: Memory or IO. PCI_Config is |
137 | * not supported here because the GAS structure is insufficient | 152 | * not supported here because the GAS structure is insufficient |
138 | */ | 153 | */ |
139 | switch (reg->space_id) { | 154 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
140 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 155 | status = acpi_os_read_memory((acpi_physical_address) |
156 | address, &value, width); | ||
157 | if (ACPI_FAILURE(status)) { | ||
158 | return (status); | ||
159 | } | ||
160 | *return_value = value; | ||
141 | 161 | ||
142 | status = acpi_os_read_memory((acpi_physical_address) address, | 162 | if (reg->bit_width == 64) { |
143 | value, width); | ||
144 | break; | ||
145 | 163 | ||
146 | case ACPI_ADR_SPACE_SYSTEM_IO: | 164 | /* Read the top 32 bits */ |
147 | 165 | ||
148 | status = | 166 | status = acpi_os_read_memory((acpi_physical_address) |
149 | acpi_hw_read_port((acpi_io_address) address, value, width); | 167 | (address + 4), &value, 32); |
150 | break; | 168 | if (ACPI_FAILURE(status)) { |
169 | return (status); | ||
170 | } | ||
171 | *return_value |= ((u64)value << 32); | ||
172 | } | ||
173 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | ||
151 | 174 | ||
152 | default: | 175 | status = acpi_hw_read_port((acpi_io_address) |
153 | ACPI_ERROR((AE_INFO, | 176 | address, &value, width); |
154 | "Unsupported address space: %X", reg->space_id)); | 177 | if (ACPI_FAILURE(status)) { |
155 | return (AE_BAD_PARAMETER); | 178 | return (status); |
179 | } | ||
180 | *return_value = value; | ||
181 | |||
182 | if (reg->bit_width == 64) { | ||
183 | |||
184 | /* Read the top 32 bits */ | ||
185 | |||
186 | status = acpi_hw_read_port((acpi_io_address) | ||
187 | (address + 4), &value, 32); | ||
188 | if (ACPI_FAILURE(status)) { | ||
189 | return (status); | ||
190 | } | ||
191 | *return_value |= ((u64)value << 32); | ||
192 | } | ||
156 | } | 193 | } |
157 | 194 | ||
158 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 195 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
159 | "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", | 196 | "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n", |
160 | *value, width, ACPI_FORMAT_UINT64(address), | 197 | ACPI_FORMAT_UINT64(*return_value), reg->bit_width, |
198 | ACPI_FORMAT_UINT64(address), | ||
161 | acpi_ut_get_region_name(reg->space_id))); | 199 | acpi_ut_get_region_name(reg->space_id))); |
162 | 200 | ||
163 | return (status); | 201 | return (status); |
@@ -169,7 +207,7 @@ ACPI_EXPORT_SYMBOL(acpi_read) | |||
169 | * | 207 | * |
170 | * FUNCTION: acpi_write | 208 | * FUNCTION: acpi_write |
171 | * | 209 | * |
172 | * PARAMETERS: Value - To be written | 210 | * PARAMETERS: Value - Value to be written |
173 | * Reg - GAS register structure | 211 | * Reg - GAS register structure |
174 | * | 212 | * |
175 | * RETURN: Status | 213 | * RETURN: Status |
@@ -177,7 +215,7 @@ ACPI_EXPORT_SYMBOL(acpi_read) | |||
177 | * DESCRIPTION: Write to either memory or IO space. | 215 | * DESCRIPTION: Write to either memory or IO space. |
178 | * | 216 | * |
179 | ******************************************************************************/ | 217 | ******************************************************************************/ |
180 | acpi_status acpi_write(u32 value, struct acpi_generic_address *reg) | 218 | acpi_status acpi_write(u64 value, struct acpi_generic_address *reg) |
181 | { | 219 | { |
182 | u32 width; | 220 | u32 width; |
183 | u64 address; | 221 | u64 address; |
@@ -185,54 +223,61 @@ acpi_status acpi_write(u32 value, struct acpi_generic_address *reg) | |||
185 | 223 | ||
186 | ACPI_FUNCTION_NAME(acpi_write); | 224 | ACPI_FUNCTION_NAME(acpi_write); |
187 | 225 | ||
188 | /* | 226 | /* Validate contents of the GAS register. Allow 64-bit transfers */ |
189 | * Must have a valid pointer to a GAS structure, and a non-zero address | ||
190 | * within. | ||
191 | */ | ||
192 | if (!reg) { | ||
193 | return (AE_BAD_PARAMETER); | ||
194 | } | ||
195 | |||
196 | /* Get a local copy of the address. Handles possible alignment issues */ | ||
197 | 227 | ||
198 | ACPI_MOVE_64_TO_64(&address, ®->address); | 228 | status = acpi_hw_validate_register(reg, 64, &address); |
199 | if (!address) { | 229 | if (ACPI_FAILURE(status)) { |
200 | return (AE_BAD_ADDRESS); | 230 | return (status); |
201 | } | 231 | } |
202 | 232 | ||
203 | /* Supported widths are 8/16/32 */ | ||
204 | |||
205 | width = reg->bit_width; | 233 | width = reg->bit_width; |
206 | if ((width != 8) && (width != 16) && (width != 32)) { | 234 | if (width == 64) { |
207 | return (AE_SUPPORT); | 235 | width = 32; /* Break into two 32-bit transfers */ |
208 | } | 236 | } |
209 | 237 | ||
210 | /* | 238 | /* |
211 | * Two address spaces supported: Memory or IO. | 239 | * Two address spaces supported: Memory or IO. PCI_Config is |
212 | * PCI_Config is not supported here because the GAS struct is insufficient | 240 | * not supported here because the GAS structure is insufficient |
213 | */ | 241 | */ |
214 | switch (reg->space_id) { | 242 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
215 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 243 | status = acpi_os_write_memory((acpi_physical_address) |
216 | 244 | address, ACPI_LODWORD(value), | |
217 | status = acpi_os_write_memory((acpi_physical_address) address, | 245 | width); |
218 | value, width); | 246 | if (ACPI_FAILURE(status)) { |
219 | break; | 247 | return (status); |
248 | } | ||
220 | 249 | ||
221 | case ACPI_ADR_SPACE_SYSTEM_IO: | 250 | if (reg->bit_width == 64) { |
251 | status = acpi_os_write_memory((acpi_physical_address) | ||
252 | (address + 4), | ||
253 | ACPI_HIDWORD(value), 32); | ||
254 | if (ACPI_FAILURE(status)) { | ||
255 | return (status); | ||
256 | } | ||
257 | } | ||
258 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | ||
222 | 259 | ||
223 | status = acpi_hw_write_port((acpi_io_address) address, value, | 260 | status = acpi_hw_write_port((acpi_io_address) |
261 | address, ACPI_LODWORD(value), | ||
224 | width); | 262 | width); |
225 | break; | 263 | if (ACPI_FAILURE(status)) { |
264 | return (status); | ||
265 | } | ||
226 | 266 | ||
227 | default: | 267 | if (reg->bit_width == 64) { |
228 | ACPI_ERROR((AE_INFO, | 268 | status = acpi_hw_write_port((acpi_io_address) |
229 | "Unsupported address space: %X", reg->space_id)); | 269 | (address + 4), |
230 | return (AE_BAD_PARAMETER); | 270 | ACPI_HIDWORD(value), 32); |
271 | if (ACPI_FAILURE(status)) { | ||
272 | return (status); | ||
273 | } | ||
274 | } | ||
231 | } | 275 | } |
232 | 276 | ||
233 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 277 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
234 | "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", | 278 | "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n", |
235 | value, width, ACPI_FORMAT_UINT64(address), | 279 | ACPI_FORMAT_UINT64(value), reg->bit_width, |
280 | ACPI_FORMAT_UINT64(address), | ||
236 | acpi_ut_get_region_name(reg->space_id))); | 281 | acpi_ut_get_region_name(reg->space_id))); |
237 | 282 | ||
238 | return (status); | 283 | return (status); |
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index efc971ab7d65..8a58a1b85aa0 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c | |||
@@ -96,17 +96,68 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name) | |||
96 | * | 96 | * |
97 | * RETURN: None | 97 | * RETURN: None |
98 | * | 98 | * |
99 | * DESCRIPTION: Delete a namespace node | 99 | * DESCRIPTION: Delete a namespace node. All node deletions must come through |
100 | * here. Detaches any attached objects, including any attached | ||
101 | * data. If a handler is associated with attached data, it is | ||
102 | * invoked before the node is deleted. | ||
100 | * | 103 | * |
101 | ******************************************************************************/ | 104 | ******************************************************************************/ |
102 | 105 | ||
103 | void acpi_ns_delete_node(struct acpi_namespace_node *node) | 106 | void acpi_ns_delete_node(struct acpi_namespace_node *node) |
104 | { | 107 | { |
108 | union acpi_operand_object *obj_desc; | ||
109 | |||
110 | ACPI_FUNCTION_NAME(ns_delete_node); | ||
111 | |||
112 | /* Detach an object if there is one */ | ||
113 | |||
114 | acpi_ns_detach_object(node); | ||
115 | |||
116 | /* | ||
117 | * Delete an attached data object if present (an object that was created | ||
118 | * and attached via acpi_attach_data). Note: After any normal object is | ||
119 | * detached above, the only possible remaining object is a data object. | ||
120 | */ | ||
121 | obj_desc = node->object; | ||
122 | if (obj_desc && (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) { | ||
123 | |||
124 | /* Invoke the attached data deletion handler if present */ | ||
125 | |||
126 | if (obj_desc->data.handler) { | ||
127 | obj_desc->data.handler(node, obj_desc->data.pointer); | ||
128 | } | ||
129 | |||
130 | acpi_ut_remove_reference(obj_desc); | ||
131 | } | ||
132 | |||
133 | /* Now we can delete the node */ | ||
134 | |||
135 | (void)acpi_os_release_object(acpi_gbl_namespace_cache, node); | ||
136 | |||
137 | ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); | ||
138 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Node %p, Remaining %X\n", | ||
139 | node, acpi_gbl_current_node_count)); | ||
140 | } | ||
141 | |||
142 | /******************************************************************************* | ||
143 | * | ||
144 | * FUNCTION: acpi_ns_remove_node | ||
145 | * | ||
146 | * PARAMETERS: Node - Node to be removed/deleted | ||
147 | * | ||
148 | * RETURN: None | ||
149 | * | ||
150 | * DESCRIPTION: Remove (unlink) and delete a namespace node | ||
151 | * | ||
152 | ******************************************************************************/ | ||
153 | |||
154 | void acpi_ns_remove_node(struct acpi_namespace_node *node) | ||
155 | { | ||
105 | struct acpi_namespace_node *parent_node; | 156 | struct acpi_namespace_node *parent_node; |
106 | struct acpi_namespace_node *prev_node; | 157 | struct acpi_namespace_node *prev_node; |
107 | struct acpi_namespace_node *next_node; | 158 | struct acpi_namespace_node *next_node; |
108 | 159 | ||
109 | ACPI_FUNCTION_TRACE_PTR(ns_delete_node, node); | 160 | ACPI_FUNCTION_TRACE_PTR(ns_remove_node, node); |
110 | 161 | ||
111 | parent_node = acpi_ns_get_parent_node(node); | 162 | parent_node = acpi_ns_get_parent_node(node); |
112 | 163 | ||
@@ -142,12 +193,9 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node) | |||
142 | } | 193 | } |
143 | } | 194 | } |
144 | 195 | ||
145 | ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); | 196 | /* Delete the node and any attached objects */ |
146 | |||
147 | /* Detach an object if there is one, then delete the node */ | ||
148 | 197 | ||
149 | acpi_ns_detach_object(node); | 198 | acpi_ns_delete_node(node); |
150 | (void)acpi_os_release_object(acpi_gbl_namespace_cache, node); | ||
151 | return_VOID; | 199 | return_VOID; |
152 | } | 200 | } |
153 | 201 | ||
@@ -273,25 +321,11 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) | |||
273 | parent_node, child_node)); | 321 | parent_node, child_node)); |
274 | } | 322 | } |
275 | 323 | ||
276 | /* Now we can free this child object */ | 324 | /* |
277 | 325 | * Delete this child node and move on to the next child in the list. | |
278 | ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); | 326 | * No need to unlink the node since we are deleting the entire branch. |
279 | 327 | */ | |
280 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | 328 | acpi_ns_delete_node(child_node); |
281 | "Object %p, Remaining %X\n", child_node, | ||
282 | acpi_gbl_current_node_count)); | ||
283 | |||
284 | /* Detach an object if there is one, then free the child node */ | ||
285 | |||
286 | acpi_ns_detach_object(child_node); | ||
287 | |||
288 | /* Now we can delete the node */ | ||
289 | |||
290 | (void)acpi_os_release_object(acpi_gbl_namespace_cache, | ||
291 | child_node); | ||
292 | |||
293 | /* And move on to the next child in the list */ | ||
294 | |||
295 | child_node = next_node; | 329 | child_node = next_node; |
296 | 330 | ||
297 | } while (!(flags & ANOBJ_END_OF_PEER_LIST)); | 331 | } while (!(flags & ANOBJ_END_OF_PEER_LIST)); |
@@ -433,7 +467,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id) | |||
433 | 467 | ||
434 | if (deletion_node) { | 468 | if (deletion_node) { |
435 | acpi_ns_delete_children(deletion_node); | 469 | acpi_ns_delete_children(deletion_node); |
436 | acpi_ns_delete_node(deletion_node); | 470 | acpi_ns_remove_node(deletion_node); |
437 | deletion_node = NULL; | 471 | deletion_node = NULL; |
438 | } | 472 | } |
439 | 473 | ||
diff --git a/drivers/acpi/acpica/nsdumpdv.c b/drivers/acpi/acpica/nsdumpdv.c index 41994fe7fbb8..0fe87f1aef16 100644 --- a/drivers/acpi/acpica/nsdumpdv.c +++ b/drivers/acpi/acpica/nsdumpdv.c | |||
@@ -70,7 +70,6 @@ static acpi_status | |||
70 | acpi_ns_dump_one_device(acpi_handle obj_handle, | 70 | acpi_ns_dump_one_device(acpi_handle obj_handle, |
71 | u32 level, void *context, void **return_value) | 71 | u32 level, void *context, void **return_value) |
72 | { | 72 | { |
73 | struct acpi_buffer buffer; | ||
74 | struct acpi_device_info *info; | 73 | struct acpi_device_info *info; |
75 | acpi_status status; | 74 | acpi_status status; |
76 | u32 i; | 75 | u32 i; |
@@ -80,17 +79,15 @@ acpi_ns_dump_one_device(acpi_handle obj_handle, | |||
80 | status = | 79 | status = |
81 | acpi_ns_dump_one_object(obj_handle, level, context, return_value); | 80 | acpi_ns_dump_one_object(obj_handle, level, context, return_value); |
82 | 81 | ||
83 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | 82 | status = acpi_get_object_info(obj_handle, &info); |
84 | status = acpi_get_object_info(obj_handle, &buffer); | ||
85 | if (ACPI_SUCCESS(status)) { | 83 | if (ACPI_SUCCESS(status)) { |
86 | info = buffer.pointer; | ||
87 | for (i = 0; i < level; i++) { | 84 | for (i = 0; i < level; i++) { |
88 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, " ")); | 85 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, " ")); |
89 | } | 86 | } |
90 | 87 | ||
91 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, | 88 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, |
92 | " HID: %s, ADR: %8.8X%8.8X, Status: %X\n", | 89 | " HID: %s, ADR: %8.8X%8.8X, Status: %X\n", |
93 | info->hardware_id.value, | 90 | info->hardware_id.string, |
94 | ACPI_FORMAT_UINT64(info->address), | 91 | ACPI_FORMAT_UINT64(info->address), |
95 | info->current_status)); | 92 | info->current_status)); |
96 | ACPI_FREE(info); | 93 | ACPI_FREE(info); |
diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c index 8e7dec1176c9..846d1132feb1 100644 --- a/drivers/acpi/acpica/nseval.c +++ b/drivers/acpi/acpica/nseval.c | |||
@@ -50,6 +50,11 @@ | |||
50 | #define _COMPONENT ACPI_NAMESPACE | 50 | #define _COMPONENT ACPI_NAMESPACE |
51 | ACPI_MODULE_NAME("nseval") | 51 | ACPI_MODULE_NAME("nseval") |
52 | 52 | ||
53 | /* Local prototypes */ | ||
54 | static void | ||
55 | acpi_ns_exec_module_code(union acpi_operand_object *method_obj, | ||
56 | struct acpi_evaluate_info *info); | ||
57 | |||
53 | /******************************************************************************* | 58 | /******************************************************************************* |
54 | * | 59 | * |
55 | * FUNCTION: acpi_ns_evaluate | 60 | * FUNCTION: acpi_ns_evaluate |
@@ -76,6 +81,7 @@ ACPI_MODULE_NAME("nseval") | |||
76 | * MUTEX: Locks interpreter | 81 | * MUTEX: Locks interpreter |
77 | * | 82 | * |
78 | ******************************************************************************/ | 83 | ******************************************************************************/ |
84 | |||
79 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | 85 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) |
80 | { | 86 | { |
81 | acpi_status status; | 87 | acpi_status status; |
@@ -276,3 +282,134 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | |||
276 | */ | 282 | */ |
277 | return_ACPI_STATUS(status); | 283 | return_ACPI_STATUS(status); |
278 | } | 284 | } |
285 | |||
286 | /******************************************************************************* | ||
287 | * | ||
288 | * FUNCTION: acpi_ns_exec_module_code_list | ||
289 | * | ||
290 | * PARAMETERS: None | ||
291 | * | ||
292 | * RETURN: None. Exceptions during method execution are ignored, since | ||
293 | * we cannot abort a table load. | ||
294 | * | ||
295 | * DESCRIPTION: Execute all elements of the global module-level code list. | ||
296 | * Each element is executed as a single control method. | ||
297 | * | ||
298 | ******************************************************************************/ | ||
299 | |||
300 | void acpi_ns_exec_module_code_list(void) | ||
301 | { | ||
302 | union acpi_operand_object *prev; | ||
303 | union acpi_operand_object *next; | ||
304 | struct acpi_evaluate_info *info; | ||
305 | u32 method_count = 0; | ||
306 | |||
307 | ACPI_FUNCTION_TRACE(ns_exec_module_code_list); | ||
308 | |||
309 | /* Exit now if the list is empty */ | ||
310 | |||
311 | next = acpi_gbl_module_code_list; | ||
312 | if (!next) { | ||
313 | return_VOID; | ||
314 | } | ||
315 | |||
316 | /* Allocate the evaluation information block */ | ||
317 | |||
318 | info = ACPI_ALLOCATE(sizeof(struct acpi_evaluate_info)); | ||
319 | if (!info) { | ||
320 | return_VOID; | ||
321 | } | ||
322 | |||
323 | /* Walk the list, executing each "method" */ | ||
324 | |||
325 | while (next) { | ||
326 | prev = next; | ||
327 | next = next->method.mutex; | ||
328 | |||
329 | /* Clear the link field and execute the method */ | ||
330 | |||
331 | prev->method.mutex = NULL; | ||
332 | acpi_ns_exec_module_code(prev, info); | ||
333 | method_count++; | ||
334 | |||
335 | /* Delete the (temporary) method object */ | ||
336 | |||
337 | acpi_ut_remove_reference(prev); | ||
338 | } | ||
339 | |||
340 | ACPI_INFO((AE_INFO, | ||
341 | "Executed %u blocks of module-level executable AML code", | ||
342 | method_count)); | ||
343 | |||
344 | ACPI_FREE(info); | ||
345 | acpi_gbl_module_code_list = NULL; | ||
346 | return_VOID; | ||
347 | } | ||
348 | |||
349 | /******************************************************************************* | ||
350 | * | ||
351 | * FUNCTION: acpi_ns_exec_module_code | ||
352 | * | ||
353 | * PARAMETERS: method_obj - Object container for the module-level code | ||
354 | * Info - Info block for method evaluation | ||
355 | * | ||
356 | * RETURN: None. Exceptions during method execution are ignored, since | ||
357 | * we cannot abort a table load. | ||
358 | * | ||
359 | * DESCRIPTION: Execute a control method containing a block of module-level | ||
360 | * executable AML code. The control method is temporarily | ||
361 | * installed to the root node, then evaluated. | ||
362 | * | ||
363 | ******************************************************************************/ | ||
364 | |||
365 | static void | ||
366 | acpi_ns_exec_module_code(union acpi_operand_object *method_obj, | ||
367 | struct acpi_evaluate_info *info) | ||
368 | { | ||
369 | union acpi_operand_object *root_obj; | ||
370 | acpi_status status; | ||
371 | |||
372 | ACPI_FUNCTION_TRACE(ns_exec_module_code); | ||
373 | |||
374 | /* Initialize the evaluation information block */ | ||
375 | |||
376 | ACPI_MEMSET(info, 0, sizeof(struct acpi_evaluate_info)); | ||
377 | info->prefix_node = acpi_gbl_root_node; | ||
378 | |||
379 | /* | ||
380 | * Get the currently attached root object. Add a reference, because the | ||
381 | * ref count will be decreased when the method object is installed to | ||
382 | * the root node. | ||
383 | */ | ||
384 | root_obj = acpi_ns_get_attached_object(acpi_gbl_root_node); | ||
385 | acpi_ut_add_reference(root_obj); | ||
386 | |||
387 | /* Install the method (module-level code) in the root node */ | ||
388 | |||
389 | status = acpi_ns_attach_object(acpi_gbl_root_node, method_obj, | ||
390 | ACPI_TYPE_METHOD); | ||
391 | if (ACPI_FAILURE(status)) { | ||
392 | goto exit; | ||
393 | } | ||
394 | |||
395 | /* Execute the root node as a control method */ | ||
396 | |||
397 | status = acpi_ns_evaluate(info); | ||
398 | |||
399 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, "Executed module-level code at %p\n", | ||
400 | method_obj->method.aml_start)); | ||
401 | |||
402 | /* Detach the temporary method object */ | ||
403 | |||
404 | acpi_ns_detach_object(acpi_gbl_root_node); | ||
405 | |||
406 | /* Restore the original root object */ | ||
407 | |||
408 | status = | ||
409 | acpi_ns_attach_object(acpi_gbl_root_node, root_obj, | ||
410 | ACPI_TYPE_DEVICE); | ||
411 | |||
412 | exit: | ||
413 | acpi_ut_remove_reference(root_obj); | ||
414 | return_VOID; | ||
415 | } | ||
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 2adfcf329e15..1d5b360eb25b 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c | |||
@@ -170,6 +170,21 @@ acpi_status acpi_ns_initialize_devices(void) | |||
170 | goto error_exit; | 170 | goto error_exit; |
171 | } | 171 | } |
172 | 172 | ||
173 | /* | ||
174 | * Execute the "global" _INI method that may appear at the root. This | ||
175 | * support is provided for Windows compatibility (Vista+) and is not | ||
176 | * part of the ACPI specification. | ||
177 | */ | ||
178 | info.evaluate_info->prefix_node = acpi_gbl_root_node; | ||
179 | info.evaluate_info->pathname = METHOD_NAME__INI; | ||
180 | info.evaluate_info->parameters = NULL; | ||
181 | info.evaluate_info->flags = ACPI_IGNORE_RETURN_VALUE; | ||
182 | |||
183 | status = acpi_ns_evaluate(info.evaluate_info); | ||
184 | if (ACPI_SUCCESS(status)) { | ||
185 | info.num_INI++; | ||
186 | } | ||
187 | |||
173 | /* Walk namespace to execute all _INIs on present devices */ | 188 | /* Walk namespace to execute all _INIs on present devices */ |
174 | 189 | ||
175 | status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | 190 | status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, |
diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c index dcd7a6adbbbc..a7234e60e985 100644 --- a/drivers/acpi/acpica/nsload.c +++ b/drivers/acpi/acpica/nsload.c | |||
@@ -270,8 +270,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle) | |||
270 | 270 | ||
271 | /* Now delete the starting object, and we are done */ | 271 | /* Now delete the starting object, and we are done */ |
272 | 272 | ||
273 | acpi_ns_delete_node(child_handle); | 273 | acpi_ns_remove_node(child_handle); |
274 | |||
275 | return_ACPI_STATUS(AE_OK); | 274 | return_ACPI_STATUS(AE_OK); |
276 | } | 275 | } |
277 | 276 | ||
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 7f8e066b12a3..f8427afeebdf 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c | |||
@@ -42,6 +42,8 @@ | |||
42 | * POSSIBILITY OF SUCH DAMAGES. | 42 | * POSSIBILITY OF SUCH DAMAGES. |
43 | */ | 43 | */ |
44 | 44 | ||
45 | #define ACPI_CREATE_PREDEFINED_TABLE | ||
46 | |||
45 | #include <acpi/acpi.h> | 47 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 48 | #include "accommon.h" |
47 | #include "acnamesp.h" | 49 | #include "acnamesp.h" |
@@ -72,30 +74,31 @@ ACPI_MODULE_NAME("nspredef") | |||
72 | ******************************************************************************/ | 74 | ******************************************************************************/ |
73 | /* Local prototypes */ | 75 | /* Local prototypes */ |
74 | static acpi_status | 76 | static acpi_status |
75 | acpi_ns_check_package(char *pathname, | 77 | acpi_ns_check_package(struct acpi_predefined_data *data, |
76 | union acpi_operand_object **return_object_ptr, | 78 | union acpi_operand_object **return_object_ptr); |
77 | const union acpi_predefined_info *predefined); | 79 | |
80 | static acpi_status | ||
81 | acpi_ns_check_package_list(struct acpi_predefined_data *data, | ||
82 | const union acpi_predefined_info *package, | ||
83 | union acpi_operand_object **elements, u32 count); | ||
78 | 84 | ||
79 | static acpi_status | 85 | static acpi_status |
80 | acpi_ns_check_package_elements(char *pathname, | 86 | acpi_ns_check_package_elements(struct acpi_predefined_data *data, |
81 | union acpi_operand_object **elements, | 87 | union acpi_operand_object **elements, |
82 | u8 type1, | 88 | u8 type1, |
83 | u32 count1, | 89 | u32 count1, |
84 | u8 type2, u32 count2, u32 start_index); | 90 | u8 type2, u32 count2, u32 start_index); |
85 | 91 | ||
86 | static acpi_status | 92 | static acpi_status |
87 | acpi_ns_check_object_type(char *pathname, | 93 | acpi_ns_check_object_type(struct acpi_predefined_data *data, |
88 | union acpi_operand_object **return_object_ptr, | 94 | union acpi_operand_object **return_object_ptr, |
89 | u32 expected_btypes, u32 package_index); | 95 | u32 expected_btypes, u32 package_index); |
90 | 96 | ||
91 | static acpi_status | 97 | static acpi_status |
92 | acpi_ns_check_reference(char *pathname, | 98 | acpi_ns_check_reference(struct acpi_predefined_data *data, |
93 | union acpi_operand_object *return_object); | 99 | union acpi_operand_object *return_object); |
94 | 100 | ||
95 | static acpi_status | 101 | static void acpi_ns_get_expected_types(char *buffer, u32 expected_btypes); |
96 | acpi_ns_repair_object(u32 expected_btypes, | ||
97 | u32 package_index, | ||
98 | union acpi_operand_object **return_object_ptr); | ||
99 | 102 | ||
100 | /* | 103 | /* |
101 | * Names for the types that can be returned by the predefined objects. | 104 | * Names for the types that can be returned by the predefined objects. |
@@ -109,13 +112,13 @@ static const char *acpi_rtype_names[] = { | |||
109 | "/Reference", | 112 | "/Reference", |
110 | }; | 113 | }; |
111 | 114 | ||
112 | #define ACPI_NOT_PACKAGE ACPI_UINT32_MAX | ||
113 | |||
114 | /******************************************************************************* | 115 | /******************************************************************************* |
115 | * | 116 | * |
116 | * FUNCTION: acpi_ns_check_predefined_names | 117 | * FUNCTION: acpi_ns_check_predefined_names |
117 | * | 118 | * |
118 | * PARAMETERS: Node - Namespace node for the method/object | 119 | * PARAMETERS: Node - Namespace node for the method/object |
120 | * user_param_count - Number of parameters actually passed | ||
121 | * return_status - Status from the object evaluation | ||
119 | * return_object_ptr - Pointer to the object returned from the | 122 | * return_object_ptr - Pointer to the object returned from the |
120 | * evaluation of a method or object | 123 | * evaluation of a method or object |
121 | * | 124 | * |
@@ -135,12 +138,13 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, | |||
135 | acpi_status status = AE_OK; | 138 | acpi_status status = AE_OK; |
136 | const union acpi_predefined_info *predefined; | 139 | const union acpi_predefined_info *predefined; |
137 | char *pathname; | 140 | char *pathname; |
141 | struct acpi_predefined_data *data; | ||
138 | 142 | ||
139 | /* Match the name for this method/object against the predefined list */ | 143 | /* Match the name for this method/object against the predefined list */ |
140 | 144 | ||
141 | predefined = acpi_ns_check_for_predefined_name(node); | 145 | predefined = acpi_ns_check_for_predefined_name(node); |
142 | 146 | ||
143 | /* Get the full pathname to the object, for use in error messages */ | 147 | /* Get the full pathname to the object, for use in warning messages */ |
144 | 148 | ||
145 | pathname = acpi_ns_get_external_pathname(node); | 149 | pathname = acpi_ns_get_external_pathname(node); |
146 | if (!pathname) { | 150 | if (!pathname) { |
@@ -158,28 +162,17 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, | |||
158 | /* If not a predefined name, we cannot validate the return object */ | 162 | /* If not a predefined name, we cannot validate the return object */ |
159 | 163 | ||
160 | if (!predefined) { | 164 | if (!predefined) { |
161 | goto exit; | 165 | goto cleanup; |
162 | } | ||
163 | |||
164 | /* If the method failed, we cannot validate the return object */ | ||
165 | |||
166 | if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) { | ||
167 | goto exit; | ||
168 | } | 166 | } |
169 | 167 | ||
170 | /* | 168 | /* |
171 | * Only validate the return value on the first successful evaluation of | 169 | * If the method failed or did not actually return an object, we cannot |
172 | * the method. This ensures that any warnings will only be emitted during | 170 | * validate the return object |
173 | * the very first evaluation of the method/object. | ||
174 | */ | 171 | */ |
175 | if (node->flags & ANOBJ_EVALUATED) { | 172 | if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) { |
176 | goto exit; | 173 | goto cleanup; |
177 | } | 174 | } |
178 | 175 | ||
179 | /* Mark the node as having been successfully evaluated */ | ||
180 | |||
181 | node->flags |= ANOBJ_EVALUATED; | ||
182 | |||
183 | /* | 176 | /* |
184 | * If there is no return value, check if we require a return value for | 177 | * If there is no return value, check if we require a return value for |
185 | * this predefined name. Either one return value is expected, or none, | 178 | * this predefined name. Either one return value is expected, or none, |
@@ -190,46 +183,67 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, | |||
190 | if (!return_object) { | 183 | if (!return_object) { |
191 | if ((predefined->info.expected_btypes) && | 184 | if ((predefined->info.expected_btypes) && |
192 | (!(predefined->info.expected_btypes & ACPI_RTYPE_NONE))) { | 185 | (!(predefined->info.expected_btypes & ACPI_RTYPE_NONE))) { |
193 | ACPI_ERROR((AE_INFO, | 186 | ACPI_WARN_PREDEFINED((AE_INFO, pathname, |
194 | "%s: Missing expected return value", | 187 | ACPI_WARN_ALWAYS, |
195 | pathname)); | 188 | "Missing expected return value")); |
196 | 189 | ||
197 | status = AE_AML_NO_RETURN_VALUE; | 190 | status = AE_AML_NO_RETURN_VALUE; |
198 | } | 191 | } |
199 | goto exit; | 192 | goto cleanup; |
200 | } | 193 | } |
201 | 194 | ||
202 | /* | 195 | /* |
203 | * We have a return value, but if one wasn't expected, just exit, this is | 196 | * 1) We have a return value, but if one wasn't expected, just exit, this is |
204 | * not a problem | 197 | * not a problem. For example, if the "Implicit Return" feature is |
198 | * enabled, methods will always return a value. | ||
205 | * | 199 | * |
206 | * For example, if the "Implicit Return" feature is enabled, methods will | 200 | * 2) If the return value can be of any type, then we cannot perform any |
207 | * always return a value | 201 | * validation, exit. |
208 | */ | 202 | */ |
209 | if (!predefined->info.expected_btypes) { | 203 | if ((!predefined->info.expected_btypes) || |
210 | goto exit; | 204 | (predefined->info.expected_btypes == ACPI_RTYPE_ALL)) { |
205 | goto cleanup; | ||
211 | } | 206 | } |
212 | 207 | ||
208 | /* Create the parameter data block for object validation */ | ||
209 | |||
210 | data = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_predefined_data)); | ||
211 | if (!data) { | ||
212 | goto cleanup; | ||
213 | } | ||
214 | data->predefined = predefined; | ||
215 | data->node_flags = node->flags; | ||
216 | data->pathname = pathname; | ||
217 | |||
213 | /* | 218 | /* |
214 | * Check that the type of the return object is what is expected for | 219 | * Check that the type of the return object is what is expected for |
215 | * this predefined name | 220 | * this predefined name |
216 | */ | 221 | */ |
217 | status = acpi_ns_check_object_type(pathname, return_object_ptr, | 222 | status = acpi_ns_check_object_type(data, return_object_ptr, |
218 | predefined->info.expected_btypes, | 223 | predefined->info.expected_btypes, |
219 | ACPI_NOT_PACKAGE); | 224 | ACPI_NOT_PACKAGE_ELEMENT); |
220 | if (ACPI_FAILURE(status)) { | 225 | if (ACPI_FAILURE(status)) { |
221 | goto exit; | 226 | goto check_validation_status; |
222 | } | 227 | } |
223 | 228 | ||
224 | /* For returned Package objects, check the type of all sub-objects */ | 229 | /* For returned Package objects, check the type of all sub-objects */ |
225 | 230 | ||
226 | if (return_object->common.type == ACPI_TYPE_PACKAGE) { | 231 | if (return_object->common.type == ACPI_TYPE_PACKAGE) { |
227 | status = | 232 | status = acpi_ns_check_package(data, return_object_ptr); |
228 | acpi_ns_check_package(pathname, return_object_ptr, | 233 | } |
229 | predefined); | 234 | |
235 | check_validation_status: | ||
236 | /* | ||
237 | * If the object validation failed or if we successfully repaired one | ||
238 | * or more objects, mark the parent node to suppress further warning | ||
239 | * messages during the next evaluation of the same method/object. | ||
240 | */ | ||
241 | if (ACPI_FAILURE(status) || (data->flags & ACPI_OBJECT_REPAIRED)) { | ||
242 | node->flags |= ANOBJ_EVALUATED; | ||
230 | } | 243 | } |
244 | ACPI_FREE(data); | ||
231 | 245 | ||
232 | exit: | 246 | cleanup: |
233 | ACPI_FREE(pathname); | 247 | ACPI_FREE(pathname); |
234 | return (status); | 248 | return (status); |
235 | } | 249 | } |
@@ -268,64 +282,58 @@ acpi_ns_check_parameter_count(char *pathname, | |||
268 | param_count = node->object->method.param_count; | 282 | param_count = node->object->method.param_count; |
269 | } | 283 | } |
270 | 284 | ||
271 | /* Argument count check for non-predefined methods/objects */ | ||
272 | |||
273 | if (!predefined) { | 285 | if (!predefined) { |
274 | /* | 286 | /* |
287 | * Check the parameter count for non-predefined methods/objects. | ||
288 | * | ||
275 | * Warning if too few or too many arguments have been passed by the | 289 | * Warning if too few or too many arguments have been passed by the |
276 | * caller. An incorrect number of arguments may not cause the method | 290 | * caller. An incorrect number of arguments may not cause the method |
277 | * to fail. However, the method will fail if there are too few | 291 | * to fail. However, the method will fail if there are too few |
278 | * arguments and the method attempts to use one of the missing ones. | 292 | * arguments and the method attempts to use one of the missing ones. |
279 | */ | 293 | */ |
280 | if (user_param_count < param_count) { | 294 | if (user_param_count < param_count) { |
281 | ACPI_WARNING((AE_INFO, | 295 | ACPI_WARN_PREDEFINED((AE_INFO, pathname, |
282 | "%s: Insufficient arguments - needs %d, found %d", | 296 | ACPI_WARN_ALWAYS, |
283 | pathname, param_count, user_param_count)); | 297 | "Insufficient arguments - needs %u, found %u", |
298 | param_count, user_param_count)); | ||
284 | } else if (user_param_count > param_count) { | 299 | } else if (user_param_count > param_count) { |
285 | ACPI_WARNING((AE_INFO, | 300 | ACPI_WARN_PREDEFINED((AE_INFO, pathname, |
286 | "%s: Excess arguments - needs %d, found %d", | 301 | ACPI_WARN_ALWAYS, |
287 | pathname, param_count, user_param_count)); | 302 | "Excess arguments - needs %u, found %u", |
303 | param_count, user_param_count)); | ||
288 | } | 304 | } |
289 | return; | 305 | return; |
290 | } | 306 | } |
291 | 307 | ||
292 | /* Allow two different legal argument counts (_SCP, etc.) */ | 308 | /* |
293 | 309 | * Validate the user-supplied parameter count. | |
310 | * Allow two different legal argument counts (_SCP, etc.) | ||
311 | */ | ||
294 | required_params_current = predefined->info.param_count & 0x0F; | 312 | required_params_current = predefined->info.param_count & 0x0F; |
295 | required_params_old = predefined->info.param_count >> 4; | 313 | required_params_old = predefined->info.param_count >> 4; |
296 | 314 | ||
297 | if (user_param_count != ACPI_UINT32_MAX) { | 315 | if (user_param_count != ACPI_UINT32_MAX) { |
298 | |||
299 | /* Validate the user-supplied parameter count */ | ||
300 | |||
301 | if ((user_param_count != required_params_current) && | 316 | if ((user_param_count != required_params_current) && |
302 | (user_param_count != required_params_old)) { | 317 | (user_param_count != required_params_old)) { |
303 | ACPI_WARNING((AE_INFO, | 318 | ACPI_WARN_PREDEFINED((AE_INFO, pathname, |
304 | "%s: Parameter count mismatch - " | 319 | ACPI_WARN_ALWAYS, |
305 | "caller passed %d, ACPI requires %d", | 320 | "Parameter count mismatch - " |
306 | pathname, user_param_count, | 321 | "caller passed %u, ACPI requires %u", |
307 | required_params_current)); | 322 | user_param_count, |
323 | required_params_current)); | ||
308 | } | 324 | } |
309 | } | 325 | } |
310 | 326 | ||
311 | /* | 327 | /* |
312 | * Only validate the argument count on the first successful evaluation of | ||
313 | * the method. This ensures that any warnings will only be emitted during | ||
314 | * the very first evaluation of the method/object. | ||
315 | */ | ||
316 | if (node->flags & ANOBJ_EVALUATED) { | ||
317 | return; | ||
318 | } | ||
319 | |||
320 | /* | ||
321 | * Check that the ASL-defined parameter count is what is expected for | 328 | * Check that the ASL-defined parameter count is what is expected for |
322 | * this predefined name. | 329 | * this predefined name (parameter count as defined by the ACPI |
330 | * specification) | ||
323 | */ | 331 | */ |
324 | if ((param_count != required_params_current) && | 332 | if ((param_count != required_params_current) && |
325 | (param_count != required_params_old)) { | 333 | (param_count != required_params_old)) { |
326 | ACPI_WARNING((AE_INFO, | 334 | ACPI_WARN_PREDEFINED((AE_INFO, pathname, node->flags, |
327 | "%s: Parameter count mismatch - ASL declared %d, ACPI requires %d", | 335 | "Parameter count mismatch - ASL declared %u, ACPI requires %u", |
328 | pathname, param_count, required_params_current)); | 336 | param_count, required_params_current)); |
329 | } | 337 | } |
330 | } | 338 | } |
331 | 339 | ||
@@ -358,9 +366,6 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct | |||
358 | this_name = predefined_names; | 366 | this_name = predefined_names; |
359 | while (this_name->info.name[0]) { | 367 | while (this_name->info.name[0]) { |
360 | if (ACPI_COMPARE_NAME(node->name.ascii, this_name->info.name)) { | 368 | if (ACPI_COMPARE_NAME(node->name.ascii, this_name->info.name)) { |
361 | |||
362 | /* Return pointer to this table entry */ | ||
363 | |||
364 | return (this_name); | 369 | return (this_name); |
365 | } | 370 | } |
366 | 371 | ||
@@ -375,17 +380,16 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct | |||
375 | this_name++; | 380 | this_name++; |
376 | } | 381 | } |
377 | 382 | ||
378 | return (NULL); | 383 | return (NULL); /* Not found */ |
379 | } | 384 | } |
380 | 385 | ||
381 | /******************************************************************************* | 386 | /******************************************************************************* |
382 | * | 387 | * |
383 | * FUNCTION: acpi_ns_check_package | 388 | * FUNCTION: acpi_ns_check_package |
384 | * | 389 | * |
385 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | 390 | * PARAMETERS: Data - Pointer to validation data structure |
386 | * return_object_ptr - Pointer to the object returned from the | 391 | * return_object_ptr - Pointer to the object returned from the |
387 | * evaluation of a method or object | 392 | * evaluation of a method or object |
388 | * Predefined - Pointer to entry in predefined name table | ||
389 | * | 393 | * |
390 | * RETURN: Status | 394 | * RETURN: Status |
391 | * | 395 | * |
@@ -395,30 +399,26 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct | |||
395 | ******************************************************************************/ | 399 | ******************************************************************************/ |
396 | 400 | ||
397 | static acpi_status | 401 | static acpi_status |
398 | acpi_ns_check_package(char *pathname, | 402 | acpi_ns_check_package(struct acpi_predefined_data *data, |
399 | union acpi_operand_object **return_object_ptr, | 403 | union acpi_operand_object **return_object_ptr) |
400 | const union acpi_predefined_info *predefined) | ||
401 | { | 404 | { |
402 | union acpi_operand_object *return_object = *return_object_ptr; | 405 | union acpi_operand_object *return_object = *return_object_ptr; |
403 | const union acpi_predefined_info *package; | 406 | const union acpi_predefined_info *package; |
404 | union acpi_operand_object *sub_package; | ||
405 | union acpi_operand_object **elements; | 407 | union acpi_operand_object **elements; |
406 | union acpi_operand_object **sub_elements; | 408 | acpi_status status = AE_OK; |
407 | acpi_status status; | ||
408 | u32 expected_count; | 409 | u32 expected_count; |
409 | u32 count; | 410 | u32 count; |
410 | u32 i; | 411 | u32 i; |
411 | u32 j; | ||
412 | 412 | ||
413 | ACPI_FUNCTION_NAME(ns_check_package); | 413 | ACPI_FUNCTION_NAME(ns_check_package); |
414 | 414 | ||
415 | /* The package info for this name is in the next table entry */ | 415 | /* The package info for this name is in the next table entry */ |
416 | 416 | ||
417 | package = predefined + 1; | 417 | package = data->predefined + 1; |
418 | 418 | ||
419 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | 419 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, |
420 | "%s Validating return Package of Type %X, Count %X\n", | 420 | "%s Validating return Package of Type %X, Count %X\n", |
421 | pathname, package->ret_info.type, | 421 | data->pathname, package->ret_info.type, |
422 | return_object->package.count)); | 422 | return_object->package.count)); |
423 | 423 | ||
424 | /* Extract package count and elements array */ | 424 | /* Extract package count and elements array */ |
@@ -429,9 +429,8 @@ acpi_ns_check_package(char *pathname, | |||
429 | /* The package must have at least one element, else invalid */ | 429 | /* The package must have at least one element, else invalid */ |
430 | 430 | ||
431 | if (!count) { | 431 | if (!count) { |
432 | ACPI_WARNING((AE_INFO, | 432 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
433 | "%s: Return Package has no elements (empty)", | 433 | "Return Package has no elements (empty)")); |
434 | pathname)); | ||
435 | 434 | ||
436 | return (AE_AML_OPERAND_VALUE); | 435 | return (AE_AML_OPERAND_VALUE); |
437 | } | 436 | } |
@@ -456,15 +455,16 @@ acpi_ns_check_package(char *pathname, | |||
456 | if (count < expected_count) { | 455 | if (count < expected_count) { |
457 | goto package_too_small; | 456 | goto package_too_small; |
458 | } else if (count > expected_count) { | 457 | } else if (count > expected_count) { |
459 | ACPI_WARNING((AE_INFO, | 458 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, |
460 | "%s: Return Package is larger than needed - " | 459 | data->node_flags, |
461 | "found %u, expected %u", pathname, count, | 460 | "Return Package is larger than needed - " |
462 | expected_count)); | 461 | "found %u, expected %u", count, |
462 | expected_count)); | ||
463 | } | 463 | } |
464 | 464 | ||
465 | /* Validate all elements of the returned package */ | 465 | /* Validate all elements of the returned package */ |
466 | 466 | ||
467 | status = acpi_ns_check_package_elements(pathname, elements, | 467 | status = acpi_ns_check_package_elements(data, elements, |
468 | package->ret_info. | 468 | package->ret_info. |
469 | object_type1, | 469 | object_type1, |
470 | package->ret_info. | 470 | package->ret_info. |
@@ -473,9 +473,6 @@ acpi_ns_check_package(char *pathname, | |||
473 | object_type2, | 473 | object_type2, |
474 | package->ret_info. | 474 | package->ret_info. |
475 | count2, 0); | 475 | count2, 0); |
476 | if (ACPI_FAILURE(status)) { | ||
477 | return (status); | ||
478 | } | ||
479 | break; | 476 | break; |
480 | 477 | ||
481 | case ACPI_PTYPE1_VAR: | 478 | case ACPI_PTYPE1_VAR: |
@@ -485,7 +482,7 @@ acpi_ns_check_package(char *pathname, | |||
485 | * elements must be of the same type | 482 | * elements must be of the same type |
486 | */ | 483 | */ |
487 | for (i = 0; i < count; i++) { | 484 | for (i = 0; i < count; i++) { |
488 | status = acpi_ns_check_object_type(pathname, elements, | 485 | status = acpi_ns_check_object_type(data, elements, |
489 | package->ret_info. | 486 | package->ret_info. |
490 | object_type1, i); | 487 | object_type1, i); |
491 | if (ACPI_FAILURE(status)) { | 488 | if (ACPI_FAILURE(status)) { |
@@ -517,8 +514,7 @@ acpi_ns_check_package(char *pathname, | |||
517 | /* These are the required package elements (0, 1, or 2) */ | 514 | /* These are the required package elements (0, 1, or 2) */ |
518 | 515 | ||
519 | status = | 516 | status = |
520 | acpi_ns_check_object_type(pathname, | 517 | acpi_ns_check_object_type(data, elements, |
521 | elements, | ||
522 | package-> | 518 | package-> |
523 | ret_info3. | 519 | ret_info3. |
524 | object_type[i], | 520 | object_type[i], |
@@ -530,8 +526,7 @@ acpi_ns_check_package(char *pathname, | |||
530 | /* These are the optional package elements */ | 526 | /* These are the optional package elements */ |
531 | 527 | ||
532 | status = | 528 | status = |
533 | acpi_ns_check_object_type(pathname, | 529 | acpi_ns_check_object_type(data, elements, |
534 | elements, | ||
535 | package-> | 530 | package-> |
536 | ret_info3. | 531 | ret_info3. |
537 | tail_object_type, | 532 | tail_object_type, |
@@ -544,11 +539,30 @@ acpi_ns_check_package(char *pathname, | |||
544 | } | 539 | } |
545 | break; | 540 | break; |
546 | 541 | ||
542 | case ACPI_PTYPE2_REV_FIXED: | ||
543 | |||
544 | /* First element is the (Integer) revision */ | ||
545 | |||
546 | status = acpi_ns_check_object_type(data, elements, | ||
547 | ACPI_RTYPE_INTEGER, 0); | ||
548 | if (ACPI_FAILURE(status)) { | ||
549 | return (status); | ||
550 | } | ||
551 | |||
552 | elements++; | ||
553 | count--; | ||
554 | |||
555 | /* Examine the sub-packages */ | ||
556 | |||
557 | status = | ||
558 | acpi_ns_check_package_list(data, package, elements, count); | ||
559 | break; | ||
560 | |||
547 | case ACPI_PTYPE2_PKG_COUNT: | 561 | case ACPI_PTYPE2_PKG_COUNT: |
548 | 562 | ||
549 | /* First element is the (Integer) count of sub-packages to follow */ | 563 | /* First element is the (Integer) count of sub-packages to follow */ |
550 | 564 | ||
551 | status = acpi_ns_check_object_type(pathname, elements, | 565 | status = acpi_ns_check_object_type(data, elements, |
552 | ACPI_RTYPE_INTEGER, 0); | 566 | ACPI_RTYPE_INTEGER, 0); |
553 | if (ACPI_FAILURE(status)) { | 567 | if (ACPI_FAILURE(status)) { |
554 | return (status); | 568 | return (status); |
@@ -566,9 +580,11 @@ acpi_ns_check_package(char *pathname, | |||
566 | count = expected_count; | 580 | count = expected_count; |
567 | elements++; | 581 | elements++; |
568 | 582 | ||
569 | /* Now we can walk the sub-packages */ | 583 | /* Examine the sub-packages */ |
570 | 584 | ||
571 | /*lint -fallthrough */ | 585 | status = |
586 | acpi_ns_check_package_list(data, package, elements, count); | ||
587 | break; | ||
572 | 588 | ||
573 | case ACPI_PTYPE2: | 589 | case ACPI_PTYPE2: |
574 | case ACPI_PTYPE2_FIXED: | 590 | case ACPI_PTYPE2_FIXED: |
@@ -576,176 +592,240 @@ acpi_ns_check_package(char *pathname, | |||
576 | case ACPI_PTYPE2_COUNT: | 592 | case ACPI_PTYPE2_COUNT: |
577 | 593 | ||
578 | /* | 594 | /* |
579 | * These types all return a single package that consists of a variable | 595 | * These types all return a single Package that consists of a |
580 | * number of sub-packages | 596 | * variable number of sub-Packages. |
597 | * | ||
598 | * First, ensure that the first element is a sub-Package. If not, | ||
599 | * the BIOS may have incorrectly returned the object as a single | ||
600 | * package instead of a Package of Packages (a common error if | ||
601 | * there is only one entry). We may be able to repair this by | ||
602 | * wrapping the returned Package with a new outer Package. | ||
581 | */ | 603 | */ |
582 | for (i = 0; i < count; i++) { | 604 | if ((*elements)->common.type != ACPI_TYPE_PACKAGE) { |
583 | sub_package = *elements; | ||
584 | sub_elements = sub_package->package.elements; | ||
585 | 605 | ||
586 | /* Each sub-object must be of type Package */ | 606 | /* Create the new outer package and populate it */ |
587 | 607 | ||
588 | status = | 608 | status = |
589 | acpi_ns_check_object_type(pathname, &sub_package, | 609 | acpi_ns_repair_package_list(data, |
590 | ACPI_RTYPE_PACKAGE, i); | 610 | return_object_ptr); |
591 | if (ACPI_FAILURE(status)) { | 611 | if (ACPI_FAILURE(status)) { |
592 | return (status); | 612 | return (status); |
593 | } | 613 | } |
594 | 614 | ||
595 | /* Examine the different types of sub-packages */ | 615 | /* Update locals to point to the new package (of 1 element) */ |
596 | 616 | ||
597 | switch (package->ret_info.type) { | 617 | return_object = *return_object_ptr; |
598 | case ACPI_PTYPE2: | 618 | elements = return_object->package.elements; |
599 | case ACPI_PTYPE2_PKG_COUNT: | 619 | count = 1; |
620 | } | ||
600 | 621 | ||
601 | /* Each subpackage has a fixed number of elements */ | 622 | /* Examine the sub-packages */ |
602 | 623 | ||
603 | expected_count = | 624 | status = |
604 | package->ret_info.count1 + | 625 | acpi_ns_check_package_list(data, package, elements, count); |
605 | package->ret_info.count2; | 626 | break; |
606 | if (sub_package->package.count != | ||
607 | expected_count) { | ||
608 | count = sub_package->package.count; | ||
609 | goto package_too_small; | ||
610 | } | ||
611 | 627 | ||
612 | status = | 628 | default: |
613 | acpi_ns_check_package_elements(pathname, | ||
614 | sub_elements, | ||
615 | package-> | ||
616 | ret_info. | ||
617 | object_type1, | ||
618 | package-> | ||
619 | ret_info. | ||
620 | count1, | ||
621 | package-> | ||
622 | ret_info. | ||
623 | object_type2, | ||
624 | package-> | ||
625 | ret_info. | ||
626 | count2, 0); | ||
627 | if (ACPI_FAILURE(status)) { | ||
628 | return (status); | ||
629 | } | ||
630 | break; | ||
631 | 629 | ||
632 | case ACPI_PTYPE2_FIXED: | 630 | /* Should not get here if predefined info table is correct */ |
633 | 631 | ||
634 | /* Each sub-package has a fixed length */ | 632 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
633 | "Invalid internal return type in table entry: %X", | ||
634 | package->ret_info.type)); | ||
635 | 635 | ||
636 | expected_count = package->ret_info2.count; | 636 | return (AE_AML_INTERNAL); |
637 | if (sub_package->package.count < expected_count) { | 637 | } |
638 | count = sub_package->package.count; | ||
639 | goto package_too_small; | ||
640 | } | ||
641 | 638 | ||
642 | /* Check the type of each sub-package element */ | 639 | return (status); |
643 | 640 | ||
644 | for (j = 0; j < expected_count; j++) { | 641 | package_too_small: |
645 | status = | ||
646 | acpi_ns_check_object_type(pathname, | ||
647 | &sub_elements[j], | ||
648 | package->ret_info2.object_type[j], j); | ||
649 | if (ACPI_FAILURE(status)) { | ||
650 | return (status); | ||
651 | } | ||
652 | } | ||
653 | break; | ||
654 | 642 | ||
655 | case ACPI_PTYPE2_MIN: | 643 | /* Error exit for the case with an incorrect package count */ |
656 | 644 | ||
657 | /* Each sub-package has a variable but minimum length */ | 645 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
646 | "Return Package is too small - found %u elements, expected %u", | ||
647 | count, expected_count)); | ||
658 | 648 | ||
659 | expected_count = package->ret_info.count1; | 649 | return (AE_AML_OPERAND_VALUE); |
660 | if (sub_package->package.count < expected_count) { | 650 | } |
661 | count = sub_package->package.count; | ||
662 | goto package_too_small; | ||
663 | } | ||
664 | 651 | ||
665 | /* Check the type of each sub-package element */ | 652 | /******************************************************************************* |
653 | * | ||
654 | * FUNCTION: acpi_ns_check_package_list | ||
655 | * | ||
656 | * PARAMETERS: Data - Pointer to validation data structure | ||
657 | * Package - Pointer to package-specific info for method | ||
658 | * Elements - Element list of parent package. All elements | ||
659 | * of this list should be of type Package. | ||
660 | * Count - Count of subpackages | ||
661 | * | ||
662 | * RETURN: Status | ||
663 | * | ||
664 | * DESCRIPTION: Examine a list of subpackages | ||
665 | * | ||
666 | ******************************************************************************/ | ||
666 | 667 | ||
667 | status = | 668 | static acpi_status |
668 | acpi_ns_check_package_elements(pathname, | 669 | acpi_ns_check_package_list(struct acpi_predefined_data *data, |
669 | sub_elements, | 670 | const union acpi_predefined_info *package, |
670 | package-> | 671 | union acpi_operand_object **elements, u32 count) |
671 | ret_info. | 672 | { |
672 | object_type1, | 673 | union acpi_operand_object *sub_package; |
673 | sub_package-> | 674 | union acpi_operand_object **sub_elements; |
674 | package. | 675 | acpi_status status; |
675 | count, 0, 0, | 676 | u32 expected_count; |
676 | 0); | 677 | u32 i; |
677 | if (ACPI_FAILURE(status)) { | 678 | u32 j; |
678 | return (status); | ||
679 | } | ||
680 | break; | ||
681 | 679 | ||
682 | case ACPI_PTYPE2_COUNT: | 680 | /* Validate each sub-Package in the parent Package */ |
683 | 681 | ||
684 | /* First element is the (Integer) count of elements to follow */ | 682 | for (i = 0; i < count; i++) { |
683 | sub_package = *elements; | ||
684 | sub_elements = sub_package->package.elements; | ||
685 | 685 | ||
686 | status = | 686 | /* Each sub-object must be of type Package */ |
687 | acpi_ns_check_object_type(pathname, | ||
688 | sub_elements, | ||
689 | ACPI_RTYPE_INTEGER, | ||
690 | 0); | ||
691 | if (ACPI_FAILURE(status)) { | ||
692 | return (status); | ||
693 | } | ||
694 | 687 | ||
695 | /* Make sure package is large enough for the Count */ | 688 | status = acpi_ns_check_object_type(data, &sub_package, |
689 | ACPI_RTYPE_PACKAGE, i); | ||
690 | if (ACPI_FAILURE(status)) { | ||
691 | return (status); | ||
692 | } | ||
696 | 693 | ||
697 | expected_count = | 694 | /* Examine the different types of expected sub-packages */ |
698 | (u32) (*sub_elements)->integer.value; | 695 | |
699 | if (sub_package->package.count < expected_count) { | 696 | switch (package->ret_info.type) { |
700 | count = sub_package->package.count; | 697 | case ACPI_PTYPE2: |
701 | goto package_too_small; | 698 | case ACPI_PTYPE2_PKG_COUNT: |
702 | } | 699 | case ACPI_PTYPE2_REV_FIXED: |
700 | |||
701 | /* Each subpackage has a fixed number of elements */ | ||
702 | |||
703 | expected_count = | ||
704 | package->ret_info.count1 + package->ret_info.count2; | ||
705 | if (sub_package->package.count < expected_count) { | ||
706 | goto package_too_small; | ||
707 | } | ||
708 | |||
709 | status = | ||
710 | acpi_ns_check_package_elements(data, sub_elements, | ||
711 | package->ret_info. | ||
712 | object_type1, | ||
713 | package->ret_info. | ||
714 | count1, | ||
715 | package->ret_info. | ||
716 | object_type2, | ||
717 | package->ret_info. | ||
718 | count2, 0); | ||
719 | if (ACPI_FAILURE(status)) { | ||
720 | return (status); | ||
721 | } | ||
722 | break; | ||
703 | 723 | ||
704 | /* Check the type of each sub-package element */ | 724 | case ACPI_PTYPE2_FIXED: |
705 | 725 | ||
726 | /* Each sub-package has a fixed length */ | ||
727 | |||
728 | expected_count = package->ret_info2.count; | ||
729 | if (sub_package->package.count < expected_count) { | ||
730 | goto package_too_small; | ||
731 | } | ||
732 | |||
733 | /* Check the type of each sub-package element */ | ||
734 | |||
735 | for (j = 0; j < expected_count; j++) { | ||
706 | status = | 736 | status = |
707 | acpi_ns_check_package_elements(pathname, | 737 | acpi_ns_check_object_type(data, |
708 | (sub_elements | 738 | &sub_elements[j], |
709 | + 1), | 739 | package-> |
710 | package-> | 740 | ret_info2. |
711 | ret_info. | 741 | object_type[j], |
712 | object_type1, | 742 | j); |
713 | (expected_count | ||
714 | - 1), 0, 0, | ||
715 | 1); | ||
716 | if (ACPI_FAILURE(status)) { | 743 | if (ACPI_FAILURE(status)) { |
717 | return (status); | 744 | return (status); |
718 | } | 745 | } |
719 | break; | 746 | } |
747 | break; | ||
748 | |||
749 | case ACPI_PTYPE2_MIN: | ||
720 | 750 | ||
721 | default: | 751 | /* Each sub-package has a variable but minimum length */ |
722 | break; | 752 | |
753 | expected_count = package->ret_info.count1; | ||
754 | if (sub_package->package.count < expected_count) { | ||
755 | goto package_too_small; | ||
723 | } | 756 | } |
724 | 757 | ||
725 | elements++; | 758 | /* Check the type of each sub-package element */ |
726 | } | ||
727 | break; | ||
728 | 759 | ||
729 | default: | 760 | status = |
761 | acpi_ns_check_package_elements(data, sub_elements, | ||
762 | package->ret_info. | ||
763 | object_type1, | ||
764 | sub_package->package. | ||
765 | count, 0, 0, 0); | ||
766 | if (ACPI_FAILURE(status)) { | ||
767 | return (status); | ||
768 | } | ||
769 | break; | ||
730 | 770 | ||
731 | /* Should not get here if predefined info table is correct */ | 771 | case ACPI_PTYPE2_COUNT: |
772 | |||
773 | /* | ||
774 | * First element is the (Integer) count of elements, including | ||
775 | * the count field. | ||
776 | */ | ||
777 | status = acpi_ns_check_object_type(data, sub_elements, | ||
778 | ACPI_RTYPE_INTEGER, | ||
779 | 0); | ||
780 | if (ACPI_FAILURE(status)) { | ||
781 | return (status); | ||
782 | } | ||
732 | 783 | ||
733 | ACPI_WARNING((AE_INFO, | 784 | /* |
734 | "%s: Invalid internal return type in table entry: %X", | 785 | * Make sure package is large enough for the Count and is |
735 | pathname, package->ret_info.type)); | 786 | * is as large as the minimum size |
787 | */ | ||
788 | expected_count = (u32)(*sub_elements)->integer.value; | ||
789 | if (sub_package->package.count < expected_count) { | ||
790 | goto package_too_small; | ||
791 | } | ||
792 | if (sub_package->package.count < | ||
793 | package->ret_info.count1) { | ||
794 | expected_count = package->ret_info.count1; | ||
795 | goto package_too_small; | ||
796 | } | ||
736 | 797 | ||
737 | return (AE_AML_INTERNAL); | 798 | /* Check the type of each sub-package element */ |
799 | |||
800 | status = | ||
801 | acpi_ns_check_package_elements(data, | ||
802 | (sub_elements + 1), | ||
803 | package->ret_info. | ||
804 | object_type1, | ||
805 | (expected_count - 1), | ||
806 | 0, 0, 1); | ||
807 | if (ACPI_FAILURE(status)) { | ||
808 | return (status); | ||
809 | } | ||
810 | break; | ||
811 | |||
812 | default: /* Should not get here, type was validated by caller */ | ||
813 | |||
814 | return (AE_AML_INTERNAL); | ||
815 | } | ||
816 | |||
817 | elements++; | ||
738 | } | 818 | } |
739 | 819 | ||
740 | return (AE_OK); | 820 | return (AE_OK); |
741 | 821 | ||
742 | package_too_small: | 822 | package_too_small: |
743 | 823 | ||
744 | /* Error exit for the case with an incorrect package count */ | 824 | /* The sub-package count was smaller than required */ |
745 | 825 | ||
746 | ACPI_WARNING((AE_INFO, "%s: Return Package is too small - " | 826 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
747 | "found %u, expected %u", pathname, count, | 827 | "Return Sub-Package[%u] is too small - found %u elements, expected %u", |
748 | expected_count)); | 828 | i, sub_package->package.count, expected_count)); |
749 | 829 | ||
750 | return (AE_AML_OPERAND_VALUE); | 830 | return (AE_AML_OPERAND_VALUE); |
751 | } | 831 | } |
@@ -754,7 +834,7 @@ acpi_ns_check_package(char *pathname, | |||
754 | * | 834 | * |
755 | * FUNCTION: acpi_ns_check_package_elements | 835 | * FUNCTION: acpi_ns_check_package_elements |
756 | * | 836 | * |
757 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | 837 | * PARAMETERS: Data - Pointer to validation data structure |
758 | * Elements - Pointer to the package elements array | 838 | * Elements - Pointer to the package elements array |
759 | * Type1 - Object type for first group | 839 | * Type1 - Object type for first group |
760 | * Count1 - Count for first group | 840 | * Count1 - Count for first group |
@@ -770,7 +850,7 @@ acpi_ns_check_package(char *pathname, | |||
770 | ******************************************************************************/ | 850 | ******************************************************************************/ |
771 | 851 | ||
772 | static acpi_status | 852 | static acpi_status |
773 | acpi_ns_check_package_elements(char *pathname, | 853 | acpi_ns_check_package_elements(struct acpi_predefined_data *data, |
774 | union acpi_operand_object **elements, | 854 | union acpi_operand_object **elements, |
775 | u8 type1, | 855 | u8 type1, |
776 | u32 count1, | 856 | u32 count1, |
@@ -786,7 +866,7 @@ acpi_ns_check_package_elements(char *pathname, | |||
786 | * The second group can have a count of zero. | 866 | * The second group can have a count of zero. |
787 | */ | 867 | */ |
788 | for (i = 0; i < count1; i++) { | 868 | for (i = 0; i < count1; i++) { |
789 | status = acpi_ns_check_object_type(pathname, this_element, | 869 | status = acpi_ns_check_object_type(data, this_element, |
790 | type1, i + start_index); | 870 | type1, i + start_index); |
791 | if (ACPI_FAILURE(status)) { | 871 | if (ACPI_FAILURE(status)) { |
792 | return (status); | 872 | return (status); |
@@ -795,7 +875,7 @@ acpi_ns_check_package_elements(char *pathname, | |||
795 | } | 875 | } |
796 | 876 | ||
797 | for (i = 0; i < count2; i++) { | 877 | for (i = 0; i < count2; i++) { |
798 | status = acpi_ns_check_object_type(pathname, this_element, | 878 | status = acpi_ns_check_object_type(data, this_element, |
799 | type2, | 879 | type2, |
800 | (i + count1 + start_index)); | 880 | (i + count1 + start_index)); |
801 | if (ACPI_FAILURE(status)) { | 881 | if (ACPI_FAILURE(status)) { |
@@ -811,12 +891,13 @@ acpi_ns_check_package_elements(char *pathname, | |||
811 | * | 891 | * |
812 | * FUNCTION: acpi_ns_check_object_type | 892 | * FUNCTION: acpi_ns_check_object_type |
813 | * | 893 | * |
814 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | 894 | * PARAMETERS: Data - Pointer to validation data structure |
815 | * return_object_ptr - Pointer to the object returned from the | 895 | * return_object_ptr - Pointer to the object returned from the |
816 | * evaluation of a method or object | 896 | * evaluation of a method or object |
817 | * expected_btypes - Bitmap of expected return type(s) | 897 | * expected_btypes - Bitmap of expected return type(s) |
818 | * package_index - Index of object within parent package (if | 898 | * package_index - Index of object within parent package (if |
819 | * applicable - ACPI_NOT_PACKAGE otherwise) | 899 | * applicable - ACPI_NOT_PACKAGE_ELEMENT |
900 | * otherwise) | ||
820 | * | 901 | * |
821 | * RETURN: Status | 902 | * RETURN: Status |
822 | * | 903 | * |
@@ -826,7 +907,7 @@ acpi_ns_check_package_elements(char *pathname, | |||
826 | ******************************************************************************/ | 907 | ******************************************************************************/ |
827 | 908 | ||
828 | static acpi_status | 909 | static acpi_status |
829 | acpi_ns_check_object_type(char *pathname, | 910 | acpi_ns_check_object_type(struct acpi_predefined_data *data, |
830 | union acpi_operand_object **return_object_ptr, | 911 | union acpi_operand_object **return_object_ptr, |
831 | u32 expected_btypes, u32 package_index) | 912 | u32 expected_btypes, u32 package_index) |
832 | { | 913 | { |
@@ -834,9 +915,6 @@ acpi_ns_check_object_type(char *pathname, | |||
834 | acpi_status status = AE_OK; | 915 | acpi_status status = AE_OK; |
835 | u32 return_btype; | 916 | u32 return_btype; |
836 | char type_buffer[48]; /* Room for 5 types */ | 917 | char type_buffer[48]; /* Room for 5 types */ |
837 | u32 this_rtype; | ||
838 | u32 i; | ||
839 | u32 j; | ||
840 | 918 | ||
841 | /* | 919 | /* |
842 | * If we get a NULL return_object here, it is a NULL package element, | 920 | * If we get a NULL return_object here, it is a NULL package element, |
@@ -849,10 +927,11 @@ acpi_ns_check_object_type(char *pathname, | |||
849 | /* A Namespace node should not get here, but make sure */ | 927 | /* A Namespace node should not get here, but make sure */ |
850 | 928 | ||
851 | if (ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) { | 929 | if (ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) { |
852 | ACPI_WARNING((AE_INFO, | 930 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
853 | "%s: Invalid return type - Found a Namespace node [%4.4s] type %s", | 931 | "Invalid return type - Found a Namespace node [%4.4s] type %s", |
854 | pathname, return_object->node.name.ascii, | 932 | return_object->node.name.ascii, |
855 | acpi_ut_get_type_name(return_object->node.type))); | 933 | acpi_ut_get_type_name(return_object->node. |
934 | type))); | ||
856 | return (AE_AML_OPERAND_TYPE); | 935 | return (AE_AML_OPERAND_TYPE); |
857 | } | 936 | } |
858 | 937 | ||
@@ -897,10 +976,11 @@ acpi_ns_check_object_type(char *pathname, | |||
897 | 976 | ||
898 | /* Type mismatch -- attempt repair of the returned object */ | 977 | /* Type mismatch -- attempt repair of the returned object */ |
899 | 978 | ||
900 | status = acpi_ns_repair_object(expected_btypes, package_index, | 979 | status = acpi_ns_repair_object(data, expected_btypes, |
980 | package_index, | ||
901 | return_object_ptr); | 981 | return_object_ptr); |
902 | if (ACPI_SUCCESS(status)) { | 982 | if (ACPI_SUCCESS(status)) { |
903 | return (status); | 983 | return (AE_OK); /* Repair was successful */ |
904 | } | 984 | } |
905 | goto type_error_exit; | 985 | goto type_error_exit; |
906 | } | 986 | } |
@@ -908,7 +988,7 @@ acpi_ns_check_object_type(char *pathname, | |||
908 | /* For reference objects, check that the reference type is correct */ | 988 | /* For reference objects, check that the reference type is correct */ |
909 | 989 | ||
910 | if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) { | 990 | if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) { |
911 | status = acpi_ns_check_reference(pathname, return_object); | 991 | status = acpi_ns_check_reference(data, return_object); |
912 | } | 992 | } |
913 | 993 | ||
914 | return (status); | 994 | return (status); |
@@ -917,33 +997,19 @@ acpi_ns_check_object_type(char *pathname, | |||
917 | 997 | ||
918 | /* Create a string with all expected types for this predefined object */ | 998 | /* Create a string with all expected types for this predefined object */ |
919 | 999 | ||
920 | j = 1; | 1000 | acpi_ns_get_expected_types(type_buffer, expected_btypes); |
921 | type_buffer[0] = 0; | ||
922 | this_rtype = ACPI_RTYPE_INTEGER; | ||
923 | |||
924 | for (i = 0; i < ACPI_NUM_RTYPES; i++) { | ||
925 | |||
926 | /* If one of the expected types, concatenate the name of this type */ | ||
927 | |||
928 | if (expected_btypes & this_rtype) { | ||
929 | ACPI_STRCAT(type_buffer, &acpi_rtype_names[i][j]); | ||
930 | j = 0; /* Use name separator from now on */ | ||
931 | } | ||
932 | this_rtype <<= 1; /* Next Rtype */ | ||
933 | } | ||
934 | 1001 | ||
935 | if (package_index == ACPI_NOT_PACKAGE) { | 1002 | if (package_index == ACPI_NOT_PACKAGE_ELEMENT) { |
936 | ACPI_WARNING((AE_INFO, | 1003 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
937 | "%s: Return type mismatch - found %s, expected %s", | 1004 | "Return type mismatch - found %s, expected %s", |
938 | pathname, | 1005 | acpi_ut_get_object_type_name |
939 | acpi_ut_get_object_type_name(return_object), | 1006 | (return_object), type_buffer)); |
940 | type_buffer)); | ||
941 | } else { | 1007 | } else { |
942 | ACPI_WARNING((AE_INFO, | 1008 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
943 | "%s: Return Package type mismatch at index %u - " | 1009 | "Return Package type mismatch at index %u - " |
944 | "found %s, expected %s", pathname, package_index, | 1010 | "found %s, expected %s", package_index, |
945 | acpi_ut_get_object_type_name(return_object), | 1011 | acpi_ut_get_object_type_name |
946 | type_buffer)); | 1012 | (return_object), type_buffer)); |
947 | } | 1013 | } |
948 | 1014 | ||
949 | return (AE_AML_OPERAND_TYPE); | 1015 | return (AE_AML_OPERAND_TYPE); |
@@ -953,7 +1019,7 @@ acpi_ns_check_object_type(char *pathname, | |||
953 | * | 1019 | * |
954 | * FUNCTION: acpi_ns_check_reference | 1020 | * FUNCTION: acpi_ns_check_reference |
955 | * | 1021 | * |
956 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | 1022 | * PARAMETERS: Data - Pointer to validation data structure |
957 | * return_object - Object returned from the evaluation of a | 1023 | * return_object - Object returned from the evaluation of a |
958 | * method or object | 1024 | * method or object |
959 | * | 1025 | * |
@@ -966,7 +1032,7 @@ acpi_ns_check_object_type(char *pathname, | |||
966 | ******************************************************************************/ | 1032 | ******************************************************************************/ |
967 | 1033 | ||
968 | static acpi_status | 1034 | static acpi_status |
969 | acpi_ns_check_reference(char *pathname, | 1035 | acpi_ns_check_reference(struct acpi_predefined_data *data, |
970 | union acpi_operand_object *return_object) | 1036 | union acpi_operand_object *return_object) |
971 | { | 1037 | { |
972 | 1038 | ||
@@ -979,94 +1045,46 @@ acpi_ns_check_reference(char *pathname, | |||
979 | return (AE_OK); | 1045 | return (AE_OK); |
980 | } | 1046 | } |
981 | 1047 | ||
982 | ACPI_WARNING((AE_INFO, | 1048 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
983 | "%s: Return type mismatch - " | 1049 | "Return type mismatch - unexpected reference object type [%s] %2.2X", |
984 | "unexpected reference object type [%s] %2.2X", | 1050 | acpi_ut_get_reference_name(return_object), |
985 | pathname, acpi_ut_get_reference_name(return_object), | 1051 | return_object->reference.class)); |
986 | return_object->reference.class)); | ||
987 | 1052 | ||
988 | return (AE_AML_OPERAND_TYPE); | 1053 | return (AE_AML_OPERAND_TYPE); |
989 | } | 1054 | } |
990 | 1055 | ||
991 | /******************************************************************************* | 1056 | /******************************************************************************* |
992 | * | 1057 | * |
993 | * FUNCTION: acpi_ns_repair_object | 1058 | * FUNCTION: acpi_ns_get_expected_types |
994 | * | 1059 | * |
995 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | 1060 | * PARAMETERS: Buffer - Pointer to where the string is returned |
996 | * package_index - Used to determine if target is in a package | 1061 | * expected_btypes - Bitmap of expected return type(s) |
997 | * return_object_ptr - Pointer to the object returned from the | ||
998 | * evaluation of a method or object | ||
999 | * | 1062 | * |
1000 | * RETURN: Status. AE_OK if repair was successful. | 1063 | * RETURN: Buffer is populated with type names. |
1001 | * | 1064 | * |
1002 | * DESCRIPTION: Attempt to repair/convert a return object of a type that was | 1065 | * DESCRIPTION: Translate the expected types bitmap into a string of ascii |
1003 | * not expected. | 1066 | * names of expected types, for use in warning messages. |
1004 | * | 1067 | * |
1005 | ******************************************************************************/ | 1068 | ******************************************************************************/ |
1006 | 1069 | ||
1007 | static acpi_status | 1070 | static void acpi_ns_get_expected_types(char *buffer, u32 expected_btypes) |
1008 | acpi_ns_repair_object(u32 expected_btypes, | ||
1009 | u32 package_index, | ||
1010 | union acpi_operand_object **return_object_ptr) | ||
1011 | { | 1071 | { |
1012 | union acpi_operand_object *return_object = *return_object_ptr; | 1072 | u32 this_rtype; |
1013 | union acpi_operand_object *new_object; | 1073 | u32 i; |
1014 | acpi_size length; | 1074 | u32 j; |
1015 | |||
1016 | switch (return_object->common.type) { | ||
1017 | case ACPI_TYPE_BUFFER: | ||
1018 | |||
1019 | if (!(expected_btypes & ACPI_RTYPE_STRING)) { | ||
1020 | return (AE_AML_OPERAND_TYPE); | ||
1021 | } | ||
1022 | |||
1023 | /* | ||
1024 | * Have a Buffer, expected a String, convert. Use a to_string | ||
1025 | * conversion, no transform performed on the buffer data. The best | ||
1026 | * example of this is the _BIF method, where the string data from | ||
1027 | * the battery is often (incorrectly) returned as buffer object(s). | ||
1028 | */ | ||
1029 | length = 0; | ||
1030 | while ((length < return_object->buffer.length) && | ||
1031 | (return_object->buffer.pointer[length])) { | ||
1032 | length++; | ||
1033 | } | ||
1034 | |||
1035 | /* Allocate a new string object */ | ||
1036 | |||
1037 | new_object = acpi_ut_create_string_object(length); | ||
1038 | if (!new_object) { | ||
1039 | return (AE_NO_MEMORY); | ||
1040 | } | ||
1041 | 1075 | ||
1042 | /* | 1076 | j = 1; |
1043 | * Copy the raw buffer data with no transform. String is already NULL | 1077 | buffer[0] = 0; |
1044 | * terminated at Length+1. | 1078 | this_rtype = ACPI_RTYPE_INTEGER; |
1045 | */ | ||
1046 | ACPI_MEMCPY(new_object->string.pointer, | ||
1047 | return_object->buffer.pointer, length); | ||
1048 | 1079 | ||
1049 | /* Install the new return object */ | 1080 | for (i = 0; i < ACPI_NUM_RTYPES; i++) { |
1050 | 1081 | ||
1051 | acpi_ut_remove_reference(return_object); | 1082 | /* If one of the expected types, concatenate the name of this type */ |
1052 | *return_object_ptr = new_object; | ||
1053 | 1083 | ||
1054 | /* | 1084 | if (expected_btypes & this_rtype) { |
1055 | * If the object is a package element, we need to: | 1085 | ACPI_STRCAT(buffer, &acpi_rtype_names[i][j]); |
1056 | * 1. Decrement the reference count of the orignal object, it was | 1086 | j = 0; /* Use name separator from now on */ |
1057 | * incremented when building the package | ||
1058 | * 2. Increment the reference count of the new object, it will be | ||
1059 | * decremented when releasing the package | ||
1060 | */ | ||
1061 | if (package_index != ACPI_NOT_PACKAGE) { | ||
1062 | acpi_ut_remove_reference(return_object); | ||
1063 | acpi_ut_add_reference(new_object); | ||
1064 | } | 1087 | } |
1065 | return (AE_OK); | 1088 | this_rtype <<= 1; /* Next Rtype */ |
1066 | |||
1067 | default: | ||
1068 | break; | ||
1069 | } | 1089 | } |
1070 | |||
1071 | return (AE_AML_OPERAND_TYPE); | ||
1072 | } | 1090 | } |
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c new file mode 100644 index 000000000000..db2b2a99c3a8 --- /dev/null +++ b/drivers/acpi/acpica/nsrepair.c | |||
@@ -0,0 +1,203 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: nsrepair - Repair for objects returned by predefined methods | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2009, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acnamesp.h" | ||
47 | #include "acpredef.h" | ||
48 | |||
49 | #define _COMPONENT ACPI_NAMESPACE | ||
50 | ACPI_MODULE_NAME("nsrepair") | ||
51 | |||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_ns_repair_object | ||
55 | * | ||
56 | * PARAMETERS: Data - Pointer to validation data structure | ||
57 | * expected_btypes - Object types expected | ||
58 | * package_index - Index of object within parent package (if | ||
59 | * applicable - ACPI_NOT_PACKAGE_ELEMENT | ||
60 | * otherwise) | ||
61 | * return_object_ptr - Pointer to the object returned from the | ||
62 | * evaluation of a method or object | ||
63 | * | ||
64 | * RETURN: Status. AE_OK if repair was successful. | ||
65 | * | ||
66 | * DESCRIPTION: Attempt to repair/convert a return object of a type that was | ||
67 | * not expected. | ||
68 | * | ||
69 | ******************************************************************************/ | ||
70 | acpi_status | ||
71 | acpi_ns_repair_object(struct acpi_predefined_data *data, | ||
72 | u32 expected_btypes, | ||
73 | u32 package_index, | ||
74 | union acpi_operand_object **return_object_ptr) | ||
75 | { | ||
76 | union acpi_operand_object *return_object = *return_object_ptr; | ||
77 | union acpi_operand_object *new_object; | ||
78 | acpi_size length; | ||
79 | |||
80 | switch (return_object->common.type) { | ||
81 | case ACPI_TYPE_BUFFER: | ||
82 | |||
83 | /* Does the method/object legally return a string? */ | ||
84 | |||
85 | if (!(expected_btypes & ACPI_RTYPE_STRING)) { | ||
86 | return (AE_AML_OPERAND_TYPE); | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * Have a Buffer, expected a String, convert. Use a to_string | ||
91 | * conversion, no transform performed on the buffer data. The best | ||
92 | * example of this is the _BIF method, where the string data from | ||
93 | * the battery is often (incorrectly) returned as buffer object(s). | ||
94 | */ | ||
95 | length = 0; | ||
96 | while ((length < return_object->buffer.length) && | ||
97 | (return_object->buffer.pointer[length])) { | ||
98 | length++; | ||
99 | } | ||
100 | |||
101 | /* Allocate a new string object */ | ||
102 | |||
103 | new_object = acpi_ut_create_string_object(length); | ||
104 | if (!new_object) { | ||
105 | return (AE_NO_MEMORY); | ||
106 | } | ||
107 | |||
108 | /* | ||
109 | * Copy the raw buffer data with no transform. String is already NULL | ||
110 | * terminated at Length+1. | ||
111 | */ | ||
112 | ACPI_MEMCPY(new_object->string.pointer, | ||
113 | return_object->buffer.pointer, length); | ||
114 | |||
115 | /* | ||
116 | * If the original object is a package element, we need to: | ||
117 | * 1. Set the reference count of the new object to match the | ||
118 | * reference count of the old object. | ||
119 | * 2. Decrement the reference count of the original object. | ||
120 | */ | ||
121 | if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { | ||
122 | new_object->common.reference_count = | ||
123 | return_object->common.reference_count; | ||
124 | |||
125 | if (return_object->common.reference_count > 1) { | ||
126 | return_object->common.reference_count--; | ||
127 | } | ||
128 | |||
129 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, | ||
130 | data->node_flags, | ||
131 | "Converted Buffer to expected String at index %u", | ||
132 | package_index)); | ||
133 | } else { | ||
134 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, | ||
135 | data->node_flags, | ||
136 | "Converted Buffer to expected String")); | ||
137 | } | ||
138 | |||
139 | /* Delete old object, install the new return object */ | ||
140 | |||
141 | acpi_ut_remove_reference(return_object); | ||
142 | *return_object_ptr = new_object; | ||
143 | data->flags |= ACPI_OBJECT_REPAIRED; | ||
144 | return (AE_OK); | ||
145 | |||
146 | default: | ||
147 | break; | ||
148 | } | ||
149 | |||
150 | return (AE_AML_OPERAND_TYPE); | ||
151 | } | ||
152 | |||
153 | /******************************************************************************* | ||
154 | * | ||
155 | * FUNCTION: acpi_ns_repair_package_list | ||
156 | * | ||
157 | * PARAMETERS: Data - Pointer to validation data structure | ||
158 | * obj_desc_ptr - Pointer to the object to repair. The new | ||
159 | * package object is returned here, | ||
160 | * overwriting the old object. | ||
161 | * | ||
162 | * RETURN: Status, new object in *obj_desc_ptr | ||
163 | * | ||
164 | * DESCRIPTION: Repair a common problem with objects that are defined to return | ||
165 | * a variable-length Package of Packages. If the variable-length | ||
166 | * is one, some BIOS code mistakenly simply declares a single | ||
167 | * Package instead of a Package with one sub-Package. This | ||
168 | * function attempts to repair this error by wrapping a Package | ||
169 | * object around the original Package, creating the correct | ||
170 | * Package with one sub-Package. | ||
171 | * | ||
172 | * Names that can be repaired in this manner include: | ||
173 | * _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS | ||
174 | * | ||
175 | ******************************************************************************/ | ||
176 | |||
177 | acpi_status | ||
178 | acpi_ns_repair_package_list(struct acpi_predefined_data *data, | ||
179 | union acpi_operand_object **obj_desc_ptr) | ||
180 | { | ||
181 | union acpi_operand_object *pkg_obj_desc; | ||
182 | |||
183 | /* | ||
184 | * Create the new outer package and populate it. The new package will | ||
185 | * have a single element, the lone subpackage. | ||
186 | */ | ||
187 | pkg_obj_desc = acpi_ut_create_package_object(1); | ||
188 | if (!pkg_obj_desc) { | ||
189 | return (AE_NO_MEMORY); | ||
190 | } | ||
191 | |||
192 | pkg_obj_desc->package.elements[0] = *obj_desc_ptr; | ||
193 | |||
194 | /* Return the new object in the object pointer */ | ||
195 | |||
196 | *obj_desc_ptr = pkg_obj_desc; | ||
197 | data->flags |= ACPI_OBJECT_REPAIRED; | ||
198 | |||
199 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, | ||
200 | "Incorrectly formed Package, attempting repair")); | ||
201 | |||
202 | return (AE_OK); | ||
203 | } | ||
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index 78277ed08339..ea55ab4f9849 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c | |||
@@ -88,7 +88,8 @@ acpi_ns_report_error(const char *module_name, | |||
88 | 88 | ||
89 | /* There is a non-ascii character in the name */ | 89 | /* There is a non-ascii character in the name */ |
90 | 90 | ||
91 | ACPI_MOVE_32_TO_32(&bad_name, internal_name); | 91 | ACPI_MOVE_32_TO_32(&bad_name, |
92 | ACPI_CAST_PTR(u32, internal_name)); | ||
92 | acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name); | 93 | acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name); |
93 | } else { | 94 | } else { |
94 | /* Convert path to external format */ | 95 | /* Convert path to external format */ |
@@ -836,7 +837,7 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node, | |||
836 | acpi_status status; | 837 | acpi_status status; |
837 | char *internal_path; | 838 | char *internal_path; |
838 | 839 | ||
839 | ACPI_FUNCTION_TRACE_PTR(ns_get_node, pathname); | 840 | ACPI_FUNCTION_TRACE_PTR(ns_get_node, ACPI_CAST_PTR(char, pathname)); |
840 | 841 | ||
841 | if (!pathname) { | 842 | if (!pathname) { |
842 | *return_node = prefix_node; | 843 | *return_node = prefix_node; |
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index daf4ad37896d..4929dbdbc8f0 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c | |||
@@ -535,10 +535,11 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, | |||
535 | acpi_status status; | 535 | acpi_status status; |
536 | struct acpi_namespace_node *node; | 536 | struct acpi_namespace_node *node; |
537 | u32 flags; | 537 | u32 flags; |
538 | struct acpica_device_id hid; | 538 | struct acpica_device_id *hid; |
539 | struct acpi_compatible_id_list *cid; | 539 | struct acpica_device_id_list *cid; |
540 | u32 i; | 540 | u32 i; |
541 | int found; | 541 | u8 found; |
542 | int no_match; | ||
542 | 543 | ||
543 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | 544 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); |
544 | if (ACPI_FAILURE(status)) { | 545 | if (ACPI_FAILURE(status)) { |
@@ -582,10 +583,14 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, | |||
582 | return (AE_CTRL_DEPTH); | 583 | return (AE_CTRL_DEPTH); |
583 | } | 584 | } |
584 | 585 | ||
585 | if (ACPI_STRNCMP(hid.value, info->hid, sizeof(hid.value)) != 0) { | 586 | no_match = ACPI_STRCMP(hid->string, info->hid); |
586 | 587 | ACPI_FREE(hid); | |
587 | /* Get the list of Compatible IDs */ | ||
588 | 588 | ||
589 | if (no_match) { | ||
590 | /* | ||
591 | * HID does not match, attempt match within the | ||
592 | * list of Compatible IDs (CIDs) | ||
593 | */ | ||
589 | status = acpi_ut_execute_CID(node, &cid); | 594 | status = acpi_ut_execute_CID(node, &cid); |
590 | if (status == AE_NOT_FOUND) { | 595 | if (status == AE_NOT_FOUND) { |
591 | return (AE_OK); | 596 | return (AE_OK); |
@@ -597,10 +602,8 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, | |||
597 | 602 | ||
598 | found = 0; | 603 | found = 0; |
599 | for (i = 0; i < cid->count; i++) { | 604 | for (i = 0; i < cid->count; i++) { |
600 | if (ACPI_STRNCMP(cid->id[i].value, info->hid, | 605 | if (ACPI_STRCMP(cid->ids[i].string, info->hid) |
601 | sizeof(struct | 606 | == 0) { |
602 | acpi_compatible_id)) == | ||
603 | 0) { | ||
604 | found = 1; | 607 | found = 1; |
605 | break; | 608 | break; |
606 | } | 609 | } |
diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index f23593d6add4..ddc84af6336e 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c | |||
@@ -51,6 +51,11 @@ | |||
51 | #define _COMPONENT ACPI_NAMESPACE | 51 | #define _COMPONENT ACPI_NAMESPACE |
52 | ACPI_MODULE_NAME("nsxfname") | 52 | ACPI_MODULE_NAME("nsxfname") |
53 | 53 | ||
54 | /* Local prototypes */ | ||
55 | static char *acpi_ns_copy_device_id(struct acpica_device_id *dest, | ||
56 | struct acpica_device_id *source, | ||
57 | char *string_area); | ||
58 | |||
54 | /****************************************************************************** | 59 | /****************************************************************************** |
55 | * | 60 | * |
56 | * FUNCTION: acpi_get_handle | 61 | * FUNCTION: acpi_get_handle |
@@ -68,6 +73,7 @@ ACPI_MODULE_NAME("nsxfname") | |||
68 | * namespace handle. | 73 | * namespace handle. |
69 | * | 74 | * |
70 | ******************************************************************************/ | 75 | ******************************************************************************/ |
76 | |||
71 | acpi_status | 77 | acpi_status |
72 | acpi_get_handle(acpi_handle parent, | 78 | acpi_get_handle(acpi_handle parent, |
73 | acpi_string pathname, acpi_handle * ret_handle) | 79 | acpi_string pathname, acpi_handle * ret_handle) |
@@ -210,10 +216,38 @@ ACPI_EXPORT_SYMBOL(acpi_get_name) | |||
210 | 216 | ||
211 | /****************************************************************************** | 217 | /****************************************************************************** |
212 | * | 218 | * |
219 | * FUNCTION: acpi_ns_copy_device_id | ||
220 | * | ||
221 | * PARAMETERS: Dest - Pointer to the destination DEVICE_ID | ||
222 | * Source - Pointer to the source DEVICE_ID | ||
223 | * string_area - Pointer to where to copy the dest string | ||
224 | * | ||
225 | * RETURN: Pointer to the next string area | ||
226 | * | ||
227 | * DESCRIPTION: Copy a single DEVICE_ID, including the string data. | ||
228 | * | ||
229 | ******************************************************************************/ | ||
230 | static char *acpi_ns_copy_device_id(struct acpica_device_id *dest, | ||
231 | struct acpica_device_id *source, | ||
232 | char *string_area) | ||
233 | { | ||
234 | /* Create the destination DEVICE_ID */ | ||
235 | |||
236 | dest->string = string_area; | ||
237 | dest->length = source->length; | ||
238 | |||
239 | /* Copy actual string and return a pointer to the next string area */ | ||
240 | |||
241 | ACPI_MEMCPY(string_area, source->string, source->length); | ||
242 | return (string_area + source->length); | ||
243 | } | ||
244 | |||
245 | /****************************************************************************** | ||
246 | * | ||
213 | * FUNCTION: acpi_get_object_info | 247 | * FUNCTION: acpi_get_object_info |
214 | * | 248 | * |
215 | * PARAMETERS: Handle - Object Handle | 249 | * PARAMETERS: Handle - Object Handle |
216 | * Buffer - Where the info is returned | 250 | * return_buffer - Where the info is returned |
217 | * | 251 | * |
218 | * RETURN: Status | 252 | * RETURN: Status |
219 | * | 253 | * |
@@ -221,33 +255,37 @@ ACPI_EXPORT_SYMBOL(acpi_get_name) | |||
221 | * namespace node and possibly by running several standard | 255 | * namespace node and possibly by running several standard |
222 | * control methods (Such as in the case of a device.) | 256 | * control methods (Such as in the case of a device.) |
223 | * | 257 | * |
258 | * For Device and Processor objects, run the Device _HID, _UID, _CID, _STA, | ||
259 | * _ADR, _sx_w, and _sx_d methods. | ||
260 | * | ||
261 | * Note: Allocates the return buffer, must be freed by the caller. | ||
262 | * | ||
224 | ******************************************************************************/ | 263 | ******************************************************************************/ |
264 | |||
225 | acpi_status | 265 | acpi_status |
226 | acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) | 266 | acpi_get_object_info(acpi_handle handle, |
267 | struct acpi_device_info **return_buffer) | ||
227 | { | 268 | { |
228 | acpi_status status; | ||
229 | struct acpi_namespace_node *node; | 269 | struct acpi_namespace_node *node; |
230 | struct acpi_device_info *info; | 270 | struct acpi_device_info *info; |
231 | struct acpi_device_info *return_info; | 271 | struct acpica_device_id_list *cid_list = NULL; |
232 | struct acpi_compatible_id_list *cid_list = NULL; | 272 | struct acpica_device_id *hid = NULL; |
233 | acpi_size size; | 273 | struct acpica_device_id *uid = NULL; |
274 | char *next_id_string; | ||
275 | acpi_object_type type; | ||
276 | acpi_name name; | ||
277 | u8 param_count = 0; | ||
278 | u8 valid = 0; | ||
279 | u32 info_size; | ||
280 | u32 i; | ||
281 | acpi_status status; | ||
234 | 282 | ||
235 | /* Parameter validation */ | 283 | /* Parameter validation */ |
236 | 284 | ||
237 | if (!handle || !buffer) { | 285 | if (!handle || !return_buffer) { |
238 | return (AE_BAD_PARAMETER); | 286 | return (AE_BAD_PARAMETER); |
239 | } | 287 | } |
240 | 288 | ||
241 | status = acpi_ut_validate_buffer(buffer); | ||
242 | if (ACPI_FAILURE(status)) { | ||
243 | return (status); | ||
244 | } | ||
245 | |||
246 | info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_device_info)); | ||
247 | if (!info) { | ||
248 | return (AE_NO_MEMORY); | ||
249 | } | ||
250 | |||
251 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | 289 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); |
252 | if (ACPI_FAILURE(status)) { | 290 | if (ACPI_FAILURE(status)) { |
253 | goto cleanup; | 291 | goto cleanup; |
@@ -256,66 +294,91 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) | |||
256 | node = acpi_ns_map_handle_to_node(handle); | 294 | node = acpi_ns_map_handle_to_node(handle); |
257 | if (!node) { | 295 | if (!node) { |
258 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 296 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
259 | status = AE_BAD_PARAMETER; | 297 | return (AE_BAD_PARAMETER); |
260 | goto cleanup; | ||
261 | } | 298 | } |
262 | 299 | ||
263 | /* Init return structure */ | 300 | /* Get the namespace node data while the namespace is locked */ |
264 | |||
265 | size = sizeof(struct acpi_device_info); | ||
266 | 301 | ||
267 | info->type = node->type; | 302 | info_size = sizeof(struct acpi_device_info); |
268 | info->name = node->name.integer; | 303 | type = node->type; |
269 | info->valid = 0; | 304 | name = node->name.integer; |
270 | 305 | ||
271 | if (node->type == ACPI_TYPE_METHOD) { | 306 | if (node->type == ACPI_TYPE_METHOD) { |
272 | info->param_count = node->object->method.param_count; | 307 | param_count = node->object->method.param_count; |
273 | } | 308 | } |
274 | 309 | ||
275 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 310 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
276 | if (ACPI_FAILURE(status)) { | 311 | if (ACPI_FAILURE(status)) { |
277 | goto cleanup; | 312 | return (status); |
278 | } | 313 | } |
279 | 314 | ||
280 | /* If not a device, we are all done */ | 315 | if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) { |
281 | |||
282 | if (info->type == ACPI_TYPE_DEVICE) { | ||
283 | /* | 316 | /* |
284 | * Get extra info for ACPI Devices objects only: | 317 | * Get extra info for ACPI Device/Processor objects only: |
285 | * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods. | 318 | * Run the Device _HID, _UID, and _CID methods. |
286 | * | 319 | * |
287 | * Note: none of these methods are required, so they may or may | 320 | * Note: none of these methods are required, so they may or may |
288 | * not be present for this device. The Info->Valid bitfield is used | 321 | * not be present for this device. The Info->Valid bitfield is used |
289 | * to indicate which methods were found and ran successfully. | 322 | * to indicate which methods were found and run successfully. |
290 | */ | 323 | */ |
291 | 324 | ||
292 | /* Execute the Device._HID method */ | 325 | /* Execute the Device._HID method */ |
293 | 326 | ||
294 | status = acpi_ut_execute_HID(node, &info->hardware_id); | 327 | status = acpi_ut_execute_HID(node, &hid); |
295 | if (ACPI_SUCCESS(status)) { | 328 | if (ACPI_SUCCESS(status)) { |
296 | info->valid |= ACPI_VALID_HID; | 329 | info_size += hid->length; |
330 | valid |= ACPI_VALID_HID; | ||
297 | } | 331 | } |
298 | 332 | ||
299 | /* Execute the Device._UID method */ | 333 | /* Execute the Device._UID method */ |
300 | 334 | ||
301 | status = acpi_ut_execute_UID(node, &info->unique_id); | 335 | status = acpi_ut_execute_UID(node, &uid); |
302 | if (ACPI_SUCCESS(status)) { | 336 | if (ACPI_SUCCESS(status)) { |
303 | info->valid |= ACPI_VALID_UID; | 337 | info_size += uid->length; |
338 | valid |= ACPI_VALID_UID; | ||
304 | } | 339 | } |
305 | 340 | ||
306 | /* Execute the Device._CID method */ | 341 | /* Execute the Device._CID method */ |
307 | 342 | ||
308 | status = acpi_ut_execute_CID(node, &cid_list); | 343 | status = acpi_ut_execute_CID(node, &cid_list); |
309 | if (ACPI_SUCCESS(status)) { | 344 | if (ACPI_SUCCESS(status)) { |
310 | size += cid_list->size; | 345 | |
311 | info->valid |= ACPI_VALID_CID; | 346 | /* Add size of CID strings and CID pointer array */ |
347 | |||
348 | info_size += | ||
349 | (cid_list->list_size - | ||
350 | sizeof(struct acpica_device_id_list)); | ||
351 | valid |= ACPI_VALID_CID; | ||
312 | } | 352 | } |
353 | } | ||
354 | |||
355 | /* | ||
356 | * Now that we have the variable-length data, we can allocate the | ||
357 | * return buffer | ||
358 | */ | ||
359 | info = ACPI_ALLOCATE_ZEROED(info_size); | ||
360 | if (!info) { | ||
361 | status = AE_NO_MEMORY; | ||
362 | goto cleanup; | ||
363 | } | ||
364 | |||
365 | /* Get the fixed-length data */ | ||
366 | |||
367 | if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) { | ||
368 | /* | ||
369 | * Get extra info for ACPI Device/Processor objects only: | ||
370 | * Run the _STA, _ADR and, sx_w, and _sx_d methods. | ||
371 | * | ||
372 | * Note: none of these methods are required, so they may or may | ||
373 | * not be present for this device. The Info->Valid bitfield is used | ||
374 | * to indicate which methods were found and run successfully. | ||
375 | */ | ||
313 | 376 | ||
314 | /* Execute the Device._STA method */ | 377 | /* Execute the Device._STA method */ |
315 | 378 | ||
316 | status = acpi_ut_execute_STA(node, &info->current_status); | 379 | status = acpi_ut_execute_STA(node, &info->current_status); |
317 | if (ACPI_SUCCESS(status)) { | 380 | if (ACPI_SUCCESS(status)) { |
318 | info->valid |= ACPI_VALID_STA; | 381 | valid |= ACPI_VALID_STA; |
319 | } | 382 | } |
320 | 383 | ||
321 | /* Execute the Device._ADR method */ | 384 | /* Execute the Device._ADR method */ |
@@ -323,36 +386,100 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) | |||
323 | status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node, | 386 | status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node, |
324 | &info->address); | 387 | &info->address); |
325 | if (ACPI_SUCCESS(status)) { | 388 | if (ACPI_SUCCESS(status)) { |
326 | info->valid |= ACPI_VALID_ADR; | 389 | valid |= ACPI_VALID_ADR; |
390 | } | ||
391 | |||
392 | /* Execute the Device._sx_w methods */ | ||
393 | |||
394 | status = acpi_ut_execute_power_methods(node, | ||
395 | acpi_gbl_lowest_dstate_names, | ||
396 | ACPI_NUM_sx_w_METHODS, | ||
397 | info->lowest_dstates); | ||
398 | if (ACPI_SUCCESS(status)) { | ||
399 | valid |= ACPI_VALID_SXWS; | ||
327 | } | 400 | } |
328 | 401 | ||
329 | /* Execute the Device._sx_d methods */ | 402 | /* Execute the Device._sx_d methods */ |
330 | 403 | ||
331 | status = acpi_ut_execute_sxds(node, info->highest_dstates); | 404 | status = acpi_ut_execute_power_methods(node, |
405 | acpi_gbl_highest_dstate_names, | ||
406 | ACPI_NUM_sx_d_METHODS, | ||
407 | info->highest_dstates); | ||
332 | if (ACPI_SUCCESS(status)) { | 408 | if (ACPI_SUCCESS(status)) { |
333 | info->valid |= ACPI_VALID_SXDS; | 409 | valid |= ACPI_VALID_SXDS; |
334 | } | 410 | } |
335 | } | 411 | } |
336 | 412 | ||
337 | /* Validate/Allocate/Clear caller buffer */ | 413 | /* |
414 | * Create a pointer to the string area of the return buffer. | ||
415 | * Point to the end of the base struct acpi_device_info structure. | ||
416 | */ | ||
417 | next_id_string = ACPI_CAST_PTR(char, info->compatible_id_list.ids); | ||
418 | if (cid_list) { | ||
338 | 419 | ||
339 | status = acpi_ut_initialize_buffer(buffer, size); | 420 | /* Point past the CID DEVICE_ID array */ |
340 | if (ACPI_FAILURE(status)) { | 421 | |
341 | goto cleanup; | 422 | next_id_string += |
423 | ((acpi_size) cid_list->count * | ||
424 | sizeof(struct acpica_device_id)); | ||
342 | } | 425 | } |
343 | 426 | ||
344 | /* Populate the return buffer */ | 427 | /* |
428 | * Copy the HID, UID, and CIDs to the return buffer. The variable-length | ||
429 | * strings are copied to the reserved area at the end of the buffer. | ||
430 | * | ||
431 | * For HID and CID, check if the ID is a PCI Root Bridge. | ||
432 | */ | ||
433 | if (hid) { | ||
434 | next_id_string = acpi_ns_copy_device_id(&info->hardware_id, | ||
435 | hid, next_id_string); | ||
436 | |||
437 | if (acpi_ut_is_pci_root_bridge(hid->string)) { | ||
438 | info->flags |= ACPI_PCI_ROOT_BRIDGE; | ||
439 | } | ||
440 | } | ||
345 | 441 | ||
346 | return_info = buffer->pointer; | 442 | if (uid) { |
347 | ACPI_MEMCPY(return_info, info, sizeof(struct acpi_device_info)); | 443 | next_id_string = acpi_ns_copy_device_id(&info->unique_id, |
444 | uid, next_id_string); | ||
445 | } | ||
348 | 446 | ||
349 | if (cid_list) { | 447 | if (cid_list) { |
350 | ACPI_MEMCPY(&return_info->compatibility_id, cid_list, | 448 | info->compatible_id_list.count = cid_list->count; |
351 | cid_list->size); | 449 | info->compatible_id_list.list_size = cid_list->list_size; |
450 | |||
451 | /* Copy each CID */ | ||
452 | |||
453 | for (i = 0; i < cid_list->count; i++) { | ||
454 | next_id_string = | ||
455 | acpi_ns_copy_device_id(&info->compatible_id_list. | ||
456 | ids[i], &cid_list->ids[i], | ||
457 | next_id_string); | ||
458 | |||
459 | if (acpi_ut_is_pci_root_bridge(cid_list->ids[i].string)) { | ||
460 | info->flags |= ACPI_PCI_ROOT_BRIDGE; | ||
461 | } | ||
462 | } | ||
352 | } | 463 | } |
353 | 464 | ||
465 | /* Copy the fixed-length data */ | ||
466 | |||
467 | info->info_size = info_size; | ||
468 | info->type = type; | ||
469 | info->name = name; | ||
470 | info->param_count = param_count; | ||
471 | info->valid = valid; | ||
472 | |||
473 | *return_buffer = info; | ||
474 | status = AE_OK; | ||
475 | |||
354 | cleanup: | 476 | cleanup: |
355 | ACPI_FREE(info); | 477 | if (hid) { |
478 | ACPI_FREE(hid); | ||
479 | } | ||
480 | if (uid) { | ||
481 | ACPI_FREE(uid); | ||
482 | } | ||
356 | if (cid_list) { | 483 | if (cid_list) { |
357 | ACPI_FREE(cid_list); | 484 | ACPI_FREE(cid_list); |
358 | } | 485 | } |
diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index c5f6ce19a401..cd7995b3aed4 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c | |||
@@ -86,6 +86,9 @@ static acpi_status | |||
86 | acpi_ps_complete_final_op(struct acpi_walk_state *walk_state, | 86 | acpi_ps_complete_final_op(struct acpi_walk_state *walk_state, |
87 | union acpi_parse_object *op, acpi_status status); | 87 | union acpi_parse_object *op, acpi_status status); |
88 | 88 | ||
89 | static void | ||
90 | acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id); | ||
91 | |||
89 | /******************************************************************************* | 92 | /******************************************************************************* |
90 | * | 93 | * |
91 | * FUNCTION: acpi_ps_get_aml_opcode | 94 | * FUNCTION: acpi_ps_get_aml_opcode |
@@ -390,6 +393,7 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, | |||
390 | { | 393 | { |
391 | acpi_status status = AE_OK; | 394 | acpi_status status = AE_OK; |
392 | union acpi_parse_object *arg = NULL; | 395 | union acpi_parse_object *arg = NULL; |
396 | const struct acpi_opcode_info *op_info; | ||
393 | 397 | ||
394 | ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state); | 398 | ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state); |
395 | 399 | ||
@@ -449,13 +453,11 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, | |||
449 | INCREMENT_ARG_LIST(walk_state->arg_types); | 453 | INCREMENT_ARG_LIST(walk_state->arg_types); |
450 | } | 454 | } |
451 | 455 | ||
452 | /* Special processing for certain opcodes */ | 456 | /* |
453 | 457 | * Handle executable code at "module-level". This refers to | |
454 | /* TBD (remove): Temporary mechanism to disable this code if needed */ | 458 | * executable opcodes that appear outside of any control method. |
455 | 459 | */ | |
456 | #ifdef ACPI_ENABLE_MODULE_LEVEL_CODE | 460 | if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS2) && |
457 | |||
458 | if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS1) && | ||
459 | ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) { | 461 | ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) { |
460 | /* | 462 | /* |
461 | * We want to skip If/Else/While constructs during Pass1 because we | 463 | * We want to skip If/Else/While constructs during Pass1 because we |
@@ -469,6 +471,23 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, | |||
469 | case AML_ELSE_OP: | 471 | case AML_ELSE_OP: |
470 | case AML_WHILE_OP: | 472 | case AML_WHILE_OP: |
471 | 473 | ||
474 | /* | ||
475 | * Currently supported module-level opcodes are: | ||
476 | * IF/ELSE/WHILE. These appear to be the most common, | ||
477 | * and easiest to support since they open an AML | ||
478 | * package. | ||
479 | */ | ||
480 | if (walk_state->pass_number == | ||
481 | ACPI_IMODE_LOAD_PASS1) { | ||
482 | acpi_ps_link_module_code(aml_op_start, | ||
483 | walk_state-> | ||
484 | parser_state. | ||
485 | pkg_end - | ||
486 | aml_op_start, | ||
487 | walk_state-> | ||
488 | owner_id); | ||
489 | } | ||
490 | |||
472 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | 491 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, |
473 | "Pass1: Skipping an If/Else/While body\n")); | 492 | "Pass1: Skipping an If/Else/While body\n")); |
474 | 493 | ||
@@ -480,10 +499,34 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, | |||
480 | break; | 499 | break; |
481 | 500 | ||
482 | default: | 501 | default: |
502 | /* | ||
503 | * Check for an unsupported executable opcode at module | ||
504 | * level. We must be in PASS1, the parent must be a SCOPE, | ||
505 | * The opcode class must be EXECUTE, and the opcode must | ||
506 | * not be an argument to another opcode. | ||
507 | */ | ||
508 | if ((walk_state->pass_number == | ||
509 | ACPI_IMODE_LOAD_PASS1) | ||
510 | && (op->common.parent->common.aml_opcode == | ||
511 | AML_SCOPE_OP)) { | ||
512 | op_info = | ||
513 | acpi_ps_get_opcode_info(op->common. | ||
514 | aml_opcode); | ||
515 | if ((op_info->class == | ||
516 | AML_CLASS_EXECUTE) && (!arg)) { | ||
517 | ACPI_WARNING((AE_INFO, | ||
518 | "Detected an unsupported executable opcode " | ||
519 | "at module-level: [0x%.4X] at table offset 0x%.4X", | ||
520 | op->common.aml_opcode, | ||
521 | (u32)((aml_op_start - walk_state->parser_state.aml_start) | ||
522 | + sizeof(struct acpi_table_header)))); | ||
523 | } | ||
524 | } | ||
483 | break; | 525 | break; |
484 | } | 526 | } |
485 | } | 527 | } |
486 | #endif | 528 | |
529 | /* Special processing for certain opcodes */ | ||
487 | 530 | ||
488 | switch (op->common.aml_opcode) { | 531 | switch (op->common.aml_opcode) { |
489 | case AML_METHOD_OP: | 532 | case AML_METHOD_OP: |
@@ -553,6 +596,66 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, | |||
553 | 596 | ||
554 | /******************************************************************************* | 597 | /******************************************************************************* |
555 | * | 598 | * |
599 | * FUNCTION: acpi_ps_link_module_code | ||
600 | * | ||
601 | * PARAMETERS: aml_start - Pointer to the AML | ||
602 | * aml_length - Length of executable AML | ||
603 | * owner_id - owner_id of module level code | ||
604 | * | ||
605 | * RETURN: None. | ||
606 | * | ||
607 | * DESCRIPTION: Wrap the module-level code with a method object and link the | ||
608 | * object to the global list. Note, the mutex field of the method | ||
609 | * object is used to link multiple module-level code objects. | ||
610 | * | ||
611 | ******************************************************************************/ | ||
612 | |||
613 | static void | ||
614 | acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id) | ||
615 | { | ||
616 | union acpi_operand_object *prev; | ||
617 | union acpi_operand_object *next; | ||
618 | union acpi_operand_object *method_obj; | ||
619 | |||
620 | /* Get the tail of the list */ | ||
621 | |||
622 | prev = next = acpi_gbl_module_code_list; | ||
623 | while (next) { | ||
624 | prev = next; | ||
625 | next = next->method.mutex; | ||
626 | } | ||
627 | |||
628 | /* | ||
629 | * Insert the module level code into the list. Merge it if it is | ||
630 | * adjacent to the previous element. | ||
631 | */ | ||
632 | if (!prev || | ||
633 | ((prev->method.aml_start + prev->method.aml_length) != aml_start)) { | ||
634 | |||
635 | /* Create, initialize, and link a new temporary method object */ | ||
636 | |||
637 | method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); | ||
638 | if (!method_obj) { | ||
639 | return; | ||
640 | } | ||
641 | |||
642 | method_obj->method.aml_start = aml_start; | ||
643 | method_obj->method.aml_length = aml_length; | ||
644 | method_obj->method.owner_id = owner_id; | ||
645 | method_obj->method.flags |= AOPOBJ_MODULE_LEVEL; | ||
646 | |||
647 | if (!prev) { | ||
648 | acpi_gbl_module_code_list = method_obj; | ||
649 | } else { | ||
650 | prev->method.mutex = method_obj; | ||
651 | } | ||
652 | } else { | ||
653 | prev->method.aml_length += aml_length; | ||
654 | } | ||
655 | } | ||
656 | |||
657 | /******************************************************************************* | ||
658 | * | ||
556 | * FUNCTION: acpi_ps_complete_op | 659 | * FUNCTION: acpi_ps_complete_op |
557 | * | 660 | * |
558 | * PARAMETERS: walk_state - Current state | 661 | * PARAMETERS: walk_state - Current state |
diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c index ff06032c0f06..dd9731c29a79 100644 --- a/drivers/acpi/acpica/psxface.c +++ b/drivers/acpi/acpica/psxface.c | |||
@@ -280,6 +280,10 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) | |||
280 | goto cleanup; | 280 | goto cleanup; |
281 | } | 281 | } |
282 | 282 | ||
283 | if (info->obj_desc->method.flags & AOPOBJ_MODULE_LEVEL) { | ||
284 | walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL; | ||
285 | } | ||
286 | |||
283 | /* Invoke an internal method if necessary */ | 287 | /* Invoke an internal method if necessary */ |
284 | 288 | ||
285 | if (info->obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { | 289 | if (info->obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { |
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index ef7d2c2d8f0b..1f15497f00d1 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c | |||
@@ -49,6 +49,12 @@ | |||
49 | ACPI_MODULE_NAME("tbutils") | 49 | ACPI_MODULE_NAME("tbutils") |
50 | 50 | ||
51 | /* Local prototypes */ | 51 | /* Local prototypes */ |
52 | static void acpi_tb_fix_string(char *string, acpi_size length); | ||
53 | |||
54 | static void | ||
55 | acpi_tb_cleanup_table_header(struct acpi_table_header *out_header, | ||
56 | struct acpi_table_header *header); | ||
57 | |||
52 | static acpi_physical_address | 58 | static acpi_physical_address |
53 | acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size); | 59 | acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size); |
54 | 60 | ||
@@ -161,6 +167,59 @@ u8 acpi_tb_tables_loaded(void) | |||
161 | 167 | ||
162 | /******************************************************************************* | 168 | /******************************************************************************* |
163 | * | 169 | * |
170 | * FUNCTION: acpi_tb_fix_string | ||
171 | * | ||
172 | * PARAMETERS: String - String to be repaired | ||
173 | * Length - Maximum length | ||
174 | * | ||
175 | * RETURN: None | ||
176 | * | ||
177 | * DESCRIPTION: Replace every non-printable or non-ascii byte in the string | ||
178 | * with a question mark '?'. | ||
179 | * | ||
180 | ******************************************************************************/ | ||
181 | |||
182 | static void acpi_tb_fix_string(char *string, acpi_size length) | ||
183 | { | ||
184 | |||
185 | while (length && *string) { | ||
186 | if (!ACPI_IS_PRINT(*string)) { | ||
187 | *string = '?'; | ||
188 | } | ||
189 | string++; | ||
190 | length--; | ||
191 | } | ||
192 | } | ||
193 | |||
194 | /******************************************************************************* | ||
195 | * | ||
196 | * FUNCTION: acpi_tb_cleanup_table_header | ||
197 | * | ||
198 | * PARAMETERS: out_header - Where the cleaned header is returned | ||
199 | * Header - Input ACPI table header | ||
200 | * | ||
201 | * RETURN: Returns the cleaned header in out_header | ||
202 | * | ||
203 | * DESCRIPTION: Copy the table header and ensure that all "string" fields in | ||
204 | * the header consist of printable characters. | ||
205 | * | ||
206 | ******************************************************************************/ | ||
207 | |||
208 | static void | ||
209 | acpi_tb_cleanup_table_header(struct acpi_table_header *out_header, | ||
210 | struct acpi_table_header *header) | ||
211 | { | ||
212 | |||
213 | ACPI_MEMCPY(out_header, header, sizeof(struct acpi_table_header)); | ||
214 | |||
215 | acpi_tb_fix_string(out_header->signature, ACPI_NAME_SIZE); | ||
216 | acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE); | ||
217 | acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE); | ||
218 | acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAME_SIZE); | ||
219 | } | ||
220 | |||
221 | /******************************************************************************* | ||
222 | * | ||
164 | * FUNCTION: acpi_tb_print_table_header | 223 | * FUNCTION: acpi_tb_print_table_header |
165 | * | 224 | * |
166 | * PARAMETERS: Address - Table physical address | 225 | * PARAMETERS: Address - Table physical address |
@@ -176,6 +235,7 @@ void | |||
176 | acpi_tb_print_table_header(acpi_physical_address address, | 235 | acpi_tb_print_table_header(acpi_physical_address address, |
177 | struct acpi_table_header *header) | 236 | struct acpi_table_header *header) |
178 | { | 237 | { |
238 | struct acpi_table_header local_header; | ||
179 | 239 | ||
180 | /* | 240 | /* |
181 | * The reason that the Address is cast to a void pointer is so that we | 241 | * The reason that the Address is cast to a void pointer is so that we |
@@ -192,6 +252,11 @@ acpi_tb_print_table_header(acpi_physical_address address, | |||
192 | 252 | ||
193 | /* RSDP has no common fields */ | 253 | /* RSDP has no common fields */ |
194 | 254 | ||
255 | ACPI_MEMCPY(local_header.oem_id, | ||
256 | ACPI_CAST_PTR(struct acpi_table_rsdp, | ||
257 | header)->oem_id, ACPI_OEM_ID_SIZE); | ||
258 | acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE); | ||
259 | |||
195 | ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)", | 260 | ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)", |
196 | ACPI_CAST_PTR (void, address), | 261 | ACPI_CAST_PTR (void, address), |
197 | (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> | 262 | (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> |
@@ -200,18 +265,21 @@ acpi_tb_print_table_header(acpi_physical_address address, | |||
200 | header)->length : 20, | 265 | header)->length : 20, |
201 | ACPI_CAST_PTR(struct acpi_table_rsdp, | 266 | ACPI_CAST_PTR(struct acpi_table_rsdp, |
202 | header)->revision, | 267 | header)->revision, |
203 | ACPI_CAST_PTR(struct acpi_table_rsdp, | 268 | local_header.oem_id)); |
204 | header)->oem_id)); | ||
205 | } else { | 269 | } else { |
206 | /* Standard ACPI table with full common header */ | 270 | /* Standard ACPI table with full common header */ |
207 | 271 | ||
272 | acpi_tb_cleanup_table_header(&local_header, header); | ||
273 | |||
208 | ACPI_INFO((AE_INFO, | 274 | ACPI_INFO((AE_INFO, |
209 | "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)", | 275 | "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)", |
210 | header->signature, ACPI_CAST_PTR (void, address), | 276 | local_header.signature, ACPI_CAST_PTR(void, address), |
211 | header->length, header->revision, header->oem_id, | 277 | local_header.length, local_header.revision, |
212 | header->oem_table_id, header->oem_revision, | 278 | local_header.oem_id, local_header.oem_table_id, |
213 | header->asl_compiler_id, | 279 | local_header.oem_revision, |
214 | header->asl_compiler_revision)); | 280 | local_header.asl_compiler_id, |
281 | local_header.asl_compiler_revision)); | ||
282 | |||
215 | } | 283 | } |
216 | } | 284 | } |
217 | 285 | ||
diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index bc1710315088..96e26e70c63d 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c | |||
@@ -215,6 +215,12 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) | |||
215 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | 215 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, |
216 | "***** Region %p\n", object)); | 216 | "***** Region %p\n", object)); |
217 | 217 | ||
218 | /* Invalidate the region address/length via the host OS */ | ||
219 | |||
220 | acpi_os_invalidate_address(object->region.space_id, | ||
221 | object->region.address, | ||
222 | (acpi_size) object->region.length); | ||
223 | |||
218 | second_desc = acpi_ns_get_secondary_object(object); | 224 | second_desc = acpi_ns_get_secondary_object(object); |
219 | if (second_desc) { | 225 | if (second_desc) { |
220 | /* | 226 | /* |
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index 006b16c26017..5d54e36ab453 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c | |||
@@ -44,19 +44,10 @@ | |||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acnamesp.h" | 46 | #include "acnamesp.h" |
47 | #include "acinterp.h" | ||
48 | 47 | ||
49 | #define _COMPONENT ACPI_UTILITIES | 48 | #define _COMPONENT ACPI_UTILITIES |
50 | ACPI_MODULE_NAME("uteval") | 49 | ACPI_MODULE_NAME("uteval") |
51 | 50 | ||
52 | /* Local prototypes */ | ||
53 | static void | ||
54 | acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length); | ||
55 | |||
56 | static acpi_status | ||
57 | acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, | ||
58 | struct acpi_compatible_id *one_cid); | ||
59 | |||
60 | /* | 51 | /* |
61 | * Strings supported by the _OSI predefined (internal) method. | 52 | * Strings supported by the _OSI predefined (internal) method. |
62 | * | 53 | * |
@@ -78,6 +69,9 @@ static struct acpi_interface_info acpi_interfaces_supported[] = { | |||
78 | {"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */ | 69 | {"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */ |
79 | {"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */ | 70 | {"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */ |
80 | {"Windows 2006", ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */ | 71 | {"Windows 2006", ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */ |
72 | {"Windows 2006.1", ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */ | ||
73 | {"Windows 2006 SP1", ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */ | ||
74 | {"Windows 2009", ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */ | ||
81 | 75 | ||
82 | /* Feature Group Strings */ | 76 | /* Feature Group Strings */ |
83 | 77 | ||
@@ -213,7 +207,7 @@ acpi_status acpi_osi_invalidate(char *interface) | |||
213 | * RETURN: Status | 207 | * RETURN: Status |
214 | * | 208 | * |
215 | * DESCRIPTION: Evaluates a namespace object and verifies the type of the | 209 | * DESCRIPTION: Evaluates a namespace object and verifies the type of the |
216 | * return object. Common code that simplifies accessing objects | 210 | * return object. Common code that simplifies accessing objects |
217 | * that have required return objects of fixed types. | 211 | * that have required return objects of fixed types. |
218 | * | 212 | * |
219 | * NOTE: Internal function, no parameter validation | 213 | * NOTE: Internal function, no parameter validation |
@@ -298,7 +292,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
298 | 292 | ||
299 | if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) { | 293 | if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) { |
300 | /* | 294 | /* |
301 | * We received a return object, but one was not expected. This can | 295 | * We received a return object, but one was not expected. This can |
302 | * happen frequently if the "implicit return" feature is enabled. | 296 | * happen frequently if the "implicit return" feature is enabled. |
303 | * Just delete the return object and return AE_OK. | 297 | * Just delete the return object and return AE_OK. |
304 | */ | 298 | */ |
@@ -340,12 +334,12 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
340 | * | 334 | * |
341 | * PARAMETERS: object_name - Object name to be evaluated | 335 | * PARAMETERS: object_name - Object name to be evaluated |
342 | * device_node - Node for the device | 336 | * device_node - Node for the device |
343 | * Address - Where the value is returned | 337 | * Value - Where the value is returned |
344 | * | 338 | * |
345 | * RETURN: Status | 339 | * RETURN: Status |
346 | * | 340 | * |
347 | * DESCRIPTION: Evaluates a numeric namespace object for a selected device | 341 | * DESCRIPTION: Evaluates a numeric namespace object for a selected device |
348 | * and stores result in *Address. | 342 | * and stores result in *Value. |
349 | * | 343 | * |
350 | * NOTE: Internal function, no parameter validation | 344 | * NOTE: Internal function, no parameter validation |
351 | * | 345 | * |
@@ -354,7 +348,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
354 | acpi_status | 348 | acpi_status |
355 | acpi_ut_evaluate_numeric_object(char *object_name, | 349 | acpi_ut_evaluate_numeric_object(char *object_name, |
356 | struct acpi_namespace_node *device_node, | 350 | struct acpi_namespace_node *device_node, |
357 | acpi_integer * address) | 351 | acpi_integer *value) |
358 | { | 352 | { |
359 | union acpi_operand_object *obj_desc; | 353 | union acpi_operand_object *obj_desc; |
360 | acpi_status status; | 354 | acpi_status status; |
@@ -369,295 +363,7 @@ acpi_ut_evaluate_numeric_object(char *object_name, | |||
369 | 363 | ||
370 | /* Get the returned Integer */ | 364 | /* Get the returned Integer */ |
371 | 365 | ||
372 | *address = obj_desc->integer.value; | 366 | *value = obj_desc->integer.value; |
373 | |||
374 | /* On exit, we must delete the return object */ | ||
375 | |||
376 | acpi_ut_remove_reference(obj_desc); | ||
377 | return_ACPI_STATUS(status); | ||
378 | } | ||
379 | |||
380 | /******************************************************************************* | ||
381 | * | ||
382 | * FUNCTION: acpi_ut_copy_id_string | ||
383 | * | ||
384 | * PARAMETERS: Destination - Where to copy the string | ||
385 | * Source - Source string | ||
386 | * max_length - Length of the destination buffer | ||
387 | * | ||
388 | * RETURN: None | ||
389 | * | ||
390 | * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. | ||
391 | * Performs removal of a leading asterisk if present -- workaround | ||
392 | * for a known issue on a bunch of machines. | ||
393 | * | ||
394 | ******************************************************************************/ | ||
395 | |||
396 | static void | ||
397 | acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length) | ||
398 | { | ||
399 | |||
400 | /* | ||
401 | * Workaround for ID strings that have a leading asterisk. This construct | ||
402 | * is not allowed by the ACPI specification (ID strings must be | ||
403 | * alphanumeric), but enough existing machines have this embedded in their | ||
404 | * ID strings that the following code is useful. | ||
405 | */ | ||
406 | if (*source == '*') { | ||
407 | source++; | ||
408 | } | ||
409 | |||
410 | /* Do the actual copy */ | ||
411 | |||
412 | ACPI_STRNCPY(destination, source, max_length); | ||
413 | } | ||
414 | |||
415 | /******************************************************************************* | ||
416 | * | ||
417 | * FUNCTION: acpi_ut_execute_HID | ||
418 | * | ||
419 | * PARAMETERS: device_node - Node for the device | ||
420 | * Hid - Where the HID is returned | ||
421 | * | ||
422 | * RETURN: Status | ||
423 | * | ||
424 | * DESCRIPTION: Executes the _HID control method that returns the hardware | ||
425 | * ID of the device. | ||
426 | * | ||
427 | * NOTE: Internal function, no parameter validation | ||
428 | * | ||
429 | ******************************************************************************/ | ||
430 | |||
431 | acpi_status | ||
432 | acpi_ut_execute_HID(struct acpi_namespace_node *device_node, | ||
433 | struct acpica_device_id *hid) | ||
434 | { | ||
435 | union acpi_operand_object *obj_desc; | ||
436 | acpi_status status; | ||
437 | |||
438 | ACPI_FUNCTION_TRACE(ut_execute_HID); | ||
439 | |||
440 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID, | ||
441 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, | ||
442 | &obj_desc); | ||
443 | if (ACPI_FAILURE(status)) { | ||
444 | return_ACPI_STATUS(status); | ||
445 | } | ||
446 | |||
447 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
448 | |||
449 | /* Convert the Numeric HID to string */ | ||
450 | |||
451 | acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value, | ||
452 | hid->value); | ||
453 | } else { | ||
454 | /* Copy the String HID from the returned object */ | ||
455 | |||
456 | acpi_ut_copy_id_string(hid->value, obj_desc->string.pointer, | ||
457 | sizeof(hid->value)); | ||
458 | } | ||
459 | |||
460 | /* On exit, we must delete the return object */ | ||
461 | |||
462 | acpi_ut_remove_reference(obj_desc); | ||
463 | return_ACPI_STATUS(status); | ||
464 | } | ||
465 | |||
466 | /******************************************************************************* | ||
467 | * | ||
468 | * FUNCTION: acpi_ut_translate_one_cid | ||
469 | * | ||
470 | * PARAMETERS: obj_desc - _CID object, must be integer or string | ||
471 | * one_cid - Where the CID string is returned | ||
472 | * | ||
473 | * RETURN: Status | ||
474 | * | ||
475 | * DESCRIPTION: Return a numeric or string _CID value as a string. | ||
476 | * (Compatible ID) | ||
477 | * | ||
478 | * NOTE: Assumes a maximum _CID string length of | ||
479 | * ACPI_MAX_CID_LENGTH. | ||
480 | * | ||
481 | ******************************************************************************/ | ||
482 | |||
483 | static acpi_status | ||
484 | acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, | ||
485 | struct acpi_compatible_id *one_cid) | ||
486 | { | ||
487 | |||
488 | switch (obj_desc->common.type) { | ||
489 | case ACPI_TYPE_INTEGER: | ||
490 | |||
491 | /* Convert the Numeric CID to string */ | ||
492 | |||
493 | acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value, | ||
494 | one_cid->value); | ||
495 | return (AE_OK); | ||
496 | |||
497 | case ACPI_TYPE_STRING: | ||
498 | |||
499 | if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) { | ||
500 | return (AE_AML_STRING_LIMIT); | ||
501 | } | ||
502 | |||
503 | /* Copy the String CID from the returned object */ | ||
504 | |||
505 | acpi_ut_copy_id_string(one_cid->value, obj_desc->string.pointer, | ||
506 | ACPI_MAX_CID_LENGTH); | ||
507 | return (AE_OK); | ||
508 | |||
509 | default: | ||
510 | |||
511 | return (AE_TYPE); | ||
512 | } | ||
513 | } | ||
514 | |||
515 | /******************************************************************************* | ||
516 | * | ||
517 | * FUNCTION: acpi_ut_execute_CID | ||
518 | * | ||
519 | * PARAMETERS: device_node - Node for the device | ||
520 | * return_cid_list - Where the CID list is returned | ||
521 | * | ||
522 | * RETURN: Status | ||
523 | * | ||
524 | * DESCRIPTION: Executes the _CID control method that returns one or more | ||
525 | * compatible hardware IDs for the device. | ||
526 | * | ||
527 | * NOTE: Internal function, no parameter validation | ||
528 | * | ||
529 | ******************************************************************************/ | ||
530 | |||
531 | acpi_status | ||
532 | acpi_ut_execute_CID(struct acpi_namespace_node * device_node, | ||
533 | struct acpi_compatible_id_list ** return_cid_list) | ||
534 | { | ||
535 | union acpi_operand_object *obj_desc; | ||
536 | acpi_status status; | ||
537 | u32 count; | ||
538 | u32 size; | ||
539 | struct acpi_compatible_id_list *cid_list; | ||
540 | u32 i; | ||
541 | |||
542 | ACPI_FUNCTION_TRACE(ut_execute_CID); | ||
543 | |||
544 | /* Evaluate the _CID method for this device */ | ||
545 | |||
546 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID, | ||
547 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ||
548 | | ACPI_BTYPE_PACKAGE, &obj_desc); | ||
549 | if (ACPI_FAILURE(status)) { | ||
550 | return_ACPI_STATUS(status); | ||
551 | } | ||
552 | |||
553 | /* Get the number of _CIDs returned */ | ||
554 | |||
555 | count = 1; | ||
556 | if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { | ||
557 | count = obj_desc->package.count; | ||
558 | } | ||
559 | |||
560 | /* Allocate a worst-case buffer for the _CIDs */ | ||
561 | |||
562 | size = (((count - 1) * sizeof(struct acpi_compatible_id)) + | ||
563 | sizeof(struct acpi_compatible_id_list)); | ||
564 | |||
565 | cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size); | ||
566 | if (!cid_list) { | ||
567 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
568 | } | ||
569 | |||
570 | /* Init CID list */ | ||
571 | |||
572 | cid_list->count = count; | ||
573 | cid_list->size = size; | ||
574 | |||
575 | /* | ||
576 | * A _CID can return either a single compatible ID or a package of | ||
577 | * compatible IDs. Each compatible ID can be one of the following: | ||
578 | * 1) Integer (32 bit compressed EISA ID) or | ||
579 | * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss") | ||
580 | */ | ||
581 | |||
582 | /* The _CID object can be either a single CID or a package (list) of CIDs */ | ||
583 | |||
584 | if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { | ||
585 | |||
586 | /* Translate each package element */ | ||
587 | |||
588 | for (i = 0; i < count; i++) { | ||
589 | status = | ||
590 | acpi_ut_translate_one_cid(obj_desc->package. | ||
591 | elements[i], | ||
592 | &cid_list->id[i]); | ||
593 | if (ACPI_FAILURE(status)) { | ||
594 | break; | ||
595 | } | ||
596 | } | ||
597 | } else { | ||
598 | /* Only one CID, translate to a string */ | ||
599 | |||
600 | status = acpi_ut_translate_one_cid(obj_desc, cid_list->id); | ||
601 | } | ||
602 | |||
603 | /* Cleanup on error */ | ||
604 | |||
605 | if (ACPI_FAILURE(status)) { | ||
606 | ACPI_FREE(cid_list); | ||
607 | } else { | ||
608 | *return_cid_list = cid_list; | ||
609 | } | ||
610 | |||
611 | /* On exit, we must delete the _CID return object */ | ||
612 | |||
613 | acpi_ut_remove_reference(obj_desc); | ||
614 | return_ACPI_STATUS(status); | ||
615 | } | ||
616 | |||
617 | /******************************************************************************* | ||
618 | * | ||
619 | * FUNCTION: acpi_ut_execute_UID | ||
620 | * | ||
621 | * PARAMETERS: device_node - Node for the device | ||
622 | * Uid - Where the UID is returned | ||
623 | * | ||
624 | * RETURN: Status | ||
625 | * | ||
626 | * DESCRIPTION: Executes the _UID control method that returns the hardware | ||
627 | * ID of the device. | ||
628 | * | ||
629 | * NOTE: Internal function, no parameter validation | ||
630 | * | ||
631 | ******************************************************************************/ | ||
632 | |||
633 | acpi_status | ||
634 | acpi_ut_execute_UID(struct acpi_namespace_node *device_node, | ||
635 | struct acpica_device_id *uid) | ||
636 | { | ||
637 | union acpi_operand_object *obj_desc; | ||
638 | acpi_status status; | ||
639 | |||
640 | ACPI_FUNCTION_TRACE(ut_execute_UID); | ||
641 | |||
642 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID, | ||
643 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, | ||
644 | &obj_desc); | ||
645 | if (ACPI_FAILURE(status)) { | ||
646 | return_ACPI_STATUS(status); | ||
647 | } | ||
648 | |||
649 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
650 | |||
651 | /* Convert the Numeric UID to string */ | ||
652 | |||
653 | acpi_ex_unsigned_integer_to_string(obj_desc->integer.value, | ||
654 | uid->value); | ||
655 | } else { | ||
656 | /* Copy the String UID from the returned object */ | ||
657 | |||
658 | acpi_ut_copy_id_string(uid->value, obj_desc->string.pointer, | ||
659 | sizeof(uid->value)); | ||
660 | } | ||
661 | 367 | ||
662 | /* On exit, we must delete the return object */ | 368 | /* On exit, we must delete the return object */ |
663 | 369 | ||
@@ -716,60 +422,64 @@ acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags) | |||
716 | 422 | ||
717 | /******************************************************************************* | 423 | /******************************************************************************* |
718 | * | 424 | * |
719 | * FUNCTION: acpi_ut_execute_Sxds | 425 | * FUNCTION: acpi_ut_execute_power_methods |
720 | * | 426 | * |
721 | * PARAMETERS: device_node - Node for the device | 427 | * PARAMETERS: device_node - Node for the device |
722 | * Flags - Where the status flags are returned | 428 | * method_names - Array of power method names |
429 | * method_count - Number of methods to execute | ||
430 | * out_values - Where the power method values are returned | ||
723 | * | 431 | * |
724 | * RETURN: Status | 432 | * RETURN: Status, out_values |
725 | * | 433 | * |
726 | * DESCRIPTION: Executes _STA for selected device and stores results in | 434 | * DESCRIPTION: Executes the specified power methods for the device and returns |
727 | * *Flags. | 435 | * the result(s). |
728 | * | 436 | * |
729 | * NOTE: Internal function, no parameter validation | 437 | * NOTE: Internal function, no parameter validation |
730 | * | 438 | * |
731 | ******************************************************************************/ | 439 | ******************************************************************************/ |
732 | 440 | ||
733 | acpi_status | 441 | acpi_status |
734 | acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest) | 442 | acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node, |
443 | const char **method_names, | ||
444 | u8 method_count, u8 *out_values) | ||
735 | { | 445 | { |
736 | union acpi_operand_object *obj_desc; | 446 | union acpi_operand_object *obj_desc; |
737 | acpi_status status; | 447 | acpi_status status; |
448 | acpi_status final_status = AE_NOT_FOUND; | ||
738 | u32 i; | 449 | u32 i; |
739 | 450 | ||
740 | ACPI_FUNCTION_TRACE(ut_execute_sxds); | 451 | ACPI_FUNCTION_TRACE(ut_execute_power_methods); |
741 | 452 | ||
742 | for (i = 0; i < 4; i++) { | 453 | for (i = 0; i < method_count; i++) { |
743 | highest[i] = 0xFF; | 454 | /* |
455 | * Execute the power method (_sx_d or _sx_w). The only allowable | ||
456 | * return type is an Integer. | ||
457 | */ | ||
744 | status = acpi_ut_evaluate_object(device_node, | 458 | status = acpi_ut_evaluate_object(device_node, |
745 | ACPI_CAST_PTR(char, | 459 | ACPI_CAST_PTR(char, |
746 | acpi_gbl_highest_dstate_names | 460 | method_names[i]), |
747 | [i]), | ||
748 | ACPI_BTYPE_INTEGER, &obj_desc); | 461 | ACPI_BTYPE_INTEGER, &obj_desc); |
749 | if (ACPI_FAILURE(status)) { | 462 | if (ACPI_SUCCESS(status)) { |
750 | if (status != AE_NOT_FOUND) { | 463 | out_values[i] = (u8)obj_desc->integer.value; |
751 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
752 | "%s on Device %4.4s, %s\n", | ||
753 | ACPI_CAST_PTR(char, | ||
754 | acpi_gbl_highest_dstate_names | ||
755 | [i]), | ||
756 | acpi_ut_get_node_name | ||
757 | (device_node), | ||
758 | acpi_format_exception | ||
759 | (status))); | ||
760 | |||
761 | return_ACPI_STATUS(status); | ||
762 | } | ||
763 | } else { | ||
764 | /* Extract the Dstate value */ | ||
765 | |||
766 | highest[i] = (u8) obj_desc->integer.value; | ||
767 | 464 | ||
768 | /* Delete the return object */ | 465 | /* Delete the return object */ |
769 | 466 | ||
770 | acpi_ut_remove_reference(obj_desc); | 467 | acpi_ut_remove_reference(obj_desc); |
468 | final_status = AE_OK; /* At least one value is valid */ | ||
469 | continue; | ||
771 | } | 470 | } |
471 | |||
472 | out_values[i] = ACPI_UINT8_MAX; | ||
473 | if (status == AE_NOT_FOUND) { | ||
474 | continue; /* Ignore if not found */ | ||
475 | } | ||
476 | |||
477 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
478 | "Failed %s on Device %4.4s, %s\n", | ||
479 | ACPI_CAST_PTR(char, method_names[i]), | ||
480 | acpi_ut_get_node_name(device_node), | ||
481 | acpi_format_exception(status))); | ||
772 | } | 482 | } |
773 | 483 | ||
774 | return_ACPI_STATUS(AE_OK); | 484 | return_ACPI_STATUS(final_status); |
775 | } | 485 | } |
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 59e46f257c02..3f2c68f4e959 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c | |||
@@ -90,7 +90,15 @@ const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = { | |||
90 | "\\_S5_" | 90 | "\\_S5_" |
91 | }; | 91 | }; |
92 | 92 | ||
93 | const char *acpi_gbl_highest_dstate_names[4] = { | 93 | const char *acpi_gbl_lowest_dstate_names[ACPI_NUM_sx_w_METHODS] = { |
94 | "_S0W", | ||
95 | "_S1W", | ||
96 | "_S2W", | ||
97 | "_S3W", | ||
98 | "_S4W" | ||
99 | }; | ||
100 | |||
101 | const char *acpi_gbl_highest_dstate_names[ACPI_NUM_sx_d_METHODS] = { | ||
94 | "_S1D", | 102 | "_S1D", |
95 | "_S2D", | 103 | "_S2D", |
96 | "_S3D", | 104 | "_S3D", |
@@ -351,6 +359,7 @@ const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = { | |||
351 | "SMBus", | 359 | "SMBus", |
352 | "SystemCMOS", | 360 | "SystemCMOS", |
353 | "PCIBARTarget", | 361 | "PCIBARTarget", |
362 | "IPMI", | ||
354 | "DataTable" | 363 | "DataTable" |
355 | }; | 364 | }; |
356 | 365 | ||
@@ -798,6 +807,7 @@ acpi_status acpi_ut_init_globals(void) | |||
798 | 807 | ||
799 | /* Namespace */ | 808 | /* Namespace */ |
800 | 809 | ||
810 | acpi_gbl_module_code_list = NULL; | ||
801 | acpi_gbl_root_node = NULL; | 811 | acpi_gbl_root_node = NULL; |
802 | acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME; | 812 | acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME; |
803 | acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED; | 813 | acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED; |
diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c new file mode 100644 index 000000000000..52eaae404554 --- /dev/null +++ b/drivers/acpi/acpica/utids.c | |||
@@ -0,0 +1,382 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: utids - support for device IDs - HID, UID, CID | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2009, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acinterp.h" | ||
47 | |||
48 | #define _COMPONENT ACPI_UTILITIES | ||
49 | ACPI_MODULE_NAME("utids") | ||
50 | |||
51 | /* Local prototypes */ | ||
52 | static void acpi_ut_copy_id_string(char *destination, char *source); | ||
53 | |||
54 | /******************************************************************************* | ||
55 | * | ||
56 | * FUNCTION: acpi_ut_copy_id_string | ||
57 | * | ||
58 | * PARAMETERS: Destination - Where to copy the string | ||
59 | * Source - Source string | ||
60 | * | ||
61 | * RETURN: None | ||
62 | * | ||
63 | * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. | ||
64 | * Performs removal of a leading asterisk if present -- workaround | ||
65 | * for a known issue on a bunch of machines. | ||
66 | * | ||
67 | ******************************************************************************/ | ||
68 | |||
69 | static void acpi_ut_copy_id_string(char *destination, char *source) | ||
70 | { | ||
71 | |||
72 | /* | ||
73 | * Workaround for ID strings that have a leading asterisk. This construct | ||
74 | * is not allowed by the ACPI specification (ID strings must be | ||
75 | * alphanumeric), but enough existing machines have this embedded in their | ||
76 | * ID strings that the following code is useful. | ||
77 | */ | ||
78 | if (*source == '*') { | ||
79 | source++; | ||
80 | } | ||
81 | |||
82 | /* Do the actual copy */ | ||
83 | |||
84 | ACPI_STRCPY(destination, source); | ||
85 | } | ||
86 | |||
87 | /******************************************************************************* | ||
88 | * | ||
89 | * FUNCTION: acpi_ut_execute_HID | ||
90 | * | ||
91 | * PARAMETERS: device_node - Node for the device | ||
92 | * return_id - Where the string HID is returned | ||
93 | * | ||
94 | * RETURN: Status | ||
95 | * | ||
96 | * DESCRIPTION: Executes the _HID control method that returns the hardware | ||
97 | * ID of the device. The HID is either an 32-bit encoded EISAID | ||
98 | * Integer or a String. A string is always returned. An EISAID | ||
99 | * is converted to a string. | ||
100 | * | ||
101 | * NOTE: Internal function, no parameter validation | ||
102 | * | ||
103 | ******************************************************************************/ | ||
104 | |||
105 | acpi_status | ||
106 | acpi_ut_execute_HID(struct acpi_namespace_node *device_node, | ||
107 | struct acpica_device_id **return_id) | ||
108 | { | ||
109 | union acpi_operand_object *obj_desc; | ||
110 | struct acpica_device_id *hid; | ||
111 | u32 length; | ||
112 | acpi_status status; | ||
113 | |||
114 | ACPI_FUNCTION_TRACE(ut_execute_HID); | ||
115 | |||
116 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID, | ||
117 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, | ||
118 | &obj_desc); | ||
119 | if (ACPI_FAILURE(status)) { | ||
120 | return_ACPI_STATUS(status); | ||
121 | } | ||
122 | |||
123 | /* Get the size of the String to be returned, includes null terminator */ | ||
124 | |||
125 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
126 | length = ACPI_EISAID_STRING_SIZE; | ||
127 | } else { | ||
128 | length = obj_desc->string.length + 1; | ||
129 | } | ||
130 | |||
131 | /* Allocate a buffer for the HID */ | ||
132 | |||
133 | hid = | ||
134 | ACPI_ALLOCATE_ZEROED(sizeof(struct acpica_device_id) + | ||
135 | (acpi_size) length); | ||
136 | if (!hid) { | ||
137 | status = AE_NO_MEMORY; | ||
138 | goto cleanup; | ||
139 | } | ||
140 | |||
141 | /* Area for the string starts after DEVICE_ID struct */ | ||
142 | |||
143 | hid->string = ACPI_ADD_PTR(char, hid, sizeof(struct acpica_device_id)); | ||
144 | |||
145 | /* Convert EISAID to a string or simply copy existing string */ | ||
146 | |||
147 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
148 | acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value); | ||
149 | } else { | ||
150 | acpi_ut_copy_id_string(hid->string, obj_desc->string.pointer); | ||
151 | } | ||
152 | |||
153 | hid->length = length; | ||
154 | *return_id = hid; | ||
155 | |||
156 | cleanup: | ||
157 | |||
158 | /* On exit, we must delete the return object */ | ||
159 | |||
160 | acpi_ut_remove_reference(obj_desc); | ||
161 | return_ACPI_STATUS(status); | ||
162 | } | ||
163 | |||
164 | /******************************************************************************* | ||
165 | * | ||
166 | * FUNCTION: acpi_ut_execute_UID | ||
167 | * | ||
168 | * PARAMETERS: device_node - Node for the device | ||
169 | * return_id - Where the string UID is returned | ||
170 | * | ||
171 | * RETURN: Status | ||
172 | * | ||
173 | * DESCRIPTION: Executes the _UID control method that returns the unique | ||
174 | * ID of the device. The UID is either a 64-bit Integer (NOT an | ||
175 | * EISAID) or a string. Always returns a string. A 64-bit integer | ||
176 | * is converted to a decimal string. | ||
177 | * | ||
178 | * NOTE: Internal function, no parameter validation | ||
179 | * | ||
180 | ******************************************************************************/ | ||
181 | |||
182 | acpi_status | ||
183 | acpi_ut_execute_UID(struct acpi_namespace_node *device_node, | ||
184 | struct acpica_device_id **return_id) | ||
185 | { | ||
186 | union acpi_operand_object *obj_desc; | ||
187 | struct acpica_device_id *uid; | ||
188 | u32 length; | ||
189 | acpi_status status; | ||
190 | |||
191 | ACPI_FUNCTION_TRACE(ut_execute_UID); | ||
192 | |||
193 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID, | ||
194 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, | ||
195 | &obj_desc); | ||
196 | if (ACPI_FAILURE(status)) { | ||
197 | return_ACPI_STATUS(status); | ||
198 | } | ||
199 | |||
200 | /* Get the size of the String to be returned, includes null terminator */ | ||
201 | |||
202 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
203 | length = ACPI_MAX64_DECIMAL_DIGITS + 1; | ||
204 | } else { | ||
205 | length = obj_desc->string.length + 1; | ||
206 | } | ||
207 | |||
208 | /* Allocate a buffer for the UID */ | ||
209 | |||
210 | uid = | ||
211 | ACPI_ALLOCATE_ZEROED(sizeof(struct acpica_device_id) + | ||
212 | (acpi_size) length); | ||
213 | if (!uid) { | ||
214 | status = AE_NO_MEMORY; | ||
215 | goto cleanup; | ||
216 | } | ||
217 | |||
218 | /* Area for the string starts after DEVICE_ID struct */ | ||
219 | |||
220 | uid->string = ACPI_ADD_PTR(char, uid, sizeof(struct acpica_device_id)); | ||
221 | |||
222 | /* Convert an Integer to string, or just copy an existing string */ | ||
223 | |||
224 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
225 | acpi_ex_integer_to_string(uid->string, obj_desc->integer.value); | ||
226 | } else { | ||
227 | acpi_ut_copy_id_string(uid->string, obj_desc->string.pointer); | ||
228 | } | ||
229 | |||
230 | uid->length = length; | ||
231 | *return_id = uid; | ||
232 | |||
233 | cleanup: | ||
234 | |||
235 | /* On exit, we must delete the return object */ | ||
236 | |||
237 | acpi_ut_remove_reference(obj_desc); | ||
238 | return_ACPI_STATUS(status); | ||
239 | } | ||
240 | |||
241 | /******************************************************************************* | ||
242 | * | ||
243 | * FUNCTION: acpi_ut_execute_CID | ||
244 | * | ||
245 | * PARAMETERS: device_node - Node for the device | ||
246 | * return_cid_list - Where the CID list is returned | ||
247 | * | ||
248 | * RETURN: Status, list of CID strings | ||
249 | * | ||
250 | * DESCRIPTION: Executes the _CID control method that returns one or more | ||
251 | * compatible hardware IDs for the device. | ||
252 | * | ||
253 | * NOTE: Internal function, no parameter validation | ||
254 | * | ||
255 | * A _CID method can return either a single compatible ID or a package of | ||
256 | * compatible IDs. Each compatible ID can be one of the following: | ||
257 | * 1) Integer (32 bit compressed EISA ID) or | ||
258 | * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss") | ||
259 | * | ||
260 | * The Integer CIDs are converted to string format by this function. | ||
261 | * | ||
262 | ******************************************************************************/ | ||
263 | |||
264 | acpi_status | ||
265 | acpi_ut_execute_CID(struct acpi_namespace_node *device_node, | ||
266 | struct acpica_device_id_list **return_cid_list) | ||
267 | { | ||
268 | union acpi_operand_object **cid_objects; | ||
269 | union acpi_operand_object *obj_desc; | ||
270 | struct acpica_device_id_list *cid_list; | ||
271 | char *next_id_string; | ||
272 | u32 string_area_size; | ||
273 | u32 length; | ||
274 | u32 cid_list_size; | ||
275 | acpi_status status; | ||
276 | u32 count; | ||
277 | u32 i; | ||
278 | |||
279 | ACPI_FUNCTION_TRACE(ut_execute_CID); | ||
280 | |||
281 | /* Evaluate the _CID method for this device */ | ||
282 | |||
283 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID, | ||
284 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ||
285 | | ACPI_BTYPE_PACKAGE, &obj_desc); | ||
286 | if (ACPI_FAILURE(status)) { | ||
287 | return_ACPI_STATUS(status); | ||
288 | } | ||
289 | |||
290 | /* | ||
291 | * Get the count and size of the returned _CIDs. _CID can return either | ||
292 | * a Package of Integers/Strings or a single Integer or String. | ||
293 | * Note: This section also validates that all CID elements are of the | ||
294 | * correct type (Integer or String). | ||
295 | */ | ||
296 | if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { | ||
297 | count = obj_desc->package.count; | ||
298 | cid_objects = obj_desc->package.elements; | ||
299 | } else { /* Single Integer or String CID */ | ||
300 | |||
301 | count = 1; | ||
302 | cid_objects = &obj_desc; | ||
303 | } | ||
304 | |||
305 | string_area_size = 0; | ||
306 | for (i = 0; i < count; i++) { | ||
307 | |||
308 | /* String lengths include null terminator */ | ||
309 | |||
310 | switch (cid_objects[i]->common.type) { | ||
311 | case ACPI_TYPE_INTEGER: | ||
312 | string_area_size += ACPI_EISAID_STRING_SIZE; | ||
313 | break; | ||
314 | |||
315 | case ACPI_TYPE_STRING: | ||
316 | string_area_size += cid_objects[i]->string.length + 1; | ||
317 | break; | ||
318 | |||
319 | default: | ||
320 | status = AE_TYPE; | ||
321 | goto cleanup; | ||
322 | } | ||
323 | } | ||
324 | |||
325 | /* | ||
326 | * Now that we know the length of the CIDs, allocate return buffer: | ||
327 | * 1) Size of the base structure + | ||
328 | * 2) Size of the CID DEVICE_ID array + | ||
329 | * 3) Size of the actual CID strings | ||
330 | */ | ||
331 | cid_list_size = sizeof(struct acpica_device_id_list) + | ||
332 | ((count - 1) * sizeof(struct acpica_device_id)) + string_area_size; | ||
333 | |||
334 | cid_list = ACPI_ALLOCATE_ZEROED(cid_list_size); | ||
335 | if (!cid_list) { | ||
336 | status = AE_NO_MEMORY; | ||
337 | goto cleanup; | ||
338 | } | ||
339 | |||
340 | /* Area for CID strings starts after the CID DEVICE_ID array */ | ||
341 | |||
342 | next_id_string = ACPI_CAST_PTR(char, cid_list->ids) + | ||
343 | ((acpi_size) count * sizeof(struct acpica_device_id)); | ||
344 | |||
345 | /* Copy/convert the CIDs to the return buffer */ | ||
346 | |||
347 | for (i = 0; i < count; i++) { | ||
348 | if (cid_objects[i]->common.type == ACPI_TYPE_INTEGER) { | ||
349 | |||
350 | /* Convert the Integer (EISAID) CID to a string */ | ||
351 | |||
352 | acpi_ex_eisa_id_to_string(next_id_string, | ||
353 | cid_objects[i]->integer. | ||
354 | value); | ||
355 | length = ACPI_EISAID_STRING_SIZE; | ||
356 | } else { /* ACPI_TYPE_STRING */ | ||
357 | |||
358 | /* Copy the String CID from the returned object */ | ||
359 | |||
360 | acpi_ut_copy_id_string(next_id_string, | ||
361 | cid_objects[i]->string.pointer); | ||
362 | length = cid_objects[i]->string.length + 1; | ||
363 | } | ||
364 | |||
365 | cid_list->ids[i].string = next_id_string; | ||
366 | cid_list->ids[i].length = length; | ||
367 | next_id_string += length; | ||
368 | } | ||
369 | |||
370 | /* Finish the CID list */ | ||
371 | |||
372 | cid_list->count = count; | ||
373 | cid_list->list_size = cid_list_size; | ||
374 | *return_cid_list = cid_list; | ||
375 | |||
376 | cleanup: | ||
377 | |||
378 | /* On exit, we must delete the _CID return object */ | ||
379 | |||
380 | acpi_ut_remove_reference(obj_desc); | ||
381 | return_ACPI_STATUS(status); | ||
382 | } | ||
diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index a54ca84eb362..9d0919ebf7b0 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c | |||
@@ -99,33 +99,19 @@ static void acpi_ut_terminate(void) | |||
99 | * | 99 | * |
100 | * FUNCTION: acpi_ut_subsystem_shutdown | 100 | * FUNCTION: acpi_ut_subsystem_shutdown |
101 | * | 101 | * |
102 | * PARAMETERS: none | 102 | * PARAMETERS: None |
103 | * | 103 | * |
104 | * RETURN: none | 104 | * RETURN: None |
105 | * | 105 | * |
106 | * DESCRIPTION: Shutdown the various subsystems. Don't delete the mutex | 106 | * DESCRIPTION: Shutdown the various components. Do not delete the mutex |
107 | * objects here -- because the AML debugger may be still running. | 107 | * objects here, because the AML debugger may be still running. |
108 | * | 108 | * |
109 | ******************************************************************************/ | 109 | ******************************************************************************/ |
110 | 110 | ||
111 | void acpi_ut_subsystem_shutdown(void) | 111 | void acpi_ut_subsystem_shutdown(void) |
112 | { | 112 | { |
113 | |||
114 | ACPI_FUNCTION_TRACE(ut_subsystem_shutdown); | 113 | ACPI_FUNCTION_TRACE(ut_subsystem_shutdown); |
115 | 114 | ||
116 | /* Just exit if subsystem is already shutdown */ | ||
117 | |||
118 | if (acpi_gbl_shutdown) { | ||
119 | ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated")); | ||
120 | return_VOID; | ||
121 | } | ||
122 | |||
123 | /* Subsystem appears active, go ahead and shut it down */ | ||
124 | |||
125 | acpi_gbl_shutdown = TRUE; | ||
126 | acpi_gbl_startup_flags = 0; | ||
127 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n")); | ||
128 | |||
129 | #ifndef ACPI_ASL_COMPILER | 115 | #ifndef ACPI_ASL_COMPILER |
130 | 116 | ||
131 | /* Close the acpi_event Handling */ | 117 | /* Close the acpi_event Handling */ |
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index fbe782348b0b..61f6315fce9f 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c | |||
@@ -50,6 +50,11 @@ | |||
50 | #define _COMPONENT ACPI_UTILITIES | 50 | #define _COMPONENT ACPI_UTILITIES |
51 | ACPI_MODULE_NAME("utmisc") | 51 | ACPI_MODULE_NAME("utmisc") |
52 | 52 | ||
53 | /* | ||
54 | * Common suffix for messages | ||
55 | */ | ||
56 | #define ACPI_COMMON_MSG_SUFFIX \ | ||
57 | acpi_os_printf(" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number) | ||
53 | /******************************************************************************* | 58 | /******************************************************************************* |
54 | * | 59 | * |
55 | * FUNCTION: acpi_ut_validate_exception | 60 | * FUNCTION: acpi_ut_validate_exception |
@@ -120,6 +125,34 @@ const char *acpi_ut_validate_exception(acpi_status status) | |||
120 | 125 | ||
121 | /******************************************************************************* | 126 | /******************************************************************************* |
122 | * | 127 | * |
128 | * FUNCTION: acpi_ut_is_pci_root_bridge | ||
129 | * | ||
130 | * PARAMETERS: Id - The HID/CID in string format | ||
131 | * | ||
132 | * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge | ||
133 | * | ||
134 | * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. | ||
135 | * | ||
136 | ******************************************************************************/ | ||
137 | |||
138 | u8 acpi_ut_is_pci_root_bridge(char *id) | ||
139 | { | ||
140 | |||
141 | /* | ||
142 | * Check if this is a PCI root bridge. | ||
143 | * ACPI 3.0+: check for a PCI Express root also. | ||
144 | */ | ||
145 | if (!(ACPI_STRCMP(id, | ||
146 | PCI_ROOT_HID_STRING)) || | ||
147 | !(ACPI_STRCMP(id, PCI_EXPRESS_ROOT_HID_STRING))) { | ||
148 | return (TRUE); | ||
149 | } | ||
150 | |||
151 | return (FALSE); | ||
152 | } | ||
153 | |||
154 | /******************************************************************************* | ||
155 | * | ||
123 | * FUNCTION: acpi_ut_is_aml_table | 156 | * FUNCTION: acpi_ut_is_aml_table |
124 | * | 157 | * |
125 | * PARAMETERS: Table - An ACPI table | 158 | * PARAMETERS: Table - An ACPI table |
@@ -1037,8 +1070,7 @@ acpi_error(const char *module_name, u32 line_number, const char *format, ...) | |||
1037 | 1070 | ||
1038 | va_start(args, format); | 1071 | va_start(args, format); |
1039 | acpi_os_vprintf(format, args); | 1072 | acpi_os_vprintf(format, args); |
1040 | acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, | 1073 | ACPI_COMMON_MSG_SUFFIX; |
1041 | line_number); | ||
1042 | va_end(args); | 1074 | va_end(args); |
1043 | } | 1075 | } |
1044 | 1076 | ||
@@ -1052,8 +1084,7 @@ acpi_exception(const char *module_name, | |||
1052 | 1084 | ||
1053 | va_start(args, format); | 1085 | va_start(args, format); |
1054 | acpi_os_vprintf(format, args); | 1086 | acpi_os_vprintf(format, args); |
1055 | acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, | 1087 | ACPI_COMMON_MSG_SUFFIX; |
1056 | line_number); | ||
1057 | va_end(args); | 1088 | va_end(args); |
1058 | } | 1089 | } |
1059 | 1090 | ||
@@ -1066,8 +1097,7 @@ acpi_warning(const char *module_name, u32 line_number, const char *format, ...) | |||
1066 | 1097 | ||
1067 | va_start(args, format); | 1098 | va_start(args, format); |
1068 | acpi_os_vprintf(format, args); | 1099 | acpi_os_vprintf(format, args); |
1069 | acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, | 1100 | ACPI_COMMON_MSG_SUFFIX; |
1070 | line_number); | ||
1071 | va_end(args); | 1101 | va_end(args); |
1072 | } | 1102 | } |
1073 | 1103 | ||
@@ -1088,3 +1118,46 @@ ACPI_EXPORT_SYMBOL(acpi_error) | |||
1088 | ACPI_EXPORT_SYMBOL(acpi_exception) | 1118 | ACPI_EXPORT_SYMBOL(acpi_exception) |
1089 | ACPI_EXPORT_SYMBOL(acpi_warning) | 1119 | ACPI_EXPORT_SYMBOL(acpi_warning) |
1090 | ACPI_EXPORT_SYMBOL(acpi_info) | 1120 | ACPI_EXPORT_SYMBOL(acpi_info) |
1121 | |||
1122 | /******************************************************************************* | ||
1123 | * | ||
1124 | * FUNCTION: acpi_ut_predefined_warning | ||
1125 | * | ||
1126 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
1127 | * line_number - Caller's line number (for error output) | ||
1128 | * Pathname - Full pathname to the node | ||
1129 | * node_flags - From Namespace node for the method/object | ||
1130 | * Format - Printf format string + additional args | ||
1131 | * | ||
1132 | * RETURN: None | ||
1133 | * | ||
1134 | * DESCRIPTION: Warnings for the predefined validation module. Messages are | ||
1135 | * only emitted the first time a problem with a particular | ||
1136 | * method/object is detected. This prevents a flood of error | ||
1137 | * messages for methods that are repeatedly evaluated. | ||
1138 | * | ||
1139 | ******************************************************************************/ | ||
1140 | |||
1141 | void ACPI_INTERNAL_VAR_XFACE | ||
1142 | acpi_ut_predefined_warning(const char *module_name, | ||
1143 | u32 line_number, | ||
1144 | char *pathname, | ||
1145 | u8 node_flags, const char *format, ...) | ||
1146 | { | ||
1147 | va_list args; | ||
1148 | |||
1149 | /* | ||
1150 | * Warning messages for this method/object will be disabled after the | ||
1151 | * first time a validation fails or an object is successfully repaired. | ||
1152 | */ | ||
1153 | if (node_flags & ANOBJ_EVALUATED) { | ||
1154 | return; | ||
1155 | } | ||
1156 | |||
1157 | acpi_os_printf("ACPI Warning for %s: ", pathname); | ||
1158 | |||
1159 | va_start(args, format); | ||
1160 | acpi_os_vprintf(format, args); | ||
1161 | ACPI_COMMON_MSG_SUFFIX; | ||
1162 | va_end(args); | ||
1163 | } | ||
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 078a22728c6b..b1f5f680bc78 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c | |||
@@ -251,6 +251,16 @@ acpi_status acpi_initialize_objects(u32 flags) | |||
251 | } | 251 | } |
252 | 252 | ||
253 | /* | 253 | /* |
254 | * Execute any module-level code that was detected during the table load | ||
255 | * phase. Although illegal since ACPI 2.0, there are many machines that | ||
256 | * contain this type of code. Each block of detected executable AML code | ||
257 | * outside of any control method is wrapped with a temporary control | ||
258 | * method object and placed on a global list. The methods on this list | ||
259 | * are executed below. | ||
260 | */ | ||
261 | acpi_ns_exec_module_code_list(); | ||
262 | |||
263 | /* | ||
254 | * Initialize the objects that remain uninitialized. This runs the | 264 | * Initialize the objects that remain uninitialized. This runs the |
255 | * executable AML that may be part of the declaration of these objects: | 265 | * executable AML that may be part of the declaration of these objects: |
256 | * operation_regions, buffer_fields, Buffers, and Packages. | 266 | * operation_regions, buffer_fields, Buffers, and Packages. |
@@ -318,7 +328,7 @@ ACPI_EXPORT_SYMBOL(acpi_initialize_objects) | |||
318 | * | 328 | * |
319 | * RETURN: Status | 329 | * RETURN: Status |
320 | * | 330 | * |
321 | * DESCRIPTION: Shutdown the ACPI subsystem. Release all resources. | 331 | * DESCRIPTION: Shutdown the ACPICA subsystem and release all resources. |
322 | * | 332 | * |
323 | ******************************************************************************/ | 333 | ******************************************************************************/ |
324 | acpi_status acpi_terminate(void) | 334 | acpi_status acpi_terminate(void) |
@@ -327,6 +337,19 @@ acpi_status acpi_terminate(void) | |||
327 | 337 | ||
328 | ACPI_FUNCTION_TRACE(acpi_terminate); | 338 | ACPI_FUNCTION_TRACE(acpi_terminate); |
329 | 339 | ||
340 | /* Just exit if subsystem is already shutdown */ | ||
341 | |||
342 | if (acpi_gbl_shutdown) { | ||
343 | ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated")); | ||
344 | return_ACPI_STATUS(AE_OK); | ||
345 | } | ||
346 | |||
347 | /* Subsystem appears active, go ahead and shut it down */ | ||
348 | |||
349 | acpi_gbl_shutdown = TRUE; | ||
350 | acpi_gbl_startup_flags = 0; | ||
351 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n")); | ||
352 | |||
330 | /* Terminate the AML Debugger if present */ | 353 | /* Terminate the AML Debugger if present */ |
331 | 354 | ||
332 | ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE); | 355 | ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE); |
@@ -353,6 +376,7 @@ acpi_status acpi_terminate(void) | |||
353 | } | 376 | } |
354 | 377 | ||
355 | ACPI_EXPORT_SYMBOL(acpi_terminate) | 378 | ACPI_EXPORT_SYMBOL(acpi_terminate) |
379 | |||
356 | #ifndef ACPI_ASL_COMPILER | 380 | #ifndef ACPI_ASL_COMPILER |
357 | #ifdef ACPI_FUTURE_USAGE | 381 | #ifdef ACPI_FUTURE_USAGE |
358 | /******************************************************************************* | 382 | /******************************************************************************* |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 58b4517ce712..3f4602b8f287 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | #include <linux/jiffies.h> | 32 | #include <linux/jiffies.h> |
33 | #include <linux/async.h> | 33 | #include <linux/async.h> |
34 | #include <linux/dmi.h> | ||
34 | 35 | ||
35 | #ifdef CONFIG_ACPI_PROCFS_POWER | 36 | #ifdef CONFIG_ACPI_PROCFS_POWER |
36 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
@@ -45,6 +46,8 @@ | |||
45 | #include <linux/power_supply.h> | 46 | #include <linux/power_supply.h> |
46 | #endif | 47 | #endif |
47 | 48 | ||
49 | #define PREFIX "ACPI: " | ||
50 | |||
48 | #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF | 51 | #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF |
49 | 52 | ||
50 | #define ACPI_BATTERY_CLASS "battery" | 53 | #define ACPI_BATTERY_CLASS "battery" |
@@ -85,6 +88,10 @@ static const struct acpi_device_id battery_device_ids[] = { | |||
85 | 88 | ||
86 | MODULE_DEVICE_TABLE(acpi, battery_device_ids); | 89 | MODULE_DEVICE_TABLE(acpi, battery_device_ids); |
87 | 90 | ||
91 | /* For buggy DSDTs that report negative 16-bit values for either charging | ||
92 | * or discharging current and/or report 0 as 65536 due to bad math. | ||
93 | */ | ||
94 | #define QUIRK_SIGNED16_CURRENT 0x0001 | ||
88 | 95 | ||
89 | struct acpi_battery { | 96 | struct acpi_battery { |
90 | struct mutex lock; | 97 | struct mutex lock; |
@@ -112,6 +119,7 @@ struct acpi_battery { | |||
112 | int state; | 119 | int state; |
113 | int power_unit; | 120 | int power_unit; |
114 | u8 alarm_present; | 121 | u8 alarm_present; |
122 | long quirks; | ||
115 | }; | 123 | }; |
116 | 124 | ||
117 | #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); | 125 | #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); |
@@ -390,6 +398,11 @@ static int acpi_battery_get_state(struct acpi_battery *battery) | |||
390 | state_offsets, ARRAY_SIZE(state_offsets)); | 398 | state_offsets, ARRAY_SIZE(state_offsets)); |
391 | battery->update_time = jiffies; | 399 | battery->update_time = jiffies; |
392 | kfree(buffer.pointer); | 400 | kfree(buffer.pointer); |
401 | |||
402 | if ((battery->quirks & QUIRK_SIGNED16_CURRENT) && | ||
403 | battery->rate_now != -1) | ||
404 | battery->rate_now = abs((s16)battery->rate_now); | ||
405 | |||
393 | return result; | 406 | return result; |
394 | } | 407 | } |
395 | 408 | ||
@@ -495,6 +508,14 @@ static void sysfs_remove_battery(struct acpi_battery *battery) | |||
495 | } | 508 | } |
496 | #endif | 509 | #endif |
497 | 510 | ||
511 | static void acpi_battery_quirks(struct acpi_battery *battery) | ||
512 | { | ||
513 | battery->quirks = 0; | ||
514 | if (dmi_name_in_vendors("Acer") && battery->power_unit) { | ||
515 | battery->quirks |= QUIRK_SIGNED16_CURRENT; | ||
516 | } | ||
517 | } | ||
518 | |||
498 | static int acpi_battery_update(struct acpi_battery *battery) | 519 | static int acpi_battery_update(struct acpi_battery *battery) |
499 | { | 520 | { |
500 | int result, old_present = acpi_battery_present(battery); | 521 | int result, old_present = acpi_battery_present(battery); |
@@ -513,6 +534,7 @@ static int acpi_battery_update(struct acpi_battery *battery) | |||
513 | result = acpi_battery_get_info(battery); | 534 | result = acpi_battery_get_info(battery); |
514 | if (result) | 535 | if (result) |
515 | return result; | 536 | return result; |
537 | acpi_battery_quirks(battery); | ||
516 | acpi_battery_init_alarm(battery); | 538 | acpi_battery_init_alarm(battery); |
517 | } | 539 | } |
518 | #ifdef CONFIG_ACPI_SYSFS_POWER | 540 | #ifdef CONFIG_ACPI_SYSFS_POWER |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 0c4ca4d318b3..e56b2a7b53db 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include <acpi/acpi_bus.h> | 34 | #include <acpi/acpi_bus.h> |
35 | #include <linux/dmi.h> | 35 | #include <linux/dmi.h> |
36 | 36 | ||
37 | #include "internal.h" | ||
38 | |||
37 | enum acpi_blacklist_predicates { | 39 | enum acpi_blacklist_predicates { |
38 | all_versions, | 40 | all_versions, |
39 | less_than_or_equal, | 41 | less_than_or_equal, |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 2876fc70c3a9..135fbfe1825c 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
39 | #include <acpi/acpi_bus.h> | 39 | #include <acpi/acpi_bus.h> |
40 | #include <acpi/acpi_drivers.h> | 40 | #include <acpi/acpi_drivers.h> |
41 | #include <linux/dmi.h> | ||
41 | 42 | ||
42 | #include "internal.h" | 43 | #include "internal.h" |
43 | 44 | ||
@@ -141,7 +142,7 @@ int acpi_bus_get_status(struct acpi_device *device) | |||
141 | EXPORT_SYMBOL(acpi_bus_get_status); | 142 | EXPORT_SYMBOL(acpi_bus_get_status); |
142 | 143 | ||
143 | void acpi_bus_private_data_handler(acpi_handle handle, | 144 | void acpi_bus_private_data_handler(acpi_handle handle, |
144 | u32 function, void *context) | 145 | void *context) |
145 | { | 146 | { |
146 | return; | 147 | return; |
147 | } | 148 | } |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 9195deba9d94..d295bdccc09c 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include <acpi/acpi_bus.h> | 33 | #include <acpi/acpi_bus.h> |
34 | #include <acpi/acpi_drivers.h> | 34 | #include <acpi/acpi_drivers.h> |
35 | 35 | ||
36 | #define PREFIX "ACPI: " | ||
37 | |||
36 | #define ACPI_BUTTON_CLASS "button" | 38 | #define ACPI_BUTTON_CLASS "button" |
37 | #define ACPI_BUTTON_FILE_INFO "info" | 39 | #define ACPI_BUTTON_FILE_INFO "info" |
38 | #define ACPI_BUTTON_FILE_STATE "state" | 40 | #define ACPI_BUTTON_FILE_STATE "state" |
diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c index 332fe4b21708..6c9ee68e46fb 100644 --- a/drivers/acpi/cm_sbs.c +++ b/drivers/acpi/cm_sbs.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <acpi/acpi_bus.h> | 28 | #include <acpi/acpi_bus.h> |
29 | #include <acpi/acpi_drivers.h> | 29 | #include <acpi/acpi_drivers.h> |
30 | 30 | ||
31 | #define PREFIX "ACPI: " | ||
32 | |||
31 | ACPI_MODULE_NAME("cm_sbs"); | 33 | ACPI_MODULE_NAME("cm_sbs"); |
32 | #define ACPI_AC_CLASS "ac_adapter" | 34 | #define ACPI_AC_CLASS "ac_adapter" |
33 | #define ACPI_BATTERY_CLASS "battery" | 35 | #define ACPI_BATTERY_CLASS "battery" |
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index fe0cdf83641a..642bb305cb65 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c | |||
@@ -35,6 +35,8 @@ | |||
35 | #include <acpi/acpi_drivers.h> | 35 | #include <acpi/acpi_drivers.h> |
36 | #include <acpi/container.h> | 36 | #include <acpi/container.h> |
37 | 37 | ||
38 | #define PREFIX "ACPI: " | ||
39 | |||
38 | #define ACPI_CONTAINER_DEVICE_NAME "ACPI container device" | 40 | #define ACPI_CONTAINER_DEVICE_NAME "ACPI container device" |
39 | #define ACPI_CONTAINER_CLASS "container" | 41 | #define ACPI_CONTAINER_CLASS "container" |
40 | 42 | ||
@@ -200,20 +202,17 @@ container_walk_namespace_cb(acpi_handle handle, | |||
200 | u32 lvl, void *context, void **rv) | 202 | u32 lvl, void *context, void **rv) |
201 | { | 203 | { |
202 | char *hid = NULL; | 204 | char *hid = NULL; |
203 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
204 | struct acpi_device_info *info; | 205 | struct acpi_device_info *info; |
205 | acpi_status status; | 206 | acpi_status status; |
206 | int *action = context; | 207 | int *action = context; |
207 | 208 | ||
208 | 209 | status = acpi_get_object_info(handle, &info); | |
209 | status = acpi_get_object_info(handle, &buffer); | 210 | if (ACPI_FAILURE(status)) { |
210 | if (ACPI_FAILURE(status) || !buffer.pointer) { | ||
211 | return AE_OK; | 211 | return AE_OK; |
212 | } | 212 | } |
213 | 213 | ||
214 | info = buffer.pointer; | ||
215 | if (info->valid & ACPI_VALID_HID) | 214 | if (info->valid & ACPI_VALID_HID) |
216 | hid = info->hardware_id.value; | 215 | hid = info->hardware_id.string; |
217 | 216 | ||
218 | if (hid == NULL) { | 217 | if (hid == NULL) { |
219 | goto end; | 218 | goto end; |
@@ -240,7 +239,7 @@ container_walk_namespace_cb(acpi_handle handle, | |||
240 | } | 239 | } |
241 | 240 | ||
242 | end: | 241 | end: |
243 | kfree(buffer.pointer); | 242 | kfree(info); |
244 | 243 | ||
245 | return AE_OK; | 244 | return AE_OK; |
246 | } | 245 | } |
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c index a8287be0870e..8a690c3b8e23 100644 --- a/drivers/acpi/debug.c +++ b/drivers/acpi/debug.c | |||
@@ -3,6 +3,7 @@ | |||
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <linux/proc_fs.h> | 5 | #include <linux/proc_fs.h> |
6 | #include <linux/seq_file.h> | ||
6 | #include <linux/init.h> | 7 | #include <linux/init.h> |
7 | #include <linux/module.h> | 8 | #include <linux/module.h> |
8 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
@@ -201,72 +202,54 @@ module_param_call(trace_state, param_set_trace_state, param_get_trace_state, | |||
201 | #define ACPI_SYSTEM_FILE_DEBUG_LAYER "debug_layer" | 202 | #define ACPI_SYSTEM_FILE_DEBUG_LAYER "debug_layer" |
202 | #define ACPI_SYSTEM_FILE_DEBUG_LEVEL "debug_level" | 203 | #define ACPI_SYSTEM_FILE_DEBUG_LEVEL "debug_level" |
203 | 204 | ||
204 | static int | 205 | static int acpi_system_debug_proc_show(struct seq_file *m, void *v) |
205 | acpi_system_read_debug(char *page, | ||
206 | char **start, off_t off, int count, int *eof, void *data) | ||
207 | { | 206 | { |
208 | char *p = page; | ||
209 | int size = 0; | ||
210 | unsigned int i; | 207 | unsigned int i; |
211 | 208 | ||
212 | if (off != 0) | 209 | seq_printf(m, "%-25s\tHex SET\n", "Description"); |
213 | goto end; | ||
214 | 210 | ||
215 | p += sprintf(p, "%-25s\tHex SET\n", "Description"); | 211 | switch ((unsigned long)m->private) { |
216 | |||
217 | switch ((unsigned long)data) { | ||
218 | case 0: | 212 | case 0: |
219 | for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) { | 213 | for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) { |
220 | p += sprintf(p, "%-25s\t0x%08lX [%c]\n", | 214 | seq_printf(m, "%-25s\t0x%08lX [%c]\n", |
221 | acpi_debug_layers[i].name, | 215 | acpi_debug_layers[i].name, |
222 | acpi_debug_layers[i].value, | 216 | acpi_debug_layers[i].value, |
223 | (acpi_dbg_layer & acpi_debug_layers[i]. | 217 | (acpi_dbg_layer & acpi_debug_layers[i]. |
224 | value) ? '*' : ' '); | 218 | value) ? '*' : ' '); |
225 | } | 219 | } |
226 | p += sprintf(p, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS", | 220 | seq_printf(m, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS", |
227 | ACPI_ALL_DRIVERS, | 221 | ACPI_ALL_DRIVERS, |
228 | (acpi_dbg_layer & ACPI_ALL_DRIVERS) == | 222 | (acpi_dbg_layer & ACPI_ALL_DRIVERS) == |
229 | ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer & | 223 | ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer & |
230 | ACPI_ALL_DRIVERS) == | 224 | ACPI_ALL_DRIVERS) == |
231 | 0 ? ' ' : '-'); | 225 | 0 ? ' ' : '-'); |
232 | p += sprintf(p, | 226 | seq_printf(m, |
233 | "--\ndebug_layer = 0x%08X (* = enabled, - = partial)\n", | 227 | "--\ndebug_layer = 0x%08X (* = enabled, - = partial)\n", |
234 | acpi_dbg_layer); | 228 | acpi_dbg_layer); |
235 | break; | 229 | break; |
236 | case 1: | 230 | case 1: |
237 | for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) { | 231 | for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) { |
238 | p += sprintf(p, "%-25s\t0x%08lX [%c]\n", | 232 | seq_printf(m, "%-25s\t0x%08lX [%c]\n", |
239 | acpi_debug_levels[i].name, | 233 | acpi_debug_levels[i].name, |
240 | acpi_debug_levels[i].value, | 234 | acpi_debug_levels[i].value, |
241 | (acpi_dbg_level & acpi_debug_levels[i]. | 235 | (acpi_dbg_level & acpi_debug_levels[i]. |
242 | value) ? '*' : ' '); | 236 | value) ? '*' : ' '); |
243 | } | 237 | } |
244 | p += sprintf(p, "--\ndebug_level = 0x%08X (* = enabled)\n", | 238 | seq_printf(m, "--\ndebug_level = 0x%08X (* = enabled)\n", |
245 | acpi_dbg_level); | 239 | acpi_dbg_level); |
246 | break; | 240 | break; |
247 | default: | ||
248 | p += sprintf(p, "Invalid debug option\n"); | ||
249 | break; | ||
250 | } | 241 | } |
242 | return 0; | ||
243 | } | ||
251 | 244 | ||
252 | end: | 245 | static int acpi_system_debug_proc_open(struct inode *inode, struct file *file) |
253 | size = (p - page); | 246 | { |
254 | if (size <= off + count) | 247 | return single_open(file, acpi_system_debug_proc_show, PDE(inode)->data); |
255 | *eof = 1; | ||
256 | *start = page + off; | ||
257 | size -= off; | ||
258 | if (size > count) | ||
259 | size = count; | ||
260 | if (size < 0) | ||
261 | size = 0; | ||
262 | |||
263 | return size; | ||
264 | } | 248 | } |
265 | 249 | ||
266 | static int | 250 | static ssize_t acpi_system_debug_proc_write(struct file *file, |
267 | acpi_system_write_debug(struct file *file, | ||
268 | const char __user * buffer, | 251 | const char __user * buffer, |
269 | unsigned long count, void *data) | 252 | size_t count, loff_t *pos) |
270 | { | 253 | { |
271 | char debug_string[12] = { '\0' }; | 254 | char debug_string[12] = { '\0' }; |
272 | 255 | ||
@@ -279,7 +262,7 @@ acpi_system_write_debug(struct file *file, | |||
279 | 262 | ||
280 | debug_string[count] = '\0'; | 263 | debug_string[count] = '\0'; |
281 | 264 | ||
282 | switch ((unsigned long)data) { | 265 | switch ((unsigned long)PDE(file->f_path.dentry->d_inode)->data) { |
283 | case 0: | 266 | case 0: |
284 | acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0); | 267 | acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0); |
285 | break; | 268 | break; |
@@ -292,6 +275,15 @@ acpi_system_write_debug(struct file *file, | |||
292 | 275 | ||
293 | return count; | 276 | return count; |
294 | } | 277 | } |
278 | |||
279 | static const struct file_operations acpi_system_debug_proc_fops = { | ||
280 | .owner = THIS_MODULE, | ||
281 | .open = acpi_system_debug_proc_open, | ||
282 | .read = seq_read, | ||
283 | .llseek = seq_lseek, | ||
284 | .release = single_release, | ||
285 | .write = acpi_system_debug_proc_write, | ||
286 | }; | ||
295 | #endif | 287 | #endif |
296 | 288 | ||
297 | int __init acpi_debug_init(void) | 289 | int __init acpi_debug_init(void) |
@@ -303,24 +295,18 @@ int __init acpi_debug_init(void) | |||
303 | 295 | ||
304 | /* 'debug_layer' [R/W] */ | 296 | /* 'debug_layer' [R/W] */ |
305 | name = ACPI_SYSTEM_FILE_DEBUG_LAYER; | 297 | name = ACPI_SYSTEM_FILE_DEBUG_LAYER; |
306 | entry = | 298 | entry = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR, |
307 | create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR, | 299 | acpi_root_dir, &acpi_system_debug_proc_fops, |
308 | acpi_root_dir, acpi_system_read_debug, | 300 | (void *)0); |
309 | (void *)0); | 301 | if (!entry) |
310 | if (entry) | ||
311 | entry->write_proc = acpi_system_write_debug; | ||
312 | else | ||
313 | goto Error; | 302 | goto Error; |
314 | 303 | ||
315 | /* 'debug_level' [R/W] */ | 304 | /* 'debug_level' [R/W] */ |
316 | name = ACPI_SYSTEM_FILE_DEBUG_LEVEL; | 305 | name = ACPI_SYSTEM_FILE_DEBUG_LEVEL; |
317 | entry = | 306 | entry = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR, |
318 | create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR, | 307 | acpi_root_dir, &acpi_system_debug_proc_fops, |
319 | acpi_root_dir, acpi_system_read_debug, | 308 | (void *)1); |
320 | (void *)1); | 309 | if (!entry) |
321 | if (entry) | ||
322 | entry->write_proc = acpi_system_write_debug; | ||
323 | else | ||
324 | goto Error; | 310 | goto Error; |
325 | 311 | ||
326 | Done: | 312 | Done: |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index efb959d6c8a9..3a2cfefc71ab 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include <acpi/acpi_bus.h> | 33 | #include <acpi/acpi_bus.h> |
34 | #include <acpi/acpi_drivers.h> | 34 | #include <acpi/acpi_drivers.h> |
35 | 35 | ||
36 | #define PREFIX "ACPI: " | ||
37 | |||
36 | #define ACPI_DOCK_DRIVER_DESCRIPTION "ACPI Dock Station Driver" | 38 | #define ACPI_DOCK_DRIVER_DESCRIPTION "ACPI Dock Station Driver" |
37 | 39 | ||
38 | ACPI_MODULE_NAME("dock"); | 40 | ACPI_MODULE_NAME("dock"); |
@@ -231,18 +233,16 @@ static int is_ata(acpi_handle handle) | |||
231 | static int is_battery(acpi_handle handle) | 233 | static int is_battery(acpi_handle handle) |
232 | { | 234 | { |
233 | struct acpi_device_info *info; | 235 | struct acpi_device_info *info; |
234 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
235 | int ret = 1; | 236 | int ret = 1; |
236 | 237 | ||
237 | if (!ACPI_SUCCESS(acpi_get_object_info(handle, &buffer))) | 238 | if (!ACPI_SUCCESS(acpi_get_object_info(handle, &info))) |
238 | return 0; | 239 | return 0; |
239 | info = buffer.pointer; | ||
240 | if (!(info->valid & ACPI_VALID_HID)) | 240 | if (!(info->valid & ACPI_VALID_HID)) |
241 | ret = 0; | 241 | ret = 0; |
242 | else | 242 | else |
243 | ret = !strcmp("PNP0C0A", info->hardware_id.value); | 243 | ret = !strcmp("PNP0C0A", info->hardware_id.string); |
244 | 244 | ||
245 | kfree(buffer.pointer); | 245 | kfree(info); |
246 | return ret; | 246 | return ret; |
247 | } | 247 | } |
248 | 248 | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 391f331674c7..f70796081c4c 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -42,12 +42,12 @@ | |||
42 | #include <asm/io.h> | 42 | #include <asm/io.h> |
43 | #include <acpi/acpi_bus.h> | 43 | #include <acpi/acpi_bus.h> |
44 | #include <acpi/acpi_drivers.h> | 44 | #include <acpi/acpi_drivers.h> |
45 | #include <linux/dmi.h> | ||
45 | 46 | ||
46 | #define ACPI_EC_CLASS "embedded_controller" | 47 | #define ACPI_EC_CLASS "embedded_controller" |
47 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" | 48 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" |
48 | #define ACPI_EC_FILE_INFO "info" | 49 | #define ACPI_EC_FILE_INFO "info" |
49 | 50 | ||
50 | #undef PREFIX | ||
51 | #define PREFIX "ACPI: EC: " | 51 | #define PREFIX "ACPI: EC: " |
52 | 52 | ||
53 | /* EC status register */ | 53 | /* EC status register */ |
@@ -68,15 +68,13 @@ enum ec_command { | |||
68 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ | 68 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ |
69 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ | 69 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
70 | #define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */ | 70 | #define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */ |
71 | #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ | ||
71 | 72 | ||
72 | #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts | 73 | #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts |
73 | per one transaction */ | 74 | per one transaction */ |
74 | 75 | ||
75 | enum { | 76 | enum { |
76 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ | 77 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ |
77 | EC_FLAGS_GPE_MODE, /* Expect GPE to be sent | ||
78 | * for status change */ | ||
79 | EC_FLAGS_NO_GPE, /* Don't use GPE mode */ | ||
80 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ | 78 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ |
81 | EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and | 79 | EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and |
82 | * OpReg are installed */ | 80 | * OpReg are installed */ |
@@ -170,7 +168,7 @@ static void start_transaction(struct acpi_ec *ec) | |||
170 | acpi_ec_write_cmd(ec, ec->curr->command); | 168 | acpi_ec_write_cmd(ec, ec->curr->command); |
171 | } | 169 | } |
172 | 170 | ||
173 | static void gpe_transaction(struct acpi_ec *ec, u8 status) | 171 | static void advance_transaction(struct acpi_ec *ec, u8 status) |
174 | { | 172 | { |
175 | unsigned long flags; | 173 | unsigned long flags; |
176 | spin_lock_irqsave(&ec->curr_lock, flags); | 174 | spin_lock_irqsave(&ec->curr_lock, flags); |
@@ -201,29 +199,6 @@ unlock: | |||
201 | spin_unlock_irqrestore(&ec->curr_lock, flags); | 199 | spin_unlock_irqrestore(&ec->curr_lock, flags); |
202 | } | 200 | } |
203 | 201 | ||
204 | static int acpi_ec_wait(struct acpi_ec *ec) | ||
205 | { | ||
206 | if (wait_event_timeout(ec->wait, ec_transaction_done(ec), | ||
207 | msecs_to_jiffies(ACPI_EC_DELAY))) | ||
208 | return 0; | ||
209 | /* try restart command if we get any false interrupts */ | ||
210 | if (ec->curr->irq_count && | ||
211 | (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) { | ||
212 | pr_debug(PREFIX "controller reset, restart transaction\n"); | ||
213 | start_transaction(ec); | ||
214 | if (wait_event_timeout(ec->wait, ec_transaction_done(ec), | ||
215 | msecs_to_jiffies(ACPI_EC_DELAY))) | ||
216 | return 0; | ||
217 | } | ||
218 | /* missing GPEs, switch back to poll mode */ | ||
219 | if (printk_ratelimit()) | ||
220 | pr_info(PREFIX "missing confirmations, " | ||
221 | "switch off interrupt mode.\n"); | ||
222 | set_bit(EC_FLAGS_NO_GPE, &ec->flags); | ||
223 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
224 | return 1; | ||
225 | } | ||
226 | |||
227 | static void acpi_ec_gpe_query(void *ec_cxt); | 202 | static void acpi_ec_gpe_query(void *ec_cxt); |
228 | 203 | ||
229 | static int ec_check_sci(struct acpi_ec *ec, u8 state) | 204 | static int ec_check_sci(struct acpi_ec *ec, u8 state) |
@@ -236,43 +211,51 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state) | |||
236 | return 0; | 211 | return 0; |
237 | } | 212 | } |
238 | 213 | ||
239 | static void ec_delay(void) | ||
240 | { | ||
241 | /* EC in MSI notebooks don't tolerate delays other than 550 usec */ | ||
242 | if (EC_FLAGS_MSI) | ||
243 | udelay(ACPI_EC_DELAY); | ||
244 | else | ||
245 | /* Use shortest sleep available */ | ||
246 | msleep(1); | ||
247 | } | ||
248 | |||
249 | static int ec_poll(struct acpi_ec *ec) | 214 | static int ec_poll(struct acpi_ec *ec) |
250 | { | 215 | { |
251 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); | 216 | unsigned long flags; |
252 | udelay(ACPI_EC_CDELAY); | 217 | int repeat = 2; /* number of command restarts */ |
253 | while (time_before(jiffies, delay)) { | 218 | while (repeat--) { |
254 | gpe_transaction(ec, acpi_ec_read_status(ec)); | 219 | unsigned long delay = jiffies + |
255 | ec_delay(); | 220 | msecs_to_jiffies(ACPI_EC_DELAY); |
256 | if (ec_transaction_done(ec)) | 221 | do { |
257 | return 0; | 222 | /* don't sleep with disabled interrupts */ |
223 | if (EC_FLAGS_MSI || irqs_disabled()) { | ||
224 | udelay(ACPI_EC_MSI_UDELAY); | ||
225 | if (ec_transaction_done(ec)) | ||
226 | return 0; | ||
227 | } else { | ||
228 | if (wait_event_timeout(ec->wait, | ||
229 | ec_transaction_done(ec), | ||
230 | msecs_to_jiffies(1))) | ||
231 | return 0; | ||
232 | } | ||
233 | advance_transaction(ec, acpi_ec_read_status(ec)); | ||
234 | } while (time_before(jiffies, delay)); | ||
235 | if (!ec->curr->irq_count || | ||
236 | (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)) | ||
237 | break; | ||
238 | /* try restart command if we get any false interrupts */ | ||
239 | pr_debug(PREFIX "controller reset, restart transaction\n"); | ||
240 | spin_lock_irqsave(&ec->curr_lock, flags); | ||
241 | start_transaction(ec); | ||
242 | spin_unlock_irqrestore(&ec->curr_lock, flags); | ||
258 | } | 243 | } |
259 | return -ETIME; | 244 | return -ETIME; |
260 | } | 245 | } |
261 | 246 | ||
262 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | 247 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, |
263 | struct transaction *t, | 248 | struct transaction *t) |
264 | int force_poll) | ||
265 | { | 249 | { |
266 | unsigned long tmp; | 250 | unsigned long tmp; |
267 | int ret = 0; | 251 | int ret = 0; |
268 | pr_debug(PREFIX "transaction start\n"); | 252 | pr_debug(PREFIX "transaction start\n"); |
269 | /* disable GPE during transaction if storm is detected */ | 253 | /* disable GPE during transaction if storm is detected */ |
270 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 254 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
271 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
272 | acpi_disable_gpe(NULL, ec->gpe); | 255 | acpi_disable_gpe(NULL, ec->gpe); |
273 | } | 256 | } |
274 | if (EC_FLAGS_MSI) | 257 | if (EC_FLAGS_MSI) |
275 | udelay(ACPI_EC_DELAY); | 258 | udelay(ACPI_EC_MSI_UDELAY); |
276 | /* start transaction */ | 259 | /* start transaction */ |
277 | spin_lock_irqsave(&ec->curr_lock, tmp); | 260 | spin_lock_irqsave(&ec->curr_lock, tmp); |
278 | /* following two actions should be kept atomic */ | 261 | /* following two actions should be kept atomic */ |
@@ -281,11 +264,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
281 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) | 264 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) |
282 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 265 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
283 | spin_unlock_irqrestore(&ec->curr_lock, tmp); | 266 | spin_unlock_irqrestore(&ec->curr_lock, tmp); |
284 | /* if we selected poll mode or failed in GPE-mode do a poll loop */ | 267 | ret = ec_poll(ec); |
285 | if (force_poll || | ||
286 | !test_bit(EC_FLAGS_GPE_MODE, &ec->flags) || | ||
287 | acpi_ec_wait(ec)) | ||
288 | ret = ec_poll(ec); | ||
289 | pr_debug(PREFIX "transaction end\n"); | 268 | pr_debug(PREFIX "transaction end\n"); |
290 | spin_lock_irqsave(&ec->curr_lock, tmp); | 269 | spin_lock_irqsave(&ec->curr_lock, tmp); |
291 | ec->curr = NULL; | 270 | ec->curr = NULL; |
@@ -295,8 +274,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
295 | ec_check_sci(ec, acpi_ec_read_status(ec)); | 274 | ec_check_sci(ec, acpi_ec_read_status(ec)); |
296 | /* it is safe to enable GPE outside of transaction */ | 275 | /* it is safe to enable GPE outside of transaction */ |
297 | acpi_enable_gpe(NULL, ec->gpe); | 276 | acpi_enable_gpe(NULL, ec->gpe); |
298 | } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && | 277 | } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) { |
299 | t->irq_count > ACPI_EC_STORM_THRESHOLD) { | ||
300 | pr_info(PREFIX "GPE storm detected, " | 278 | pr_info(PREFIX "GPE storm detected, " |
301 | "transactions will use polling mode\n"); | 279 | "transactions will use polling mode\n"); |
302 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); | 280 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); |
@@ -314,16 +292,14 @@ static int ec_wait_ibf0(struct acpi_ec *ec) | |||
314 | { | 292 | { |
315 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); | 293 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); |
316 | /* interrupt wait manually if GPE mode is not active */ | 294 | /* interrupt wait manually if GPE mode is not active */ |
317 | unsigned long timeout = test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ? | ||
318 | msecs_to_jiffies(ACPI_EC_DELAY) : msecs_to_jiffies(1); | ||
319 | while (time_before(jiffies, delay)) | 295 | while (time_before(jiffies, delay)) |
320 | if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), timeout)) | 296 | if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), |
297 | msecs_to_jiffies(1))) | ||
321 | return 0; | 298 | return 0; |
322 | return -ETIME; | 299 | return -ETIME; |
323 | } | 300 | } |
324 | 301 | ||
325 | static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t, | 302 | static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) |
326 | int force_poll) | ||
327 | { | 303 | { |
328 | int status; | 304 | int status; |
329 | u32 glk; | 305 | u32 glk; |
@@ -345,7 +321,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t, | |||
345 | status = -ETIME; | 321 | status = -ETIME; |
346 | goto end; | 322 | goto end; |
347 | } | 323 | } |
348 | status = acpi_ec_transaction_unlocked(ec, t, force_poll); | 324 | status = acpi_ec_transaction_unlocked(ec, t); |
349 | end: | 325 | end: |
350 | if (ec->global_lock) | 326 | if (ec->global_lock) |
351 | acpi_release_global_lock(glk); | 327 | acpi_release_global_lock(glk); |
@@ -354,10 +330,6 @@ unlock: | |||
354 | return status; | 330 | return status; |
355 | } | 331 | } |
356 | 332 | ||
357 | /* | ||
358 | * Note: samsung nv5000 doesn't work with ec burst mode. | ||
359 | * http://bugzilla.kernel.org/show_bug.cgi?id=4980 | ||
360 | */ | ||
361 | static int acpi_ec_burst_enable(struct acpi_ec *ec) | 333 | static int acpi_ec_burst_enable(struct acpi_ec *ec) |
362 | { | 334 | { |
363 | u8 d; | 335 | u8 d; |
@@ -365,7 +337,7 @@ static int acpi_ec_burst_enable(struct acpi_ec *ec) | |||
365 | .wdata = NULL, .rdata = &d, | 337 | .wdata = NULL, .rdata = &d, |
366 | .wlen = 0, .rlen = 1}; | 338 | .wlen = 0, .rlen = 1}; |
367 | 339 | ||
368 | return acpi_ec_transaction(ec, &t, 0); | 340 | return acpi_ec_transaction(ec, &t); |
369 | } | 341 | } |
370 | 342 | ||
371 | static int acpi_ec_burst_disable(struct acpi_ec *ec) | 343 | static int acpi_ec_burst_disable(struct acpi_ec *ec) |
@@ -375,7 +347,7 @@ static int acpi_ec_burst_disable(struct acpi_ec *ec) | |||
375 | .wlen = 0, .rlen = 0}; | 347 | .wlen = 0, .rlen = 0}; |
376 | 348 | ||
377 | return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? | 349 | return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? |
378 | acpi_ec_transaction(ec, &t, 0) : 0; | 350 | acpi_ec_transaction(ec, &t) : 0; |
379 | } | 351 | } |
380 | 352 | ||
381 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) | 353 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) |
@@ -386,7 +358,7 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) | |||
386 | .wdata = &address, .rdata = &d, | 358 | .wdata = &address, .rdata = &d, |
387 | .wlen = 1, .rlen = 1}; | 359 | .wlen = 1, .rlen = 1}; |
388 | 360 | ||
389 | result = acpi_ec_transaction(ec, &t, 0); | 361 | result = acpi_ec_transaction(ec, &t); |
390 | *data = d; | 362 | *data = d; |
391 | return result; | 363 | return result; |
392 | } | 364 | } |
@@ -398,7 +370,7 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) | |||
398 | .wdata = wdata, .rdata = NULL, | 370 | .wdata = wdata, .rdata = NULL, |
399 | .wlen = 2, .rlen = 0}; | 371 | .wlen = 2, .rlen = 0}; |
400 | 372 | ||
401 | return acpi_ec_transaction(ec, &t, 0); | 373 | return acpi_ec_transaction(ec, &t); |
402 | } | 374 | } |
403 | 375 | ||
404 | /* | 376 | /* |
@@ -466,7 +438,7 @@ int ec_transaction(u8 command, | |||
466 | if (!first_ec) | 438 | if (!first_ec) |
467 | return -ENODEV; | 439 | return -ENODEV; |
468 | 440 | ||
469 | return acpi_ec_transaction(first_ec, &t, force_poll); | 441 | return acpi_ec_transaction(first_ec, &t); |
470 | } | 442 | } |
471 | 443 | ||
472 | EXPORT_SYMBOL(ec_transaction); | 444 | EXPORT_SYMBOL(ec_transaction); |
@@ -487,7 +459,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data) | |||
487 | * bit to be cleared (and thus clearing the interrupt source). | 459 | * bit to be cleared (and thus clearing the interrupt source). |
488 | */ | 460 | */ |
489 | 461 | ||
490 | result = acpi_ec_transaction(ec, &t, 0); | 462 | result = acpi_ec_transaction(ec, &t); |
491 | if (result) | 463 | if (result) |
492 | return result; | 464 | return result; |
493 | 465 | ||
@@ -570,28 +542,10 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
570 | pr_debug(PREFIX "~~~> interrupt\n"); | 542 | pr_debug(PREFIX "~~~> interrupt\n"); |
571 | status = acpi_ec_read_status(ec); | 543 | status = acpi_ec_read_status(ec); |
572 | 544 | ||
573 | if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) { | 545 | advance_transaction(ec, status); |
574 | gpe_transaction(ec, status); | 546 | if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0) |
575 | if (ec_transaction_done(ec) && | 547 | wake_up(&ec->wait); |
576 | (status & ACPI_EC_FLAG_IBF) == 0) | ||
577 | wake_up(&ec->wait); | ||
578 | } | ||
579 | |||
580 | ec_check_sci(ec, status); | 548 | ec_check_sci(ec, status); |
581 | if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && | ||
582 | !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) { | ||
583 | /* this is non-query, must be confirmation */ | ||
584 | if (!test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | ||
585 | if (printk_ratelimit()) | ||
586 | pr_info(PREFIX "non-query interrupt received," | ||
587 | " switching to interrupt mode\n"); | ||
588 | } else { | ||
589 | /* hush, STORM switches the mode every transaction */ | ||
590 | pr_debug(PREFIX "non-query interrupt received," | ||
591 | " switching to interrupt mode\n"); | ||
592 | } | ||
593 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
594 | } | ||
595 | return ACPI_INTERRUPT_HANDLED; | 549 | return ACPI_INTERRUPT_HANDLED; |
596 | } | 550 | } |
597 | 551 | ||
@@ -617,7 +571,8 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, | |||
617 | if (bits != 8 && acpi_strict) | 571 | if (bits != 8 && acpi_strict) |
618 | return AE_BAD_PARAMETER; | 572 | return AE_BAD_PARAMETER; |
619 | 573 | ||
620 | acpi_ec_burst_enable(ec); | 574 | if (EC_FLAGS_MSI) |
575 | acpi_ec_burst_enable(ec); | ||
621 | 576 | ||
622 | if (function == ACPI_READ) { | 577 | if (function == ACPI_READ) { |
623 | result = acpi_ec_read(ec, address, &temp); | 578 | result = acpi_ec_read(ec, address, &temp); |
@@ -638,7 +593,8 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, | |||
638 | } | 593 | } |
639 | } | 594 | } |
640 | 595 | ||
641 | acpi_ec_burst_disable(ec); | 596 | if (EC_FLAGS_MSI) |
597 | acpi_ec_burst_disable(ec); | ||
642 | 598 | ||
643 | switch (result) { | 599 | switch (result) { |
644 | case -EINVAL: | 600 | case -EINVAL: |
@@ -788,6 +744,42 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) | |||
788 | return AE_CTRL_TERMINATE; | 744 | return AE_CTRL_TERMINATE; |
789 | } | 745 | } |
790 | 746 | ||
747 | static int ec_install_handlers(struct acpi_ec *ec) | ||
748 | { | ||
749 | acpi_status status; | ||
750 | if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) | ||
751 | return 0; | ||
752 | status = acpi_install_gpe_handler(NULL, ec->gpe, | ||
753 | ACPI_GPE_EDGE_TRIGGERED, | ||
754 | &acpi_ec_gpe_handler, ec); | ||
755 | if (ACPI_FAILURE(status)) | ||
756 | return -ENODEV; | ||
757 | acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); | ||
758 | acpi_enable_gpe(NULL, ec->gpe); | ||
759 | status = acpi_install_address_space_handler(ec->handle, | ||
760 | ACPI_ADR_SPACE_EC, | ||
761 | &acpi_ec_space_handler, | ||
762 | NULL, ec); | ||
763 | if (ACPI_FAILURE(status)) { | ||
764 | if (status == AE_NOT_FOUND) { | ||
765 | /* | ||
766 | * Maybe OS fails in evaluating the _REG object. | ||
767 | * The AE_NOT_FOUND error will be ignored and OS | ||
768 | * continue to initialize EC. | ||
769 | */ | ||
770 | printk(KERN_ERR "Fail in evaluating the _REG object" | ||
771 | " of EC device. Broken bios is suspected.\n"); | ||
772 | } else { | ||
773 | acpi_remove_gpe_handler(NULL, ec->gpe, | ||
774 | &acpi_ec_gpe_handler); | ||
775 | return -ENODEV; | ||
776 | } | ||
777 | } | ||
778 | |||
779 | set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); | ||
780 | return 0; | ||
781 | } | ||
782 | |||
791 | static void ec_remove_handlers(struct acpi_ec *ec) | 783 | static void ec_remove_handlers(struct acpi_ec *ec) |
792 | { | 784 | { |
793 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, | 785 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, |
@@ -802,9 +794,8 @@ static void ec_remove_handlers(struct acpi_ec *ec) | |||
802 | static int acpi_ec_add(struct acpi_device *device) | 794 | static int acpi_ec_add(struct acpi_device *device) |
803 | { | 795 | { |
804 | struct acpi_ec *ec = NULL; | 796 | struct acpi_ec *ec = NULL; |
797 | int ret; | ||
805 | 798 | ||
806 | if (!device) | ||
807 | return -EINVAL; | ||
808 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); | 799 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); |
809 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); | 800 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); |
810 | 801 | ||
@@ -837,9 +828,12 @@ static int acpi_ec_add(struct acpi_device *device) | |||
837 | acpi_ec_add_fs(device); | 828 | acpi_ec_add_fs(device); |
838 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", | 829 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", |
839 | ec->gpe, ec->command_addr, ec->data_addr); | 830 | ec->gpe, ec->command_addr, ec->data_addr); |
840 | pr_info(PREFIX "driver started in %s mode\n", | 831 | |
841 | (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))?"interrupt":"poll"); | 832 | ret = ec_install_handlers(ec); |
842 | return 0; | 833 | |
834 | /* EC is fully operational, allow queries */ | ||
835 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | ||
836 | return ret; | ||
843 | } | 837 | } |
844 | 838 | ||
845 | static int acpi_ec_remove(struct acpi_device *device, int type) | 839 | static int acpi_ec_remove(struct acpi_device *device, int type) |
@@ -851,6 +845,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type) | |||
851 | return -EINVAL; | 845 | return -EINVAL; |
852 | 846 | ||
853 | ec = acpi_driver_data(device); | 847 | ec = acpi_driver_data(device); |
848 | ec_remove_handlers(ec); | ||
854 | mutex_lock(&ec->lock); | 849 | mutex_lock(&ec->lock); |
855 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { | 850 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { |
856 | list_del(&handler->node); | 851 | list_del(&handler->node); |
@@ -888,75 +883,6 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context) | |||
888 | return AE_OK; | 883 | return AE_OK; |
889 | } | 884 | } |
890 | 885 | ||
891 | static int ec_install_handlers(struct acpi_ec *ec) | ||
892 | { | ||
893 | acpi_status status; | ||
894 | if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) | ||
895 | return 0; | ||
896 | status = acpi_install_gpe_handler(NULL, ec->gpe, | ||
897 | ACPI_GPE_EDGE_TRIGGERED, | ||
898 | &acpi_ec_gpe_handler, ec); | ||
899 | if (ACPI_FAILURE(status)) | ||
900 | return -ENODEV; | ||
901 | acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); | ||
902 | acpi_enable_gpe(NULL, ec->gpe); | ||
903 | status = acpi_install_address_space_handler(ec->handle, | ||
904 | ACPI_ADR_SPACE_EC, | ||
905 | &acpi_ec_space_handler, | ||
906 | NULL, ec); | ||
907 | if (ACPI_FAILURE(status)) { | ||
908 | if (status == AE_NOT_FOUND) { | ||
909 | /* | ||
910 | * Maybe OS fails in evaluating the _REG object. | ||
911 | * The AE_NOT_FOUND error will be ignored and OS | ||
912 | * continue to initialize EC. | ||
913 | */ | ||
914 | printk(KERN_ERR "Fail in evaluating the _REG object" | ||
915 | " of EC device. Broken bios is suspected.\n"); | ||
916 | } else { | ||
917 | acpi_remove_gpe_handler(NULL, ec->gpe, | ||
918 | &acpi_ec_gpe_handler); | ||
919 | return -ENODEV; | ||
920 | } | ||
921 | } | ||
922 | |||
923 | set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); | ||
924 | return 0; | ||
925 | } | ||
926 | |||
927 | static int acpi_ec_start(struct acpi_device *device) | ||
928 | { | ||
929 | struct acpi_ec *ec; | ||
930 | int ret = 0; | ||
931 | |||
932 | if (!device) | ||
933 | return -EINVAL; | ||
934 | |||
935 | ec = acpi_driver_data(device); | ||
936 | |||
937 | if (!ec) | ||
938 | return -EINVAL; | ||
939 | |||
940 | ret = ec_install_handlers(ec); | ||
941 | |||
942 | /* EC is fully operational, allow queries */ | ||
943 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | ||
944 | return ret; | ||
945 | } | ||
946 | |||
947 | static int acpi_ec_stop(struct acpi_device *device, int type) | ||
948 | { | ||
949 | struct acpi_ec *ec; | ||
950 | if (!device) | ||
951 | return -EINVAL; | ||
952 | ec = acpi_driver_data(device); | ||
953 | if (!ec) | ||
954 | return -EINVAL; | ||
955 | ec_remove_handlers(ec); | ||
956 | |||
957 | return 0; | ||
958 | } | ||
959 | |||
960 | int __init acpi_boot_ec_enable(void) | 886 | int __init acpi_boot_ec_enable(void) |
961 | { | 887 | { |
962 | if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags)) | 888 | if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags)) |
@@ -1054,8 +980,6 @@ static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state) | |||
1054 | { | 980 | { |
1055 | struct acpi_ec *ec = acpi_driver_data(device); | 981 | struct acpi_ec *ec = acpi_driver_data(device); |
1056 | /* Stop using GPE */ | 982 | /* Stop using GPE */ |
1057 | set_bit(EC_FLAGS_NO_GPE, &ec->flags); | ||
1058 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
1059 | acpi_disable_gpe(NULL, ec->gpe); | 983 | acpi_disable_gpe(NULL, ec->gpe); |
1060 | return 0; | 984 | return 0; |
1061 | } | 985 | } |
@@ -1064,8 +988,6 @@ static int acpi_ec_resume(struct acpi_device *device) | |||
1064 | { | 988 | { |
1065 | struct acpi_ec *ec = acpi_driver_data(device); | 989 | struct acpi_ec *ec = acpi_driver_data(device); |
1066 | /* Enable use of GPE back */ | 990 | /* Enable use of GPE back */ |
1067 | clear_bit(EC_FLAGS_NO_GPE, &ec->flags); | ||
1068 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
1069 | acpi_enable_gpe(NULL, ec->gpe); | 991 | acpi_enable_gpe(NULL, ec->gpe); |
1070 | return 0; | 992 | return 0; |
1071 | } | 993 | } |
@@ -1077,8 +999,6 @@ static struct acpi_driver acpi_ec_driver = { | |||
1077 | .ops = { | 999 | .ops = { |
1078 | .add = acpi_ec_add, | 1000 | .add = acpi_ec_add, |
1079 | .remove = acpi_ec_remove, | 1001 | .remove = acpi_ec_remove, |
1080 | .start = acpi_ec_start, | ||
1081 | .stop = acpi_ec_stop, | ||
1082 | .suspend = acpi_ec_suspend, | 1002 | .suspend = acpi_ec_suspend, |
1083 | .resume = acpi_ec_resume, | 1003 | .resume = acpi_ec_resume, |
1084 | }, | 1004 | }, |
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c index aeb7e5fb4a04..c511071bfd79 100644 --- a/drivers/acpi/event.c +++ b/drivers/acpi/event.c | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <net/netlink.h> | 14 | #include <net/netlink.h> |
15 | #include <net/genetlink.h> | 15 | #include <net/genetlink.h> |
16 | 16 | ||
17 | #include "internal.h" | ||
18 | |||
17 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | 19 | #define _COMPONENT ACPI_SYSTEM_COMPONENT |
18 | ACPI_MODULE_NAME("event"); | 20 | ACPI_MODULE_NAME("event"); |
19 | 21 | ||
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 53698ea08371..f419849a0d3f 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include <acpi/acpi_bus.h> | 34 | #include <acpi/acpi_bus.h> |
35 | #include <acpi/acpi_drivers.h> | 35 | #include <acpi/acpi_drivers.h> |
36 | 36 | ||
37 | #define PREFIX "ACPI: " | ||
38 | |||
37 | #define ACPI_FAN_CLASS "fan" | 39 | #define ACPI_FAN_CLASS "fan" |
38 | #define ACPI_FAN_FILE_STATE "state" | 40 | #define ACPI_FAN_FILE_STATE "state" |
39 | 41 | ||
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index a8a5c29958c8..c6645f26224b 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -12,6 +12,8 @@ | |||
12 | #include <linux/rwsem.h> | 12 | #include <linux/rwsem.h> |
13 | #include <linux/acpi.h> | 13 | #include <linux/acpi.h> |
14 | 14 | ||
15 | #include "internal.h" | ||
16 | |||
15 | #define ACPI_GLUE_DEBUG 0 | 17 | #define ACPI_GLUE_DEBUG 0 |
16 | #if ACPI_GLUE_DEBUG | 18 | #if ACPI_GLUE_DEBUG |
17 | #define DBG(x...) printk(PREFIX x) | 19 | #define DBG(x...) printk(PREFIX x) |
@@ -93,15 +95,13 @@ do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
93 | { | 95 | { |
94 | acpi_status status; | 96 | acpi_status status; |
95 | struct acpi_device_info *info; | 97 | struct acpi_device_info *info; |
96 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
97 | struct acpi_find_child *find = context; | 98 | struct acpi_find_child *find = context; |
98 | 99 | ||
99 | status = acpi_get_object_info(handle, &buffer); | 100 | status = acpi_get_object_info(handle, &info); |
100 | if (ACPI_SUCCESS(status)) { | 101 | if (ACPI_SUCCESS(status)) { |
101 | info = buffer.pointer; | ||
102 | if (info->address == find->address) | 102 | if (info->address == find->address) |
103 | find->handle = handle; | 103 | find->handle = handle; |
104 | kfree(buffer.pointer); | 104 | kfree(info); |
105 | } | 105 | } |
106 | return AE_OK; | 106 | return AE_OK; |
107 | } | 107 | } |
@@ -121,7 +121,7 @@ EXPORT_SYMBOL(acpi_get_child); | |||
121 | 121 | ||
122 | /* Link ACPI devices with physical devices */ | 122 | /* Link ACPI devices with physical devices */ |
123 | static void acpi_glue_data_handler(acpi_handle handle, | 123 | static void acpi_glue_data_handler(acpi_handle handle, |
124 | u32 function, void *context) | 124 | void *context) |
125 | { | 125 | { |
126 | /* we provide an empty handler */ | 126 | /* we provide an empty handler */ |
127 | } | 127 | } |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 11a69b53004e..074cf8682d52 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -1,4 +1,24 @@ | |||
1 | /* For use by Linux/ACPI infrastructure, not drivers */ | 1 | /* |
2 | * acpi/internal.h | ||
3 | * For use by Linux/ACPI infrastructure, not drivers | ||
4 | * | ||
5 | * Copyright (c) 2009, Intel Corporation. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms and conditions of the GNU General Public License, | ||
9 | * version 2, as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #define PREFIX "ACPI: " | ||
2 | 22 | ||
3 | int init_acpi_device_notify(void); | 23 | int init_acpi_device_notify(void); |
4 | int acpi_scan_init(void); | 24 | int acpi_scan_init(void); |
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index d440ccd27d91..202dd0c976a3 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <linux/acpi.h> | 30 | #include <linux/acpi.h> |
31 | #include <acpi/acpi_bus.h> | 31 | #include <acpi/acpi_bus.h> |
32 | 32 | ||
33 | #define PREFIX "ACPI: " | ||
34 | |||
33 | #define ACPI_NUMA 0x80000000 | 35 | #define ACPI_NUMA 0x80000000 |
34 | #define _COMPONENT ACPI_NUMA | 36 | #define _COMPONENT ACPI_NUMA |
35 | ACPI_MODULE_NAME("numa"); | 37 | ACPI_MODULE_NAME("numa"); |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 5691f165a952..56071b67bed5 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -58,6 +58,7 @@ struct acpi_os_dpc { | |||
58 | acpi_osd_exec_callback function; | 58 | acpi_osd_exec_callback function; |
59 | void *context; | 59 | void *context; |
60 | struct work_struct work; | 60 | struct work_struct work; |
61 | int wait; | ||
61 | }; | 62 | }; |
62 | 63 | ||
63 | #ifdef CONFIG_ACPI_CUSTOM_DSDT | 64 | #ifdef CONFIG_ACPI_CUSTOM_DSDT |
@@ -88,6 +89,7 @@ struct acpi_res_list { | |||
88 | char name[5]; /* only can have a length of 4 chars, make use of this | 89 | char name[5]; /* only can have a length of 4 chars, make use of this |
89 | one instead of res->name, no need to kalloc then */ | 90 | one instead of res->name, no need to kalloc then */ |
90 | struct list_head resource_list; | 91 | struct list_head resource_list; |
92 | int count; | ||
91 | }; | 93 | }; |
92 | 94 | ||
93 | static LIST_HEAD(resource_list_head); | 95 | static LIST_HEAD(resource_list_head); |
@@ -697,31 +699,12 @@ void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */ | |||
697 | static void acpi_os_execute_deferred(struct work_struct *work) | 699 | static void acpi_os_execute_deferred(struct work_struct *work) |
698 | { | 700 | { |
699 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); | 701 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); |
700 | if (!dpc) { | ||
701 | printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); | ||
702 | return; | ||
703 | } | ||
704 | |||
705 | dpc->function(dpc->context); | ||
706 | kfree(dpc); | ||
707 | |||
708 | return; | ||
709 | } | ||
710 | |||
711 | static void acpi_os_execute_hp_deferred(struct work_struct *work) | ||
712 | { | ||
713 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); | ||
714 | if (!dpc) { | ||
715 | printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); | ||
716 | return; | ||
717 | } | ||
718 | 702 | ||
719 | acpi_os_wait_events_complete(NULL); | 703 | if (dpc->wait) |
704 | acpi_os_wait_events_complete(NULL); | ||
720 | 705 | ||
721 | dpc->function(dpc->context); | 706 | dpc->function(dpc->context); |
722 | kfree(dpc); | 707 | kfree(dpc); |
723 | |||
724 | return; | ||
725 | } | 708 | } |
726 | 709 | ||
727 | /******************************************************************************* | 710 | /******************************************************************************* |
@@ -745,15 +728,11 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, | |||
745 | acpi_status status = AE_OK; | 728 | acpi_status status = AE_OK; |
746 | struct acpi_os_dpc *dpc; | 729 | struct acpi_os_dpc *dpc; |
747 | struct workqueue_struct *queue; | 730 | struct workqueue_struct *queue; |
748 | work_func_t func; | ||
749 | int ret; | 731 | int ret; |
750 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 732 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
751 | "Scheduling function [%p(%p)] for deferred execution.\n", | 733 | "Scheduling function [%p(%p)] for deferred execution.\n", |
752 | function, context)); | 734 | function, context)); |
753 | 735 | ||
754 | if (!function) | ||
755 | return AE_BAD_PARAMETER; | ||
756 | |||
757 | /* | 736 | /* |
758 | * Allocate/initialize DPC structure. Note that this memory will be | 737 | * Allocate/initialize DPC structure. Note that this memory will be |
759 | * freed by the callee. The kernel handles the work_struct list in a | 738 | * freed by the callee. The kernel handles the work_struct list in a |
@@ -778,8 +757,8 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, | |||
778 | */ | 757 | */ |
779 | queue = hp ? kacpi_hotplug_wq : | 758 | queue = hp ? kacpi_hotplug_wq : |
780 | (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq); | 759 | (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq); |
781 | func = hp ? acpi_os_execute_hp_deferred : acpi_os_execute_deferred; | 760 | dpc->wait = hp ? 1 : 0; |
782 | INIT_WORK(&dpc->work, func); | 761 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); |
783 | ret = queue_work(queue, &dpc->work); | 762 | ret = queue_work(queue, &dpc->work); |
784 | 763 | ||
785 | if (!ret) { | 764 | if (!ret) { |
@@ -1358,6 +1337,89 @@ acpi_os_validate_interface (char *interface) | |||
1358 | return AE_SUPPORT; | 1337 | return AE_SUPPORT; |
1359 | } | 1338 | } |
1360 | 1339 | ||
1340 | static inline int acpi_res_list_add(struct acpi_res_list *res) | ||
1341 | { | ||
1342 | struct acpi_res_list *res_list_elem; | ||
1343 | |||
1344 | list_for_each_entry(res_list_elem, &resource_list_head, | ||
1345 | resource_list) { | ||
1346 | |||
1347 | if (res->resource_type == res_list_elem->resource_type && | ||
1348 | res->start == res_list_elem->start && | ||
1349 | res->end == res_list_elem->end) { | ||
1350 | |||
1351 | /* | ||
1352 | * The Region(addr,len) already exist in the list, | ||
1353 | * just increase the count | ||
1354 | */ | ||
1355 | |||
1356 | res_list_elem->count++; | ||
1357 | return 0; | ||
1358 | } | ||
1359 | } | ||
1360 | |||
1361 | res->count = 1; | ||
1362 | list_add(&res->resource_list, &resource_list_head); | ||
1363 | return 1; | ||
1364 | } | ||
1365 | |||
1366 | static inline void acpi_res_list_del(struct acpi_res_list *res) | ||
1367 | { | ||
1368 | struct acpi_res_list *res_list_elem; | ||
1369 | |||
1370 | list_for_each_entry(res_list_elem, &resource_list_head, | ||
1371 | resource_list) { | ||
1372 | |||
1373 | if (res->resource_type == res_list_elem->resource_type && | ||
1374 | res->start == res_list_elem->start && | ||
1375 | res->end == res_list_elem->end) { | ||
1376 | |||
1377 | /* | ||
1378 | * If the res count is decreased to 0, | ||
1379 | * remove and free it | ||
1380 | */ | ||
1381 | |||
1382 | if (--res_list_elem->count == 0) { | ||
1383 | list_del(&res_list_elem->resource_list); | ||
1384 | kfree(res_list_elem); | ||
1385 | } | ||
1386 | return; | ||
1387 | } | ||
1388 | } | ||
1389 | } | ||
1390 | |||
1391 | acpi_status | ||
1392 | acpi_os_invalidate_address( | ||
1393 | u8 space_id, | ||
1394 | acpi_physical_address address, | ||
1395 | acpi_size length) | ||
1396 | { | ||
1397 | struct acpi_res_list res; | ||
1398 | |||
1399 | switch (space_id) { | ||
1400 | case ACPI_ADR_SPACE_SYSTEM_IO: | ||
1401 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | ||
1402 | /* Only interference checks against SystemIO and SytemMemory | ||
1403 | are needed */ | ||
1404 | res.start = address; | ||
1405 | res.end = address + length - 1; | ||
1406 | res.resource_type = space_id; | ||
1407 | spin_lock(&acpi_res_lock); | ||
1408 | acpi_res_list_del(&res); | ||
1409 | spin_unlock(&acpi_res_lock); | ||
1410 | break; | ||
1411 | case ACPI_ADR_SPACE_PCI_CONFIG: | ||
1412 | case ACPI_ADR_SPACE_EC: | ||
1413 | case ACPI_ADR_SPACE_SMBUS: | ||
1414 | case ACPI_ADR_SPACE_CMOS: | ||
1415 | case ACPI_ADR_SPACE_PCI_BAR_TARGET: | ||
1416 | case ACPI_ADR_SPACE_DATA_TABLE: | ||
1417 | case ACPI_ADR_SPACE_FIXED_HARDWARE: | ||
1418 | break; | ||
1419 | } | ||
1420 | return AE_OK; | ||
1421 | } | ||
1422 | |||
1361 | /****************************************************************************** | 1423 | /****************************************************************************** |
1362 | * | 1424 | * |
1363 | * FUNCTION: acpi_os_validate_address | 1425 | * FUNCTION: acpi_os_validate_address |
@@ -1382,6 +1444,7 @@ acpi_os_validate_address ( | |||
1382 | char *name) | 1444 | char *name) |
1383 | { | 1445 | { |
1384 | struct acpi_res_list *res; | 1446 | struct acpi_res_list *res; |
1447 | int added; | ||
1385 | if (acpi_enforce_resources == ENFORCE_RESOURCES_NO) | 1448 | if (acpi_enforce_resources == ENFORCE_RESOURCES_NO) |
1386 | return AE_OK; | 1449 | return AE_OK; |
1387 | 1450 | ||
@@ -1399,14 +1462,17 @@ acpi_os_validate_address ( | |||
1399 | res->end = address + length - 1; | 1462 | res->end = address + length - 1; |
1400 | res->resource_type = space_id; | 1463 | res->resource_type = space_id; |
1401 | spin_lock(&acpi_res_lock); | 1464 | spin_lock(&acpi_res_lock); |
1402 | list_add(&res->resource_list, &resource_list_head); | 1465 | added = acpi_res_list_add(res); |
1403 | spin_unlock(&acpi_res_lock); | 1466 | spin_unlock(&acpi_res_lock); |
1404 | pr_debug("Added %s resource: start: 0x%llx, end: 0x%llx, " | 1467 | pr_debug("%s %s resource: start: 0x%llx, end: 0x%llx, " |
1405 | "name: %s\n", (space_id == ACPI_ADR_SPACE_SYSTEM_IO) | 1468 | "name: %s\n", added ? "Added" : "Already exist", |
1469 | (space_id == ACPI_ADR_SPACE_SYSTEM_IO) | ||
1406 | ? "SystemIO" : "System Memory", | 1470 | ? "SystemIO" : "System Memory", |
1407 | (unsigned long long)res->start, | 1471 | (unsigned long long)res->start, |
1408 | (unsigned long long)res->end, | 1472 | (unsigned long long)res->end, |
1409 | res->name); | 1473 | res->name); |
1474 | if (!added) | ||
1475 | kfree(res); | ||
1410 | break; | 1476 | break; |
1411 | case ACPI_ADR_SPACE_PCI_CONFIG: | 1477 | case ACPI_ADR_SPACE_PCI_CONFIG: |
1412 | case ACPI_ADR_SPACE_EC: | 1478 | case ACPI_ADR_SPACE_EC: |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index b794eb88ab90..843699ed93f2 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include <acpi/acpi_bus.h> | 40 | #include <acpi/acpi_bus.h> |
41 | #include <acpi/acpi_drivers.h> | 41 | #include <acpi/acpi_drivers.h> |
42 | 42 | ||
43 | #define PREFIX "ACPI: " | ||
44 | |||
43 | #define _COMPONENT ACPI_PCI_COMPONENT | 45 | #define _COMPONENT ACPI_PCI_COMPONENT |
44 | ACPI_MODULE_NAME("pci_irq"); | 46 | ACPI_MODULE_NAME("pci_irq"); |
45 | 47 | ||
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 16e0f9d3d17c..394ae89409c2 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
@@ -43,6 +43,8 @@ | |||
43 | #include <acpi/acpi_bus.h> | 43 | #include <acpi/acpi_bus.h> |
44 | #include <acpi/acpi_drivers.h> | 44 | #include <acpi/acpi_drivers.h> |
45 | 45 | ||
46 | #define PREFIX "ACPI: " | ||
47 | |||
46 | #define _COMPONENT ACPI_PCI_COMPONENT | 48 | #define _COMPONENT ACPI_PCI_COMPONENT |
47 | ACPI_MODULE_NAME("pci_link"); | 49 | ACPI_MODULE_NAME("pci_link"); |
48 | #define ACPI_PCI_LINK_CLASS "pci_irq_routing" | 50 | #define ACPI_PCI_LINK_CLASS "pci_irq_routing" |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 31b961c2f22f..31122214e0ec 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -36,6 +36,8 @@ | |||
36 | #include <acpi/acpi_bus.h> | 36 | #include <acpi/acpi_bus.h> |
37 | #include <acpi/acpi_drivers.h> | 37 | #include <acpi/acpi_drivers.h> |
38 | 38 | ||
39 | #define PREFIX "ACPI: " | ||
40 | |||
39 | #define _COMPONENT ACPI_PCI_COMPONENT | 41 | #define _COMPONENT ACPI_PCI_COMPONENT |
40 | ACPI_MODULE_NAME("pci_root"); | 42 | ACPI_MODULE_NAME("pci_root"); |
41 | #define ACPI_PCI_ROOT_CLASS "pci_bridge" | 43 | #define ACPI_PCI_ROOT_CLASS "pci_bridge" |
diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c index 12158e0d009b..45da2bae36c8 100644 --- a/drivers/acpi/pci_slot.c +++ b/drivers/acpi/pci_slot.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/acpi.h> | 31 | #include <linux/acpi.h> |
32 | #include <acpi/acpi_bus.h> | 32 | #include <acpi/acpi_bus.h> |
33 | #include <acpi/acpi_drivers.h> | 33 | #include <acpi/acpi_drivers.h> |
34 | #include <linux/dmi.h> | ||
34 | 35 | ||
35 | static int debug; | 36 | static int debug; |
36 | static int check_sta_before_sun; | 37 | static int check_sta_before_sun; |
@@ -57,7 +58,7 @@ ACPI_MODULE_NAME("pci_slot"); | |||
57 | MY_NAME , ## arg); \ | 58 | MY_NAME , ## arg); \ |
58 | } while (0) | 59 | } while (0) |
59 | 60 | ||
60 | #define SLOT_NAME_SIZE 20 /* Inspired by #define in acpiphp.h */ | 61 | #define SLOT_NAME_SIZE 21 /* Inspired by #define in acpiphp.h */ |
61 | 62 | ||
62 | struct acpi_pci_slot { | 63 | struct acpi_pci_slot { |
63 | acpi_handle root_handle; /* handle of the root bridge */ | 64 | acpi_handle root_handle; /* handle of the root bridge */ |
@@ -149,7 +150,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
149 | return AE_OK; | 150 | return AE_OK; |
150 | } | 151 | } |
151 | 152 | ||
152 | snprintf(name, sizeof(name), "%u", (u32)sun); | 153 | snprintf(name, sizeof(name), "%llu", sun); |
153 | pci_slot = pci_create_slot(pci_bus, device, name, NULL); | 154 | pci_slot = pci_create_slot(pci_bus, device, name, NULL); |
154 | if (IS_ERR(pci_slot)) { | 155 | if (IS_ERR(pci_slot)) { |
155 | err("pci_create_slot returned %ld\n", PTR_ERR(pci_slot)); | 156 | err("pci_create_slot returned %ld\n", PTR_ERR(pci_slot)); |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 5a09bf392ec1..22b297916519 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -43,9 +43,10 @@ | |||
43 | #include <linux/seq_file.h> | 43 | #include <linux/seq_file.h> |
44 | #include <acpi/acpi_bus.h> | 44 | #include <acpi/acpi_bus.h> |
45 | #include <acpi/acpi_drivers.h> | 45 | #include <acpi/acpi_drivers.h> |
46 | |||
47 | #include "sleep.h" | 46 | #include "sleep.h" |
48 | 47 | ||
48 | #define PREFIX "ACPI: " | ||
49 | |||
49 | #define _COMPONENT ACPI_POWER_COMPONENT | 50 | #define _COMPONENT ACPI_POWER_COMPONENT |
50 | ACPI_MODULE_NAME("power"); | 51 | ACPI_MODULE_NAME("power"); |
51 | #define ACPI_POWER_CLASS "power_resource" | 52 | #define ACPI_POWER_CLASS "power_resource" |
diff --git a/drivers/acpi/power_meter.c b/drivers/acpi/power_meter.c new file mode 100644 index 000000000000..e6bfd77986b8 --- /dev/null +++ b/drivers/acpi/power_meter.c | |||
@@ -0,0 +1,1018 @@ | |||
1 | /* | ||
2 | * A hwmon driver for ACPI 4.0 power meters | ||
3 | * Copyright (C) 2009 IBM | ||
4 | * | ||
5 | * Author: Darrick J. Wong <djwong@us.ibm.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/hwmon.h> | ||
24 | #include <linux/hwmon-sysfs.h> | ||
25 | #include <linux/jiffies.h> | ||
26 | #include <linux/mutex.h> | ||
27 | #include <linux/dmi.h> | ||
28 | #include <linux/kdev_t.h> | ||
29 | #include <linux/sched.h> | ||
30 | #include <linux/time.h> | ||
31 | #include <acpi/acpi_drivers.h> | ||
32 | #include <acpi/acpi_bus.h> | ||
33 | |||
34 | #define ACPI_POWER_METER_NAME "power_meter" | ||
35 | ACPI_MODULE_NAME(ACPI_POWER_METER_NAME); | ||
36 | #define ACPI_POWER_METER_DEVICE_NAME "Power Meter" | ||
37 | #define ACPI_POWER_METER_CLASS "power_meter_resource" | ||
38 | |||
39 | #define NUM_SENSORS 17 | ||
40 | |||
41 | #define POWER_METER_CAN_MEASURE (1 << 0) | ||
42 | #define POWER_METER_CAN_TRIP (1 << 1) | ||
43 | #define POWER_METER_CAN_CAP (1 << 2) | ||
44 | #define POWER_METER_CAN_NOTIFY (1 << 3) | ||
45 | #define POWER_METER_IS_BATTERY (1 << 8) | ||
46 | #define UNKNOWN_HYSTERESIS 0xFFFFFFFF | ||
47 | |||
48 | #define METER_NOTIFY_CONFIG 0x80 | ||
49 | #define METER_NOTIFY_TRIP 0x81 | ||
50 | #define METER_NOTIFY_CAP 0x82 | ||
51 | #define METER_NOTIFY_CAPPING 0x83 | ||
52 | #define METER_NOTIFY_INTERVAL 0x84 | ||
53 | |||
54 | #define POWER_AVERAGE_NAME "power1_average" | ||
55 | #define POWER_CAP_NAME "power1_cap" | ||
56 | #define POWER_AVG_INTERVAL_NAME "power1_average_interval" | ||
57 | #define POWER_ALARM_NAME "power1_alarm" | ||
58 | |||
59 | static int cap_in_hardware; | ||
60 | static int force_cap_on; | ||
61 | |||
62 | static int can_cap_in_hardware(void) | ||
63 | { | ||
64 | return force_cap_on || cap_in_hardware; | ||
65 | } | ||
66 | |||
67 | static struct acpi_device_id power_meter_ids[] = { | ||
68 | {"ACPI000D", 0}, | ||
69 | {"", 0}, | ||
70 | }; | ||
71 | MODULE_DEVICE_TABLE(acpi, power_meter_ids); | ||
72 | |||
73 | struct acpi_power_meter_capabilities { | ||
74 | acpi_integer flags; | ||
75 | acpi_integer units; | ||
76 | acpi_integer type; | ||
77 | acpi_integer accuracy; | ||
78 | acpi_integer sampling_time; | ||
79 | acpi_integer min_avg_interval; | ||
80 | acpi_integer max_avg_interval; | ||
81 | acpi_integer hysteresis; | ||
82 | acpi_integer configurable_cap; | ||
83 | acpi_integer min_cap; | ||
84 | acpi_integer max_cap; | ||
85 | }; | ||
86 | |||
87 | struct acpi_power_meter_resource { | ||
88 | struct acpi_device *acpi_dev; | ||
89 | acpi_bus_id name; | ||
90 | struct mutex lock; | ||
91 | struct device *hwmon_dev; | ||
92 | struct acpi_power_meter_capabilities caps; | ||
93 | acpi_string model_number; | ||
94 | acpi_string serial_number; | ||
95 | acpi_string oem_info; | ||
96 | acpi_integer power; | ||
97 | acpi_integer cap; | ||
98 | acpi_integer avg_interval; | ||
99 | int sensors_valid; | ||
100 | unsigned long sensors_last_updated; | ||
101 | struct sensor_device_attribute sensors[NUM_SENSORS]; | ||
102 | int num_sensors; | ||
103 | int trip[2]; | ||
104 | int num_domain_devices; | ||
105 | struct acpi_device **domain_devices; | ||
106 | struct kobject *holders_dir; | ||
107 | }; | ||
108 | |||
109 | struct ro_sensor_template { | ||
110 | char *label; | ||
111 | ssize_t (*show)(struct device *dev, | ||
112 | struct device_attribute *devattr, | ||
113 | char *buf); | ||
114 | int index; | ||
115 | }; | ||
116 | |||
117 | struct rw_sensor_template { | ||
118 | char *label; | ||
119 | ssize_t (*show)(struct device *dev, | ||
120 | struct device_attribute *devattr, | ||
121 | char *buf); | ||
122 | ssize_t (*set)(struct device *dev, | ||
123 | struct device_attribute *devattr, | ||
124 | const char *buf, size_t count); | ||
125 | int index; | ||
126 | }; | ||
127 | |||
128 | /* Averaging interval */ | ||
129 | static int update_avg_interval(struct acpi_power_meter_resource *resource) | ||
130 | { | ||
131 | unsigned long long data; | ||
132 | acpi_status status; | ||
133 | |||
134 | status = acpi_evaluate_integer(resource->acpi_dev->handle, "_GAI", | ||
135 | NULL, &data); | ||
136 | if (ACPI_FAILURE(status)) { | ||
137 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _GAI")); | ||
138 | return -ENODEV; | ||
139 | } | ||
140 | |||
141 | resource->avg_interval = data; | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static ssize_t show_avg_interval(struct device *dev, | ||
146 | struct device_attribute *devattr, | ||
147 | char *buf) | ||
148 | { | ||
149 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
150 | struct acpi_power_meter_resource *resource = acpi_dev->driver_data; | ||
151 | |||
152 | mutex_lock(&resource->lock); | ||
153 | update_avg_interval(resource); | ||
154 | mutex_unlock(&resource->lock); | ||
155 | |||
156 | return sprintf(buf, "%llu\n", resource->avg_interval); | ||
157 | } | ||
158 | |||
159 | static ssize_t set_avg_interval(struct device *dev, | ||
160 | struct device_attribute *devattr, | ||
161 | const char *buf, size_t count) | ||
162 | { | ||
163 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
164 | struct acpi_power_meter_resource *resource = acpi_dev->driver_data; | ||
165 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | ||
166 | struct acpi_object_list args = { 1, &arg0 }; | ||
167 | int res; | ||
168 | unsigned long temp; | ||
169 | unsigned long long data; | ||
170 | acpi_status status; | ||
171 | |||
172 | res = strict_strtoul(buf, 10, &temp); | ||
173 | if (res) | ||
174 | return res; | ||
175 | |||
176 | if (temp > resource->caps.max_avg_interval || | ||
177 | temp < resource->caps.min_avg_interval) | ||
178 | return -EINVAL; | ||
179 | arg0.integer.value = temp; | ||
180 | |||
181 | mutex_lock(&resource->lock); | ||
182 | status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PAI", | ||
183 | &args, &data); | ||
184 | if (!ACPI_FAILURE(status)) | ||
185 | resource->avg_interval = temp; | ||
186 | mutex_unlock(&resource->lock); | ||
187 | |||
188 | if (ACPI_FAILURE(status)) { | ||
189 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PAI")); | ||
190 | return -EINVAL; | ||
191 | } | ||
192 | |||
193 | /* _PAI returns 0 on success, nonzero otherwise */ | ||
194 | if (data) | ||
195 | return -EINVAL; | ||
196 | |||
197 | return count; | ||
198 | } | ||
199 | |||
200 | /* Cap functions */ | ||
201 | static int update_cap(struct acpi_power_meter_resource *resource) | ||
202 | { | ||
203 | unsigned long long data; | ||
204 | acpi_status status; | ||
205 | |||
206 | status = acpi_evaluate_integer(resource->acpi_dev->handle, "_GHL", | ||
207 | NULL, &data); | ||
208 | if (ACPI_FAILURE(status)) { | ||
209 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _GHL")); | ||
210 | return -ENODEV; | ||
211 | } | ||
212 | |||
213 | resource->cap = data; | ||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | static ssize_t show_cap(struct device *dev, | ||
218 | struct device_attribute *devattr, | ||
219 | char *buf) | ||
220 | { | ||
221 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
222 | struct acpi_power_meter_resource *resource = acpi_dev->driver_data; | ||
223 | |||
224 | mutex_lock(&resource->lock); | ||
225 | update_cap(resource); | ||
226 | mutex_unlock(&resource->lock); | ||
227 | |||
228 | return sprintf(buf, "%llu\n", resource->cap * 1000); | ||
229 | } | ||
230 | |||
231 | static ssize_t set_cap(struct device *dev, struct device_attribute *devattr, | ||
232 | const char *buf, size_t count) | ||
233 | { | ||
234 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
235 | struct acpi_power_meter_resource *resource = acpi_dev->driver_data; | ||
236 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | ||
237 | struct acpi_object_list args = { 1, &arg0 }; | ||
238 | int res; | ||
239 | unsigned long temp; | ||
240 | unsigned long long data; | ||
241 | acpi_status status; | ||
242 | |||
243 | res = strict_strtoul(buf, 10, &temp); | ||
244 | if (res) | ||
245 | return res; | ||
246 | |||
247 | temp /= 1000; | ||
248 | if (temp > resource->caps.max_cap || temp < resource->caps.min_cap) | ||
249 | return -EINVAL; | ||
250 | arg0.integer.value = temp; | ||
251 | |||
252 | mutex_lock(&resource->lock); | ||
253 | status = acpi_evaluate_integer(resource->acpi_dev->handle, "_SHL", | ||
254 | &args, &data); | ||
255 | if (!ACPI_FAILURE(status)) | ||
256 | resource->cap = temp; | ||
257 | mutex_unlock(&resource->lock); | ||
258 | |||
259 | if (ACPI_FAILURE(status)) { | ||
260 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _SHL")); | ||
261 | return -EINVAL; | ||
262 | } | ||
263 | |||
264 | /* _SHL returns 0 on success, nonzero otherwise */ | ||
265 | if (data) | ||
266 | return -EINVAL; | ||
267 | |||
268 | return count; | ||
269 | } | ||
270 | |||
271 | /* Power meter trip points */ | ||
272 | static int set_acpi_trip(struct acpi_power_meter_resource *resource) | ||
273 | { | ||
274 | union acpi_object arg_objs[] = { | ||
275 | {ACPI_TYPE_INTEGER}, | ||
276 | {ACPI_TYPE_INTEGER} | ||
277 | }; | ||
278 | struct acpi_object_list args = { 2, arg_objs }; | ||
279 | unsigned long long data; | ||
280 | acpi_status status; | ||
281 | |||
282 | /* Both trip levels must be set */ | ||
283 | if (resource->trip[0] < 0 || resource->trip[1] < 0) | ||
284 | return 0; | ||
285 | |||
286 | /* This driver stores min, max; ACPI wants max, min. */ | ||
287 | arg_objs[0].integer.value = resource->trip[1]; | ||
288 | arg_objs[1].integer.value = resource->trip[0]; | ||
289 | |||
290 | status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PTP", | ||
291 | &args, &data); | ||
292 | if (ACPI_FAILURE(status)) { | ||
293 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PTP")); | ||
294 | return -EINVAL; | ||
295 | } | ||
296 | |||
297 | return data; | ||
298 | } | ||
299 | |||
300 | static ssize_t set_trip(struct device *dev, struct device_attribute *devattr, | ||
301 | const char *buf, size_t count) | ||
302 | { | ||
303 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
304 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
305 | struct acpi_power_meter_resource *resource = acpi_dev->driver_data; | ||
306 | int res; | ||
307 | unsigned long temp; | ||
308 | |||
309 | res = strict_strtoul(buf, 10, &temp); | ||
310 | if (res) | ||
311 | return res; | ||
312 | |||
313 | temp /= 1000; | ||
314 | if (temp < 0) | ||
315 | return -EINVAL; | ||
316 | |||
317 | mutex_lock(&resource->lock); | ||
318 | resource->trip[attr->index - 7] = temp; | ||
319 | res = set_acpi_trip(resource); | ||
320 | mutex_unlock(&resource->lock); | ||
321 | |||
322 | if (res) | ||
323 | return res; | ||
324 | |||
325 | return count; | ||
326 | } | ||
327 | |||
328 | /* Power meter */ | ||
329 | static int update_meter(struct acpi_power_meter_resource *resource) | ||
330 | { | ||
331 | unsigned long long data; | ||
332 | acpi_status status; | ||
333 | unsigned long local_jiffies = jiffies; | ||
334 | |||
335 | if (time_before(local_jiffies, resource->sensors_last_updated + | ||
336 | msecs_to_jiffies(resource->caps.sampling_time)) && | ||
337 | resource->sensors_valid) | ||
338 | return 0; | ||
339 | |||
340 | status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PMM", | ||
341 | NULL, &data); | ||
342 | if (ACPI_FAILURE(status)) { | ||
343 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMM")); | ||
344 | return -ENODEV; | ||
345 | } | ||
346 | |||
347 | resource->power = data; | ||
348 | resource->sensors_valid = 1; | ||
349 | resource->sensors_last_updated = jiffies; | ||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | static ssize_t show_power(struct device *dev, | ||
354 | struct device_attribute *devattr, | ||
355 | char *buf) | ||
356 | { | ||
357 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
358 | struct acpi_power_meter_resource *resource = acpi_dev->driver_data; | ||
359 | |||
360 | mutex_lock(&resource->lock); | ||
361 | update_meter(resource); | ||
362 | mutex_unlock(&resource->lock); | ||
363 | |||
364 | return sprintf(buf, "%llu\n", resource->power * 1000); | ||
365 | } | ||
366 | |||
367 | /* Miscellaneous */ | ||
368 | static ssize_t show_str(struct device *dev, | ||
369 | struct device_attribute *devattr, | ||
370 | char *buf) | ||
371 | { | ||
372 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
373 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
374 | struct acpi_power_meter_resource *resource = acpi_dev->driver_data; | ||
375 | acpi_string val; | ||
376 | |||
377 | switch (attr->index) { | ||
378 | case 0: | ||
379 | val = resource->model_number; | ||
380 | break; | ||
381 | case 1: | ||
382 | val = resource->serial_number; | ||
383 | break; | ||
384 | case 2: | ||
385 | val = resource->oem_info; | ||
386 | break; | ||
387 | default: | ||
388 | BUG(); | ||
389 | } | ||
390 | |||
391 | return sprintf(buf, "%s\n", val); | ||
392 | } | ||
393 | |||
394 | static ssize_t show_val(struct device *dev, | ||
395 | struct device_attribute *devattr, | ||
396 | char *buf) | ||
397 | { | ||
398 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
399 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
400 | struct acpi_power_meter_resource *resource = acpi_dev->driver_data; | ||
401 | acpi_integer val = 0; | ||
402 | |||
403 | switch (attr->index) { | ||
404 | case 0: | ||
405 | val = resource->caps.min_avg_interval; | ||
406 | break; | ||
407 | case 1: | ||
408 | val = resource->caps.max_avg_interval; | ||
409 | break; | ||
410 | case 2: | ||
411 | val = resource->caps.min_cap * 1000; | ||
412 | break; | ||
413 | case 3: | ||
414 | val = resource->caps.max_cap * 1000; | ||
415 | break; | ||
416 | case 4: | ||
417 | if (resource->caps.hysteresis == UNKNOWN_HYSTERESIS) | ||
418 | return sprintf(buf, "unknown\n"); | ||
419 | |||
420 | val = resource->caps.hysteresis * 1000; | ||
421 | break; | ||
422 | case 5: | ||
423 | if (resource->caps.flags & POWER_METER_IS_BATTERY) | ||
424 | val = 1; | ||
425 | else | ||
426 | val = 0; | ||
427 | break; | ||
428 | case 6: | ||
429 | if (resource->power > resource->cap) | ||
430 | val = 1; | ||
431 | else | ||
432 | val = 0; | ||
433 | break; | ||
434 | case 7: | ||
435 | case 8: | ||
436 | if (resource->trip[attr->index - 7] < 0) | ||
437 | return sprintf(buf, "unknown\n"); | ||
438 | |||
439 | val = resource->trip[attr->index - 7] * 1000; | ||
440 | break; | ||
441 | default: | ||
442 | BUG(); | ||
443 | } | ||
444 | |||
445 | return sprintf(buf, "%llu\n", val); | ||
446 | } | ||
447 | |||
448 | static ssize_t show_accuracy(struct device *dev, | ||
449 | struct device_attribute *devattr, | ||
450 | char *buf) | ||
451 | { | ||
452 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
453 | struct acpi_power_meter_resource *resource = acpi_dev->driver_data; | ||
454 | unsigned int acc = resource->caps.accuracy; | ||
455 | |||
456 | return sprintf(buf, "%u.%u%%\n", acc / 1000, acc % 1000); | ||
457 | } | ||
458 | |||
459 | static ssize_t show_name(struct device *dev, | ||
460 | struct device_attribute *devattr, | ||
461 | char *buf) | ||
462 | { | ||
463 | return sprintf(buf, "%s\n", ACPI_POWER_METER_NAME); | ||
464 | } | ||
465 | |||
466 | /* Sensor descriptions. If you add a sensor, update NUM_SENSORS above! */ | ||
467 | static struct ro_sensor_template meter_ro_attrs[] = { | ||
468 | {POWER_AVERAGE_NAME, show_power, 0}, | ||
469 | {"power1_accuracy", show_accuracy, 0}, | ||
470 | {"power1_average_interval_min", show_val, 0}, | ||
471 | {"power1_average_interval_max", show_val, 1}, | ||
472 | {"power1_is_battery", show_val, 5}, | ||
473 | {NULL, NULL, 0}, | ||
474 | }; | ||
475 | |||
476 | static struct rw_sensor_template meter_rw_attrs[] = { | ||
477 | {POWER_AVG_INTERVAL_NAME, show_avg_interval, set_avg_interval, 0}, | ||
478 | {NULL, NULL, NULL, 0}, | ||
479 | }; | ||
480 | |||
481 | static struct ro_sensor_template misc_cap_attrs[] = { | ||
482 | {"power1_cap_min", show_val, 2}, | ||
483 | {"power1_cap_max", show_val, 3}, | ||
484 | {"power1_cap_hyst", show_val, 4}, | ||
485 | {POWER_ALARM_NAME, show_val, 6}, | ||
486 | {NULL, NULL, 0}, | ||
487 | }; | ||
488 | |||
489 | static struct ro_sensor_template ro_cap_attrs[] = { | ||
490 | {POWER_CAP_NAME, show_cap, 0}, | ||
491 | {NULL, NULL, 0}, | ||
492 | }; | ||
493 | |||
494 | static struct rw_sensor_template rw_cap_attrs[] = { | ||
495 | {POWER_CAP_NAME, show_cap, set_cap, 0}, | ||
496 | {NULL, NULL, NULL, 0}, | ||
497 | }; | ||
498 | |||
499 | static struct rw_sensor_template trip_attrs[] = { | ||
500 | {"power1_average_min", show_val, set_trip, 7}, | ||
501 | {"power1_average_max", show_val, set_trip, 8}, | ||
502 | {NULL, NULL, NULL, 0}, | ||
503 | }; | ||
504 | |||
505 | static struct ro_sensor_template misc_attrs[] = { | ||
506 | {"name", show_name, 0}, | ||
507 | {"power1_model_number", show_str, 0}, | ||
508 | {"power1_oem_info", show_str, 2}, | ||
509 | {"power1_serial_number", show_str, 1}, | ||
510 | {NULL, NULL, 0}, | ||
511 | }; | ||
512 | |||
513 | /* Read power domain data */ | ||
514 | static void remove_domain_devices(struct acpi_power_meter_resource *resource) | ||
515 | { | ||
516 | int i; | ||
517 | |||
518 | if (!resource->num_domain_devices) | ||
519 | return; | ||
520 | |||
521 | for (i = 0; i < resource->num_domain_devices; i++) { | ||
522 | struct acpi_device *obj = resource->domain_devices[i]; | ||
523 | if (!obj) | ||
524 | continue; | ||
525 | |||
526 | sysfs_remove_link(resource->holders_dir, | ||
527 | kobject_name(&obj->dev.kobj)); | ||
528 | put_device(&obj->dev); | ||
529 | } | ||
530 | |||
531 | kfree(resource->domain_devices); | ||
532 | kobject_put(resource->holders_dir); | ||
533 | } | ||
534 | |||
535 | static int read_domain_devices(struct acpi_power_meter_resource *resource) | ||
536 | { | ||
537 | int res = 0; | ||
538 | int i; | ||
539 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
540 | union acpi_object *pss; | ||
541 | acpi_status status; | ||
542 | |||
543 | status = acpi_evaluate_object(resource->acpi_dev->handle, "_PMD", NULL, | ||
544 | &buffer); | ||
545 | if (ACPI_FAILURE(status)) { | ||
546 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMD")); | ||
547 | return -ENODEV; | ||
548 | } | ||
549 | |||
550 | pss = buffer.pointer; | ||
551 | if (!pss || | ||
552 | pss->type != ACPI_TYPE_PACKAGE) { | ||
553 | dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME | ||
554 | "Invalid _PMD data\n"); | ||
555 | res = -EFAULT; | ||
556 | goto end; | ||
557 | } | ||
558 | |||
559 | if (!pss->package.count) | ||
560 | goto end; | ||
561 | |||
562 | resource->domain_devices = kzalloc(sizeof(struct acpi_device *) * | ||
563 | pss->package.count, GFP_KERNEL); | ||
564 | if (!resource->domain_devices) { | ||
565 | res = -ENOMEM; | ||
566 | goto end; | ||
567 | } | ||
568 | |||
569 | resource->holders_dir = kobject_create_and_add("measures", | ||
570 | &resource->acpi_dev->dev.kobj); | ||
571 | if (!resource->holders_dir) { | ||
572 | res = -ENOMEM; | ||
573 | goto exit_free; | ||
574 | } | ||
575 | |||
576 | resource->num_domain_devices = pss->package.count; | ||
577 | |||
578 | for (i = 0; i < pss->package.count; i++) { | ||
579 | struct acpi_device *obj; | ||
580 | union acpi_object *element = &(pss->package.elements[i]); | ||
581 | |||
582 | /* Refuse non-references */ | ||
583 | if (element->type != ACPI_TYPE_LOCAL_REFERENCE) | ||
584 | continue; | ||
585 | |||
586 | /* Create a symlink to domain objects */ | ||
587 | resource->domain_devices[i] = NULL; | ||
588 | status = acpi_bus_get_device(element->reference.handle, | ||
589 | &resource->domain_devices[i]); | ||
590 | if (ACPI_FAILURE(status)) | ||
591 | continue; | ||
592 | |||
593 | obj = resource->domain_devices[i]; | ||
594 | get_device(&obj->dev); | ||
595 | |||
596 | res = sysfs_create_link(resource->holders_dir, &obj->dev.kobj, | ||
597 | kobject_name(&obj->dev.kobj)); | ||
598 | if (res) { | ||
599 | put_device(&obj->dev); | ||
600 | resource->domain_devices[i] = NULL; | ||
601 | } | ||
602 | } | ||
603 | |||
604 | res = 0; | ||
605 | goto end; | ||
606 | |||
607 | exit_free: | ||
608 | kfree(resource->domain_devices); | ||
609 | end: | ||
610 | kfree(buffer.pointer); | ||
611 | return res; | ||
612 | } | ||
613 | |||
614 | /* Registration and deregistration */ | ||
615 | static int register_ro_attrs(struct acpi_power_meter_resource *resource, | ||
616 | struct ro_sensor_template *ro) | ||
617 | { | ||
618 | struct device *dev = &resource->acpi_dev->dev; | ||
619 | struct sensor_device_attribute *sensors = | ||
620 | &resource->sensors[resource->num_sensors]; | ||
621 | int res = 0; | ||
622 | |||
623 | while (ro->label) { | ||
624 | sensors->dev_attr.attr.name = ro->label; | ||
625 | sensors->dev_attr.attr.mode = S_IRUGO; | ||
626 | sensors->dev_attr.show = ro->show; | ||
627 | sensors->index = ro->index; | ||
628 | |||
629 | res = device_create_file(dev, &sensors->dev_attr); | ||
630 | if (res) { | ||
631 | sensors->dev_attr.attr.name = NULL; | ||
632 | goto error; | ||
633 | } | ||
634 | sensors++; | ||
635 | resource->num_sensors++; | ||
636 | ro++; | ||
637 | } | ||
638 | |||
639 | error: | ||
640 | return res; | ||
641 | } | ||
642 | |||
643 | static int register_rw_attrs(struct acpi_power_meter_resource *resource, | ||
644 | struct rw_sensor_template *rw) | ||
645 | { | ||
646 | struct device *dev = &resource->acpi_dev->dev; | ||
647 | struct sensor_device_attribute *sensors = | ||
648 | &resource->sensors[resource->num_sensors]; | ||
649 | int res = 0; | ||
650 | |||
651 | while (rw->label) { | ||
652 | sensors->dev_attr.attr.name = rw->label; | ||
653 | sensors->dev_attr.attr.mode = S_IRUGO | S_IWUSR; | ||
654 | sensors->dev_attr.show = rw->show; | ||
655 | sensors->dev_attr.store = rw->set; | ||
656 | sensors->index = rw->index; | ||
657 | |||
658 | res = device_create_file(dev, &sensors->dev_attr); | ||
659 | if (res) { | ||
660 | sensors->dev_attr.attr.name = NULL; | ||
661 | goto error; | ||
662 | } | ||
663 | sensors++; | ||
664 | resource->num_sensors++; | ||
665 | rw++; | ||
666 | } | ||
667 | |||
668 | error: | ||
669 | return res; | ||
670 | } | ||
671 | |||
672 | static void remove_attrs(struct acpi_power_meter_resource *resource) | ||
673 | { | ||
674 | int i; | ||
675 | |||
676 | for (i = 0; i < resource->num_sensors; i++) { | ||
677 | if (!resource->sensors[i].dev_attr.attr.name) | ||
678 | continue; | ||
679 | device_remove_file(&resource->acpi_dev->dev, | ||
680 | &resource->sensors[i].dev_attr); | ||
681 | } | ||
682 | |||
683 | remove_domain_devices(resource); | ||
684 | |||
685 | resource->num_sensors = 0; | ||
686 | } | ||
687 | |||
688 | static int setup_attrs(struct acpi_power_meter_resource *resource) | ||
689 | { | ||
690 | int res = 0; | ||
691 | |||
692 | res = read_domain_devices(resource); | ||
693 | if (res) | ||
694 | return res; | ||
695 | |||
696 | if (resource->caps.flags & POWER_METER_CAN_MEASURE) { | ||
697 | res = register_ro_attrs(resource, meter_ro_attrs); | ||
698 | if (res) | ||
699 | goto error; | ||
700 | res = register_rw_attrs(resource, meter_rw_attrs); | ||
701 | if (res) | ||
702 | goto error; | ||
703 | } | ||
704 | |||
705 | if (resource->caps.flags & POWER_METER_CAN_CAP) { | ||
706 | if (!can_cap_in_hardware()) { | ||
707 | dev_err(&resource->acpi_dev->dev, | ||
708 | "Ignoring unsafe software power cap!\n"); | ||
709 | goto skip_unsafe_cap; | ||
710 | } | ||
711 | |||
712 | if (resource->caps.configurable_cap) { | ||
713 | res = register_rw_attrs(resource, rw_cap_attrs); | ||
714 | if (res) | ||
715 | goto error; | ||
716 | } else { | ||
717 | res = register_ro_attrs(resource, ro_cap_attrs); | ||
718 | if (res) | ||
719 | goto error; | ||
720 | } | ||
721 | res = register_ro_attrs(resource, misc_cap_attrs); | ||
722 | if (res) | ||
723 | goto error; | ||
724 | } | ||
725 | skip_unsafe_cap: | ||
726 | |||
727 | if (resource->caps.flags & POWER_METER_CAN_TRIP) { | ||
728 | res = register_rw_attrs(resource, trip_attrs); | ||
729 | if (res) | ||
730 | goto error; | ||
731 | } | ||
732 | |||
733 | res = register_ro_attrs(resource, misc_attrs); | ||
734 | if (res) | ||
735 | goto error; | ||
736 | |||
737 | return res; | ||
738 | error: | ||
739 | remove_domain_devices(resource); | ||
740 | remove_attrs(resource); | ||
741 | return res; | ||
742 | } | ||
743 | |||
744 | static void free_capabilities(struct acpi_power_meter_resource *resource) | ||
745 | { | ||
746 | acpi_string *str; | ||
747 | int i; | ||
748 | |||
749 | str = &resource->model_number; | ||
750 | for (i = 0; i < 3; i++, str++) | ||
751 | kfree(*str); | ||
752 | } | ||
753 | |||
754 | static int read_capabilities(struct acpi_power_meter_resource *resource) | ||
755 | { | ||
756 | int res = 0; | ||
757 | int i; | ||
758 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
759 | struct acpi_buffer state = { 0, NULL }; | ||
760 | struct acpi_buffer format = { sizeof("NNNNNNNNNNN"), "NNNNNNNNNNN" }; | ||
761 | union acpi_object *pss; | ||
762 | acpi_string *str; | ||
763 | acpi_status status; | ||
764 | |||
765 | status = acpi_evaluate_object(resource->acpi_dev->handle, "_PMC", NULL, | ||
766 | &buffer); | ||
767 | if (ACPI_FAILURE(status)) { | ||
768 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMC")); | ||
769 | return -ENODEV; | ||
770 | } | ||
771 | |||
772 | pss = buffer.pointer; | ||
773 | if (!pss || | ||
774 | pss->type != ACPI_TYPE_PACKAGE || | ||
775 | pss->package.count != 14) { | ||
776 | dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME | ||
777 | "Invalid _PMC data\n"); | ||
778 | res = -EFAULT; | ||
779 | goto end; | ||
780 | } | ||
781 | |||
782 | /* Grab all the integer data at once */ | ||
783 | state.length = sizeof(struct acpi_power_meter_capabilities); | ||
784 | state.pointer = &resource->caps; | ||
785 | |||
786 | status = acpi_extract_package(pss, &format, &state); | ||
787 | if (ACPI_FAILURE(status)) { | ||
788 | ACPI_EXCEPTION((AE_INFO, status, "Invalid data")); | ||
789 | res = -EFAULT; | ||
790 | goto end; | ||
791 | } | ||
792 | |||
793 | if (resource->caps.units) { | ||
794 | dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME | ||
795 | "Unknown units %llu.\n", | ||
796 | resource->caps.units); | ||
797 | res = -EINVAL; | ||
798 | goto end; | ||
799 | } | ||
800 | |||
801 | /* Grab the string data */ | ||
802 | str = &resource->model_number; | ||
803 | |||
804 | for (i = 11; i < 14; i++) { | ||
805 | union acpi_object *element = &(pss->package.elements[i]); | ||
806 | |||
807 | if (element->type != ACPI_TYPE_STRING) { | ||
808 | res = -EINVAL; | ||
809 | goto error; | ||
810 | } | ||
811 | |||
812 | *str = kzalloc(sizeof(u8) * (element->string.length + 1), | ||
813 | GFP_KERNEL); | ||
814 | if (!*str) { | ||
815 | res = -ENOMEM; | ||
816 | goto error; | ||
817 | } | ||
818 | |||
819 | strncpy(*str, element->string.pointer, element->string.length); | ||
820 | str++; | ||
821 | } | ||
822 | |||
823 | dev_info(&resource->acpi_dev->dev, "Found ACPI power meter.\n"); | ||
824 | goto end; | ||
825 | error: | ||
826 | str = &resource->model_number; | ||
827 | for (i = 0; i < 3; i++, str++) | ||
828 | kfree(*str); | ||
829 | end: | ||
830 | kfree(buffer.pointer); | ||
831 | return res; | ||
832 | } | ||
833 | |||
834 | /* Handle ACPI event notifications */ | ||
835 | static void acpi_power_meter_notify(struct acpi_device *device, u32 event) | ||
836 | { | ||
837 | struct acpi_power_meter_resource *resource; | ||
838 | int res; | ||
839 | |||
840 | if (!device || !acpi_driver_data(device)) | ||
841 | return; | ||
842 | |||
843 | resource = acpi_driver_data(device); | ||
844 | |||
845 | mutex_lock(&resource->lock); | ||
846 | switch (event) { | ||
847 | case METER_NOTIFY_CONFIG: | ||
848 | free_capabilities(resource); | ||
849 | res = read_capabilities(resource); | ||
850 | if (res) | ||
851 | break; | ||
852 | |||
853 | remove_attrs(resource); | ||
854 | setup_attrs(resource); | ||
855 | break; | ||
856 | case METER_NOTIFY_TRIP: | ||
857 | sysfs_notify(&device->dev.kobj, NULL, POWER_AVERAGE_NAME); | ||
858 | update_meter(resource); | ||
859 | break; | ||
860 | case METER_NOTIFY_CAP: | ||
861 | sysfs_notify(&device->dev.kobj, NULL, POWER_CAP_NAME); | ||
862 | update_cap(resource); | ||
863 | break; | ||
864 | case METER_NOTIFY_INTERVAL: | ||
865 | sysfs_notify(&device->dev.kobj, NULL, POWER_AVG_INTERVAL_NAME); | ||
866 | update_avg_interval(resource); | ||
867 | break; | ||
868 | case METER_NOTIFY_CAPPING: | ||
869 | sysfs_notify(&device->dev.kobj, NULL, POWER_ALARM_NAME); | ||
870 | dev_info(&device->dev, "Capping in progress.\n"); | ||
871 | break; | ||
872 | default: | ||
873 | BUG(); | ||
874 | } | ||
875 | mutex_unlock(&resource->lock); | ||
876 | |||
877 | acpi_bus_generate_netlink_event(ACPI_POWER_METER_CLASS, | ||
878 | dev_name(&device->dev), event, 0); | ||
879 | } | ||
880 | |||
881 | static int acpi_power_meter_add(struct acpi_device *device) | ||
882 | { | ||
883 | int res; | ||
884 | struct acpi_power_meter_resource *resource; | ||
885 | |||
886 | if (!device) | ||
887 | return -EINVAL; | ||
888 | |||
889 | resource = kzalloc(sizeof(struct acpi_power_meter_resource), | ||
890 | GFP_KERNEL); | ||
891 | if (!resource) | ||
892 | return -ENOMEM; | ||
893 | |||
894 | resource->sensors_valid = 0; | ||
895 | resource->acpi_dev = device; | ||
896 | mutex_init(&resource->lock); | ||
897 | strcpy(acpi_device_name(device), ACPI_POWER_METER_DEVICE_NAME); | ||
898 | strcpy(acpi_device_class(device), ACPI_POWER_METER_CLASS); | ||
899 | device->driver_data = resource; | ||
900 | |||
901 | free_capabilities(resource); | ||
902 | res = read_capabilities(resource); | ||
903 | if (res) | ||
904 | goto exit_free; | ||
905 | |||
906 | resource->trip[0] = resource->trip[1] = -1; | ||
907 | |||
908 | res = setup_attrs(resource); | ||
909 | if (res) | ||
910 | goto exit_free; | ||
911 | |||
912 | resource->hwmon_dev = hwmon_device_register(&device->dev); | ||
913 | if (IS_ERR(resource->hwmon_dev)) { | ||
914 | res = PTR_ERR(resource->hwmon_dev); | ||
915 | goto exit_remove; | ||
916 | } | ||
917 | |||
918 | res = 0; | ||
919 | goto exit; | ||
920 | |||
921 | exit_remove: | ||
922 | remove_attrs(resource); | ||
923 | exit_free: | ||
924 | kfree(resource); | ||
925 | exit: | ||
926 | return res; | ||
927 | } | ||
928 | |||
929 | static int acpi_power_meter_remove(struct acpi_device *device, int type) | ||
930 | { | ||
931 | struct acpi_power_meter_resource *resource; | ||
932 | |||
933 | if (!device || !acpi_driver_data(device)) | ||
934 | return -EINVAL; | ||
935 | |||
936 | resource = acpi_driver_data(device); | ||
937 | hwmon_device_unregister(resource->hwmon_dev); | ||
938 | |||
939 | free_capabilities(resource); | ||
940 | remove_attrs(resource); | ||
941 | |||
942 | kfree(resource); | ||
943 | return 0; | ||
944 | } | ||
945 | |||
946 | static int acpi_power_meter_resume(struct acpi_device *device) | ||
947 | { | ||
948 | struct acpi_power_meter_resource *resource; | ||
949 | |||
950 | if (!device || !acpi_driver_data(device)) | ||
951 | return -EINVAL; | ||
952 | |||
953 | resource = acpi_driver_data(device); | ||
954 | free_capabilities(resource); | ||
955 | read_capabilities(resource); | ||
956 | |||
957 | return 0; | ||
958 | } | ||
959 | |||
960 | static struct acpi_driver acpi_power_meter_driver = { | ||
961 | .name = "power_meter", | ||
962 | .class = ACPI_POWER_METER_CLASS, | ||
963 | .ids = power_meter_ids, | ||
964 | .ops = { | ||
965 | .add = acpi_power_meter_add, | ||
966 | .remove = acpi_power_meter_remove, | ||
967 | .resume = acpi_power_meter_resume, | ||
968 | .notify = acpi_power_meter_notify, | ||
969 | }, | ||
970 | }; | ||
971 | |||
972 | /* Module init/exit routines */ | ||
973 | static int __init enable_cap_knobs(const struct dmi_system_id *d) | ||
974 | { | ||
975 | cap_in_hardware = 1; | ||
976 | return 0; | ||
977 | } | ||
978 | |||
979 | static struct dmi_system_id __initdata pm_dmi_table[] = { | ||
980 | { | ||
981 | enable_cap_knobs, "IBM Active Energy Manager", | ||
982 | { | ||
983 | DMI_MATCH(DMI_SYS_VENDOR, "IBM") | ||
984 | }, | ||
985 | }, | ||
986 | {} | ||
987 | }; | ||
988 | |||
989 | static int __init acpi_power_meter_init(void) | ||
990 | { | ||
991 | int result; | ||
992 | |||
993 | if (acpi_disabled) | ||
994 | return -ENODEV; | ||
995 | |||
996 | dmi_check_system(pm_dmi_table); | ||
997 | |||
998 | result = acpi_bus_register_driver(&acpi_power_meter_driver); | ||
999 | if (result < 0) | ||
1000 | return -ENODEV; | ||
1001 | |||
1002 | return 0; | ||
1003 | } | ||
1004 | |||
1005 | static void __exit acpi_power_meter_exit(void) | ||
1006 | { | ||
1007 | acpi_bus_unregister_driver(&acpi_power_meter_driver); | ||
1008 | } | ||
1009 | |||
1010 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); | ||
1011 | MODULE_DESCRIPTION("ACPI 4.0 power meter driver"); | ||
1012 | MODULE_LICENSE("GPL"); | ||
1013 | |||
1014 | module_param(force_cap_on, bool, 0644); | ||
1015 | MODULE_PARM_DESC(force_cap_on, "Enable power cap even it is unsafe to do so."); | ||
1016 | |||
1017 | module_init(acpi_power_meter_init); | ||
1018 | module_exit(acpi_power_meter_exit); | ||
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 2cc4b3033872..c2d4d6e09364 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -59,6 +59,8 @@ | |||
59 | #include <acpi/acpi_drivers.h> | 59 | #include <acpi/acpi_drivers.h> |
60 | #include <acpi/processor.h> | 60 | #include <acpi/processor.h> |
61 | 61 | ||
62 | #define PREFIX "ACPI: " | ||
63 | |||
62 | #define ACPI_PROCESSOR_CLASS "processor" | 64 | #define ACPI_PROCESSOR_CLASS "processor" |
63 | #define ACPI_PROCESSOR_DEVICE_NAME "Processor" | 65 | #define ACPI_PROCESSOR_DEVICE_NAME "Processor" |
64 | #define ACPI_PROCESSOR_FILE_INFO "info" | 66 | #define ACPI_PROCESSOR_FILE_INFO "info" |
@@ -79,9 +81,10 @@ MODULE_DESCRIPTION("ACPI Processor Driver"); | |||
79 | MODULE_LICENSE("GPL"); | 81 | MODULE_LICENSE("GPL"); |
80 | 82 | ||
81 | static int acpi_processor_add(struct acpi_device *device); | 83 | static int acpi_processor_add(struct acpi_device *device); |
82 | static int acpi_processor_start(struct acpi_device *device); | ||
83 | static int acpi_processor_remove(struct acpi_device *device, int type); | 84 | static int acpi_processor_remove(struct acpi_device *device, int type); |
85 | #ifdef CONFIG_ACPI_PROCFS | ||
84 | static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); | 86 | static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); |
87 | #endif | ||
85 | static void acpi_processor_notify(struct acpi_device *device, u32 event); | 88 | static void acpi_processor_notify(struct acpi_device *device, u32 event); |
86 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); | 89 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); |
87 | static int acpi_processor_handle_eject(struct acpi_processor *pr); | 90 | static int acpi_processor_handle_eject(struct acpi_processor *pr); |
@@ -101,7 +104,6 @@ static struct acpi_driver acpi_processor_driver = { | |||
101 | .ops = { | 104 | .ops = { |
102 | .add = acpi_processor_add, | 105 | .add = acpi_processor_add, |
103 | .remove = acpi_processor_remove, | 106 | .remove = acpi_processor_remove, |
104 | .start = acpi_processor_start, | ||
105 | .suspend = acpi_processor_suspend, | 107 | .suspend = acpi_processor_suspend, |
106 | .resume = acpi_processor_resume, | 108 | .resume = acpi_processor_resume, |
107 | .notify = acpi_processor_notify, | 109 | .notify = acpi_processor_notify, |
@@ -110,7 +112,7 @@ static struct acpi_driver acpi_processor_driver = { | |||
110 | 112 | ||
111 | #define INSTALL_NOTIFY_HANDLER 1 | 113 | #define INSTALL_NOTIFY_HANDLER 1 |
112 | #define UNINSTALL_NOTIFY_HANDLER 2 | 114 | #define UNINSTALL_NOTIFY_HANDLER 2 |
113 | 115 | #ifdef CONFIG_ACPI_PROCFS | |
114 | static const struct file_operations acpi_processor_info_fops = { | 116 | static const struct file_operations acpi_processor_info_fops = { |
115 | .owner = THIS_MODULE, | 117 | .owner = THIS_MODULE, |
116 | .open = acpi_processor_info_open_fs, | 118 | .open = acpi_processor_info_open_fs, |
@@ -118,6 +120,7 @@ static const struct file_operations acpi_processor_info_fops = { | |||
118 | .llseek = seq_lseek, | 120 | .llseek = seq_lseek, |
119 | .release = single_release, | 121 | .release = single_release, |
120 | }; | 122 | }; |
123 | #endif | ||
121 | 124 | ||
122 | DEFINE_PER_CPU(struct acpi_processor *, processors); | 125 | DEFINE_PER_CPU(struct acpi_processor *, processors); |
123 | struct acpi_processor_errata errata __read_mostly; | 126 | struct acpi_processor_errata errata __read_mostly; |
@@ -316,6 +319,7 @@ static int acpi_processor_set_pdc(struct acpi_processor *pr) | |||
316 | FS Interface (/proc) | 319 | FS Interface (/proc) |
317 | -------------------------------------------------------------------------- */ | 320 | -------------------------------------------------------------------------- */ |
318 | 321 | ||
322 | #ifdef CONFIG_ACPI_PROCFS | ||
319 | static struct proc_dir_entry *acpi_processor_dir = NULL; | 323 | static struct proc_dir_entry *acpi_processor_dir = NULL; |
320 | 324 | ||
321 | static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset) | 325 | static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset) |
@@ -388,7 +392,6 @@ static int acpi_processor_add_fs(struct acpi_device *device) | |||
388 | return -EIO; | 392 | return -EIO; |
389 | return 0; | 393 | return 0; |
390 | } | 394 | } |
391 | |||
392 | static int acpi_processor_remove_fs(struct acpi_device *device) | 395 | static int acpi_processor_remove_fs(struct acpi_device *device) |
393 | { | 396 | { |
394 | 397 | ||
@@ -405,6 +408,16 @@ static int acpi_processor_remove_fs(struct acpi_device *device) | |||
405 | 408 | ||
406 | return 0; | 409 | return 0; |
407 | } | 410 | } |
411 | #else | ||
412 | static inline int acpi_processor_add_fs(struct acpi_device *device) | ||
413 | { | ||
414 | return 0; | ||
415 | } | ||
416 | static inline int acpi_processor_remove_fs(struct acpi_device *device) | ||
417 | { | ||
418 | return 0; | ||
419 | } | ||
420 | #endif | ||
408 | 421 | ||
409 | /* Use the acpiid in MADT to map cpus in case of SMP */ | 422 | /* Use the acpiid in MADT to map cpus in case of SMP */ |
410 | 423 | ||
@@ -698,92 +711,6 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
698 | 711 | ||
699 | static DEFINE_PER_CPU(void *, processor_device_array); | 712 | static DEFINE_PER_CPU(void *, processor_device_array); |
700 | 713 | ||
701 | static int __cpuinit acpi_processor_start(struct acpi_device *device) | ||
702 | { | ||
703 | int result = 0; | ||
704 | struct acpi_processor *pr; | ||
705 | struct sys_device *sysdev; | ||
706 | |||
707 | pr = acpi_driver_data(device); | ||
708 | |||
709 | result = acpi_processor_get_info(device); | ||
710 | if (result) { | ||
711 | /* Processor is physically not present */ | ||
712 | return 0; | ||
713 | } | ||
714 | |||
715 | BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); | ||
716 | |||
717 | /* | ||
718 | * Buggy BIOS check | ||
719 | * ACPI id of processors can be reported wrongly by the BIOS. | ||
720 | * Don't trust it blindly | ||
721 | */ | ||
722 | if (per_cpu(processor_device_array, pr->id) != NULL && | ||
723 | per_cpu(processor_device_array, pr->id) != device) { | ||
724 | printk(KERN_WARNING "BIOS reported wrong ACPI id " | ||
725 | "for the processor\n"); | ||
726 | return -ENODEV; | ||
727 | } | ||
728 | per_cpu(processor_device_array, pr->id) = device; | ||
729 | |||
730 | per_cpu(processors, pr->id) = pr; | ||
731 | |||
732 | result = acpi_processor_add_fs(device); | ||
733 | if (result) | ||
734 | goto end; | ||
735 | |||
736 | sysdev = get_cpu_sysdev(pr->id); | ||
737 | if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) | ||
738 | return -EFAULT; | ||
739 | |||
740 | /* _PDC call should be done before doing anything else (if reqd.). */ | ||
741 | arch_acpi_processor_init_pdc(pr); | ||
742 | acpi_processor_set_pdc(pr); | ||
743 | arch_acpi_processor_cleanup_pdc(pr); | ||
744 | |||
745 | #ifdef CONFIG_CPU_FREQ | ||
746 | acpi_processor_ppc_has_changed(pr); | ||
747 | #endif | ||
748 | acpi_processor_get_throttling_info(pr); | ||
749 | acpi_processor_get_limit_info(pr); | ||
750 | |||
751 | |||
752 | acpi_processor_power_init(pr, device); | ||
753 | |||
754 | pr->cdev = thermal_cooling_device_register("Processor", device, | ||
755 | &processor_cooling_ops); | ||
756 | if (IS_ERR(pr->cdev)) { | ||
757 | result = PTR_ERR(pr->cdev); | ||
758 | goto end; | ||
759 | } | ||
760 | |||
761 | dev_info(&device->dev, "registered as cooling_device%d\n", | ||
762 | pr->cdev->id); | ||
763 | |||
764 | result = sysfs_create_link(&device->dev.kobj, | ||
765 | &pr->cdev->device.kobj, | ||
766 | "thermal_cooling"); | ||
767 | if (result) | ||
768 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
769 | result = sysfs_create_link(&pr->cdev->device.kobj, | ||
770 | &device->dev.kobj, | ||
771 | "device"); | ||
772 | if (result) | ||
773 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
774 | |||
775 | if (pr->flags.throttling) { | ||
776 | printk(KERN_INFO PREFIX "%s [%s] (supports", | ||
777 | acpi_device_name(device), acpi_device_bid(device)); | ||
778 | printk(" %d throttling states", pr->throttling.state_count); | ||
779 | printk(")\n"); | ||
780 | } | ||
781 | |||
782 | end: | ||
783 | |||
784 | return result; | ||
785 | } | ||
786 | |||
787 | static void acpi_processor_notify(struct acpi_device *device, u32 event) | 714 | static void acpi_processor_notify(struct acpi_device *device, u32 event) |
788 | { | 715 | { |
789 | struct acpi_processor *pr = acpi_driver_data(device); | 716 | struct acpi_processor *pr = acpi_driver_data(device); |
@@ -846,10 +773,8 @@ static struct notifier_block acpi_cpu_notifier = | |||
846 | static int acpi_processor_add(struct acpi_device *device) | 773 | static int acpi_processor_add(struct acpi_device *device) |
847 | { | 774 | { |
848 | struct acpi_processor *pr = NULL; | 775 | struct acpi_processor *pr = NULL; |
849 | 776 | int result = 0; | |
850 | 777 | struct sys_device *sysdev; | |
851 | if (!device) | ||
852 | return -EINVAL; | ||
853 | 778 | ||
854 | pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); | 779 | pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); |
855 | if (!pr) | 780 | if (!pr) |
@@ -865,7 +790,100 @@ static int acpi_processor_add(struct acpi_device *device) | |||
865 | strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); | 790 | strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); |
866 | device->driver_data = pr; | 791 | device->driver_data = pr; |
867 | 792 | ||
793 | result = acpi_processor_get_info(device); | ||
794 | if (result) { | ||
795 | /* Processor is physically not present */ | ||
796 | return 0; | ||
797 | } | ||
798 | |||
799 | BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); | ||
800 | |||
801 | /* | ||
802 | * Buggy BIOS check | ||
803 | * ACPI id of processors can be reported wrongly by the BIOS. | ||
804 | * Don't trust it blindly | ||
805 | */ | ||
806 | if (per_cpu(processor_device_array, pr->id) != NULL && | ||
807 | per_cpu(processor_device_array, pr->id) != device) { | ||
808 | printk(KERN_WARNING "BIOS reported wrong ACPI id " | ||
809 | "for the processor\n"); | ||
810 | result = -ENODEV; | ||
811 | goto err_free_cpumask; | ||
812 | } | ||
813 | per_cpu(processor_device_array, pr->id) = device; | ||
814 | |||
815 | per_cpu(processors, pr->id) = pr; | ||
816 | |||
817 | result = acpi_processor_add_fs(device); | ||
818 | if (result) | ||
819 | goto err_free_cpumask; | ||
820 | |||
821 | sysdev = get_cpu_sysdev(pr->id); | ||
822 | if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) { | ||
823 | result = -EFAULT; | ||
824 | goto err_remove_fs; | ||
825 | } | ||
826 | |||
827 | /* _PDC call should be done before doing anything else (if reqd.). */ | ||
828 | arch_acpi_processor_init_pdc(pr); | ||
829 | acpi_processor_set_pdc(pr); | ||
830 | arch_acpi_processor_cleanup_pdc(pr); | ||
831 | |||
832 | #ifdef CONFIG_CPU_FREQ | ||
833 | acpi_processor_ppc_has_changed(pr); | ||
834 | #endif | ||
835 | acpi_processor_get_throttling_info(pr); | ||
836 | acpi_processor_get_limit_info(pr); | ||
837 | |||
838 | |||
839 | acpi_processor_power_init(pr, device); | ||
840 | |||
841 | pr->cdev = thermal_cooling_device_register("Processor", device, | ||
842 | &processor_cooling_ops); | ||
843 | if (IS_ERR(pr->cdev)) { | ||
844 | result = PTR_ERR(pr->cdev); | ||
845 | goto err_power_exit; | ||
846 | } | ||
847 | |||
848 | dev_info(&device->dev, "registered as cooling_device%d\n", | ||
849 | pr->cdev->id); | ||
850 | |||
851 | result = sysfs_create_link(&device->dev.kobj, | ||
852 | &pr->cdev->device.kobj, | ||
853 | "thermal_cooling"); | ||
854 | if (result) { | ||
855 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
856 | goto err_thermal_unregister; | ||
857 | } | ||
858 | result = sysfs_create_link(&pr->cdev->device.kobj, | ||
859 | &device->dev.kobj, | ||
860 | "device"); | ||
861 | if (result) { | ||
862 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
863 | goto err_remove_sysfs; | ||
864 | } | ||
865 | |||
866 | if (pr->flags.throttling) { | ||
867 | printk(KERN_INFO PREFIX "%s [%s] (supports", | ||
868 | acpi_device_name(device), acpi_device_bid(device)); | ||
869 | printk(" %d throttling states", pr->throttling.state_count); | ||
870 | printk(")\n"); | ||
871 | } | ||
872 | |||
868 | return 0; | 873 | return 0; |
874 | |||
875 | err_remove_sysfs: | ||
876 | sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); | ||
877 | err_thermal_unregister: | ||
878 | thermal_cooling_device_unregister(pr->cdev); | ||
879 | err_power_exit: | ||
880 | acpi_processor_power_exit(pr, device); | ||
881 | err_remove_fs: | ||
882 | acpi_processor_remove_fs(device); | ||
883 | err_free_cpumask: | ||
884 | free_cpumask_var(pr->throttling.shared_cpu_map); | ||
885 | |||
886 | return result; | ||
869 | } | 887 | } |
870 | 888 | ||
871 | static int acpi_processor_remove(struct acpi_device *device, int type) | 889 | static int acpi_processor_remove(struct acpi_device *device, int type) |
@@ -942,7 +960,6 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) | |||
942 | { | 960 | { |
943 | acpi_handle phandle; | 961 | acpi_handle phandle; |
944 | struct acpi_device *pdev; | 962 | struct acpi_device *pdev; |
945 | struct acpi_processor *pr; | ||
946 | 963 | ||
947 | 964 | ||
948 | if (acpi_get_parent(handle, &phandle)) { | 965 | if (acpi_get_parent(handle, &phandle)) { |
@@ -957,15 +974,6 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) | |||
957 | return -ENODEV; | 974 | return -ENODEV; |
958 | } | 975 | } |
959 | 976 | ||
960 | acpi_bus_start(*device); | ||
961 | |||
962 | pr = acpi_driver_data(*device); | ||
963 | if (!pr) | ||
964 | return -ENODEV; | ||
965 | |||
966 | if ((pr->id >= 0) && (pr->id < nr_cpu_ids)) { | ||
967 | kobject_uevent(&(*device)->dev.kobj, KOBJ_ONLINE); | ||
968 | } | ||
969 | return 0; | 977 | return 0; |
970 | } | 978 | } |
971 | 979 | ||
@@ -995,25 +1003,6 @@ static void __ref acpi_processor_hotplug_notify(acpi_handle handle, | |||
995 | "Unable to add the device\n"); | 1003 | "Unable to add the device\n"); |
996 | break; | 1004 | break; |
997 | } | 1005 | } |
998 | |||
999 | pr = acpi_driver_data(device); | ||
1000 | if (!pr) { | ||
1001 | printk(KERN_ERR PREFIX "Driver data is NULL\n"); | ||
1002 | break; | ||
1003 | } | ||
1004 | |||
1005 | if (pr->id >= 0 && (pr->id < nr_cpu_ids)) { | ||
1006 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); | ||
1007 | break; | ||
1008 | } | ||
1009 | |||
1010 | result = acpi_processor_start(device); | ||
1011 | if ((!result) && ((pr->id >= 0) && (pr->id < nr_cpu_ids))) { | ||
1012 | kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); | ||
1013 | } else { | ||
1014 | printk(KERN_ERR PREFIX "Device [%s] failed to start\n", | ||
1015 | acpi_device_bid(device)); | ||
1016 | } | ||
1017 | break; | 1006 | break; |
1018 | case ACPI_NOTIFY_EJECT_REQUEST: | 1007 | case ACPI_NOTIFY_EJECT_REQUEST: |
1019 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 1008 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
@@ -1030,9 +1019,6 @@ static void __ref acpi_processor_hotplug_notify(acpi_handle handle, | |||
1030 | "Driver data is NULL, dropping EJECT\n"); | 1019 | "Driver data is NULL, dropping EJECT\n"); |
1031 | return; | 1020 | return; |
1032 | } | 1021 | } |
1033 | |||
1034 | if ((pr->id < nr_cpu_ids) && (cpu_present(pr->id))) | ||
1035 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); | ||
1036 | break; | 1022 | break; |
1037 | default: | 1023 | default: |
1038 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 1024 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
@@ -1161,11 +1147,11 @@ static int __init acpi_processor_init(void) | |||
1161 | (struct acpi_table_header **)&madt))) | 1147 | (struct acpi_table_header **)&madt))) |
1162 | madt = NULL; | 1148 | madt = NULL; |
1163 | #endif | 1149 | #endif |
1164 | 1150 | #ifdef CONFIG_ACPI_PROCFS | |
1165 | acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 1151 | acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
1166 | if (!acpi_processor_dir) | 1152 | if (!acpi_processor_dir) |
1167 | return -ENOMEM; | 1153 | return -ENOMEM; |
1168 | 1154 | #endif | |
1169 | /* | 1155 | /* |
1170 | * Check whether the system is DMI table. If yes, OSPM | 1156 | * Check whether the system is DMI table. If yes, OSPM |
1171 | * should not use mwait for CPU-states. | 1157 | * should not use mwait for CPU-states. |
@@ -1193,7 +1179,9 @@ out_cpuidle: | |||
1193 | cpuidle_unregister_driver(&acpi_idle_driver); | 1179 | cpuidle_unregister_driver(&acpi_idle_driver); |
1194 | 1180 | ||
1195 | out_proc: | 1181 | out_proc: |
1182 | #ifdef CONFIG_ACPI_PROCFS | ||
1196 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 1183 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
1184 | #endif | ||
1197 | 1185 | ||
1198 | return result; | 1186 | return result; |
1199 | } | 1187 | } |
@@ -1213,7 +1201,9 @@ static void __exit acpi_processor_exit(void) | |||
1213 | 1201 | ||
1214 | cpuidle_unregister_driver(&acpi_idle_driver); | 1202 | cpuidle_unregister_driver(&acpi_idle_driver); |
1215 | 1203 | ||
1204 | #ifdef CONFIG_ACPI_PROCFS | ||
1216 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 1205 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
1206 | #endif | ||
1217 | 1207 | ||
1218 | return; | 1208 | return; |
1219 | } | 1209 | } |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 66393d5c4c7c..cc61a6220102 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -60,6 +60,8 @@ | |||
60 | #include <acpi/processor.h> | 60 | #include <acpi/processor.h> |
61 | #include <asm/processor.h> | 61 | #include <asm/processor.h> |
62 | 62 | ||
63 | #define PREFIX "ACPI: " | ||
64 | |||
63 | #define ACPI_PROCESSOR_CLASS "processor" | 65 | #define ACPI_PROCESSOR_CLASS "processor" |
64 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 66 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
65 | ACPI_MODULE_NAME("processor_idle"); | 67 | ACPI_MODULE_NAME("processor_idle"); |
@@ -680,6 +682,7 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr) | |||
680 | return 0; | 682 | return 0; |
681 | } | 683 | } |
682 | 684 | ||
685 | #ifdef CONFIG_ACPI_PROCFS | ||
683 | static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) | 686 | static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) |
684 | { | 687 | { |
685 | struct acpi_processor *pr = seq->private; | 688 | struct acpi_processor *pr = seq->private; |
@@ -759,7 +762,7 @@ static const struct file_operations acpi_processor_power_fops = { | |||
759 | .llseek = seq_lseek, | 762 | .llseek = seq_lseek, |
760 | .release = single_release, | 763 | .release = single_release, |
761 | }; | 764 | }; |
762 | 765 | #endif | |
763 | 766 | ||
764 | /** | 767 | /** |
765 | * acpi_idle_bm_check - checks if bus master activity was detected | 768 | * acpi_idle_bm_check - checks if bus master activity was detected |
@@ -1160,7 +1163,9 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1160 | { | 1163 | { |
1161 | acpi_status status = 0; | 1164 | acpi_status status = 0; |
1162 | static int first_run; | 1165 | static int first_run; |
1166 | #ifdef CONFIG_ACPI_PROCFS | ||
1163 | struct proc_dir_entry *entry = NULL; | 1167 | struct proc_dir_entry *entry = NULL; |
1168 | #endif | ||
1164 | unsigned int i; | 1169 | unsigned int i; |
1165 | 1170 | ||
1166 | if (boot_option_idle_override) | 1171 | if (boot_option_idle_override) |
@@ -1217,7 +1222,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1217 | pr->power.states[i].type); | 1222 | pr->power.states[i].type); |
1218 | printk(")\n"); | 1223 | printk(")\n"); |
1219 | } | 1224 | } |
1220 | 1225 | #ifdef CONFIG_ACPI_PROCFS | |
1221 | /* 'power' [R] */ | 1226 | /* 'power' [R] */ |
1222 | entry = proc_create_data(ACPI_PROCESSOR_FILE_POWER, | 1227 | entry = proc_create_data(ACPI_PROCESSOR_FILE_POWER, |
1223 | S_IRUGO, acpi_device_dir(device), | 1228 | S_IRUGO, acpi_device_dir(device), |
@@ -1225,6 +1230,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1225 | acpi_driver_data(device)); | 1230 | acpi_driver_data(device)); |
1226 | if (!entry) | 1231 | if (!entry) |
1227 | return -EIO; | 1232 | return -EIO; |
1233 | #endif | ||
1228 | return 0; | 1234 | return 0; |
1229 | } | 1235 | } |
1230 | 1236 | ||
@@ -1237,9 +1243,11 @@ int acpi_processor_power_exit(struct acpi_processor *pr, | |||
1237 | cpuidle_unregister_device(&pr->power.dev); | 1243 | cpuidle_unregister_device(&pr->power.dev); |
1238 | pr->flags.power_setup_done = 0; | 1244 | pr->flags.power_setup_done = 0; |
1239 | 1245 | ||
1246 | #ifdef CONFIG_ACPI_PROCFS | ||
1240 | if (acpi_device_dir(device)) | 1247 | if (acpi_device_dir(device)) |
1241 | remove_proc_entry(ACPI_PROCESSOR_FILE_POWER, | 1248 | remove_proc_entry(ACPI_PROCESSOR_FILE_POWER, |
1242 | acpi_device_dir(device)); | 1249 | acpi_device_dir(device)); |
1250 | #endif | ||
1243 | 1251 | ||
1244 | return 0; | 1252 | return 0; |
1245 | } | 1253 | } |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 60e543d3234e..11088cf10319 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <acpi/acpi_drivers.h> | 39 | #include <acpi/acpi_drivers.h> |
40 | #include <acpi/processor.h> | 40 | #include <acpi/processor.h> |
41 | 41 | ||
42 | #define PREFIX "ACPI: " | ||
43 | |||
42 | #define ACPI_PROCESSOR_CLASS "processor" | 44 | #define ACPI_PROCESSOR_CLASS "processor" |
43 | #define ACPI_PROCESSOR_FILE_PERFORMANCE "performance" | 45 | #define ACPI_PROCESSOR_FILE_PERFORMANCE "performance" |
44 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 46 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index 31adda1099e0..140c5c5b423c 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include <acpi/processor.h> | 40 | #include <acpi/processor.h> |
41 | #include <acpi/acpi_drivers.h> | 41 | #include <acpi/acpi_drivers.h> |
42 | 42 | ||
43 | #define PREFIX "ACPI: " | ||
44 | |||
43 | #define ACPI_PROCESSOR_CLASS "processor" | 45 | #define ACPI_PROCESSOR_CLASS "processor" |
44 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 46 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
45 | ACPI_MODULE_NAME("processor_thermal"); | 47 | ACPI_MODULE_NAME("processor_thermal"); |
@@ -438,7 +440,7 @@ struct thermal_cooling_device_ops processor_cooling_ops = { | |||
438 | }; | 440 | }; |
439 | 441 | ||
440 | /* /proc interface */ | 442 | /* /proc interface */ |
441 | 443 | #ifdef CONFIG_ACPI_PROCFS | |
442 | static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset) | 444 | static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset) |
443 | { | 445 | { |
444 | struct acpi_processor *pr = (struct acpi_processor *)seq->private; | 446 | struct acpi_processor *pr = (struct acpi_processor *)seq->private; |
@@ -517,3 +519,4 @@ const struct file_operations acpi_processor_limit_fops = { | |||
517 | .llseek = seq_lseek, | 519 | .llseek = seq_lseek, |
518 | .release = single_release, | 520 | .release = single_release, |
519 | }; | 521 | }; |
522 | #endif | ||
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index ae39797aab55..ce7cf3bc5101 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
@@ -41,6 +41,8 @@ | |||
41 | #include <acpi/acpi_drivers.h> | 41 | #include <acpi/acpi_drivers.h> |
42 | #include <acpi/processor.h> | 42 | #include <acpi/processor.h> |
43 | 43 | ||
44 | #define PREFIX "ACPI: " | ||
45 | |||
44 | #define ACPI_PROCESSOR_CLASS "processor" | 46 | #define ACPI_PROCESSOR_CLASS "processor" |
45 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 47 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
46 | ACPI_MODULE_NAME("processor_throttling"); | 48 | ACPI_MODULE_NAME("processor_throttling"); |
@@ -1216,7 +1218,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) | |||
1216 | } | 1218 | } |
1217 | 1219 | ||
1218 | /* proc interface */ | 1220 | /* proc interface */ |
1219 | 1221 | #ifdef CONFIG_ACPI_PROCFS | |
1220 | static int acpi_processor_throttling_seq_show(struct seq_file *seq, | 1222 | static int acpi_processor_throttling_seq_show(struct seq_file *seq, |
1221 | void *offset) | 1223 | void *offset) |
1222 | { | 1224 | { |
@@ -1324,3 +1326,4 @@ const struct file_operations acpi_processor_throttling_fops = { | |||
1324 | .llseek = seq_lseek, | 1326 | .llseek = seq_lseek, |
1325 | .release = single_release, | 1327 | .release = single_release, |
1326 | }; | 1328 | }; |
1329 | #endif | ||
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 4b214b74ebaa..52b9db8afc20 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -46,6 +46,8 @@ | |||
46 | 46 | ||
47 | #include "sbshc.h" | 47 | #include "sbshc.h" |
48 | 48 | ||
49 | #define PREFIX "ACPI: " | ||
50 | |||
49 | #define ACPI_SBS_CLASS "sbs" | 51 | #define ACPI_SBS_CLASS "sbs" |
50 | #define ACPI_AC_CLASS "ac_adapter" | 52 | #define ACPI_AC_CLASS "ac_adapter" |
51 | #define ACPI_BATTERY_CLASS "battery" | 53 | #define ACPI_BATTERY_CLASS "battery" |
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index 0619734895b2..d9339806df45 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include "sbshc.h" | 16 | #include "sbshc.h" |
17 | 17 | ||
18 | #define PREFIX "ACPI: " | ||
19 | |||
18 | #define ACPI_SMB_HC_CLASS "smbus_host_controller" | 20 | #define ACPI_SMB_HC_CLASS "smbus_host_controller" |
19 | #define ACPI_SMB_HC_DEVICE_NAME "ACPI SMBus HC" | 21 | #define ACPI_SMB_HC_DEVICE_NAME "ACPI SMBus HC" |
20 | 22 | ||
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 318b1ea7a5bf..408ebde18986 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -60,13 +60,13 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, | |||
60 | } | 60 | } |
61 | 61 | ||
62 | if (acpi_dev->flags.compatible_ids) { | 62 | if (acpi_dev->flags.compatible_ids) { |
63 | struct acpi_compatible_id_list *cid_list; | 63 | struct acpica_device_id_list *cid_list; |
64 | int i; | 64 | int i; |
65 | 65 | ||
66 | cid_list = acpi_dev->pnp.cid_list; | 66 | cid_list = acpi_dev->pnp.cid_list; |
67 | for (i = 0; i < cid_list->count; i++) { | 67 | for (i = 0; i < cid_list->count; i++) { |
68 | count = snprintf(&modalias[len], size, "%s:", | 68 | count = snprintf(&modalias[len], size, "%s:", |
69 | cid_list->id[i].value); | 69 | cid_list->ids[i].string); |
70 | if (count < 0 || count >= size) { | 70 | if (count < 0 || count >= size) { |
71 | printk(KERN_ERR PREFIX "%s cid[%i] exceeds event buffer size", | 71 | printk(KERN_ERR PREFIX "%s cid[%i] exceeds event buffer size", |
72 | acpi_dev->pnp.device_name, i); | 72 | acpi_dev->pnp.device_name, i); |
@@ -287,14 +287,14 @@ int acpi_match_device_ids(struct acpi_device *device, | |||
287 | } | 287 | } |
288 | 288 | ||
289 | if (device->flags.compatible_ids) { | 289 | if (device->flags.compatible_ids) { |
290 | struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; | 290 | struct acpica_device_id_list *cid_list = device->pnp.cid_list; |
291 | int i; | 291 | int i; |
292 | 292 | ||
293 | for (id = ids; id->id[0]; id++) { | 293 | for (id = ids; id->id[0]; id++) { |
294 | /* compare multiple _CID entries against driver ids */ | 294 | /* compare multiple _CID entries against driver ids */ |
295 | for (i = 0; i < cid_list->count; i++) { | 295 | for (i = 0; i < cid_list->count; i++) { |
296 | if (!strcmp((char*)id->id, | 296 | if (!strcmp((char*)id->id, |
297 | cid_list->id[i].value)) | 297 | cid_list->ids[i].string)) |
298 | return 0; | 298 | return 0; |
299 | } | 299 | } |
300 | } | 300 | } |
@@ -309,6 +309,10 @@ static void acpi_device_release(struct device *dev) | |||
309 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 309 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
310 | 310 | ||
311 | kfree(acpi_dev->pnp.cid_list); | 311 | kfree(acpi_dev->pnp.cid_list); |
312 | if (acpi_dev->flags.hardware_id) | ||
313 | kfree(acpi_dev->pnp.hardware_id); | ||
314 | if (acpi_dev->flags.unique_id) | ||
315 | kfree(acpi_dev->pnp.unique_id); | ||
312 | kfree(acpi_dev); | 316 | kfree(acpi_dev); |
313 | } | 317 | } |
314 | 318 | ||
@@ -366,7 +370,8 @@ static acpi_status acpi_device_notify_fixed(void *data) | |||
366 | { | 370 | { |
367 | struct acpi_device *device = data; | 371 | struct acpi_device *device = data; |
368 | 372 | ||
369 | acpi_device_notify(device->handle, ACPI_FIXED_HARDWARE_EVENT, device); | 373 | /* Fixed hardware devices have no handles */ |
374 | acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device); | ||
370 | return AE_OK; | 375 | return AE_OK; |
371 | } | 376 | } |
372 | 377 | ||
@@ -426,9 +431,6 @@ static int acpi_device_probe(struct device * dev) | |||
426 | if (acpi_drv->ops.notify) { | 431 | if (acpi_drv->ops.notify) { |
427 | ret = acpi_device_install_notify_handler(acpi_dev); | 432 | ret = acpi_device_install_notify_handler(acpi_dev); |
428 | if (ret) { | 433 | if (ret) { |
429 | if (acpi_drv->ops.stop) | ||
430 | acpi_drv->ops.stop(acpi_dev, | ||
431 | acpi_dev->removal_type); | ||
432 | if (acpi_drv->ops.remove) | 434 | if (acpi_drv->ops.remove) |
433 | acpi_drv->ops.remove(acpi_dev, | 435 | acpi_drv->ops.remove(acpi_dev, |
434 | acpi_dev->removal_type); | 436 | acpi_dev->removal_type); |
@@ -452,8 +454,6 @@ static int acpi_device_remove(struct device * dev) | |||
452 | if (acpi_drv) { | 454 | if (acpi_drv) { |
453 | if (acpi_drv->ops.notify) | 455 | if (acpi_drv->ops.notify) |
454 | acpi_device_remove_notify_handler(acpi_dev); | 456 | acpi_device_remove_notify_handler(acpi_dev); |
455 | if (acpi_drv->ops.stop) | ||
456 | acpi_drv->ops.stop(acpi_dev, acpi_dev->removal_type); | ||
457 | if (acpi_drv->ops.remove) | 457 | if (acpi_drv->ops.remove) |
458 | acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); | 458 | acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); |
459 | } | 459 | } |
@@ -687,7 +687,7 @@ acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) | |||
687 | } | 687 | } |
688 | EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); | 688 | EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); |
689 | 689 | ||
690 | void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context) | 690 | void acpi_bus_data_handler(acpi_handle handle, void *context) |
691 | { | 691 | { |
692 | 692 | ||
693 | /* TBD */ | 693 | /* TBD */ |
@@ -1000,33 +1000,89 @@ static int acpi_dock_match(struct acpi_device *device) | |||
1000 | return acpi_get_handle(device->handle, "_DCK", &tmp); | 1000 | return acpi_get_handle(device->handle, "_DCK", &tmp); |
1001 | } | 1001 | } |
1002 | 1002 | ||
1003 | static struct acpica_device_id_list* | ||
1004 | acpi_add_cid( | ||
1005 | struct acpi_device_info *info, | ||
1006 | struct acpica_device_id *new_cid) | ||
1007 | { | ||
1008 | struct acpica_device_id_list *cid; | ||
1009 | char *next_id_string; | ||
1010 | acpi_size cid_length; | ||
1011 | acpi_size new_cid_length; | ||
1012 | u32 i; | ||
1013 | |||
1014 | |||
1015 | /* Allocate new CID list with room for the new CID */ | ||
1016 | |||
1017 | if (!new_cid) | ||
1018 | new_cid_length = info->compatible_id_list.list_size; | ||
1019 | else if (info->compatible_id_list.list_size) | ||
1020 | new_cid_length = info->compatible_id_list.list_size + | ||
1021 | new_cid->length + sizeof(struct acpica_device_id); | ||
1022 | else | ||
1023 | new_cid_length = sizeof(struct acpica_device_id_list) + new_cid->length; | ||
1024 | |||
1025 | cid = ACPI_ALLOCATE_ZEROED(new_cid_length); | ||
1026 | if (!cid) { | ||
1027 | return NULL; | ||
1028 | } | ||
1029 | |||
1030 | cid->list_size = new_cid_length; | ||
1031 | cid->count = info->compatible_id_list.count; | ||
1032 | if (new_cid) | ||
1033 | cid->count++; | ||
1034 | next_id_string = (char *) cid->ids + (cid->count * sizeof(struct acpica_device_id)); | ||
1035 | |||
1036 | /* Copy all existing CIDs */ | ||
1037 | |||
1038 | for (i = 0; i < info->compatible_id_list.count; i++) { | ||
1039 | cid_length = info->compatible_id_list.ids[i].length; | ||
1040 | cid->ids[i].string = next_id_string; | ||
1041 | cid->ids[i].length = cid_length; | ||
1042 | |||
1043 | ACPI_MEMCPY(next_id_string, info->compatible_id_list.ids[i].string, | ||
1044 | cid_length); | ||
1045 | |||
1046 | next_id_string += cid_length; | ||
1047 | } | ||
1048 | |||
1049 | /* Append the new CID */ | ||
1050 | |||
1051 | if (new_cid) { | ||
1052 | cid->ids[i].string = next_id_string; | ||
1053 | cid->ids[i].length = new_cid->length; | ||
1054 | |||
1055 | ACPI_MEMCPY(next_id_string, new_cid->string, new_cid->length); | ||
1056 | } | ||
1057 | |||
1058 | return cid; | ||
1059 | } | ||
1060 | |||
1003 | static void acpi_device_set_id(struct acpi_device *device, | 1061 | static void acpi_device_set_id(struct acpi_device *device, |
1004 | struct acpi_device *parent, acpi_handle handle, | 1062 | struct acpi_device *parent, acpi_handle handle, |
1005 | int type) | 1063 | int type) |
1006 | { | 1064 | { |
1007 | struct acpi_device_info *info; | 1065 | struct acpi_device_info *info = NULL; |
1008 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
1009 | char *hid = NULL; | 1066 | char *hid = NULL; |
1010 | char *uid = NULL; | 1067 | char *uid = NULL; |
1011 | struct acpi_compatible_id_list *cid_list = NULL; | 1068 | struct acpica_device_id_list *cid_list = NULL; |
1012 | const char *cid_add = NULL; | 1069 | char *cid_add = NULL; |
1013 | acpi_status status; | 1070 | acpi_status status; |
1014 | 1071 | ||
1015 | switch (type) { | 1072 | switch (type) { |
1016 | case ACPI_BUS_TYPE_DEVICE: | 1073 | case ACPI_BUS_TYPE_DEVICE: |
1017 | status = acpi_get_object_info(handle, &buffer); | 1074 | status = acpi_get_object_info(handle, &info); |
1018 | if (ACPI_FAILURE(status)) { | 1075 | if (ACPI_FAILURE(status)) { |
1019 | printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__); | 1076 | printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__); |
1020 | return; | 1077 | return; |
1021 | } | 1078 | } |
1022 | 1079 | ||
1023 | info = buffer.pointer; | ||
1024 | if (info->valid & ACPI_VALID_HID) | 1080 | if (info->valid & ACPI_VALID_HID) |
1025 | hid = info->hardware_id.value; | 1081 | hid = info->hardware_id.string; |
1026 | if (info->valid & ACPI_VALID_UID) | 1082 | if (info->valid & ACPI_VALID_UID) |
1027 | uid = info->unique_id.value; | 1083 | uid = info->unique_id.string; |
1028 | if (info->valid & ACPI_VALID_CID) | 1084 | if (info->valid & ACPI_VALID_CID) |
1029 | cid_list = &info->compatibility_id; | 1085 | cid_list = &info->compatible_id_list; |
1030 | if (info->valid & ACPI_VALID_ADR) { | 1086 | if (info->valid & ACPI_VALID_ADR) { |
1031 | device->pnp.bus_address = info->address; | 1087 | device->pnp.bus_address = info->address; |
1032 | device->flags.bus_address = 1; | 1088 | device->flags.bus_address = 1; |
@@ -1077,55 +1133,46 @@ static void acpi_device_set_id(struct acpi_device *device, | |||
1077 | } | 1133 | } |
1078 | 1134 | ||
1079 | if (hid) { | 1135 | if (hid) { |
1080 | strcpy(device->pnp.hardware_id, hid); | 1136 | device->pnp.hardware_id = ACPI_ALLOCATE_ZEROED(strlen (hid) + 1); |
1081 | device->flags.hardware_id = 1; | 1137 | if (device->pnp.hardware_id) { |
1138 | strcpy(device->pnp.hardware_id, hid); | ||
1139 | device->flags.hardware_id = 1; | ||
1140 | } | ||
1082 | } | 1141 | } |
1142 | if (!device->flags.hardware_id) | ||
1143 | device->pnp.hardware_id = ""; | ||
1144 | |||
1083 | if (uid) { | 1145 | if (uid) { |
1084 | strcpy(device->pnp.unique_id, uid); | 1146 | device->pnp.unique_id = ACPI_ALLOCATE_ZEROED(strlen (uid) + 1); |
1085 | device->flags.unique_id = 1; | 1147 | if (device->pnp.unique_id) { |
1148 | strcpy(device->pnp.unique_id, uid); | ||
1149 | device->flags.unique_id = 1; | ||
1150 | } | ||
1086 | } | 1151 | } |
1152 | if (!device->flags.unique_id) | ||
1153 | device->pnp.unique_id = ""; | ||
1154 | |||
1087 | if (cid_list || cid_add) { | 1155 | if (cid_list || cid_add) { |
1088 | struct acpi_compatible_id_list *list; | 1156 | struct acpica_device_id_list *list; |
1089 | int size = 0; | 1157 | |
1090 | int count = 0; | 1158 | if (cid_add) { |
1091 | 1159 | struct acpica_device_id cid; | |
1092 | if (cid_list) { | 1160 | cid.length = strlen (cid_add) + 1; |
1093 | size = cid_list->size; | 1161 | cid.string = cid_add; |
1094 | } else if (cid_add) { | 1162 | |
1095 | size = sizeof(struct acpi_compatible_id_list); | 1163 | list = acpi_add_cid(info, &cid); |
1096 | cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size); | 1164 | } else { |
1097 | if (!cid_list) { | 1165 | list = acpi_add_cid(info, NULL); |
1098 | printk(KERN_ERR "Memory allocation error\n"); | ||
1099 | kfree(buffer.pointer); | ||
1100 | return; | ||
1101 | } else { | ||
1102 | cid_list->count = 0; | ||
1103 | cid_list->size = size; | ||
1104 | } | ||
1105 | } | 1166 | } |
1106 | if (cid_add) | ||
1107 | size += sizeof(struct acpi_compatible_id); | ||
1108 | list = kmalloc(size, GFP_KERNEL); | ||
1109 | 1167 | ||
1110 | if (list) { | 1168 | if (list) { |
1111 | if (cid_list) { | ||
1112 | memcpy(list, cid_list, cid_list->size); | ||
1113 | count = cid_list->count; | ||
1114 | } | ||
1115 | if (cid_add) { | ||
1116 | strncpy(list->id[count].value, cid_add, | ||
1117 | ACPI_MAX_CID_LENGTH); | ||
1118 | count++; | ||
1119 | device->flags.compatible_ids = 1; | ||
1120 | } | ||
1121 | list->size = size; | ||
1122 | list->count = count; | ||
1123 | device->pnp.cid_list = list; | 1169 | device->pnp.cid_list = list; |
1124 | } else | 1170 | if (cid_add) |
1125 | printk(KERN_ERR PREFIX "Memory allocation error\n"); | 1171 | device->flags.compatible_ids = 1; |
1172 | } | ||
1126 | } | 1173 | } |
1127 | 1174 | ||
1128 | kfree(buffer.pointer); | 1175 | kfree(info); |
1129 | } | 1176 | } |
1130 | 1177 | ||
1131 | static int acpi_device_set_context(struct acpi_device *device, int type) | 1178 | static int acpi_device_set_context(struct acpi_device *device, int type) |
@@ -1265,16 +1312,6 @@ acpi_add_single_object(struct acpi_device **child, | |||
1265 | acpi_device_set_id(device, parent, handle, type); | 1312 | acpi_device_set_id(device, parent, handle, type); |
1266 | 1313 | ||
1267 | /* | 1314 | /* |
1268 | * The ACPI device is attached to acpi handle before getting | ||
1269 | * the power/wakeup/peformance flags. Otherwise OS can't get | ||
1270 | * the corresponding ACPI device by the acpi handle in the course | ||
1271 | * of getting the power/wakeup/performance flags. | ||
1272 | */ | ||
1273 | result = acpi_device_set_context(device, type); | ||
1274 | if (result) | ||
1275 | goto end; | ||
1276 | |||
1277 | /* | ||
1278 | * Power Management | 1315 | * Power Management |
1279 | * ---------------- | 1316 | * ---------------- |
1280 | */ | 1317 | */ |
@@ -1304,6 +1341,8 @@ acpi_add_single_object(struct acpi_device **child, | |||
1304 | goto end; | 1341 | goto end; |
1305 | } | 1342 | } |
1306 | 1343 | ||
1344 | if ((result = acpi_device_set_context(device, type))) | ||
1345 | goto end; | ||
1307 | 1346 | ||
1308 | result = acpi_device_register(device, parent); | 1347 | result = acpi_device_register(device, parent); |
1309 | 1348 | ||
@@ -1318,10 +1357,8 @@ acpi_add_single_object(struct acpi_device **child, | |||
1318 | end: | 1357 | end: |
1319 | if (!result) | 1358 | if (!result) |
1320 | *child = device; | 1359 | *child = device; |
1321 | else { | 1360 | else |
1322 | kfree(device->pnp.cid_list); | 1361 | acpi_device_release(&device->dev); |
1323 | kfree(device); | ||
1324 | } | ||
1325 | 1362 | ||
1326 | return result; | 1363 | return result; |
1327 | } | 1364 | } |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index feece693d773..a90afcc723ab 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -405,6 +405,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
405 | }, | 405 | }, |
406 | }, | 406 | }, |
407 | { | 407 | { |
408 | .callback = init_set_sci_en_on_resume, | ||
409 | .ident = "Hewlett-Packard HP Pavilion dv3 Notebook PC", | ||
410 | .matches = { | ||
411 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
412 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv3 Notebook PC"), | ||
413 | }, | ||
414 | }, | ||
415 | { | ||
408 | .callback = init_old_suspend_ordering, | 416 | .callback = init_old_suspend_ordering, |
409 | .ident = "Panasonic CF51-2L", | 417 | .ident = "Panasonic CF51-2L", |
410 | .matches = { | 418 | .matches = { |
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 9c61ab2177cf..d11282975f35 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c | |||
@@ -31,6 +31,8 @@ | |||
31 | 31 | ||
32 | #include <acpi/acpi_drivers.h> | 32 | #include <acpi/acpi_drivers.h> |
33 | 33 | ||
34 | #define PREFIX "ACPI: " | ||
35 | |||
34 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | 36 | #define _COMPONENT ACPI_SYSTEM_COMPONENT |
35 | ACPI_MODULE_NAME("system"); | 37 | ACPI_MODULE_NAME("system"); |
36 | 38 | ||
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 646d39c031ca..f336bca7c450 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c | |||
@@ -213,6 +213,9 @@ acpi_table_parse_entries(char *id, | |||
213 | unsigned long table_end; | 213 | unsigned long table_end; |
214 | acpi_size tbl_size; | 214 | acpi_size tbl_size; |
215 | 215 | ||
216 | if (acpi_disabled) | ||
217 | return -ENODEV; | ||
218 | |||
216 | if (!handler) | 219 | if (!handler) |
217 | return -EINVAL; | 220 | return -EINVAL; |
218 | 221 | ||
@@ -277,6 +280,9 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler) | |||
277 | struct acpi_table_header *table = NULL; | 280 | struct acpi_table_header *table = NULL; |
278 | acpi_size tbl_size; | 281 | acpi_size tbl_size; |
279 | 282 | ||
283 | if (acpi_disabled) | ||
284 | return -ENODEV; | ||
285 | |||
280 | if (!handler) | 286 | if (!handler) |
281 | return -EINVAL; | 287 | return -EINVAL; |
282 | 288 | ||
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 564ea1424288..65f67815902a 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -47,6 +47,8 @@ | |||
47 | #include <acpi/acpi_bus.h> | 47 | #include <acpi/acpi_bus.h> |
48 | #include <acpi/acpi_drivers.h> | 48 | #include <acpi/acpi_drivers.h> |
49 | 49 | ||
50 | #define PREFIX "ACPI: " | ||
51 | |||
50 | #define ACPI_THERMAL_CLASS "thermal_zone" | 52 | #define ACPI_THERMAL_CLASS "thermal_zone" |
51 | #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" | 53 | #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" |
52 | #define ACPI_THERMAL_FILE_STATE "state" | 54 | #define ACPI_THERMAL_FILE_STATE "state" |
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index f844941089bb..811fec10462b 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <acpi/acpi_bus.h> | 30 | #include <acpi/acpi_bus.h> |
31 | #include <acpi/acpi_drivers.h> | 31 | #include <acpi/acpi_drivers.h> |
32 | 32 | ||
33 | #include "internal.h" | ||
34 | |||
33 | #define _COMPONENT ACPI_BUS_COMPONENT | 35 | #define _COMPONENT ACPI_BUS_COMPONENT |
34 | ACPI_MODULE_NAME("utils"); | 36 | ACPI_MODULE_NAME("utils"); |
35 | 37 | ||
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 60ea984c84a0..94b1a4c5abab 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -40,10 +40,12 @@ | |||
40 | #include <linux/pci.h> | 40 | #include <linux/pci.h> |
41 | #include <linux/pci_ids.h> | 41 | #include <linux/pci_ids.h> |
42 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
43 | 43 | #include <linux/dmi.h> | |
44 | #include <acpi/acpi_bus.h> | 44 | #include <acpi/acpi_bus.h> |
45 | #include <acpi/acpi_drivers.h> | 45 | #include <acpi/acpi_drivers.h> |
46 | 46 | ||
47 | #define PREFIX "ACPI: " | ||
48 | |||
47 | #define ACPI_VIDEO_CLASS "video" | 49 | #define ACPI_VIDEO_CLASS "video" |
48 | #define ACPI_VIDEO_BUS_NAME "Video Bus" | 50 | #define ACPI_VIDEO_BUS_NAME "Video Bus" |
49 | #define ACPI_VIDEO_DEVICE_NAME "Video Device" | 51 | #define ACPI_VIDEO_DEVICE_NAME "Video Device" |
@@ -198,7 +200,7 @@ struct acpi_video_device { | |||
198 | struct acpi_device *dev; | 200 | struct acpi_device *dev; |
199 | struct acpi_video_device_brightness *brightness; | 201 | struct acpi_video_device_brightness *brightness; |
200 | struct backlight_device *backlight; | 202 | struct backlight_device *backlight; |
201 | struct thermal_cooling_device *cdev; | 203 | struct thermal_cooling_device *cooling_dev; |
202 | struct output_device *output_dev; | 204 | struct output_device *output_dev; |
203 | }; | 205 | }; |
204 | 206 | ||
@@ -387,20 +389,20 @@ static struct output_properties acpi_output_properties = { | |||
387 | 389 | ||
388 | 390 | ||
389 | /* thermal cooling device callbacks */ | 391 | /* thermal cooling device callbacks */ |
390 | static int video_get_max_state(struct thermal_cooling_device *cdev, unsigned | 392 | static int video_get_max_state(struct thermal_cooling_device *cooling_dev, unsigned |
391 | long *state) | 393 | long *state) |
392 | { | 394 | { |
393 | struct acpi_device *device = cdev->devdata; | 395 | struct acpi_device *device = cooling_dev->devdata; |
394 | struct acpi_video_device *video = acpi_driver_data(device); | 396 | struct acpi_video_device *video = acpi_driver_data(device); |
395 | 397 | ||
396 | *state = video->brightness->count - 3; | 398 | *state = video->brightness->count - 3; |
397 | return 0; | 399 | return 0; |
398 | } | 400 | } |
399 | 401 | ||
400 | static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned | 402 | static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, unsigned |
401 | long *state) | 403 | long *state) |
402 | { | 404 | { |
403 | struct acpi_device *device = cdev->devdata; | 405 | struct acpi_device *device = cooling_dev->devdata; |
404 | struct acpi_video_device *video = acpi_driver_data(device); | 406 | struct acpi_video_device *video = acpi_driver_data(device); |
405 | unsigned long long level; | 407 | unsigned long long level; |
406 | int offset; | 408 | int offset; |
@@ -417,9 +419,9 @@ static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned | |||
417 | } | 419 | } |
418 | 420 | ||
419 | static int | 421 | static int |
420 | video_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) | 422 | video_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long state) |
421 | { | 423 | { |
422 | struct acpi_device *device = cdev->devdata; | 424 | struct acpi_device *device = cooling_dev->devdata; |
423 | struct acpi_video_device *video = acpi_driver_data(device); | 425 | struct acpi_video_device *video = acpi_driver_data(device); |
424 | int level; | 426 | int level; |
425 | 427 | ||
@@ -603,6 +605,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, | |||
603 | unsigned long long *level) | 605 | unsigned long long *level) |
604 | { | 606 | { |
605 | acpi_status status = AE_OK; | 607 | acpi_status status = AE_OK; |
608 | int i; | ||
606 | 609 | ||
607 | if (device->cap._BQC || device->cap._BCQ) { | 610 | if (device->cap._BQC || device->cap._BCQ) { |
608 | char *buf = device->cap._BQC ? "_BQC" : "_BCQ"; | 611 | char *buf = device->cap._BQC ? "_BQC" : "_BCQ"; |
@@ -618,8 +621,15 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, | |||
618 | 621 | ||
619 | } | 622 | } |
620 | *level += bqc_offset_aml_bug_workaround; | 623 | *level += bqc_offset_aml_bug_workaround; |
621 | device->brightness->curr = *level; | 624 | for (i = 2; i < device->brightness->count; i++) |
622 | return 0; | 625 | if (device->brightness->levels[i] == *level) { |
626 | device->brightness->curr = *level; | ||
627 | return 0; | ||
628 | } | ||
629 | /* BQC returned an invalid level. Stop using it. */ | ||
630 | ACPI_WARNING((AE_INFO, "%s returned an invalid level", | ||
631 | buf)); | ||
632 | device->cap._BQC = device->cap._BCQ = 0; | ||
623 | } else { | 633 | } else { |
624 | /* Fixme: | 634 | /* Fixme: |
625 | * should we return an error or ignore this failure? | 635 | * should we return an error or ignore this failure? |
@@ -870,7 +880,7 @@ acpi_video_init_brightness(struct acpi_video_device *device) | |||
870 | br->flags._BCM_use_index = br->flags._BCL_use_index; | 880 | br->flags._BCM_use_index = br->flags._BCL_use_index; |
871 | 881 | ||
872 | /* _BQC uses INDEX while _BCL uses VALUE in some laptops */ | 882 | /* _BQC uses INDEX while _BCL uses VALUE in some laptops */ |
873 | br->curr = level_old = max_level; | 883 | br->curr = level = max_level; |
874 | 884 | ||
875 | if (!device->cap._BQC) | 885 | if (!device->cap._BQC) |
876 | goto set_level; | 886 | goto set_level; |
@@ -892,15 +902,25 @@ acpi_video_init_brightness(struct acpi_video_device *device) | |||
892 | 902 | ||
893 | br->flags._BQC_use_index = (level == max_level ? 0 : 1); | 903 | br->flags._BQC_use_index = (level == max_level ? 0 : 1); |
894 | 904 | ||
895 | if (!br->flags._BQC_use_index) | 905 | if (!br->flags._BQC_use_index) { |
906 | /* | ||
907 | * Set the backlight to the initial state. | ||
908 | * On some buggy laptops, _BQC returns an uninitialized value | ||
909 | * when invoked for the first time, i.e. level_old is invalid. | ||
910 | * set the backlight to max_level in this case | ||
911 | */ | ||
912 | for (i = 2; i < br->count; i++) | ||
913 | if (level_old == br->levels[i]) | ||
914 | level = level_old; | ||
896 | goto set_level; | 915 | goto set_level; |
916 | } | ||
897 | 917 | ||
898 | if (br->flags._BCL_reversed) | 918 | if (br->flags._BCL_reversed) |
899 | level_old = (br->count - 1) - level_old; | 919 | level_old = (br->count - 1) - level_old; |
900 | level_old = br->levels[level_old]; | 920 | level = br->levels[level_old]; |
901 | 921 | ||
902 | set_level: | 922 | set_level: |
903 | result = acpi_video_device_lcd_set_level(device, level_old); | 923 | result = acpi_video_device_lcd_set_level(device, level); |
904 | if (result) | 924 | if (result) |
905 | goto out_free_levels; | 925 | goto out_free_levels; |
906 | 926 | ||
@@ -934,9 +954,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
934 | { | 954 | { |
935 | acpi_handle h_dummy1; | 955 | acpi_handle h_dummy1; |
936 | 956 | ||
937 | |||
938 | memset(&device->cap, 0, sizeof(device->cap)); | ||
939 | |||
940 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) { | 957 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) { |
941 | device->cap._ADR = 1; | 958 | device->cap._ADR = 1; |
942 | } | 959 | } |
@@ -990,19 +1007,29 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
990 | if (result) | 1007 | if (result) |
991 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | 1008 | printk(KERN_ERR PREFIX "Create sysfs link\n"); |
992 | 1009 | ||
993 | device->cdev = thermal_cooling_device_register("LCD", | 1010 | device->cooling_dev = thermal_cooling_device_register("LCD", |
994 | device->dev, &video_cooling_ops); | 1011 | device->dev, &video_cooling_ops); |
995 | if (IS_ERR(device->cdev)) | 1012 | if (IS_ERR(device->cooling_dev)) { |
1013 | /* | ||
1014 | * Set cooling_dev to NULL so we don't crash trying to | ||
1015 | * free it. | ||
1016 | * Also, why the hell we are returning early and | ||
1017 | * not attempt to register video output if cooling | ||
1018 | * device registration failed? | ||
1019 | * -- dtor | ||
1020 | */ | ||
1021 | device->cooling_dev = NULL; | ||
996 | return; | 1022 | return; |
1023 | } | ||
997 | 1024 | ||
998 | dev_info(&device->dev->dev, "registered as cooling_device%d\n", | 1025 | dev_info(&device->dev->dev, "registered as cooling_device%d\n", |
999 | device->cdev->id); | 1026 | device->cooling_dev->id); |
1000 | result = sysfs_create_link(&device->dev->dev.kobj, | 1027 | result = sysfs_create_link(&device->dev->dev.kobj, |
1001 | &device->cdev->device.kobj, | 1028 | &device->cooling_dev->device.kobj, |
1002 | "thermal_cooling"); | 1029 | "thermal_cooling"); |
1003 | if (result) | 1030 | if (result) |
1004 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | 1031 | printk(KERN_ERR PREFIX "Create sysfs link\n"); |
1005 | result = sysfs_create_link(&device->cdev->device.kobj, | 1032 | result = sysfs_create_link(&device->cooling_dev->device.kobj, |
1006 | &device->dev->dev.kobj, "device"); | 1033 | &device->dev->dev.kobj, "device"); |
1007 | if (result) | 1034 | if (result) |
1008 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | 1035 | printk(KERN_ERR PREFIX "Create sysfs link\n"); |
@@ -1039,7 +1066,6 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video) | |||
1039 | { | 1066 | { |
1040 | acpi_handle h_dummy1; | 1067 | acpi_handle h_dummy1; |
1041 | 1068 | ||
1042 | memset(&video->cap, 0, sizeof(video->cap)); | ||
1043 | if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) { | 1069 | if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) { |
1044 | video->cap._DOS = 1; | 1070 | video->cap._DOS = 1; |
1045 | } | 1071 | } |
@@ -2009,13 +2035,13 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | |||
2009 | backlight_device_unregister(device->backlight); | 2035 | backlight_device_unregister(device->backlight); |
2010 | device->backlight = NULL; | 2036 | device->backlight = NULL; |
2011 | } | 2037 | } |
2012 | if (device->cdev) { | 2038 | if (device->cooling_dev) { |
2013 | sysfs_remove_link(&device->dev->dev.kobj, | 2039 | sysfs_remove_link(&device->dev->dev.kobj, |
2014 | "thermal_cooling"); | 2040 | "thermal_cooling"); |
2015 | sysfs_remove_link(&device->cdev->device.kobj, | 2041 | sysfs_remove_link(&device->cooling_dev->device.kobj, |
2016 | "device"); | 2042 | "device"); |
2017 | thermal_cooling_device_unregister(device->cdev); | 2043 | thermal_cooling_device_unregister(device->cooling_dev); |
2018 | device->cdev = NULL; | 2044 | device->cooling_dev = NULL; |
2019 | } | 2045 | } |
2020 | video_output_unregister(device->output_dev); | 2046 | video_output_unregister(device->output_dev); |
2021 | 2047 | ||
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 7cd2b63435ea..7032f25da9b5 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -38,6 +38,8 @@ | |||
38 | #include <linux/dmi.h> | 38 | #include <linux/dmi.h> |
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | 40 | ||
41 | #define PREFIX "ACPI: " | ||
42 | |||
41 | ACPI_MODULE_NAME("video"); | 43 | ACPI_MODULE_NAME("video"); |
42 | #define _COMPONENT ACPI_VIDEO_COMPONENT | 44 | #define _COMPONENT ACPI_VIDEO_COMPONENT |
43 | 45 | ||
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index 501e293e5ad0..9047b2714653 100644 --- a/drivers/char/agp/hp-agp.c +++ b/drivers/char/agp/hp-agp.c | |||
@@ -476,7 +476,6 @@ zx1_gart_probe (acpi_handle obj, u32 depth, void *context, void **ret) | |||
476 | { | 476 | { |
477 | acpi_handle handle, parent; | 477 | acpi_handle handle, parent; |
478 | acpi_status status; | 478 | acpi_status status; |
479 | struct acpi_buffer buffer; | ||
480 | struct acpi_device_info *info; | 479 | struct acpi_device_info *info; |
481 | u64 lba_hpa, sba_hpa, length; | 480 | u64 lba_hpa, sba_hpa, length; |
482 | int match; | 481 | int match; |
@@ -488,13 +487,11 @@ zx1_gart_probe (acpi_handle obj, u32 depth, void *context, void **ret) | |||
488 | /* Look for an enclosing IOC scope and find its CSR space */ | 487 | /* Look for an enclosing IOC scope and find its CSR space */ |
489 | handle = obj; | 488 | handle = obj; |
490 | do { | 489 | do { |
491 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | 490 | status = acpi_get_object_info(handle, &info); |
492 | status = acpi_get_object_info(handle, &buffer); | ||
493 | if (ACPI_SUCCESS(status)) { | 491 | if (ACPI_SUCCESS(status)) { |
494 | /* TBD check _CID also */ | 492 | /* TBD check _CID also */ |
495 | info = buffer.pointer; | 493 | info->hardware_id.string[sizeof(info->hardware_id.length)-1] = '\0'; |
496 | info->hardware_id.value[sizeof(info->hardware_id)-1] = '\0'; | 494 | match = (strcmp(info->hardware_id.string, "HWP0001") == 0); |
497 | match = (strcmp(info->hardware_id.value, "HWP0001") == 0); | ||
498 | kfree(info); | 495 | kfree(info); |
499 | if (match) { | 496 | if (match) { |
500 | status = hp_acpi_csr_space(handle, &sba_hpa, &length); | 497 | status = hp_acpi_csr_space(handle, &sba_hpa, &length); |
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index c509c9916464..c0cf45a11b93 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c | |||
@@ -114,8 +114,6 @@ static int ide_get_dev_handle(struct device *dev, acpi_handle *handle, | |||
114 | unsigned int bus, devnum, func; | 114 | unsigned int bus, devnum, func; |
115 | acpi_integer addr; | 115 | acpi_integer addr; |
116 | acpi_handle dev_handle; | 116 | acpi_handle dev_handle; |
117 | struct acpi_buffer buffer = {.length = ACPI_ALLOCATE_BUFFER, | ||
118 | .pointer = NULL}; | ||
119 | acpi_status status; | 117 | acpi_status status; |
120 | struct acpi_device_info *dinfo = NULL; | 118 | struct acpi_device_info *dinfo = NULL; |
121 | int ret = -ENODEV; | 119 | int ret = -ENODEV; |
@@ -134,12 +132,11 @@ static int ide_get_dev_handle(struct device *dev, acpi_handle *handle, | |||
134 | goto err; | 132 | goto err; |
135 | } | 133 | } |
136 | 134 | ||
137 | status = acpi_get_object_info(dev_handle, &buffer); | 135 | status = acpi_get_object_info(dev_handle, &dinfo); |
138 | if (ACPI_FAILURE(status)) { | 136 | if (ACPI_FAILURE(status)) { |
139 | DEBPRINT("get_object_info for device failed\n"); | 137 | DEBPRINT("get_object_info for device failed\n"); |
140 | goto err; | 138 | goto err; |
141 | } | 139 | } |
142 | dinfo = buffer.pointer; | ||
143 | if (dinfo && (dinfo->valid & ACPI_VALID_ADR) && | 140 | if (dinfo && (dinfo->valid & ACPI_VALID_ADR) && |
144 | dinfo->address == addr) { | 141 | dinfo->address == addr) { |
145 | *pcidevfn = addr; | 142 | *pcidevfn = addr; |
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index ab99783dccec..5f6b915d0d82 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
@@ -34,9 +34,9 @@ | |||
34 | #include <linux/irq.h> | 34 | #include <linux/irq.h> |
35 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
36 | #include <linux/tboot.h> | 36 | #include <linux/tboot.h> |
37 | #include <linux/dmi.h> | ||
37 | 38 | ||
38 | #undef PREFIX | 39 | #define PREFIX "DMAR: " |
39 | #define PREFIX "DMAR:" | ||
40 | 40 | ||
41 | /* No locks are needed as DMA remapping hardware unit | 41 | /* No locks are needed as DMA remapping hardware unit |
42 | * list is constructed at boot time and hotplug of | 42 | * list is constructed at boot time and hotplug of |
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 5befa7e379b7..a9d926b7d805 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c | |||
@@ -398,23 +398,21 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle, | |||
398 | acpi_handle *phandle = (acpi_handle *)context; | 398 | acpi_handle *phandle = (acpi_handle *)context; |
399 | acpi_status status; | 399 | acpi_status status; |
400 | struct acpi_device_info *info; | 400 | struct acpi_device_info *info; |
401 | struct acpi_buffer info_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
402 | int retval = 0; | 401 | int retval = 0; |
403 | 402 | ||
404 | status = acpi_get_object_info(handle, &info_buffer); | 403 | status = acpi_get_object_info(handle, &info); |
405 | if (ACPI_FAILURE(status)) { | 404 | if (ACPI_FAILURE(status)) { |
406 | err("%s: Failed to get device information status=0x%x\n", | 405 | err("%s: Failed to get device information status=0x%x\n", |
407 | __func__, status); | 406 | __func__, status); |
408 | return retval; | 407 | return retval; |
409 | } | 408 | } |
410 | info = info_buffer.pointer; | 409 | info->hardware_id.string[sizeof(info->hardware_id.length) - 1] = '\0'; |
411 | info->hardware_id.value[sizeof(info->hardware_id.value) - 1] = '\0'; | ||
412 | 410 | ||
413 | if (info->current_status && (info->valid & ACPI_VALID_HID) && | 411 | if (info->current_status && (info->valid & ACPI_VALID_HID) && |
414 | (!strcmp(info->hardware_id.value, IBM_HARDWARE_ID1) || | 412 | (!strcmp(info->hardware_id.string, IBM_HARDWARE_ID1) || |
415 | !strcmp(info->hardware_id.value, IBM_HARDWARE_ID2))) { | 413 | !strcmp(info->hardware_id.string, IBM_HARDWARE_ID2))) { |
416 | dbg("found hardware: %s, handle: %p\n", | 414 | dbg("found hardware: %s, handle: %p\n", |
417 | info->hardware_id.value, handle); | 415 | info->hardware_id.string, handle); |
418 | *phandle = handle; | 416 | *phandle = handle; |
419 | /* returning non-zero causes the search to stop | 417 | /* returning non-zero causes the search to stop |
420 | * and returns this value to the caller of | 418 | * and returns this value to the caller of |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 77c6097ced80..55ca39dea42e 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -99,6 +99,7 @@ config FUJITSU_LAPTOP | |||
99 | depends on ACPI | 99 | depends on ACPI |
100 | depends on INPUT | 100 | depends on INPUT |
101 | depends on BACKLIGHT_CLASS_DEVICE | 101 | depends on BACKLIGHT_CLASS_DEVICE |
102 | depends on LEDS_CLASS || LEDS_CLASS=n | ||
102 | ---help--- | 103 | ---help--- |
103 | This is a driver for laptops built by Fujitsu: | 104 | This is a driver for laptops built by Fujitsu: |
104 | 105 | ||
@@ -396,6 +397,15 @@ config ACPI_ASUS | |||
396 | NOTE: This driver is deprecated and will probably be removed soon, | 397 | NOTE: This driver is deprecated and will probably be removed soon, |
397 | use asus-laptop instead. | 398 | use asus-laptop instead. |
398 | 399 | ||
400 | config TOPSTAR_LAPTOP | ||
401 | tristate "Topstar Laptop Extras" | ||
402 | depends on ACPI | ||
403 | depends on INPUT | ||
404 | ---help--- | ||
405 | This driver adds support for hotkeys found on Topstar laptops. | ||
406 | |||
407 | If you have a Topstar laptop, say Y or M here. | ||
408 | |||
399 | config ACPI_TOSHIBA | 409 | config ACPI_TOSHIBA |
400 | tristate "Toshiba Laptop Extras" | 410 | tristate "Toshiba Laptop Extras" |
401 | depends on ACPI | 411 | depends on ACPI |
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 641b8bfa5538..d1c16210a512 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile | |||
@@ -19,4 +19,5 @@ obj-$(CONFIG_PANASONIC_LAPTOP) += panasonic-laptop.o | |||
19 | obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o | 19 | obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o |
20 | obj-$(CONFIG_ACPI_WMI) += wmi.o | 20 | obj-$(CONFIG_ACPI_WMI) += wmi.o |
21 | obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o | 21 | obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o |
22 | obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o | ||
22 | obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o | 23 | obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o |
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index bdfee177eefb..0a8f735f6c4a 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c | |||
@@ -52,7 +52,7 @@ | |||
52 | */ | 52 | */ |
53 | #undef START_IN_KERNEL_MODE | 53 | #undef START_IN_KERNEL_MODE |
54 | 54 | ||
55 | #define DRV_VER "0.5.13" | 55 | #define DRV_VER "0.5.17" |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * According to the Atom N270 datasheet, | 58 | * According to the Atom N270 datasheet, |
@@ -90,6 +90,7 @@ static unsigned int fanoff = 58; | |||
90 | static unsigned int verbose; | 90 | static unsigned int verbose; |
91 | static unsigned int fanstate = ACERHDF_FAN_AUTO; | 91 | static unsigned int fanstate = ACERHDF_FAN_AUTO; |
92 | static char force_bios[16]; | 92 | static char force_bios[16]; |
93 | static char force_product[16]; | ||
93 | static unsigned int prev_interval; | 94 | static unsigned int prev_interval; |
94 | struct thermal_zone_device *thz_dev; | 95 | struct thermal_zone_device *thz_dev; |
95 | struct thermal_cooling_device *cl_dev; | 96 | struct thermal_cooling_device *cl_dev; |
@@ -107,34 +108,62 @@ module_param(verbose, uint, 0600); | |||
107 | MODULE_PARM_DESC(verbose, "Enable verbose dmesg output"); | 108 | MODULE_PARM_DESC(verbose, "Enable verbose dmesg output"); |
108 | module_param_string(force_bios, force_bios, 16, 0); | 109 | module_param_string(force_bios, force_bios, 16, 0); |
109 | MODULE_PARM_DESC(force_bios, "Force BIOS version and omit BIOS check"); | 110 | MODULE_PARM_DESC(force_bios, "Force BIOS version and omit BIOS check"); |
111 | module_param_string(force_product, force_product, 16, 0); | ||
112 | MODULE_PARM_DESC(force_product, "Force BIOS product and omit BIOS check"); | ||
113 | |||
114 | /* | ||
115 | * cmd_off: to switch the fan completely off / to check if the fan is off | ||
116 | * cmd_auto: to set the BIOS in control of the fan. The BIOS regulates then | ||
117 | * the fan speed depending on the temperature | ||
118 | */ | ||
119 | struct fancmd { | ||
120 | u8 cmd_off; | ||
121 | u8 cmd_auto; | ||
122 | }; | ||
110 | 123 | ||
111 | /* BIOS settings */ | 124 | /* BIOS settings */ |
112 | struct bios_settings_t { | 125 | struct bios_settings_t { |
113 | const char *vendor; | 126 | const char *vendor; |
127 | const char *product; | ||
114 | const char *version; | 128 | const char *version; |
115 | unsigned char fanreg; | 129 | unsigned char fanreg; |
116 | unsigned char tempreg; | 130 | unsigned char tempreg; |
117 | unsigned char fancmd[2]; /* fan off and auto commands */ | 131 | struct fancmd cmd; |
118 | }; | 132 | }; |
119 | 133 | ||
120 | /* Register addresses and values for different BIOS versions */ | 134 | /* Register addresses and values for different BIOS versions */ |
121 | static const struct bios_settings_t bios_tbl[] = { | 135 | static const struct bios_settings_t bios_tbl[] = { |
122 | {"Acer", "v0.3109", 0x55, 0x58, {0x1f, 0x00} }, | 136 | /* AOA110 */ |
123 | {"Acer", "v0.3114", 0x55, 0x58, {0x1f, 0x00} }, | 137 | {"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x00} }, |
124 | {"Acer", "v0.3301", 0x55, 0x58, {0xaf, 0x00} }, | 138 | {"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x00} }, |
125 | {"Acer", "v0.3304", 0x55, 0x58, {0xaf, 0x00} }, | 139 | {"Acer", "AOA110", "v0.3301", 0x55, 0x58, {0xaf, 0x00} }, |
126 | {"Acer", "v0.3305", 0x55, 0x58, {0xaf, 0x00} }, | 140 | {"Acer", "AOA110", "v0.3304", 0x55, 0x58, {0xaf, 0x00} }, |
127 | {"Acer", "v0.3308", 0x55, 0x58, {0x21, 0x00} }, | 141 | {"Acer", "AOA110", "v0.3305", 0x55, 0x58, {0xaf, 0x00} }, |
128 | {"Acer", "v0.3309", 0x55, 0x58, {0x21, 0x00} }, | 142 | {"Acer", "AOA110", "v0.3307", 0x55, 0x58, {0xaf, 0x00} }, |
129 | {"Acer", "v0.3310", 0x55, 0x58, {0x21, 0x00} }, | 143 | {"Acer", "AOA110", "v0.3308", 0x55, 0x58, {0x21, 0x00} }, |
130 | {"Gateway", "v0.3103", 0x55, 0x58, {0x21, 0x00} }, | 144 | {"Acer", "AOA110", "v0.3309", 0x55, 0x58, {0x21, 0x00} }, |
131 | {"Packard Bell", "v0.3105", 0x55, 0x58, {0x21, 0x00} }, | 145 | {"Acer", "AOA110", "v0.3310", 0x55, 0x58, {0x21, 0x00} }, |
132 | {"", "", 0, 0, {0, 0} } | 146 | /* AOA150 */ |
147 | {"Acer", "AOA150", "v0.3114", 0x55, 0x58, {0x20, 0x00} }, | ||
148 | {"Acer", "AOA150", "v0.3301", 0x55, 0x58, {0x20, 0x00} }, | ||
149 | {"Acer", "AOA150", "v0.3304", 0x55, 0x58, {0x20, 0x00} }, | ||
150 | {"Acer", "AOA150", "v0.3305", 0x55, 0x58, {0x20, 0x00} }, | ||
151 | {"Acer", "AOA150", "v0.3307", 0x55, 0x58, {0x20, 0x00} }, | ||
152 | {"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x00} }, | ||
153 | {"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x00} }, | ||
154 | {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x00} }, | ||
155 | /* special BIOS / other */ | ||
156 | {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00} }, | ||
157 | {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00} }, | ||
158 | {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00} }, | ||
159 | {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00} }, | ||
160 | {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} }, | ||
161 | /* pewpew-terminator */ | ||
162 | {"", "", "", 0, 0, {0, 0} } | ||
133 | }; | 163 | }; |
134 | 164 | ||
135 | static const struct bios_settings_t *bios_cfg __read_mostly; | 165 | static const struct bios_settings_t *bios_cfg __read_mostly; |
136 | 166 | ||
137 | |||
138 | static int acerhdf_get_temp(int *temp) | 167 | static int acerhdf_get_temp(int *temp) |
139 | { | 168 | { |
140 | u8 read_temp; | 169 | u8 read_temp; |
@@ -150,13 +179,14 @@ static int acerhdf_get_temp(int *temp) | |||
150 | static int acerhdf_get_fanstate(int *state) | 179 | static int acerhdf_get_fanstate(int *state) |
151 | { | 180 | { |
152 | u8 fan; | 181 | u8 fan; |
153 | bool tmp; | ||
154 | 182 | ||
155 | if (ec_read(bios_cfg->fanreg, &fan)) | 183 | if (ec_read(bios_cfg->fanreg, &fan)) |
156 | return -EINVAL; | 184 | return -EINVAL; |
157 | 185 | ||
158 | tmp = (fan == bios_cfg->fancmd[ACERHDF_FAN_OFF]); | 186 | if (fan != bios_cfg->cmd.cmd_off) |
159 | *state = tmp ? ACERHDF_FAN_OFF : ACERHDF_FAN_AUTO; | 187 | *state = ACERHDF_FAN_AUTO; |
188 | else | ||
189 | *state = ACERHDF_FAN_OFF; | ||
160 | 190 | ||
161 | return 0; | 191 | return 0; |
162 | } | 192 | } |
@@ -175,7 +205,8 @@ static void acerhdf_change_fanstate(int state) | |||
175 | state = ACERHDF_FAN_AUTO; | 205 | state = ACERHDF_FAN_AUTO; |
176 | } | 206 | } |
177 | 207 | ||
178 | cmd = bios_cfg->fancmd[state]; | 208 | cmd = (state == ACERHDF_FAN_OFF) ? bios_cfg->cmd.cmd_off |
209 | : bios_cfg->cmd.cmd_auto; | ||
179 | fanstate = state; | 210 | fanstate = state; |
180 | 211 | ||
181 | ec_write(bios_cfg->fanreg, cmd); | 212 | ec_write(bios_cfg->fanreg, cmd); |
@@ -408,7 +439,7 @@ struct thermal_cooling_device_ops acerhdf_cooling_ops = { | |||
408 | }; | 439 | }; |
409 | 440 | ||
410 | /* suspend / resume functionality */ | 441 | /* suspend / resume functionality */ |
411 | static int acerhdf_suspend(struct platform_device *dev, pm_message_t state) | 442 | static int acerhdf_suspend(struct device *dev) |
412 | { | 443 | { |
413 | if (kernelmode) | 444 | if (kernelmode) |
414 | acerhdf_change_fanstate(ACERHDF_FAN_AUTO); | 445 | acerhdf_change_fanstate(ACERHDF_FAN_AUTO); |
@@ -419,14 +450,6 @@ static int acerhdf_suspend(struct platform_device *dev, pm_message_t state) | |||
419 | return 0; | 450 | return 0; |
420 | } | 451 | } |
421 | 452 | ||
422 | static int acerhdf_resume(struct platform_device *device) | ||
423 | { | ||
424 | if (verbose) | ||
425 | pr_notice("resuming\n"); | ||
426 | |||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | static int __devinit acerhdf_probe(struct platform_device *device) | 453 | static int __devinit acerhdf_probe(struct platform_device *device) |
431 | { | 454 | { |
432 | return 0; | 455 | return 0; |
@@ -437,15 +460,19 @@ static int acerhdf_remove(struct platform_device *device) | |||
437 | return 0; | 460 | return 0; |
438 | } | 461 | } |
439 | 462 | ||
440 | struct platform_driver acerhdf_drv = { | 463 | static struct dev_pm_ops acerhdf_pm_ops = { |
464 | .suspend = acerhdf_suspend, | ||
465 | .freeze = acerhdf_suspend, | ||
466 | }; | ||
467 | |||
468 | static struct platform_driver acerhdf_driver = { | ||
441 | .driver = { | 469 | .driver = { |
442 | .name = "acerhdf", | 470 | .name = "acerhdf", |
443 | .owner = THIS_MODULE, | 471 | .owner = THIS_MODULE, |
472 | .pm = &acerhdf_pm_ops, | ||
444 | }, | 473 | }, |
445 | .probe = acerhdf_probe, | 474 | .probe = acerhdf_probe, |
446 | .remove = acerhdf_remove, | 475 | .remove = acerhdf_remove, |
447 | .suspend = acerhdf_suspend, | ||
448 | .resume = acerhdf_resume, | ||
449 | }; | 476 | }; |
450 | 477 | ||
451 | 478 | ||
@@ -454,32 +481,40 @@ static int acerhdf_check_hardware(void) | |||
454 | { | 481 | { |
455 | char const *vendor, *version, *product; | 482 | char const *vendor, *version, *product; |
456 | int i; | 483 | int i; |
484 | unsigned long prod_len = 0; | ||
457 | 485 | ||
458 | /* get BIOS data */ | 486 | /* get BIOS data */ |
459 | vendor = dmi_get_system_info(DMI_SYS_VENDOR); | 487 | vendor = dmi_get_system_info(DMI_SYS_VENDOR); |
460 | version = dmi_get_system_info(DMI_BIOS_VERSION); | 488 | version = dmi_get_system_info(DMI_BIOS_VERSION); |
461 | product = dmi_get_system_info(DMI_PRODUCT_NAME); | 489 | product = dmi_get_system_info(DMI_PRODUCT_NAME); |
462 | 490 | ||
491 | |||
463 | pr_info("Acer Aspire One Fan driver, v.%s\n", DRV_VER); | 492 | pr_info("Acer Aspire One Fan driver, v.%s\n", DRV_VER); |
464 | 493 | ||
465 | if (!force_bios[0]) { | 494 | if (force_bios[0]) { |
466 | if (strncmp(product, "AO", 2)) { | ||
467 | pr_err("no Aspire One hardware found\n"); | ||
468 | return -EINVAL; | ||
469 | } | ||
470 | } else { | ||
471 | pr_info("forcing BIOS version: %s\n", version); | ||
472 | version = force_bios; | 495 | version = force_bios; |
496 | pr_info("forcing BIOS version: %s\n", version); | ||
497 | kernelmode = 0; | ||
498 | } | ||
499 | |||
500 | if (force_product[0]) { | ||
501 | product = force_product; | ||
502 | pr_info("forcing BIOS product: %s\n", product); | ||
473 | kernelmode = 0; | 503 | kernelmode = 0; |
474 | } | 504 | } |
475 | 505 | ||
506 | prod_len = strlen(product); | ||
507 | |||
476 | if (verbose) | 508 | if (verbose) |
477 | pr_info("BIOS info: %s %s, product: %s\n", | 509 | pr_info("BIOS info: %s %s, product: %s\n", |
478 | vendor, version, product); | 510 | vendor, version, product); |
479 | 511 | ||
480 | /* search BIOS version and vendor in BIOS settings table */ | 512 | /* search BIOS version and vendor in BIOS settings table */ |
481 | for (i = 0; bios_tbl[i].version[0]; i++) { | 513 | for (i = 0; bios_tbl[i].version[0]; i++) { |
482 | if (!strcmp(bios_tbl[i].vendor, vendor) && | 514 | if (strlen(bios_tbl[i].product) >= prod_len && |
515 | !strncmp(bios_tbl[i].product, product, | ||
516 | strlen(bios_tbl[i].product)) && | ||
517 | !strcmp(bios_tbl[i].vendor, vendor) && | ||
483 | !strcmp(bios_tbl[i].version, version)) { | 518 | !strcmp(bios_tbl[i].version, version)) { |
484 | bios_cfg = &bios_tbl[i]; | 519 | bios_cfg = &bios_tbl[i]; |
485 | break; | 520 | break; |
@@ -487,8 +522,8 @@ static int acerhdf_check_hardware(void) | |||
487 | } | 522 | } |
488 | 523 | ||
489 | if (!bios_cfg) { | 524 | if (!bios_cfg) { |
490 | pr_err("unknown (unsupported) BIOS version %s/%s, " | 525 | pr_err("unknown (unsupported) BIOS version %s/%s/%s, " |
491 | "please report, aborting!\n", vendor, version); | 526 | "please report, aborting!\n", vendor, product, version); |
492 | return -EINVAL; | 527 | return -EINVAL; |
493 | } | 528 | } |
494 | 529 | ||
@@ -509,7 +544,7 @@ static int acerhdf_register_platform(void) | |||
509 | { | 544 | { |
510 | int err = 0; | 545 | int err = 0; |
511 | 546 | ||
512 | err = platform_driver_register(&acerhdf_drv); | 547 | err = platform_driver_register(&acerhdf_driver); |
513 | if (err) | 548 | if (err) |
514 | return err; | 549 | return err; |
515 | 550 | ||
@@ -525,7 +560,7 @@ static void acerhdf_unregister_platform(void) | |||
525 | return; | 560 | return; |
526 | 561 | ||
527 | platform_device_del(acerhdf_dev); | 562 | platform_device_del(acerhdf_dev); |
528 | platform_driver_unregister(&acerhdf_drv); | 563 | platform_driver_unregister(&acerhdf_driver); |
529 | } | 564 | } |
530 | 565 | ||
531 | static int acerhdf_register_thermal(void) | 566 | static int acerhdf_register_thermal(void) |
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index db657bbeec90..b39d2bb3e75b 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c | |||
@@ -77,15 +77,16 @@ | |||
77 | * Flags for hotk status | 77 | * Flags for hotk status |
78 | * WL_ON and BT_ON are also used for wireless_status() | 78 | * WL_ON and BT_ON are also used for wireless_status() |
79 | */ | 79 | */ |
80 | #define WL_ON 0x01 //internal Wifi | 80 | #define WL_ON 0x01 /* internal Wifi */ |
81 | #define BT_ON 0x02 //internal Bluetooth | 81 | #define BT_ON 0x02 /* internal Bluetooth */ |
82 | #define MLED_ON 0x04 //mail LED | 82 | #define MLED_ON 0x04 /* mail LED */ |
83 | #define TLED_ON 0x08 //touchpad LED | 83 | #define TLED_ON 0x08 /* touchpad LED */ |
84 | #define RLED_ON 0x10 //Record LED | 84 | #define RLED_ON 0x10 /* Record LED */ |
85 | #define PLED_ON 0x20 //Phone LED | 85 | #define PLED_ON 0x20 /* Phone LED */ |
86 | #define GLED_ON 0x40 //Gaming LED | 86 | #define GLED_ON 0x40 /* Gaming LED */ |
87 | #define LCD_ON 0x80 //LCD backlight | 87 | #define LCD_ON 0x80 /* LCD backlight */ |
88 | #define GPS_ON 0x100 //GPS | 88 | #define GPS_ON 0x100 /* GPS */ |
89 | #define KEY_ON 0x200 /* Keyboard backlight */ | ||
89 | 90 | ||
90 | #define ASUS_LOG ASUS_HOTK_FILE ": " | 91 | #define ASUS_LOG ASUS_HOTK_FILE ": " |
91 | #define ASUS_ERR KERN_ERR ASUS_LOG | 92 | #define ASUS_ERR KERN_ERR ASUS_LOG |
@@ -98,7 +99,8 @@ MODULE_AUTHOR("Julien Lerouge, Karol Kozimor, Corentin Chary"); | |||
98 | MODULE_DESCRIPTION(ASUS_HOTK_NAME); | 99 | MODULE_DESCRIPTION(ASUS_HOTK_NAME); |
99 | MODULE_LICENSE("GPL"); | 100 | MODULE_LICENSE("GPL"); |
100 | 101 | ||
101 | /* WAPF defines the behavior of the Fn+Fx wlan key | 102 | /* |
103 | * WAPF defines the behavior of the Fn+Fx wlan key | ||
102 | * The significance of values is yet to be found, but | 104 | * The significance of values is yet to be found, but |
103 | * most of the time: | 105 | * most of the time: |
104 | * 0x0 will do nothing | 106 | * 0x0 will do nothing |
@@ -125,7 +127,8 @@ ASUS_HANDLE(gled_set, ASUS_HOTK_PREFIX "GLED"); /* G1, G2 (probably) */ | |||
125 | /* LEDD */ | 127 | /* LEDD */ |
126 | ASUS_HANDLE(ledd_set, ASUS_HOTK_PREFIX "SLCM"); | 128 | ASUS_HANDLE(ledd_set, ASUS_HOTK_PREFIX "SLCM"); |
127 | 129 | ||
128 | /* Bluetooth and WLAN | 130 | /* |
131 | * Bluetooth and WLAN | ||
129 | * WLED and BLED are not handled like other XLED, because in some dsdt | 132 | * WLED and BLED are not handled like other XLED, because in some dsdt |
130 | * they also control the WLAN/Bluetooth device. | 133 | * they also control the WLAN/Bluetooth device. |
131 | */ | 134 | */ |
@@ -149,22 +152,32 @@ ASUS_HANDLE(lcd_switch, "\\_SB.PCI0.SBRG.EC0._Q10", /* All new models */ | |||
149 | 152 | ||
150 | /* Display */ | 153 | /* Display */ |
151 | ASUS_HANDLE(display_set, ASUS_HOTK_PREFIX "SDSP"); | 154 | ASUS_HANDLE(display_set, ASUS_HOTK_PREFIX "SDSP"); |
152 | ASUS_HANDLE(display_get, "\\_SB.PCI0.P0P1.VGA.GETD", /* A6B, A6K A6R A7D F3JM L4R M6R A3G | 155 | ASUS_HANDLE(display_get, |
153 | M6A M6V VX-1 V6J V6V W3Z */ | 156 | /* A6B, A6K A6R A7D F3JM L4R M6R A3G M6A M6V VX-1 V6J V6V W3Z */ |
154 | "\\_SB.PCI0.P0P2.VGA.GETD", /* A3E A4K, A4D A4L A6J A7J A8J Z71V M9V | 157 | "\\_SB.PCI0.P0P1.VGA.GETD", |
155 | S5A M5A z33A W1Jc W2V G1 */ | 158 | /* A3E A4K, A4D A4L A6J A7J A8J Z71V M9V S5A M5A z33A W1Jc W2V G1 */ |
156 | "\\_SB.PCI0.P0P3.VGA.GETD", /* A6V A6Q */ | 159 | "\\_SB.PCI0.P0P2.VGA.GETD", |
157 | "\\_SB.PCI0.P0PA.VGA.GETD", /* A6T, A6M */ | 160 | /* A6V A6Q */ |
158 | "\\_SB.PCI0.PCI1.VGAC.NMAP", /* L3C */ | 161 | "\\_SB.PCI0.P0P3.VGA.GETD", |
159 | "\\_SB.PCI0.VGA.GETD", /* Z96F */ | 162 | /* A6T, A6M */ |
160 | "\\ACTD", /* A2D */ | 163 | "\\_SB.PCI0.P0PA.VGA.GETD", |
161 | "\\ADVG", /* A4G Z71A W1N W5A W5F M2N M3N M5N M6N S1N S5N */ | 164 | /* L3C */ |
162 | "\\DNXT", /* P30 */ | 165 | "\\_SB.PCI0.PCI1.VGAC.NMAP", |
163 | "\\INFB", /* A2H D1 L2D L3D L3H L2E L5D L5C M1A M2E L4L W3V */ | 166 | /* Z96F */ |
164 | "\\SSTE"); /* A3F A6F A3N A3L M6N W3N W6A */ | 167 | "\\_SB.PCI0.VGA.GETD", |
165 | 168 | /* A2D */ | |
166 | ASUS_HANDLE(ls_switch, ASUS_HOTK_PREFIX "ALSC"); /* Z71A Z71V */ | 169 | "\\ACTD", |
167 | ASUS_HANDLE(ls_level, ASUS_HOTK_PREFIX "ALSL"); /* Z71A Z71V */ | 170 | /* A4G Z71A W1N W5A W5F M2N M3N M5N M6N S1N S5N */ |
171 | "\\ADVG", | ||
172 | /* P30 */ | ||
173 | "\\DNXT", | ||
174 | /* A2H D1 L2D L3D L3H L2E L5D L5C M1A M2E L4L W3V */ | ||
175 | "\\INFB", | ||
176 | /* A3F A6F A3N A3L M6N W3N W6A */ | ||
177 | "\\SSTE"); | ||
178 | |||
179 | ASUS_HANDLE(ls_switch, ASUS_HOTK_PREFIX "ALSC"); /* Z71A Z71V */ | ||
180 | ASUS_HANDLE(ls_level, ASUS_HOTK_PREFIX "ALSL"); /* Z71A Z71V */ | ||
168 | 181 | ||
169 | /* GPS */ | 182 | /* GPS */ |
170 | /* R2H use different handle for GPS on/off */ | 183 | /* R2H use different handle for GPS on/off */ |
@@ -172,19 +185,23 @@ ASUS_HANDLE(gps_on, ASUS_HOTK_PREFIX "SDON"); /* R2H */ | |||
172 | ASUS_HANDLE(gps_off, ASUS_HOTK_PREFIX "SDOF"); /* R2H */ | 185 | ASUS_HANDLE(gps_off, ASUS_HOTK_PREFIX "SDOF"); /* R2H */ |
173 | ASUS_HANDLE(gps_status, ASUS_HOTK_PREFIX "GPST"); | 186 | ASUS_HANDLE(gps_status, ASUS_HOTK_PREFIX "GPST"); |
174 | 187 | ||
188 | /* Keyboard light */ | ||
189 | ASUS_HANDLE(kled_set, ASUS_HOTK_PREFIX "SLKB"); | ||
190 | ASUS_HANDLE(kled_get, ASUS_HOTK_PREFIX "GLKB"); | ||
191 | |||
175 | /* | 192 | /* |
176 | * This is the main structure, we can use it to store anything interesting | 193 | * This is the main structure, we can use it to store anything interesting |
177 | * about the hotk device | 194 | * about the hotk device |
178 | */ | 195 | */ |
179 | struct asus_hotk { | 196 | struct asus_hotk { |
180 | char *name; //laptop name | 197 | char *name; /* laptop name */ |
181 | struct acpi_device *device; //the device we are in | 198 | struct acpi_device *device; /* the device we are in */ |
182 | acpi_handle handle; //the handle of the hotk device | 199 | acpi_handle handle; /* the handle of the hotk device */ |
183 | char status; //status of the hotk, for LEDs, ... | 200 | char status; /* status of the hotk, for LEDs, ... */ |
184 | u32 ledd_status; //status of the LED display | 201 | u32 ledd_status; /* status of the LED display */ |
185 | u8 light_level; //light sensor level | 202 | u8 light_level; /* light sensor level */ |
186 | u8 light_switch; //light sensor switch value | 203 | u8 light_switch; /* light sensor switch value */ |
187 | u16 event_count[128]; //count for each event TODO make this better | 204 | u16 event_count[128]; /* count for each event TODO make this better */ |
188 | struct input_dev *inputdev; | 205 | struct input_dev *inputdev; |
189 | u16 *keycode_map; | 206 | u16 *keycode_map; |
190 | }; | 207 | }; |
@@ -237,28 +254,35 @@ static struct backlight_ops asusbl_ops = { | |||
237 | .update_status = update_bl_status, | 254 | .update_status = update_bl_status, |
238 | }; | 255 | }; |
239 | 256 | ||
240 | /* These functions actually update the LED's, and are called from a | 257 | /* |
258 | * These functions actually update the LED's, and are called from a | ||
241 | * workqueue. By doing this as separate work rather than when the LED | 259 | * workqueue. By doing this as separate work rather than when the LED |
242 | * subsystem asks, we avoid messing with the Asus ACPI stuff during a | 260 | * subsystem asks, we avoid messing with the Asus ACPI stuff during a |
243 | * potentially bad time, such as a timer interrupt. */ | 261 | * potentially bad time, such as a timer interrupt. |
262 | */ | ||
244 | static struct workqueue_struct *led_workqueue; | 263 | static struct workqueue_struct *led_workqueue; |
245 | 264 | ||
246 | #define ASUS_LED(object, ledname) \ | 265 | #define ASUS_LED(object, ledname, max) \ |
247 | static void object##_led_set(struct led_classdev *led_cdev, \ | 266 | static void object##_led_set(struct led_classdev *led_cdev, \ |
248 | enum led_brightness value); \ | 267 | enum led_brightness value); \ |
268 | static enum led_brightness object##_led_get( \ | ||
269 | struct led_classdev *led_cdev); \ | ||
249 | static void object##_led_update(struct work_struct *ignored); \ | 270 | static void object##_led_update(struct work_struct *ignored); \ |
250 | static int object##_led_wk; \ | 271 | static int object##_led_wk; \ |
251 | static DECLARE_WORK(object##_led_work, object##_led_update); \ | 272 | static DECLARE_WORK(object##_led_work, object##_led_update); \ |
252 | static struct led_classdev object##_led = { \ | 273 | static struct led_classdev object##_led = { \ |
253 | .name = "asus::" ledname, \ | 274 | .name = "asus::" ledname, \ |
254 | .brightness_set = object##_led_set, \ | 275 | .brightness_set = object##_led_set, \ |
276 | .brightness_get = object##_led_get, \ | ||
277 | .max_brightness = max \ | ||
255 | } | 278 | } |
256 | 279 | ||
257 | ASUS_LED(mled, "mail"); | 280 | ASUS_LED(mled, "mail", 1); |
258 | ASUS_LED(tled, "touchpad"); | 281 | ASUS_LED(tled, "touchpad", 1); |
259 | ASUS_LED(rled, "record"); | 282 | ASUS_LED(rled, "record", 1); |
260 | ASUS_LED(pled, "phone"); | 283 | ASUS_LED(pled, "phone", 1); |
261 | ASUS_LED(gled, "gaming"); | 284 | ASUS_LED(gled, "gaming", 1); |
285 | ASUS_LED(kled, "kbd_backlight", 3); | ||
262 | 286 | ||
263 | struct key_entry { | 287 | struct key_entry { |
264 | char type; | 288 | char type; |
@@ -278,16 +302,23 @@ static struct key_entry asus_keymap[] = { | |||
278 | {KE_KEY, 0x41, KEY_NEXTSONG}, | 302 | {KE_KEY, 0x41, KEY_NEXTSONG}, |
279 | {KE_KEY, 0x43, KEY_STOPCD}, | 303 | {KE_KEY, 0x43, KEY_STOPCD}, |
280 | {KE_KEY, 0x45, KEY_PLAYPAUSE}, | 304 | {KE_KEY, 0x45, KEY_PLAYPAUSE}, |
305 | {KE_KEY, 0x4c, KEY_MEDIA}, | ||
281 | {KE_KEY, 0x50, KEY_EMAIL}, | 306 | {KE_KEY, 0x50, KEY_EMAIL}, |
282 | {KE_KEY, 0x51, KEY_WWW}, | 307 | {KE_KEY, 0x51, KEY_WWW}, |
308 | {KE_KEY, 0x55, KEY_CALC}, | ||
283 | {KE_KEY, 0x5C, KEY_SCREENLOCK}, /* Screenlock */ | 309 | {KE_KEY, 0x5C, KEY_SCREENLOCK}, /* Screenlock */ |
284 | {KE_KEY, 0x5D, KEY_WLAN}, | 310 | {KE_KEY, 0x5D, KEY_WLAN}, |
311 | {KE_KEY, 0x5E, KEY_WLAN}, | ||
312 | {KE_KEY, 0x5F, KEY_WLAN}, | ||
313 | {KE_KEY, 0x60, KEY_SWITCHVIDEOMODE}, | ||
285 | {KE_KEY, 0x61, KEY_SWITCHVIDEOMODE}, | 314 | {KE_KEY, 0x61, KEY_SWITCHVIDEOMODE}, |
286 | {KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */ | 315 | {KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */ |
287 | {KE_KEY, 0x82, KEY_CAMERA}, | 316 | {KE_KEY, 0x82, KEY_CAMERA}, |
288 | {KE_KEY, 0x8A, KEY_PROG1}, | 317 | {KE_KEY, 0x8A, KEY_PROG1}, |
289 | {KE_KEY, 0x95, KEY_MEDIA}, | 318 | {KE_KEY, 0x95, KEY_MEDIA}, |
290 | {KE_KEY, 0x99, KEY_PHONE}, | 319 | {KE_KEY, 0x99, KEY_PHONE}, |
320 | {KE_KEY, 0xc4, KEY_KBDILLUMUP}, | ||
321 | {KE_KEY, 0xc5, KEY_KBDILLUMDOWN}, | ||
291 | {KE_END, 0}, | 322 | {KE_END, 0}, |
292 | }; | 323 | }; |
293 | 324 | ||
@@ -301,8 +332,8 @@ static struct key_entry asus_keymap[] = { | |||
301 | static int write_acpi_int(acpi_handle handle, const char *method, int val, | 332 | static int write_acpi_int(acpi_handle handle, const char *method, int val, |
302 | struct acpi_buffer *output) | 333 | struct acpi_buffer *output) |
303 | { | 334 | { |
304 | struct acpi_object_list params; //list of input parameters (an int here) | 335 | struct acpi_object_list params; /* list of input parameters (an int) */ |
305 | union acpi_object in_obj; //the only param we use | 336 | union acpi_object in_obj; /* the only param we use */ |
306 | acpi_status status; | 337 | acpi_status status; |
307 | 338 | ||
308 | if (!handle) | 339 | if (!handle) |
@@ -399,6 +430,11 @@ static void write_status(acpi_handle handle, int out, int mask) | |||
399 | { \ | 430 | { \ |
400 | int value = object##_led_wk; \ | 431 | int value = object##_led_wk; \ |
401 | write_status(object##_set_handle, value, (mask)); \ | 432 | write_status(object##_set_handle, value, (mask)); \ |
433 | } \ | ||
434 | static enum led_brightness object##_led_get( \ | ||
435 | struct led_classdev *led_cdev) \ | ||
436 | { \ | ||
437 | return led_cdev->brightness; \ | ||
402 | } | 438 | } |
403 | 439 | ||
404 | ASUS_LED_HANDLER(mled, MLED_ON); | 440 | ASUS_LED_HANDLER(mled, MLED_ON); |
@@ -407,6 +443,60 @@ ASUS_LED_HANDLER(rled, RLED_ON); | |||
407 | ASUS_LED_HANDLER(tled, TLED_ON); | 443 | ASUS_LED_HANDLER(tled, TLED_ON); |
408 | ASUS_LED_HANDLER(gled, GLED_ON); | 444 | ASUS_LED_HANDLER(gled, GLED_ON); |
409 | 445 | ||
446 | /* | ||
447 | * Keyboard backlight | ||
448 | */ | ||
449 | static int get_kled_lvl(void) | ||
450 | { | ||
451 | unsigned long long kblv; | ||
452 | struct acpi_object_list params; | ||
453 | union acpi_object in_obj; | ||
454 | acpi_status rv; | ||
455 | |||
456 | params.count = 1; | ||
457 | params.pointer = &in_obj; | ||
458 | in_obj.type = ACPI_TYPE_INTEGER; | ||
459 | in_obj.integer.value = 2; | ||
460 | |||
461 | rv = acpi_evaluate_integer(kled_get_handle, NULL, ¶ms, &kblv); | ||
462 | if (ACPI_FAILURE(rv)) { | ||
463 | pr_warning("Error reading kled level\n"); | ||
464 | return 0; | ||
465 | } | ||
466 | return kblv; | ||
467 | } | ||
468 | |||
469 | static int set_kled_lvl(int kblv) | ||
470 | { | ||
471 | if (kblv > 0) | ||
472 | kblv = (1 << 7) | (kblv & 0x7F); | ||
473 | else | ||
474 | kblv = 0; | ||
475 | |||
476 | if (write_acpi_int(kled_set_handle, NULL, kblv, NULL)) { | ||
477 | pr_warning("Keyboard LED display write failed\n"); | ||
478 | return -EINVAL; | ||
479 | } | ||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | static void kled_led_set(struct led_classdev *led_cdev, | ||
484 | enum led_brightness value) | ||
485 | { | ||
486 | kled_led_wk = value; | ||
487 | queue_work(led_workqueue, &kled_led_work); | ||
488 | } | ||
489 | |||
490 | static void kled_led_update(struct work_struct *ignored) | ||
491 | { | ||
492 | set_kled_lvl(kled_led_wk); | ||
493 | } | ||
494 | |||
495 | static enum led_brightness kled_led_get(struct led_classdev *led_cdev) | ||
496 | { | ||
497 | return get_kled_lvl(); | ||
498 | } | ||
499 | |||
410 | static int get_lcd_state(void) | 500 | static int get_lcd_state(void) |
411 | { | 501 | { |
412 | return read_status(LCD_ON); | 502 | return read_status(LCD_ON); |
@@ -498,7 +588,7 @@ static ssize_t show_infos(struct device *dev, | |||
498 | { | 588 | { |
499 | int len = 0; | 589 | int len = 0; |
500 | unsigned long long temp; | 590 | unsigned long long temp; |
501 | char buf[16]; //enough for all info | 591 | char buf[16]; /* enough for all info */ |
502 | acpi_status rv = AE_OK; | 592 | acpi_status rv = AE_OK; |
503 | 593 | ||
504 | /* | 594 | /* |
@@ -516,7 +606,17 @@ static ssize_t show_infos(struct device *dev, | |||
516 | */ | 606 | */ |
517 | rv = acpi_evaluate_integer(hotk->handle, "SFUN", NULL, &temp); | 607 | rv = acpi_evaluate_integer(hotk->handle, "SFUN", NULL, &temp); |
518 | if (!ACPI_FAILURE(rv)) | 608 | if (!ACPI_FAILURE(rv)) |
519 | len += sprintf(page + len, "SFUN value : 0x%04x\n", | 609 | len += sprintf(page + len, "SFUN value : %#x\n", |
610 | (uint) temp); | ||
611 | /* | ||
612 | * The HWRS method return informations about the hardware. | ||
613 | * 0x80 bit is for WLAN, 0x100 for Bluetooth. | ||
614 | * The significance of others is yet to be found. | ||
615 | * If we don't find the method, we assume the device are present. | ||
616 | */ | ||
617 | rv = acpi_evaluate_integer(hotk->handle, "HRWS", NULL, &temp); | ||
618 | if (!ACPI_FAILURE(rv)) | ||
619 | len += sprintf(page + len, "HRWS value : %#x\n", | ||
520 | (uint) temp); | 620 | (uint) temp); |
521 | /* | 621 | /* |
522 | * Another value for userspace: the ASYM method returns 0x02 for | 622 | * Another value for userspace: the ASYM method returns 0x02 for |
@@ -527,7 +627,7 @@ static ssize_t show_infos(struct device *dev, | |||
527 | */ | 627 | */ |
528 | rv = acpi_evaluate_integer(hotk->handle, "ASYM", NULL, &temp); | 628 | rv = acpi_evaluate_integer(hotk->handle, "ASYM", NULL, &temp); |
529 | if (!ACPI_FAILURE(rv)) | 629 | if (!ACPI_FAILURE(rv)) |
530 | len += sprintf(page + len, "ASYM value : 0x%04x\n", | 630 | len += sprintf(page + len, "ASYM value : %#x\n", |
531 | (uint) temp); | 631 | (uint) temp); |
532 | if (asus_info) { | 632 | if (asus_info) { |
533 | snprintf(buf, 16, "%d", asus_info->length); | 633 | snprintf(buf, 16, "%d", asus_info->length); |
@@ -648,8 +748,10 @@ static int read_display(void) | |||
648 | unsigned long long value = 0; | 748 | unsigned long long value = 0; |
649 | acpi_status rv = AE_OK; | 749 | acpi_status rv = AE_OK; |
650 | 750 | ||
651 | /* In most of the case, we know how to set the display, but sometime | 751 | /* |
652 | we can't read it */ | 752 | * In most of the case, we know how to set the display, but sometime |
753 | * we can't read it | ||
754 | */ | ||
653 | if (display_get_handle) { | 755 | if (display_get_handle) { |
654 | rv = acpi_evaluate_integer(display_get_handle, NULL, | 756 | rv = acpi_evaluate_integer(display_get_handle, NULL, |
655 | NULL, &value); | 757 | NULL, &value); |
@@ -1037,6 +1139,9 @@ static int asus_hotk_get_info(void) | |||
1037 | 1139 | ||
1038 | ASUS_HANDLE_INIT(ledd_set); | 1140 | ASUS_HANDLE_INIT(ledd_set); |
1039 | 1141 | ||
1142 | ASUS_HANDLE_INIT(kled_set); | ||
1143 | ASUS_HANDLE_INIT(kled_get); | ||
1144 | |||
1040 | /* | 1145 | /* |
1041 | * The HWRS method return informations about the hardware. | 1146 | * The HWRS method return informations about the hardware. |
1042 | * 0x80 bit is for WLAN, 0x100 for Bluetooth. | 1147 | * 0x80 bit is for WLAN, 0x100 for Bluetooth. |
@@ -1063,8 +1168,10 @@ static int asus_hotk_get_info(void) | |||
1063 | ASUS_HANDLE_INIT(display_set); | 1168 | ASUS_HANDLE_INIT(display_set); |
1064 | ASUS_HANDLE_INIT(display_get); | 1169 | ASUS_HANDLE_INIT(display_get); |
1065 | 1170 | ||
1066 | /* There is a lot of models with "ALSL", but a few get | 1171 | /* |
1067 | a real light sens, so we need to check it. */ | 1172 | * There is a lot of models with "ALSL", but a few get |
1173 | * a real light sens, so we need to check it. | ||
1174 | */ | ||
1068 | if (!ASUS_HANDLE_INIT(ls_switch)) | 1175 | if (!ASUS_HANDLE_INIT(ls_switch)) |
1069 | ASUS_HANDLE_INIT(ls_level); | 1176 | ASUS_HANDLE_INIT(ls_level); |
1070 | 1177 | ||
@@ -1168,6 +1275,10 @@ static int asus_hotk_add(struct acpi_device *device) | |||
1168 | /* LCD Backlight is on by default */ | 1275 | /* LCD Backlight is on by default */ |
1169 | write_status(NULL, 1, LCD_ON); | 1276 | write_status(NULL, 1, LCD_ON); |
1170 | 1277 | ||
1278 | /* Keyboard Backlight is on by default */ | ||
1279 | if (kled_set_handle) | ||
1280 | set_kled_lvl(1); | ||
1281 | |||
1171 | /* LED display is off by default */ | 1282 | /* LED display is off by default */ |
1172 | hotk->ledd_status = 0xFFF; | 1283 | hotk->ledd_status = 0xFFF; |
1173 | 1284 | ||
@@ -1222,6 +1333,7 @@ static void asus_led_exit(void) | |||
1222 | ASUS_LED_UNREGISTER(pled); | 1333 | ASUS_LED_UNREGISTER(pled); |
1223 | ASUS_LED_UNREGISTER(rled); | 1334 | ASUS_LED_UNREGISTER(rled); |
1224 | ASUS_LED_UNREGISTER(gled); | 1335 | ASUS_LED_UNREGISTER(gled); |
1336 | ASUS_LED_UNREGISTER(kled); | ||
1225 | } | 1337 | } |
1226 | 1338 | ||
1227 | static void asus_input_exit(void) | 1339 | static void asus_input_exit(void) |
@@ -1301,13 +1413,20 @@ static int asus_led_init(struct device *dev) | |||
1301 | if (rv) | 1413 | if (rv) |
1302 | goto out4; | 1414 | goto out4; |
1303 | 1415 | ||
1416 | if (kled_set_handle && kled_get_handle) | ||
1417 | rv = ASUS_LED_REGISTER(kled, dev); | ||
1418 | if (rv) | ||
1419 | goto out5; | ||
1420 | |||
1304 | led_workqueue = create_singlethread_workqueue("led_workqueue"); | 1421 | led_workqueue = create_singlethread_workqueue("led_workqueue"); |
1305 | if (!led_workqueue) | 1422 | if (!led_workqueue) |
1306 | goto out5; | 1423 | goto out6; |
1307 | 1424 | ||
1308 | return 0; | 1425 | return 0; |
1309 | out5: | 1426 | out6: |
1310 | rv = -ENOMEM; | 1427 | rv = -ENOMEM; |
1428 | ASUS_LED_UNREGISTER(kled); | ||
1429 | out5: | ||
1311 | ASUS_LED_UNREGISTER(gled); | 1430 | ASUS_LED_UNREGISTER(gled); |
1312 | out4: | 1431 | out4: |
1313 | ASUS_LED_UNREGISTER(pled); | 1432 | ASUS_LED_UNREGISTER(pled); |
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 222ffb892f22..da3c08b3dcc1 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -142,18 +142,28 @@ struct eeepc_hotk { | |||
142 | struct rfkill *wlan_rfkill; | 142 | struct rfkill *wlan_rfkill; |
143 | struct rfkill *bluetooth_rfkill; | 143 | struct rfkill *bluetooth_rfkill; |
144 | struct rfkill *wwan3g_rfkill; | 144 | struct rfkill *wwan3g_rfkill; |
145 | struct rfkill *wimax_rfkill; | ||
145 | struct hotplug_slot *hotplug_slot; | 146 | struct hotplug_slot *hotplug_slot; |
146 | struct work_struct hotplug_work; | 147 | struct mutex hotplug_lock; |
147 | }; | 148 | }; |
148 | 149 | ||
149 | /* The actual device the driver binds to */ | 150 | /* The actual device the driver binds to */ |
150 | static struct eeepc_hotk *ehotk; | 151 | static struct eeepc_hotk *ehotk; |
151 | 152 | ||
152 | /* Platform device/driver */ | 153 | /* Platform device/driver */ |
154 | static int eeepc_hotk_thaw(struct device *device); | ||
155 | static int eeepc_hotk_restore(struct device *device); | ||
156 | |||
157 | static struct dev_pm_ops eeepc_pm_ops = { | ||
158 | .thaw = eeepc_hotk_thaw, | ||
159 | .restore = eeepc_hotk_restore, | ||
160 | }; | ||
161 | |||
153 | static struct platform_driver platform_driver = { | 162 | static struct platform_driver platform_driver = { |
154 | .driver = { | 163 | .driver = { |
155 | .name = EEEPC_HOTK_FILE, | 164 | .name = EEEPC_HOTK_FILE, |
156 | .owner = THIS_MODULE, | 165 | .owner = THIS_MODULE, |
166 | .pm = &eeepc_pm_ops, | ||
157 | } | 167 | } |
158 | }; | 168 | }; |
159 | 169 | ||
@@ -192,7 +202,6 @@ static struct key_entry eeepc_keymap[] = { | |||
192 | */ | 202 | */ |
193 | static int eeepc_hotk_add(struct acpi_device *device); | 203 | static int eeepc_hotk_add(struct acpi_device *device); |
194 | static int eeepc_hotk_remove(struct acpi_device *device, int type); | 204 | static int eeepc_hotk_remove(struct acpi_device *device, int type); |
195 | static int eeepc_hotk_resume(struct acpi_device *device); | ||
196 | static void eeepc_hotk_notify(struct acpi_device *device, u32 event); | 205 | static void eeepc_hotk_notify(struct acpi_device *device, u32 event); |
197 | 206 | ||
198 | static const struct acpi_device_id eeepc_device_ids[] = { | 207 | static const struct acpi_device_id eeepc_device_ids[] = { |
@@ -209,7 +218,6 @@ static struct acpi_driver eeepc_hotk_driver = { | |||
209 | .ops = { | 218 | .ops = { |
210 | .add = eeepc_hotk_add, | 219 | .add = eeepc_hotk_add, |
211 | .remove = eeepc_hotk_remove, | 220 | .remove = eeepc_hotk_remove, |
212 | .resume = eeepc_hotk_resume, | ||
213 | .notify = eeepc_hotk_notify, | 221 | .notify = eeepc_hotk_notify, |
214 | }, | 222 | }, |
215 | }; | 223 | }; |
@@ -579,7 +587,6 @@ static void cmsg_quirks(void) | |||
579 | 587 | ||
580 | static int eeepc_hotk_check(void) | 588 | static int eeepc_hotk_check(void) |
581 | { | 589 | { |
582 | const struct key_entry *key; | ||
583 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 590 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
584 | int result; | 591 | int result; |
585 | 592 | ||
@@ -604,31 +611,6 @@ static int eeepc_hotk_check(void) | |||
604 | pr_info("Get control methods supported: 0x%x\n", | 611 | pr_info("Get control methods supported: 0x%x\n", |
605 | ehotk->cm_supported); | 612 | ehotk->cm_supported); |
606 | } | 613 | } |
607 | ehotk->inputdev = input_allocate_device(); | ||
608 | if (!ehotk->inputdev) { | ||
609 | pr_info("Unable to allocate input device\n"); | ||
610 | return 0; | ||
611 | } | ||
612 | ehotk->inputdev->name = "Asus EeePC extra buttons"; | ||
613 | ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0"; | ||
614 | ehotk->inputdev->id.bustype = BUS_HOST; | ||
615 | ehotk->inputdev->getkeycode = eeepc_getkeycode; | ||
616 | ehotk->inputdev->setkeycode = eeepc_setkeycode; | ||
617 | |||
618 | for (key = eeepc_keymap; key->type != KE_END; key++) { | ||
619 | switch (key->type) { | ||
620 | case KE_KEY: | ||
621 | set_bit(EV_KEY, ehotk->inputdev->evbit); | ||
622 | set_bit(key->keycode, ehotk->inputdev->keybit); | ||
623 | break; | ||
624 | } | ||
625 | } | ||
626 | result = input_register_device(ehotk->inputdev); | ||
627 | if (result) { | ||
628 | pr_info("Unable to register input device\n"); | ||
629 | input_free_device(ehotk->inputdev); | ||
630 | return 0; | ||
631 | } | ||
632 | } else { | 614 | } else { |
633 | pr_err("Hotkey device not present, aborting\n"); | 615 | pr_err("Hotkey device not present, aborting\n"); |
634 | return -EINVAL; | 616 | return -EINVAL; |
@@ -661,40 +643,48 @@ static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot, | |||
661 | return 0; | 643 | return 0; |
662 | } | 644 | } |
663 | 645 | ||
664 | static void eeepc_hotplug_work(struct work_struct *work) | 646 | static void eeepc_rfkill_hotplug(void) |
665 | { | 647 | { |
666 | struct pci_dev *dev; | 648 | struct pci_dev *dev; |
667 | struct pci_bus *bus = pci_find_bus(0, 1); | 649 | struct pci_bus *bus; |
668 | bool blocked; | 650 | bool blocked = eeepc_wlan_rfkill_blocked(); |
669 | 651 | ||
670 | if (!bus) { | 652 | if (ehotk->wlan_rfkill) |
671 | pr_warning("Unable to find PCI bus 1?\n"); | 653 | rfkill_set_sw_state(ehotk->wlan_rfkill, blocked); |
672 | return; | ||
673 | } | ||
674 | 654 | ||
675 | blocked = eeepc_wlan_rfkill_blocked(); | 655 | mutex_lock(&ehotk->hotplug_lock); |
676 | if (!blocked) { | 656 | |
677 | dev = pci_get_slot(bus, 0); | 657 | if (ehotk->hotplug_slot) { |
678 | if (dev) { | 658 | bus = pci_find_bus(0, 1); |
679 | /* Device already present */ | 659 | if (!bus) { |
680 | pci_dev_put(dev); | 660 | pr_warning("Unable to find PCI bus 1?\n"); |
681 | return; | 661 | goto out_unlock; |
682 | } | ||
683 | dev = pci_scan_single_device(bus, 0); | ||
684 | if (dev) { | ||
685 | pci_bus_assign_resources(bus); | ||
686 | if (pci_bus_add_device(dev)) | ||
687 | pr_err("Unable to hotplug wifi\n"); | ||
688 | } | 662 | } |
689 | } else { | 663 | |
690 | dev = pci_get_slot(bus, 0); | 664 | if (!blocked) { |
691 | if (dev) { | 665 | dev = pci_get_slot(bus, 0); |
692 | pci_remove_bus_device(dev); | 666 | if (dev) { |
693 | pci_dev_put(dev); | 667 | /* Device already present */ |
668 | pci_dev_put(dev); | ||
669 | goto out_unlock; | ||
670 | } | ||
671 | dev = pci_scan_single_device(bus, 0); | ||
672 | if (dev) { | ||
673 | pci_bus_assign_resources(bus); | ||
674 | if (pci_bus_add_device(dev)) | ||
675 | pr_err("Unable to hotplug wifi\n"); | ||
676 | } | ||
677 | } else { | ||
678 | dev = pci_get_slot(bus, 0); | ||
679 | if (dev) { | ||
680 | pci_remove_bus_device(dev); | ||
681 | pci_dev_put(dev); | ||
682 | } | ||
694 | } | 683 | } |
695 | } | 684 | } |
696 | 685 | ||
697 | rfkill_set_sw_state(ehotk->wlan_rfkill, blocked); | 686 | out_unlock: |
687 | mutex_unlock(&ehotk->hotplug_lock); | ||
698 | } | 688 | } |
699 | 689 | ||
700 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | 690 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) |
@@ -702,7 +692,7 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | |||
702 | if (event != ACPI_NOTIFY_BUS_CHECK) | 692 | if (event != ACPI_NOTIFY_BUS_CHECK) |
703 | return; | 693 | return; |
704 | 694 | ||
705 | schedule_work(&ehotk->hotplug_work); | 695 | eeepc_rfkill_hotplug(); |
706 | } | 696 | } |
707 | 697 | ||
708 | static void eeepc_hotk_notify(struct acpi_device *device, u32 event) | 698 | static void eeepc_hotk_notify(struct acpi_device *device, u32 event) |
@@ -839,66 +829,38 @@ error_slot: | |||
839 | return ret; | 829 | return ret; |
840 | } | 830 | } |
841 | 831 | ||
842 | static int eeepc_hotk_add(struct acpi_device *device) | 832 | static int eeepc_hotk_thaw(struct device *device) |
843 | { | ||
844 | int result; | ||
845 | |||
846 | if (!device) | ||
847 | return -EINVAL; | ||
848 | pr_notice(EEEPC_HOTK_NAME "\n"); | ||
849 | ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL); | ||
850 | if (!ehotk) | ||
851 | return -ENOMEM; | ||
852 | ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH; | ||
853 | ehotk->handle = device->handle; | ||
854 | strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME); | ||
855 | strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS); | ||
856 | device->driver_data = ehotk; | ||
857 | ehotk->device = device; | ||
858 | result = eeepc_hotk_check(); | ||
859 | if (result) | ||
860 | goto ehotk_fail; | ||
861 | |||
862 | return 0; | ||
863 | |||
864 | ehotk_fail: | ||
865 | kfree(ehotk); | ||
866 | ehotk = NULL; | ||
867 | |||
868 | return result; | ||
869 | } | ||
870 | |||
871 | static int eeepc_hotk_remove(struct acpi_device *device, int type) | ||
872 | { | ||
873 | if (!device || !acpi_driver_data(device)) | ||
874 | return -EINVAL; | ||
875 | |||
876 | kfree(ehotk); | ||
877 | return 0; | ||
878 | } | ||
879 | |||
880 | static int eeepc_hotk_resume(struct acpi_device *device) | ||
881 | { | 833 | { |
882 | if (ehotk->wlan_rfkill) { | 834 | if (ehotk->wlan_rfkill) { |
883 | bool wlan; | 835 | bool wlan; |
884 | 836 | ||
885 | /* Workaround - it seems that _PTS disables the wireless | 837 | /* |
886 | without notification or changing the value read by WLAN. | 838 | * Work around bios bug - acpi _PTS turns off the wireless led |
887 | Normally this is fine because the correct value is restored | 839 | * during suspend. Normally it restores it on resume, but |
888 | from the non-volatile storage on resume, but we need to do | 840 | * we should kick it ourselves in case hibernation is aborted. |
889 | it ourself if case suspend is aborted, or we lose wireless. | ||
890 | */ | 841 | */ |
891 | wlan = get_acpi(CM_ASL_WLAN); | 842 | wlan = get_acpi(CM_ASL_WLAN); |
892 | set_acpi(CM_ASL_WLAN, wlan); | 843 | set_acpi(CM_ASL_WLAN, wlan); |
844 | } | ||
893 | 845 | ||
894 | rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1); | 846 | return 0; |
847 | } | ||
895 | 848 | ||
896 | schedule_work(&ehotk->hotplug_work); | 849 | static int eeepc_hotk_restore(struct device *device) |
897 | } | 850 | { |
851 | /* Refresh both wlan rfkill state and pci hotplug */ | ||
852 | if (ehotk->wlan_rfkill) | ||
853 | eeepc_rfkill_hotplug(); | ||
898 | 854 | ||
899 | if (ehotk->bluetooth_rfkill) | 855 | if (ehotk->bluetooth_rfkill) |
900 | rfkill_set_sw_state(ehotk->bluetooth_rfkill, | 856 | rfkill_set_sw_state(ehotk->bluetooth_rfkill, |
901 | get_acpi(CM_ASL_BLUETOOTH) != 1); | 857 | get_acpi(CM_ASL_BLUETOOTH) != 1); |
858 | if (ehotk->wwan3g_rfkill) | ||
859 | rfkill_set_sw_state(ehotk->wwan3g_rfkill, | ||
860 | get_acpi(CM_ASL_3G) != 1); | ||
861 | if (ehotk->wimax_rfkill) | ||
862 | rfkill_set_sw_state(ehotk->wimax_rfkill, | ||
863 | get_acpi(CM_ASL_WIMAX) != 1); | ||
902 | 864 | ||
903 | return 0; | 865 | return 0; |
904 | } | 866 | } |
@@ -1019,16 +981,37 @@ static void eeepc_backlight_exit(void) | |||
1019 | 981 | ||
1020 | static void eeepc_rfkill_exit(void) | 982 | static void eeepc_rfkill_exit(void) |
1021 | { | 983 | { |
984 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P5"); | ||
1022 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); | 985 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); |
1023 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); | 986 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); |
1024 | if (ehotk->wlan_rfkill) | 987 | if (ehotk->wlan_rfkill) { |
1025 | rfkill_unregister(ehotk->wlan_rfkill); | 988 | rfkill_unregister(ehotk->wlan_rfkill); |
1026 | if (ehotk->bluetooth_rfkill) | 989 | rfkill_destroy(ehotk->wlan_rfkill); |
1027 | rfkill_unregister(ehotk->bluetooth_rfkill); | 990 | ehotk->wlan_rfkill = NULL; |
1028 | if (ehotk->wwan3g_rfkill) | 991 | } |
1029 | rfkill_unregister(ehotk->wwan3g_rfkill); | 992 | /* |
993 | * Refresh pci hotplug in case the rfkill state was changed after | ||
994 | * eeepc_unregister_rfkill_notifier() | ||
995 | */ | ||
996 | eeepc_rfkill_hotplug(); | ||
1030 | if (ehotk->hotplug_slot) | 997 | if (ehotk->hotplug_slot) |
1031 | pci_hp_deregister(ehotk->hotplug_slot); | 998 | pci_hp_deregister(ehotk->hotplug_slot); |
999 | |||
1000 | if (ehotk->bluetooth_rfkill) { | ||
1001 | rfkill_unregister(ehotk->bluetooth_rfkill); | ||
1002 | rfkill_destroy(ehotk->bluetooth_rfkill); | ||
1003 | ehotk->bluetooth_rfkill = NULL; | ||
1004 | } | ||
1005 | if (ehotk->wwan3g_rfkill) { | ||
1006 | rfkill_unregister(ehotk->wwan3g_rfkill); | ||
1007 | rfkill_destroy(ehotk->wwan3g_rfkill); | ||
1008 | ehotk->wwan3g_rfkill = NULL; | ||
1009 | } | ||
1010 | if (ehotk->wimax_rfkill) { | ||
1011 | rfkill_unregister(ehotk->wimax_rfkill); | ||
1012 | rfkill_destroy(ehotk->wimax_rfkill); | ||
1013 | ehotk->wimax_rfkill = NULL; | ||
1014 | } | ||
1032 | } | 1015 | } |
1033 | 1016 | ||
1034 | static void eeepc_input_exit(void) | 1017 | static void eeepc_input_exit(void) |
@@ -1050,19 +1033,6 @@ static void eeepc_hwmon_exit(void) | |||
1050 | eeepc_hwmon_device = NULL; | 1033 | eeepc_hwmon_device = NULL; |
1051 | } | 1034 | } |
1052 | 1035 | ||
1053 | static void __exit eeepc_laptop_exit(void) | ||
1054 | { | ||
1055 | eeepc_backlight_exit(); | ||
1056 | eeepc_rfkill_exit(); | ||
1057 | eeepc_input_exit(); | ||
1058 | eeepc_hwmon_exit(); | ||
1059 | acpi_bus_unregister_driver(&eeepc_hotk_driver); | ||
1060 | sysfs_remove_group(&platform_device->dev.kobj, | ||
1061 | &platform_attribute_group); | ||
1062 | platform_device_unregister(platform_device); | ||
1063 | platform_driver_unregister(&platform_driver); | ||
1064 | } | ||
1065 | |||
1066 | static int eeepc_new_rfkill(struct rfkill **rfkill, | 1036 | static int eeepc_new_rfkill(struct rfkill **rfkill, |
1067 | const char *name, struct device *dev, | 1037 | const char *name, struct device *dev, |
1068 | enum rfkill_type type, int cm) | 1038 | enum rfkill_type type, int cm) |
@@ -1094,10 +1064,7 @@ static int eeepc_rfkill_init(struct device *dev) | |||
1094 | { | 1064 | { |
1095 | int result = 0; | 1065 | int result = 0; |
1096 | 1066 | ||
1097 | INIT_WORK(&ehotk->hotplug_work, eeepc_hotplug_work); | 1067 | mutex_init(&ehotk->hotplug_lock); |
1098 | |||
1099 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
1100 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
1101 | 1068 | ||
1102 | result = eeepc_new_rfkill(&ehotk->wlan_rfkill, | 1069 | result = eeepc_new_rfkill(&ehotk->wlan_rfkill, |
1103 | "eeepc-wlan", dev, | 1070 | "eeepc-wlan", dev, |
@@ -1120,6 +1087,13 @@ static int eeepc_rfkill_init(struct device *dev) | |||
1120 | if (result && result != -ENODEV) | 1087 | if (result && result != -ENODEV) |
1121 | goto exit; | 1088 | goto exit; |
1122 | 1089 | ||
1090 | result = eeepc_new_rfkill(&ehotk->wimax_rfkill, | ||
1091 | "eeepc-wimax", dev, | ||
1092 | RFKILL_TYPE_WIMAX, CM_ASL_WIMAX); | ||
1093 | |||
1094 | if (result && result != -ENODEV) | ||
1095 | goto exit; | ||
1096 | |||
1123 | result = eeepc_setup_pci_hotplug(); | 1097 | result = eeepc_setup_pci_hotplug(); |
1124 | /* | 1098 | /* |
1125 | * If we get -EBUSY then something else is handling the PCI hotplug - | 1099 | * If we get -EBUSY then something else is handling the PCI hotplug - |
@@ -1128,6 +1102,15 @@ static int eeepc_rfkill_init(struct device *dev) | |||
1128 | if (result == -EBUSY) | 1102 | if (result == -EBUSY) |
1129 | result = 0; | 1103 | result = 0; |
1130 | 1104 | ||
1105 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P5"); | ||
1106 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
1107 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
1108 | /* | ||
1109 | * Refresh pci hotplug in case the rfkill state was changed during | ||
1110 | * setup. | ||
1111 | */ | ||
1112 | eeepc_rfkill_hotplug(); | ||
1113 | |||
1131 | exit: | 1114 | exit: |
1132 | if (result && result != -ENODEV) | 1115 | if (result && result != -ENODEV) |
1133 | eeepc_rfkill_exit(); | 1116 | eeepc_rfkill_exit(); |
@@ -1172,21 +1155,61 @@ static int eeepc_hwmon_init(struct device *dev) | |||
1172 | return result; | 1155 | return result; |
1173 | } | 1156 | } |
1174 | 1157 | ||
1175 | static int __init eeepc_laptop_init(void) | 1158 | static int eeepc_input_init(struct device *dev) |
1176 | { | 1159 | { |
1177 | struct device *dev; | 1160 | const struct key_entry *key; |
1178 | int result; | 1161 | int result; |
1179 | 1162 | ||
1180 | if (acpi_disabled) | 1163 | ehotk->inputdev = input_allocate_device(); |
1181 | return -ENODEV; | 1164 | if (!ehotk->inputdev) { |
1182 | result = acpi_bus_register_driver(&eeepc_hotk_driver); | 1165 | pr_info("Unable to allocate input device\n"); |
1183 | if (result < 0) | 1166 | return -ENOMEM; |
1167 | } | ||
1168 | ehotk->inputdev->name = "Asus EeePC extra buttons"; | ||
1169 | ehotk->inputdev->dev.parent = dev; | ||
1170 | ehotk->inputdev->phys = EEEPC_HOTK_FILE "/input0"; | ||
1171 | ehotk->inputdev->id.bustype = BUS_HOST; | ||
1172 | ehotk->inputdev->getkeycode = eeepc_getkeycode; | ||
1173 | ehotk->inputdev->setkeycode = eeepc_setkeycode; | ||
1174 | |||
1175 | for (key = eeepc_keymap; key->type != KE_END; key++) { | ||
1176 | switch (key->type) { | ||
1177 | case KE_KEY: | ||
1178 | set_bit(EV_KEY, ehotk->inputdev->evbit); | ||
1179 | set_bit(key->keycode, ehotk->inputdev->keybit); | ||
1180 | break; | ||
1181 | } | ||
1182 | } | ||
1183 | result = input_register_device(ehotk->inputdev); | ||
1184 | if (result) { | ||
1185 | pr_info("Unable to register input device\n"); | ||
1186 | input_free_device(ehotk->inputdev); | ||
1184 | return result; | 1187 | return result; |
1185 | if (!ehotk) { | ||
1186 | acpi_bus_unregister_driver(&eeepc_hotk_driver); | ||
1187 | return -ENODEV; | ||
1188 | } | 1188 | } |
1189 | return 0; | ||
1190 | } | ||
1191 | |||
1192 | static int eeepc_hotk_add(struct acpi_device *device) | ||
1193 | { | ||
1194 | struct device *dev; | ||
1195 | int result; | ||
1189 | 1196 | ||
1197 | if (!device) | ||
1198 | return -EINVAL; | ||
1199 | pr_notice(EEEPC_HOTK_NAME "\n"); | ||
1200 | ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL); | ||
1201 | if (!ehotk) | ||
1202 | return -ENOMEM; | ||
1203 | ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH; | ||
1204 | ehotk->handle = device->handle; | ||
1205 | strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME); | ||
1206 | strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS); | ||
1207 | device->driver_data = ehotk; | ||
1208 | ehotk->device = device; | ||
1209 | |||
1210 | result = eeepc_hotk_check(); | ||
1211 | if (result) | ||
1212 | goto fail_platform_driver; | ||
1190 | eeepc_enable_camera(); | 1213 | eeepc_enable_camera(); |
1191 | 1214 | ||
1192 | /* Register platform stuff */ | 1215 | /* Register platform stuff */ |
@@ -1216,6 +1239,10 @@ static int __init eeepc_laptop_init(void) | |||
1216 | pr_info("Backlight controlled by ACPI video " | 1239 | pr_info("Backlight controlled by ACPI video " |
1217 | "driver\n"); | 1240 | "driver\n"); |
1218 | 1241 | ||
1242 | result = eeepc_input_init(dev); | ||
1243 | if (result) | ||
1244 | goto fail_input; | ||
1245 | |||
1219 | result = eeepc_hwmon_init(dev); | 1246 | result = eeepc_hwmon_init(dev); |
1220 | if (result) | 1247 | if (result) |
1221 | goto fail_hwmon; | 1248 | goto fail_hwmon; |
@@ -1225,9 +1252,12 @@ static int __init eeepc_laptop_init(void) | |||
1225 | goto fail_rfkill; | 1252 | goto fail_rfkill; |
1226 | 1253 | ||
1227 | return 0; | 1254 | return 0; |
1255 | |||
1228 | fail_rfkill: | 1256 | fail_rfkill: |
1229 | eeepc_hwmon_exit(); | 1257 | eeepc_hwmon_exit(); |
1230 | fail_hwmon: | 1258 | fail_hwmon: |
1259 | eeepc_input_exit(); | ||
1260 | fail_input: | ||
1231 | eeepc_backlight_exit(); | 1261 | eeepc_backlight_exit(); |
1232 | fail_backlight: | 1262 | fail_backlight: |
1233 | sysfs_remove_group(&platform_device->dev.kobj, | 1263 | sysfs_remove_group(&platform_device->dev.kobj, |
@@ -1239,9 +1269,49 @@ fail_platform_device2: | |||
1239 | fail_platform_device1: | 1269 | fail_platform_device1: |
1240 | platform_driver_unregister(&platform_driver); | 1270 | platform_driver_unregister(&platform_driver); |
1241 | fail_platform_driver: | 1271 | fail_platform_driver: |
1242 | eeepc_input_exit(); | 1272 | kfree(ehotk); |
1273 | |||
1243 | return result; | 1274 | return result; |
1244 | } | 1275 | } |
1245 | 1276 | ||
1277 | static int eeepc_hotk_remove(struct acpi_device *device, int type) | ||
1278 | { | ||
1279 | if (!device || !acpi_driver_data(device)) | ||
1280 | return -EINVAL; | ||
1281 | |||
1282 | eeepc_backlight_exit(); | ||
1283 | eeepc_rfkill_exit(); | ||
1284 | eeepc_input_exit(); | ||
1285 | eeepc_hwmon_exit(); | ||
1286 | sysfs_remove_group(&platform_device->dev.kobj, | ||
1287 | &platform_attribute_group); | ||
1288 | platform_device_unregister(platform_device); | ||
1289 | platform_driver_unregister(&platform_driver); | ||
1290 | |||
1291 | kfree(ehotk); | ||
1292 | return 0; | ||
1293 | } | ||
1294 | |||
1295 | static int __init eeepc_laptop_init(void) | ||
1296 | { | ||
1297 | int result; | ||
1298 | |||
1299 | if (acpi_disabled) | ||
1300 | return -ENODEV; | ||
1301 | result = acpi_bus_register_driver(&eeepc_hotk_driver); | ||
1302 | if (result < 0) | ||
1303 | return result; | ||
1304 | if (!ehotk) { | ||
1305 | acpi_bus_unregister_driver(&eeepc_hotk_driver); | ||
1306 | return -ENODEV; | ||
1307 | } | ||
1308 | return 0; | ||
1309 | } | ||
1310 | |||
1311 | static void __exit eeepc_laptop_exit(void) | ||
1312 | { | ||
1313 | acpi_bus_unregister_driver(&eeepc_hotk_driver); | ||
1314 | } | ||
1315 | |||
1246 | module_init(eeepc_laptop_init); | 1316 | module_init(eeepc_laptop_init); |
1247 | module_exit(eeepc_laptop_exit); | 1317 | module_exit(eeepc_laptop_exit); |
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 218b9a16ac3f..f35aee5c2149 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c | |||
@@ -66,11 +66,11 @@ | |||
66 | #include <linux/kfifo.h> | 66 | #include <linux/kfifo.h> |
67 | #include <linux/video_output.h> | 67 | #include <linux/video_output.h> |
68 | #include <linux/platform_device.h> | 68 | #include <linux/platform_device.h> |
69 | #ifdef CONFIG_LEDS_CLASS | 69 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) |
70 | #include <linux/leds.h> | 70 | #include <linux/leds.h> |
71 | #endif | 71 | #endif |
72 | 72 | ||
73 | #define FUJITSU_DRIVER_VERSION "0.5.0" | 73 | #define FUJITSU_DRIVER_VERSION "0.6.0" |
74 | 74 | ||
75 | #define FUJITSU_LCD_N_LEVELS 8 | 75 | #define FUJITSU_LCD_N_LEVELS 8 |
76 | 76 | ||
@@ -96,7 +96,7 @@ | |||
96 | /* FUNC interface - responses */ | 96 | /* FUNC interface - responses */ |
97 | #define UNSUPPORTED_CMD 0x80000000 | 97 | #define UNSUPPORTED_CMD 0x80000000 |
98 | 98 | ||
99 | #ifdef CONFIG_LEDS_CLASS | 99 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) |
100 | /* FUNC interface - LED control */ | 100 | /* FUNC interface - LED control */ |
101 | #define FUNC_LED_OFF 0x1 | 101 | #define FUNC_LED_OFF 0x1 |
102 | #define FUNC_LED_ON 0x30001 | 102 | #define FUNC_LED_ON 0x30001 |
@@ -176,7 +176,7 @@ static struct fujitsu_hotkey_t *fujitsu_hotkey; | |||
176 | 176 | ||
177 | static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event); | 177 | static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event); |
178 | 178 | ||
179 | #ifdef CONFIG_LEDS_CLASS | 179 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) |
180 | static enum led_brightness logolamp_get(struct led_classdev *cdev); | 180 | static enum led_brightness logolamp_get(struct led_classdev *cdev); |
181 | static void logolamp_set(struct led_classdev *cdev, | 181 | static void logolamp_set(struct led_classdev *cdev, |
182 | enum led_brightness brightness); | 182 | enum led_brightness brightness); |
@@ -257,7 +257,7 @@ static int call_fext_func(int cmd, int arg0, int arg1, int arg2) | |||
257 | return out_obj.integer.value; | 257 | return out_obj.integer.value; |
258 | } | 258 | } |
259 | 259 | ||
260 | #ifdef CONFIG_LEDS_CLASS | 260 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) |
261 | /* LED class callbacks */ | 261 | /* LED class callbacks */ |
262 | 262 | ||
263 | static void logolamp_set(struct led_classdev *cdev, | 263 | static void logolamp_set(struct led_classdev *cdev, |
@@ -324,9 +324,6 @@ static int set_lcd_level(int level) | |||
324 | if (level < 0 || level >= fujitsu->max_brightness) | 324 | if (level < 0 || level >= fujitsu->max_brightness) |
325 | return -EINVAL; | 325 | return -EINVAL; |
326 | 326 | ||
327 | if (!fujitsu) | ||
328 | return -EINVAL; | ||
329 | |||
330 | status = acpi_get_handle(fujitsu->acpi_handle, "SBLL", &handle); | 327 | status = acpi_get_handle(fujitsu->acpi_handle, "SBLL", &handle); |
331 | if (ACPI_FAILURE(status)) { | 328 | if (ACPI_FAILURE(status)) { |
332 | vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBLL not present\n"); | 329 | vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBLL not present\n"); |
@@ -355,9 +352,6 @@ static int set_lcd_level_alt(int level) | |||
355 | if (level < 0 || level >= fujitsu->max_brightness) | 352 | if (level < 0 || level >= fujitsu->max_brightness) |
356 | return -EINVAL; | 353 | return -EINVAL; |
357 | 354 | ||
358 | if (!fujitsu) | ||
359 | return -EINVAL; | ||
360 | |||
361 | status = acpi_get_handle(fujitsu->acpi_handle, "SBL2", &handle); | 355 | status = acpi_get_handle(fujitsu->acpi_handle, "SBL2", &handle); |
362 | if (ACPI_FAILURE(status)) { | 356 | if (ACPI_FAILURE(status)) { |
363 | vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBL2 not present\n"); | 357 | vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBL2 not present\n"); |
@@ -697,10 +691,10 @@ static int acpi_fujitsu_add(struct acpi_device *device) | |||
697 | result = acpi_bus_get_power(fujitsu->acpi_handle, &state); | 691 | result = acpi_bus_get_power(fujitsu->acpi_handle, &state); |
698 | if (result) { | 692 | if (result) { |
699 | printk(KERN_ERR "Error reading power state\n"); | 693 | printk(KERN_ERR "Error reading power state\n"); |
700 | goto end; | 694 | goto err_unregister_input_dev; |
701 | } | 695 | } |
702 | 696 | ||
703 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", | 697 | printk(KERN_INFO "ACPI: %s [%s] (%s)\n", |
704 | acpi_device_name(device), acpi_device_bid(device), | 698 | acpi_device_name(device), acpi_device_bid(device), |
705 | !device->power.state ? "on" : "off"); | 699 | !device->power.state ? "on" : "off"); |
706 | 700 | ||
@@ -728,25 +722,22 @@ static int acpi_fujitsu_add(struct acpi_device *device) | |||
728 | 722 | ||
729 | return result; | 723 | return result; |
730 | 724 | ||
731 | end: | 725 | err_unregister_input_dev: |
726 | input_unregister_device(input); | ||
732 | err_free_input_dev: | 727 | err_free_input_dev: |
733 | input_free_device(input); | 728 | input_free_device(input); |
734 | err_stop: | 729 | err_stop: |
735 | |||
736 | return result; | 730 | return result; |
737 | } | 731 | } |
738 | 732 | ||
739 | static int acpi_fujitsu_remove(struct acpi_device *device, int type) | 733 | static int acpi_fujitsu_remove(struct acpi_device *device, int type) |
740 | { | 734 | { |
741 | struct fujitsu_t *fujitsu = NULL; | 735 | struct fujitsu_t *fujitsu = acpi_driver_data(device); |
736 | struct input_dev *input = fujitsu->input; | ||
742 | 737 | ||
743 | if (!device || !acpi_driver_data(device)) | 738 | input_unregister_device(input); |
744 | return -EINVAL; | ||
745 | 739 | ||
746 | fujitsu = acpi_driver_data(device); | 740 | input_free_device(input); |
747 | |||
748 | if (!device || !acpi_driver_data(device)) | ||
749 | return -EINVAL; | ||
750 | 741 | ||
751 | fujitsu->acpi_handle = NULL; | 742 | fujitsu->acpi_handle = NULL; |
752 | 743 | ||
@@ -871,10 +862,10 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
871 | result = acpi_bus_get_power(fujitsu_hotkey->acpi_handle, &state); | 862 | result = acpi_bus_get_power(fujitsu_hotkey->acpi_handle, &state); |
872 | if (result) { | 863 | if (result) { |
873 | printk(KERN_ERR "Error reading power state\n"); | 864 | printk(KERN_ERR "Error reading power state\n"); |
874 | goto end; | 865 | goto err_unregister_input_dev; |
875 | } | 866 | } |
876 | 867 | ||
877 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", | 868 | printk(KERN_INFO "ACPI: %s [%s] (%s)\n", |
878 | acpi_device_name(device), acpi_device_bid(device), | 869 | acpi_device_name(device), acpi_device_bid(device), |
879 | !device->power.state ? "on" : "off"); | 870 | !device->power.state ? "on" : "off"); |
880 | 871 | ||
@@ -911,7 +902,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
911 | printk(KERN_INFO "fujitsu-laptop: BTNI: [0x%x]\n", | 902 | printk(KERN_INFO "fujitsu-laptop: BTNI: [0x%x]\n", |
912 | call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0)); | 903 | call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0)); |
913 | 904 | ||
914 | #ifdef CONFIG_LEDS_CLASS | 905 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) |
915 | if (call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) { | 906 | if (call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) { |
916 | result = led_classdev_register(&fujitsu->pf_device->dev, | 907 | result = led_classdev_register(&fujitsu->pf_device->dev, |
917 | &logolamp_led); | 908 | &logolamp_led); |
@@ -934,33 +925,41 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
934 | "LED handler for keyboard lamps, error %i\n", result); | 925 | "LED handler for keyboard lamps, error %i\n", result); |
935 | } | 926 | } |
936 | } | 927 | } |
937 | #endif | 928 | #endif |
938 | 929 | ||
939 | return result; | 930 | return result; |
940 | 931 | ||
941 | end: | 932 | err_unregister_input_dev: |
933 | input_unregister_device(input); | ||
942 | err_free_input_dev: | 934 | err_free_input_dev: |
943 | input_free_device(input); | 935 | input_free_device(input); |
944 | err_free_fifo: | 936 | err_free_fifo: |
945 | kfifo_free(fujitsu_hotkey->fifo); | 937 | kfifo_free(fujitsu_hotkey->fifo); |
946 | err_stop: | 938 | err_stop: |
947 | |||
948 | return result; | 939 | return result; |
949 | } | 940 | } |
950 | 941 | ||
951 | static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type) | 942 | static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type) |
952 | { | 943 | { |
953 | struct fujitsu_hotkey_t *fujitsu_hotkey = NULL; | 944 | struct fujitsu_hotkey_t *fujitsu_hotkey = acpi_driver_data(device); |
945 | struct input_dev *input = fujitsu_hotkey->input; | ||
954 | 946 | ||
955 | if (!device || !acpi_driver_data(device)) | 947 | #ifdef CONFIG_LEDS_CLASS |
956 | return -EINVAL; | 948 | if (fujitsu_hotkey->logolamp_registered) |
949 | led_classdev_unregister(&logolamp_led); | ||
957 | 950 | ||
958 | fujitsu_hotkey = acpi_driver_data(device); | 951 | if (fujitsu_hotkey->kblamps_registered) |
952 | led_classdev_unregister(&kblamps_led); | ||
953 | #endif | ||
959 | 954 | ||
960 | fujitsu_hotkey->acpi_handle = NULL; | 955 | input_unregister_device(input); |
956 | |||
957 | input_free_device(input); | ||
961 | 958 | ||
962 | kfifo_free(fujitsu_hotkey->fifo); | 959 | kfifo_free(fujitsu_hotkey->fifo); |
963 | 960 | ||
961 | fujitsu_hotkey->acpi_handle = NULL; | ||
962 | |||
964 | return 0; | 963 | return 0; |
965 | } | 964 | } |
966 | 965 | ||
@@ -1130,8 +1129,11 @@ static int __init fujitsu_init(void) | |||
1130 | fujitsu->bl_device = | 1129 | fujitsu->bl_device = |
1131 | backlight_device_register("fujitsu-laptop", NULL, NULL, | 1130 | backlight_device_register("fujitsu-laptop", NULL, NULL, |
1132 | &fujitsubl_ops); | 1131 | &fujitsubl_ops); |
1133 | if (IS_ERR(fujitsu->bl_device)) | 1132 | if (IS_ERR(fujitsu->bl_device)) { |
1134 | return PTR_ERR(fujitsu->bl_device); | 1133 | ret = PTR_ERR(fujitsu->bl_device); |
1134 | fujitsu->bl_device = NULL; | ||
1135 | goto fail_sysfs_group; | ||
1136 | } | ||
1135 | max_brightness = fujitsu->max_brightness; | 1137 | max_brightness = fujitsu->max_brightness; |
1136 | fujitsu->bl_device->props.max_brightness = max_brightness - 1; | 1138 | fujitsu->bl_device->props.max_brightness = max_brightness - 1; |
1137 | fujitsu->bl_device->props.brightness = fujitsu->brightness_level; | 1139 | fujitsu->bl_device->props.brightness = fujitsu->brightness_level; |
@@ -1171,32 +1173,22 @@ static int __init fujitsu_init(void) | |||
1171 | return 0; | 1173 | return 0; |
1172 | 1174 | ||
1173 | fail_hotkey1: | 1175 | fail_hotkey1: |
1174 | |||
1175 | kfree(fujitsu_hotkey); | 1176 | kfree(fujitsu_hotkey); |
1176 | |||
1177 | fail_hotkey: | 1177 | fail_hotkey: |
1178 | |||
1179 | platform_driver_unregister(&fujitsupf_driver); | 1178 | platform_driver_unregister(&fujitsupf_driver); |
1180 | |||
1181 | fail_backlight: | 1179 | fail_backlight: |
1182 | |||
1183 | if (fujitsu->bl_device) | 1180 | if (fujitsu->bl_device) |
1184 | backlight_device_unregister(fujitsu->bl_device); | 1181 | backlight_device_unregister(fujitsu->bl_device); |
1185 | 1182 | fail_sysfs_group: | |
1183 | sysfs_remove_group(&fujitsu->pf_device->dev.kobj, | ||
1184 | &fujitsupf_attribute_group); | ||
1186 | fail_platform_device2: | 1185 | fail_platform_device2: |
1187 | |||
1188 | platform_device_del(fujitsu->pf_device); | 1186 | platform_device_del(fujitsu->pf_device); |
1189 | |||
1190 | fail_platform_device1: | 1187 | fail_platform_device1: |
1191 | |||
1192 | platform_device_put(fujitsu->pf_device); | 1188 | platform_device_put(fujitsu->pf_device); |
1193 | |||
1194 | fail_platform_driver: | 1189 | fail_platform_driver: |
1195 | |||
1196 | acpi_bus_unregister_driver(&acpi_fujitsu_driver); | 1190 | acpi_bus_unregister_driver(&acpi_fujitsu_driver); |
1197 | |||
1198 | fail_acpi: | 1191 | fail_acpi: |
1199 | |||
1200 | kfree(fujitsu); | 1192 | kfree(fujitsu); |
1201 | 1193 | ||
1202 | return ret; | 1194 | return ret; |
@@ -1204,28 +1196,23 @@ fail_acpi: | |||
1204 | 1196 | ||
1205 | static void __exit fujitsu_cleanup(void) | 1197 | static void __exit fujitsu_cleanup(void) |
1206 | { | 1198 | { |
1207 | #ifdef CONFIG_LEDS_CLASS | 1199 | acpi_bus_unregister_driver(&acpi_fujitsu_hotkey_driver); |
1208 | if (fujitsu_hotkey->logolamp_registered != 0) | ||
1209 | led_classdev_unregister(&logolamp_led); | ||
1210 | 1200 | ||
1211 | if (fujitsu_hotkey->kblamps_registered != 0) | 1201 | kfree(fujitsu_hotkey); |
1212 | led_classdev_unregister(&kblamps_led); | ||
1213 | #endif | ||
1214 | 1202 | ||
1215 | sysfs_remove_group(&fujitsu->pf_device->dev.kobj, | ||
1216 | &fujitsupf_attribute_group); | ||
1217 | platform_device_unregister(fujitsu->pf_device); | ||
1218 | platform_driver_unregister(&fujitsupf_driver); | 1203 | platform_driver_unregister(&fujitsupf_driver); |
1204 | |||
1219 | if (fujitsu->bl_device) | 1205 | if (fujitsu->bl_device) |
1220 | backlight_device_unregister(fujitsu->bl_device); | 1206 | backlight_device_unregister(fujitsu->bl_device); |
1221 | 1207 | ||
1222 | acpi_bus_unregister_driver(&acpi_fujitsu_driver); | 1208 | sysfs_remove_group(&fujitsu->pf_device->dev.kobj, |
1209 | &fujitsupf_attribute_group); | ||
1223 | 1210 | ||
1224 | kfree(fujitsu); | 1211 | platform_device_unregister(fujitsu->pf_device); |
1225 | 1212 | ||
1226 | acpi_bus_unregister_driver(&acpi_fujitsu_hotkey_driver); | 1213 | acpi_bus_unregister_driver(&acpi_fujitsu_driver); |
1227 | 1214 | ||
1228 | kfree(fujitsu_hotkey); | 1215 | kfree(fujitsu); |
1229 | 1216 | ||
1230 | printk(KERN_INFO "fujitsu-laptop: driver unloaded.\n"); | 1217 | printk(KERN_INFO "fujitsu-laptop: driver unloaded.\n"); |
1231 | } | 1218 | } |
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index af04f5b049db..c2842171cec6 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
@@ -507,7 +507,7 @@ static int __exit hp_wmi_bios_remove(struct platform_device *device) | |||
507 | } | 507 | } |
508 | if (bluetooth_rfkill) { | 508 | if (bluetooth_rfkill) { |
509 | rfkill_unregister(bluetooth_rfkill); | 509 | rfkill_unregister(bluetooth_rfkill); |
510 | rfkill_destroy(wifi_rfkill); | 510 | rfkill_destroy(bluetooth_rfkill); |
511 | } | 511 | } |
512 | if (wwan_rfkill) { | 512 | if (wwan_rfkill) { |
513 | rfkill_unregister(wwan_rfkill); | 513 | rfkill_unregister(wwan_rfkill); |
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index dafaa4a92df5..f9f68e0e7344 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -976,15 +976,12 @@ static acpi_status sony_walk_callback(acpi_handle handle, u32 level, | |||
976 | void *context, void **return_value) | 976 | void *context, void **return_value) |
977 | { | 977 | { |
978 | struct acpi_device_info *info; | 978 | struct acpi_device_info *info; |
979 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
980 | |||
981 | if (ACPI_SUCCESS(acpi_get_object_info(handle, &buffer))) { | ||
982 | info = buffer.pointer; | ||
983 | 979 | ||
980 | if (ACPI_SUCCESS(acpi_get_object_info(handle, &info))) { | ||
984 | printk(KERN_WARNING DRV_PFX "method: name: %4.4s, args %X\n", | 981 | printk(KERN_WARNING DRV_PFX "method: name: %4.4s, args %X\n", |
985 | (char *)&info->name, info->param_count); | 982 | (char *)&info->name, info->param_count); |
986 | 983 | ||
987 | kfree(buffer.pointer); | 984 | kfree(info); |
988 | } | 985 | } |
989 | 986 | ||
990 | return AE_OK; | 987 | return AE_OK; |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index e85600852502..f78d27503925 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -1278,6 +1278,7 @@ static void tpacpi_destroy_rfkill(const enum tpacpi_rfk_id id) | |||
1278 | tp_rfk = tpacpi_rfkill_switches[id]; | 1278 | tp_rfk = tpacpi_rfkill_switches[id]; |
1279 | if (tp_rfk) { | 1279 | if (tp_rfk) { |
1280 | rfkill_unregister(tp_rfk->rfkill); | 1280 | rfkill_unregister(tp_rfk->rfkill); |
1281 | rfkill_destroy(tp_rfk->rfkill); | ||
1281 | tpacpi_rfkill_switches[id] = NULL; | 1282 | tpacpi_rfkill_switches[id] = NULL; |
1282 | kfree(tp_rfk); | 1283 | kfree(tp_rfk); |
1283 | } | 1284 | } |
@@ -1601,6 +1602,196 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv) | |||
1601 | #endif | 1602 | #endif |
1602 | } | 1603 | } |
1603 | 1604 | ||
1605 | /************************************************************************* | ||
1606 | * Firmware Data | ||
1607 | */ | ||
1608 | |||
1609 | /* | ||
1610 | * Table of recommended minimum BIOS versions | ||
1611 | * | ||
1612 | * Reasons for listing: | ||
1613 | * 1. Stable BIOS, listed because the unknown ammount of | ||
1614 | * bugs and bad ACPI behaviour on older versions | ||
1615 | * | ||
1616 | * 2. BIOS or EC fw with known bugs that trigger on Linux | ||
1617 | * | ||
1618 | * 3. BIOS with known reduced functionality in older versions | ||
1619 | * | ||
1620 | * We recommend the latest BIOS and EC version. | ||
1621 | * We only support the latest BIOS and EC fw version as a rule. | ||
1622 | * | ||
1623 | * Sources: IBM ThinkPad Public Web Documents (update changelogs), | ||
1624 | * Information from users in ThinkWiki | ||
1625 | * | ||
1626 | * WARNING: we use this table also to detect that the machine is | ||
1627 | * a ThinkPad in some cases, so don't remove entries lightly. | ||
1628 | */ | ||
1629 | |||
1630 | #define TPV_Q(__v, __id1, __id2, __bv1, __bv2) \ | ||
1631 | { .vendor = (__v), \ | ||
1632 | .bios = TPID(__id1, __id2), \ | ||
1633 | .ec = TPACPI_MATCH_ANY, \ | ||
1634 | .quirks = TPACPI_MATCH_ANY << 16 \ | ||
1635 | | (__bv1) << 8 | (__bv2) } | ||
1636 | |||
1637 | #define TPV_Q_X(__v, __bid1, __bid2, __bv1, __bv2, \ | ||
1638 | __eid1, __eid2, __ev1, __ev2) \ | ||
1639 | { .vendor = (__v), \ | ||
1640 | .bios = TPID(__bid1, __bid2), \ | ||
1641 | .ec = TPID(__eid1, __eid2), \ | ||
1642 | .quirks = (__ev1) << 24 | (__ev2) << 16 \ | ||
1643 | | (__bv1) << 8 | (__bv2) } | ||
1644 | |||
1645 | #define TPV_QI0(__id1, __id2, __bv1, __bv2) \ | ||
1646 | TPV_Q(PCI_VENDOR_ID_IBM, __id1, __id2, __bv1, __bv2) | ||
1647 | |||
1648 | #define TPV_QI1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \ | ||
1649 | TPV_Q_X(PCI_VENDOR_ID_IBM, __id1, __id2, \ | ||
1650 | __bv1, __bv2, __id1, __id2, __ev1, __ev2) | ||
1651 | |||
1652 | #define TPV_QI2(__bid1, __bid2, __bv1, __bv2, \ | ||
1653 | __eid1, __eid2, __ev1, __ev2) \ | ||
1654 | TPV_Q_X(PCI_VENDOR_ID_IBM, __bid1, __bid2, \ | ||
1655 | __bv1, __bv2, __eid1, __eid2, __ev1, __ev2) | ||
1656 | |||
1657 | #define TPV_QL0(__id1, __id2, __bv1, __bv2) \ | ||
1658 | TPV_Q(PCI_VENDOR_ID_LENOVO, __id1, __id2, __bv1, __bv2) | ||
1659 | |||
1660 | #define TPV_QL1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \ | ||
1661 | TPV_Q_X(PCI_VENDOR_ID_LENOVO, __id1, __id2, \ | ||
1662 | __bv1, __bv2, __id1, __id2, __ev1, __ev2) | ||
1663 | |||
1664 | #define TPV_QL2(__bid1, __bid2, __bv1, __bv2, \ | ||
1665 | __eid1, __eid2, __ev1, __ev2) \ | ||
1666 | TPV_Q_X(PCI_VENDOR_ID_LENOVO, __bid1, __bid2, \ | ||
1667 | __bv1, __bv2, __eid1, __eid2, __ev1, __ev2) | ||
1668 | |||
1669 | static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = { | ||
1670 | /* Numeric models ------------------ */ | ||
1671 | /* FW MODEL BIOS VERS */ | ||
1672 | TPV_QI0('I', 'M', '6', '5'), /* 570 */ | ||
1673 | TPV_QI0('I', 'U', '2', '6'), /* 570E */ | ||
1674 | TPV_QI0('I', 'B', '5', '4'), /* 600 */ | ||
1675 | TPV_QI0('I', 'H', '4', '7'), /* 600E */ | ||
1676 | TPV_QI0('I', 'N', '3', '6'), /* 600E */ | ||
1677 | TPV_QI0('I', 'T', '5', '5'), /* 600X */ | ||
1678 | TPV_QI0('I', 'D', '4', '8'), /* 770, 770E, 770ED */ | ||
1679 | TPV_QI0('I', 'I', '4', '2'), /* 770X */ | ||
1680 | TPV_QI0('I', 'O', '2', '3'), /* 770Z */ | ||
1681 | |||
1682 | /* A-series ------------------------- */ | ||
1683 | /* FW MODEL BIOS VERS EC VERS */ | ||
1684 | TPV_QI0('I', 'W', '5', '9'), /* A20m */ | ||
1685 | TPV_QI0('I', 'V', '6', '9'), /* A20p */ | ||
1686 | TPV_QI0('1', '0', '2', '6'), /* A21e, A22e */ | ||
1687 | TPV_QI0('K', 'U', '3', '6'), /* A21e */ | ||
1688 | TPV_QI0('K', 'X', '3', '6'), /* A21m, A22m */ | ||
1689 | TPV_QI0('K', 'Y', '3', '8'), /* A21p, A22p */ | ||
1690 | TPV_QI0('1', 'B', '1', '7'), /* A22e */ | ||
1691 | TPV_QI0('1', '3', '2', '0'), /* A22m */ | ||
1692 | TPV_QI0('1', 'E', '7', '3'), /* A30/p (0) */ | ||
1693 | TPV_QI1('1', 'G', '4', '1', '1', '7'), /* A31/p (0) */ | ||
1694 | TPV_QI1('1', 'N', '1', '6', '0', '7'), /* A31/p (0) */ | ||
1695 | |||
1696 | /* G-series ------------------------- */ | ||
1697 | /* FW MODEL BIOS VERS */ | ||
1698 | TPV_QI0('1', 'T', 'A', '6'), /* G40 */ | ||
1699 | TPV_QI0('1', 'X', '5', '7'), /* G41 */ | ||
1700 | |||
1701 | /* R-series, T-series --------------- */ | ||
1702 | /* FW MODEL BIOS VERS EC VERS */ | ||
1703 | TPV_QI0('1', 'C', 'F', '0'), /* R30 */ | ||
1704 | TPV_QI0('1', 'F', 'F', '1'), /* R31 */ | ||
1705 | TPV_QI0('1', 'M', '9', '7'), /* R32 */ | ||
1706 | TPV_QI0('1', 'O', '6', '1'), /* R40 */ | ||
1707 | TPV_QI0('1', 'P', '6', '5'), /* R40 */ | ||
1708 | TPV_QI0('1', 'S', '7', '0'), /* R40e */ | ||
1709 | TPV_QI1('1', 'R', 'D', 'R', '7', '1'), /* R50/p, R51, | ||
1710 | T40/p, T41/p, T42/p (1) */ | ||
1711 | TPV_QI1('1', 'V', '7', '1', '2', '8'), /* R50e, R51 (1) */ | ||
1712 | TPV_QI1('7', '8', '7', '1', '0', '6'), /* R51e (1) */ | ||
1713 | TPV_QI1('7', '6', '6', '9', '1', '6'), /* R52 (1) */ | ||
1714 | TPV_QI1('7', '0', '6', '9', '2', '8'), /* R52, T43 (1) */ | ||
1715 | |||
1716 | TPV_QI0('I', 'Y', '6', '1'), /* T20 */ | ||
1717 | TPV_QI0('K', 'Z', '3', '4'), /* T21 */ | ||
1718 | TPV_QI0('1', '6', '3', '2'), /* T22 */ | ||
1719 | TPV_QI1('1', 'A', '6', '4', '2', '3'), /* T23 (0) */ | ||
1720 | TPV_QI1('1', 'I', '7', '1', '2', '0'), /* T30 (0) */ | ||
1721 | TPV_QI1('1', 'Y', '6', '5', '2', '9'), /* T43/p (1) */ | ||
1722 | |||
1723 | TPV_QL1('7', '9', 'E', '3', '5', '0'), /* T60/p */ | ||
1724 | TPV_QL1('7', 'C', 'D', '2', '2', '2'), /* R60, R60i */ | ||
1725 | TPV_QL0('7', 'E', 'D', '0'), /* R60e, R60i */ | ||
1726 | |||
1727 | /* BIOS FW BIOS VERS EC FW EC VERS */ | ||
1728 | TPV_QI2('1', 'W', '9', '0', '1', 'V', '2', '8'), /* R50e (1) */ | ||
1729 | TPV_QL2('7', 'I', '3', '4', '7', '9', '5', '0'), /* T60/p wide */ | ||
1730 | |||
1731 | /* X-series ------------------------- */ | ||
1732 | /* FW MODEL BIOS VERS EC VERS */ | ||
1733 | TPV_QI0('I', 'Z', '9', 'D'), /* X20, X21 */ | ||
1734 | TPV_QI0('1', 'D', '7', '0'), /* X22, X23, X24 */ | ||
1735 | TPV_QI1('1', 'K', '4', '8', '1', '8'), /* X30 (0) */ | ||
1736 | TPV_QI1('1', 'Q', '9', '7', '2', '3'), /* X31, X32 (0) */ | ||
1737 | TPV_QI1('1', 'U', 'D', '3', 'B', '2'), /* X40 (0) */ | ||
1738 | TPV_QI1('7', '4', '6', '4', '2', '7'), /* X41 (0) */ | ||
1739 | TPV_QI1('7', '5', '6', '0', '2', '0'), /* X41t (0) */ | ||
1740 | |||
1741 | TPV_QL0('7', 'B', 'D', '7'), /* X60/s */ | ||
1742 | TPV_QL0('7', 'J', '3', '0'), /* X60t */ | ||
1743 | |||
1744 | /* (0) - older versions lack DMI EC fw string and functionality */ | ||
1745 | /* (1) - older versions known to lack functionality */ | ||
1746 | }; | ||
1747 | |||
1748 | #undef TPV_QL1 | ||
1749 | #undef TPV_QL0 | ||
1750 | #undef TPV_QI2 | ||
1751 | #undef TPV_QI1 | ||
1752 | #undef TPV_QI0 | ||
1753 | #undef TPV_Q_X | ||
1754 | #undef TPV_Q | ||
1755 | |||
1756 | static void __init tpacpi_check_outdated_fw(void) | ||
1757 | { | ||
1758 | unsigned long fwvers; | ||
1759 | u16 ec_version, bios_version; | ||
1760 | |||
1761 | fwvers = tpacpi_check_quirks(tpacpi_bios_version_qtable, | ||
1762 | ARRAY_SIZE(tpacpi_bios_version_qtable)); | ||
1763 | |||
1764 | if (!fwvers) | ||
1765 | return; | ||
1766 | |||
1767 | bios_version = fwvers & 0xffffU; | ||
1768 | ec_version = (fwvers >> 16) & 0xffffU; | ||
1769 | |||
1770 | /* note that unknown versions are set to 0x0000 and we use that */ | ||
1771 | if ((bios_version > thinkpad_id.bios_release) || | ||
1772 | (ec_version > thinkpad_id.ec_release && | ||
1773 | ec_version != TPACPI_MATCH_ANY)) { | ||
1774 | /* | ||
1775 | * The changelogs would let us track down the exact | ||
1776 | * reason, but it is just too much of a pain to track | ||
1777 | * it. We only list BIOSes that are either really | ||
1778 | * broken, or really stable to begin with, so it is | ||
1779 | * best if the user upgrades the firmware anyway. | ||
1780 | */ | ||
1781 | printk(TPACPI_WARN | ||
1782 | "WARNING: Outdated ThinkPad BIOS/EC firmware\n"); | ||
1783 | printk(TPACPI_WARN | ||
1784 | "WARNING: This firmware may be missing critical bug " | ||
1785 | "fixes and/or important features\n"); | ||
1786 | } | ||
1787 | } | ||
1788 | |||
1789 | static bool __init tpacpi_is_fw_known(void) | ||
1790 | { | ||
1791 | return tpacpi_check_quirks(tpacpi_bios_version_qtable, | ||
1792 | ARRAY_SIZE(tpacpi_bios_version_qtable)) != 0; | ||
1793 | } | ||
1794 | |||
1604 | /**************************************************************************** | 1795 | /**************************************************************************** |
1605 | **************************************************************************** | 1796 | **************************************************************************** |
1606 | * | 1797 | * |
@@ -1634,6 +1825,7 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm) | |||
1634 | (thinkpad_id.nummodel_str) ? | 1825 | (thinkpad_id.nummodel_str) ? |
1635 | thinkpad_id.nummodel_str : "unknown"); | 1826 | thinkpad_id.nummodel_str : "unknown"); |
1636 | 1827 | ||
1828 | tpacpi_check_outdated_fw(); | ||
1637 | return 0; | 1829 | return 0; |
1638 | } | 1830 | } |
1639 | 1831 | ||
@@ -1731,16 +1923,42 @@ struct tp_nvram_state { | |||
1731 | u8 volume_level; | 1923 | u8 volume_level; |
1732 | }; | 1924 | }; |
1733 | 1925 | ||
1926 | /* kthread for the hotkey poller */ | ||
1734 | static struct task_struct *tpacpi_hotkey_task; | 1927 | static struct task_struct *tpacpi_hotkey_task; |
1735 | static u32 hotkey_source_mask; /* bit mask 0=ACPI,1=NVRAM */ | 1928 | |
1736 | static int hotkey_poll_freq = 10; /* Hz */ | 1929 | /* Acquired while the poller kthread is running, use to sync start/stop */ |
1737 | static struct mutex hotkey_thread_mutex; | 1930 | static struct mutex hotkey_thread_mutex; |
1931 | |||
1932 | /* | ||
1933 | * Acquire mutex to write poller control variables. | ||
1934 | * Increment hotkey_config_change when changing them. | ||
1935 | * | ||
1936 | * See HOTKEY_CONFIG_CRITICAL_START/HOTKEY_CONFIG_CRITICAL_END | ||
1937 | */ | ||
1738 | static struct mutex hotkey_thread_data_mutex; | 1938 | static struct mutex hotkey_thread_data_mutex; |
1739 | static unsigned int hotkey_config_change; | 1939 | static unsigned int hotkey_config_change; |
1740 | 1940 | ||
1941 | /* | ||
1942 | * hotkey poller control variables | ||
1943 | * | ||
1944 | * Must be atomic or readers will also need to acquire mutex | ||
1945 | */ | ||
1946 | static u32 hotkey_source_mask; /* bit mask 0=ACPI,1=NVRAM */ | ||
1947 | static unsigned int hotkey_poll_freq = 10; /* Hz */ | ||
1948 | |||
1949 | #define HOTKEY_CONFIG_CRITICAL_START \ | ||
1950 | do { \ | ||
1951 | mutex_lock(&hotkey_thread_data_mutex); \ | ||
1952 | hotkey_config_change++; \ | ||
1953 | } while (0); | ||
1954 | #define HOTKEY_CONFIG_CRITICAL_END \ | ||
1955 | mutex_unlock(&hotkey_thread_data_mutex); | ||
1956 | |||
1741 | #else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ | 1957 | #else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ |
1742 | 1958 | ||
1743 | #define hotkey_source_mask 0U | 1959 | #define hotkey_source_mask 0U |
1960 | #define HOTKEY_CONFIG_CRITICAL_START | ||
1961 | #define HOTKEY_CONFIG_CRITICAL_END | ||
1744 | 1962 | ||
1745 | #endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ | 1963 | #endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ |
1746 | 1964 | ||
@@ -1765,19 +1983,6 @@ static u16 *hotkey_keycode_map; | |||
1765 | 1983 | ||
1766 | static struct attribute_set *hotkey_dev_attributes; | 1984 | static struct attribute_set *hotkey_dev_attributes; |
1767 | 1985 | ||
1768 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL | ||
1769 | #define HOTKEY_CONFIG_CRITICAL_START \ | ||
1770 | do { \ | ||
1771 | mutex_lock(&hotkey_thread_data_mutex); \ | ||
1772 | hotkey_config_change++; \ | ||
1773 | } while (0); | ||
1774 | #define HOTKEY_CONFIG_CRITICAL_END \ | ||
1775 | mutex_unlock(&hotkey_thread_data_mutex); | ||
1776 | #else | ||
1777 | #define HOTKEY_CONFIG_CRITICAL_START | ||
1778 | #define HOTKEY_CONFIG_CRITICAL_END | ||
1779 | #endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ | ||
1780 | |||
1781 | /* HKEY.MHKG() return bits */ | 1986 | /* HKEY.MHKG() return bits */ |
1782 | #define TP_HOTKEY_TABLET_MASK (1 << 3) | 1987 | #define TP_HOTKEY_TABLET_MASK (1 << 3) |
1783 | 1988 | ||
@@ -1822,7 +2027,9 @@ static int hotkey_mask_get(void) | |||
1822 | if (!acpi_evalf(hkey_handle, &m, "DHKN", "d")) | 2027 | if (!acpi_evalf(hkey_handle, &m, "DHKN", "d")) |
1823 | return -EIO; | 2028 | return -EIO; |
1824 | } | 2029 | } |
2030 | HOTKEY_CONFIG_CRITICAL_START | ||
1825 | hotkey_mask = m | (hotkey_source_mask & hotkey_mask); | 2031 | hotkey_mask = m | (hotkey_source_mask & hotkey_mask); |
2032 | HOTKEY_CONFIG_CRITICAL_END | ||
1826 | 2033 | ||
1827 | return 0; | 2034 | return 0; |
1828 | } | 2035 | } |
@@ -2075,6 +2282,7 @@ static int hotkey_kthread(void *data) | |||
2075 | unsigned int si, so; | 2282 | unsigned int si, so; |
2076 | unsigned long t; | 2283 | unsigned long t; |
2077 | unsigned int change_detector, must_reset; | 2284 | unsigned int change_detector, must_reset; |
2285 | unsigned int poll_freq; | ||
2078 | 2286 | ||
2079 | mutex_lock(&hotkey_thread_mutex); | 2287 | mutex_lock(&hotkey_thread_mutex); |
2080 | 2288 | ||
@@ -2091,12 +2299,17 @@ static int hotkey_kthread(void *data) | |||
2091 | mutex_lock(&hotkey_thread_data_mutex); | 2299 | mutex_lock(&hotkey_thread_data_mutex); |
2092 | change_detector = hotkey_config_change; | 2300 | change_detector = hotkey_config_change; |
2093 | mask = hotkey_source_mask & hotkey_mask; | 2301 | mask = hotkey_source_mask & hotkey_mask; |
2302 | poll_freq = hotkey_poll_freq; | ||
2094 | mutex_unlock(&hotkey_thread_data_mutex); | 2303 | mutex_unlock(&hotkey_thread_data_mutex); |
2095 | hotkey_read_nvram(&s[so], mask); | 2304 | hotkey_read_nvram(&s[so], mask); |
2096 | 2305 | ||
2097 | while (!kthread_should_stop() && hotkey_poll_freq) { | 2306 | while (!kthread_should_stop()) { |
2098 | if (t == 0) | 2307 | if (t == 0) { |
2099 | t = 1000/hotkey_poll_freq; | 2308 | if (likely(poll_freq)) |
2309 | t = 1000/poll_freq; | ||
2310 | else | ||
2311 | t = 100; /* should never happen... */ | ||
2312 | } | ||
2100 | t = msleep_interruptible(t); | 2313 | t = msleep_interruptible(t); |
2101 | if (unlikely(kthread_should_stop())) | 2314 | if (unlikely(kthread_should_stop())) |
2102 | break; | 2315 | break; |
@@ -2112,6 +2325,7 @@ static int hotkey_kthread(void *data) | |||
2112 | change_detector = hotkey_config_change; | 2325 | change_detector = hotkey_config_change; |
2113 | } | 2326 | } |
2114 | mask = hotkey_source_mask & hotkey_mask; | 2327 | mask = hotkey_source_mask & hotkey_mask; |
2328 | poll_freq = hotkey_poll_freq; | ||
2115 | mutex_unlock(&hotkey_thread_data_mutex); | 2329 | mutex_unlock(&hotkey_thread_data_mutex); |
2116 | 2330 | ||
2117 | if (likely(mask)) { | 2331 | if (likely(mask)) { |
@@ -2131,6 +2345,7 @@ exit: | |||
2131 | return 0; | 2345 | return 0; |
2132 | } | 2346 | } |
2133 | 2347 | ||
2348 | /* call with hotkey_mutex held */ | ||
2134 | static void hotkey_poll_stop_sync(void) | 2349 | static void hotkey_poll_stop_sync(void) |
2135 | { | 2350 | { |
2136 | if (tpacpi_hotkey_task) { | 2351 | if (tpacpi_hotkey_task) { |
@@ -2147,10 +2362,11 @@ static void hotkey_poll_stop_sync(void) | |||
2147 | } | 2362 | } |
2148 | 2363 | ||
2149 | /* call with hotkey_mutex held */ | 2364 | /* call with hotkey_mutex held */ |
2150 | static void hotkey_poll_setup(int may_warn) | 2365 | static void hotkey_poll_setup(bool may_warn) |
2151 | { | 2366 | { |
2152 | if ((hotkey_source_mask & hotkey_mask) != 0 && | 2367 | u32 hotkeys_to_poll = hotkey_source_mask & hotkey_mask; |
2153 | hotkey_poll_freq > 0 && | 2368 | |
2369 | if (hotkeys_to_poll != 0 && hotkey_poll_freq > 0 && | ||
2154 | (tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) { | 2370 | (tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) { |
2155 | if (!tpacpi_hotkey_task) { | 2371 | if (!tpacpi_hotkey_task) { |
2156 | tpacpi_hotkey_task = kthread_run(hotkey_kthread, | 2372 | tpacpi_hotkey_task = kthread_run(hotkey_kthread, |
@@ -2164,26 +2380,37 @@ static void hotkey_poll_setup(int may_warn) | |||
2164 | } | 2380 | } |
2165 | } else { | 2381 | } else { |
2166 | hotkey_poll_stop_sync(); | 2382 | hotkey_poll_stop_sync(); |
2167 | if (may_warn && | 2383 | if (may_warn && hotkeys_to_poll != 0 && |
2168 | hotkey_source_mask != 0 && hotkey_poll_freq == 0) { | 2384 | hotkey_poll_freq == 0) { |
2169 | printk(TPACPI_NOTICE | 2385 | printk(TPACPI_NOTICE |
2170 | "hot keys 0x%08x require polling, " | 2386 | "hot keys 0x%08x require polling, " |
2171 | "which is currently disabled\n", | 2387 | "which is currently disabled\n", |
2172 | hotkey_source_mask); | 2388 | hotkeys_to_poll); |
2173 | } | 2389 | } |
2174 | } | 2390 | } |
2175 | } | 2391 | } |
2176 | 2392 | ||
2177 | static void hotkey_poll_setup_safe(int may_warn) | 2393 | static void hotkey_poll_setup_safe(bool may_warn) |
2178 | { | 2394 | { |
2179 | mutex_lock(&hotkey_mutex); | 2395 | mutex_lock(&hotkey_mutex); |
2180 | hotkey_poll_setup(may_warn); | 2396 | hotkey_poll_setup(may_warn); |
2181 | mutex_unlock(&hotkey_mutex); | 2397 | mutex_unlock(&hotkey_mutex); |
2182 | } | 2398 | } |
2183 | 2399 | ||
2400 | /* call with hotkey_mutex held */ | ||
2401 | static void hotkey_poll_set_freq(unsigned int freq) | ||
2402 | { | ||
2403 | if (!freq) | ||
2404 | hotkey_poll_stop_sync(); | ||
2405 | |||
2406 | HOTKEY_CONFIG_CRITICAL_START | ||
2407 | hotkey_poll_freq = freq; | ||
2408 | HOTKEY_CONFIG_CRITICAL_END | ||
2409 | } | ||
2410 | |||
2184 | #else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ | 2411 | #else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ |
2185 | 2412 | ||
2186 | static void hotkey_poll_setup_safe(int __unused) | 2413 | static void hotkey_poll_setup_safe(bool __unused) |
2187 | { | 2414 | { |
2188 | } | 2415 | } |
2189 | 2416 | ||
@@ -2201,7 +2428,7 @@ static int hotkey_inputdev_open(struct input_dev *dev) | |||
2201 | case TPACPI_LIFE_EXITING: | 2428 | case TPACPI_LIFE_EXITING: |
2202 | return -EBUSY; | 2429 | return -EBUSY; |
2203 | case TPACPI_LIFE_RUNNING: | 2430 | case TPACPI_LIFE_RUNNING: |
2204 | hotkey_poll_setup_safe(0); | 2431 | hotkey_poll_setup_safe(false); |
2205 | return 0; | 2432 | return 0; |
2206 | } | 2433 | } |
2207 | 2434 | ||
@@ -2214,7 +2441,7 @@ static void hotkey_inputdev_close(struct input_dev *dev) | |||
2214 | { | 2441 | { |
2215 | /* disable hotkey polling when possible */ | 2442 | /* disable hotkey polling when possible */ |
2216 | if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING) | 2443 | if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING) |
2217 | hotkey_poll_setup_safe(0); | 2444 | hotkey_poll_setup_safe(false); |
2218 | } | 2445 | } |
2219 | 2446 | ||
2220 | /* sysfs hotkey enable ------------------------------------------------- */ | 2447 | /* sysfs hotkey enable ------------------------------------------------- */ |
@@ -2288,7 +2515,7 @@ static ssize_t hotkey_mask_store(struct device *dev, | |||
2288 | res = hotkey_mask_set(t); | 2515 | res = hotkey_mask_set(t); |
2289 | 2516 | ||
2290 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL | 2517 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL |
2291 | hotkey_poll_setup(1); | 2518 | hotkey_poll_setup(true); |
2292 | #endif | 2519 | #endif |
2293 | 2520 | ||
2294 | mutex_unlock(&hotkey_mutex); | 2521 | mutex_unlock(&hotkey_mutex); |
@@ -2318,6 +2545,8 @@ static ssize_t hotkey_bios_mask_show(struct device *dev, | |||
2318 | struct device_attribute *attr, | 2545 | struct device_attribute *attr, |
2319 | char *buf) | 2546 | char *buf) |
2320 | { | 2547 | { |
2548 | printk_deprecated_attribute("hotkey_bios_mask", | ||
2549 | "This attribute is useless."); | ||
2321 | return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask); | 2550 | return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask); |
2322 | } | 2551 | } |
2323 | 2552 | ||
@@ -2377,7 +2606,8 @@ static ssize_t hotkey_source_mask_store(struct device *dev, | |||
2377 | hotkey_source_mask = t; | 2606 | hotkey_source_mask = t; |
2378 | HOTKEY_CONFIG_CRITICAL_END | 2607 | HOTKEY_CONFIG_CRITICAL_END |
2379 | 2608 | ||
2380 | hotkey_poll_setup(1); | 2609 | hotkey_poll_setup(true); |
2610 | hotkey_mask_set(hotkey_mask); | ||
2381 | 2611 | ||
2382 | mutex_unlock(&hotkey_mutex); | 2612 | mutex_unlock(&hotkey_mutex); |
2383 | 2613 | ||
@@ -2410,9 +2640,9 @@ static ssize_t hotkey_poll_freq_store(struct device *dev, | |||
2410 | if (mutex_lock_killable(&hotkey_mutex)) | 2640 | if (mutex_lock_killable(&hotkey_mutex)) |
2411 | return -ERESTARTSYS; | 2641 | return -ERESTARTSYS; |
2412 | 2642 | ||
2413 | hotkey_poll_freq = t; | 2643 | hotkey_poll_set_freq(t); |
2644 | hotkey_poll_setup(true); | ||
2414 | 2645 | ||
2415 | hotkey_poll_setup(1); | ||
2416 | mutex_unlock(&hotkey_mutex); | 2646 | mutex_unlock(&hotkey_mutex); |
2417 | 2647 | ||
2418 | tpacpi_disclose_usertask("hotkey_poll_freq", "set to %lu\n", t); | 2648 | tpacpi_disclose_usertask("hotkey_poll_freq", "set to %lu\n", t); |
@@ -2603,7 +2833,9 @@ static void tpacpi_send_radiosw_update(void) | |||
2603 | static void hotkey_exit(void) | 2833 | static void hotkey_exit(void) |
2604 | { | 2834 | { |
2605 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL | 2835 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL |
2836 | mutex_lock(&hotkey_mutex); | ||
2606 | hotkey_poll_stop_sync(); | 2837 | hotkey_poll_stop_sync(); |
2838 | mutex_unlock(&hotkey_mutex); | ||
2607 | #endif | 2839 | #endif |
2608 | 2840 | ||
2609 | if (hotkey_dev_attributes) | 2841 | if (hotkey_dev_attributes) |
@@ -2623,6 +2855,15 @@ static void hotkey_exit(void) | |||
2623 | } | 2855 | } |
2624 | } | 2856 | } |
2625 | 2857 | ||
2858 | static void __init hotkey_unmap(const unsigned int scancode) | ||
2859 | { | ||
2860 | if (hotkey_keycode_map[scancode] != KEY_RESERVED) { | ||
2861 | clear_bit(hotkey_keycode_map[scancode], | ||
2862 | tpacpi_inputdev->keybit); | ||
2863 | hotkey_keycode_map[scancode] = KEY_RESERVED; | ||
2864 | } | ||
2865 | } | ||
2866 | |||
2626 | static int __init hotkey_init(struct ibm_init_struct *iibm) | 2867 | static int __init hotkey_init(struct ibm_init_struct *iibm) |
2627 | { | 2868 | { |
2628 | /* Requirements for changing the default keymaps: | 2869 | /* Requirements for changing the default keymaps: |
@@ -2701,11 +2942,11 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
2701 | KEY_UNKNOWN, /* 0x0D: FN+INSERT */ | 2942 | KEY_UNKNOWN, /* 0x0D: FN+INSERT */ |
2702 | KEY_UNKNOWN, /* 0x0E: FN+DELETE */ | 2943 | KEY_UNKNOWN, /* 0x0E: FN+DELETE */ |
2703 | 2944 | ||
2704 | /* These either have to go through ACPI video, or | 2945 | /* These should be enabled --only-- when ACPI video |
2705 | * act like in the IBM ThinkPads, so don't ever | 2946 | * is disabled (i.e. in "vendor" mode), and are handled |
2706 | * enable them by default */ | 2947 | * in a special way by the init code */ |
2707 | KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ | 2948 | KEY_BRIGHTNESSUP, /* 0x0F: FN+HOME (brightness up) */ |
2708 | KEY_RESERVED, /* 0x10: FN+END (brightness down) */ | 2949 | KEY_BRIGHTNESSDOWN, /* 0x10: FN+END (brightness down) */ |
2709 | 2950 | ||
2710 | KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ | 2951 | KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ |
2711 | 2952 | ||
@@ -2831,19 +3072,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
2831 | goto err_exit; | 3072 | goto err_exit; |
2832 | } | 3073 | } |
2833 | 3074 | ||
2834 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL | ||
2835 | if (tp_features.hotkey_mask) { | ||
2836 | hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK | ||
2837 | & ~hotkey_all_mask; | ||
2838 | } else { | ||
2839 | hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK; | ||
2840 | } | ||
2841 | |||
2842 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, | ||
2843 | "hotkey source mask 0x%08x, polling freq %d\n", | ||
2844 | hotkey_source_mask, hotkey_poll_freq); | ||
2845 | #endif | ||
2846 | |||
2847 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES | 3075 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES |
2848 | if (dbg_wlswemul) { | 3076 | if (dbg_wlswemul) { |
2849 | tp_features.hotkey_wlsw = 1; | 3077 | tp_features.hotkey_wlsw = 1; |
@@ -2944,17 +3172,31 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
2944 | "Disabling thinkpad-acpi brightness events " | 3172 | "Disabling thinkpad-acpi brightness events " |
2945 | "by default...\n"); | 3173 | "by default...\n"); |
2946 | 3174 | ||
2947 | /* The hotkey_reserved_mask change below is not | 3175 | /* Disable brightness up/down on Lenovo thinkpads when |
2948 | * necessary while the keys are at KEY_RESERVED in the | 3176 | * ACPI is handling them, otherwise it is plain impossible |
2949 | * default map, but better safe than sorry, leave it | 3177 | * for userspace to do something even remotely sane */ |
2950 | * here as a marker of what we have to do, especially | ||
2951 | * when we finally become able to set this at runtime | ||
2952 | * on response to X.org requests */ | ||
2953 | hotkey_reserved_mask |= | 3178 | hotkey_reserved_mask |= |
2954 | (1 << TP_ACPI_HOTKEYSCAN_FNHOME) | 3179 | (1 << TP_ACPI_HOTKEYSCAN_FNHOME) |
2955 | | (1 << TP_ACPI_HOTKEYSCAN_FNEND); | 3180 | | (1 << TP_ACPI_HOTKEYSCAN_FNEND); |
3181 | hotkey_unmap(TP_ACPI_HOTKEYSCAN_FNHOME); | ||
3182 | hotkey_unmap(TP_ACPI_HOTKEYSCAN_FNEND); | ||
2956 | } | 3183 | } |
2957 | 3184 | ||
3185 | #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL | ||
3186 | if (tp_features.hotkey_mask) { | ||
3187 | hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK | ||
3188 | & ~hotkey_all_mask | ||
3189 | & ~hotkey_reserved_mask; | ||
3190 | } else { | ||
3191 | hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK | ||
3192 | & ~hotkey_reserved_mask; | ||
3193 | } | ||
3194 | |||
3195 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, | ||
3196 | "hotkey source mask 0x%08x, polling freq %u\n", | ||
3197 | hotkey_source_mask, hotkey_poll_freq); | ||
3198 | #endif | ||
3199 | |||
2958 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, | 3200 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, |
2959 | "enabling firmware HKEY event interface...\n"); | 3201 | "enabling firmware HKEY event interface...\n"); |
2960 | res = hotkey_status_set(true); | 3202 | res = hotkey_status_set(true); |
@@ -2978,7 +3220,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
2978 | tpacpi_inputdev->open = &hotkey_inputdev_open; | 3220 | tpacpi_inputdev->open = &hotkey_inputdev_open; |
2979 | tpacpi_inputdev->close = &hotkey_inputdev_close; | 3221 | tpacpi_inputdev->close = &hotkey_inputdev_close; |
2980 | 3222 | ||
2981 | hotkey_poll_setup_safe(1); | 3223 | hotkey_poll_setup_safe(true); |
2982 | tpacpi_send_radiosw_update(); | 3224 | tpacpi_send_radiosw_update(); |
2983 | tpacpi_input_send_tabletsw(); | 3225 | tpacpi_input_send_tabletsw(); |
2984 | 3226 | ||
@@ -3266,7 +3508,7 @@ static void hotkey_resume(void) | |||
3266 | hotkey_tablet_mode_notify_change(); | 3508 | hotkey_tablet_mode_notify_change(); |
3267 | hotkey_wakeup_reason_notify_change(); | 3509 | hotkey_wakeup_reason_notify_change(); |
3268 | hotkey_wakeup_hotunplug_complete_notify_change(); | 3510 | hotkey_wakeup_hotunplug_complete_notify_change(); |
3269 | hotkey_poll_setup_safe(0); | 3511 | hotkey_poll_setup_safe(false); |
3270 | } | 3512 | } |
3271 | 3513 | ||
3272 | /* procfs -------------------------------------------------------------- */ | 3514 | /* procfs -------------------------------------------------------------- */ |
@@ -3338,7 +3580,8 @@ static int hotkey_write(char *buf) | |||
3338 | hotkey_enabledisable_warn(0); | 3580 | hotkey_enabledisable_warn(0); |
3339 | res = -EPERM; | 3581 | res = -EPERM; |
3340 | } else if (strlencmp(cmd, "reset") == 0) { | 3582 | } else if (strlencmp(cmd, "reset") == 0) { |
3341 | mask = hotkey_orig_mask; | 3583 | mask = (hotkey_all_mask | hotkey_source_mask) |
3584 | & ~hotkey_reserved_mask; | ||
3342 | } else if (sscanf(cmd, "0x%x", &mask) == 1) { | 3585 | } else if (sscanf(cmd, "0x%x", &mask) == 1) { |
3343 | /* mask set */ | 3586 | /* mask set */ |
3344 | } else if (sscanf(cmd, "%x", &mask) == 1) { | 3587 | } else if (sscanf(cmd, "%x", &mask) == 1) { |
@@ -5655,16 +5898,16 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = { | |||
5655 | /* Models with ATI GPUs known to require ECNVRAM mode */ | 5898 | /* Models with ATI GPUs known to require ECNVRAM mode */ |
5656 | TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC), /* T43/p ATI */ | 5899 | TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC), /* T43/p ATI */ |
5657 | 5900 | ||
5658 | /* Models with ATI GPUs (waiting confirmation) */ | 5901 | /* Models with ATI GPUs that can use ECNVRAM */ |
5659 | TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), | 5902 | TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC), |
5660 | TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), | 5903 | TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), |
5661 | TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), | 5904 | TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), |
5662 | TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), | 5905 | TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), |
5663 | 5906 | ||
5664 | /* Models with Intel Extreme Graphics 2 (waiting confirmation) */ | 5907 | /* Models with Intel Extreme Graphics 2 */ |
5908 | TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC), | ||
5665 | TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), | 5909 | TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), |
5666 | TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), | 5910 | TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), |
5667 | TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_NOEC), | ||
5668 | 5911 | ||
5669 | /* Models with Intel GMA900 */ | 5912 | /* Models with Intel GMA900 */ |
5670 | TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC), /* T43, R52 */ | 5913 | TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC), /* T43, R52 */ |
@@ -7524,9 +7767,11 @@ static int __init probe_for_thinkpad(void) | |||
7524 | 7767 | ||
7525 | /* | 7768 | /* |
7526 | * Non-ancient models have better DMI tagging, but very old models | 7769 | * Non-ancient models have better DMI tagging, but very old models |
7527 | * don't. | 7770 | * don't. tpacpi_is_fw_known() is a cheat to help in that case. |
7528 | */ | 7771 | */ |
7529 | is_thinkpad = (thinkpad_id.model_str != NULL); | 7772 | is_thinkpad = (thinkpad_id.model_str != NULL) || |
7773 | (thinkpad_id.ec_model != 0) || | ||
7774 | tpacpi_is_fw_known(); | ||
7530 | 7775 | ||
7531 | /* ec is required because many other handles are relative to it */ | 7776 | /* ec is required because many other handles are relative to it */ |
7532 | TPACPI_ACPIHANDLE_INIT(ec); | 7777 | TPACPI_ACPIHANDLE_INIT(ec); |
@@ -7537,13 +7782,6 @@ static int __init probe_for_thinkpad(void) | |||
7537 | return -ENODEV; | 7782 | return -ENODEV; |
7538 | } | 7783 | } |
7539 | 7784 | ||
7540 | /* | ||
7541 | * Risks a regression on very old machines, but reduces potential | ||
7542 | * false positives a damn great deal | ||
7543 | */ | ||
7544 | if (!is_thinkpad) | ||
7545 | is_thinkpad = (thinkpad_id.vendor == PCI_VENDOR_ID_IBM); | ||
7546 | |||
7547 | if (!is_thinkpad && !force_load) | 7785 | if (!is_thinkpad && !force_load) |
7548 | return -ENODEV; | 7786 | return -ENODEV; |
7549 | 7787 | ||
diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c new file mode 100644 index 000000000000..02f3d4e9e666 --- /dev/null +++ b/drivers/platform/x86/topstar-laptop.c | |||
@@ -0,0 +1,265 @@ | |||
1 | /* | ||
2 | * ACPI driver for Topstar notebooks (hotkeys support only) | ||
3 | * | ||
4 | * Copyright (c) 2009 Herton Ronaldo Krzesinski <herton@mandriva.com.br> | ||
5 | * | ||
6 | * Implementation inspired by existing x86 platform drivers, in special | ||
7 | * asus/eepc/fujitsu-laptop, thanks to their authors | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/acpi.h> | ||
20 | #include <linux/input.h> | ||
21 | |||
22 | #define ACPI_TOPSTAR_CLASS "topstar" | ||
23 | |||
24 | struct topstar_hkey { | ||
25 | struct input_dev *inputdev; | ||
26 | }; | ||
27 | |||
28 | struct tps_key_entry { | ||
29 | u8 code; | ||
30 | u16 keycode; | ||
31 | }; | ||
32 | |||
33 | static struct tps_key_entry topstar_keymap[] = { | ||
34 | { 0x80, KEY_BRIGHTNESSUP }, | ||
35 | { 0x81, KEY_BRIGHTNESSDOWN }, | ||
36 | { 0x83, KEY_VOLUMEUP }, | ||
37 | { 0x84, KEY_VOLUMEDOWN }, | ||
38 | { 0x85, KEY_MUTE }, | ||
39 | { 0x86, KEY_SWITCHVIDEOMODE }, | ||
40 | { 0x87, KEY_F13 }, /* touchpad enable/disable key */ | ||
41 | { 0x88, KEY_WLAN }, | ||
42 | { 0x8a, KEY_WWW }, | ||
43 | { 0x8b, KEY_MAIL }, | ||
44 | { 0x8c, KEY_MEDIA }, | ||
45 | { 0x96, KEY_F14 }, /* G key? */ | ||
46 | { } | ||
47 | }; | ||
48 | |||
49 | static struct tps_key_entry *tps_get_key_by_scancode(int code) | ||
50 | { | ||
51 | struct tps_key_entry *key; | ||
52 | |||
53 | for (key = topstar_keymap; key->code; key++) | ||
54 | if (code == key->code) | ||
55 | return key; | ||
56 | |||
57 | return NULL; | ||
58 | } | ||
59 | |||
60 | static struct tps_key_entry *tps_get_key_by_keycode(int code) | ||
61 | { | ||
62 | struct tps_key_entry *key; | ||
63 | |||
64 | for (key = topstar_keymap; key->code; key++) | ||
65 | if (code == key->keycode) | ||
66 | return key; | ||
67 | |||
68 | return NULL; | ||
69 | } | ||
70 | |||
71 | static void acpi_topstar_notify(struct acpi_device *device, u32 event) | ||
72 | { | ||
73 | struct tps_key_entry *key; | ||
74 | static bool dup_evnt[2]; | ||
75 | bool *dup; | ||
76 | struct topstar_hkey *hkey = acpi_driver_data(device); | ||
77 | |||
78 | /* 0x83 and 0x84 key events comes duplicated... */ | ||
79 | if (event == 0x83 || event == 0x84) { | ||
80 | dup = &dup_evnt[event - 0x83]; | ||
81 | if (*dup) { | ||
82 | *dup = false; | ||
83 | return; | ||
84 | } | ||
85 | *dup = true; | ||
86 | } | ||
87 | |||
88 | /* | ||
89 | * 'G key' generate two event codes, convert to only | ||
90 | * one event/key code for now (3G switch?) | ||
91 | */ | ||
92 | if (event == 0x97) | ||
93 | event = 0x96; | ||
94 | |||
95 | key = tps_get_key_by_scancode(event); | ||
96 | if (key) { | ||
97 | input_report_key(hkey->inputdev, key->keycode, 1); | ||
98 | input_sync(hkey->inputdev); | ||
99 | input_report_key(hkey->inputdev, key->keycode, 0); | ||
100 | input_sync(hkey->inputdev); | ||
101 | return; | ||
102 | } | ||
103 | |||
104 | /* Known non hotkey events don't handled or that we don't care yet */ | ||
105 | if (event == 0x8e || event == 0x8f || event == 0x90) | ||
106 | return; | ||
107 | |||
108 | pr_info("unknown event = 0x%02x\n", event); | ||
109 | } | ||
110 | |||
111 | static int acpi_topstar_fncx_switch(struct acpi_device *device, bool state) | ||
112 | { | ||
113 | acpi_status status; | ||
114 | union acpi_object fncx_params[1] = { | ||
115 | { .type = ACPI_TYPE_INTEGER } | ||
116 | }; | ||
117 | struct acpi_object_list fncx_arg_list = { 1, &fncx_params[0] }; | ||
118 | |||
119 | fncx_params[0].integer.value = state ? 0x86 : 0x87; | ||
120 | status = acpi_evaluate_object(device->handle, "FNCX", &fncx_arg_list, NULL); | ||
121 | if (ACPI_FAILURE(status)) { | ||
122 | pr_err("Unable to switch FNCX notifications\n"); | ||
123 | return -ENODEV; | ||
124 | } | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int topstar_getkeycode(struct input_dev *dev, int scancode, int *keycode) | ||
130 | { | ||
131 | struct tps_key_entry *key = tps_get_key_by_scancode(scancode); | ||
132 | |||
133 | if (!key) | ||
134 | return -EINVAL; | ||
135 | |||
136 | *keycode = key->keycode; | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static int topstar_setkeycode(struct input_dev *dev, int scancode, int keycode) | ||
141 | { | ||
142 | struct tps_key_entry *key; | ||
143 | int old_keycode; | ||
144 | |||
145 | if (keycode < 0 || keycode > KEY_MAX) | ||
146 | return -EINVAL; | ||
147 | |||
148 | key = tps_get_key_by_scancode(scancode); | ||
149 | |||
150 | if (!key) | ||
151 | return -EINVAL; | ||
152 | |||
153 | old_keycode = key->keycode; | ||
154 | key->keycode = keycode; | ||
155 | set_bit(keycode, dev->keybit); | ||
156 | if (!tps_get_key_by_keycode(old_keycode)) | ||
157 | clear_bit(old_keycode, dev->keybit); | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | static int acpi_topstar_init_hkey(struct topstar_hkey *hkey) | ||
162 | { | ||
163 | struct tps_key_entry *key; | ||
164 | |||
165 | hkey->inputdev = input_allocate_device(); | ||
166 | if (!hkey->inputdev) { | ||
167 | pr_err("Unable to allocate input device\n"); | ||
168 | return -ENODEV; | ||
169 | } | ||
170 | hkey->inputdev->name = "Topstar Laptop extra buttons"; | ||
171 | hkey->inputdev->phys = "topstar/input0"; | ||
172 | hkey->inputdev->id.bustype = BUS_HOST; | ||
173 | hkey->inputdev->getkeycode = topstar_getkeycode; | ||
174 | hkey->inputdev->setkeycode = topstar_setkeycode; | ||
175 | for (key = topstar_keymap; key->code; key++) { | ||
176 | set_bit(EV_KEY, hkey->inputdev->evbit); | ||
177 | set_bit(key->keycode, hkey->inputdev->keybit); | ||
178 | } | ||
179 | if (input_register_device(hkey->inputdev)) { | ||
180 | pr_err("Unable to register input device\n"); | ||
181 | input_free_device(hkey->inputdev); | ||
182 | return -ENODEV; | ||
183 | } | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static int acpi_topstar_add(struct acpi_device *device) | ||
189 | { | ||
190 | struct topstar_hkey *tps_hkey; | ||
191 | |||
192 | tps_hkey = kzalloc(sizeof(struct topstar_hkey), GFP_KERNEL); | ||
193 | if (!tps_hkey) | ||
194 | return -ENOMEM; | ||
195 | |||
196 | strcpy(acpi_device_name(device), "Topstar TPSACPI"); | ||
197 | strcpy(acpi_device_class(device), ACPI_TOPSTAR_CLASS); | ||
198 | |||
199 | if (acpi_topstar_fncx_switch(device, true)) | ||
200 | goto add_err; | ||
201 | |||
202 | if (acpi_topstar_init_hkey(tps_hkey)) | ||
203 | goto add_err; | ||
204 | |||
205 | device->driver_data = tps_hkey; | ||
206 | return 0; | ||
207 | |||
208 | add_err: | ||
209 | kfree(tps_hkey); | ||
210 | return -ENODEV; | ||
211 | } | ||
212 | |||
213 | static int acpi_topstar_remove(struct acpi_device *device, int type) | ||
214 | { | ||
215 | struct topstar_hkey *tps_hkey = acpi_driver_data(device); | ||
216 | |||
217 | acpi_topstar_fncx_switch(device, false); | ||
218 | |||
219 | input_unregister_device(tps_hkey->inputdev); | ||
220 | kfree(tps_hkey); | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static const struct acpi_device_id topstar_device_ids[] = { | ||
226 | { "TPSACPI01", 0 }, | ||
227 | { "", 0 }, | ||
228 | }; | ||
229 | MODULE_DEVICE_TABLE(acpi, topstar_device_ids); | ||
230 | |||
231 | static struct acpi_driver acpi_topstar_driver = { | ||
232 | .name = "Topstar laptop ACPI driver", | ||
233 | .class = ACPI_TOPSTAR_CLASS, | ||
234 | .ids = topstar_device_ids, | ||
235 | .ops = { | ||
236 | .add = acpi_topstar_add, | ||
237 | .remove = acpi_topstar_remove, | ||
238 | .notify = acpi_topstar_notify, | ||
239 | }, | ||
240 | }; | ||
241 | |||
242 | static int __init topstar_laptop_init(void) | ||
243 | { | ||
244 | int ret; | ||
245 | |||
246 | ret = acpi_bus_register_driver(&acpi_topstar_driver); | ||
247 | if (ret < 0) | ||
248 | return ret; | ||
249 | |||
250 | printk(KERN_INFO "Topstar Laptop ACPI extras driver loaded\n"); | ||
251 | |||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | static void __exit topstar_laptop_exit(void) | ||
256 | { | ||
257 | acpi_bus_unregister_driver(&acpi_topstar_driver); | ||
258 | } | ||
259 | |||
260 | module_init(topstar_laptop_init); | ||
261 | module_exit(topstar_laptop_exit); | ||
262 | |||
263 | MODULE_AUTHOR("Herton Ronaldo Krzesinski"); | ||
264 | MODULE_DESCRIPTION("Topstar Laptop ACPI Extras driver"); | ||
265 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index f215a5919192..177f8d767df4 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c | |||
@@ -42,7 +42,6 @@ MODULE_LICENSE("GPL"); | |||
42 | 42 | ||
43 | #define ACPI_WMI_CLASS "wmi" | 43 | #define ACPI_WMI_CLASS "wmi" |
44 | 44 | ||
45 | #undef PREFIX | ||
46 | #define PREFIX "ACPI: WMI: " | 45 | #define PREFIX "ACPI: WMI: " |
47 | 46 | ||
48 | static DEFINE_MUTEX(wmi_data_lock); | 47 | static DEFINE_MUTEX(wmi_data_lock); |
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 9496494f340e..c07fdb94d665 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -194,13 +194,13 @@ static int __init pnpacpi_add_device(struct acpi_device *device) | |||
194 | pnpacpi_parse_resource_option_data(dev); | 194 | pnpacpi_parse_resource_option_data(dev); |
195 | 195 | ||
196 | if (device->flags.compatible_ids) { | 196 | if (device->flags.compatible_ids) { |
197 | struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; | 197 | struct acpica_device_id_list *cid_list = device->pnp.cid_list; |
198 | int i; | 198 | int i; |
199 | 199 | ||
200 | for (i = 0; i < cid_list->count; i++) { | 200 | for (i = 0; i < cid_list->count; i++) { |
201 | if (!ispnpidacpi(cid_list->id[i].value)) | 201 | if (!ispnpidacpi(cid_list->ids[i].string)) |
202 | continue; | 202 | continue; |
203 | pnp_add_id(dev, cid_list->id[i].value); | 203 | pnp_add_id(dev, cid_list->ids[i].string); |
204 | } | 204 | } |
205 | } | 205 | } |
206 | 206 | ||
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index a86e952ed4ca..bf7c687519ef 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig | |||
@@ -15,6 +15,7 @@ menuconfig THERMAL | |||
15 | 15 | ||
16 | config THERMAL_HWMON | 16 | config THERMAL_HWMON |
17 | bool "Hardware monitoring support" | 17 | bool "Hardware monitoring support" |
18 | depends on THERMAL | ||
18 | depends on HWMON=y || HWMON=THERMAL | 19 | depends on HWMON=y || HWMON=THERMAL |
19 | help | 20 | help |
20 | The generic thermal sysfs driver's hardware monitoring support | 21 | The generic thermal sysfs driver's hardware monitoring support |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 1b3b36068ca5..1cef1398e358 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -30,8 +30,6 @@ | |||
30 | 30 | ||
31 | #include <acpi/acpi.h> | 31 | #include <acpi/acpi.h> |
32 | 32 | ||
33 | #define PREFIX "ACPI: " | ||
34 | |||
35 | /* TBD: Make dynamic */ | 33 | /* TBD: Make dynamic */ |
36 | #define ACPI_MAX_HANDLES 10 | 34 | #define ACPI_MAX_HANDLES 10 |
37 | struct acpi_handle_list { | 35 | struct acpi_handle_list { |
@@ -89,7 +87,6 @@ struct acpi_device; | |||
89 | typedef int (*acpi_op_add) (struct acpi_device * device); | 87 | typedef int (*acpi_op_add) (struct acpi_device * device); |
90 | typedef int (*acpi_op_remove) (struct acpi_device * device, int type); | 88 | typedef int (*acpi_op_remove) (struct acpi_device * device, int type); |
91 | typedef int (*acpi_op_start) (struct acpi_device * device); | 89 | typedef int (*acpi_op_start) (struct acpi_device * device); |
92 | typedef int (*acpi_op_stop) (struct acpi_device * device, int type); | ||
93 | typedef int (*acpi_op_suspend) (struct acpi_device * device, | 90 | typedef int (*acpi_op_suspend) (struct acpi_device * device, |
94 | pm_message_t state); | 91 | pm_message_t state); |
95 | typedef int (*acpi_op_resume) (struct acpi_device * device); | 92 | typedef int (*acpi_op_resume) (struct acpi_device * device); |
@@ -106,7 +103,6 @@ struct acpi_device_ops { | |||
106 | acpi_op_add add; | 103 | acpi_op_add add; |
107 | acpi_op_remove remove; | 104 | acpi_op_remove remove; |
108 | acpi_op_start start; | 105 | acpi_op_start start; |
109 | acpi_op_stop stop; | ||
110 | acpi_op_suspend suspend; | 106 | acpi_op_suspend suspend; |
111 | acpi_op_resume resume; | 107 | acpi_op_resume resume; |
112 | acpi_op_bind bind; | 108 | acpi_op_bind bind; |
@@ -173,17 +169,15 @@ struct acpi_device_dir { | |||
173 | 169 | ||
174 | typedef char acpi_bus_id[8]; | 170 | typedef char acpi_bus_id[8]; |
175 | typedef unsigned long acpi_bus_address; | 171 | typedef unsigned long acpi_bus_address; |
176 | typedef char acpi_hardware_id[15]; | ||
177 | typedef char acpi_unique_id[9]; | ||
178 | typedef char acpi_device_name[40]; | 172 | typedef char acpi_device_name[40]; |
179 | typedef char acpi_device_class[20]; | 173 | typedef char acpi_device_class[20]; |
180 | 174 | ||
181 | struct acpi_device_pnp { | 175 | struct acpi_device_pnp { |
182 | acpi_bus_id bus_id; /* Object name */ | 176 | acpi_bus_id bus_id; /* Object name */ |
183 | acpi_bus_address bus_address; /* _ADR */ | 177 | acpi_bus_address bus_address; /* _ADR */ |
184 | acpi_hardware_id hardware_id; /* _HID */ | 178 | char *hardware_id; /* _HID */ |
185 | struct acpi_compatible_id_list *cid_list; /* _CIDs */ | 179 | struct acpica_device_id_list *cid_list; /* _CIDs */ |
186 | acpi_unique_id unique_id; /* _UID */ | 180 | char *unique_id; /* _UID */ |
187 | acpi_device_name device_name; /* Driver-determined */ | 181 | acpi_device_name device_name; /* Driver-determined */ |
188 | acpi_device_class device_class; /* " */ | 182 | acpi_device_class device_class; /* " */ |
189 | }; | 183 | }; |
@@ -314,7 +308,7 @@ struct acpi_bus_event { | |||
314 | 308 | ||
315 | extern struct kobject *acpi_kobj; | 309 | extern struct kobject *acpi_kobj; |
316 | extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int); | 310 | extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int); |
317 | void acpi_bus_private_data_handler(acpi_handle, u32, void *); | 311 | void acpi_bus_private_data_handler(acpi_handle, void *); |
318 | int acpi_bus_get_private_data(acpi_handle, void **); | 312 | int acpi_bus_get_private_data(acpi_handle, void **); |
319 | extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32); | 313 | extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32); |
320 | extern int register_acpi_notifier(struct notifier_block *); | 314 | extern int register_acpi_notifier(struct notifier_block *); |
@@ -327,7 +321,7 @@ extern void unregister_acpi_bus_notifier(struct notifier_block *nb); | |||
327 | */ | 321 | */ |
328 | 322 | ||
329 | int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device); | 323 | int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device); |
330 | void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context); | 324 | void acpi_bus_data_handler(acpi_handle handle, void *context); |
331 | int acpi_bus_get_status(struct acpi_device *device); | 325 | int acpi_bus_get_status(struct acpi_device *device); |
332 | int acpi_bus_get_power(acpi_handle handle, int *state); | 326 | int acpi_bus_get_power(acpi_handle handle, int *state); |
333 | int acpi_bus_set_power(acpi_handle handle, int state); | 327 | int acpi_bus_set_power(acpi_handle handle, int state); |
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index ab0b85cf21f3..eb0e7189075f 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h | |||
@@ -245,6 +245,9 @@ acpi_status acpi_osi_invalidate(char* interface); | |||
245 | acpi_status | 245 | acpi_status |
246 | acpi_os_validate_address(u8 space_id, acpi_physical_address address, | 246 | acpi_os_validate_address(u8 space_id, acpi_physical_address address, |
247 | acpi_size length, char *name); | 247 | acpi_size length, char *name); |
248 | acpi_status | ||
249 | acpi_os_invalidate_address(u8 space_id, acpi_physical_address address, | ||
250 | acpi_size length); | ||
248 | 251 | ||
249 | u64 acpi_os_get_timer(void); | 252 | u64 acpi_os_get_timer(void); |
250 | 253 | ||
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 82ec6a3c0500..e723b0fd8e41 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
@@ -47,7 +47,7 @@ | |||
47 | 47 | ||
48 | /* Current ACPICA subsystem version in YYYYMMDD format */ | 48 | /* Current ACPICA subsystem version in YYYYMMDD format */ |
49 | 49 | ||
50 | #define ACPI_CA_VERSION 0x20090521 | 50 | #define ACPI_CA_VERSION 0x20090903 |
51 | 51 | ||
52 | #include "actypes.h" | 52 | #include "actypes.h" |
53 | #include "actbl.h" | 53 | #include "actbl.h" |
@@ -64,6 +64,7 @@ extern u8 acpi_gbl_enable_interpreter_slack; | |||
64 | extern u8 acpi_gbl_all_methods_serialized; | 64 | extern u8 acpi_gbl_all_methods_serialized; |
65 | extern u8 acpi_gbl_create_osi_method; | 65 | extern u8 acpi_gbl_create_osi_method; |
66 | extern u8 acpi_gbl_leave_wake_gpes_disabled; | 66 | extern u8 acpi_gbl_leave_wake_gpes_disabled; |
67 | extern u8 acpi_gbl_use_default_register_widths; | ||
67 | extern acpi_name acpi_gbl_trace_method_name; | 68 | extern acpi_name acpi_gbl_trace_method_name; |
68 | extern u32 acpi_gbl_trace_flags; | 69 | extern u32 acpi_gbl_trace_flags; |
69 | 70 | ||
@@ -199,7 +200,8 @@ acpi_evaluate_object_typed(acpi_handle object, | |||
199 | acpi_object_type return_type); | 200 | acpi_object_type return_type); |
200 | 201 | ||
201 | acpi_status | 202 | acpi_status |
202 | acpi_get_object_info(acpi_handle handle, struct acpi_buffer *return_buffer); | 203 | acpi_get_object_info(acpi_handle handle, |
204 | struct acpi_device_info **return_buffer); | ||
203 | 205 | ||
204 | acpi_status acpi_install_method(u8 *buffer); | 206 | acpi_status acpi_install_method(u8 *buffer); |
205 | 207 | ||
@@ -359,9 +361,9 @@ acpi_status acpi_set_firmware_waking_vector(u32 physical_address); | |||
359 | acpi_status acpi_set_firmware_waking_vector64(u64 physical_address); | 361 | acpi_status acpi_set_firmware_waking_vector64(u64 physical_address); |
360 | #endif | 362 | #endif |
361 | 363 | ||
362 | acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg); | 364 | acpi_status acpi_read(u64 *value, struct acpi_generic_address *reg); |
363 | 365 | ||
364 | acpi_status acpi_write(u32 value, struct acpi_generic_address *reg); | 366 | acpi_status acpi_write(u64 value, struct acpi_generic_address *reg); |
365 | 367 | ||
366 | acpi_status | 368 | acpi_status |
367 | acpi_get_sleep_type_data(u8 sleep_state, u8 * slp_typ_a, u8 * slp_typ_b); | 369 | acpi_get_sleep_type_data(u8 sleep_state, u8 * slp_typ_a, u8 * slp_typ_b); |
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index 222733d01f36..1b6587952604 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h | |||
@@ -44,9 +44,23 @@ | |||
44 | #ifndef __ACTBL_H__ | 44 | #ifndef __ACTBL_H__ |
45 | #define __ACTBL_H__ | 45 | #define __ACTBL_H__ |
46 | 46 | ||
47 | /******************************************************************************* | ||
48 | * | ||
49 | * Fundamental ACPI tables | ||
50 | * | ||
51 | * This file contains definitions for the ACPI tables that are directly consumed | ||
52 | * by ACPICA. All other tables are consumed by the OS-dependent ACPI-related | ||
53 | * device drivers and other OS support code. | ||
54 | * | ||
55 | * The RSDP and FACS do not use the common ACPI table header. All other ACPI | ||
56 | * tables use the header. | ||
57 | * | ||
58 | ******************************************************************************/ | ||
59 | |||
47 | /* | 60 | /* |
48 | * Values for description table header signatures. Useful because they make | 61 | * Values for description table header signatures for tables defined in this |
49 | * it more difficult to inadvertently type in the wrong signature. | 62 | * file. Useful because they make it more difficult to inadvertently type in |
63 | * the wrong signature. | ||
50 | */ | 64 | */ |
51 | #define ACPI_SIG_DSDT "DSDT" /* Differentiated System Description Table */ | 65 | #define ACPI_SIG_DSDT "DSDT" /* Differentiated System Description Table */ |
52 | #define ACPI_SIG_FADT "FACP" /* Fixed ACPI Description Table */ | 66 | #define ACPI_SIG_FADT "FACP" /* Fixed ACPI Description Table */ |
@@ -65,11 +79,6 @@ | |||
65 | #pragma pack(1) | 79 | #pragma pack(1) |
66 | 80 | ||
67 | /* | 81 | /* |
68 | * These are the ACPI tables that are directly consumed by the subsystem. | ||
69 | * | ||
70 | * The RSDP and FACS do not use the common ACPI table header. All other ACPI | ||
71 | * tables use the header. | ||
72 | * | ||
73 | * Note about bitfields: The u8 type is used for bitfields in ACPI tables. | 82 | * Note about bitfields: The u8 type is used for bitfields in ACPI tables. |
74 | * This is the only type that is even remotely portable. Anything else is not | 83 | * This is the only type that is even remotely portable. Anything else is not |
75 | * portable, so do not use any other bitfield types. | 84 | * portable, so do not use any other bitfield types. |
@@ -77,9 +86,8 @@ | |||
77 | 86 | ||
78 | /******************************************************************************* | 87 | /******************************************************************************* |
79 | * | 88 | * |
80 | * ACPI Table Header. This common header is used by all tables except the | 89 | * Master ACPI Table Header. This common header is used by all ACPI tables |
81 | * RSDP and FACS. The define is used for direct inclusion of header into | 90 | * except the RSDP and FACS. |
82 | * other ACPI tables | ||
83 | * | 91 | * |
84 | ******************************************************************************/ | 92 | ******************************************************************************/ |
85 | 93 | ||
@@ -95,13 +103,16 @@ struct acpi_table_header { | |||
95 | u32 asl_compiler_revision; /* ASL compiler version */ | 103 | u32 asl_compiler_revision; /* ASL compiler version */ |
96 | }; | 104 | }; |
97 | 105 | ||
98 | /* | 106 | /******************************************************************************* |
107 | * | ||
99 | * GAS - Generic Address Structure (ACPI 2.0+) | 108 | * GAS - Generic Address Structure (ACPI 2.0+) |
100 | * | 109 | * |
101 | * Note: Since this structure is used in the ACPI tables, it is byte aligned. | 110 | * Note: Since this structure is used in the ACPI tables, it is byte aligned. |
102 | * If misalignment is not supported, access to the Address field must be | 111 | * If misaliged access is not supported by the hardware, accesses to the |
103 | * performed with care. | 112 | * 64-bit Address field must be performed with care. |
104 | */ | 113 | * |
114 | ******************************************************************************/ | ||
115 | |||
105 | struct acpi_generic_address { | 116 | struct acpi_generic_address { |
106 | u8 space_id; /* Address space where struct or register exists */ | 117 | u8 space_id; /* Address space where struct or register exists */ |
107 | u8 bit_width; /* Size in bits of given register */ | 118 | u8 bit_width; /* Size in bits of given register */ |
@@ -113,6 +124,7 @@ struct acpi_generic_address { | |||
113 | /******************************************************************************* | 124 | /******************************************************************************* |
114 | * | 125 | * |
115 | * RSDP - Root System Description Pointer (Signature is "RSD PTR ") | 126 | * RSDP - Root System Description Pointer (Signature is "RSD PTR ") |
127 | * Version 2 | ||
116 | * | 128 | * |
117 | ******************************************************************************/ | 129 | ******************************************************************************/ |
118 | 130 | ||
@@ -133,6 +145,7 @@ struct acpi_table_rsdp { | |||
133 | /******************************************************************************* | 145 | /******************************************************************************* |
134 | * | 146 | * |
135 | * RSDT/XSDT - Root System Description Tables | 147 | * RSDT/XSDT - Root System Description Tables |
148 | * Version 1 (both) | ||
136 | * | 149 | * |
137 | ******************************************************************************/ | 150 | ******************************************************************************/ |
138 | 151 | ||
@@ -161,21 +174,29 @@ struct acpi_table_facs { | |||
161 | u32 flags; | 174 | u32 flags; |
162 | u64 xfirmware_waking_vector; /* 64-bit version of the Firmware Waking Vector (ACPI 2.0+) */ | 175 | u64 xfirmware_waking_vector; /* 64-bit version of the Firmware Waking Vector (ACPI 2.0+) */ |
163 | u8 version; /* Version of this table (ACPI 2.0+) */ | 176 | u8 version; /* Version of this table (ACPI 2.0+) */ |
164 | u8 reserved[31]; /* Reserved, must be zero */ | 177 | u8 reserved[3]; /* Reserved, must be zero */ |
178 | u32 ospm_flags; /* Flags to be set by OSPM (ACPI 4.0) */ | ||
179 | u8 reserved1[24]; /* Reserved, must be zero */ | ||
165 | }; | 180 | }; |
166 | 181 | ||
167 | /* Flag macros */ | 182 | /* Masks for global_lock flag field above */ |
168 | 183 | ||
169 | #define ACPI_FACS_S4_BIOS_PRESENT (1) /* 00: S4BIOS support is present */ | 184 | #define ACPI_GLOCK_PENDING (1) /* 00: Pending global lock ownership */ |
185 | #define ACPI_GLOCK_OWNED (1<<1) /* 01: Global lock is owned */ | ||
170 | 186 | ||
171 | /* Global lock flags */ | 187 | /* Masks for Flags field above */ |
172 | 188 | ||
173 | #define ACPI_GLOCK_PENDING 0x01 /* 00: Pending global lock ownership */ | 189 | #define ACPI_FACS_S4_BIOS_PRESENT (1) /* 00: S4BIOS support is present */ |
174 | #define ACPI_GLOCK_OWNED 0x02 /* 01: Global lock is owned */ | 190 | #define ACPI_FACS_64BIT_WAKE (1<<1) /* 01: 64-bit wake vector supported (ACPI 4.0) */ |
191 | |||
192 | /* Masks for ospm_flags field above */ | ||
193 | |||
194 | #define ACPI_FACS_64BIT_ENVIRONMENT (1) /* 00: 64-bit wake environment is required (ACPI 4.0) */ | ||
175 | 195 | ||
176 | /******************************************************************************* | 196 | /******************************************************************************* |
177 | * | 197 | * |
178 | * FADT - Fixed ACPI Description Table (Signature "FACP") | 198 | * FADT - Fixed ACPI Description Table (Signature "FACP") |
199 | * Version 4 | ||
179 | * | 200 | * |
180 | ******************************************************************************/ | 201 | ******************************************************************************/ |
181 | 202 | ||
@@ -236,7 +257,7 @@ struct acpi_table_fadt { | |||
236 | struct acpi_generic_address xgpe1_block; /* 64-bit Extended General Purpose Event 1 Reg Blk address */ | 257 | struct acpi_generic_address xgpe1_block; /* 64-bit Extended General Purpose Event 1 Reg Blk address */ |
237 | }; | 258 | }; |
238 | 259 | ||
239 | /* FADT Boot Architecture Flags (boot_flags) */ | 260 | /* Masks for FADT Boot Architecture Flags (boot_flags) */ |
240 | 261 | ||
241 | #define ACPI_FADT_LEGACY_DEVICES (1) /* 00: [V2] System has LPC or ISA bus devices */ | 262 | #define ACPI_FADT_LEGACY_DEVICES (1) /* 00: [V2] System has LPC or ISA bus devices */ |
242 | #define ACPI_FADT_8042 (1<<1) /* 01: [V3] System has an 8042 controller on port 60/64 */ | 263 | #define ACPI_FADT_8042 (1<<1) /* 01: [V3] System has an 8042 controller on port 60/64 */ |
@@ -246,7 +267,7 @@ struct acpi_table_fadt { | |||
246 | 267 | ||
247 | #define FADT2_REVISION_ID 3 | 268 | #define FADT2_REVISION_ID 3 |
248 | 269 | ||
249 | /* FADT flags */ | 270 | /* Masks for FADT flags */ |
250 | 271 | ||
251 | #define ACPI_FADT_WBINVD (1) /* 00: [V1] The wbinvd instruction works properly */ | 272 | #define ACPI_FADT_WBINVD (1) /* 00: [V1] The wbinvd instruction works properly */ |
252 | #define ACPI_FADT_WBINVD_FLUSH (1<<1) /* 01: [V1] wbinvd flushes but does not invalidate caches */ | 273 | #define ACPI_FADT_WBINVD_FLUSH (1<<1) /* 01: [V1] wbinvd flushes but does not invalidate caches */ |
@@ -269,7 +290,7 @@ struct acpi_table_fadt { | |||
269 | #define ACPI_FADT_APIC_CLUSTER (1<<18) /* 18: [V4] All local APICs must use cluster model (ACPI 3.0) */ | 290 | #define ACPI_FADT_APIC_CLUSTER (1<<18) /* 18: [V4] All local APICs must use cluster model (ACPI 3.0) */ |
270 | #define ACPI_FADT_APIC_PHYSICAL (1<<19) /* 19: [V4] All local x_aPICs must use physical dest mode (ACPI 3.0) */ | 291 | #define ACPI_FADT_APIC_PHYSICAL (1<<19) /* 19: [V4] All local x_aPICs must use physical dest mode (ACPI 3.0) */ |
271 | 292 | ||
272 | /* FADT Prefered Power Management Profiles */ | 293 | /* Values for preferred_profile (Prefered Power Management Profiles) */ |
273 | 294 | ||
274 | enum acpi_prefered_pm_profiles { | 295 | enum acpi_prefered_pm_profiles { |
275 | PM_UNSPECIFIED = 0, | 296 | PM_UNSPECIFIED = 0, |
@@ -287,14 +308,16 @@ enum acpi_prefered_pm_profiles { | |||
287 | 308 | ||
288 | #define ACPI_FADT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_fadt, f) | 309 | #define ACPI_FADT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_fadt, f) |
289 | 310 | ||
311 | /* | ||
312 | * Internal table-related structures | ||
313 | */ | ||
290 | union acpi_name_union { | 314 | union acpi_name_union { |
291 | u32 integer; | 315 | u32 integer; |
292 | char ascii[4]; | 316 | char ascii[4]; |
293 | }; | 317 | }; |
294 | 318 | ||
295 | /* | 319 | /* Internal ACPI Table Descriptor. One per ACPI table. */ |
296 | * Internal ACPI Table Descriptor. One per ACPI table | 320 | |
297 | */ | ||
298 | struct acpi_table_desc { | 321 | struct acpi_table_desc { |
299 | acpi_physical_address address; | 322 | acpi_physical_address address; |
300 | struct acpi_table_header *pointer; | 323 | struct acpi_table_header *pointer; |
@@ -304,7 +327,7 @@ struct acpi_table_desc { | |||
304 | u8 flags; | 327 | u8 flags; |
305 | }; | 328 | }; |
306 | 329 | ||
307 | /* Flags for above */ | 330 | /* Masks for Flags field above */ |
308 | 331 | ||
309 | #define ACPI_TABLE_ORIGIN_UNKNOWN (0) | 332 | #define ACPI_TABLE_ORIGIN_UNKNOWN (0) |
310 | #define ACPI_TABLE_ORIGIN_MAPPED (1) | 333 | #define ACPI_TABLE_ORIGIN_MAPPED (1) |
@@ -318,5 +341,6 @@ struct acpi_table_desc { | |||
318 | */ | 341 | */ |
319 | 342 | ||
320 | #include <acpi/actbl1.h> | 343 | #include <acpi/actbl1.h> |
344 | #include <acpi/actbl2.h> | ||
321 | 345 | ||
322 | #endif /* __ACTBL_H__ */ | 346 | #endif /* __ACTBL_H__ */ |
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index 59ade0752473..0b9b430b092b 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h | |||
@@ -46,41 +46,31 @@ | |||
46 | 46 | ||
47 | /******************************************************************************* | 47 | /******************************************************************************* |
48 | * | 48 | * |
49 | * Additional ACPI Tables | 49 | * Additional ACPI Tables (1) |
50 | * | 50 | * |
51 | * These tables are not consumed directly by the ACPICA subsystem, but are | 51 | * These tables are not consumed directly by the ACPICA subsystem, but are |
52 | * included here to support device drivers and the AML disassembler. | 52 | * included here to support device drivers and the AML disassembler. |
53 | * | 53 | * |
54 | * The tables in this file are fully defined within the ACPI specification. | ||
55 | * | ||
54 | ******************************************************************************/ | 56 | ******************************************************************************/ |
55 | 57 | ||
56 | /* | 58 | /* |
57 | * Values for description table header signatures. Useful because they make | 59 | * Values for description table header signatures for tables defined in this |
58 | * it more difficult to inadvertently type in the wrong signature. | 60 | * file. Useful because they make it more difficult to inadvertently type in |
61 | * the wrong signature. | ||
59 | */ | 62 | */ |
60 | #define ACPI_SIG_ASF "ASF!" /* Alert Standard Format table */ | ||
61 | #define ACPI_SIG_BERT "BERT" /* Boot Error Record Table */ | 63 | #define ACPI_SIG_BERT "BERT" /* Boot Error Record Table */ |
62 | #define ACPI_SIG_BOOT "BOOT" /* Simple Boot Flag Table */ | ||
63 | #define ACPI_SIG_CPEP "CPEP" /* Corrected Platform Error Polling table */ | 64 | #define ACPI_SIG_CPEP "CPEP" /* Corrected Platform Error Polling table */ |
64 | #define ACPI_SIG_DBGP "DBGP" /* Debug Port table */ | ||
65 | #define ACPI_SIG_DMAR "DMAR" /* DMA Remapping table */ | ||
66 | #define ACPI_SIG_ECDT "ECDT" /* Embedded Controller Boot Resources Table */ | 65 | #define ACPI_SIG_ECDT "ECDT" /* Embedded Controller Boot Resources Table */ |
67 | #define ACPI_SIG_EINJ "EINJ" /* Error Injection table */ | 66 | #define ACPI_SIG_EINJ "EINJ" /* Error Injection table */ |
68 | #define ACPI_SIG_ERST "ERST" /* Error Record Serialization Table */ | 67 | #define ACPI_SIG_ERST "ERST" /* Error Record Serialization Table */ |
69 | #define ACPI_SIG_HEST "HEST" /* Hardware Error Source Table */ | 68 | #define ACPI_SIG_HEST "HEST" /* Hardware Error Source Table */ |
70 | #define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */ | ||
71 | #define ACPI_SIG_IBFT "IBFT" /* i_sCSI Boot Firmware Table */ | ||
72 | #define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */ | 69 | #define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */ |
73 | #define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */ | 70 | #define ACPI_SIG_MSCT "MSCT" /* Maximum System Characteristics Table */ |
74 | #define ACPI_SIG_SBST "SBST" /* Smart Battery Specification Table */ | 71 | #define ACPI_SIG_SBST "SBST" /* Smart Battery Specification Table */ |
75 | #define ACPI_SIG_SLIC "SLIC" /* Software Licensing Description Table */ | ||
76 | #define ACPI_SIG_SLIT "SLIT" /* System Locality Distance Information Table */ | 72 | #define ACPI_SIG_SLIT "SLIT" /* System Locality Distance Information Table */ |
77 | #define ACPI_SIG_SPCR "SPCR" /* Serial Port Console Redirection table */ | ||
78 | #define ACPI_SIG_SPMI "SPMI" /* Server Platform Management Interface table */ | ||
79 | #define ACPI_SIG_SRAT "SRAT" /* System Resource Affinity Table */ | 73 | #define ACPI_SIG_SRAT "SRAT" /* System Resource Affinity 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 */ | ||
83 | #define ACPI_SIG_WDRT "WDRT" /* Watchdog Resource Table */ | ||
84 | 74 | ||
85 | /* | 75 | /* |
86 | * All tables must be byte-packed to match the ACPI specification, since | 76 | * All tables must be byte-packed to match the ACPI specification, since |
@@ -94,14 +84,20 @@ | |||
94 | * portable, so do not use any other bitfield types. | 84 | * portable, so do not use any other bitfield types. |
95 | */ | 85 | */ |
96 | 86 | ||
97 | /* Common Subtable header (used in MADT, SRAT, etc.) */ | 87 | /******************************************************************************* |
88 | * | ||
89 | * Common subtable headers | ||
90 | * | ||
91 | ******************************************************************************/ | ||
92 | |||
93 | /* Generic subtable header (used in MADT, SRAT, etc.) */ | ||
98 | 94 | ||
99 | struct acpi_subtable_header { | 95 | struct acpi_subtable_header { |
100 | u8 type; | 96 | u8 type; |
101 | u8 length; | 97 | u8 length; |
102 | }; | 98 | }; |
103 | 99 | ||
104 | /* Common Subtable header for WHEA tables (EINJ, ERST, WDAT) */ | 100 | /* Subtable header for WHEA tables (EINJ, ERST, WDAT) */ |
105 | 101 | ||
106 | struct acpi_whea_header { | 102 | struct acpi_whea_header { |
107 | u8 action; | 103 | u8 action; |
@@ -115,116 +111,8 @@ struct acpi_whea_header { | |||
115 | 111 | ||
116 | /******************************************************************************* | 112 | /******************************************************************************* |
117 | * | 113 | * |
118 | * ASF - Alert Standard Format table (Signature "ASF!") | 114 | * BERT - Boot Error Record Table (ACPI 4.0) |
119 | * | 115 | * Version 1 |
120 | * Conforms to the Alert Standard Format Specification V2.0, 23 April 2003 | ||
121 | * | ||
122 | ******************************************************************************/ | ||
123 | |||
124 | struct acpi_table_asf { | ||
125 | struct acpi_table_header header; /* Common ACPI table header */ | ||
126 | }; | ||
127 | |||
128 | /* ASF subtable header */ | ||
129 | |||
130 | struct acpi_asf_header { | ||
131 | u8 type; | ||
132 | u8 reserved; | ||
133 | u16 length; | ||
134 | }; | ||
135 | |||
136 | /* Values for Type field above */ | ||
137 | |||
138 | enum acpi_asf_type { | ||
139 | ACPI_ASF_TYPE_INFO = 0, | ||
140 | ACPI_ASF_TYPE_ALERT = 1, | ||
141 | ACPI_ASF_TYPE_CONTROL = 2, | ||
142 | ACPI_ASF_TYPE_BOOT = 3, | ||
143 | ACPI_ASF_TYPE_ADDRESS = 4, | ||
144 | ACPI_ASF_TYPE_RESERVED = 5 | ||
145 | }; | ||
146 | |||
147 | /* | ||
148 | * ASF subtables | ||
149 | */ | ||
150 | |||
151 | /* 0: ASF Information */ | ||
152 | |||
153 | struct acpi_asf_info { | ||
154 | struct acpi_asf_header header; | ||
155 | u8 min_reset_value; | ||
156 | u8 min_poll_interval; | ||
157 | u16 system_id; | ||
158 | u32 mfg_id; | ||
159 | u8 flags; | ||
160 | u8 reserved2[3]; | ||
161 | }; | ||
162 | |||
163 | /* 1: ASF Alerts */ | ||
164 | |||
165 | struct acpi_asf_alert { | ||
166 | struct acpi_asf_header header; | ||
167 | u8 assert_mask; | ||
168 | u8 deassert_mask; | ||
169 | u8 alerts; | ||
170 | u8 data_length; | ||
171 | }; | ||
172 | |||
173 | struct acpi_asf_alert_data { | ||
174 | u8 address; | ||
175 | u8 command; | ||
176 | u8 mask; | ||
177 | u8 value; | ||
178 | u8 sensor_type; | ||
179 | u8 type; | ||
180 | u8 offset; | ||
181 | u8 source_type; | ||
182 | u8 severity; | ||
183 | u8 sensor_number; | ||
184 | u8 entity; | ||
185 | u8 instance; | ||
186 | }; | ||
187 | |||
188 | /* 2: ASF Remote Control */ | ||
189 | |||
190 | struct acpi_asf_remote { | ||
191 | struct acpi_asf_header header; | ||
192 | u8 controls; | ||
193 | u8 data_length; | ||
194 | u16 reserved2; | ||
195 | }; | ||
196 | |||
197 | struct acpi_asf_control_data { | ||
198 | u8 function; | ||
199 | u8 address; | ||
200 | u8 command; | ||
201 | u8 value; | ||
202 | }; | ||
203 | |||
204 | /* 3: ASF RMCP Boot Options */ | ||
205 | |||
206 | struct acpi_asf_rmcp { | ||
207 | struct acpi_asf_header header; | ||
208 | u8 capabilities[7]; | ||
209 | u8 completion_code; | ||
210 | u32 enterprise_id; | ||
211 | u8 command; | ||
212 | u16 parameter; | ||
213 | u16 boot_options; | ||
214 | u16 oem_parameters; | ||
215 | }; | ||
216 | |||
217 | /* 4: ASF Address */ | ||
218 | |||
219 | struct acpi_asf_address { | ||
220 | struct acpi_asf_header header; | ||
221 | u8 eprom_address; | ||
222 | u8 devices; | ||
223 | }; | ||
224 | |||
225 | /******************************************************************************* | ||
226 | * | ||
227 | * BERT - Boot Error Record Table | ||
228 | * | 116 | * |
229 | ******************************************************************************/ | 117 | ******************************************************************************/ |
230 | 118 | ||
@@ -234,38 +122,43 @@ struct acpi_table_bert { | |||
234 | u64 address; /* Physical addresss of the error region */ | 122 | u64 address; /* Physical addresss of the error region */ |
235 | }; | 123 | }; |
236 | 124 | ||
237 | /* Boot Error Region */ | 125 | /* Boot Error Region (not a subtable, pointed to by Address field above) */ |
238 | 126 | ||
239 | struct acpi_bert_region { | 127 | struct acpi_bert_region { |
240 | u32 block_status; | 128 | u32 block_status; /* Type of error information */ |
241 | u32 raw_data_offset; | 129 | u32 raw_data_offset; /* Offset to raw error data */ |
242 | u32 raw_data_length; | 130 | u32 raw_data_length; /* Length of raw error data */ |
243 | u32 data_length; | 131 | u32 data_length; /* Length of generic error data */ |
244 | u32 error_severity; | 132 | u32 error_severity; /* Severity code */ |
245 | }; | 133 | }; |
246 | 134 | ||
247 | /* block_status Flags */ | 135 | /* Values for block_status flags above */ |
248 | 136 | ||
249 | #define ACPI_BERT_UNCORRECTABLE (1) | 137 | #define ACPI_BERT_UNCORRECTABLE (1) |
250 | #define ACPI_BERT_CORRECTABLE (2) | 138 | #define ACPI_BERT_CORRECTABLE (1<<1) |
251 | #define ACPI_BERT_MULTIPLE_UNCORRECTABLE (4) | 139 | #define ACPI_BERT_MULTIPLE_UNCORRECTABLE (1<<2) |
252 | #define ACPI_BERT_MULTIPLE_CORRECTABLE (8) | 140 | #define ACPI_BERT_MULTIPLE_CORRECTABLE (1<<3) |
141 | #define ACPI_BERT_ERROR_ENTRY_COUNT (0xFF<<4) /* 8 bits, error count */ | ||
253 | 142 | ||
254 | /******************************************************************************* | 143 | /* Values for error_severity above */ |
255 | * | ||
256 | * BOOT - Simple Boot Flag Table | ||
257 | * | ||
258 | ******************************************************************************/ | ||
259 | 144 | ||
260 | struct acpi_table_boot { | 145 | enum acpi_bert_error_severity { |
261 | struct acpi_table_header header; /* Common ACPI table header */ | 146 | ACPI_BERT_ERROR_CORRECTABLE = 0, |
262 | u8 cmos_index; /* Index in CMOS RAM for the boot register */ | 147 | ACPI_BERT_ERROR_FATAL = 1, |
263 | u8 reserved[3]; | 148 | ACPI_BERT_ERROR_CORRECTED = 2, |
149 | ACPI_BERT_ERROR_NONE = 3, | ||
150 | ACPI_BERT_ERROR_RESERVED = 4 /* 4 and greater are reserved */ | ||
264 | }; | 151 | }; |
265 | 152 | ||
153 | /* | ||
154 | * Note: The generic error data that follows the error_severity field above | ||
155 | * uses the struct acpi_hest_generic_data defined under the HEST table below | ||
156 | */ | ||
157 | |||
266 | /******************************************************************************* | 158 | /******************************************************************************* |
267 | * | 159 | * |
268 | * CPEP - Corrected Platform Error Polling table | 160 | * CPEP - Corrected Platform Error Polling table (ACPI 4.0) |
161 | * Version 1 | ||
269 | * | 162 | * |
270 | ******************************************************************************/ | 163 | ******************************************************************************/ |
271 | 164 | ||
@@ -277,8 +170,7 @@ struct acpi_table_cpep { | |||
277 | /* Subtable */ | 170 | /* Subtable */ |
278 | 171 | ||
279 | struct acpi_cpep_polling { | 172 | struct acpi_cpep_polling { |
280 | u8 type; | 173 | struct acpi_subtable_header header; |
281 | u8 length; | ||
282 | u8 id; /* Processor ID */ | 174 | u8 id; /* Processor ID */ |
283 | u8 eid; /* Processor EID */ | 175 | u8 eid; /* Processor EID */ |
284 | u32 interval; /* Polling interval (msec) */ | 176 | u32 interval; /* Polling interval (msec) */ |
@@ -286,124 +178,8 @@ struct acpi_cpep_polling { | |||
286 | 178 | ||
287 | /******************************************************************************* | 179 | /******************************************************************************* |
288 | * | 180 | * |
289 | * DBGP - Debug Port table | ||
290 | * | ||
291 | ******************************************************************************/ | ||
292 | |||
293 | struct acpi_table_dbgp { | ||
294 | struct acpi_table_header header; /* Common ACPI table header */ | ||
295 | u8 type; /* 0=full 16550, 1=subset of 16550 */ | ||
296 | u8 reserved[3]; | ||
297 | struct acpi_generic_address debug_port; | ||
298 | }; | ||
299 | |||
300 | /******************************************************************************* | ||
301 | * | ||
302 | * DMAR - DMA Remapping table | ||
303 | * From "Intel Virtualization Technology for Directed I/O", Sept. 2007 | ||
304 | * | ||
305 | ******************************************************************************/ | ||
306 | |||
307 | struct acpi_table_dmar { | ||
308 | struct acpi_table_header header; /* Common ACPI table header */ | ||
309 | u8 width; /* Host Address Width */ | ||
310 | u8 flags; | ||
311 | u8 reserved[10]; | ||
312 | }; | ||
313 | |||
314 | /* Flags */ | ||
315 | |||
316 | #define ACPI_DMAR_INTR_REMAP (1) | ||
317 | |||
318 | /* DMAR subtable header */ | ||
319 | |||
320 | struct acpi_dmar_header { | ||
321 | u16 type; | ||
322 | u16 length; | ||
323 | }; | ||
324 | |||
325 | /* Values for subtable type in struct acpi_dmar_header */ | ||
326 | |||
327 | enum acpi_dmar_type { | ||
328 | ACPI_DMAR_TYPE_HARDWARE_UNIT = 0, | ||
329 | ACPI_DMAR_TYPE_RESERVED_MEMORY = 1, | ||
330 | ACPI_DMAR_TYPE_ATSR = 2, | ||
331 | ACPI_DMAR_TYPE_RESERVED = 3 /* 3 and greater are reserved */ | ||
332 | }; | ||
333 | |||
334 | struct acpi_dmar_device_scope { | ||
335 | u8 entry_type; | ||
336 | u8 length; | ||
337 | u16 reserved; | ||
338 | u8 enumeration_id; | ||
339 | u8 bus; | ||
340 | }; | ||
341 | |||
342 | /* Values for entry_type in struct acpi_dmar_device_scope */ | ||
343 | |||
344 | enum acpi_dmar_scope_type { | ||
345 | ACPI_DMAR_SCOPE_TYPE_NOT_USED = 0, | ||
346 | ACPI_DMAR_SCOPE_TYPE_ENDPOINT = 1, | ||
347 | ACPI_DMAR_SCOPE_TYPE_BRIDGE = 2, | ||
348 | ACPI_DMAR_SCOPE_TYPE_IOAPIC = 3, | ||
349 | ACPI_DMAR_SCOPE_TYPE_HPET = 4, | ||
350 | ACPI_DMAR_SCOPE_TYPE_RESERVED = 5 /* 5 and greater are reserved */ | ||
351 | }; | ||
352 | |||
353 | struct acpi_dmar_pci_path { | ||
354 | u8 dev; | ||
355 | u8 fn; | ||
356 | }; | ||
357 | |||
358 | /* | ||
359 | * DMAR Sub-tables, correspond to Type in struct acpi_dmar_header | ||
360 | */ | ||
361 | |||
362 | /* 0: Hardware Unit Definition */ | ||
363 | |||
364 | struct acpi_dmar_hardware_unit { | ||
365 | struct acpi_dmar_header header; | ||
366 | u8 flags; | ||
367 | u8 reserved; | ||
368 | u16 segment; | ||
369 | u64 address; /* Register Base Address */ | ||
370 | }; | ||
371 | |||
372 | /* Flags */ | ||
373 | |||
374 | #define ACPI_DMAR_INCLUDE_ALL (1) | ||
375 | |||
376 | /* 1: Reserved Memory Defininition */ | ||
377 | |||
378 | struct acpi_dmar_reserved_memory { | ||
379 | struct acpi_dmar_header header; | ||
380 | u16 reserved; | ||
381 | u16 segment; | ||
382 | u64 base_address; /* 4_k aligned base address */ | ||
383 | u64 end_address; /* 4_k aligned limit address */ | ||
384 | }; | ||
385 | |||
386 | /* Flags */ | ||
387 | |||
388 | #define ACPI_DMAR_ALLOW_ALL (1) | ||
389 | |||
390 | |||
391 | /* 2: Root Port ATS Capability Reporting Structure */ | ||
392 | |||
393 | struct acpi_dmar_atsr { | ||
394 | struct acpi_dmar_header header; | ||
395 | u8 flags; | ||
396 | u8 reserved; | ||
397 | u16 segment; | ||
398 | }; | ||
399 | |||
400 | /* Flags */ | ||
401 | |||
402 | #define ACPI_DMAR_ALL_PORTS (1) | ||
403 | |||
404 | /******************************************************************************* | ||
405 | * | ||
406 | * ECDT - Embedded Controller Boot Resources Table | 181 | * ECDT - Embedded Controller Boot Resources Table |
182 | * Version 1 | ||
407 | * | 183 | * |
408 | ******************************************************************************/ | 184 | ******************************************************************************/ |
409 | 185 | ||
@@ -418,14 +194,16 @@ struct acpi_table_ecdt { | |||
418 | 194 | ||
419 | /******************************************************************************* | 195 | /******************************************************************************* |
420 | * | 196 | * |
421 | * EINJ - Error Injection Table | 197 | * EINJ - Error Injection Table (ACPI 4.0) |
198 | * Version 1 | ||
422 | * | 199 | * |
423 | ******************************************************************************/ | 200 | ******************************************************************************/ |
424 | 201 | ||
425 | struct acpi_table_einj { | 202 | struct acpi_table_einj { |
426 | struct acpi_table_header header; /* Common ACPI table header */ | 203 | struct acpi_table_header header; /* Common ACPI table header */ |
427 | u32 header_length; | 204 | u32 header_length; |
428 | u32 reserved; | 205 | u8 flags; |
206 | u8 reserved[3]; | ||
429 | u32 entries; | 207 | u32 entries; |
430 | }; | 208 | }; |
431 | 209 | ||
@@ -435,6 +213,10 @@ struct acpi_einj_entry { | |||
435 | struct acpi_whea_header whea_header; /* Common header for WHEA tables */ | 213 | struct acpi_whea_header whea_header; /* Common header for WHEA tables */ |
436 | }; | 214 | }; |
437 | 215 | ||
216 | /* Masks for Flags field above */ | ||
217 | |||
218 | #define ACPI_EINJ_PRESERVE (1) | ||
219 | |||
438 | /* Values for Action field above */ | 220 | /* Values for Action field above */ |
439 | 221 | ||
440 | enum acpi_einj_actions { | 222 | enum acpi_einj_actions { |
@@ -470,9 +252,34 @@ struct acpi_einj_trigger { | |||
470 | u32 entry_count; | 252 | u32 entry_count; |
471 | }; | 253 | }; |
472 | 254 | ||
255 | /* Command status return values */ | ||
256 | |||
257 | enum acpi_einj_command_status { | ||
258 | ACPI_EINJ_SUCCESS = 0, | ||
259 | ACPI_EINJ_FAILURE = 1, | ||
260 | ACPI_EINJ_INVALID_ACCESS = 2, | ||
261 | ACPI_EINJ_STATUS_RESERVED = 3 /* 3 and greater are reserved */ | ||
262 | }; | ||
263 | |||
264 | /* Error types returned from ACPI_EINJ_GET_ERROR_TYPE (bitfield) */ | ||
265 | |||
266 | #define ACPI_EINJ_PROCESSOR_CORRECTABLE (1) | ||
267 | #define ACPI_EINJ_PROCESSOR_UNCORRECTABLE (1<<1) | ||
268 | #define ACPI_EINJ_PROCESSOR_FATAL (1<<2) | ||
269 | #define ACPI_EINJ_MEMORY_CORRECTABLE (1<<3) | ||
270 | #define ACPI_EINJ_MEMORY_UNCORRECTABLE (1<<4) | ||
271 | #define ACPI_EINJ_MEMORY_FATAL (1<<5) | ||
272 | #define ACPI_EINJ_PCIX_CORRECTABLE (1<<6) | ||
273 | #define ACPI_EINJ_PCIX_UNCORRECTABLE (1<<7) | ||
274 | #define ACPI_EINJ_PCIX_FATAL (1<<8) | ||
275 | #define ACPI_EINJ_PLATFORM_CORRECTABLE (1<<9) | ||
276 | #define ACPI_EINJ_PLATFORM_UNCORRECTABLE (1<<10) | ||
277 | #define ACPI_EINJ_PLATFORM_FATAL (1<<11) | ||
278 | |||
473 | /******************************************************************************* | 279 | /******************************************************************************* |
474 | * | 280 | * |
475 | * ERST - Error Record Serialization Table | 281 | * ERST - Error Record Serialization Table (ACPI 4.0) |
282 | * Version 1 | ||
476 | * | 283 | * |
477 | ******************************************************************************/ | 284 | ******************************************************************************/ |
478 | 285 | ||
@@ -489,19 +296,23 @@ struct acpi_erst_entry { | |||
489 | struct acpi_whea_header whea_header; /* Common header for WHEA tables */ | 296 | struct acpi_whea_header whea_header; /* Common header for WHEA tables */ |
490 | }; | 297 | }; |
491 | 298 | ||
299 | /* Masks for Flags field above */ | ||
300 | |||
301 | #define ACPI_ERST_PRESERVE (1) | ||
302 | |||
492 | /* Values for Action field above */ | 303 | /* Values for Action field above */ |
493 | 304 | ||
494 | enum acpi_erst_actions { | 305 | enum acpi_erst_actions { |
495 | ACPI_ERST_BEGIN_WRITE_OPERATION = 0, | 306 | ACPI_ERST_BEGIN_WRITE = 0, |
496 | ACPI_ERST_BEGIN_READ_OPERATION = 1, | 307 | ACPI_ERST_BEGIN_READ = 1, |
497 | ACPI_ERST_BETGIN_CLEAR_OPERATION = 2, | 308 | ACPI_ERST_BEGIN_CLEAR = 2, |
498 | ACPI_ERST_END_OPERATION = 3, | 309 | ACPI_ERST_END = 3, |
499 | ACPI_ERST_SET_RECORD_OFFSET = 4, | 310 | ACPI_ERST_SET_RECORD_OFFSET = 4, |
500 | ACPI_ERST_EXECUTE_OPERATION = 5, | 311 | ACPI_ERST_EXECUTE_OPERATION = 5, |
501 | ACPI_ERST_CHECK_BUSY_STATUS = 6, | 312 | ACPI_ERST_CHECK_BUSY_STATUS = 6, |
502 | ACPI_ERST_GET_COMMAND_STATUS = 7, | 313 | ACPI_ERST_GET_COMMAND_STATUS = 7, |
503 | ACPI_ERST_GET_RECORD_IDENTIFIER = 8, | 314 | ACPI_ERST_GET_RECORD_ID = 8, |
504 | ACPI_ERST_SET_RECORD_IDENTIFIER = 9, | 315 | ACPI_ERST_SET_RECORD_ID = 9, |
505 | ACPI_ERST_GET_RECORD_COUNT = 10, | 316 | ACPI_ERST_GET_RECORD_COUNT = 10, |
506 | ACPI_ERST_BEGIN_DUMMY_WRIITE = 11, | 317 | ACPI_ERST_BEGIN_DUMMY_WRIITE = 11, |
507 | ACPI_ERST_NOT_USED = 12, | 318 | ACPI_ERST_NOT_USED = 12, |
@@ -536,9 +347,29 @@ enum acpi_erst_instructions { | |||
536 | ACPI_ERST_INSTRUCTION_RESERVED = 19 /* 19 and greater are reserved */ | 347 | ACPI_ERST_INSTRUCTION_RESERVED = 19 /* 19 and greater are reserved */ |
537 | }; | 348 | }; |
538 | 349 | ||
350 | /* Command status return values */ | ||
351 | |||
352 | enum acpi_erst_command_status { | ||
353 | ACPI_ERST_SUCESS = 0, | ||
354 | ACPI_ERST_NO_SPACE = 1, | ||
355 | ACPI_ERST_NOT_AVAILABLE = 2, | ||
356 | ACPI_ERST_FAILURE = 3, | ||
357 | ACPI_ERST_RECORD_EMPTY = 4, | ||
358 | ACPI_ERST_NOT_FOUND = 5, | ||
359 | ACPI_ERST_STATUS_RESERVED = 6 /* 6 and greater are reserved */ | ||
360 | }; | ||
361 | |||
362 | /* Error Record Serialization Information */ | ||
363 | |||
364 | struct acpi_erst_info { | ||
365 | u16 signature; /* Should be "ER" */ | ||
366 | u8 data[48]; | ||
367 | }; | ||
368 | |||
539 | /******************************************************************************* | 369 | /******************************************************************************* |
540 | * | 370 | * |
541 | * HEST - Hardware Error Source Table | 371 | * HEST - Hardware Error Source Table (ACPI 4.0) |
372 | * Version 1 | ||
542 | * | 373 | * |
543 | ******************************************************************************/ | 374 | ******************************************************************************/ |
544 | 375 | ||
@@ -551,85 +382,69 @@ struct acpi_table_hest { | |||
551 | 382 | ||
552 | struct acpi_hest_header { | 383 | struct acpi_hest_header { |
553 | u16 type; | 384 | u16 type; |
385 | u16 source_id; | ||
554 | }; | 386 | }; |
555 | 387 | ||
556 | /* Values for Type field above for subtables */ | 388 | /* Values for Type field above for subtables */ |
557 | 389 | ||
558 | enum acpi_hest_types { | 390 | enum acpi_hest_types { |
559 | ACPI_HEST_TYPE_XPF_MACHINE_CHECK = 0, | 391 | ACPI_HEST_TYPE_IA32_CHECK = 0, |
560 | ACPI_HEST_TYPE_XPF_CORRECTED_MACHINE_CHECK = 1, | 392 | ACPI_HEST_TYPE_IA32_CORRECTED_CHECK = 1, |
561 | ACPI_HEST_TYPE_XPF_UNUSED = 2, | 393 | ACPI_HEST_TYPE_IA32_NMI = 2, |
562 | ACPI_HEST_TYPE_XPF_NON_MASKABLE_INTERRUPT = 3, | 394 | ACPI_HEST_TYPE_NOT_USED3 = 3, |
563 | ACPI_HEST_TYPE_IPF_CORRECTED_MACHINE_CHECK = 4, | 395 | ACPI_HEST_TYPE_NOT_USED4 = 4, |
564 | ACPI_HEST_TYPE_IPF_CORRECTED_PLATFORM_ERROR = 5, | 396 | ACPI_HEST_TYPE_NOT_USED5 = 5, |
565 | ACPI_HEST_TYPE_AER_ROOT_PORT = 6, | 397 | ACPI_HEST_TYPE_AER_ROOT_PORT = 6, |
566 | ACPI_HEST_TYPE_AER_ENDPOINT = 7, | 398 | ACPI_HEST_TYPE_AER_ENDPOINT = 7, |
567 | ACPI_HEST_TYPE_AER_BRIDGE = 8, | 399 | ACPI_HEST_TYPE_AER_BRIDGE = 8, |
568 | ACPI_HEST_TYPE_GENERIC_HARDWARE_ERROR_SOURCE = 9, | 400 | ACPI_HEST_TYPE_GENERIC_ERROR = 9, |
569 | ACPI_HEST_TYPE_RESERVED = 10 /* 10 and greater are reserved */ | 401 | ACPI_HEST_TYPE_RESERVED = 10 /* 10 and greater are reserved */ |
570 | }; | 402 | }; |
571 | 403 | ||
572 | /* | 404 | /* |
573 | * HEST Sub-subtables | 405 | * HEST substructures contained in subtables |
574 | */ | 406 | */ |
575 | 407 | ||
576 | /* XPF Machine Check Error Bank */ | 408 | /* |
577 | 409 | * IA32 Error Bank(s) - Follows the struct acpi_hest_ia_machine_check and | |
578 | struct acpi_hest_xpf_error_bank { | 410 | * struct acpi_hest_ia_corrected structures. |
411 | */ | ||
412 | struct acpi_hest_ia_error_bank { | ||
579 | u8 bank_number; | 413 | u8 bank_number; |
580 | u8 clear_status_on_init; | 414 | u8 clear_status_on_init; |
581 | u8 status_format; | 415 | u8 status_format; |
582 | u8 config_write_enable; | 416 | u8 reserved; |
583 | u32 control_register; | 417 | u32 control_register; |
584 | u64 control_init_data; | 418 | u64 control_data; |
585 | u32 status_register; | 419 | u32 status_register; |
586 | u32 address_register; | 420 | u32 address_register; |
587 | u32 misc_register; | 421 | u32 misc_register; |
588 | }; | 422 | }; |
589 | 423 | ||
590 | /* Generic Error Status */ | 424 | /* Common HEST sub-structure for PCI/AER structures below (6,7,8) */ |
591 | |||
592 | struct acpi_hest_generic_status { | ||
593 | u32 block_status; | ||
594 | u32 raw_data_offset; | ||
595 | u32 raw_data_length; | ||
596 | u32 data_length; | ||
597 | u32 error_severity; | ||
598 | }; | ||
599 | |||
600 | /* Generic Error Data */ | ||
601 | |||
602 | struct acpi_hest_generic_data { | ||
603 | u8 section_type[16]; | ||
604 | u32 error_severity; | ||
605 | u16 revision; | ||
606 | u8 validation_bits; | ||
607 | u8 flags; | ||
608 | u32 error_data_length; | ||
609 | u8 fru_id[16]; | ||
610 | u8 fru_text[20]; | ||
611 | }; | ||
612 | |||
613 | /* Common HEST structure for PCI/AER types below (6,7,8) */ | ||
614 | 425 | ||
615 | struct acpi_hest_aer_common { | 426 | struct acpi_hest_aer_common { |
616 | u16 source_id; | 427 | u16 reserved1; |
617 | u16 config_write_enable; | ||
618 | u8 flags; | 428 | u8 flags; |
619 | u8 enabled; | 429 | u8 enabled; |
620 | u32 records_to_pre_allocate; | 430 | u32 records_to_preallocate; |
621 | u32 max_sections_per_record; | 431 | u32 max_sections_per_record; |
622 | u32 bus; | 432 | u32 bus; |
623 | u16 device; | 433 | u16 device; |
624 | u16 function; | 434 | u16 function; |
625 | u16 device_control; | 435 | u16 device_control; |
626 | u16 reserved; | 436 | u16 reserved2; |
627 | u32 uncorrectable_error_mask; | 437 | u32 uncorrectable_mask; |
628 | u32 uncorrectable_error_severity; | 438 | u32 uncorrectable_severity; |
629 | u32 correctable_error_mask; | 439 | u32 correctable_mask; |
630 | u32 advanced_error_capabilities; | 440 | u32 advanced_capabilities; |
631 | }; | 441 | }; |
632 | 442 | ||
443 | /* Masks for HEST Flags fields */ | ||
444 | |||
445 | #define ACPI_HEST_FIRMWARE_FIRST (1) | ||
446 | #define ACPI_HEST_GLOBAL (1<<1) | ||
447 | |||
633 | /* Hardware Error Notification */ | 448 | /* Hardware Error Notification */ |
634 | 449 | ||
635 | struct acpi_hest_notify { | 450 | struct acpi_hest_notify { |
@@ -655,71 +470,59 @@ enum acpi_hest_notify_types { | |||
655 | ACPI_HEST_NOTIFY_RESERVED = 5 /* 5 and greater are reserved */ | 470 | ACPI_HEST_NOTIFY_RESERVED = 5 /* 5 and greater are reserved */ |
656 | }; | 471 | }; |
657 | 472 | ||
473 | /* Values for config_write_enable bitfield above */ | ||
474 | |||
475 | #define ACPI_HEST_TYPE (1) | ||
476 | #define ACPI_HEST_POLL_INTERVAL (1<<1) | ||
477 | #define ACPI_HEST_POLL_THRESHOLD_VALUE (1<<2) | ||
478 | #define ACPI_HEST_POLL_THRESHOLD_WINDOW (1<<3) | ||
479 | #define ACPI_HEST_ERR_THRESHOLD_VALUE (1<<4) | ||
480 | #define ACPI_HEST_ERR_THRESHOLD_WINDOW (1<<5) | ||
481 | |||
658 | /* | 482 | /* |
659 | * HEST subtables | 483 | * HEST subtables |
660 | * | ||
661 | * From WHEA Design Document, 16 May 2007. | ||
662 | * Note: There is no subtable type 2 in this version of the document, | ||
663 | * and there are two different subtable type 3s. | ||
664 | */ | 484 | */ |
665 | 485 | ||
666 | /* 0: XPF Machine Check Exception */ | 486 | /* 0: IA32 Machine Check Exception */ |
667 | 487 | ||
668 | struct acpi_hest_xpf_machine_check { | 488 | struct acpi_hest_ia_machine_check { |
669 | struct acpi_hest_header header; | 489 | struct acpi_hest_header header; |
670 | u16 source_id; | 490 | u16 reserved1; |
671 | u16 config_write_enable; | ||
672 | u8 flags; | 491 | u8 flags; |
673 | u8 reserved1; | 492 | u8 enabled; |
674 | u32 records_to_pre_allocate; | 493 | u32 records_to_preallocate; |
675 | u32 max_sections_per_record; | 494 | u32 max_sections_per_record; |
676 | u64 global_capability_data; | 495 | u64 global_capability_data; |
677 | u64 global_control_data; | 496 | u64 global_control_data; |
678 | u8 num_hardware_banks; | 497 | u8 num_hardware_banks; |
679 | u8 reserved2[7]; | 498 | u8 reserved3[7]; |
680 | }; | 499 | }; |
681 | 500 | ||
682 | /* 1: XPF Corrected Machine Check */ | 501 | /* 1: IA32 Corrected Machine Check */ |
683 | 502 | ||
684 | struct acpi_table_hest_xpf_corrected { | 503 | struct acpi_hest_ia_corrected { |
685 | struct acpi_hest_header header; | 504 | struct acpi_hest_header header; |
686 | u16 source_id; | 505 | u16 reserved1; |
687 | u16 config_write_enable; | ||
688 | u8 flags; | 506 | u8 flags; |
689 | u8 enabled; | 507 | u8 enabled; |
690 | u32 records_to_pre_allocate; | 508 | u32 records_to_preallocate; |
691 | u32 max_sections_per_record; | 509 | u32 max_sections_per_record; |
692 | struct acpi_hest_notify notify; | 510 | struct acpi_hest_notify notify; |
693 | u8 num_hardware_banks; | 511 | u8 num_hardware_banks; |
694 | u8 reserved[3]; | 512 | u8 reserved2[3]; |
695 | }; | 513 | }; |
696 | 514 | ||
697 | /* 3: XPF Non-Maskable Interrupt */ | 515 | /* 2: IA32 Non-Maskable Interrupt */ |
698 | 516 | ||
699 | struct acpi_hest_xpf_nmi { | 517 | struct acpi_hest_ia_nmi { |
700 | struct acpi_hest_header header; | 518 | struct acpi_hest_header header; |
701 | u16 source_id; | ||
702 | u32 reserved; | 519 | u32 reserved; |
703 | u32 records_to_pre_allocate; | 520 | u32 records_to_preallocate; |
704 | u32 max_sections_per_record; | 521 | u32 max_sections_per_record; |
705 | u32 max_raw_data_length; | 522 | u32 max_raw_data_length; |
706 | }; | 523 | }; |
707 | 524 | ||
708 | /* 4: IPF Corrected Machine Check */ | 525 | /* 3,4,5: Not used */ |
709 | |||
710 | struct acpi_hest_ipf_corrected { | ||
711 | struct acpi_hest_header header; | ||
712 | u8 enabled; | ||
713 | u8 reserved; | ||
714 | }; | ||
715 | |||
716 | /* 5: IPF Corrected Platform Error */ | ||
717 | |||
718 | struct acpi_hest_ipf_corrected_platform { | ||
719 | struct acpi_hest_header header; | ||
720 | u8 enabled; | ||
721 | u8 reserved; | ||
722 | }; | ||
723 | 526 | ||
724 | /* 6: PCI Express Root Port AER */ | 527 | /* 6: PCI Express Root Port AER */ |
725 | 528 | ||
@@ -741,143 +544,61 @@ struct acpi_hest_aer { | |||
741 | struct acpi_hest_aer_bridge { | 544 | struct acpi_hest_aer_bridge { |
742 | struct acpi_hest_header header; | 545 | struct acpi_hest_header header; |
743 | struct acpi_hest_aer_common aer; | 546 | struct acpi_hest_aer_common aer; |
744 | u32 secondary_uncorrectable_error_mask; | 547 | u32 uncorrectable_mask2; |
745 | u32 secondary_uncorrectable_error_severity; | 548 | u32 uncorrectable_severity2; |
746 | u32 secondary_advanced_capabilities; | 549 | u32 advanced_capabilities2; |
747 | }; | 550 | }; |
748 | 551 | ||
749 | /* 9: Generic Hardware Error Source */ | 552 | /* 9: Generic Hardware Error Source */ |
750 | 553 | ||
751 | struct acpi_hest_generic { | 554 | struct acpi_hest_generic { |
752 | struct acpi_hest_header header; | 555 | struct acpi_hest_header header; |
753 | u16 source_id; | ||
754 | u16 related_source_id; | 556 | u16 related_source_id; |
755 | u8 config_write_enable; | 557 | u8 reserved; |
756 | u8 enabled; | 558 | u8 enabled; |
757 | u32 records_to_pre_allocate; | 559 | u32 records_to_preallocate; |
758 | u32 max_sections_per_record; | 560 | u32 max_sections_per_record; |
759 | u32 max_raw_data_length; | 561 | u32 max_raw_data_length; |
760 | struct acpi_generic_address error_status_address; | 562 | struct acpi_generic_address error_status_address; |
761 | struct acpi_hest_notify notify; | 563 | struct acpi_hest_notify notify; |
762 | u32 error_status_block_length; | 564 | u32 error_block_length; |
763 | }; | 565 | }; |
764 | 566 | ||
765 | /******************************************************************************* | 567 | /* Generic Error Status block */ |
766 | * | ||
767 | * HPET - High Precision Event Timer table | ||
768 | * | ||
769 | ******************************************************************************/ | ||
770 | 568 | ||
771 | struct acpi_table_hpet { | 569 | struct acpi_hest_generic_status { |
772 | struct acpi_table_header header; /* Common ACPI table header */ | 570 | u32 block_status; |
773 | u32 id; /* Hardware ID of event timer block */ | 571 | u32 raw_data_offset; |
774 | struct acpi_generic_address address; /* Address of event timer block */ | 572 | u32 raw_data_length; |
775 | u8 sequence; /* HPET sequence number */ | 573 | u32 data_length; |
776 | u16 minimum_tick; /* Main counter min tick, periodic mode */ | 574 | u32 error_severity; |
777 | u8 flags; | ||
778 | }; | 575 | }; |
779 | 576 | ||
780 | /*! Flags */ | 577 | /* Values for block_status flags above */ |
781 | 578 | ||
782 | #define ACPI_HPET_PAGE_PROTECT (1) /* 00: No page protection */ | 579 | #define ACPI_HEST_UNCORRECTABLE (1) |
783 | #define ACPI_HPET_PAGE_PROTECT_4 (1<<1) /* 01: 4KB page protected */ | 580 | #define ACPI_HEST_CORRECTABLE (1<<1) |
784 | #define ACPI_HPET_PAGE_PROTECT_64 (1<<2) /* 02: 64KB page protected */ | 581 | #define ACPI_HEST_MULTIPLE_UNCORRECTABLE (1<<2) |
582 | #define ACPI_HEST_MULTIPLE_CORRECTABLE (1<<3) | ||
583 | #define ACPI_HEST_ERROR_ENTRY_COUNT (0xFF<<4) /* 8 bits, error count */ | ||
785 | 584 | ||
786 | /*! [End] no source code translation !*/ | 585 | /* Generic Error Data entry */ |
787 | 586 | ||
788 | /******************************************************************************* | 587 | struct acpi_hest_generic_data { |
789 | * | 588 | u8 section_type[16]; |
790 | * IBFT - Boot Firmware Table | 589 | u32 error_severity; |
791 | * | 590 | u16 revision; |
792 | ******************************************************************************/ | 591 | u8 validation_bits; |
793 | |||
794 | struct acpi_table_ibft { | ||
795 | struct acpi_table_header header; /* Common ACPI table header */ | ||
796 | u8 reserved[12]; | ||
797 | }; | ||
798 | |||
799 | /* IBFT common subtable header */ | ||
800 | |||
801 | struct acpi_ibft_header { | ||
802 | u8 type; | ||
803 | u8 version; | ||
804 | u16 length; | ||
805 | u8 index; | ||
806 | u8 flags; | 592 | u8 flags; |
807 | }; | 593 | u32 error_data_length; |
808 | 594 | u8 fru_id[16]; | |
809 | /* Values for Type field above */ | 595 | u8 fru_text[20]; |
810 | |||
811 | enum acpi_ibft_type { | ||
812 | ACPI_IBFT_TYPE_NOT_USED = 0, | ||
813 | ACPI_IBFT_TYPE_CONTROL = 1, | ||
814 | ACPI_IBFT_TYPE_INITIATOR = 2, | ||
815 | ACPI_IBFT_TYPE_NIC = 3, | ||
816 | ACPI_IBFT_TYPE_TARGET = 4, | ||
817 | ACPI_IBFT_TYPE_EXTENSIONS = 5, | ||
818 | ACPI_IBFT_TYPE_RESERVED = 6 /* 6 and greater are reserved */ | ||
819 | }; | ||
820 | |||
821 | /* IBFT subtables */ | ||
822 | |||
823 | struct acpi_ibft_control { | ||
824 | struct acpi_ibft_header header; | ||
825 | u16 extensions; | ||
826 | u16 initiator_offset; | ||
827 | u16 nic0_offset; | ||
828 | u16 target0_offset; | ||
829 | u16 nic1_offset; | ||
830 | u16 target1_offset; | ||
831 | }; | ||
832 | |||
833 | struct acpi_ibft_initiator { | ||
834 | struct acpi_ibft_header header; | ||
835 | u8 sns_server[16]; | ||
836 | u8 slp_server[16]; | ||
837 | u8 primary_server[16]; | ||
838 | u8 secondary_server[16]; | ||
839 | u16 name_length; | ||
840 | u16 name_offset; | ||
841 | }; | ||
842 | |||
843 | struct acpi_ibft_nic { | ||
844 | struct acpi_ibft_header header; | ||
845 | u8 ip_address[16]; | ||
846 | u8 subnet_mask_prefix; | ||
847 | u8 origin; | ||
848 | u8 gateway[16]; | ||
849 | u8 primary_dns[16]; | ||
850 | u8 secondary_dns[16]; | ||
851 | u8 dhcp[16]; | ||
852 | u16 vlan; | ||
853 | u8 mac_address[6]; | ||
854 | u16 pci_address; | ||
855 | u16 name_length; | ||
856 | u16 name_offset; | ||
857 | }; | ||
858 | |||
859 | struct acpi_ibft_target { | ||
860 | struct acpi_ibft_header header; | ||
861 | u8 target_ip_address[16]; | ||
862 | u16 target_ip_socket; | ||
863 | u8 target_boot_lun[8]; | ||
864 | u8 chap_type; | ||
865 | u8 nic_association; | ||
866 | u16 target_name_length; | ||
867 | u16 target_name_offset; | ||
868 | u16 chap_name_length; | ||
869 | u16 chap_name_offset; | ||
870 | u16 chap_secret_length; | ||
871 | u16 chap_secret_offset; | ||
872 | u16 reverse_chap_name_length; | ||
873 | u16 reverse_chap_name_offset; | ||
874 | u16 reverse_chap_secret_length; | ||
875 | u16 reverse_chap_secret_offset; | ||
876 | }; | 596 | }; |
877 | 597 | ||
878 | /******************************************************************************* | 598 | /******************************************************************************* |
879 | * | 599 | * |
880 | * MADT - Multiple APIC Description Table | 600 | * MADT - Multiple APIC Description Table |
601 | * Version 3 | ||
881 | * | 602 | * |
882 | ******************************************************************************/ | 603 | ******************************************************************************/ |
883 | 604 | ||
@@ -887,16 +608,16 @@ struct acpi_table_madt { | |||
887 | u32 flags; | 608 | u32 flags; |
888 | }; | 609 | }; |
889 | 610 | ||
890 | /* Flags */ | 611 | /* Masks for Flags field above */ |
891 | 612 | ||
892 | #define ACPI_MADT_PCAT_COMPAT (1) /* 00: System also has dual 8259s */ | 613 | #define ACPI_MADT_PCAT_COMPAT (1) /* 00: System also has dual 8259s */ |
893 | 614 | ||
894 | /* Values for PCATCompat flag */ | 615 | /* Values for PCATCompat flag */ |
895 | 616 | ||
896 | #define ACPI_MADT_DUAL_PIC 0 | 617 | #define ACPI_MADT_DUAL_PIC 0 |
897 | #define ACPI_MADT_MULTIPLE_APIC 1 | 618 | #define ACPI_MADT_MULTIPLE_APIC 1 |
898 | 619 | ||
899 | /* Values for subtable type in struct acpi_subtable_header */ | 620 | /* Values for MADT subtable type in struct acpi_subtable_header */ |
900 | 621 | ||
901 | enum acpi_madt_type { | 622 | enum acpi_madt_type { |
902 | ACPI_MADT_TYPE_LOCAL_APIC = 0, | 623 | ACPI_MADT_TYPE_LOCAL_APIC = 0, |
@@ -1007,11 +728,11 @@ struct acpi_madt_interrupt_source { | |||
1007 | u32 flags; /* Interrupt Source Flags */ | 728 | u32 flags; /* Interrupt Source Flags */ |
1008 | }; | 729 | }; |
1009 | 730 | ||
1010 | /* Flags field above */ | 731 | /* Masks for Flags field above */ |
1011 | 732 | ||
1012 | #define ACPI_MADT_CPEI_OVERRIDE (1) | 733 | #define ACPI_MADT_CPEI_OVERRIDE (1) |
1013 | 734 | ||
1014 | /* 9: Processor Local X2_APIC (07/2008) */ | 735 | /* 9: Processor Local X2APIC (ACPI 4.0) */ |
1015 | 736 | ||
1016 | struct acpi_madt_local_x2apic { | 737 | struct acpi_madt_local_x2apic { |
1017 | struct acpi_subtable_header header; | 738 | struct acpi_subtable_header header; |
@@ -1021,7 +742,7 @@ struct acpi_madt_local_x2apic { | |||
1021 | u32 uid; /* ACPI processor UID */ | 742 | u32 uid; /* ACPI processor UID */ |
1022 | }; | 743 | }; |
1023 | 744 | ||
1024 | /* 10: Local X2APIC NMI (07/2008) */ | 745 | /* 10: Local X2APIC NMI (ACPI 4.0) */ |
1025 | 746 | ||
1026 | struct acpi_madt_local_x2apic_nmi { | 747 | struct acpi_madt_local_x2apic_nmi { |
1027 | struct acpi_subtable_header header; | 748 | struct acpi_subtable_header header; |
@@ -1058,28 +779,34 @@ struct acpi_madt_local_x2apic_nmi { | |||
1058 | 779 | ||
1059 | /******************************************************************************* | 780 | /******************************************************************************* |
1060 | * | 781 | * |
1061 | * MCFG - PCI Memory Mapped Configuration table and sub-table | 782 | * MSCT - Maximum System Characteristics Table (ACPI 4.0) |
783 | * Version 1 | ||
1062 | * | 784 | * |
1063 | ******************************************************************************/ | 785 | ******************************************************************************/ |
1064 | 786 | ||
1065 | struct acpi_table_mcfg { | 787 | struct acpi_table_msct { |
1066 | struct acpi_table_header header; /* Common ACPI table header */ | 788 | struct acpi_table_header header; /* Common ACPI table header */ |
1067 | u8 reserved[8]; | 789 | u32 proximity_offset; /* Location of proximity info struct(s) */ |
790 | u32 max_proximity_domains; /* Max number of proximity domains */ | ||
791 | u32 max_clock_domains; /* Max number of clock domains */ | ||
792 | u64 max_address; /* Max physical address in system */ | ||
1068 | }; | 793 | }; |
1069 | 794 | ||
1070 | /* Subtable */ | 795 | /* Subtable - Maximum Proximity Domain Information. Version 1 */ |
1071 | 796 | ||
1072 | struct acpi_mcfg_allocation { | 797 | struct acpi_msct_proximity { |
1073 | u64 address; /* Base address, processor-relative */ | 798 | u8 revision; |
1074 | u16 pci_segment; /* PCI segment group number */ | 799 | u8 length; |
1075 | u8 start_bus_number; /* Starting PCI Bus number */ | 800 | u32 range_start; /* Start of domain range */ |
1076 | u8 end_bus_number; /* Final PCI Bus number */ | 801 | u32 range_end; /* End of domain range */ |
1077 | u32 reserved; | 802 | u32 processor_capacity; |
803 | u64 memory_capacity; /* In bytes */ | ||
1078 | }; | 804 | }; |
1079 | 805 | ||
1080 | /******************************************************************************* | 806 | /******************************************************************************* |
1081 | * | 807 | * |
1082 | * SBST - Smart Battery Specification Table | 808 | * SBST - Smart Battery Specification Table |
809 | * Version 1 | ||
1083 | * | 810 | * |
1084 | ******************************************************************************/ | 811 | ******************************************************************************/ |
1085 | 812 | ||
@@ -1093,6 +820,7 @@ struct acpi_table_sbst { | |||
1093 | /******************************************************************************* | 820 | /******************************************************************************* |
1094 | * | 821 | * |
1095 | * SLIT - System Locality Distance Information Table | 822 | * SLIT - System Locality Distance Information Table |
823 | * Version 1 | ||
1096 | * | 824 | * |
1097 | ******************************************************************************/ | 825 | ******************************************************************************/ |
1098 | 826 | ||
@@ -1104,60 +832,8 @@ struct acpi_table_slit { | |||
1104 | 832 | ||
1105 | /******************************************************************************* | 833 | /******************************************************************************* |
1106 | * | 834 | * |
1107 | * SPCR - Serial Port Console Redirection table | ||
1108 | * | ||
1109 | ******************************************************************************/ | ||
1110 | |||
1111 | struct acpi_table_spcr { | ||
1112 | struct acpi_table_header header; /* Common ACPI table header */ | ||
1113 | u8 interface_type; /* 0=full 16550, 1=subset of 16550 */ | ||
1114 | u8 reserved[3]; | ||
1115 | struct acpi_generic_address serial_port; | ||
1116 | u8 interrupt_type; | ||
1117 | u8 pc_interrupt; | ||
1118 | u32 interrupt; | ||
1119 | u8 baud_rate; | ||
1120 | u8 parity; | ||
1121 | u8 stop_bits; | ||
1122 | u8 flow_control; | ||
1123 | u8 terminal_type; | ||
1124 | u8 reserved1; | ||
1125 | u16 pci_device_id; | ||
1126 | u16 pci_vendor_id; | ||
1127 | u8 pci_bus; | ||
1128 | u8 pci_device; | ||
1129 | u8 pci_function; | ||
1130 | u32 pci_flags; | ||
1131 | u8 pci_segment; | ||
1132 | u32 reserved2; | ||
1133 | }; | ||
1134 | |||
1135 | /******************************************************************************* | ||
1136 | * | ||
1137 | * SPMI - Server Platform Management Interface table | ||
1138 | * | ||
1139 | ******************************************************************************/ | ||
1140 | |||
1141 | struct acpi_table_spmi { | ||
1142 | struct acpi_table_header header; /* Common ACPI table header */ | ||
1143 | u8 reserved; | ||
1144 | u8 interface_type; | ||
1145 | u16 spec_revision; /* Version of IPMI */ | ||
1146 | u8 interrupt_type; | ||
1147 | u8 gpe_number; /* GPE assigned */ | ||
1148 | u8 reserved1; | ||
1149 | u8 pci_device_flag; | ||
1150 | u32 interrupt; | ||
1151 | struct acpi_generic_address ipmi_register; | ||
1152 | u8 pci_segment; | ||
1153 | u8 pci_bus; | ||
1154 | u8 pci_device; | ||
1155 | u8 pci_function; | ||
1156 | }; | ||
1157 | |||
1158 | /******************************************************************************* | ||
1159 | * | ||
1160 | * SRAT - System Resource Affinity Table | 835 | * SRAT - System Resource Affinity Table |
836 | * Version 3 | ||
1161 | * | 837 | * |
1162 | ******************************************************************************/ | 838 | ******************************************************************************/ |
1163 | 839 | ||
@@ -1192,6 +868,10 @@ struct acpi_srat_cpu_affinity { | |||
1192 | u32 reserved; /* Reserved, must be zero */ | 868 | u32 reserved; /* Reserved, must be zero */ |
1193 | }; | 869 | }; |
1194 | 870 | ||
871 | /* Flags */ | ||
872 | |||
873 | #define ACPI_SRAT_CPU_USE_AFFINITY (1) /* 00: Use affinity structure */ | ||
874 | |||
1195 | /* 1: Memory Affinity */ | 875 | /* 1: Memory Affinity */ |
1196 | 876 | ||
1197 | struct acpi_srat_mem_affinity { | 877 | struct acpi_srat_mem_affinity { |
@@ -1211,7 +891,7 @@ struct acpi_srat_mem_affinity { | |||
1211 | #define ACPI_SRAT_MEM_HOT_PLUGGABLE (1<<1) /* 01: Memory region is hot pluggable */ | 891 | #define ACPI_SRAT_MEM_HOT_PLUGGABLE (1<<1) /* 01: Memory region is hot pluggable */ |
1212 | #define ACPI_SRAT_MEM_NON_VOLATILE (1<<2) /* 02: Memory region is non-volatile */ | 892 | #define ACPI_SRAT_MEM_NON_VOLATILE (1<<2) /* 02: Memory region is non-volatile */ |
1213 | 893 | ||
1214 | /* 2: Processor Local X2_APIC Affinity (07/2008) */ | 894 | /* 2: Processor Local X2_APIC Affinity (ACPI 4.0) */ |
1215 | 895 | ||
1216 | struct acpi_srat_x2apic_cpu_affinity { | 896 | struct acpi_srat_x2apic_cpu_affinity { |
1217 | struct acpi_subtable_header header; | 897 | struct acpi_subtable_header header; |
@@ -1219,122 +899,14 @@ struct acpi_srat_x2apic_cpu_affinity { | |||
1219 | u32 proximity_domain; | 899 | u32 proximity_domain; |
1220 | u32 apic_id; | 900 | u32 apic_id; |
1221 | u32 flags; | 901 | u32 flags; |
902 | u32 clock_domain; | ||
903 | u32 reserved2; | ||
1222 | }; | 904 | }; |
1223 | 905 | ||
1224 | /* Flags for struct acpi_srat_cpu_affinity and struct acpi_srat_x2apic_cpu_affinity */ | 906 | /* Flags for struct acpi_srat_cpu_affinity and struct acpi_srat_x2apic_cpu_affinity */ |
1225 | 907 | ||
1226 | #define ACPI_SRAT_CPU_ENABLED (1) /* 00: Use affinity structure */ | 908 | #define ACPI_SRAT_CPU_ENABLED (1) /* 00: Use affinity structure */ |
1227 | 909 | ||
1228 | /******************************************************************************* | ||
1229 | * | ||
1230 | * TCPA - Trusted Computing Platform Alliance table | ||
1231 | * | ||
1232 | ******************************************************************************/ | ||
1233 | |||
1234 | struct acpi_table_tcpa { | ||
1235 | struct acpi_table_header header; /* Common ACPI table header */ | ||
1236 | u16 reserved; | ||
1237 | u32 max_log_length; /* Maximum length for the event log area */ | ||
1238 | u64 log_address; /* Address of the event log area */ | ||
1239 | }; | ||
1240 | |||
1241 | /******************************************************************************* | ||
1242 | * | ||
1243 | * UEFI - UEFI Boot optimization Table | ||
1244 | * | ||
1245 | ******************************************************************************/ | ||
1246 | |||
1247 | struct acpi_table_uefi { | ||
1248 | struct acpi_table_header header; /* Common ACPI table header */ | ||
1249 | u8 identifier[16]; /* UUID identifier */ | ||
1250 | u16 data_offset; /* Offset of remaining data in table */ | ||
1251 | u8 data; | ||
1252 | }; | ||
1253 | |||
1254 | /******************************************************************************* | ||
1255 | * | ||
1256 | * WDAT - Watchdog Action Table | ||
1257 | * | ||
1258 | ******************************************************************************/ | ||
1259 | |||
1260 | struct acpi_table_wdat { | ||
1261 | struct acpi_table_header header; /* Common ACPI table header */ | ||
1262 | u32 header_length; /* Watchdog Header Length */ | ||
1263 | u16 pci_segment; /* PCI Segment number */ | ||
1264 | u8 pci_bus; /* PCI Bus number */ | ||
1265 | u8 pci_device; /* PCI Device number */ | ||
1266 | u8 pci_function; /* PCI Function number */ | ||
1267 | u8 reserved[3]; | ||
1268 | u32 timer_period; /* Period of one timer count (msec) */ | ||
1269 | u32 max_count; /* Maximum counter value supported */ | ||
1270 | u32 min_count; /* Minimum counter value */ | ||
1271 | u8 flags; | ||
1272 | u8 reserved2[3]; | ||
1273 | u32 entries; /* Number of watchdog entries that follow */ | ||
1274 | }; | ||
1275 | |||
1276 | /* WDAT Instruction Entries (actions) */ | ||
1277 | |||
1278 | struct acpi_wdat_entry { | ||
1279 | struct acpi_whea_header whea_header; /* Common header for WHEA tables */ | ||
1280 | }; | ||
1281 | |||
1282 | /* Values for Action field above */ | ||
1283 | |||
1284 | enum acpi_wdat_actions { | ||
1285 | ACPI_WDAT_RESET = 1, | ||
1286 | ACPI_WDAT_GET_CURRENT_COUNTDOWN = 4, | ||
1287 | ACPI_WDAT_GET_COUNTDOWN = 5, | ||
1288 | ACPI_WDAT_SET_COUNTDOWN = 6, | ||
1289 | ACPI_WDAT_GET_RUNNING_STATE = 8, | ||
1290 | ACPI_WDAT_SET_RUNNING_STATE = 9, | ||
1291 | ACPI_WDAT_GET_STOPPED_STATE = 10, | ||
1292 | ACPI_WDAT_SET_STOPPED_STATE = 11, | ||
1293 | ACPI_WDAT_GET_REBOOT = 16, | ||
1294 | ACPI_WDAT_SET_REBOOT = 17, | ||
1295 | ACPI_WDAT_GET_SHUTDOWN = 18, | ||
1296 | ACPI_WDAT_SET_SHUTDOWN = 19, | ||
1297 | ACPI_WDAT_GET_STATUS = 32, | ||
1298 | ACPI_WDAT_SET_STATUS = 33, | ||
1299 | ACPI_WDAT_ACTION_RESERVED = 34 /* 34 and greater are reserved */ | ||
1300 | }; | ||
1301 | |||
1302 | /* Values for Instruction field above */ | ||
1303 | |||
1304 | enum acpi_wdat_instructions { | ||
1305 | ACPI_WDAT_READ_VALUE = 0, | ||
1306 | ACPI_WDAT_READ_COUNTDOWN = 1, | ||
1307 | ACPI_WDAT_WRITE_VALUE = 2, | ||
1308 | ACPI_WDAT_WRITE_COUNTDOWN = 3, | ||
1309 | ACPI_WDAT_INSTRUCTION_RESERVED = 4, /* 4 and greater are reserved */ | ||
1310 | ACPI_WDAT_PRESERVE_REGISTER = 0x80 /* Except for this value */ | ||
1311 | }; | ||
1312 | |||
1313 | /******************************************************************************* | ||
1314 | * | ||
1315 | * WDRT - Watchdog Resource Table | ||
1316 | * | ||
1317 | ******************************************************************************/ | ||
1318 | |||
1319 | struct acpi_table_wdrt { | ||
1320 | struct acpi_table_header header; /* Common ACPI table header */ | ||
1321 | u32 header_length; /* Watchdog Header Length */ | ||
1322 | u8 pci_segment; /* PCI Segment number */ | ||
1323 | u8 pci_bus; /* PCI Bus number */ | ||
1324 | u8 pci_device; /* PCI Device number */ | ||
1325 | u8 pci_function; /* PCI Function number */ | ||
1326 | u32 timer_period; /* Period of one timer count (msec) */ | ||
1327 | u32 max_count; /* Maximum counter value supported */ | ||
1328 | u32 min_count; /* Minimum counter value */ | ||
1329 | u8 flags; | ||
1330 | u8 reserved[3]; | ||
1331 | u32 entries; /* Number of watchdog entries that follow */ | ||
1332 | }; | ||
1333 | |||
1334 | /* Flags */ | ||
1335 | |||
1336 | #define ACPI_WDRT_TIMER_ENABLED (1) /* 00: Timer enabled */ | ||
1337 | |||
1338 | /* Reset to default packing */ | 910 | /* Reset to default packing */ |
1339 | 911 | ||
1340 | #pragma pack() | 912 | #pragma pack() |
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h new file mode 100644 index 000000000000..6f3dce9991e1 --- /dev/null +++ b/include/acpi/actbl2.h | |||
@@ -0,0 +1,868 @@ | |||
1 | #ifndef __ACTBL2_H__ | ||
2 | #define __ACTBL2_H__ | ||
3 | |||
4 | /******************************************************************************* | ||
5 | * | ||
6 | * Additional ACPI Tables (2) | ||
7 | * | ||
8 | * These tables are not consumed directly by the ACPICA subsystem, but are | ||
9 | * included here to support device drivers and the AML disassembler. | ||
10 | * | ||
11 | * The tables in this file are defined by third-party specifications, and are | ||
12 | * not defined directly by the ACPI specification itself. | ||
13 | * | ||
14 | ******************************************************************************/ | ||
15 | |||
16 | /* | ||
17 | * Values for description table header signatures for tables defined in this | ||
18 | * file. Useful because they make it more difficult to inadvertently type in | ||
19 | * the wrong signature. | ||
20 | */ | ||
21 | #define ACPI_SIG_ASF "ASF!" /* Alert Standard Format table */ | ||
22 | #define ACPI_SIG_BOOT "BOOT" /* Simple Boot Flag Table */ | ||
23 | #define ACPI_SIG_DBGP "DBGP" /* Debug Port table */ | ||
24 | #define ACPI_SIG_DMAR "DMAR" /* DMA Remapping table */ | ||
25 | #define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */ | ||
26 | #define ACPI_SIG_IBFT "IBFT" /* i_sCSI Boot Firmware Table */ | ||
27 | #define ACPI_SIG_IVRS "IVRS" /* I/O Virtualization Reporting Structure */ | ||
28 | #define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */ | ||
29 | #define ACPI_SIG_SLIC "SLIC" /* Software Licensing Description Table */ | ||
30 | #define ACPI_SIG_SPCR "SPCR" /* Serial Port Console Redirection table */ | ||
31 | #define ACPI_SIG_SPMI "SPMI" /* Server Platform Management Interface table */ | ||
32 | #define ACPI_SIG_TCPA "TCPA" /* Trusted Computing Platform Alliance table */ | ||
33 | #define ACPI_SIG_UEFI "UEFI" /* Uefi Boot Optimization Table */ | ||
34 | #define ACPI_SIG_WAET "WAET" /* Windows ACPI Emulated devices Table */ | ||
35 | #define ACPI_SIG_WDAT "WDAT" /* Watchdog Action Table */ | ||
36 | #define ACPI_SIG_WDRT "WDRT" /* Watchdog Resource Table */ | ||
37 | |||
38 | /* | ||
39 | * All tables must be byte-packed to match the ACPI specification, since | ||
40 | * the tables are provided by the system BIOS. | ||
41 | */ | ||
42 | #pragma pack(1) | ||
43 | |||
44 | /* | ||
45 | * Note about bitfields: The u8 type is used for bitfields in ACPI tables. | ||
46 | * This is the only type that is even remotely portable. Anything else is not | ||
47 | * portable, so do not use any other bitfield types. | ||
48 | */ | ||
49 | |||
50 | /******************************************************************************* | ||
51 | * | ||
52 | * ASF - Alert Standard Format table (Signature "ASF!") | ||
53 | * Revision 0x10 | ||
54 | * | ||
55 | * Conforms to the Alert Standard Format Specification V2.0, 23 April 2003 | ||
56 | * | ||
57 | ******************************************************************************/ | ||
58 | |||
59 | struct acpi_table_asf { | ||
60 | struct acpi_table_header header; /* Common ACPI table header */ | ||
61 | }; | ||
62 | |||
63 | /* ASF subtable header */ | ||
64 | |||
65 | struct acpi_asf_header { | ||
66 | u8 type; | ||
67 | u8 reserved; | ||
68 | u16 length; | ||
69 | }; | ||
70 | |||
71 | /* Values for Type field above */ | ||
72 | |||
73 | enum acpi_asf_type { | ||
74 | ACPI_ASF_TYPE_INFO = 0, | ||
75 | ACPI_ASF_TYPE_ALERT = 1, | ||
76 | ACPI_ASF_TYPE_CONTROL = 2, | ||
77 | ACPI_ASF_TYPE_BOOT = 3, | ||
78 | ACPI_ASF_TYPE_ADDRESS = 4, | ||
79 | ACPI_ASF_TYPE_RESERVED = 5 | ||
80 | }; | ||
81 | |||
82 | /* | ||
83 | * ASF subtables | ||
84 | */ | ||
85 | |||
86 | /* 0: ASF Information */ | ||
87 | |||
88 | struct acpi_asf_info { | ||
89 | struct acpi_asf_header header; | ||
90 | u8 min_reset_value; | ||
91 | u8 min_poll_interval; | ||
92 | u16 system_id; | ||
93 | u32 mfg_id; | ||
94 | u8 flags; | ||
95 | u8 reserved2[3]; | ||
96 | }; | ||
97 | |||
98 | /* Masks for Flags field above */ | ||
99 | |||
100 | #define ACPI_ASF_SMBUS_PROTOCOLS (1) | ||
101 | |||
102 | /* 1: ASF Alerts */ | ||
103 | |||
104 | struct acpi_asf_alert { | ||
105 | struct acpi_asf_header header; | ||
106 | u8 assert_mask; | ||
107 | u8 deassert_mask; | ||
108 | u8 alerts; | ||
109 | u8 data_length; | ||
110 | }; | ||
111 | |||
112 | struct acpi_asf_alert_data { | ||
113 | u8 address; | ||
114 | u8 command; | ||
115 | u8 mask; | ||
116 | u8 value; | ||
117 | u8 sensor_type; | ||
118 | u8 type; | ||
119 | u8 offset; | ||
120 | u8 source_type; | ||
121 | u8 severity; | ||
122 | u8 sensor_number; | ||
123 | u8 entity; | ||
124 | u8 instance; | ||
125 | }; | ||
126 | |||
127 | /* 2: ASF Remote Control */ | ||
128 | |||
129 | struct acpi_asf_remote { | ||
130 | struct acpi_asf_header header; | ||
131 | u8 controls; | ||
132 | u8 data_length; | ||
133 | u16 reserved2; | ||
134 | }; | ||
135 | |||
136 | struct acpi_asf_control_data { | ||
137 | u8 function; | ||
138 | u8 address; | ||
139 | u8 command; | ||
140 | u8 value; | ||
141 | }; | ||
142 | |||
143 | /* 3: ASF RMCP Boot Options */ | ||
144 | |||
145 | struct acpi_asf_rmcp { | ||
146 | struct acpi_asf_header header; | ||
147 | u8 capabilities[7]; | ||
148 | u8 completion_code; | ||
149 | u32 enterprise_id; | ||
150 | u8 command; | ||
151 | u16 parameter; | ||
152 | u16 boot_options; | ||
153 | u16 oem_parameters; | ||
154 | }; | ||
155 | |||
156 | /* 4: ASF Address */ | ||
157 | |||
158 | struct acpi_asf_address { | ||
159 | struct acpi_asf_header header; | ||
160 | u8 eprom_address; | ||
161 | u8 devices; | ||
162 | }; | ||
163 | |||
164 | /******************************************************************************* | ||
165 | * | ||
166 | * BOOT - Simple Boot Flag Table | ||
167 | * Version 1 | ||
168 | * | ||
169 | * Conforms to the "Simple Boot Flag Specification", Version 2.1 | ||
170 | * | ||
171 | ******************************************************************************/ | ||
172 | |||
173 | struct acpi_table_boot { | ||
174 | struct acpi_table_header header; /* Common ACPI table header */ | ||
175 | u8 cmos_index; /* Index in CMOS RAM for the boot register */ | ||
176 | u8 reserved[3]; | ||
177 | }; | ||
178 | |||
179 | /******************************************************************************* | ||
180 | * | ||
181 | * DBGP - Debug Port table | ||
182 | * Version 1 | ||
183 | * | ||
184 | * Conforms to the "Debug Port Specification", Version 1.00, 2/9/2000 | ||
185 | * | ||
186 | ******************************************************************************/ | ||
187 | |||
188 | struct acpi_table_dbgp { | ||
189 | struct acpi_table_header header; /* Common ACPI table header */ | ||
190 | u8 type; /* 0=full 16550, 1=subset of 16550 */ | ||
191 | u8 reserved[3]; | ||
192 | struct acpi_generic_address debug_port; | ||
193 | }; | ||
194 | |||
195 | /******************************************************************************* | ||
196 | * | ||
197 | * DMAR - DMA Remapping table | ||
198 | * Version 1 | ||
199 | * | ||
200 | * Conforms to "Intel Virtualization Technology for Directed I/O", | ||
201 | * Version 1.2, Sept. 2008 | ||
202 | * | ||
203 | ******************************************************************************/ | ||
204 | |||
205 | struct acpi_table_dmar { | ||
206 | struct acpi_table_header header; /* Common ACPI table header */ | ||
207 | u8 width; /* Host Address Width */ | ||
208 | u8 flags; | ||
209 | u8 reserved[10]; | ||
210 | }; | ||
211 | |||
212 | /* Masks for Flags field above */ | ||
213 | |||
214 | #define ACPI_DMAR_INTR_REMAP (1) | ||
215 | |||
216 | /* DMAR subtable header */ | ||
217 | |||
218 | struct acpi_dmar_header { | ||
219 | u16 type; | ||
220 | u16 length; | ||
221 | }; | ||
222 | |||
223 | /* Values for subtable type in struct acpi_dmar_header */ | ||
224 | |||
225 | enum acpi_dmar_type { | ||
226 | ACPI_DMAR_TYPE_HARDWARE_UNIT = 0, | ||
227 | ACPI_DMAR_TYPE_RESERVED_MEMORY = 1, | ||
228 | ACPI_DMAR_TYPE_ATSR = 2, | ||
229 | ACPI_DMAR_HARDWARE_AFFINITY = 3, | ||
230 | ACPI_DMAR_TYPE_RESERVED = 4 /* 4 and greater are reserved */ | ||
231 | }; | ||
232 | |||
233 | /* DMAR Device Scope structure */ | ||
234 | |||
235 | struct acpi_dmar_device_scope { | ||
236 | u8 entry_type; | ||
237 | u8 length; | ||
238 | u16 reserved; | ||
239 | u8 enumeration_id; | ||
240 | u8 bus; | ||
241 | }; | ||
242 | |||
243 | /* Values for entry_type in struct acpi_dmar_device_scope */ | ||
244 | |||
245 | enum acpi_dmar_scope_type { | ||
246 | ACPI_DMAR_SCOPE_TYPE_NOT_USED = 0, | ||
247 | ACPI_DMAR_SCOPE_TYPE_ENDPOINT = 1, | ||
248 | ACPI_DMAR_SCOPE_TYPE_BRIDGE = 2, | ||
249 | ACPI_DMAR_SCOPE_TYPE_IOAPIC = 3, | ||
250 | ACPI_DMAR_SCOPE_TYPE_HPET = 4, | ||
251 | ACPI_DMAR_SCOPE_TYPE_RESERVED = 5 /* 5 and greater are reserved */ | ||
252 | }; | ||
253 | |||
254 | struct acpi_dmar_pci_path { | ||
255 | u8 dev; | ||
256 | u8 fn; | ||
257 | }; | ||
258 | |||
259 | /* | ||
260 | * DMAR Sub-tables, correspond to Type in struct acpi_dmar_header | ||
261 | */ | ||
262 | |||
263 | /* 0: Hardware Unit Definition */ | ||
264 | |||
265 | struct acpi_dmar_hardware_unit { | ||
266 | struct acpi_dmar_header header; | ||
267 | u8 flags; | ||
268 | u8 reserved; | ||
269 | u16 segment; | ||
270 | u64 address; /* Register Base Address */ | ||
271 | }; | ||
272 | |||
273 | /* Masks for Flags field above */ | ||
274 | |||
275 | #define ACPI_DMAR_INCLUDE_ALL (1) | ||
276 | |||
277 | /* 1: Reserved Memory Defininition */ | ||
278 | |||
279 | struct acpi_dmar_reserved_memory { | ||
280 | struct acpi_dmar_header header; | ||
281 | u16 reserved; | ||
282 | u16 segment; | ||
283 | u64 base_address; /* 4_k aligned base address */ | ||
284 | u64 end_address; /* 4_k aligned limit address */ | ||
285 | }; | ||
286 | |||
287 | /* Masks for Flags field above */ | ||
288 | |||
289 | #define ACPI_DMAR_ALLOW_ALL (1) | ||
290 | |||
291 | /* 2: Root Port ATS Capability Reporting Structure */ | ||
292 | |||
293 | struct acpi_dmar_atsr { | ||
294 | struct acpi_dmar_header header; | ||
295 | u8 flags; | ||
296 | u8 reserved; | ||
297 | u16 segment; | ||
298 | }; | ||
299 | |||
300 | /* Masks for Flags field above */ | ||
301 | |||
302 | #define ACPI_DMAR_ALL_PORTS (1) | ||
303 | |||
304 | /* 3: Remapping Hardware Static Affinity Structure */ | ||
305 | |||
306 | struct acpi_dmar_rhsa { | ||
307 | struct acpi_dmar_header header; | ||
308 | u32 reserved; | ||
309 | u64 base_address; | ||
310 | u32 proximity_domain; | ||
311 | }; | ||
312 | |||
313 | /******************************************************************************* | ||
314 | * | ||
315 | * HPET - High Precision Event Timer table | ||
316 | * Version 1 | ||
317 | * | ||
318 | * Conforms to "IA-PC HPET (High Precision Event Timers) Specification", | ||
319 | * Version 1.0a, October 2004 | ||
320 | * | ||
321 | ******************************************************************************/ | ||
322 | |||
323 | struct acpi_table_hpet { | ||
324 | struct acpi_table_header header; /* Common ACPI table header */ | ||
325 | u32 id; /* Hardware ID of event timer block */ | ||
326 | struct acpi_generic_address address; /* Address of event timer block */ | ||
327 | u8 sequence; /* HPET sequence number */ | ||
328 | u16 minimum_tick; /* Main counter min tick, periodic mode */ | ||
329 | u8 flags; | ||
330 | }; | ||
331 | |||
332 | /* Masks for Flags field above */ | ||
333 | |||
334 | #define ACPI_HPET_PAGE_PROTECT_MASK (3) | ||
335 | |||
336 | /* Values for Page Protect flags */ | ||
337 | |||
338 | enum acpi_hpet_page_protect { | ||
339 | ACPI_HPET_NO_PAGE_PROTECT = 0, | ||
340 | ACPI_HPET_PAGE_PROTECT4 = 1, | ||
341 | ACPI_HPET_PAGE_PROTECT64 = 2 | ||
342 | }; | ||
343 | |||
344 | /******************************************************************************* | ||
345 | * | ||
346 | * IBFT - Boot Firmware Table | ||
347 | * Version 1 | ||
348 | * | ||
349 | * Conforms to "iSCSI Boot Firmware Table (iBFT) as Defined in ACPI 3.0b | ||
350 | * Specification", Version 1.01, March 1, 2007 | ||
351 | * | ||
352 | * Note: It appears that this table is not intended to appear in the RSDT/XSDT. | ||
353 | * Therefore, it is not currently supported by the disassembler. | ||
354 | * | ||
355 | ******************************************************************************/ | ||
356 | |||
357 | struct acpi_table_ibft { | ||
358 | struct acpi_table_header header; /* Common ACPI table header */ | ||
359 | u8 reserved[12]; | ||
360 | }; | ||
361 | |||
362 | /* IBFT common subtable header */ | ||
363 | |||
364 | struct acpi_ibft_header { | ||
365 | u8 type; | ||
366 | u8 version; | ||
367 | u16 length; | ||
368 | u8 index; | ||
369 | u8 flags; | ||
370 | }; | ||
371 | |||
372 | /* Values for Type field above */ | ||
373 | |||
374 | enum acpi_ibft_type { | ||
375 | ACPI_IBFT_TYPE_NOT_USED = 0, | ||
376 | ACPI_IBFT_TYPE_CONTROL = 1, | ||
377 | ACPI_IBFT_TYPE_INITIATOR = 2, | ||
378 | ACPI_IBFT_TYPE_NIC = 3, | ||
379 | ACPI_IBFT_TYPE_TARGET = 4, | ||
380 | ACPI_IBFT_TYPE_EXTENSIONS = 5, | ||
381 | ACPI_IBFT_TYPE_RESERVED = 6 /* 6 and greater are reserved */ | ||
382 | }; | ||
383 | |||
384 | /* IBFT subtables */ | ||
385 | |||
386 | struct acpi_ibft_control { | ||
387 | struct acpi_ibft_header header; | ||
388 | u16 extensions; | ||
389 | u16 initiator_offset; | ||
390 | u16 nic0_offset; | ||
391 | u16 target0_offset; | ||
392 | u16 nic1_offset; | ||
393 | u16 target1_offset; | ||
394 | }; | ||
395 | |||
396 | struct acpi_ibft_initiator { | ||
397 | struct acpi_ibft_header header; | ||
398 | u8 sns_server[16]; | ||
399 | u8 slp_server[16]; | ||
400 | u8 primary_server[16]; | ||
401 | u8 secondary_server[16]; | ||
402 | u16 name_length; | ||
403 | u16 name_offset; | ||
404 | }; | ||
405 | |||
406 | struct acpi_ibft_nic { | ||
407 | struct acpi_ibft_header header; | ||
408 | u8 ip_address[16]; | ||
409 | u8 subnet_mask_prefix; | ||
410 | u8 origin; | ||
411 | u8 gateway[16]; | ||
412 | u8 primary_dns[16]; | ||
413 | u8 secondary_dns[16]; | ||
414 | u8 dhcp[16]; | ||
415 | u16 vlan; | ||
416 | u8 mac_address[6]; | ||
417 | u16 pci_address; | ||
418 | u16 name_length; | ||
419 | u16 name_offset; | ||
420 | }; | ||
421 | |||
422 | struct acpi_ibft_target { | ||
423 | struct acpi_ibft_header header; | ||
424 | u8 target_ip_address[16]; | ||
425 | u16 target_ip_socket; | ||
426 | u8 target_boot_lun[8]; | ||
427 | u8 chap_type; | ||
428 | u8 nic_association; | ||
429 | u16 target_name_length; | ||
430 | u16 target_name_offset; | ||
431 | u16 chap_name_length; | ||
432 | u16 chap_name_offset; | ||
433 | u16 chap_secret_length; | ||
434 | u16 chap_secret_offset; | ||
435 | u16 reverse_chap_name_length; | ||
436 | u16 reverse_chap_name_offset; | ||
437 | u16 reverse_chap_secret_length; | ||
438 | u16 reverse_chap_secret_offset; | ||
439 | }; | ||
440 | |||
441 | /******************************************************************************* | ||
442 | * | ||
443 | * IVRS - I/O Virtualization Reporting Structure | ||
444 | * Version 1 | ||
445 | * | ||
446 | * Conforms to "AMD I/O Virtualization Technology (IOMMU) Specification", | ||
447 | * Revision 1.26, February 2009. | ||
448 | * | ||
449 | ******************************************************************************/ | ||
450 | |||
451 | struct acpi_table_ivrs { | ||
452 | struct acpi_table_header header; /* Common ACPI table header */ | ||
453 | u32 info; /* Common virtualization info */ | ||
454 | u64 reserved; | ||
455 | }; | ||
456 | |||
457 | /* Values for Info field above */ | ||
458 | |||
459 | #define ACPI_IVRS_PHYSICAL_SIZE 0x00007F00 /* 7 bits, physical address size */ | ||
460 | #define ACPI_IVRS_VIRTUAL_SIZE 0x003F8000 /* 7 bits, virtual address size */ | ||
461 | #define ACPI_IVRS_ATS_RESERVED 0x00400000 /* ATS address translation range reserved */ | ||
462 | |||
463 | /* IVRS subtable header */ | ||
464 | |||
465 | struct acpi_ivrs_header { | ||
466 | u8 type; /* Subtable type */ | ||
467 | u8 flags; | ||
468 | u16 length; /* Subtable length */ | ||
469 | u16 device_id; /* ID of IOMMU */ | ||
470 | }; | ||
471 | |||
472 | /* Values for subtable Type above */ | ||
473 | |||
474 | enum acpi_ivrs_type { | ||
475 | ACPI_IVRS_TYPE_HARDWARE = 0x10, | ||
476 | ACPI_IVRS_TYPE_MEMORY1 = 0x20, | ||
477 | ACPI_IVRS_TYPE_MEMORY2 = 0x21, | ||
478 | ACPI_IVRS_TYPE_MEMORY3 = 0x22 | ||
479 | }; | ||
480 | |||
481 | /* Masks for Flags field above for IVHD subtable */ | ||
482 | |||
483 | #define ACPI_IVHD_TT_ENABLE (1) | ||
484 | #define ACPI_IVHD_PASS_PW (1<<1) | ||
485 | #define ACPI_IVHD_RES_PASS_PW (1<<2) | ||
486 | #define ACPI_IVHD_ISOC (1<<3) | ||
487 | #define ACPI_IVHD_IOTLB (1<<4) | ||
488 | |||
489 | /* Masks for Flags field above for IVMD subtable */ | ||
490 | |||
491 | #define ACPI_IVMD_UNITY (1) | ||
492 | #define ACPI_IVMD_READ (1<<1) | ||
493 | #define ACPI_IVMD_WRITE (1<<2) | ||
494 | #define ACPI_IVMD_EXCLUSION_RANGE (1<<3) | ||
495 | |||
496 | /* | ||
497 | * IVRS subtables, correspond to Type in struct acpi_ivrs_header | ||
498 | */ | ||
499 | |||
500 | /* 0x10: I/O Virtualization Hardware Definition Block (IVHD) */ | ||
501 | |||
502 | struct acpi_ivrs_hardware { | ||
503 | struct acpi_ivrs_header header; | ||
504 | u16 capability_offset; /* Offset for IOMMU control fields */ | ||
505 | u64 base_address; /* IOMMU control registers */ | ||
506 | u16 pci_segment_group; | ||
507 | u16 info; /* MSI number and unit ID */ | ||
508 | u32 reserved; | ||
509 | }; | ||
510 | |||
511 | /* Masks for Info field above */ | ||
512 | |||
513 | #define ACPI_IVHD_MSI_NUMBER_MASK 0x001F /* 5 bits, MSI message number */ | ||
514 | #define ACPI_IVHD_UNIT_ID_MASK 0x1F00 /* 5 bits, unit_iD */ | ||
515 | |||
516 | /* | ||
517 | * Device Entries for IVHD subtable, appear after struct acpi_ivrs_hardware structure. | ||
518 | * Upper two bits of the Type field are the (encoded) length of the structure. | ||
519 | * Currently, only 4 and 8 byte entries are defined. 16 and 32 byte entries | ||
520 | * are reserved for future use but not defined. | ||
521 | */ | ||
522 | struct acpi_ivrs_de_header { | ||
523 | u8 type; | ||
524 | u16 id; | ||
525 | u8 data_setting; | ||
526 | }; | ||
527 | |||
528 | /* Length of device entry is in the top two bits of Type field above */ | ||
529 | |||
530 | #define ACPI_IVHD_ENTRY_LENGTH 0xC0 | ||
531 | |||
532 | /* Values for device entry Type field above */ | ||
533 | |||
534 | enum acpi_ivrs_device_entry_type { | ||
535 | /* 4-byte device entries, all use struct acpi_ivrs_device4 */ | ||
536 | |||
537 | ACPI_IVRS_TYPE_PAD4 = 0, | ||
538 | ACPI_IVRS_TYPE_ALL = 1, | ||
539 | ACPI_IVRS_TYPE_SELECT = 2, | ||
540 | ACPI_IVRS_TYPE_START = 3, | ||
541 | ACPI_IVRS_TYPE_END = 4, | ||
542 | |||
543 | /* 8-byte device entries */ | ||
544 | |||
545 | ACPI_IVRS_TYPE_PAD8 = 64, | ||
546 | ACPI_IVRS_TYPE_NOT_USED = 65, | ||
547 | ACPI_IVRS_TYPE_ALIAS_SELECT = 66, /* Uses struct acpi_ivrs_device8a */ | ||
548 | ACPI_IVRS_TYPE_ALIAS_START = 67, /* Uses struct acpi_ivrs_device8a */ | ||
549 | ACPI_IVRS_TYPE_EXT_SELECT = 70, /* Uses struct acpi_ivrs_device8b */ | ||
550 | ACPI_IVRS_TYPE_EXT_START = 71, /* Uses struct acpi_ivrs_device8b */ | ||
551 | ACPI_IVRS_TYPE_SPECIAL = 72 /* Uses struct acpi_ivrs_device8c */ | ||
552 | }; | ||
553 | |||
554 | /* Values for Data field above */ | ||
555 | |||
556 | #define ACPI_IVHD_INIT_PASS (1) | ||
557 | #define ACPI_IVHD_EINT_PASS (1<<1) | ||
558 | #define ACPI_IVHD_NMI_PASS (1<<2) | ||
559 | #define ACPI_IVHD_SYSTEM_MGMT (3<<4) | ||
560 | #define ACPI_IVHD_LINT0_PASS (1<<6) | ||
561 | #define ACPI_IVHD_LINT1_PASS (1<<7) | ||
562 | |||
563 | /* Types 0-4: 4-byte device entry */ | ||
564 | |||
565 | struct acpi_ivrs_device4 { | ||
566 | struct acpi_ivrs_de_header header; | ||
567 | }; | ||
568 | |||
569 | /* Types 66-67: 8-byte device entry */ | ||
570 | |||
571 | struct acpi_ivrs_device8a { | ||
572 | struct acpi_ivrs_de_header header; | ||
573 | u8 reserved1; | ||
574 | u16 used_id; | ||
575 | u8 reserved2; | ||
576 | }; | ||
577 | |||
578 | /* Types 70-71: 8-byte device entry */ | ||
579 | |||
580 | struct acpi_ivrs_device8b { | ||
581 | struct acpi_ivrs_de_header header; | ||
582 | u32 extended_data; | ||
583 | }; | ||
584 | |||
585 | /* Values for extended_data above */ | ||
586 | |||
587 | #define ACPI_IVHD_ATS_DISABLED (1<<31) | ||
588 | |||
589 | /* Type 72: 8-byte device entry */ | ||
590 | |||
591 | struct acpi_ivrs_device8c { | ||
592 | struct acpi_ivrs_de_header header; | ||
593 | u8 handle; | ||
594 | u16 used_id; | ||
595 | u8 variety; | ||
596 | }; | ||
597 | |||
598 | /* Values for Variety field above */ | ||
599 | |||
600 | #define ACPI_IVHD_IOAPIC 1 | ||
601 | #define ACPI_IVHD_HPET 2 | ||
602 | |||
603 | /* 0x20, 0x21, 0x22: I/O Virtualization Memory Definition Block (IVMD) */ | ||
604 | |||
605 | struct acpi_ivrs_memory { | ||
606 | struct acpi_ivrs_header header; | ||
607 | u16 aux_data; | ||
608 | u64 reserved; | ||
609 | u64 start_address; | ||
610 | u64 memory_length; | ||
611 | }; | ||
612 | |||
613 | /******************************************************************************* | ||
614 | * | ||
615 | * MCFG - PCI Memory Mapped Configuration table and sub-table | ||
616 | * Version 1 | ||
617 | * | ||
618 | * Conforms to "PCI Firmware Specification", Revision 3.0, June 20, 2005 | ||
619 | * | ||
620 | ******************************************************************************/ | ||
621 | |||
622 | struct acpi_table_mcfg { | ||
623 | struct acpi_table_header header; /* Common ACPI table header */ | ||
624 | u8 reserved[8]; | ||
625 | }; | ||
626 | |||
627 | /* Subtable */ | ||
628 | |||
629 | struct acpi_mcfg_allocation { | ||
630 | u64 address; /* Base address, processor-relative */ | ||
631 | u16 pci_segment; /* PCI segment group number */ | ||
632 | u8 start_bus_number; /* Starting PCI Bus number */ | ||
633 | u8 end_bus_number; /* Final PCI Bus number */ | ||
634 | u32 reserved; | ||
635 | }; | ||
636 | |||
637 | /******************************************************************************* | ||
638 | * | ||
639 | * SPCR - Serial Port Console Redirection table | ||
640 | * Version 1 | ||
641 | * | ||
642 | * Conforms to "Serial Port Console Redirection Table", | ||
643 | * Version 1.00, January 11, 2002 | ||
644 | * | ||
645 | ******************************************************************************/ | ||
646 | |||
647 | struct acpi_table_spcr { | ||
648 | struct acpi_table_header header; /* Common ACPI table header */ | ||
649 | u8 interface_type; /* 0=full 16550, 1=subset of 16550 */ | ||
650 | u8 reserved[3]; | ||
651 | struct acpi_generic_address serial_port; | ||
652 | u8 interrupt_type; | ||
653 | u8 pc_interrupt; | ||
654 | u32 interrupt; | ||
655 | u8 baud_rate; | ||
656 | u8 parity; | ||
657 | u8 stop_bits; | ||
658 | u8 flow_control; | ||
659 | u8 terminal_type; | ||
660 | u8 reserved1; | ||
661 | u16 pci_device_id; | ||
662 | u16 pci_vendor_id; | ||
663 | u8 pci_bus; | ||
664 | u8 pci_device; | ||
665 | u8 pci_function; | ||
666 | u32 pci_flags; | ||
667 | u8 pci_segment; | ||
668 | u32 reserved2; | ||
669 | }; | ||
670 | |||
671 | /* Masks for pci_flags field above */ | ||
672 | |||
673 | #define ACPI_SPCR_DO_NOT_DISABLE (1) | ||
674 | |||
675 | /******************************************************************************* | ||
676 | * | ||
677 | * SPMI - Server Platform Management Interface table | ||
678 | * Version 5 | ||
679 | * | ||
680 | * Conforms to "Intelligent Platform Management Interface Specification | ||
681 | * Second Generation v2.0", Document Revision 1.0, February 12, 2004 with | ||
682 | * June 12, 2009 markup. | ||
683 | * | ||
684 | ******************************************************************************/ | ||
685 | |||
686 | struct acpi_table_spmi { | ||
687 | struct acpi_table_header header; /* Common ACPI table header */ | ||
688 | u8 interface_type; | ||
689 | u8 reserved; /* Must be 1 */ | ||
690 | u16 spec_revision; /* Version of IPMI */ | ||
691 | u8 interrupt_type; | ||
692 | u8 gpe_number; /* GPE assigned */ | ||
693 | u8 reserved1; | ||
694 | u8 pci_device_flag; | ||
695 | u32 interrupt; | ||
696 | struct acpi_generic_address ipmi_register; | ||
697 | u8 pci_segment; | ||
698 | u8 pci_bus; | ||
699 | u8 pci_device; | ||
700 | u8 pci_function; | ||
701 | u8 reserved2; | ||
702 | }; | ||
703 | |||
704 | /* Values for interface_type above */ | ||
705 | |||
706 | enum acpi_spmi_interface_types { | ||
707 | ACPI_SPMI_NOT_USED = 0, | ||
708 | ACPI_SPMI_KEYBOARD = 1, | ||
709 | ACPI_SPMI_SMI = 2, | ||
710 | ACPI_SPMI_BLOCK_TRANSFER = 3, | ||
711 | ACPI_SPMI_SMBUS = 4, | ||
712 | ACPI_SPMI_RESERVED = 5 /* 5 and above are reserved */ | ||
713 | }; | ||
714 | |||
715 | /******************************************************************************* | ||
716 | * | ||
717 | * TCPA - Trusted Computing Platform Alliance table | ||
718 | * Version 1 | ||
719 | * | ||
720 | * Conforms to "TCG PC Specific Implementation Specification", | ||
721 | * Version 1.1, August 18, 2003 | ||
722 | * | ||
723 | ******************************************************************************/ | ||
724 | |||
725 | struct acpi_table_tcpa { | ||
726 | struct acpi_table_header header; /* Common ACPI table header */ | ||
727 | u16 reserved; | ||
728 | u32 max_log_length; /* Maximum length for the event log area */ | ||
729 | u64 log_address; /* Address of the event log area */ | ||
730 | }; | ||
731 | |||
732 | /******************************************************************************* | ||
733 | * | ||
734 | * UEFI - UEFI Boot optimization Table | ||
735 | * Version 1 | ||
736 | * | ||
737 | * Conforms to "Unified Extensible Firmware Interface Specification", | ||
738 | * Version 2.3, May 8, 2009 | ||
739 | * | ||
740 | ******************************************************************************/ | ||
741 | |||
742 | struct acpi_table_uefi { | ||
743 | struct acpi_table_header header; /* Common ACPI table header */ | ||
744 | u8 identifier[16]; /* UUID identifier */ | ||
745 | u16 data_offset; /* Offset of remaining data in table */ | ||
746 | }; | ||
747 | |||
748 | /******************************************************************************* | ||
749 | * | ||
750 | * WAET - Windows ACPI Emulated devices Table | ||
751 | * Version 1 | ||
752 | * | ||
753 | * Conforms to "Windows ACPI Emulated Devices Table", version 1.0, April 6, 2009 | ||
754 | * | ||
755 | ******************************************************************************/ | ||
756 | |||
757 | struct acpi_table_waet { | ||
758 | struct acpi_table_header header; /* Common ACPI table header */ | ||
759 | u32 flags; | ||
760 | }; | ||
761 | |||
762 | /* Masks for Flags field above */ | ||
763 | |||
764 | #define ACPI_WAET_RTC_NO_ACK (1) /* RTC requires no int acknowledge */ | ||
765 | #define ACPI_WAET_TIMER_ONE_READ (1<<1) /* PM timer requires only one read */ | ||
766 | |||
767 | /******************************************************************************* | ||
768 | * | ||
769 | * WDAT - Watchdog Action Table | ||
770 | * Version 1 | ||
771 | * | ||
772 | * Conforms to "Hardware Watchdog Timers Design Specification", | ||
773 | * Copyright 2006 Microsoft Corporation. | ||
774 | * | ||
775 | ******************************************************************************/ | ||
776 | |||
777 | struct acpi_table_wdat { | ||
778 | struct acpi_table_header header; /* Common ACPI table header */ | ||
779 | u32 header_length; /* Watchdog Header Length */ | ||
780 | u16 pci_segment; /* PCI Segment number */ | ||
781 | u8 pci_bus; /* PCI Bus number */ | ||
782 | u8 pci_device; /* PCI Device number */ | ||
783 | u8 pci_function; /* PCI Function number */ | ||
784 | u8 reserved[3]; | ||
785 | u32 timer_period; /* Period of one timer count (msec) */ | ||
786 | u32 max_count; /* Maximum counter value supported */ | ||
787 | u32 min_count; /* Minimum counter value */ | ||
788 | u8 flags; | ||
789 | u8 reserved2[3]; | ||
790 | u32 entries; /* Number of watchdog entries that follow */ | ||
791 | }; | ||
792 | |||
793 | /* Masks for Flags field above */ | ||
794 | |||
795 | #define ACPI_WDAT_ENABLED (1) | ||
796 | #define ACPI_WDAT_STOPPED 0x80 | ||
797 | |||
798 | /* WDAT Instruction Entries (actions) */ | ||
799 | |||
800 | struct acpi_wdat_entry { | ||
801 | u8 action; | ||
802 | u8 instruction; | ||
803 | u16 reserved; | ||
804 | struct acpi_generic_address register_region; | ||
805 | u32 value; /* Value used with Read/Write register */ | ||
806 | u32 mask; /* Bitmask required for this register instruction */ | ||
807 | }; | ||
808 | |||
809 | /* Values for Action field above */ | ||
810 | |||
811 | enum acpi_wdat_actions { | ||
812 | ACPI_WDAT_RESET = 1, | ||
813 | ACPI_WDAT_GET_CURRENT_COUNTDOWN = 4, | ||
814 | ACPI_WDAT_GET_COUNTDOWN = 5, | ||
815 | ACPI_WDAT_SET_COUNTDOWN = 6, | ||
816 | ACPI_WDAT_GET_RUNNING_STATE = 8, | ||
817 | ACPI_WDAT_SET_RUNNING_STATE = 9, | ||
818 | ACPI_WDAT_GET_STOPPED_STATE = 10, | ||
819 | ACPI_WDAT_SET_STOPPED_STATE = 11, | ||
820 | ACPI_WDAT_GET_REBOOT = 16, | ||
821 | ACPI_WDAT_SET_REBOOT = 17, | ||
822 | ACPI_WDAT_GET_SHUTDOWN = 18, | ||
823 | ACPI_WDAT_SET_SHUTDOWN = 19, | ||
824 | ACPI_WDAT_GET_STATUS = 32, | ||
825 | ACPI_WDAT_SET_STATUS = 33, | ||
826 | ACPI_WDAT_ACTION_RESERVED = 34 /* 34 and greater are reserved */ | ||
827 | }; | ||
828 | |||
829 | /* Values for Instruction field above */ | ||
830 | |||
831 | enum acpi_wdat_instructions { | ||
832 | ACPI_WDAT_READ_VALUE = 0, | ||
833 | ACPI_WDAT_READ_COUNTDOWN = 1, | ||
834 | ACPI_WDAT_WRITE_VALUE = 2, | ||
835 | ACPI_WDAT_WRITE_COUNTDOWN = 3, | ||
836 | ACPI_WDAT_INSTRUCTION_RESERVED = 4, /* 4 and greater are reserved */ | ||
837 | ACPI_WDAT_PRESERVE_REGISTER = 0x80 /* Except for this value */ | ||
838 | }; | ||
839 | |||
840 | /******************************************************************************* | ||
841 | * | ||
842 | * WDRT - Watchdog Resource Table | ||
843 | * Version 1 | ||
844 | * | ||
845 | * Conforms to "Watchdog Timer Hardware Requirements for Windows Server 2003", | ||
846 | * Version 1.01, August 28, 2006 | ||
847 | * | ||
848 | ******************************************************************************/ | ||
849 | |||
850 | struct acpi_table_wdrt { | ||
851 | struct acpi_table_header header; /* Common ACPI table header */ | ||
852 | struct acpi_generic_address control_register; | ||
853 | struct acpi_generic_address count_register; | ||
854 | u16 pci_device_id; | ||
855 | u16 pci_vendor_id; | ||
856 | u8 pci_bus; /* PCI Bus number */ | ||
857 | u8 pci_device; /* PCI Device number */ | ||
858 | u8 pci_function; /* PCI Function number */ | ||
859 | u8 pci_segment; /* PCI Segment number */ | ||
860 | u16 max_count; /* Maximum counter value supported */ | ||
861 | u8 units; | ||
862 | }; | ||
863 | |||
864 | /* Reset to default packing */ | ||
865 | |||
866 | #pragma pack() | ||
867 | |||
868 | #endif /* __ACTBL2_H__ */ | ||
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 8052236d1a3d..153f12dc3373 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h | |||
@@ -338,7 +338,7 @@ typedef u32 acpi_physical_address; | |||
338 | 338 | ||
339 | /* PM Timer ticks per second (HZ) */ | 339 | /* PM Timer ticks per second (HZ) */ |
340 | 340 | ||
341 | #define PM_TIMER_FREQUENCY 3579545 | 341 | #define PM_TIMER_FREQUENCY 3579545 |
342 | 342 | ||
343 | /******************************************************************************* | 343 | /******************************************************************************* |
344 | * | 344 | * |
@@ -732,7 +732,8 @@ typedef u8 acpi_adr_space_type; | |||
732 | #define ACPI_ADR_SPACE_SMBUS (acpi_adr_space_type) 4 | 732 | #define ACPI_ADR_SPACE_SMBUS (acpi_adr_space_type) 4 |
733 | #define ACPI_ADR_SPACE_CMOS (acpi_adr_space_type) 5 | 733 | #define ACPI_ADR_SPACE_CMOS (acpi_adr_space_type) 5 |
734 | #define ACPI_ADR_SPACE_PCI_BAR_TARGET (acpi_adr_space_type) 6 | 734 | #define ACPI_ADR_SPACE_PCI_BAR_TARGET (acpi_adr_space_type) 6 |
735 | #define ACPI_ADR_SPACE_DATA_TABLE (acpi_adr_space_type) 7 | 735 | #define ACPI_ADR_SPACE_IPMI (acpi_adr_space_type) 7 |
736 | #define ACPI_ADR_SPACE_DATA_TABLE (acpi_adr_space_type) 8 | ||
736 | #define ACPI_ADR_SPACE_FIXED_HARDWARE (acpi_adr_space_type) 127 | 737 | #define ACPI_ADR_SPACE_FIXED_HARDWARE (acpi_adr_space_type) 127 |
737 | 738 | ||
738 | /* | 739 | /* |
@@ -921,7 +922,7 @@ typedef | |||
921 | void (*acpi_notify_handler) (acpi_handle device, u32 value, void *context); | 922 | void (*acpi_notify_handler) (acpi_handle device, u32 value, void *context); |
922 | 923 | ||
923 | typedef | 924 | typedef |
924 | void (*acpi_object_handler) (acpi_handle object, u32 function, void *data); | 925 | void (*acpi_object_handler) (acpi_handle object, void *data); |
925 | 926 | ||
926 | typedef acpi_status(*acpi_init_handler) (acpi_handle object, u32 function); | 927 | typedef acpi_status(*acpi_init_handler) (acpi_handle object, u32 function); |
927 | 928 | ||
@@ -969,38 +970,60 @@ acpi_status(*acpi_walk_callback) (acpi_handle obj_handle, | |||
969 | #define ACPI_INTERRUPT_NOT_HANDLED 0x00 | 970 | #define ACPI_INTERRUPT_NOT_HANDLED 0x00 |
970 | #define ACPI_INTERRUPT_HANDLED 0x01 | 971 | #define ACPI_INTERRUPT_HANDLED 0x01 |
971 | 972 | ||
972 | /* Length of _HID, _UID, _CID, and UUID values */ | 973 | /* Length of 32-bit EISAID values when converted back to a string */ |
974 | |||
975 | #define ACPI_EISAID_STRING_SIZE 8 /* Includes null terminator */ | ||
976 | |||
977 | /* Length of UUID (string) values */ | ||
973 | 978 | ||
974 | #define ACPI_DEVICE_ID_LENGTH 0x09 | ||
975 | #define ACPI_MAX_CID_LENGTH 48 | ||
976 | #define ACPI_UUID_LENGTH 16 | 979 | #define ACPI_UUID_LENGTH 16 |
977 | 980 | ||
978 | /* Common string version of device HIDs and UIDs */ | 981 | /* Structures used for device/processor HID, UID, CID */ |
979 | 982 | ||
980 | struct acpica_device_id { | 983 | struct acpica_device_id { |
981 | char value[ACPI_DEVICE_ID_LENGTH]; | 984 | u32 length; /* Length of string + null */ |
985 | char *string; | ||
982 | }; | 986 | }; |
983 | 987 | ||
984 | /* Common string version of device CIDs */ | 988 | struct acpica_device_id_list { |
985 | 989 | u32 count; /* Number of IDs in Ids array */ | |
986 | struct acpi_compatible_id { | 990 | u32 list_size; /* Size of list, including ID strings */ |
987 | char value[ACPI_MAX_CID_LENGTH]; | 991 | struct acpica_device_id ids[1]; /* ID array */ |
988 | }; | 992 | }; |
989 | 993 | ||
990 | struct acpi_compatible_id_list { | 994 | /* |
991 | u32 count; | 995 | * Structure returned from acpi_get_object_info. |
992 | u32 size; | 996 | * Optimized for both 32- and 64-bit builds |
993 | struct acpi_compatible_id id[1]; | 997 | */ |
998 | struct acpi_device_info { | ||
999 | u32 info_size; /* Size of info, including ID strings */ | ||
1000 | u32 name; /* ACPI object Name */ | ||
1001 | acpi_object_type type; /* ACPI object Type */ | ||
1002 | u8 param_count; /* If a method, required parameter count */ | ||
1003 | u8 valid; /* Indicates which optional fields are valid */ | ||
1004 | u8 flags; /* Miscellaneous info */ | ||
1005 | u8 highest_dstates[4]; /* _sx_d values: 0xFF indicates not valid */ | ||
1006 | u8 lowest_dstates[5]; /* _sx_w values: 0xFF indicates not valid */ | ||
1007 | u32 current_status; /* _STA value */ | ||
1008 | acpi_integer address; /* _ADR value */ | ||
1009 | struct acpica_device_id hardware_id; /* _HID value */ | ||
1010 | struct acpica_device_id unique_id; /* _UID value */ | ||
1011 | struct acpica_device_id_list compatible_id_list; /* _CID list <must be last> */ | ||
994 | }; | 1012 | }; |
995 | 1013 | ||
996 | /* Structure and flags for acpi_get_object_info */ | 1014 | /* Values for Flags field above (acpi_get_object_info) */ |
1015 | |||
1016 | #define ACPI_PCI_ROOT_BRIDGE 0x01 | ||
997 | 1017 | ||
998 | #define ACPI_VALID_STA 0x0001 | 1018 | /* Flags for Valid field above (acpi_get_object_info) */ |
999 | #define ACPI_VALID_ADR 0x0002 | 1019 | |
1000 | #define ACPI_VALID_HID 0x0004 | 1020 | #define ACPI_VALID_STA 0x01 |
1001 | #define ACPI_VALID_UID 0x0008 | 1021 | #define ACPI_VALID_ADR 0x02 |
1002 | #define ACPI_VALID_CID 0x0010 | 1022 | #define ACPI_VALID_HID 0x04 |
1003 | #define ACPI_VALID_SXDS 0x0020 | 1023 | #define ACPI_VALID_UID 0x08 |
1024 | #define ACPI_VALID_CID 0x10 | ||
1025 | #define ACPI_VALID_SXDS 0x20 | ||
1026 | #define ACPI_VALID_SXWS 0x40 | ||
1004 | 1027 | ||
1005 | /* Flags for _STA method */ | 1028 | /* Flags for _STA method */ |
1006 | 1029 | ||
@@ -1011,29 +1034,6 @@ struct acpi_compatible_id_list { | |||
1011 | #define ACPI_STA_DEVICE_OK 0x08 /* Synonym */ | 1034 | #define ACPI_STA_DEVICE_OK 0x08 /* Synonym */ |
1012 | #define ACPI_STA_BATTERY_PRESENT 0x10 | 1035 | #define ACPI_STA_BATTERY_PRESENT 0x10 |
1013 | 1036 | ||
1014 | #define ACPI_COMMON_OBJ_INFO \ | ||
1015 | acpi_object_type type; /* ACPI object type */ \ | ||
1016 | acpi_name name /* ACPI object Name */ | ||
1017 | |||
1018 | struct acpi_obj_info_header { | ||
1019 | ACPI_COMMON_OBJ_INFO; | ||
1020 | }; | ||
1021 | |||
1022 | /* Structure returned from Get Object Info */ | ||
1023 | |||
1024 | struct acpi_device_info { | ||
1025 | ACPI_COMMON_OBJ_INFO; | ||
1026 | |||
1027 | u32 param_count; /* If a method, required parameter count */ | ||
1028 | u32 valid; /* Indicates which fields below are valid */ | ||
1029 | u32 current_status; /* _STA value */ | ||
1030 | acpi_integer address; /* _ADR value if any */ | ||
1031 | struct acpica_device_id hardware_id; /* _HID value if any */ | ||
1032 | struct acpica_device_id unique_id; /* _UID value if any */ | ||
1033 | u8 highest_dstates[4]; /* _sx_d values: 0xFF indicates not valid */ | ||
1034 | struct acpi_compatible_id_list compatibility_id; /* List of _CIDs if any */ | ||
1035 | }; | ||
1036 | |||
1037 | /* Context structs for address space handlers */ | 1037 | /* Context structs for address space handlers */ |
1038 | 1038 | ||
1039 | struct acpi_pci_id { | 1039 | struct acpi_pci_id { |
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index fcb8e4b159b1..9d7febde10a1 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h | |||
@@ -149,10 +149,10 @@ static inline void *acpi_os_acquire_object(acpi_cache_t * cache) | |||
149 | #define ACPI_FREE(a) kfree(a) | 149 | #define ACPI_FREE(a) kfree(a) |
150 | 150 | ||
151 | /* Used within ACPICA to show where it is safe to preempt execution */ | 151 | /* Used within ACPICA to show where it is safe to preempt execution */ |
152 | 152 | #include <linux/hardirq.h> | |
153 | #define ACPI_PREEMPTION_POINT() \ | 153 | #define ACPI_PREEMPTION_POINT() \ |
154 | do { \ | 154 | do { \ |
155 | if (!irqs_disabled()) \ | 155 | if (!in_atomic_preempt_off()) \ |
156 | cond_resched(); \ | 156 | cond_resched(); \ |
157 | } while (0) | 157 | } while (0) |
158 | 158 | ||
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 34321cfffeab..dfcd920c3e54 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -41,8 +41,6 @@ | |||
41 | #include <acpi/acpi_drivers.h> | 41 | #include <acpi/acpi_drivers.h> |
42 | #include <acpi/acpi_numa.h> | 42 | #include <acpi/acpi_numa.h> |
43 | #include <asm/acpi.h> | 43 | #include <asm/acpi.h> |
44 | #include <linux/dmi.h> | ||
45 | |||
46 | 44 | ||
47 | enum acpi_irq_model_id { | 45 | enum acpi_irq_model_id { |
48 | ACPI_IRQ_MODEL_PIC = 0, | 46 | ACPI_IRQ_MODEL_PIC = 0, |
@@ -219,10 +217,8 @@ static inline int acpi_video_display_switch_support(void) | |||
219 | #endif /* defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE) */ | 217 | #endif /* defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE) */ |
220 | 218 | ||
221 | extern int acpi_blacklisted(void); | 219 | extern int acpi_blacklisted(void); |
222 | #ifdef CONFIG_DMI | ||
223 | extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d); | 220 | extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d); |
224 | extern int acpi_osi_setup(char *str); | 221 | extern int acpi_osi_setup(char *str); |
225 | #endif | ||
226 | 222 | ||
227 | #ifdef CONFIG_ACPI_NUMA | 223 | #ifdef CONFIG_ACPI_NUMA |
228 | int acpi_get_pxm(acpi_handle handle); | 224 | int acpi_get_pxm(acpi_handle handle); |
@@ -292,7 +288,10 @@ void __init acpi_s4_no_nvs(void); | |||
292 | extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags); | 288 | extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags); |
293 | extern void acpi_early_init(void); | 289 | extern void acpi_early_init(void); |
294 | 290 | ||
295 | #else /* CONFIG_ACPI */ | 291 | #else /* !CONFIG_ACPI */ |
292 | |||
293 | #define acpi_disabled 1 | ||
294 | |||
296 | static inline void acpi_early_init(void) { } | 295 | static inline void acpi_early_init(void) { } |
297 | 296 | ||
298 | static inline int early_acpi_boot_init(void) | 297 | static inline int early_acpi_boot_init(void) |
@@ -331,5 +330,11 @@ static inline int acpi_check_mem_region(resource_size_t start, | |||
331 | return 0; | 330 | return 0; |
332 | } | 331 | } |
333 | 332 | ||
333 | struct acpi_table_header; | ||
334 | static inline int acpi_table_parse(char *id, | ||
335 | int (*handler)(struct acpi_table_header *)) | ||
336 | { | ||
337 | return -1; | ||
338 | } | ||
334 | #endif /* !CONFIG_ACPI */ | 339 | #endif /* !CONFIG_ACPI */ |
335 | #endif /*_LINUX_ACPI_H*/ | 340 | #endif /*_LINUX_ACPI_H*/ |