Commit 76dfdc2c6ed8cd9dde0d18091c2cf41b1e378be4
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
Merge branches 'acpi-scan' and 'acpi-ec'
* acpi-scan: ACPI: Use ACPI companion to match only the first physical device * acpi-ec: ACPI / EC: Fix regression due to conflicting firmware behavior between Samsung and Acer. Revert "ACPI / EC: Add support to disallow QR_EC to be issued before completing previous QR_EC"
Showing 2 changed files Inline Diff
drivers/acpi/ec.c
1 | /* | 1 | /* |
2 | * ec.c - ACPI Embedded Controller Driver (v2.2) | 2 | * ec.c - ACPI Embedded Controller Driver (v2.2) |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2014 Intel Corporation | 4 | * Copyright (C) 2001-2014 Intel Corporation |
5 | * Author: 2014 Lv Zheng <lv.zheng@intel.com> | 5 | * Author: 2014 Lv Zheng <lv.zheng@intel.com> |
6 | * 2006, 2007 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> | 6 | * 2006, 2007 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> |
7 | * 2006 Denis Sadykov <denis.m.sadykov@intel.com> | 7 | * 2006 Denis Sadykov <denis.m.sadykov@intel.com> |
8 | * 2004 Luming Yu <luming.yu@intel.com> | 8 | * 2004 Luming Yu <luming.yu@intel.com> |
9 | * 2001, 2002 Andy Grover <andrew.grover@intel.com> | 9 | * 2001, 2002 Andy Grover <andrew.grover@intel.com> |
10 | * 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> | 10 | * 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> |
11 | * Copyright (C) 2008 Alexey Starikovskiy <astarikovskiy@suse.de> | 11 | * Copyright (C) 2008 Alexey Starikovskiy <astarikovskiy@suse.de> |
12 | * | 12 | * |
13 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 13 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
14 | * | 14 | * |
15 | * This program is free software; you can redistribute it and/or modify | 15 | * This program is free software; you can redistribute it and/or modify |
16 | * it under the terms of the GNU General Public License as published by | 16 | * it under the terms of the GNU General Public License as published by |
17 | * the Free Software Foundation; either version 2 of the License, or (at | 17 | * the Free Software Foundation; either version 2 of the License, or (at |
18 | * your option) any later version. | 18 | * your option) any later version. |
19 | * | 19 | * |
20 | * This program is distributed in the hope that it will be useful, but | 20 | * This program is distributed in the hope that it will be useful, but |
21 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 21 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
23 | * General Public License for more details. | 23 | * General Public License for more details. |
24 | * | 24 | * |
25 | * You should have received a copy of the GNU General Public License along | 25 | * You should have received a copy of the GNU General Public License along |
26 | * with this program; if not, write to the Free Software Foundation, Inc., | 26 | * with this program; if not, write to the Free Software Foundation, Inc., |
27 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | 27 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
28 | * | 28 | * |
29 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 29 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
30 | */ | 30 | */ |
31 | 31 | ||
32 | /* Uncomment next line to get verbose printout */ | 32 | /* Uncomment next line to get verbose printout */ |
33 | /* #define DEBUG */ | 33 | /* #define DEBUG */ |
34 | #define pr_fmt(fmt) "ACPI : EC: " fmt | 34 | #define pr_fmt(fmt) "ACPI : EC: " fmt |
35 | 35 | ||
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #include <linux/init.h> | 38 | #include <linux/init.h> |
39 | #include <linux/types.h> | 39 | #include <linux/types.h> |
40 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
41 | #include <linux/interrupt.h> | 41 | #include <linux/interrupt.h> |
42 | #include <linux/list.h> | 42 | #include <linux/list.h> |
43 | #include <linux/spinlock.h> | 43 | #include <linux/spinlock.h> |
44 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
45 | #include <linux/acpi.h> | 45 | #include <linux/acpi.h> |
46 | #include <linux/dmi.h> | 46 | #include <linux/dmi.h> |
47 | #include <asm/io.h> | 47 | #include <asm/io.h> |
48 | 48 | ||
49 | #include "internal.h" | 49 | #include "internal.h" |
50 | 50 | ||
51 | #define ACPI_EC_CLASS "embedded_controller" | 51 | #define ACPI_EC_CLASS "embedded_controller" |
52 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" | 52 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" |
53 | #define ACPI_EC_FILE_INFO "info" | 53 | #define ACPI_EC_FILE_INFO "info" |
54 | 54 | ||
55 | /* EC status register */ | 55 | /* EC status register */ |
56 | #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ | 56 | #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ |
57 | #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ | 57 | #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ |
58 | #define ACPI_EC_FLAG_CMD 0x08 /* Input buffer contains a command */ | 58 | #define ACPI_EC_FLAG_CMD 0x08 /* Input buffer contains a command */ |
59 | #define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ | 59 | #define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ |
60 | #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ | 60 | #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ |
61 | 61 | ||
62 | /* EC commands */ | 62 | /* EC commands */ |
63 | enum ec_command { | 63 | enum ec_command { |
64 | ACPI_EC_COMMAND_READ = 0x80, | 64 | ACPI_EC_COMMAND_READ = 0x80, |
65 | ACPI_EC_COMMAND_WRITE = 0x81, | 65 | ACPI_EC_COMMAND_WRITE = 0x81, |
66 | ACPI_EC_BURST_ENABLE = 0x82, | 66 | ACPI_EC_BURST_ENABLE = 0x82, |
67 | ACPI_EC_BURST_DISABLE = 0x83, | 67 | ACPI_EC_BURST_DISABLE = 0x83, |
68 | ACPI_EC_COMMAND_QUERY = 0x84, | 68 | ACPI_EC_COMMAND_QUERY = 0x84, |
69 | }; | 69 | }; |
70 | 70 | ||
71 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ | 71 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ |
72 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ | 72 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
73 | #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ | 73 | #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ |
74 | #define ACPI_EC_CLEAR_MAX 100 /* Maximum number of events to query | 74 | #define ACPI_EC_CLEAR_MAX 100 /* Maximum number of events to query |
75 | * when trying to clear the EC */ | 75 | * when trying to clear the EC */ |
76 | 76 | ||
77 | enum { | 77 | enum { |
78 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ | 78 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ |
79 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ | 79 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ |
80 | EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and | 80 | EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and |
81 | * OpReg are installed */ | 81 | * OpReg are installed */ |
82 | EC_FLAGS_BLOCKED, /* Transactions are blocked */ | 82 | EC_FLAGS_BLOCKED, /* Transactions are blocked */ |
83 | }; | 83 | }; |
84 | 84 | ||
85 | #define ACPI_EC_COMMAND_POLL 0x01 /* Available for command byte */ | 85 | #define ACPI_EC_COMMAND_POLL 0x01 /* Available for command byte */ |
86 | #define ACPI_EC_COMMAND_COMPLETE 0x02 /* Completed last byte */ | 86 | #define ACPI_EC_COMMAND_COMPLETE 0x02 /* Completed last byte */ |
87 | 87 | ||
88 | /* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */ | 88 | /* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */ |
89 | static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY; | 89 | static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY; |
90 | module_param(ec_delay, uint, 0644); | 90 | module_param(ec_delay, uint, 0644); |
91 | MODULE_PARM_DESC(ec_delay, "Timeout(ms) waited until an EC command completes"); | 91 | MODULE_PARM_DESC(ec_delay, "Timeout(ms) waited until an EC command completes"); |
92 | 92 | ||
93 | /* | 93 | /* |
94 | * If the number of false interrupts per one transaction exceeds | 94 | * If the number of false interrupts per one transaction exceeds |
95 | * this threshold, will think there is a GPE storm happened and | 95 | * this threshold, will think there is a GPE storm happened and |
96 | * will disable the GPE for normal transaction. | 96 | * will disable the GPE for normal transaction. |
97 | */ | 97 | */ |
98 | static unsigned int ec_storm_threshold __read_mostly = 8; | 98 | static unsigned int ec_storm_threshold __read_mostly = 8; |
99 | module_param(ec_storm_threshold, uint, 0644); | 99 | module_param(ec_storm_threshold, uint, 0644); |
100 | MODULE_PARM_DESC(ec_storm_threshold, "Maxim false GPE numbers not considered as GPE storm"); | 100 | MODULE_PARM_DESC(ec_storm_threshold, "Maxim false GPE numbers not considered as GPE storm"); |
101 | 101 | ||
102 | struct acpi_ec_query_handler { | 102 | struct acpi_ec_query_handler { |
103 | struct list_head node; | 103 | struct list_head node; |
104 | acpi_ec_query_func func; | 104 | acpi_ec_query_func func; |
105 | acpi_handle handle; | 105 | acpi_handle handle; |
106 | void *data; | 106 | void *data; |
107 | u8 query_bit; | 107 | u8 query_bit; |
108 | }; | 108 | }; |
109 | 109 | ||
110 | struct transaction { | 110 | struct transaction { |
111 | const u8 *wdata; | 111 | const u8 *wdata; |
112 | u8 *rdata; | 112 | u8 *rdata; |
113 | unsigned short irq_count; | 113 | unsigned short irq_count; |
114 | u8 command; | 114 | u8 command; |
115 | u8 wi; | 115 | u8 wi; |
116 | u8 ri; | 116 | u8 ri; |
117 | u8 wlen; | 117 | u8 wlen; |
118 | u8 rlen; | 118 | u8 rlen; |
119 | u8 flags; | 119 | u8 flags; |
120 | }; | 120 | }; |
121 | 121 | ||
122 | struct acpi_ec *boot_ec, *first_ec; | 122 | struct acpi_ec *boot_ec, *first_ec; |
123 | EXPORT_SYMBOL(first_ec); | 123 | EXPORT_SYMBOL(first_ec); |
124 | 124 | ||
125 | static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ | 125 | static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ |
126 | static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ | 126 | static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ |
127 | static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */ | 127 | static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */ |
128 | static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ | 128 | static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ |
129 | static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */ | ||
129 | 130 | ||
130 | /* -------------------------------------------------------------------------- | 131 | /* -------------------------------------------------------------------------- |
131 | * Transaction Management | 132 | * Transaction Management |
132 | * -------------------------------------------------------------------------- */ | 133 | * -------------------------------------------------------------------------- */ |
133 | 134 | ||
134 | static inline u8 acpi_ec_read_status(struct acpi_ec *ec) | 135 | static inline u8 acpi_ec_read_status(struct acpi_ec *ec) |
135 | { | 136 | { |
136 | u8 x = inb(ec->command_addr); | 137 | u8 x = inb(ec->command_addr); |
137 | 138 | ||
138 | pr_debug("EC_SC(R) = 0x%2.2x " | 139 | pr_debug("EC_SC(R) = 0x%2.2x " |
139 | "SCI_EVT=%d BURST=%d CMD=%d IBF=%d OBF=%d\n", | 140 | "SCI_EVT=%d BURST=%d CMD=%d IBF=%d OBF=%d\n", |
140 | x, | 141 | x, |
141 | !!(x & ACPI_EC_FLAG_SCI), | 142 | !!(x & ACPI_EC_FLAG_SCI), |
142 | !!(x & ACPI_EC_FLAG_BURST), | 143 | !!(x & ACPI_EC_FLAG_BURST), |
143 | !!(x & ACPI_EC_FLAG_CMD), | 144 | !!(x & ACPI_EC_FLAG_CMD), |
144 | !!(x & ACPI_EC_FLAG_IBF), | 145 | !!(x & ACPI_EC_FLAG_IBF), |
145 | !!(x & ACPI_EC_FLAG_OBF)); | 146 | !!(x & ACPI_EC_FLAG_OBF)); |
146 | return x; | 147 | return x; |
147 | } | 148 | } |
148 | 149 | ||
149 | static inline u8 acpi_ec_read_data(struct acpi_ec *ec) | 150 | static inline u8 acpi_ec_read_data(struct acpi_ec *ec) |
150 | { | 151 | { |
151 | u8 x = inb(ec->data_addr); | 152 | u8 x = inb(ec->data_addr); |
152 | 153 | ||
153 | pr_debug("EC_DATA(R) = 0x%2.2x\n", x); | 154 | pr_debug("EC_DATA(R) = 0x%2.2x\n", x); |
154 | return x; | 155 | return x; |
155 | } | 156 | } |
156 | 157 | ||
157 | static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) | 158 | static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) |
158 | { | 159 | { |
159 | pr_debug("EC_SC(W) = 0x%2.2x\n", command); | 160 | pr_debug("EC_SC(W) = 0x%2.2x\n", command); |
160 | outb(command, ec->command_addr); | 161 | outb(command, ec->command_addr); |
161 | } | 162 | } |
162 | 163 | ||
163 | static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) | 164 | static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) |
164 | { | 165 | { |
165 | pr_debug("EC_DATA(W) = 0x%2.2x\n", data); | 166 | pr_debug("EC_DATA(W) = 0x%2.2x\n", data); |
166 | outb(data, ec->data_addr); | 167 | outb(data, ec->data_addr); |
167 | } | 168 | } |
168 | 169 | ||
169 | #ifdef DEBUG | 170 | #ifdef DEBUG |
170 | static const char *acpi_ec_cmd_string(u8 cmd) | 171 | static const char *acpi_ec_cmd_string(u8 cmd) |
171 | { | 172 | { |
172 | switch (cmd) { | 173 | switch (cmd) { |
173 | case 0x80: | 174 | case 0x80: |
174 | return "RD_EC"; | 175 | return "RD_EC"; |
175 | case 0x81: | 176 | case 0x81: |
176 | return "WR_EC"; | 177 | return "WR_EC"; |
177 | case 0x82: | 178 | case 0x82: |
178 | return "BE_EC"; | 179 | return "BE_EC"; |
179 | case 0x83: | 180 | case 0x83: |
180 | return "BD_EC"; | 181 | return "BD_EC"; |
181 | case 0x84: | 182 | case 0x84: |
182 | return "QR_EC"; | 183 | return "QR_EC"; |
183 | } | 184 | } |
184 | return "UNKNOWN"; | 185 | return "UNKNOWN"; |
185 | } | 186 | } |
186 | #else | 187 | #else |
187 | #define acpi_ec_cmd_string(cmd) "UNDEF" | 188 | #define acpi_ec_cmd_string(cmd) "UNDEF" |
188 | #endif | 189 | #endif |
189 | 190 | ||
190 | static int ec_transaction_completed(struct acpi_ec *ec) | 191 | static int ec_transaction_completed(struct acpi_ec *ec) |
191 | { | 192 | { |
192 | unsigned long flags; | 193 | unsigned long flags; |
193 | int ret = 0; | 194 | int ret = 0; |
194 | 195 | ||
195 | spin_lock_irqsave(&ec->lock, flags); | 196 | spin_lock_irqsave(&ec->lock, flags); |
196 | if (ec->curr && (ec->curr->flags & ACPI_EC_COMMAND_COMPLETE)) | 197 | if (ec->curr && (ec->curr->flags & ACPI_EC_COMMAND_COMPLETE)) |
197 | ret = 1; | 198 | ret = 1; |
198 | spin_unlock_irqrestore(&ec->lock, flags); | 199 | spin_unlock_irqrestore(&ec->lock, flags); |
199 | return ret; | 200 | return ret; |
200 | } | 201 | } |
201 | 202 | ||
202 | static bool advance_transaction(struct acpi_ec *ec) | 203 | static bool advance_transaction(struct acpi_ec *ec) |
203 | { | 204 | { |
204 | struct transaction *t; | 205 | struct transaction *t; |
205 | u8 status; | 206 | u8 status; |
206 | bool wakeup = false; | 207 | bool wakeup = false; |
207 | 208 | ||
208 | pr_debug("===== %s (%d) =====\n", | 209 | pr_debug("===== %s (%d) =====\n", |
209 | in_interrupt() ? "IRQ" : "TASK", smp_processor_id()); | 210 | in_interrupt() ? "IRQ" : "TASK", smp_processor_id()); |
210 | status = acpi_ec_read_status(ec); | 211 | status = acpi_ec_read_status(ec); |
211 | t = ec->curr; | 212 | t = ec->curr; |
212 | if (!t) | 213 | if (!t) |
213 | goto err; | 214 | goto err; |
214 | if (t->flags & ACPI_EC_COMMAND_POLL) { | 215 | if (t->flags & ACPI_EC_COMMAND_POLL) { |
215 | if (t->wlen > t->wi) { | 216 | if (t->wlen > t->wi) { |
216 | if ((status & ACPI_EC_FLAG_IBF) == 0) | 217 | if ((status & ACPI_EC_FLAG_IBF) == 0) |
217 | acpi_ec_write_data(ec, t->wdata[t->wi++]); | 218 | acpi_ec_write_data(ec, t->wdata[t->wi++]); |
218 | else | 219 | else |
219 | goto err; | 220 | goto err; |
220 | } else if (t->rlen > t->ri) { | 221 | } else if (t->rlen > t->ri) { |
221 | if ((status & ACPI_EC_FLAG_OBF) == 1) { | 222 | if ((status & ACPI_EC_FLAG_OBF) == 1) { |
222 | t->rdata[t->ri++] = acpi_ec_read_data(ec); | 223 | t->rdata[t->ri++] = acpi_ec_read_data(ec); |
223 | if (t->rlen == t->ri) { | 224 | if (t->rlen == t->ri) { |
224 | t->flags |= ACPI_EC_COMMAND_COMPLETE; | 225 | t->flags |= ACPI_EC_COMMAND_COMPLETE; |
225 | if (t->command == ACPI_EC_COMMAND_QUERY) | 226 | if (t->command == ACPI_EC_COMMAND_QUERY) |
226 | pr_debug("***** Command(%s) hardware completion *****\n", | 227 | pr_debug("***** Command(%s) hardware completion *****\n", |
227 | acpi_ec_cmd_string(t->command)); | 228 | acpi_ec_cmd_string(t->command)); |
228 | wakeup = true; | 229 | wakeup = true; |
229 | } | 230 | } |
230 | } else | 231 | } else |
231 | goto err; | 232 | goto err; |
232 | } else if (t->wlen == t->wi && | 233 | } else if (t->wlen == t->wi && |
233 | (status & ACPI_EC_FLAG_IBF) == 0) { | 234 | (status & ACPI_EC_FLAG_IBF) == 0) { |
234 | t->flags |= ACPI_EC_COMMAND_COMPLETE; | 235 | t->flags |= ACPI_EC_COMMAND_COMPLETE; |
235 | wakeup = true; | 236 | wakeup = true; |
236 | } | 237 | } |
237 | return wakeup; | 238 | return wakeup; |
238 | } else { | 239 | } else { |
239 | /* | 240 | if (EC_FLAGS_QUERY_HANDSHAKE && |
240 | * There is firmware refusing to respond QR_EC when SCI_EVT | 241 | !(status & ACPI_EC_FLAG_SCI) && |
241 | * is not set, for which case, we complete the QR_EC | ||
242 | * without issuing it to the firmware. | ||
243 | * https://bugzilla.kernel.org/show_bug.cgi?id=86211 | ||
244 | */ | ||
245 | if (!(status & ACPI_EC_FLAG_SCI) && | ||
246 | (t->command == ACPI_EC_COMMAND_QUERY)) { | 242 | (t->command == ACPI_EC_COMMAND_QUERY)) { |
247 | t->flags |= ACPI_EC_COMMAND_POLL; | 243 | t->flags |= ACPI_EC_COMMAND_POLL; |
248 | t->rdata[t->ri++] = 0x00; | 244 | t->rdata[t->ri++] = 0x00; |
249 | t->flags |= ACPI_EC_COMMAND_COMPLETE; | 245 | t->flags |= ACPI_EC_COMMAND_COMPLETE; |
250 | pr_debug("***** Command(%s) software completion *****\n", | 246 | pr_debug("***** Command(%s) software completion *****\n", |
251 | acpi_ec_cmd_string(t->command)); | 247 | acpi_ec_cmd_string(t->command)); |
252 | wakeup = true; | 248 | wakeup = true; |
253 | } else if ((status & ACPI_EC_FLAG_IBF) == 0) { | 249 | } else if ((status & ACPI_EC_FLAG_IBF) == 0) { |
254 | acpi_ec_write_cmd(ec, t->command); | 250 | acpi_ec_write_cmd(ec, t->command); |
255 | t->flags |= ACPI_EC_COMMAND_POLL; | 251 | t->flags |= ACPI_EC_COMMAND_POLL; |
256 | } else | 252 | } else |
257 | goto err; | 253 | goto err; |
258 | return wakeup; | 254 | return wakeup; |
259 | } | 255 | } |
260 | err: | 256 | err: |
261 | /* | 257 | /* |
262 | * If SCI bit is set, then don't think it's a false IRQ | 258 | * If SCI bit is set, then don't think it's a false IRQ |
263 | * otherwise will take a not handled IRQ as a false one. | 259 | * otherwise will take a not handled IRQ as a false one. |
264 | */ | 260 | */ |
265 | if (!(status & ACPI_EC_FLAG_SCI)) { | 261 | if (!(status & ACPI_EC_FLAG_SCI)) { |
266 | if (in_interrupt() && t) | 262 | if (in_interrupt() && t) |
267 | ++t->irq_count; | 263 | ++t->irq_count; |
268 | } | 264 | } |
269 | return wakeup; | 265 | return wakeup; |
270 | } | 266 | } |
271 | 267 | ||
272 | static void start_transaction(struct acpi_ec *ec) | 268 | static void start_transaction(struct acpi_ec *ec) |
273 | { | 269 | { |
274 | ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0; | 270 | ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0; |
275 | ec->curr->flags = 0; | 271 | ec->curr->flags = 0; |
276 | (void)advance_transaction(ec); | 272 | (void)advance_transaction(ec); |
277 | } | 273 | } |
278 | 274 | ||
279 | static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data); | 275 | static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data); |
280 | 276 | ||
281 | static int ec_check_sci_sync(struct acpi_ec *ec, u8 state) | 277 | static int ec_check_sci_sync(struct acpi_ec *ec, u8 state) |
282 | { | 278 | { |
283 | if (state & ACPI_EC_FLAG_SCI) { | 279 | if (state & ACPI_EC_FLAG_SCI) { |
284 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) | 280 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) |
285 | return acpi_ec_sync_query(ec, NULL); | 281 | return acpi_ec_sync_query(ec, NULL); |
286 | } | 282 | } |
287 | return 0; | 283 | return 0; |
288 | } | 284 | } |
289 | 285 | ||
290 | static int ec_poll(struct acpi_ec *ec) | 286 | static int ec_poll(struct acpi_ec *ec) |
291 | { | 287 | { |
292 | unsigned long flags; | 288 | unsigned long flags; |
293 | int repeat = 5; /* number of command restarts */ | 289 | int repeat = 5; /* number of command restarts */ |
294 | 290 | ||
295 | while (repeat--) { | 291 | while (repeat--) { |
296 | unsigned long delay = jiffies + | 292 | unsigned long delay = jiffies + |
297 | msecs_to_jiffies(ec_delay); | 293 | msecs_to_jiffies(ec_delay); |
298 | do { | 294 | do { |
299 | /* don't sleep with disabled interrupts */ | 295 | /* don't sleep with disabled interrupts */ |
300 | if (EC_FLAGS_MSI || irqs_disabled()) { | 296 | if (EC_FLAGS_MSI || irqs_disabled()) { |
301 | udelay(ACPI_EC_MSI_UDELAY); | 297 | udelay(ACPI_EC_MSI_UDELAY); |
302 | if (ec_transaction_completed(ec)) | 298 | if (ec_transaction_completed(ec)) |
303 | return 0; | 299 | return 0; |
304 | } else { | 300 | } else { |
305 | if (wait_event_timeout(ec->wait, | 301 | if (wait_event_timeout(ec->wait, |
306 | ec_transaction_completed(ec), | 302 | ec_transaction_completed(ec), |
307 | msecs_to_jiffies(1))) | 303 | msecs_to_jiffies(1))) |
308 | return 0; | 304 | return 0; |
309 | } | 305 | } |
310 | spin_lock_irqsave(&ec->lock, flags); | 306 | spin_lock_irqsave(&ec->lock, flags); |
311 | (void)advance_transaction(ec); | 307 | (void)advance_transaction(ec); |
312 | spin_unlock_irqrestore(&ec->lock, flags); | 308 | spin_unlock_irqrestore(&ec->lock, flags); |
313 | } while (time_before(jiffies, delay)); | 309 | } while (time_before(jiffies, delay)); |
314 | pr_debug("controller reset, restart transaction\n"); | 310 | pr_debug("controller reset, restart transaction\n"); |
315 | spin_lock_irqsave(&ec->lock, flags); | 311 | spin_lock_irqsave(&ec->lock, flags); |
316 | start_transaction(ec); | 312 | start_transaction(ec); |
317 | spin_unlock_irqrestore(&ec->lock, flags); | 313 | spin_unlock_irqrestore(&ec->lock, flags); |
318 | } | 314 | } |
319 | return -ETIME; | 315 | return -ETIME; |
320 | } | 316 | } |
321 | 317 | ||
322 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | 318 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, |
323 | struct transaction *t) | 319 | struct transaction *t) |
324 | { | 320 | { |
325 | unsigned long tmp; | 321 | unsigned long tmp; |
326 | int ret = 0; | 322 | int ret = 0; |
327 | 323 | ||
328 | if (EC_FLAGS_MSI) | 324 | if (EC_FLAGS_MSI) |
329 | udelay(ACPI_EC_MSI_UDELAY); | 325 | udelay(ACPI_EC_MSI_UDELAY); |
330 | /* start transaction */ | 326 | /* start transaction */ |
331 | spin_lock_irqsave(&ec->lock, tmp); | 327 | spin_lock_irqsave(&ec->lock, tmp); |
332 | /* following two actions should be kept atomic */ | 328 | /* following two actions should be kept atomic */ |
333 | ec->curr = t; | 329 | ec->curr = t; |
334 | pr_debug("***** Command(%s) started *****\n", | 330 | pr_debug("***** Command(%s) started *****\n", |
335 | acpi_ec_cmd_string(t->command)); | 331 | acpi_ec_cmd_string(t->command)); |
336 | start_transaction(ec); | 332 | start_transaction(ec); |
337 | spin_unlock_irqrestore(&ec->lock, tmp); | ||
338 | ret = ec_poll(ec); | ||
339 | spin_lock_irqsave(&ec->lock, tmp); | ||
340 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { | 333 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { |
341 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 334 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
342 | pr_debug("***** Event stopped *****\n"); | 335 | pr_debug("***** Event stopped *****\n"); |
343 | } | 336 | } |
337 | spin_unlock_irqrestore(&ec->lock, tmp); | ||
338 | ret = ec_poll(ec); | ||
339 | spin_lock_irqsave(&ec->lock, tmp); | ||
344 | pr_debug("***** Command(%s) stopped *****\n", | 340 | pr_debug("***** Command(%s) stopped *****\n", |
345 | acpi_ec_cmd_string(t->command)); | 341 | acpi_ec_cmd_string(t->command)); |
346 | ec->curr = NULL; | 342 | ec->curr = NULL; |
347 | spin_unlock_irqrestore(&ec->lock, tmp); | 343 | spin_unlock_irqrestore(&ec->lock, tmp); |
348 | return ret; | 344 | return ret; |
349 | } | 345 | } |
350 | 346 | ||
351 | static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | 347 | static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) |
352 | { | 348 | { |
353 | int status; | 349 | int status; |
354 | u32 glk; | 350 | u32 glk; |
355 | 351 | ||
356 | if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata)) | 352 | if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata)) |
357 | return -EINVAL; | 353 | return -EINVAL; |
358 | if (t->rdata) | 354 | if (t->rdata) |
359 | memset(t->rdata, 0, t->rlen); | 355 | memset(t->rdata, 0, t->rlen); |
360 | mutex_lock(&ec->mutex); | 356 | mutex_lock(&ec->mutex); |
361 | if (test_bit(EC_FLAGS_BLOCKED, &ec->flags)) { | 357 | if (test_bit(EC_FLAGS_BLOCKED, &ec->flags)) { |
362 | status = -EINVAL; | 358 | status = -EINVAL; |
363 | goto unlock; | 359 | goto unlock; |
364 | } | 360 | } |
365 | if (ec->global_lock) { | 361 | if (ec->global_lock) { |
366 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | 362 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); |
367 | if (ACPI_FAILURE(status)) { | 363 | if (ACPI_FAILURE(status)) { |
368 | status = -ENODEV; | 364 | status = -ENODEV; |
369 | goto unlock; | 365 | goto unlock; |
370 | } | 366 | } |
371 | } | 367 | } |
372 | /* disable GPE during transaction if storm is detected */ | 368 | /* disable GPE during transaction if storm is detected */ |
373 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 369 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
374 | /* It has to be disabled, so that it doesn't trigger. */ | 370 | /* It has to be disabled, so that it doesn't trigger. */ |
375 | acpi_disable_gpe(NULL, ec->gpe); | 371 | acpi_disable_gpe(NULL, ec->gpe); |
376 | } | 372 | } |
377 | 373 | ||
378 | status = acpi_ec_transaction_unlocked(ec, t); | 374 | status = acpi_ec_transaction_unlocked(ec, t); |
379 | 375 | ||
380 | /* check if we received SCI during transaction */ | 376 | /* check if we received SCI during transaction */ |
381 | ec_check_sci_sync(ec, acpi_ec_read_status(ec)); | 377 | ec_check_sci_sync(ec, acpi_ec_read_status(ec)); |
382 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 378 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
383 | msleep(1); | 379 | msleep(1); |
384 | /* It is safe to enable the GPE outside of the transaction. */ | 380 | /* It is safe to enable the GPE outside of the transaction. */ |
385 | acpi_enable_gpe(NULL, ec->gpe); | 381 | acpi_enable_gpe(NULL, ec->gpe); |
386 | } else if (t->irq_count > ec_storm_threshold) { | 382 | } else if (t->irq_count > ec_storm_threshold) { |
387 | pr_info("GPE storm detected(%d GPEs), " | 383 | pr_info("GPE storm detected(%d GPEs), " |
388 | "transactions will use polling mode\n", | 384 | "transactions will use polling mode\n", |
389 | t->irq_count); | 385 | t->irq_count); |
390 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); | 386 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); |
391 | } | 387 | } |
392 | if (ec->global_lock) | 388 | if (ec->global_lock) |
393 | acpi_release_global_lock(glk); | 389 | acpi_release_global_lock(glk); |
394 | unlock: | 390 | unlock: |
395 | mutex_unlock(&ec->mutex); | 391 | mutex_unlock(&ec->mutex); |
396 | return status; | 392 | return status; |
397 | } | 393 | } |
398 | 394 | ||
399 | static int acpi_ec_burst_enable(struct acpi_ec *ec) | 395 | static int acpi_ec_burst_enable(struct acpi_ec *ec) |
400 | { | 396 | { |
401 | u8 d; | 397 | u8 d; |
402 | struct transaction t = {.command = ACPI_EC_BURST_ENABLE, | 398 | struct transaction t = {.command = ACPI_EC_BURST_ENABLE, |
403 | .wdata = NULL, .rdata = &d, | 399 | .wdata = NULL, .rdata = &d, |
404 | .wlen = 0, .rlen = 1}; | 400 | .wlen = 0, .rlen = 1}; |
405 | 401 | ||
406 | return acpi_ec_transaction(ec, &t); | 402 | return acpi_ec_transaction(ec, &t); |
407 | } | 403 | } |
408 | 404 | ||
409 | static int acpi_ec_burst_disable(struct acpi_ec *ec) | 405 | static int acpi_ec_burst_disable(struct acpi_ec *ec) |
410 | { | 406 | { |
411 | struct transaction t = {.command = ACPI_EC_BURST_DISABLE, | 407 | struct transaction t = {.command = ACPI_EC_BURST_DISABLE, |
412 | .wdata = NULL, .rdata = NULL, | 408 | .wdata = NULL, .rdata = NULL, |
413 | .wlen = 0, .rlen = 0}; | 409 | .wlen = 0, .rlen = 0}; |
414 | 410 | ||
415 | return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? | 411 | return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? |
416 | acpi_ec_transaction(ec, &t) : 0; | 412 | acpi_ec_transaction(ec, &t) : 0; |
417 | } | 413 | } |
418 | 414 | ||
419 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data) | 415 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data) |
420 | { | 416 | { |
421 | int result; | 417 | int result; |
422 | u8 d; | 418 | u8 d; |
423 | struct transaction t = {.command = ACPI_EC_COMMAND_READ, | 419 | struct transaction t = {.command = ACPI_EC_COMMAND_READ, |
424 | .wdata = &address, .rdata = &d, | 420 | .wdata = &address, .rdata = &d, |
425 | .wlen = 1, .rlen = 1}; | 421 | .wlen = 1, .rlen = 1}; |
426 | 422 | ||
427 | result = acpi_ec_transaction(ec, &t); | 423 | result = acpi_ec_transaction(ec, &t); |
428 | *data = d; | 424 | *data = d; |
429 | return result; | 425 | return result; |
430 | } | 426 | } |
431 | 427 | ||
432 | static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) | 428 | static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) |
433 | { | 429 | { |
434 | u8 wdata[2] = { address, data }; | 430 | u8 wdata[2] = { address, data }; |
435 | struct transaction t = {.command = ACPI_EC_COMMAND_WRITE, | 431 | struct transaction t = {.command = ACPI_EC_COMMAND_WRITE, |
436 | .wdata = wdata, .rdata = NULL, | 432 | .wdata = wdata, .rdata = NULL, |
437 | .wlen = 2, .rlen = 0}; | 433 | .wlen = 2, .rlen = 0}; |
438 | 434 | ||
439 | return acpi_ec_transaction(ec, &t); | 435 | return acpi_ec_transaction(ec, &t); |
440 | } | 436 | } |
441 | 437 | ||
442 | int ec_read(u8 addr, u8 *val) | 438 | int ec_read(u8 addr, u8 *val) |
443 | { | 439 | { |
444 | int err; | 440 | int err; |
445 | u8 temp_data; | 441 | u8 temp_data; |
446 | 442 | ||
447 | if (!first_ec) | 443 | if (!first_ec) |
448 | return -ENODEV; | 444 | return -ENODEV; |
449 | 445 | ||
450 | err = acpi_ec_read(first_ec, addr, &temp_data); | 446 | err = acpi_ec_read(first_ec, addr, &temp_data); |
451 | 447 | ||
452 | if (!err) { | 448 | if (!err) { |
453 | *val = temp_data; | 449 | *val = temp_data; |
454 | return 0; | 450 | return 0; |
455 | } | 451 | } |
456 | return err; | 452 | return err; |
457 | } | 453 | } |
458 | EXPORT_SYMBOL(ec_read); | 454 | EXPORT_SYMBOL(ec_read); |
459 | 455 | ||
460 | int ec_write(u8 addr, u8 val) | 456 | int ec_write(u8 addr, u8 val) |
461 | { | 457 | { |
462 | int err; | 458 | int err; |
463 | 459 | ||
464 | if (!first_ec) | 460 | if (!first_ec) |
465 | return -ENODEV; | 461 | return -ENODEV; |
466 | 462 | ||
467 | err = acpi_ec_write(first_ec, addr, val); | 463 | err = acpi_ec_write(first_ec, addr, val); |
468 | 464 | ||
469 | return err; | 465 | return err; |
470 | } | 466 | } |
471 | EXPORT_SYMBOL(ec_write); | 467 | EXPORT_SYMBOL(ec_write); |
472 | 468 | ||
473 | int ec_transaction(u8 command, | 469 | int ec_transaction(u8 command, |
474 | const u8 *wdata, unsigned wdata_len, | 470 | const u8 *wdata, unsigned wdata_len, |
475 | u8 *rdata, unsigned rdata_len) | 471 | u8 *rdata, unsigned rdata_len) |
476 | { | 472 | { |
477 | struct transaction t = {.command = command, | 473 | struct transaction t = {.command = command, |
478 | .wdata = wdata, .rdata = rdata, | 474 | .wdata = wdata, .rdata = rdata, |
479 | .wlen = wdata_len, .rlen = rdata_len}; | 475 | .wlen = wdata_len, .rlen = rdata_len}; |
480 | 476 | ||
481 | if (!first_ec) | 477 | if (!first_ec) |
482 | return -ENODEV; | 478 | return -ENODEV; |
483 | 479 | ||
484 | return acpi_ec_transaction(first_ec, &t); | 480 | return acpi_ec_transaction(first_ec, &t); |
485 | } | 481 | } |
486 | EXPORT_SYMBOL(ec_transaction); | 482 | EXPORT_SYMBOL(ec_transaction); |
487 | 483 | ||
488 | /* Get the handle to the EC device */ | 484 | /* Get the handle to the EC device */ |
489 | acpi_handle ec_get_handle(void) | 485 | acpi_handle ec_get_handle(void) |
490 | { | 486 | { |
491 | if (!first_ec) | 487 | if (!first_ec) |
492 | return NULL; | 488 | return NULL; |
493 | return first_ec->handle; | 489 | return first_ec->handle; |
494 | } | 490 | } |
495 | EXPORT_SYMBOL(ec_get_handle); | 491 | EXPORT_SYMBOL(ec_get_handle); |
496 | 492 | ||
497 | /* | 493 | /* |
498 | * Process _Q events that might have accumulated in the EC. | 494 | * Process _Q events that might have accumulated in the EC. |
499 | * Run with locked ec mutex. | 495 | * Run with locked ec mutex. |
500 | */ | 496 | */ |
501 | static void acpi_ec_clear(struct acpi_ec *ec) | 497 | static void acpi_ec_clear(struct acpi_ec *ec) |
502 | { | 498 | { |
503 | int i, status; | 499 | int i, status; |
504 | u8 value = 0; | 500 | u8 value = 0; |
505 | 501 | ||
506 | for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) { | 502 | for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) { |
507 | status = acpi_ec_sync_query(ec, &value); | 503 | status = acpi_ec_sync_query(ec, &value); |
508 | if (status || !value) | 504 | if (status || !value) |
509 | break; | 505 | break; |
510 | } | 506 | } |
511 | 507 | ||
512 | if (unlikely(i == ACPI_EC_CLEAR_MAX)) | 508 | if (unlikely(i == ACPI_EC_CLEAR_MAX)) |
513 | pr_warn("Warning: Maximum of %d stale EC events cleared\n", i); | 509 | pr_warn("Warning: Maximum of %d stale EC events cleared\n", i); |
514 | else | 510 | else |
515 | pr_info("%d stale EC events cleared\n", i); | 511 | pr_info("%d stale EC events cleared\n", i); |
516 | } | 512 | } |
517 | 513 | ||
518 | void acpi_ec_block_transactions(void) | 514 | void acpi_ec_block_transactions(void) |
519 | { | 515 | { |
520 | struct acpi_ec *ec = first_ec; | 516 | struct acpi_ec *ec = first_ec; |
521 | 517 | ||
522 | if (!ec) | 518 | if (!ec) |
523 | return; | 519 | return; |
524 | 520 | ||
525 | mutex_lock(&ec->mutex); | 521 | mutex_lock(&ec->mutex); |
526 | /* Prevent transactions from being carried out */ | 522 | /* Prevent transactions from being carried out */ |
527 | set_bit(EC_FLAGS_BLOCKED, &ec->flags); | 523 | set_bit(EC_FLAGS_BLOCKED, &ec->flags); |
528 | mutex_unlock(&ec->mutex); | 524 | mutex_unlock(&ec->mutex); |
529 | } | 525 | } |
530 | 526 | ||
531 | void acpi_ec_unblock_transactions(void) | 527 | void acpi_ec_unblock_transactions(void) |
532 | { | 528 | { |
533 | struct acpi_ec *ec = first_ec; | 529 | struct acpi_ec *ec = first_ec; |
534 | 530 | ||
535 | if (!ec) | 531 | if (!ec) |
536 | return; | 532 | return; |
537 | 533 | ||
538 | mutex_lock(&ec->mutex); | 534 | mutex_lock(&ec->mutex); |
539 | /* Allow transactions to be carried out again */ | 535 | /* Allow transactions to be carried out again */ |
540 | clear_bit(EC_FLAGS_BLOCKED, &ec->flags); | 536 | clear_bit(EC_FLAGS_BLOCKED, &ec->flags); |
541 | 537 | ||
542 | if (EC_FLAGS_CLEAR_ON_RESUME) | 538 | if (EC_FLAGS_CLEAR_ON_RESUME) |
543 | acpi_ec_clear(ec); | 539 | acpi_ec_clear(ec); |
544 | 540 | ||
545 | mutex_unlock(&ec->mutex); | 541 | mutex_unlock(&ec->mutex); |
546 | } | 542 | } |
547 | 543 | ||
548 | void acpi_ec_unblock_transactions_early(void) | 544 | void acpi_ec_unblock_transactions_early(void) |
549 | { | 545 | { |
550 | /* | 546 | /* |
551 | * Allow transactions to happen again (this function is called from | 547 | * Allow transactions to happen again (this function is called from |
552 | * atomic context during wakeup, so we don't need to acquire the mutex). | 548 | * atomic context during wakeup, so we don't need to acquire the mutex). |
553 | */ | 549 | */ |
554 | if (first_ec) | 550 | if (first_ec) |
555 | clear_bit(EC_FLAGS_BLOCKED, &first_ec->flags); | 551 | clear_bit(EC_FLAGS_BLOCKED, &first_ec->flags); |
556 | } | 552 | } |
557 | 553 | ||
558 | static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 *data) | 554 | static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 *data) |
559 | { | 555 | { |
560 | int result; | 556 | int result; |
561 | u8 d; | 557 | u8 d; |
562 | struct transaction t = {.command = ACPI_EC_COMMAND_QUERY, | 558 | struct transaction t = {.command = ACPI_EC_COMMAND_QUERY, |
563 | .wdata = NULL, .rdata = &d, | 559 | .wdata = NULL, .rdata = &d, |
564 | .wlen = 0, .rlen = 1}; | 560 | .wlen = 0, .rlen = 1}; |
565 | 561 | ||
566 | if (!ec || !data) | 562 | if (!ec || !data) |
567 | return -EINVAL; | 563 | return -EINVAL; |
568 | /* | 564 | /* |
569 | * Query the EC to find out which _Qxx method we need to evaluate. | 565 | * Query the EC to find out which _Qxx method we need to evaluate. |
570 | * Note that successful completion of the query causes the ACPI_EC_SCI | 566 | * Note that successful completion of the query causes the ACPI_EC_SCI |
571 | * bit to be cleared (and thus clearing the interrupt source). | 567 | * bit to be cleared (and thus clearing the interrupt source). |
572 | */ | 568 | */ |
573 | result = acpi_ec_transaction_unlocked(ec, &t); | 569 | result = acpi_ec_transaction_unlocked(ec, &t); |
574 | if (result) | 570 | if (result) |
575 | return result; | 571 | return result; |
576 | if (!d) | 572 | if (!d) |
577 | return -ENODATA; | 573 | return -ENODATA; |
578 | *data = d; | 574 | *data = d; |
579 | return 0; | 575 | return 0; |
580 | } | 576 | } |
581 | 577 | ||
582 | /* -------------------------------------------------------------------------- | 578 | /* -------------------------------------------------------------------------- |
583 | Event Management | 579 | Event Management |
584 | -------------------------------------------------------------------------- */ | 580 | -------------------------------------------------------------------------- */ |
585 | int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, | 581 | int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, |
586 | acpi_handle handle, acpi_ec_query_func func, | 582 | acpi_handle handle, acpi_ec_query_func func, |
587 | void *data) | 583 | void *data) |
588 | { | 584 | { |
589 | struct acpi_ec_query_handler *handler = | 585 | struct acpi_ec_query_handler *handler = |
590 | kzalloc(sizeof(struct acpi_ec_query_handler), GFP_KERNEL); | 586 | kzalloc(sizeof(struct acpi_ec_query_handler), GFP_KERNEL); |
591 | 587 | ||
592 | if (!handler) | 588 | if (!handler) |
593 | return -ENOMEM; | 589 | return -ENOMEM; |
594 | 590 | ||
595 | handler->query_bit = query_bit; | 591 | handler->query_bit = query_bit; |
596 | handler->handle = handle; | 592 | handler->handle = handle; |
597 | handler->func = func; | 593 | handler->func = func; |
598 | handler->data = data; | 594 | handler->data = data; |
599 | mutex_lock(&ec->mutex); | 595 | mutex_lock(&ec->mutex); |
600 | list_add(&handler->node, &ec->list); | 596 | list_add(&handler->node, &ec->list); |
601 | mutex_unlock(&ec->mutex); | 597 | mutex_unlock(&ec->mutex); |
602 | return 0; | 598 | return 0; |
603 | } | 599 | } |
604 | EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler); | 600 | EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler); |
605 | 601 | ||
606 | void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) | 602 | void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) |
607 | { | 603 | { |
608 | struct acpi_ec_query_handler *handler, *tmp; | 604 | struct acpi_ec_query_handler *handler, *tmp; |
609 | 605 | ||
610 | mutex_lock(&ec->mutex); | 606 | mutex_lock(&ec->mutex); |
611 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { | 607 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { |
612 | if (query_bit == handler->query_bit) { | 608 | if (query_bit == handler->query_bit) { |
613 | list_del(&handler->node); | 609 | list_del(&handler->node); |
614 | kfree(handler); | 610 | kfree(handler); |
615 | } | 611 | } |
616 | } | 612 | } |
617 | mutex_unlock(&ec->mutex); | 613 | mutex_unlock(&ec->mutex); |
618 | } | 614 | } |
619 | EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); | 615 | EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); |
620 | 616 | ||
621 | static void acpi_ec_run(void *cxt) | 617 | static void acpi_ec_run(void *cxt) |
622 | { | 618 | { |
623 | struct acpi_ec_query_handler *handler = cxt; | 619 | struct acpi_ec_query_handler *handler = cxt; |
624 | 620 | ||
625 | if (!handler) | 621 | if (!handler) |
626 | return; | 622 | return; |
627 | pr_debug("##### Query(0x%02x) started #####\n", handler->query_bit); | 623 | pr_debug("##### Query(0x%02x) started #####\n", handler->query_bit); |
628 | if (handler->func) | 624 | if (handler->func) |
629 | handler->func(handler->data); | 625 | handler->func(handler->data); |
630 | else if (handler->handle) | 626 | else if (handler->handle) |
631 | acpi_evaluate_object(handler->handle, NULL, NULL, NULL); | 627 | acpi_evaluate_object(handler->handle, NULL, NULL, NULL); |
632 | pr_debug("##### Query(0x%02x) stopped #####\n", handler->query_bit); | 628 | pr_debug("##### Query(0x%02x) stopped #####\n", handler->query_bit); |
633 | kfree(handler); | 629 | kfree(handler); |
634 | } | 630 | } |
635 | 631 | ||
636 | static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data) | 632 | static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data) |
637 | { | 633 | { |
638 | u8 value = 0; | 634 | u8 value = 0; |
639 | int status; | 635 | int status; |
640 | struct acpi_ec_query_handler *handler, *copy; | 636 | struct acpi_ec_query_handler *handler, *copy; |
641 | 637 | ||
642 | status = acpi_ec_query_unlocked(ec, &value); | 638 | status = acpi_ec_query_unlocked(ec, &value); |
643 | if (data) | 639 | if (data) |
644 | *data = value; | 640 | *data = value; |
645 | if (status) | 641 | if (status) |
646 | return status; | 642 | return status; |
647 | 643 | ||
648 | list_for_each_entry(handler, &ec->list, node) { | 644 | list_for_each_entry(handler, &ec->list, node) { |
649 | if (value == handler->query_bit) { | 645 | if (value == handler->query_bit) { |
650 | /* have custom handler for this bit */ | 646 | /* have custom handler for this bit */ |
651 | copy = kmalloc(sizeof(*handler), GFP_KERNEL); | 647 | copy = kmalloc(sizeof(*handler), GFP_KERNEL); |
652 | if (!copy) | 648 | if (!copy) |
653 | return -ENOMEM; | 649 | return -ENOMEM; |
654 | memcpy(copy, handler, sizeof(*copy)); | 650 | memcpy(copy, handler, sizeof(*copy)); |
655 | pr_debug("##### Query(0x%02x) scheduled #####\n", | 651 | pr_debug("##### Query(0x%02x) scheduled #####\n", |
656 | handler->query_bit); | 652 | handler->query_bit); |
657 | return acpi_os_execute((copy->func) ? | 653 | return acpi_os_execute((copy->func) ? |
658 | OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER, | 654 | OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER, |
659 | acpi_ec_run, copy); | 655 | acpi_ec_run, copy); |
660 | } | 656 | } |
661 | } | 657 | } |
662 | return 0; | 658 | return 0; |
663 | } | 659 | } |
664 | 660 | ||
665 | static void acpi_ec_gpe_query(void *ec_cxt) | 661 | static void acpi_ec_gpe_query(void *ec_cxt) |
666 | { | 662 | { |
667 | struct acpi_ec *ec = ec_cxt; | 663 | struct acpi_ec *ec = ec_cxt; |
668 | 664 | ||
669 | if (!ec) | 665 | if (!ec) |
670 | return; | 666 | return; |
671 | mutex_lock(&ec->mutex); | 667 | mutex_lock(&ec->mutex); |
672 | acpi_ec_sync_query(ec, NULL); | 668 | acpi_ec_sync_query(ec, NULL); |
673 | mutex_unlock(&ec->mutex); | 669 | mutex_unlock(&ec->mutex); |
674 | } | 670 | } |
675 | 671 | ||
676 | static int ec_check_sci(struct acpi_ec *ec, u8 state) | 672 | static int ec_check_sci(struct acpi_ec *ec, u8 state) |
677 | { | 673 | { |
678 | if (state & ACPI_EC_FLAG_SCI) { | 674 | if (state & ACPI_EC_FLAG_SCI) { |
679 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { | 675 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { |
680 | pr_debug("***** Event started *****\n"); | 676 | pr_debug("***** Event started *****\n"); |
681 | return acpi_os_execute(OSL_NOTIFY_HANDLER, | 677 | return acpi_os_execute(OSL_NOTIFY_HANDLER, |
682 | acpi_ec_gpe_query, ec); | 678 | acpi_ec_gpe_query, ec); |
683 | } | 679 | } |
684 | } | 680 | } |
685 | return 0; | 681 | return 0; |
686 | } | 682 | } |
687 | 683 | ||
688 | static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, | 684 | static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, |
689 | u32 gpe_number, void *data) | 685 | u32 gpe_number, void *data) |
690 | { | 686 | { |
691 | unsigned long flags; | 687 | unsigned long flags; |
692 | struct acpi_ec *ec = data; | 688 | struct acpi_ec *ec = data; |
693 | 689 | ||
694 | spin_lock_irqsave(&ec->lock, flags); | 690 | spin_lock_irqsave(&ec->lock, flags); |
695 | if (advance_transaction(ec)) | 691 | if (advance_transaction(ec)) |
696 | wake_up(&ec->wait); | 692 | wake_up(&ec->wait); |
697 | spin_unlock_irqrestore(&ec->lock, flags); | 693 | spin_unlock_irqrestore(&ec->lock, flags); |
698 | ec_check_sci(ec, acpi_ec_read_status(ec)); | 694 | ec_check_sci(ec, acpi_ec_read_status(ec)); |
699 | return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE; | 695 | return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE; |
700 | } | 696 | } |
701 | 697 | ||
702 | /* -------------------------------------------------------------------------- | 698 | /* -------------------------------------------------------------------------- |
703 | * Address Space Management | 699 | * Address Space Management |
704 | * -------------------------------------------------------------------------- */ | 700 | * -------------------------------------------------------------------------- */ |
705 | 701 | ||
706 | static acpi_status | 702 | static acpi_status |
707 | acpi_ec_space_handler(u32 function, acpi_physical_address address, | 703 | acpi_ec_space_handler(u32 function, acpi_physical_address address, |
708 | u32 bits, u64 *value64, | 704 | u32 bits, u64 *value64, |
709 | void *handler_context, void *region_context) | 705 | void *handler_context, void *region_context) |
710 | { | 706 | { |
711 | struct acpi_ec *ec = handler_context; | 707 | struct acpi_ec *ec = handler_context; |
712 | int result = 0, i, bytes = bits / 8; | 708 | int result = 0, i, bytes = bits / 8; |
713 | u8 *value = (u8 *)value64; | 709 | u8 *value = (u8 *)value64; |
714 | 710 | ||
715 | if ((address > 0xFF) || !value || !handler_context) | 711 | if ((address > 0xFF) || !value || !handler_context) |
716 | return AE_BAD_PARAMETER; | 712 | return AE_BAD_PARAMETER; |
717 | 713 | ||
718 | if (function != ACPI_READ && function != ACPI_WRITE) | 714 | if (function != ACPI_READ && function != ACPI_WRITE) |
719 | return AE_BAD_PARAMETER; | 715 | return AE_BAD_PARAMETER; |
720 | 716 | ||
721 | if (EC_FLAGS_MSI || bits > 8) | 717 | if (EC_FLAGS_MSI || bits > 8) |
722 | acpi_ec_burst_enable(ec); | 718 | acpi_ec_burst_enable(ec); |
723 | 719 | ||
724 | for (i = 0; i < bytes; ++i, ++address, ++value) | 720 | for (i = 0; i < bytes; ++i, ++address, ++value) |
725 | result = (function == ACPI_READ) ? | 721 | result = (function == ACPI_READ) ? |
726 | acpi_ec_read(ec, address, value) : | 722 | acpi_ec_read(ec, address, value) : |
727 | acpi_ec_write(ec, address, *value); | 723 | acpi_ec_write(ec, address, *value); |
728 | 724 | ||
729 | if (EC_FLAGS_MSI || bits > 8) | 725 | if (EC_FLAGS_MSI || bits > 8) |
730 | acpi_ec_burst_disable(ec); | 726 | acpi_ec_burst_disable(ec); |
731 | 727 | ||
732 | switch (result) { | 728 | switch (result) { |
733 | case -EINVAL: | 729 | case -EINVAL: |
734 | return AE_BAD_PARAMETER; | 730 | return AE_BAD_PARAMETER; |
735 | case -ENODEV: | 731 | case -ENODEV: |
736 | return AE_NOT_FOUND; | 732 | return AE_NOT_FOUND; |
737 | case -ETIME: | 733 | case -ETIME: |
738 | return AE_TIME; | 734 | return AE_TIME; |
739 | default: | 735 | default: |
740 | return AE_OK; | 736 | return AE_OK; |
741 | } | 737 | } |
742 | } | 738 | } |
743 | 739 | ||
744 | /* -------------------------------------------------------------------------- | 740 | /* -------------------------------------------------------------------------- |
745 | * Driver Interface | 741 | * Driver Interface |
746 | * -------------------------------------------------------------------------- */ | 742 | * -------------------------------------------------------------------------- */ |
747 | 743 | ||
748 | static acpi_status | 744 | static acpi_status |
749 | ec_parse_io_ports(struct acpi_resource *resource, void *context); | 745 | ec_parse_io_ports(struct acpi_resource *resource, void *context); |
750 | 746 | ||
751 | static struct acpi_ec *make_acpi_ec(void) | 747 | static struct acpi_ec *make_acpi_ec(void) |
752 | { | 748 | { |
753 | struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); | 749 | struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); |
754 | 750 | ||
755 | if (!ec) | 751 | if (!ec) |
756 | return NULL; | 752 | return NULL; |
757 | ec->flags = 1 << EC_FLAGS_QUERY_PENDING; | 753 | ec->flags = 1 << EC_FLAGS_QUERY_PENDING; |
758 | mutex_init(&ec->mutex); | 754 | mutex_init(&ec->mutex); |
759 | init_waitqueue_head(&ec->wait); | 755 | init_waitqueue_head(&ec->wait); |
760 | INIT_LIST_HEAD(&ec->list); | 756 | INIT_LIST_HEAD(&ec->list); |
761 | spin_lock_init(&ec->lock); | 757 | spin_lock_init(&ec->lock); |
762 | return ec; | 758 | return ec; |
763 | } | 759 | } |
764 | 760 | ||
765 | static acpi_status | 761 | static acpi_status |
766 | acpi_ec_register_query_methods(acpi_handle handle, u32 level, | 762 | acpi_ec_register_query_methods(acpi_handle handle, u32 level, |
767 | void *context, void **return_value) | 763 | void *context, void **return_value) |
768 | { | 764 | { |
769 | char node_name[5]; | 765 | char node_name[5]; |
770 | struct acpi_buffer buffer = { sizeof(node_name), node_name }; | 766 | struct acpi_buffer buffer = { sizeof(node_name), node_name }; |
771 | struct acpi_ec *ec = context; | 767 | struct acpi_ec *ec = context; |
772 | int value = 0; | 768 | int value = 0; |
773 | acpi_status status; | 769 | acpi_status status; |
774 | 770 | ||
775 | status = acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer); | 771 | status = acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer); |
776 | 772 | ||
777 | if (ACPI_SUCCESS(status) && sscanf(node_name, "_Q%x", &value) == 1) | 773 | if (ACPI_SUCCESS(status) && sscanf(node_name, "_Q%x", &value) == 1) |
778 | acpi_ec_add_query_handler(ec, value, handle, NULL, NULL); | 774 | acpi_ec_add_query_handler(ec, value, handle, NULL, NULL); |
779 | return AE_OK; | 775 | return AE_OK; |
780 | } | 776 | } |
781 | 777 | ||
782 | static acpi_status | 778 | static acpi_status |
783 | ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) | 779 | ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) |
784 | { | 780 | { |
785 | acpi_status status; | 781 | acpi_status status; |
786 | unsigned long long tmp = 0; | 782 | unsigned long long tmp = 0; |
787 | struct acpi_ec *ec = context; | 783 | struct acpi_ec *ec = context; |
788 | 784 | ||
789 | /* clear addr values, ec_parse_io_ports depend on it */ | 785 | /* clear addr values, ec_parse_io_ports depend on it */ |
790 | ec->command_addr = ec->data_addr = 0; | 786 | ec->command_addr = ec->data_addr = 0; |
791 | 787 | ||
792 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, | 788 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, |
793 | ec_parse_io_ports, ec); | 789 | ec_parse_io_ports, ec); |
794 | if (ACPI_FAILURE(status)) | 790 | if (ACPI_FAILURE(status)) |
795 | return status; | 791 | return status; |
796 | 792 | ||
797 | /* Get GPE bit assignment (EC events). */ | 793 | /* Get GPE bit assignment (EC events). */ |
798 | /* TODO: Add support for _GPE returning a package */ | 794 | /* TODO: Add support for _GPE returning a package */ |
799 | status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp); | 795 | status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp); |
800 | if (ACPI_FAILURE(status)) | 796 | if (ACPI_FAILURE(status)) |
801 | return status; | 797 | return status; |
802 | ec->gpe = tmp; | 798 | ec->gpe = tmp; |
803 | /* Use the global lock for all EC transactions? */ | 799 | /* Use the global lock for all EC transactions? */ |
804 | tmp = 0; | 800 | tmp = 0; |
805 | acpi_evaluate_integer(handle, "_GLK", NULL, &tmp); | 801 | acpi_evaluate_integer(handle, "_GLK", NULL, &tmp); |
806 | ec->global_lock = tmp; | 802 | ec->global_lock = tmp; |
807 | ec->handle = handle; | 803 | ec->handle = handle; |
808 | return AE_CTRL_TERMINATE; | 804 | return AE_CTRL_TERMINATE; |
809 | } | 805 | } |
810 | 806 | ||
811 | static int ec_install_handlers(struct acpi_ec *ec) | 807 | static int ec_install_handlers(struct acpi_ec *ec) |
812 | { | 808 | { |
813 | acpi_status status; | 809 | acpi_status status; |
814 | 810 | ||
815 | if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) | 811 | if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) |
816 | return 0; | 812 | return 0; |
817 | status = acpi_install_gpe_handler(NULL, ec->gpe, | 813 | status = acpi_install_gpe_handler(NULL, ec->gpe, |
818 | ACPI_GPE_EDGE_TRIGGERED, | 814 | ACPI_GPE_EDGE_TRIGGERED, |
819 | &acpi_ec_gpe_handler, ec); | 815 | &acpi_ec_gpe_handler, ec); |
820 | if (ACPI_FAILURE(status)) | 816 | if (ACPI_FAILURE(status)) |
821 | return -ENODEV; | 817 | return -ENODEV; |
822 | 818 | ||
823 | acpi_enable_gpe(NULL, ec->gpe); | 819 | acpi_enable_gpe(NULL, ec->gpe); |
824 | status = acpi_install_address_space_handler(ec->handle, | 820 | status = acpi_install_address_space_handler(ec->handle, |
825 | ACPI_ADR_SPACE_EC, | 821 | ACPI_ADR_SPACE_EC, |
826 | &acpi_ec_space_handler, | 822 | &acpi_ec_space_handler, |
827 | NULL, ec); | 823 | NULL, ec); |
828 | if (ACPI_FAILURE(status)) { | 824 | if (ACPI_FAILURE(status)) { |
829 | if (status == AE_NOT_FOUND) { | 825 | if (status == AE_NOT_FOUND) { |
830 | /* | 826 | /* |
831 | * Maybe OS fails in evaluating the _REG object. | 827 | * Maybe OS fails in evaluating the _REG object. |
832 | * The AE_NOT_FOUND error will be ignored and OS | 828 | * The AE_NOT_FOUND error will be ignored and OS |
833 | * continue to initialize EC. | 829 | * continue to initialize EC. |
834 | */ | 830 | */ |
835 | pr_err("Fail in evaluating the _REG object" | 831 | pr_err("Fail in evaluating the _REG object" |
836 | " of EC device. Broken bios is suspected.\n"); | 832 | " of EC device. Broken bios is suspected.\n"); |
837 | } else { | 833 | } else { |
838 | acpi_disable_gpe(NULL, ec->gpe); | 834 | acpi_disable_gpe(NULL, ec->gpe); |
839 | acpi_remove_gpe_handler(NULL, ec->gpe, | 835 | acpi_remove_gpe_handler(NULL, ec->gpe, |
840 | &acpi_ec_gpe_handler); | 836 | &acpi_ec_gpe_handler); |
841 | return -ENODEV; | 837 | return -ENODEV; |
842 | } | 838 | } |
843 | } | 839 | } |
844 | 840 | ||
845 | set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); | 841 | set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); |
846 | return 0; | 842 | return 0; |
847 | } | 843 | } |
848 | 844 | ||
849 | static void ec_remove_handlers(struct acpi_ec *ec) | 845 | static void ec_remove_handlers(struct acpi_ec *ec) |
850 | { | 846 | { |
851 | acpi_disable_gpe(NULL, ec->gpe); | 847 | acpi_disable_gpe(NULL, ec->gpe); |
852 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, | 848 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, |
853 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) | 849 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) |
854 | pr_err("failed to remove space handler\n"); | 850 | pr_err("failed to remove space handler\n"); |
855 | if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, | 851 | if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, |
856 | &acpi_ec_gpe_handler))) | 852 | &acpi_ec_gpe_handler))) |
857 | pr_err("failed to remove gpe handler\n"); | 853 | pr_err("failed to remove gpe handler\n"); |
858 | clear_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); | 854 | clear_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); |
859 | } | 855 | } |
860 | 856 | ||
861 | static int acpi_ec_add(struct acpi_device *device) | 857 | static int acpi_ec_add(struct acpi_device *device) |
862 | { | 858 | { |
863 | struct acpi_ec *ec = NULL; | 859 | struct acpi_ec *ec = NULL; |
864 | int ret; | 860 | int ret; |
865 | 861 | ||
866 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); | 862 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); |
867 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); | 863 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); |
868 | 864 | ||
869 | /* Check for boot EC */ | 865 | /* Check for boot EC */ |
870 | if (boot_ec && | 866 | if (boot_ec && |
871 | (boot_ec->handle == device->handle || | 867 | (boot_ec->handle == device->handle || |
872 | boot_ec->handle == ACPI_ROOT_OBJECT)) { | 868 | boot_ec->handle == ACPI_ROOT_OBJECT)) { |
873 | ec = boot_ec; | 869 | ec = boot_ec; |
874 | boot_ec = NULL; | 870 | boot_ec = NULL; |
875 | } else { | 871 | } else { |
876 | ec = make_acpi_ec(); | 872 | ec = make_acpi_ec(); |
877 | if (!ec) | 873 | if (!ec) |
878 | return -ENOMEM; | 874 | return -ENOMEM; |
879 | } | 875 | } |
880 | if (ec_parse_device(device->handle, 0, ec, NULL) != | 876 | if (ec_parse_device(device->handle, 0, ec, NULL) != |
881 | AE_CTRL_TERMINATE) { | 877 | AE_CTRL_TERMINATE) { |
882 | kfree(ec); | 878 | kfree(ec); |
883 | return -EINVAL; | 879 | return -EINVAL; |
884 | } | 880 | } |
885 | 881 | ||
886 | /* Find and register all query methods */ | 882 | /* Find and register all query methods */ |
887 | acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1, | 883 | acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1, |
888 | acpi_ec_register_query_methods, NULL, ec, NULL); | 884 | acpi_ec_register_query_methods, NULL, ec, NULL); |
889 | 885 | ||
890 | if (!first_ec) | 886 | if (!first_ec) |
891 | first_ec = ec; | 887 | first_ec = ec; |
892 | device->driver_data = ec; | 888 | device->driver_data = ec; |
893 | 889 | ||
894 | ret = !!request_region(ec->data_addr, 1, "EC data"); | 890 | ret = !!request_region(ec->data_addr, 1, "EC data"); |
895 | WARN(!ret, "Could not request EC data io port 0x%lx", ec->data_addr); | 891 | WARN(!ret, "Could not request EC data io port 0x%lx", ec->data_addr); |
896 | ret = !!request_region(ec->command_addr, 1, "EC cmd"); | 892 | ret = !!request_region(ec->command_addr, 1, "EC cmd"); |
897 | WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr); | 893 | WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr); |
898 | 894 | ||
899 | pr_info("GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", | 895 | pr_info("GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", |
900 | ec->gpe, ec->command_addr, ec->data_addr); | 896 | ec->gpe, ec->command_addr, ec->data_addr); |
901 | 897 | ||
902 | ret = ec_install_handlers(ec); | 898 | ret = ec_install_handlers(ec); |
903 | 899 | ||
904 | /* EC is fully operational, allow queries */ | 900 | /* EC is fully operational, allow queries */ |
905 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 901 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
906 | 902 | ||
907 | /* Clear stale _Q events if hardware might require that */ | 903 | /* Clear stale _Q events if hardware might require that */ |
908 | if (EC_FLAGS_CLEAR_ON_RESUME) { | 904 | if (EC_FLAGS_CLEAR_ON_RESUME) { |
909 | mutex_lock(&ec->mutex); | 905 | mutex_lock(&ec->mutex); |
910 | acpi_ec_clear(ec); | 906 | acpi_ec_clear(ec); |
911 | mutex_unlock(&ec->mutex); | 907 | mutex_unlock(&ec->mutex); |
912 | } | 908 | } |
913 | return ret; | 909 | return ret; |
914 | } | 910 | } |
915 | 911 | ||
916 | static int acpi_ec_remove(struct acpi_device *device) | 912 | static int acpi_ec_remove(struct acpi_device *device) |
917 | { | 913 | { |
918 | struct acpi_ec *ec; | 914 | struct acpi_ec *ec; |
919 | struct acpi_ec_query_handler *handler, *tmp; | 915 | struct acpi_ec_query_handler *handler, *tmp; |
920 | 916 | ||
921 | if (!device) | 917 | if (!device) |
922 | return -EINVAL; | 918 | return -EINVAL; |
923 | 919 | ||
924 | ec = acpi_driver_data(device); | 920 | ec = acpi_driver_data(device); |
925 | ec_remove_handlers(ec); | 921 | ec_remove_handlers(ec); |
926 | mutex_lock(&ec->mutex); | 922 | mutex_lock(&ec->mutex); |
927 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { | 923 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { |
928 | list_del(&handler->node); | 924 | list_del(&handler->node); |
929 | kfree(handler); | 925 | kfree(handler); |
930 | } | 926 | } |
931 | mutex_unlock(&ec->mutex); | 927 | mutex_unlock(&ec->mutex); |
932 | release_region(ec->data_addr, 1); | 928 | release_region(ec->data_addr, 1); |
933 | release_region(ec->command_addr, 1); | 929 | release_region(ec->command_addr, 1); |
934 | device->driver_data = NULL; | 930 | device->driver_data = NULL; |
935 | if (ec == first_ec) | 931 | if (ec == first_ec) |
936 | first_ec = NULL; | 932 | first_ec = NULL; |
937 | kfree(ec); | 933 | kfree(ec); |
938 | return 0; | 934 | return 0; |
939 | } | 935 | } |
940 | 936 | ||
941 | static acpi_status | 937 | static acpi_status |
942 | ec_parse_io_ports(struct acpi_resource *resource, void *context) | 938 | ec_parse_io_ports(struct acpi_resource *resource, void *context) |
943 | { | 939 | { |
944 | struct acpi_ec *ec = context; | 940 | struct acpi_ec *ec = context; |
945 | 941 | ||
946 | if (resource->type != ACPI_RESOURCE_TYPE_IO) | 942 | if (resource->type != ACPI_RESOURCE_TYPE_IO) |
947 | return AE_OK; | 943 | return AE_OK; |
948 | 944 | ||
949 | /* | 945 | /* |
950 | * The first address region returned is the data port, and | 946 | * The first address region returned is the data port, and |
951 | * the second address region returned is the status/command | 947 | * the second address region returned is the status/command |
952 | * port. | 948 | * port. |
953 | */ | 949 | */ |
954 | if (ec->data_addr == 0) | 950 | if (ec->data_addr == 0) |
955 | ec->data_addr = resource->data.io.minimum; | 951 | ec->data_addr = resource->data.io.minimum; |
956 | else if (ec->command_addr == 0) | 952 | else if (ec->command_addr == 0) |
957 | ec->command_addr = resource->data.io.minimum; | 953 | ec->command_addr = resource->data.io.minimum; |
958 | else | 954 | else |
959 | return AE_CTRL_TERMINATE; | 955 | return AE_CTRL_TERMINATE; |
960 | 956 | ||
961 | return AE_OK; | 957 | return AE_OK; |
962 | } | 958 | } |
963 | 959 | ||
964 | int __init acpi_boot_ec_enable(void) | 960 | int __init acpi_boot_ec_enable(void) |
965 | { | 961 | { |
966 | if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags)) | 962 | if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags)) |
967 | return 0; | 963 | return 0; |
968 | if (!ec_install_handlers(boot_ec)) { | 964 | if (!ec_install_handlers(boot_ec)) { |
969 | first_ec = boot_ec; | 965 | first_ec = boot_ec; |
970 | return 0; | 966 | return 0; |
971 | } | 967 | } |
972 | return -EFAULT; | 968 | return -EFAULT; |
973 | } | 969 | } |
974 | 970 | ||
975 | static const struct acpi_device_id ec_device_ids[] = { | 971 | static const struct acpi_device_id ec_device_ids[] = { |
976 | {"PNP0C09", 0}, | 972 | {"PNP0C09", 0}, |
977 | {"", 0}, | 973 | {"", 0}, |
978 | }; | 974 | }; |
979 | 975 | ||
980 | /* Some BIOS do not survive early DSDT scan, skip it */ | 976 | /* Some BIOS do not survive early DSDT scan, skip it */ |
981 | static int ec_skip_dsdt_scan(const struct dmi_system_id *id) | 977 | static int ec_skip_dsdt_scan(const struct dmi_system_id *id) |
982 | { | 978 | { |
983 | EC_FLAGS_SKIP_DSDT_SCAN = 1; | 979 | EC_FLAGS_SKIP_DSDT_SCAN = 1; |
984 | return 0; | 980 | return 0; |
985 | } | 981 | } |
986 | 982 | ||
987 | /* ASUStek often supplies us with broken ECDT, validate it */ | 983 | /* ASUStek often supplies us with broken ECDT, validate it */ |
988 | static int ec_validate_ecdt(const struct dmi_system_id *id) | 984 | static int ec_validate_ecdt(const struct dmi_system_id *id) |
989 | { | 985 | { |
990 | EC_FLAGS_VALIDATE_ECDT = 1; | 986 | EC_FLAGS_VALIDATE_ECDT = 1; |
991 | return 0; | 987 | return 0; |
992 | } | 988 | } |
993 | 989 | ||
994 | /* MSI EC needs special treatment, enable it */ | 990 | /* MSI EC needs special treatment, enable it */ |
995 | static int ec_flag_msi(const struct dmi_system_id *id) | 991 | static int ec_flag_msi(const struct dmi_system_id *id) |
996 | { | 992 | { |
997 | pr_debug("Detected MSI hardware, enabling workarounds.\n"); | 993 | pr_debug("Detected MSI hardware, enabling workarounds.\n"); |
998 | EC_FLAGS_MSI = 1; | 994 | EC_FLAGS_MSI = 1; |
999 | EC_FLAGS_VALIDATE_ECDT = 1; | 995 | EC_FLAGS_VALIDATE_ECDT = 1; |
1000 | return 0; | 996 | return 0; |
1001 | } | 997 | } |
1002 | 998 | ||
1003 | /* | 999 | /* |
1004 | * Clevo M720 notebook actually works ok with IRQ mode, if we lifted | 1000 | * Clevo M720 notebook actually works ok with IRQ mode, if we lifted |
1005 | * the GPE storm threshold back to 20 | 1001 | * the GPE storm threshold back to 20 |
1006 | */ | 1002 | */ |
1007 | static int ec_enlarge_storm_threshold(const struct dmi_system_id *id) | 1003 | static int ec_enlarge_storm_threshold(const struct dmi_system_id *id) |
1008 | { | 1004 | { |
1009 | pr_debug("Setting the EC GPE storm threshold to 20\n"); | 1005 | pr_debug("Setting the EC GPE storm threshold to 20\n"); |
1010 | ec_storm_threshold = 20; | 1006 | ec_storm_threshold = 20; |
1011 | return 0; | 1007 | return 0; |
1012 | } | 1008 | } |
1013 | 1009 | ||
1014 | /* | 1010 | /* |
1011 | * Acer EC firmware refuses to respond QR_EC when SCI_EVT is not set, for | ||
1012 | * which case, we complete the QR_EC without issuing it to the firmware. | ||
1013 | * https://bugzilla.kernel.org/show_bug.cgi?id=86211 | ||
1014 | */ | ||
1015 | static int ec_flag_query_handshake(const struct dmi_system_id *id) | ||
1016 | { | ||
1017 | pr_debug("Detected the EC firmware requiring QR_EC issued when SCI_EVT set\n"); | ||
1018 | EC_FLAGS_QUERY_HANDSHAKE = 1; | ||
1019 | return 0; | ||
1020 | } | ||
1021 | |||
1022 | /* | ||
1015 | * On some hardware it is necessary to clear events accumulated by the EC during | 1023 | * On some hardware it is necessary to clear events accumulated by the EC during |
1016 | * sleep. These ECs stop reporting GPEs until they are manually polled, if too | 1024 | * sleep. These ECs stop reporting GPEs until they are manually polled, if too |
1017 | * many events are accumulated. (e.g. Samsung Series 5/9 notebooks) | 1025 | * many events are accumulated. (e.g. Samsung Series 5/9 notebooks) |
1018 | * | 1026 | * |
1019 | * https://bugzilla.kernel.org/show_bug.cgi?id=44161 | 1027 | * https://bugzilla.kernel.org/show_bug.cgi?id=44161 |
1020 | * | 1028 | * |
1021 | * Ideally, the EC should also be instructed NOT to accumulate events during | 1029 | * Ideally, the EC should also be instructed NOT to accumulate events during |
1022 | * sleep (which Windows seems to do somehow), but the interface to control this | 1030 | * sleep (which Windows seems to do somehow), but the interface to control this |
1023 | * behaviour is not known at this time. | 1031 | * behaviour is not known at this time. |
1024 | * | 1032 | * |
1025 | * Models known to be affected are Samsung 530Uxx/535Uxx/540Uxx/550Pxx/900Xxx, | 1033 | * Models known to be affected are Samsung 530Uxx/535Uxx/540Uxx/550Pxx/900Xxx, |
1026 | * however it is very likely that other Samsung models are affected. | 1034 | * however it is very likely that other Samsung models are affected. |
1027 | * | 1035 | * |
1028 | * On systems which don't accumulate _Q events during sleep, this extra check | 1036 | * On systems which don't accumulate _Q events during sleep, this extra check |
1029 | * should be harmless. | 1037 | * should be harmless. |
1030 | */ | 1038 | */ |
1031 | static int ec_clear_on_resume(const struct dmi_system_id *id) | 1039 | static int ec_clear_on_resume(const struct dmi_system_id *id) |
1032 | { | 1040 | { |
1033 | pr_debug("Detected system needing EC poll on resume.\n"); | 1041 | pr_debug("Detected system needing EC poll on resume.\n"); |
1034 | EC_FLAGS_CLEAR_ON_RESUME = 1; | 1042 | EC_FLAGS_CLEAR_ON_RESUME = 1; |
1035 | return 0; | 1043 | return 0; |
1036 | } | 1044 | } |
1037 | 1045 | ||
1038 | static struct dmi_system_id ec_dmi_table[] __initdata = { | 1046 | static struct dmi_system_id ec_dmi_table[] __initdata = { |
1039 | { | 1047 | { |
1040 | ec_skip_dsdt_scan, "Compal JFL92", { | 1048 | ec_skip_dsdt_scan, "Compal JFL92", { |
1041 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), | 1049 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), |
1042 | DMI_MATCH(DMI_BOARD_NAME, "JFL92") }, NULL}, | 1050 | DMI_MATCH(DMI_BOARD_NAME, "JFL92") }, NULL}, |
1043 | { | 1051 | { |
1044 | ec_flag_msi, "MSI hardware", { | 1052 | ec_flag_msi, "MSI hardware", { |
1045 | DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star")}, NULL}, | 1053 | DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star")}, NULL}, |
1046 | { | 1054 | { |
1047 | ec_flag_msi, "MSI hardware", { | 1055 | ec_flag_msi, "MSI hardware", { |
1048 | DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star")}, NULL}, | 1056 | DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star")}, NULL}, |
1049 | { | 1057 | { |
1050 | ec_flag_msi, "MSI hardware", { | 1058 | ec_flag_msi, "MSI hardware", { |
1051 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL}, | 1059 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL}, |
1052 | { | 1060 | { |
1053 | ec_flag_msi, "MSI hardware", { | 1061 | ec_flag_msi, "MSI hardware", { |
1054 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL}, | 1062 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL}, |
1055 | { | 1063 | { |
1056 | ec_flag_msi, "Quanta hardware", { | 1064 | ec_flag_msi, "Quanta hardware", { |
1057 | DMI_MATCH(DMI_SYS_VENDOR, "Quanta"), | 1065 | DMI_MATCH(DMI_SYS_VENDOR, "Quanta"), |
1058 | DMI_MATCH(DMI_PRODUCT_NAME, "TW8/SW8/DW8"),}, NULL}, | 1066 | DMI_MATCH(DMI_PRODUCT_NAME, "TW8/SW8/DW8"),}, NULL}, |
1059 | { | 1067 | { |
1060 | ec_flag_msi, "Quanta hardware", { | 1068 | ec_flag_msi, "Quanta hardware", { |
1061 | DMI_MATCH(DMI_SYS_VENDOR, "Quanta"), | 1069 | DMI_MATCH(DMI_SYS_VENDOR, "Quanta"), |
1062 | DMI_MATCH(DMI_PRODUCT_NAME, "TW9/SW9"),}, NULL}, | 1070 | DMI_MATCH(DMI_PRODUCT_NAME, "TW9/SW9"),}, NULL}, |
1063 | { | 1071 | { |
1064 | ec_flag_msi, "Clevo W350etq", { | 1072 | ec_flag_msi, "Clevo W350etq", { |
1065 | DMI_MATCH(DMI_SYS_VENDOR, "CLEVO CO."), | 1073 | DMI_MATCH(DMI_SYS_VENDOR, "CLEVO CO."), |
1066 | DMI_MATCH(DMI_PRODUCT_NAME, "W35_37ET"),}, NULL}, | 1074 | DMI_MATCH(DMI_PRODUCT_NAME, "W35_37ET"),}, NULL}, |
1067 | { | 1075 | { |
1068 | ec_validate_ecdt, "ASUS hardware", { | 1076 | ec_validate_ecdt, "ASUS hardware", { |
1069 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, | 1077 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, |
1070 | { | 1078 | { |
1071 | ec_validate_ecdt, "ASUS hardware", { | 1079 | ec_validate_ecdt, "ASUS hardware", { |
1072 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc.") }, NULL}, | 1080 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc.") }, NULL}, |
1073 | { | 1081 | { |
1074 | ec_enlarge_storm_threshold, "CLEVO hardware", { | 1082 | ec_enlarge_storm_threshold, "CLEVO hardware", { |
1075 | DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."), | 1083 | DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."), |
1076 | DMI_MATCH(DMI_PRODUCT_NAME, "M720T/M730T"),}, NULL}, | 1084 | DMI_MATCH(DMI_PRODUCT_NAME, "M720T/M730T"),}, NULL}, |
1077 | { | 1085 | { |
1078 | ec_skip_dsdt_scan, "HP Folio 13", { | 1086 | ec_skip_dsdt_scan, "HP Folio 13", { |
1079 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1087 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1080 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13"),}, NULL}, | 1088 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13"),}, NULL}, |
1081 | { | 1089 | { |
1082 | ec_validate_ecdt, "ASUS hardware", { | 1090 | ec_validate_ecdt, "ASUS hardware", { |
1083 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek Computer Inc."), | 1091 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek Computer Inc."), |
1084 | DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),}, NULL}, | 1092 | DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),}, NULL}, |
1085 | { | 1093 | { |
1086 | ec_clear_on_resume, "Samsung hardware", { | 1094 | ec_clear_on_resume, "Samsung hardware", { |
1087 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL}, | 1095 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL}, |
1096 | { | ||
1097 | ec_flag_query_handshake, "Acer hardware", { | ||
1098 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), }, NULL}, | ||
1088 | {}, | 1099 | {}, |
1089 | }; | 1100 | }; |
1090 | 1101 | ||
1091 | int __init acpi_ec_ecdt_probe(void) | 1102 | int __init acpi_ec_ecdt_probe(void) |
1092 | { | 1103 | { |
1093 | acpi_status status; | 1104 | acpi_status status; |
1094 | struct acpi_ec *saved_ec = NULL; | 1105 | struct acpi_ec *saved_ec = NULL; |
1095 | struct acpi_table_ecdt *ecdt_ptr; | 1106 | struct acpi_table_ecdt *ecdt_ptr; |
1096 | 1107 | ||
1097 | boot_ec = make_acpi_ec(); | 1108 | boot_ec = make_acpi_ec(); |
1098 | if (!boot_ec) | 1109 | if (!boot_ec) |
1099 | return -ENOMEM; | 1110 | return -ENOMEM; |
1100 | /* | 1111 | /* |
1101 | * Generate a boot ec context | 1112 | * Generate a boot ec context |
1102 | */ | 1113 | */ |
1103 | dmi_check_system(ec_dmi_table); | 1114 | dmi_check_system(ec_dmi_table); |
1104 | status = acpi_get_table(ACPI_SIG_ECDT, 1, | 1115 | status = acpi_get_table(ACPI_SIG_ECDT, 1, |
1105 | (struct acpi_table_header **)&ecdt_ptr); | 1116 | (struct acpi_table_header **)&ecdt_ptr); |
1106 | if (ACPI_SUCCESS(status)) { | 1117 | if (ACPI_SUCCESS(status)) { |
1107 | pr_info("EC description table is found, configuring boot EC\n"); | 1118 | pr_info("EC description table is found, configuring boot EC\n"); |
1108 | boot_ec->command_addr = ecdt_ptr->control.address; | 1119 | boot_ec->command_addr = ecdt_ptr->control.address; |
1109 | boot_ec->data_addr = ecdt_ptr->data.address; | 1120 | boot_ec->data_addr = ecdt_ptr->data.address; |
1110 | boot_ec->gpe = ecdt_ptr->gpe; | 1121 | boot_ec->gpe = ecdt_ptr->gpe; |
1111 | boot_ec->handle = ACPI_ROOT_OBJECT; | 1122 | boot_ec->handle = ACPI_ROOT_OBJECT; |
1112 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, | 1123 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, |
1113 | &boot_ec->handle); | 1124 | &boot_ec->handle); |
1114 | /* Don't trust ECDT, which comes from ASUSTek */ | 1125 | /* Don't trust ECDT, which comes from ASUSTek */ |
1115 | if (!EC_FLAGS_VALIDATE_ECDT) | 1126 | if (!EC_FLAGS_VALIDATE_ECDT) |
1116 | goto install; | 1127 | goto install; |
1117 | saved_ec = kmemdup(boot_ec, sizeof(struct acpi_ec), GFP_KERNEL); | 1128 | saved_ec = kmemdup(boot_ec, sizeof(struct acpi_ec), GFP_KERNEL); |
1118 | if (!saved_ec) | 1129 | if (!saved_ec) |
1119 | return -ENOMEM; | 1130 | return -ENOMEM; |
1120 | /* fall through */ | 1131 | /* fall through */ |
1121 | } | 1132 | } |
1122 | 1133 | ||
1123 | if (EC_FLAGS_SKIP_DSDT_SCAN) { | 1134 | if (EC_FLAGS_SKIP_DSDT_SCAN) { |
1124 | kfree(saved_ec); | 1135 | kfree(saved_ec); |
1125 | return -ENODEV; | 1136 | return -ENODEV; |
1126 | } | 1137 | } |
1127 | 1138 | ||
1128 | /* This workaround is needed only on some broken machines, | 1139 | /* This workaround is needed only on some broken machines, |
1129 | * which require early EC, but fail to provide ECDT */ | 1140 | * which require early EC, but fail to provide ECDT */ |
1130 | pr_debug("Look up EC in DSDT\n"); | 1141 | pr_debug("Look up EC in DSDT\n"); |
1131 | status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, | 1142 | status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, |
1132 | boot_ec, NULL); | 1143 | boot_ec, NULL); |
1133 | /* Check that acpi_get_devices actually find something */ | 1144 | /* Check that acpi_get_devices actually find something */ |
1134 | if (ACPI_FAILURE(status) || !boot_ec->handle) | 1145 | if (ACPI_FAILURE(status) || !boot_ec->handle) |
1135 | goto error; | 1146 | goto error; |
1136 | if (saved_ec) { | 1147 | if (saved_ec) { |
1137 | /* try to find good ECDT from ASUSTek */ | 1148 | /* try to find good ECDT from ASUSTek */ |
1138 | if (saved_ec->command_addr != boot_ec->command_addr || | 1149 | if (saved_ec->command_addr != boot_ec->command_addr || |
1139 | saved_ec->data_addr != boot_ec->data_addr || | 1150 | saved_ec->data_addr != boot_ec->data_addr || |
1140 | saved_ec->gpe != boot_ec->gpe || | 1151 | saved_ec->gpe != boot_ec->gpe || |
1141 | saved_ec->handle != boot_ec->handle) | 1152 | saved_ec->handle != boot_ec->handle) |
1142 | pr_info("ASUSTek keeps feeding us with broken " | 1153 | pr_info("ASUSTek keeps feeding us with broken " |
1143 | "ECDT tables, which are very hard to workaround. " | 1154 | "ECDT tables, which are very hard to workaround. " |
1144 | "Trying to use DSDT EC info instead. Please send " | 1155 | "Trying to use DSDT EC info instead. Please send " |
1145 | "output of acpidump to linux-acpi@vger.kernel.org\n"); | 1156 | "output of acpidump to linux-acpi@vger.kernel.org\n"); |
1146 | kfree(saved_ec); | 1157 | kfree(saved_ec); |
1147 | saved_ec = NULL; | 1158 | saved_ec = NULL; |
1148 | } else { | 1159 | } else { |
1149 | /* We really need to limit this workaround, the only ASUS, | 1160 | /* We really need to limit this workaround, the only ASUS, |
1150 | * which needs it, has fake EC._INI method, so use it as flag. | 1161 | * which needs it, has fake EC._INI method, so use it as flag. |
1151 | * Keep boot_ec struct as it will be needed soon. | 1162 | * Keep boot_ec struct as it will be needed soon. |
1152 | */ | 1163 | */ |
1153 | if (!dmi_name_in_vendors("ASUS") || | 1164 | if (!dmi_name_in_vendors("ASUS") || |
1154 | !acpi_has_method(boot_ec->handle, "_INI")) | 1165 | !acpi_has_method(boot_ec->handle, "_INI")) |
1155 | return -ENODEV; | 1166 | return -ENODEV; |
1156 | } | 1167 | } |
1157 | install: | 1168 | install: |
1158 | if (!ec_install_handlers(boot_ec)) { | 1169 | if (!ec_install_handlers(boot_ec)) { |
1159 | first_ec = boot_ec; | 1170 | first_ec = boot_ec; |
1160 | return 0; | 1171 | return 0; |
1161 | } | 1172 | } |
1162 | error: | 1173 | error: |
1163 | kfree(boot_ec); | 1174 | kfree(boot_ec); |
1164 | kfree(saved_ec); | 1175 | kfree(saved_ec); |
1165 | boot_ec = NULL; | 1176 | boot_ec = NULL; |
1166 | return -ENODEV; | 1177 | return -ENODEV; |
1167 | } | 1178 | } |
1168 | 1179 | ||
1169 | static struct acpi_driver acpi_ec_driver = { | 1180 | static struct acpi_driver acpi_ec_driver = { |
1170 | .name = "ec", | 1181 | .name = "ec", |
1171 | .class = ACPI_EC_CLASS, | 1182 | .class = ACPI_EC_CLASS, |
1172 | .ids = ec_device_ids, | 1183 | .ids = ec_device_ids, |
1173 | .ops = { | 1184 | .ops = { |
1174 | .add = acpi_ec_add, | 1185 | .add = acpi_ec_add, |
1175 | .remove = acpi_ec_remove, | 1186 | .remove = acpi_ec_remove, |
1176 | }, | 1187 | }, |
1177 | }; | 1188 | }; |
1178 | 1189 | ||
1179 | int __init acpi_ec_init(void) | 1190 | int __init acpi_ec_init(void) |
1180 | { | 1191 | { |
1181 | int result = 0; | 1192 | int result = 0; |
1182 | 1193 | ||
1183 | /* Now register the driver for the EC */ | 1194 | /* Now register the driver for the EC */ |
1184 | result = acpi_bus_register_driver(&acpi_ec_driver); | 1195 | result = acpi_bus_register_driver(&acpi_ec_driver); |
1185 | if (result < 0) | 1196 | if (result < 0) |
1186 | return -ENODEV; | 1197 | return -ENODEV; |
1187 | 1198 | ||
1188 | return result; | 1199 | return result; |
1189 | } | 1200 | } |
1190 | 1201 | ||
1191 | /* EC driver currently not unloadable */ | 1202 | /* EC driver currently not unloadable */ |
drivers/acpi/scan.c
1 | /* | 1 | /* |
2 | * scan.c - support for transforming the ACPI namespace into individual objects | 2 | * scan.c - support for transforming the ACPI namespace into individual objects |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <linux/module.h> | 5 | #include <linux/module.h> |
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/slab.h> | 7 | #include <linux/slab.h> |
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
9 | #include <linux/acpi.h> | 9 | #include <linux/acpi.h> |
10 | #include <linux/signal.h> | 10 | #include <linux/signal.h> |
11 | #include <linux/kthread.h> | 11 | #include <linux/kthread.h> |
12 | #include <linux/dmi.h> | 12 | #include <linux/dmi.h> |
13 | #include <linux/nls.h> | 13 | #include <linux/nls.h> |
14 | 14 | ||
15 | #include <asm/pgtable.h> | 15 | #include <asm/pgtable.h> |
16 | 16 | ||
17 | #include "internal.h" | 17 | #include "internal.h" |
18 | 18 | ||
19 | #define _COMPONENT ACPI_BUS_COMPONENT | 19 | #define _COMPONENT ACPI_BUS_COMPONENT |
20 | ACPI_MODULE_NAME("scan"); | 20 | ACPI_MODULE_NAME("scan"); |
21 | extern struct acpi_device *acpi_root; | 21 | extern struct acpi_device *acpi_root; |
22 | 22 | ||
23 | #define ACPI_BUS_CLASS "system_bus" | 23 | #define ACPI_BUS_CLASS "system_bus" |
24 | #define ACPI_BUS_HID "LNXSYBUS" | 24 | #define ACPI_BUS_HID "LNXSYBUS" |
25 | #define ACPI_BUS_DEVICE_NAME "System Bus" | 25 | #define ACPI_BUS_DEVICE_NAME "System Bus" |
26 | 26 | ||
27 | #define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent) | 27 | #define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent) |
28 | 28 | ||
29 | #define INVALID_ACPI_HANDLE ((acpi_handle)empty_zero_page) | 29 | #define INVALID_ACPI_HANDLE ((acpi_handle)empty_zero_page) |
30 | 30 | ||
31 | /* | 31 | /* |
32 | * If set, devices will be hot-removed even if they cannot be put offline | 32 | * If set, devices will be hot-removed even if they cannot be put offline |
33 | * gracefully (from the kernel's standpoint). | 33 | * gracefully (from the kernel's standpoint). |
34 | */ | 34 | */ |
35 | bool acpi_force_hot_remove; | 35 | bool acpi_force_hot_remove; |
36 | 36 | ||
37 | static const char *dummy_hid = "device"; | 37 | static const char *dummy_hid = "device"; |
38 | 38 | ||
39 | static LIST_HEAD(acpi_bus_id_list); | 39 | static LIST_HEAD(acpi_bus_id_list); |
40 | static DEFINE_MUTEX(acpi_scan_lock); | 40 | static DEFINE_MUTEX(acpi_scan_lock); |
41 | static LIST_HEAD(acpi_scan_handlers_list); | 41 | static LIST_HEAD(acpi_scan_handlers_list); |
42 | DEFINE_MUTEX(acpi_device_lock); | 42 | DEFINE_MUTEX(acpi_device_lock); |
43 | LIST_HEAD(acpi_wakeup_device_list); | 43 | LIST_HEAD(acpi_wakeup_device_list); |
44 | static DEFINE_MUTEX(acpi_hp_context_lock); | 44 | static DEFINE_MUTEX(acpi_hp_context_lock); |
45 | 45 | ||
46 | struct acpi_device_bus_id{ | 46 | struct acpi_device_bus_id{ |
47 | char bus_id[15]; | 47 | char bus_id[15]; |
48 | unsigned int instance_no; | 48 | unsigned int instance_no; |
49 | struct list_head node; | 49 | struct list_head node; |
50 | }; | 50 | }; |
51 | 51 | ||
52 | void acpi_scan_lock_acquire(void) | 52 | void acpi_scan_lock_acquire(void) |
53 | { | 53 | { |
54 | mutex_lock(&acpi_scan_lock); | 54 | mutex_lock(&acpi_scan_lock); |
55 | } | 55 | } |
56 | EXPORT_SYMBOL_GPL(acpi_scan_lock_acquire); | 56 | EXPORT_SYMBOL_GPL(acpi_scan_lock_acquire); |
57 | 57 | ||
58 | void acpi_scan_lock_release(void) | 58 | void acpi_scan_lock_release(void) |
59 | { | 59 | { |
60 | mutex_unlock(&acpi_scan_lock); | 60 | mutex_unlock(&acpi_scan_lock); |
61 | } | 61 | } |
62 | EXPORT_SYMBOL_GPL(acpi_scan_lock_release); | 62 | EXPORT_SYMBOL_GPL(acpi_scan_lock_release); |
63 | 63 | ||
64 | void acpi_lock_hp_context(void) | 64 | void acpi_lock_hp_context(void) |
65 | { | 65 | { |
66 | mutex_lock(&acpi_hp_context_lock); | 66 | mutex_lock(&acpi_hp_context_lock); |
67 | } | 67 | } |
68 | 68 | ||
69 | void acpi_unlock_hp_context(void) | 69 | void acpi_unlock_hp_context(void) |
70 | { | 70 | { |
71 | mutex_unlock(&acpi_hp_context_lock); | 71 | mutex_unlock(&acpi_hp_context_lock); |
72 | } | 72 | } |
73 | 73 | ||
74 | void acpi_initialize_hp_context(struct acpi_device *adev, | 74 | void acpi_initialize_hp_context(struct acpi_device *adev, |
75 | struct acpi_hotplug_context *hp, | 75 | struct acpi_hotplug_context *hp, |
76 | int (*notify)(struct acpi_device *, u32), | 76 | int (*notify)(struct acpi_device *, u32), |
77 | void (*uevent)(struct acpi_device *, u32)) | 77 | void (*uevent)(struct acpi_device *, u32)) |
78 | { | 78 | { |
79 | acpi_lock_hp_context(); | 79 | acpi_lock_hp_context(); |
80 | hp->notify = notify; | 80 | hp->notify = notify; |
81 | hp->uevent = uevent; | 81 | hp->uevent = uevent; |
82 | acpi_set_hp_context(adev, hp); | 82 | acpi_set_hp_context(adev, hp); |
83 | acpi_unlock_hp_context(); | 83 | acpi_unlock_hp_context(); |
84 | } | 84 | } |
85 | EXPORT_SYMBOL_GPL(acpi_initialize_hp_context); | 85 | EXPORT_SYMBOL_GPL(acpi_initialize_hp_context); |
86 | 86 | ||
87 | int acpi_scan_add_handler(struct acpi_scan_handler *handler) | 87 | int acpi_scan_add_handler(struct acpi_scan_handler *handler) |
88 | { | 88 | { |
89 | if (!handler) | 89 | if (!handler) |
90 | return -EINVAL; | 90 | return -EINVAL; |
91 | 91 | ||
92 | list_add_tail(&handler->list_node, &acpi_scan_handlers_list); | 92 | list_add_tail(&handler->list_node, &acpi_scan_handlers_list); |
93 | return 0; | 93 | return 0; |
94 | } | 94 | } |
95 | 95 | ||
96 | int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler, | 96 | int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler, |
97 | const char *hotplug_profile_name) | 97 | const char *hotplug_profile_name) |
98 | { | 98 | { |
99 | int error; | 99 | int error; |
100 | 100 | ||
101 | error = acpi_scan_add_handler(handler); | 101 | error = acpi_scan_add_handler(handler); |
102 | if (error) | 102 | if (error) |
103 | return error; | 103 | return error; |
104 | 104 | ||
105 | acpi_sysfs_add_hotplug_profile(&handler->hotplug, hotplug_profile_name); | 105 | acpi_sysfs_add_hotplug_profile(&handler->hotplug, hotplug_profile_name); |
106 | return 0; | 106 | return 0; |
107 | } | 107 | } |
108 | 108 | ||
109 | /* | 109 | /* |
110 | * Creates hid/cid(s) string needed for modalias and uevent | 110 | * Creates hid/cid(s) string needed for modalias and uevent |
111 | * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: | 111 | * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: |
112 | * char *modalias: "acpi:IBM0001:ACPI0001" | 112 | * char *modalias: "acpi:IBM0001:ACPI0001" |
113 | * Return: 0: no _HID and no _CID | 113 | * Return: 0: no _HID and no _CID |
114 | * -EINVAL: output error | 114 | * -EINVAL: output error |
115 | * -ENOMEM: output is truncated | 115 | * -ENOMEM: output is truncated |
116 | */ | 116 | */ |
117 | static int create_modalias(struct acpi_device *acpi_dev, char *modalias, | 117 | static int create_modalias(struct acpi_device *acpi_dev, char *modalias, |
118 | int size) | 118 | int size) |
119 | { | 119 | { |
120 | int len; | 120 | int len; |
121 | int count; | 121 | int count; |
122 | struct acpi_hardware_id *id; | 122 | struct acpi_hardware_id *id; |
123 | 123 | ||
124 | if (list_empty(&acpi_dev->pnp.ids)) | 124 | if (list_empty(&acpi_dev->pnp.ids)) |
125 | return 0; | 125 | return 0; |
126 | 126 | ||
127 | len = snprintf(modalias, size, "acpi:"); | 127 | len = snprintf(modalias, size, "acpi:"); |
128 | size -= len; | 128 | size -= len; |
129 | 129 | ||
130 | list_for_each_entry(id, &acpi_dev->pnp.ids, list) { | 130 | list_for_each_entry(id, &acpi_dev->pnp.ids, list) { |
131 | count = snprintf(&modalias[len], size, "%s:", id->id); | 131 | count = snprintf(&modalias[len], size, "%s:", id->id); |
132 | if (count < 0) | 132 | if (count < 0) |
133 | return -EINVAL; | 133 | return -EINVAL; |
134 | if (count >= size) | 134 | if (count >= size) |
135 | return -ENOMEM; | 135 | return -ENOMEM; |
136 | len += count; | 136 | len += count; |
137 | size -= count; | 137 | size -= count; |
138 | } | 138 | } |
139 | 139 | ||
140 | modalias[len] = '\0'; | 140 | modalias[len] = '\0'; |
141 | return len; | 141 | return len; |
142 | } | 142 | } |
143 | 143 | ||
144 | /* | 144 | /* |
145 | * acpi_companion_match() - Can we match via ACPI companion device | ||
146 | * @dev: Device in question | ||
147 | * | ||
148 | * Check if the given device has an ACPI companion and if that companion has | ||
149 | * a valid list of PNP IDs, and if the device is the first (primary) physical | ||
150 | * device associated with it. | ||
151 | * | ||
152 | * If multiple physical devices are attached to a single ACPI companion, we need | ||
153 | * to be careful. The usage scenario for this kind of relationship is that all | ||
154 | * of the physical devices in question use resources provided by the ACPI | ||
155 | * companion. A typical case is an MFD device where all the sub-devices share | ||
156 | * the parent's ACPI companion. In such cases we can only allow the primary | ||
157 | * (first) physical device to be matched with the help of the companion's PNP | ||
158 | * IDs. | ||
159 | * | ||
160 | * Additional physical devices sharing the ACPI companion can still use | ||
161 | * resources available from it but they will be matched normally using functions | ||
162 | * provided by their bus types (and analogously for their modalias). | ||
163 | */ | ||
164 | static bool acpi_companion_match(const struct device *dev) | ||
165 | { | ||
166 | struct acpi_device *adev; | ||
167 | bool ret; | ||
168 | |||
169 | adev = ACPI_COMPANION(dev); | ||
170 | if (!adev) | ||
171 | return false; | ||
172 | |||
173 | if (list_empty(&adev->pnp.ids)) | ||
174 | return false; | ||
175 | |||
176 | mutex_lock(&adev->physical_node_lock); | ||
177 | if (list_empty(&adev->physical_node_list)) { | ||
178 | ret = false; | ||
179 | } else { | ||
180 | const struct acpi_device_physical_node *node; | ||
181 | |||
182 | node = list_first_entry(&adev->physical_node_list, | ||
183 | struct acpi_device_physical_node, node); | ||
184 | ret = node->dev == dev; | ||
185 | } | ||
186 | mutex_unlock(&adev->physical_node_lock); | ||
187 | |||
188 | return ret; | ||
189 | } | ||
190 | |||
191 | /* | ||
145 | * Creates uevent modalias field for ACPI enumerated devices. | 192 | * Creates uevent modalias field for ACPI enumerated devices. |
146 | * Because the other buses does not support ACPI HIDs & CIDs. | 193 | * Because the other buses does not support ACPI HIDs & CIDs. |
147 | * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get: | 194 | * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get: |
148 | * "acpi:IBM0001:ACPI0001" | 195 | * "acpi:IBM0001:ACPI0001" |
149 | */ | 196 | */ |
150 | int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) | 197 | int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) |
151 | { | 198 | { |
152 | struct acpi_device *acpi_dev; | ||
153 | int len; | 199 | int len; |
154 | 200 | ||
155 | acpi_dev = ACPI_COMPANION(dev); | 201 | if (!acpi_companion_match(dev)) |
156 | if (!acpi_dev) | ||
157 | return -ENODEV; | 202 | return -ENODEV; |
158 | 203 | ||
159 | /* Fall back to bus specific way of modalias exporting */ | ||
160 | if (list_empty(&acpi_dev->pnp.ids)) | ||
161 | return -ENODEV; | ||
162 | |||
163 | if (add_uevent_var(env, "MODALIAS=")) | 204 | if (add_uevent_var(env, "MODALIAS=")) |
164 | return -ENOMEM; | 205 | return -ENOMEM; |
165 | len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], | 206 | len = create_modalias(ACPI_COMPANION(dev), &env->buf[env->buflen - 1], |
166 | sizeof(env->buf) - env->buflen); | 207 | sizeof(env->buf) - env->buflen); |
167 | if (len <= 0) | 208 | if (len <= 0) |
168 | return len; | 209 | return len; |
169 | env->buflen += len; | 210 | env->buflen += len; |
170 | return 0; | 211 | return 0; |
171 | } | 212 | } |
172 | EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias); | 213 | EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias); |
173 | 214 | ||
174 | /* | 215 | /* |
175 | * Creates modalias sysfs attribute for ACPI enumerated devices. | 216 | * Creates modalias sysfs attribute for ACPI enumerated devices. |
176 | * Because the other buses does not support ACPI HIDs & CIDs. | 217 | * Because the other buses does not support ACPI HIDs & CIDs. |
177 | * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get: | 218 | * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get: |
178 | * "acpi:IBM0001:ACPI0001" | 219 | * "acpi:IBM0001:ACPI0001" |
179 | */ | 220 | */ |
180 | int acpi_device_modalias(struct device *dev, char *buf, int size) | 221 | int acpi_device_modalias(struct device *dev, char *buf, int size) |
181 | { | 222 | { |
182 | struct acpi_device *acpi_dev; | ||
183 | int len; | 223 | int len; |
184 | 224 | ||
185 | acpi_dev = ACPI_COMPANION(dev); | 225 | if (!acpi_companion_match(dev)) |
186 | if (!acpi_dev) | ||
187 | return -ENODEV; | 226 | return -ENODEV; |
188 | 227 | ||
189 | /* Fall back to bus specific way of modalias exporting */ | 228 | len = create_modalias(ACPI_COMPANION(dev), buf, size -1); |
190 | if (list_empty(&acpi_dev->pnp.ids)) | ||
191 | return -ENODEV; | ||
192 | |||
193 | len = create_modalias(acpi_dev, buf, size -1); | ||
194 | if (len <= 0) | 229 | if (len <= 0) |
195 | return len; | 230 | return len; |
196 | buf[len++] = '\n'; | 231 | buf[len++] = '\n'; |
197 | return len; | 232 | return len; |
198 | } | 233 | } |
199 | EXPORT_SYMBOL_GPL(acpi_device_modalias); | 234 | EXPORT_SYMBOL_GPL(acpi_device_modalias); |
200 | 235 | ||
201 | static ssize_t | 236 | static ssize_t |
202 | acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { | 237 | acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { |
203 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 238 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
204 | int len; | 239 | int len; |
205 | 240 | ||
206 | len = create_modalias(acpi_dev, buf, 1024); | 241 | len = create_modalias(acpi_dev, buf, 1024); |
207 | if (len <= 0) | 242 | if (len <= 0) |
208 | return len; | 243 | return len; |
209 | buf[len++] = '\n'; | 244 | buf[len++] = '\n'; |
210 | return len; | 245 | return len; |
211 | } | 246 | } |
212 | static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); | 247 | static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); |
213 | 248 | ||
214 | bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent) | 249 | bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent) |
215 | { | 250 | { |
216 | struct acpi_device_physical_node *pn; | 251 | struct acpi_device_physical_node *pn; |
217 | bool offline = true; | 252 | bool offline = true; |
218 | 253 | ||
219 | mutex_lock(&adev->physical_node_lock); | 254 | mutex_lock(&adev->physical_node_lock); |
220 | 255 | ||
221 | list_for_each_entry(pn, &adev->physical_node_list, node) | 256 | list_for_each_entry(pn, &adev->physical_node_list, node) |
222 | if (device_supports_offline(pn->dev) && !pn->dev->offline) { | 257 | if (device_supports_offline(pn->dev) && !pn->dev->offline) { |
223 | if (uevent) | 258 | if (uevent) |
224 | kobject_uevent(&pn->dev->kobj, KOBJ_CHANGE); | 259 | kobject_uevent(&pn->dev->kobj, KOBJ_CHANGE); |
225 | 260 | ||
226 | offline = false; | 261 | offline = false; |
227 | break; | 262 | break; |
228 | } | 263 | } |
229 | 264 | ||
230 | mutex_unlock(&adev->physical_node_lock); | 265 | mutex_unlock(&adev->physical_node_lock); |
231 | return offline; | 266 | return offline; |
232 | } | 267 | } |
233 | 268 | ||
234 | static acpi_status acpi_bus_offline(acpi_handle handle, u32 lvl, void *data, | 269 | static acpi_status acpi_bus_offline(acpi_handle handle, u32 lvl, void *data, |
235 | void **ret_p) | 270 | void **ret_p) |
236 | { | 271 | { |
237 | struct acpi_device *device = NULL; | 272 | struct acpi_device *device = NULL; |
238 | struct acpi_device_physical_node *pn; | 273 | struct acpi_device_physical_node *pn; |
239 | bool second_pass = (bool)data; | 274 | bool second_pass = (bool)data; |
240 | acpi_status status = AE_OK; | 275 | acpi_status status = AE_OK; |
241 | 276 | ||
242 | if (acpi_bus_get_device(handle, &device)) | 277 | if (acpi_bus_get_device(handle, &device)) |
243 | return AE_OK; | 278 | return AE_OK; |
244 | 279 | ||
245 | if (device->handler && !device->handler->hotplug.enabled) { | 280 | if (device->handler && !device->handler->hotplug.enabled) { |
246 | *ret_p = &device->dev; | 281 | *ret_p = &device->dev; |
247 | return AE_SUPPORT; | 282 | return AE_SUPPORT; |
248 | } | 283 | } |
249 | 284 | ||
250 | mutex_lock(&device->physical_node_lock); | 285 | mutex_lock(&device->physical_node_lock); |
251 | 286 | ||
252 | list_for_each_entry(pn, &device->physical_node_list, node) { | 287 | list_for_each_entry(pn, &device->physical_node_list, node) { |
253 | int ret; | 288 | int ret; |
254 | 289 | ||
255 | if (second_pass) { | 290 | if (second_pass) { |
256 | /* Skip devices offlined by the first pass. */ | 291 | /* Skip devices offlined by the first pass. */ |
257 | if (pn->put_online) | 292 | if (pn->put_online) |
258 | continue; | 293 | continue; |
259 | } else { | 294 | } else { |
260 | pn->put_online = false; | 295 | pn->put_online = false; |
261 | } | 296 | } |
262 | ret = device_offline(pn->dev); | 297 | ret = device_offline(pn->dev); |
263 | if (acpi_force_hot_remove) | 298 | if (acpi_force_hot_remove) |
264 | continue; | 299 | continue; |
265 | 300 | ||
266 | if (ret >= 0) { | 301 | if (ret >= 0) { |
267 | pn->put_online = !ret; | 302 | pn->put_online = !ret; |
268 | } else { | 303 | } else { |
269 | *ret_p = pn->dev; | 304 | *ret_p = pn->dev; |
270 | if (second_pass) { | 305 | if (second_pass) { |
271 | status = AE_ERROR; | 306 | status = AE_ERROR; |
272 | break; | 307 | break; |
273 | } | 308 | } |
274 | } | 309 | } |
275 | } | 310 | } |
276 | 311 | ||
277 | mutex_unlock(&device->physical_node_lock); | 312 | mutex_unlock(&device->physical_node_lock); |
278 | 313 | ||
279 | return status; | 314 | return status; |
280 | } | 315 | } |
281 | 316 | ||
282 | static acpi_status acpi_bus_online(acpi_handle handle, u32 lvl, void *data, | 317 | static acpi_status acpi_bus_online(acpi_handle handle, u32 lvl, void *data, |
283 | void **ret_p) | 318 | void **ret_p) |
284 | { | 319 | { |
285 | struct acpi_device *device = NULL; | 320 | struct acpi_device *device = NULL; |
286 | struct acpi_device_physical_node *pn; | 321 | struct acpi_device_physical_node *pn; |
287 | 322 | ||
288 | if (acpi_bus_get_device(handle, &device)) | 323 | if (acpi_bus_get_device(handle, &device)) |
289 | return AE_OK; | 324 | return AE_OK; |
290 | 325 | ||
291 | mutex_lock(&device->physical_node_lock); | 326 | mutex_lock(&device->physical_node_lock); |
292 | 327 | ||
293 | list_for_each_entry(pn, &device->physical_node_list, node) | 328 | list_for_each_entry(pn, &device->physical_node_list, node) |
294 | if (pn->put_online) { | 329 | if (pn->put_online) { |
295 | device_online(pn->dev); | 330 | device_online(pn->dev); |
296 | pn->put_online = false; | 331 | pn->put_online = false; |
297 | } | 332 | } |
298 | 333 | ||
299 | mutex_unlock(&device->physical_node_lock); | 334 | mutex_unlock(&device->physical_node_lock); |
300 | 335 | ||
301 | return AE_OK; | 336 | return AE_OK; |
302 | } | 337 | } |
303 | 338 | ||
304 | static int acpi_scan_try_to_offline(struct acpi_device *device) | 339 | static int acpi_scan_try_to_offline(struct acpi_device *device) |
305 | { | 340 | { |
306 | acpi_handle handle = device->handle; | 341 | acpi_handle handle = device->handle; |
307 | struct device *errdev = NULL; | 342 | struct device *errdev = NULL; |
308 | acpi_status status; | 343 | acpi_status status; |
309 | 344 | ||
310 | /* | 345 | /* |
311 | * Carry out two passes here and ignore errors in the first pass, | 346 | * Carry out two passes here and ignore errors in the first pass, |
312 | * because if the devices in question are memory blocks and | 347 | * because if the devices in question are memory blocks and |
313 | * CONFIG_MEMCG is set, one of the blocks may hold data structures | 348 | * CONFIG_MEMCG is set, one of the blocks may hold data structures |
314 | * that the other blocks depend on, but it is not known in advance which | 349 | * that the other blocks depend on, but it is not known in advance which |
315 | * block holds them. | 350 | * block holds them. |
316 | * | 351 | * |
317 | * If the first pass is successful, the second one isn't needed, though. | 352 | * If the first pass is successful, the second one isn't needed, though. |
318 | */ | 353 | */ |
319 | status = acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | 354 | status = acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, |
320 | NULL, acpi_bus_offline, (void *)false, | 355 | NULL, acpi_bus_offline, (void *)false, |
321 | (void **)&errdev); | 356 | (void **)&errdev); |
322 | if (status == AE_SUPPORT) { | 357 | if (status == AE_SUPPORT) { |
323 | dev_warn(errdev, "Offline disabled.\n"); | 358 | dev_warn(errdev, "Offline disabled.\n"); |
324 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | 359 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, |
325 | acpi_bus_online, NULL, NULL, NULL); | 360 | acpi_bus_online, NULL, NULL, NULL); |
326 | return -EPERM; | 361 | return -EPERM; |
327 | } | 362 | } |
328 | acpi_bus_offline(handle, 0, (void *)false, (void **)&errdev); | 363 | acpi_bus_offline(handle, 0, (void *)false, (void **)&errdev); |
329 | if (errdev) { | 364 | if (errdev) { |
330 | errdev = NULL; | 365 | errdev = NULL; |
331 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | 366 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, |
332 | NULL, acpi_bus_offline, (void *)true, | 367 | NULL, acpi_bus_offline, (void *)true, |
333 | (void **)&errdev); | 368 | (void **)&errdev); |
334 | if (!errdev || acpi_force_hot_remove) | 369 | if (!errdev || acpi_force_hot_remove) |
335 | acpi_bus_offline(handle, 0, (void *)true, | 370 | acpi_bus_offline(handle, 0, (void *)true, |
336 | (void **)&errdev); | 371 | (void **)&errdev); |
337 | 372 | ||
338 | if (errdev && !acpi_force_hot_remove) { | 373 | if (errdev && !acpi_force_hot_remove) { |
339 | dev_warn(errdev, "Offline failed.\n"); | 374 | dev_warn(errdev, "Offline failed.\n"); |
340 | acpi_bus_online(handle, 0, NULL, NULL); | 375 | acpi_bus_online(handle, 0, NULL, NULL); |
341 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, | 376 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, |
342 | ACPI_UINT32_MAX, acpi_bus_online, | 377 | ACPI_UINT32_MAX, acpi_bus_online, |
343 | NULL, NULL, NULL); | 378 | NULL, NULL, NULL); |
344 | return -EBUSY; | 379 | return -EBUSY; |
345 | } | 380 | } |
346 | } | 381 | } |
347 | return 0; | 382 | return 0; |
348 | } | 383 | } |
349 | 384 | ||
350 | static int acpi_scan_hot_remove(struct acpi_device *device) | 385 | static int acpi_scan_hot_remove(struct acpi_device *device) |
351 | { | 386 | { |
352 | acpi_handle handle = device->handle; | 387 | acpi_handle handle = device->handle; |
353 | unsigned long long sta; | 388 | unsigned long long sta; |
354 | acpi_status status; | 389 | acpi_status status; |
355 | 390 | ||
356 | if (device->handler && device->handler->hotplug.demand_offline | 391 | if (device->handler && device->handler->hotplug.demand_offline |
357 | && !acpi_force_hot_remove) { | 392 | && !acpi_force_hot_remove) { |
358 | if (!acpi_scan_is_offline(device, true)) | 393 | if (!acpi_scan_is_offline(device, true)) |
359 | return -EBUSY; | 394 | return -EBUSY; |
360 | } else { | 395 | } else { |
361 | int error = acpi_scan_try_to_offline(device); | 396 | int error = acpi_scan_try_to_offline(device); |
362 | if (error) | 397 | if (error) |
363 | return error; | 398 | return error; |
364 | } | 399 | } |
365 | 400 | ||
366 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 401 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
367 | "Hot-removing device %s...\n", dev_name(&device->dev))); | 402 | "Hot-removing device %s...\n", dev_name(&device->dev))); |
368 | 403 | ||
369 | acpi_bus_trim(device); | 404 | acpi_bus_trim(device); |
370 | 405 | ||
371 | acpi_evaluate_lck(handle, 0); | 406 | acpi_evaluate_lck(handle, 0); |
372 | /* | 407 | /* |
373 | * TBD: _EJD support. | 408 | * TBD: _EJD support. |
374 | */ | 409 | */ |
375 | status = acpi_evaluate_ej0(handle); | 410 | status = acpi_evaluate_ej0(handle); |
376 | if (status == AE_NOT_FOUND) | 411 | if (status == AE_NOT_FOUND) |
377 | return -ENODEV; | 412 | return -ENODEV; |
378 | else if (ACPI_FAILURE(status)) | 413 | else if (ACPI_FAILURE(status)) |
379 | return -EIO; | 414 | return -EIO; |
380 | 415 | ||
381 | /* | 416 | /* |
382 | * Verify if eject was indeed successful. If not, log an error | 417 | * Verify if eject was indeed successful. If not, log an error |
383 | * message. No need to call _OST since _EJ0 call was made OK. | 418 | * message. No need to call _OST since _EJ0 call was made OK. |
384 | */ | 419 | */ |
385 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | 420 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); |
386 | if (ACPI_FAILURE(status)) { | 421 | if (ACPI_FAILURE(status)) { |
387 | acpi_handle_warn(handle, | 422 | acpi_handle_warn(handle, |
388 | "Status check after eject failed (0x%x)\n", status); | 423 | "Status check after eject failed (0x%x)\n", status); |
389 | } else if (sta & ACPI_STA_DEVICE_ENABLED) { | 424 | } else if (sta & ACPI_STA_DEVICE_ENABLED) { |
390 | acpi_handle_warn(handle, | 425 | acpi_handle_warn(handle, |
391 | "Eject incomplete - status 0x%llx\n", sta); | 426 | "Eject incomplete - status 0x%llx\n", sta); |
392 | } | 427 | } |
393 | 428 | ||
394 | return 0; | 429 | return 0; |
395 | } | 430 | } |
396 | 431 | ||
397 | static int acpi_scan_device_not_present(struct acpi_device *adev) | 432 | static int acpi_scan_device_not_present(struct acpi_device *adev) |
398 | { | 433 | { |
399 | if (!acpi_device_enumerated(adev)) { | 434 | if (!acpi_device_enumerated(adev)) { |
400 | dev_warn(&adev->dev, "Still not present\n"); | 435 | dev_warn(&adev->dev, "Still not present\n"); |
401 | return -EALREADY; | 436 | return -EALREADY; |
402 | } | 437 | } |
403 | acpi_bus_trim(adev); | 438 | acpi_bus_trim(adev); |
404 | return 0; | 439 | return 0; |
405 | } | 440 | } |
406 | 441 | ||
407 | static int acpi_scan_device_check(struct acpi_device *adev) | 442 | static int acpi_scan_device_check(struct acpi_device *adev) |
408 | { | 443 | { |
409 | int error; | 444 | int error; |
410 | 445 | ||
411 | acpi_bus_get_status(adev); | 446 | acpi_bus_get_status(adev); |
412 | if (adev->status.present || adev->status.functional) { | 447 | if (adev->status.present || adev->status.functional) { |
413 | /* | 448 | /* |
414 | * This function is only called for device objects for which | 449 | * This function is only called for device objects for which |
415 | * matching scan handlers exist. The only situation in which | 450 | * matching scan handlers exist. The only situation in which |
416 | * the scan handler is not attached to this device object yet | 451 | * the scan handler is not attached to this device object yet |
417 | * is when the device has just appeared (either it wasn't | 452 | * is when the device has just appeared (either it wasn't |
418 | * present at all before or it was removed and then added | 453 | * present at all before or it was removed and then added |
419 | * again). | 454 | * again). |
420 | */ | 455 | */ |
421 | if (adev->handler) { | 456 | if (adev->handler) { |
422 | dev_warn(&adev->dev, "Already enumerated\n"); | 457 | dev_warn(&adev->dev, "Already enumerated\n"); |
423 | return -EALREADY; | 458 | return -EALREADY; |
424 | } | 459 | } |
425 | error = acpi_bus_scan(adev->handle); | 460 | error = acpi_bus_scan(adev->handle); |
426 | if (error) { | 461 | if (error) { |
427 | dev_warn(&adev->dev, "Namespace scan failure\n"); | 462 | dev_warn(&adev->dev, "Namespace scan failure\n"); |
428 | return error; | 463 | return error; |
429 | } | 464 | } |
430 | if (!adev->handler) { | 465 | if (!adev->handler) { |
431 | dev_warn(&adev->dev, "Enumeration failure\n"); | 466 | dev_warn(&adev->dev, "Enumeration failure\n"); |
432 | error = -ENODEV; | 467 | error = -ENODEV; |
433 | } | 468 | } |
434 | } else { | 469 | } else { |
435 | error = acpi_scan_device_not_present(adev); | 470 | error = acpi_scan_device_not_present(adev); |
436 | } | 471 | } |
437 | return error; | 472 | return error; |
438 | } | 473 | } |
439 | 474 | ||
440 | static int acpi_scan_bus_check(struct acpi_device *adev) | 475 | static int acpi_scan_bus_check(struct acpi_device *adev) |
441 | { | 476 | { |
442 | struct acpi_scan_handler *handler = adev->handler; | 477 | struct acpi_scan_handler *handler = adev->handler; |
443 | struct acpi_device *child; | 478 | struct acpi_device *child; |
444 | int error; | 479 | int error; |
445 | 480 | ||
446 | acpi_bus_get_status(adev); | 481 | acpi_bus_get_status(adev); |
447 | if (!(adev->status.present || adev->status.functional)) { | 482 | if (!(adev->status.present || adev->status.functional)) { |
448 | acpi_scan_device_not_present(adev); | 483 | acpi_scan_device_not_present(adev); |
449 | return 0; | 484 | return 0; |
450 | } | 485 | } |
451 | if (handler && handler->hotplug.scan_dependent) | 486 | if (handler && handler->hotplug.scan_dependent) |
452 | return handler->hotplug.scan_dependent(adev); | 487 | return handler->hotplug.scan_dependent(adev); |
453 | 488 | ||
454 | error = acpi_bus_scan(adev->handle); | 489 | error = acpi_bus_scan(adev->handle); |
455 | if (error) { | 490 | if (error) { |
456 | dev_warn(&adev->dev, "Namespace scan failure\n"); | 491 | dev_warn(&adev->dev, "Namespace scan failure\n"); |
457 | return error; | 492 | return error; |
458 | } | 493 | } |
459 | list_for_each_entry(child, &adev->children, node) { | 494 | list_for_each_entry(child, &adev->children, node) { |
460 | error = acpi_scan_bus_check(child); | 495 | error = acpi_scan_bus_check(child); |
461 | if (error) | 496 | if (error) |
462 | return error; | 497 | return error; |
463 | } | 498 | } |
464 | return 0; | 499 | return 0; |
465 | } | 500 | } |
466 | 501 | ||
467 | static int acpi_generic_hotplug_event(struct acpi_device *adev, u32 type) | 502 | static int acpi_generic_hotplug_event(struct acpi_device *adev, u32 type) |
468 | { | 503 | { |
469 | switch (type) { | 504 | switch (type) { |
470 | case ACPI_NOTIFY_BUS_CHECK: | 505 | case ACPI_NOTIFY_BUS_CHECK: |
471 | return acpi_scan_bus_check(adev); | 506 | return acpi_scan_bus_check(adev); |
472 | case ACPI_NOTIFY_DEVICE_CHECK: | 507 | case ACPI_NOTIFY_DEVICE_CHECK: |
473 | return acpi_scan_device_check(adev); | 508 | return acpi_scan_device_check(adev); |
474 | case ACPI_NOTIFY_EJECT_REQUEST: | 509 | case ACPI_NOTIFY_EJECT_REQUEST: |
475 | case ACPI_OST_EC_OSPM_EJECT: | 510 | case ACPI_OST_EC_OSPM_EJECT: |
476 | if (adev->handler && !adev->handler->hotplug.enabled) { | 511 | if (adev->handler && !adev->handler->hotplug.enabled) { |
477 | dev_info(&adev->dev, "Eject disabled\n"); | 512 | dev_info(&adev->dev, "Eject disabled\n"); |
478 | return -EPERM; | 513 | return -EPERM; |
479 | } | 514 | } |
480 | acpi_evaluate_ost(adev->handle, ACPI_NOTIFY_EJECT_REQUEST, | 515 | acpi_evaluate_ost(adev->handle, ACPI_NOTIFY_EJECT_REQUEST, |
481 | ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); | 516 | ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); |
482 | return acpi_scan_hot_remove(adev); | 517 | return acpi_scan_hot_remove(adev); |
483 | } | 518 | } |
484 | return -EINVAL; | 519 | return -EINVAL; |
485 | } | 520 | } |
486 | 521 | ||
487 | void acpi_device_hotplug(struct acpi_device *adev, u32 src) | 522 | void acpi_device_hotplug(struct acpi_device *adev, u32 src) |
488 | { | 523 | { |
489 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; | 524 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; |
490 | int error = -ENODEV; | 525 | int error = -ENODEV; |
491 | 526 | ||
492 | lock_device_hotplug(); | 527 | lock_device_hotplug(); |
493 | mutex_lock(&acpi_scan_lock); | 528 | mutex_lock(&acpi_scan_lock); |
494 | 529 | ||
495 | /* | 530 | /* |
496 | * The device object's ACPI handle cannot become invalid as long as we | 531 | * The device object's ACPI handle cannot become invalid as long as we |
497 | * are holding acpi_scan_lock, but it might have become invalid before | 532 | * are holding acpi_scan_lock, but it might have become invalid before |
498 | * that lock was acquired. | 533 | * that lock was acquired. |
499 | */ | 534 | */ |
500 | if (adev->handle == INVALID_ACPI_HANDLE) | 535 | if (adev->handle == INVALID_ACPI_HANDLE) |
501 | goto err_out; | 536 | goto err_out; |
502 | 537 | ||
503 | if (adev->flags.is_dock_station) { | 538 | if (adev->flags.is_dock_station) { |
504 | error = dock_notify(adev, src); | 539 | error = dock_notify(adev, src); |
505 | } else if (adev->flags.hotplug_notify) { | 540 | } else if (adev->flags.hotplug_notify) { |
506 | error = acpi_generic_hotplug_event(adev, src); | 541 | error = acpi_generic_hotplug_event(adev, src); |
507 | if (error == -EPERM) { | 542 | if (error == -EPERM) { |
508 | ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; | 543 | ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; |
509 | goto err_out; | 544 | goto err_out; |
510 | } | 545 | } |
511 | } else { | 546 | } else { |
512 | int (*notify)(struct acpi_device *, u32); | 547 | int (*notify)(struct acpi_device *, u32); |
513 | 548 | ||
514 | acpi_lock_hp_context(); | 549 | acpi_lock_hp_context(); |
515 | notify = adev->hp ? adev->hp->notify : NULL; | 550 | notify = adev->hp ? adev->hp->notify : NULL; |
516 | acpi_unlock_hp_context(); | 551 | acpi_unlock_hp_context(); |
517 | /* | 552 | /* |
518 | * There may be additional notify handlers for device objects | 553 | * There may be additional notify handlers for device objects |
519 | * without the .event() callback, so ignore them here. | 554 | * without the .event() callback, so ignore them here. |
520 | */ | 555 | */ |
521 | if (notify) | 556 | if (notify) |
522 | error = notify(adev, src); | 557 | error = notify(adev, src); |
523 | else | 558 | else |
524 | goto out; | 559 | goto out; |
525 | } | 560 | } |
526 | if (!error) | 561 | if (!error) |
527 | ost_code = ACPI_OST_SC_SUCCESS; | 562 | ost_code = ACPI_OST_SC_SUCCESS; |
528 | 563 | ||
529 | err_out: | 564 | err_out: |
530 | acpi_evaluate_ost(adev->handle, src, ost_code, NULL); | 565 | acpi_evaluate_ost(adev->handle, src, ost_code, NULL); |
531 | 566 | ||
532 | out: | 567 | out: |
533 | acpi_bus_put_acpi_device(adev); | 568 | acpi_bus_put_acpi_device(adev); |
534 | mutex_unlock(&acpi_scan_lock); | 569 | mutex_unlock(&acpi_scan_lock); |
535 | unlock_device_hotplug(); | 570 | unlock_device_hotplug(); |
536 | } | 571 | } |
537 | 572 | ||
538 | static ssize_t real_power_state_show(struct device *dev, | 573 | static ssize_t real_power_state_show(struct device *dev, |
539 | struct device_attribute *attr, char *buf) | 574 | struct device_attribute *attr, char *buf) |
540 | { | 575 | { |
541 | struct acpi_device *adev = to_acpi_device(dev); | 576 | struct acpi_device *adev = to_acpi_device(dev); |
542 | int state; | 577 | int state; |
543 | int ret; | 578 | int ret; |
544 | 579 | ||
545 | ret = acpi_device_get_power(adev, &state); | 580 | ret = acpi_device_get_power(adev, &state); |
546 | if (ret) | 581 | if (ret) |
547 | return ret; | 582 | return ret; |
548 | 583 | ||
549 | return sprintf(buf, "%s\n", acpi_power_state_string(state)); | 584 | return sprintf(buf, "%s\n", acpi_power_state_string(state)); |
550 | } | 585 | } |
551 | 586 | ||
552 | static DEVICE_ATTR(real_power_state, 0444, real_power_state_show, NULL); | 587 | static DEVICE_ATTR(real_power_state, 0444, real_power_state_show, NULL); |
553 | 588 | ||
554 | static ssize_t power_state_show(struct device *dev, | 589 | static ssize_t power_state_show(struct device *dev, |
555 | struct device_attribute *attr, char *buf) | 590 | struct device_attribute *attr, char *buf) |
556 | { | 591 | { |
557 | struct acpi_device *adev = to_acpi_device(dev); | 592 | struct acpi_device *adev = to_acpi_device(dev); |
558 | 593 | ||
559 | return sprintf(buf, "%s\n", acpi_power_state_string(adev->power.state)); | 594 | return sprintf(buf, "%s\n", acpi_power_state_string(adev->power.state)); |
560 | } | 595 | } |
561 | 596 | ||
562 | static DEVICE_ATTR(power_state, 0444, power_state_show, NULL); | 597 | static DEVICE_ATTR(power_state, 0444, power_state_show, NULL); |
563 | 598 | ||
564 | static ssize_t | 599 | static ssize_t |
565 | acpi_eject_store(struct device *d, struct device_attribute *attr, | 600 | acpi_eject_store(struct device *d, struct device_attribute *attr, |
566 | const char *buf, size_t count) | 601 | const char *buf, size_t count) |
567 | { | 602 | { |
568 | struct acpi_device *acpi_device = to_acpi_device(d); | 603 | struct acpi_device *acpi_device = to_acpi_device(d); |
569 | acpi_object_type not_used; | 604 | acpi_object_type not_used; |
570 | acpi_status status; | 605 | acpi_status status; |
571 | 606 | ||
572 | if (!count || buf[0] != '1') | 607 | if (!count || buf[0] != '1') |
573 | return -EINVAL; | 608 | return -EINVAL; |
574 | 609 | ||
575 | if ((!acpi_device->handler || !acpi_device->handler->hotplug.enabled) | 610 | if ((!acpi_device->handler || !acpi_device->handler->hotplug.enabled) |
576 | && !acpi_device->driver) | 611 | && !acpi_device->driver) |
577 | return -ENODEV; | 612 | return -ENODEV; |
578 | 613 | ||
579 | status = acpi_get_type(acpi_device->handle, ¬_used); | 614 | status = acpi_get_type(acpi_device->handle, ¬_used); |
580 | if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable) | 615 | if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable) |
581 | return -ENODEV; | 616 | return -ENODEV; |
582 | 617 | ||
583 | get_device(&acpi_device->dev); | 618 | get_device(&acpi_device->dev); |
584 | status = acpi_hotplug_schedule(acpi_device, ACPI_OST_EC_OSPM_EJECT); | 619 | status = acpi_hotplug_schedule(acpi_device, ACPI_OST_EC_OSPM_EJECT); |
585 | if (ACPI_SUCCESS(status)) | 620 | if (ACPI_SUCCESS(status)) |
586 | return count; | 621 | return count; |
587 | 622 | ||
588 | put_device(&acpi_device->dev); | 623 | put_device(&acpi_device->dev); |
589 | acpi_evaluate_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, | 624 | acpi_evaluate_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, |
590 | ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL); | 625 | ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL); |
591 | return status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN; | 626 | return status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN; |
592 | } | 627 | } |
593 | 628 | ||
594 | static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); | 629 | static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); |
595 | 630 | ||
596 | static ssize_t | 631 | static ssize_t |
597 | acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) { | 632 | acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) { |
598 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 633 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
599 | 634 | ||
600 | return sprintf(buf, "%s\n", acpi_device_hid(acpi_dev)); | 635 | return sprintf(buf, "%s\n", acpi_device_hid(acpi_dev)); |
601 | } | 636 | } |
602 | static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL); | 637 | static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL); |
603 | 638 | ||
604 | static ssize_t acpi_device_uid_show(struct device *dev, | 639 | static ssize_t acpi_device_uid_show(struct device *dev, |
605 | struct device_attribute *attr, char *buf) | 640 | struct device_attribute *attr, char *buf) |
606 | { | 641 | { |
607 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 642 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
608 | 643 | ||
609 | return sprintf(buf, "%s\n", acpi_dev->pnp.unique_id); | 644 | return sprintf(buf, "%s\n", acpi_dev->pnp.unique_id); |
610 | } | 645 | } |
611 | static DEVICE_ATTR(uid, 0444, acpi_device_uid_show, NULL); | 646 | static DEVICE_ATTR(uid, 0444, acpi_device_uid_show, NULL); |
612 | 647 | ||
613 | static ssize_t acpi_device_adr_show(struct device *dev, | 648 | static ssize_t acpi_device_adr_show(struct device *dev, |
614 | struct device_attribute *attr, char *buf) | 649 | struct device_attribute *attr, char *buf) |
615 | { | 650 | { |
616 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 651 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
617 | 652 | ||
618 | return sprintf(buf, "0x%08x\n", | 653 | return sprintf(buf, "0x%08x\n", |
619 | (unsigned int)(acpi_dev->pnp.bus_address)); | 654 | (unsigned int)(acpi_dev->pnp.bus_address)); |
620 | } | 655 | } |
621 | static DEVICE_ATTR(adr, 0444, acpi_device_adr_show, NULL); | 656 | static DEVICE_ATTR(adr, 0444, acpi_device_adr_show, NULL); |
622 | 657 | ||
623 | static ssize_t | 658 | static ssize_t |
624 | acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) { | 659 | acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) { |
625 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 660 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
626 | struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL}; | 661 | struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL}; |
627 | int result; | 662 | int result; |
628 | 663 | ||
629 | result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path); | 664 | result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path); |
630 | if (result) | 665 | if (result) |
631 | goto end; | 666 | goto end; |
632 | 667 | ||
633 | result = sprintf(buf, "%s\n", (char*)path.pointer); | 668 | result = sprintf(buf, "%s\n", (char*)path.pointer); |
634 | kfree(path.pointer); | 669 | kfree(path.pointer); |
635 | end: | 670 | end: |
636 | return result; | 671 | return result; |
637 | } | 672 | } |
638 | static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); | 673 | static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); |
639 | 674 | ||
640 | /* sysfs file that shows description text from the ACPI _STR method */ | 675 | /* sysfs file that shows description text from the ACPI _STR method */ |
641 | static ssize_t description_show(struct device *dev, | 676 | static ssize_t description_show(struct device *dev, |
642 | struct device_attribute *attr, | 677 | struct device_attribute *attr, |
643 | char *buf) { | 678 | char *buf) { |
644 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 679 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
645 | int result; | 680 | int result; |
646 | 681 | ||
647 | if (acpi_dev->pnp.str_obj == NULL) | 682 | if (acpi_dev->pnp.str_obj == NULL) |
648 | return 0; | 683 | return 0; |
649 | 684 | ||
650 | /* | 685 | /* |
651 | * The _STR object contains a Unicode identifier for a device. | 686 | * The _STR object contains a Unicode identifier for a device. |
652 | * We need to convert to utf-8 so it can be displayed. | 687 | * We need to convert to utf-8 so it can be displayed. |
653 | */ | 688 | */ |
654 | result = utf16s_to_utf8s( | 689 | result = utf16s_to_utf8s( |
655 | (wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer, | 690 | (wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer, |
656 | acpi_dev->pnp.str_obj->buffer.length, | 691 | acpi_dev->pnp.str_obj->buffer.length, |
657 | UTF16_LITTLE_ENDIAN, buf, | 692 | UTF16_LITTLE_ENDIAN, buf, |
658 | PAGE_SIZE); | 693 | PAGE_SIZE); |
659 | 694 | ||
660 | buf[result++] = '\n'; | 695 | buf[result++] = '\n'; |
661 | 696 | ||
662 | return result; | 697 | return result; |
663 | } | 698 | } |
664 | static DEVICE_ATTR(description, 0444, description_show, NULL); | 699 | static DEVICE_ATTR(description, 0444, description_show, NULL); |
665 | 700 | ||
666 | static ssize_t | 701 | static ssize_t |
667 | acpi_device_sun_show(struct device *dev, struct device_attribute *attr, | 702 | acpi_device_sun_show(struct device *dev, struct device_attribute *attr, |
668 | char *buf) { | 703 | char *buf) { |
669 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 704 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
670 | acpi_status status; | 705 | acpi_status status; |
671 | unsigned long long sun; | 706 | unsigned long long sun; |
672 | 707 | ||
673 | status = acpi_evaluate_integer(acpi_dev->handle, "_SUN", NULL, &sun); | 708 | status = acpi_evaluate_integer(acpi_dev->handle, "_SUN", NULL, &sun); |
674 | if (ACPI_FAILURE(status)) | 709 | if (ACPI_FAILURE(status)) |
675 | return -ENODEV; | 710 | return -ENODEV; |
676 | 711 | ||
677 | return sprintf(buf, "%llu\n", sun); | 712 | return sprintf(buf, "%llu\n", sun); |
678 | } | 713 | } |
679 | static DEVICE_ATTR(sun, 0444, acpi_device_sun_show, NULL); | 714 | static DEVICE_ATTR(sun, 0444, acpi_device_sun_show, NULL); |
680 | 715 | ||
681 | static ssize_t status_show(struct device *dev, struct device_attribute *attr, | 716 | static ssize_t status_show(struct device *dev, struct device_attribute *attr, |
682 | char *buf) { | 717 | char *buf) { |
683 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 718 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
684 | acpi_status status; | 719 | acpi_status status; |
685 | unsigned long long sta; | 720 | unsigned long long sta; |
686 | 721 | ||
687 | status = acpi_evaluate_integer(acpi_dev->handle, "_STA", NULL, &sta); | 722 | status = acpi_evaluate_integer(acpi_dev->handle, "_STA", NULL, &sta); |
688 | if (ACPI_FAILURE(status)) | 723 | if (ACPI_FAILURE(status)) |
689 | return -ENODEV; | 724 | return -ENODEV; |
690 | 725 | ||
691 | return sprintf(buf, "%llu\n", sta); | 726 | return sprintf(buf, "%llu\n", sta); |
692 | } | 727 | } |
693 | static DEVICE_ATTR_RO(status); | 728 | static DEVICE_ATTR_RO(status); |
694 | 729 | ||
695 | static int acpi_device_setup_files(struct acpi_device *dev) | 730 | static int acpi_device_setup_files(struct acpi_device *dev) |
696 | { | 731 | { |
697 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | 732 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; |
698 | acpi_status status; | 733 | acpi_status status; |
699 | int result = 0; | 734 | int result = 0; |
700 | 735 | ||
701 | /* | 736 | /* |
702 | * Devices gotten from FADT don't have a "path" attribute | 737 | * Devices gotten from FADT don't have a "path" attribute |
703 | */ | 738 | */ |
704 | if (dev->handle) { | 739 | if (dev->handle) { |
705 | result = device_create_file(&dev->dev, &dev_attr_path); | 740 | result = device_create_file(&dev->dev, &dev_attr_path); |
706 | if (result) | 741 | if (result) |
707 | goto end; | 742 | goto end; |
708 | } | 743 | } |
709 | 744 | ||
710 | if (!list_empty(&dev->pnp.ids)) { | 745 | if (!list_empty(&dev->pnp.ids)) { |
711 | result = device_create_file(&dev->dev, &dev_attr_hid); | 746 | result = device_create_file(&dev->dev, &dev_attr_hid); |
712 | if (result) | 747 | if (result) |
713 | goto end; | 748 | goto end; |
714 | 749 | ||
715 | result = device_create_file(&dev->dev, &dev_attr_modalias); | 750 | result = device_create_file(&dev->dev, &dev_attr_modalias); |
716 | if (result) | 751 | if (result) |
717 | goto end; | 752 | goto end; |
718 | } | 753 | } |
719 | 754 | ||
720 | /* | 755 | /* |
721 | * If device has _STR, 'description' file is created | 756 | * If device has _STR, 'description' file is created |
722 | */ | 757 | */ |
723 | if (acpi_has_method(dev->handle, "_STR")) { | 758 | if (acpi_has_method(dev->handle, "_STR")) { |
724 | status = acpi_evaluate_object(dev->handle, "_STR", | 759 | status = acpi_evaluate_object(dev->handle, "_STR", |
725 | NULL, &buffer); | 760 | NULL, &buffer); |
726 | if (ACPI_FAILURE(status)) | 761 | if (ACPI_FAILURE(status)) |
727 | buffer.pointer = NULL; | 762 | buffer.pointer = NULL; |
728 | dev->pnp.str_obj = buffer.pointer; | 763 | dev->pnp.str_obj = buffer.pointer; |
729 | result = device_create_file(&dev->dev, &dev_attr_description); | 764 | result = device_create_file(&dev->dev, &dev_attr_description); |
730 | if (result) | 765 | if (result) |
731 | goto end; | 766 | goto end; |
732 | } | 767 | } |
733 | 768 | ||
734 | if (dev->pnp.type.bus_address) | 769 | if (dev->pnp.type.bus_address) |
735 | result = device_create_file(&dev->dev, &dev_attr_adr); | 770 | result = device_create_file(&dev->dev, &dev_attr_adr); |
736 | if (dev->pnp.unique_id) | 771 | if (dev->pnp.unique_id) |
737 | result = device_create_file(&dev->dev, &dev_attr_uid); | 772 | result = device_create_file(&dev->dev, &dev_attr_uid); |
738 | 773 | ||
739 | if (acpi_has_method(dev->handle, "_SUN")) { | 774 | if (acpi_has_method(dev->handle, "_SUN")) { |
740 | result = device_create_file(&dev->dev, &dev_attr_sun); | 775 | result = device_create_file(&dev->dev, &dev_attr_sun); |
741 | if (result) | 776 | if (result) |
742 | goto end; | 777 | goto end; |
743 | } | 778 | } |
744 | 779 | ||
745 | if (acpi_has_method(dev->handle, "_STA")) { | 780 | if (acpi_has_method(dev->handle, "_STA")) { |
746 | result = device_create_file(&dev->dev, &dev_attr_status); | 781 | result = device_create_file(&dev->dev, &dev_attr_status); |
747 | if (result) | 782 | if (result) |
748 | goto end; | 783 | goto end; |
749 | } | 784 | } |
750 | 785 | ||
751 | /* | 786 | /* |
752 | * If device has _EJ0, 'eject' file is created that is used to trigger | 787 | * If device has _EJ0, 'eject' file is created that is used to trigger |
753 | * hot-removal function from userland. | 788 | * hot-removal function from userland. |
754 | */ | 789 | */ |
755 | if (acpi_has_method(dev->handle, "_EJ0")) { | 790 | if (acpi_has_method(dev->handle, "_EJ0")) { |
756 | result = device_create_file(&dev->dev, &dev_attr_eject); | 791 | result = device_create_file(&dev->dev, &dev_attr_eject); |
757 | if (result) | 792 | if (result) |
758 | return result; | 793 | return result; |
759 | } | 794 | } |
760 | 795 | ||
761 | if (dev->flags.power_manageable) { | 796 | if (dev->flags.power_manageable) { |
762 | result = device_create_file(&dev->dev, &dev_attr_power_state); | 797 | result = device_create_file(&dev->dev, &dev_attr_power_state); |
763 | if (result) | 798 | if (result) |
764 | return result; | 799 | return result; |
765 | 800 | ||
766 | if (dev->power.flags.power_resources) | 801 | if (dev->power.flags.power_resources) |
767 | result = device_create_file(&dev->dev, | 802 | result = device_create_file(&dev->dev, |
768 | &dev_attr_real_power_state); | 803 | &dev_attr_real_power_state); |
769 | } | 804 | } |
770 | 805 | ||
771 | end: | 806 | end: |
772 | return result; | 807 | return result; |
773 | } | 808 | } |
774 | 809 | ||
775 | static void acpi_device_remove_files(struct acpi_device *dev) | 810 | static void acpi_device_remove_files(struct acpi_device *dev) |
776 | { | 811 | { |
777 | if (dev->flags.power_manageable) { | 812 | if (dev->flags.power_manageable) { |
778 | device_remove_file(&dev->dev, &dev_attr_power_state); | 813 | device_remove_file(&dev->dev, &dev_attr_power_state); |
779 | if (dev->power.flags.power_resources) | 814 | if (dev->power.flags.power_resources) |
780 | device_remove_file(&dev->dev, | 815 | device_remove_file(&dev->dev, |
781 | &dev_attr_real_power_state); | 816 | &dev_attr_real_power_state); |
782 | } | 817 | } |
783 | 818 | ||
784 | /* | 819 | /* |
785 | * If device has _STR, remove 'description' file | 820 | * If device has _STR, remove 'description' file |
786 | */ | 821 | */ |
787 | if (acpi_has_method(dev->handle, "_STR")) { | 822 | if (acpi_has_method(dev->handle, "_STR")) { |
788 | kfree(dev->pnp.str_obj); | 823 | kfree(dev->pnp.str_obj); |
789 | device_remove_file(&dev->dev, &dev_attr_description); | 824 | device_remove_file(&dev->dev, &dev_attr_description); |
790 | } | 825 | } |
791 | /* | 826 | /* |
792 | * If device has _EJ0, remove 'eject' file. | 827 | * If device has _EJ0, remove 'eject' file. |
793 | */ | 828 | */ |
794 | if (acpi_has_method(dev->handle, "_EJ0")) | 829 | if (acpi_has_method(dev->handle, "_EJ0")) |
795 | device_remove_file(&dev->dev, &dev_attr_eject); | 830 | device_remove_file(&dev->dev, &dev_attr_eject); |
796 | 831 | ||
797 | if (acpi_has_method(dev->handle, "_SUN")) | 832 | if (acpi_has_method(dev->handle, "_SUN")) |
798 | device_remove_file(&dev->dev, &dev_attr_sun); | 833 | device_remove_file(&dev->dev, &dev_attr_sun); |
799 | 834 | ||
800 | if (dev->pnp.unique_id) | 835 | if (dev->pnp.unique_id) |
801 | device_remove_file(&dev->dev, &dev_attr_uid); | 836 | device_remove_file(&dev->dev, &dev_attr_uid); |
802 | if (dev->pnp.type.bus_address) | 837 | if (dev->pnp.type.bus_address) |
803 | device_remove_file(&dev->dev, &dev_attr_adr); | 838 | device_remove_file(&dev->dev, &dev_attr_adr); |
804 | device_remove_file(&dev->dev, &dev_attr_modalias); | 839 | device_remove_file(&dev->dev, &dev_attr_modalias); |
805 | device_remove_file(&dev->dev, &dev_attr_hid); | 840 | device_remove_file(&dev->dev, &dev_attr_hid); |
806 | if (acpi_has_method(dev->handle, "_STA")) | 841 | if (acpi_has_method(dev->handle, "_STA")) |
807 | device_remove_file(&dev->dev, &dev_attr_status); | 842 | device_remove_file(&dev->dev, &dev_attr_status); |
808 | if (dev->handle) | 843 | if (dev->handle) |
809 | device_remove_file(&dev->dev, &dev_attr_path); | 844 | device_remove_file(&dev->dev, &dev_attr_path); |
810 | } | 845 | } |
811 | /* -------------------------------------------------------------------------- | 846 | /* -------------------------------------------------------------------------- |
812 | ACPI Bus operations | 847 | ACPI Bus operations |
813 | -------------------------------------------------------------------------- */ | 848 | -------------------------------------------------------------------------- */ |
814 | 849 | ||
815 | static const struct acpi_device_id *__acpi_match_device( | 850 | static const struct acpi_device_id *__acpi_match_device( |
816 | struct acpi_device *device, const struct acpi_device_id *ids) | 851 | struct acpi_device *device, const struct acpi_device_id *ids) |
817 | { | 852 | { |
818 | const struct acpi_device_id *id; | 853 | const struct acpi_device_id *id; |
819 | struct acpi_hardware_id *hwid; | 854 | struct acpi_hardware_id *hwid; |
820 | 855 | ||
821 | /* | 856 | /* |
822 | * If the device is not present, it is unnecessary to load device | 857 | * If the device is not present, it is unnecessary to load device |
823 | * driver for it. | 858 | * driver for it. |
824 | */ | 859 | */ |
825 | if (!device->status.present) | 860 | if (!device->status.present) |
826 | return NULL; | 861 | return NULL; |
827 | 862 | ||
828 | for (id = ids; id->id[0]; id++) | 863 | for (id = ids; id->id[0]; id++) |
829 | list_for_each_entry(hwid, &device->pnp.ids, list) | 864 | list_for_each_entry(hwid, &device->pnp.ids, list) |
830 | if (!strcmp((char *) id->id, hwid->id)) | 865 | if (!strcmp((char *) id->id, hwid->id)) |
831 | return id; | 866 | return id; |
832 | 867 | ||
833 | return NULL; | 868 | return NULL; |
834 | } | 869 | } |
835 | 870 | ||
836 | /** | 871 | /** |
837 | * acpi_match_device - Match a struct device against a given list of ACPI IDs | 872 | * acpi_match_device - Match a struct device against a given list of ACPI IDs |
838 | * @ids: Array of struct acpi_device_id object to match against. | 873 | * @ids: Array of struct acpi_device_id object to match against. |
839 | * @dev: The device structure to match. | 874 | * @dev: The device structure to match. |
840 | * | 875 | * |
841 | * Check if @dev has a valid ACPI handle and if there is a struct acpi_device | 876 | * Check if @dev has a valid ACPI handle and if there is a struct acpi_device |
842 | * object for that handle and use that object to match against a given list of | 877 | * object for that handle and use that object to match against a given list of |
843 | * device IDs. | 878 | * device IDs. |
844 | * | 879 | * |
845 | * Return a pointer to the first matching ID on success or %NULL on failure. | 880 | * Return a pointer to the first matching ID on success or %NULL on failure. |
846 | */ | 881 | */ |
847 | const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids, | 882 | const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids, |
848 | const struct device *dev) | 883 | const struct device *dev) |
849 | { | 884 | { |
850 | struct acpi_device *adev; | 885 | struct acpi_device *adev; |
851 | acpi_handle handle = ACPI_HANDLE(dev); | 886 | acpi_handle handle = ACPI_HANDLE(dev); |
852 | 887 | ||
853 | if (!ids || !handle || acpi_bus_get_device(handle, &adev)) | 888 | if (!ids || !handle || acpi_bus_get_device(handle, &adev)) |
889 | return NULL; | ||
890 | |||
891 | if (!acpi_companion_match(dev)) | ||
854 | return NULL; | 892 | return NULL; |
855 | 893 | ||
856 | return __acpi_match_device(adev, ids); | 894 | return __acpi_match_device(adev, ids); |
857 | } | 895 | } |
858 | EXPORT_SYMBOL_GPL(acpi_match_device); | 896 | EXPORT_SYMBOL_GPL(acpi_match_device); |
859 | 897 | ||
860 | int acpi_match_device_ids(struct acpi_device *device, | 898 | int acpi_match_device_ids(struct acpi_device *device, |
861 | const struct acpi_device_id *ids) | 899 | const struct acpi_device_id *ids) |
862 | { | 900 | { |
863 | return __acpi_match_device(device, ids) ? 0 : -ENOENT; | 901 | return __acpi_match_device(device, ids) ? 0 : -ENOENT; |
864 | } | 902 | } |
865 | EXPORT_SYMBOL(acpi_match_device_ids); | 903 | EXPORT_SYMBOL(acpi_match_device_ids); |
866 | 904 | ||
867 | static void acpi_free_power_resources_lists(struct acpi_device *device) | 905 | static void acpi_free_power_resources_lists(struct acpi_device *device) |
868 | { | 906 | { |
869 | int i; | 907 | int i; |
870 | 908 | ||
871 | if (device->wakeup.flags.valid) | 909 | if (device->wakeup.flags.valid) |
872 | acpi_power_resources_list_free(&device->wakeup.resources); | 910 | acpi_power_resources_list_free(&device->wakeup.resources); |
873 | 911 | ||
874 | if (!device->flags.power_manageable) | 912 | if (!device->flags.power_manageable) |
875 | return; | 913 | return; |
876 | 914 | ||
877 | for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) { | 915 | for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) { |
878 | struct acpi_device_power_state *ps = &device->power.states[i]; | 916 | struct acpi_device_power_state *ps = &device->power.states[i]; |
879 | acpi_power_resources_list_free(&ps->resources); | 917 | acpi_power_resources_list_free(&ps->resources); |
880 | } | 918 | } |
881 | } | 919 | } |
882 | 920 | ||
883 | static void acpi_device_release(struct device *dev) | 921 | static void acpi_device_release(struct device *dev) |
884 | { | 922 | { |
885 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 923 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
886 | 924 | ||
887 | acpi_free_pnp_ids(&acpi_dev->pnp); | 925 | acpi_free_pnp_ids(&acpi_dev->pnp); |
888 | acpi_free_power_resources_lists(acpi_dev); | 926 | acpi_free_power_resources_lists(acpi_dev); |
889 | kfree(acpi_dev); | 927 | kfree(acpi_dev); |
890 | } | 928 | } |
891 | 929 | ||
892 | static int acpi_bus_match(struct device *dev, struct device_driver *drv) | 930 | static int acpi_bus_match(struct device *dev, struct device_driver *drv) |
893 | { | 931 | { |
894 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 932 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
895 | struct acpi_driver *acpi_drv = to_acpi_driver(drv); | 933 | struct acpi_driver *acpi_drv = to_acpi_driver(drv); |
896 | 934 | ||
897 | return acpi_dev->flags.match_driver | 935 | return acpi_dev->flags.match_driver |
898 | && !acpi_match_device_ids(acpi_dev, acpi_drv->ids); | 936 | && !acpi_match_device_ids(acpi_dev, acpi_drv->ids); |
899 | } | 937 | } |
900 | 938 | ||
901 | static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env) | 939 | static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env) |
902 | { | 940 | { |
903 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 941 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
904 | int len; | 942 | int len; |
905 | 943 | ||
906 | if (list_empty(&acpi_dev->pnp.ids)) | 944 | if (list_empty(&acpi_dev->pnp.ids)) |
907 | return 0; | 945 | return 0; |
908 | 946 | ||
909 | if (add_uevent_var(env, "MODALIAS=")) | 947 | if (add_uevent_var(env, "MODALIAS=")) |
910 | return -ENOMEM; | 948 | return -ENOMEM; |
911 | len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], | 949 | len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], |
912 | sizeof(env->buf) - env->buflen); | 950 | sizeof(env->buf) - env->buflen); |
913 | if (len <= 0) | 951 | if (len <= 0) |
914 | return len; | 952 | return len; |
915 | env->buflen += len; | 953 | env->buflen += len; |
916 | return 0; | 954 | return 0; |
917 | } | 955 | } |
918 | 956 | ||
919 | static void acpi_device_notify(acpi_handle handle, u32 event, void *data) | 957 | static void acpi_device_notify(acpi_handle handle, u32 event, void *data) |
920 | { | 958 | { |
921 | struct acpi_device *device = data; | 959 | struct acpi_device *device = data; |
922 | 960 | ||
923 | device->driver->ops.notify(device, event); | 961 | device->driver->ops.notify(device, event); |
924 | } | 962 | } |
925 | 963 | ||
926 | static void acpi_device_notify_fixed(void *data) | 964 | static void acpi_device_notify_fixed(void *data) |
927 | { | 965 | { |
928 | struct acpi_device *device = data; | 966 | struct acpi_device *device = data; |
929 | 967 | ||
930 | /* Fixed hardware devices have no handles */ | 968 | /* Fixed hardware devices have no handles */ |
931 | acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device); | 969 | acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device); |
932 | } | 970 | } |
933 | 971 | ||
934 | static acpi_status acpi_device_fixed_event(void *data) | 972 | static acpi_status acpi_device_fixed_event(void *data) |
935 | { | 973 | { |
936 | acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_device_notify_fixed, data); | 974 | acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_device_notify_fixed, data); |
937 | return AE_OK; | 975 | return AE_OK; |
938 | } | 976 | } |
939 | 977 | ||
940 | static int acpi_device_install_notify_handler(struct acpi_device *device) | 978 | static int acpi_device_install_notify_handler(struct acpi_device *device) |
941 | { | 979 | { |
942 | acpi_status status; | 980 | acpi_status status; |
943 | 981 | ||
944 | if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) | 982 | if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) |
945 | status = | 983 | status = |
946 | acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, | 984 | acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, |
947 | acpi_device_fixed_event, | 985 | acpi_device_fixed_event, |
948 | device); | 986 | device); |
949 | else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) | 987 | else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) |
950 | status = | 988 | status = |
951 | acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, | 989 | acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, |
952 | acpi_device_fixed_event, | 990 | acpi_device_fixed_event, |
953 | device); | 991 | device); |
954 | else | 992 | else |
955 | status = acpi_install_notify_handler(device->handle, | 993 | status = acpi_install_notify_handler(device->handle, |
956 | ACPI_DEVICE_NOTIFY, | 994 | ACPI_DEVICE_NOTIFY, |
957 | acpi_device_notify, | 995 | acpi_device_notify, |
958 | device); | 996 | device); |
959 | 997 | ||
960 | if (ACPI_FAILURE(status)) | 998 | if (ACPI_FAILURE(status)) |
961 | return -EINVAL; | 999 | return -EINVAL; |
962 | return 0; | 1000 | return 0; |
963 | } | 1001 | } |
964 | 1002 | ||
965 | static void acpi_device_remove_notify_handler(struct acpi_device *device) | 1003 | static void acpi_device_remove_notify_handler(struct acpi_device *device) |
966 | { | 1004 | { |
967 | if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) | 1005 | if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) |
968 | acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, | 1006 | acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, |
969 | acpi_device_fixed_event); | 1007 | acpi_device_fixed_event); |
970 | else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) | 1008 | else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) |
971 | acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, | 1009 | acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, |
972 | acpi_device_fixed_event); | 1010 | acpi_device_fixed_event); |
973 | else | 1011 | else |
974 | acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, | 1012 | acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, |
975 | acpi_device_notify); | 1013 | acpi_device_notify); |
976 | } | 1014 | } |
977 | 1015 | ||
978 | static int acpi_device_probe(struct device *dev) | 1016 | static int acpi_device_probe(struct device *dev) |
979 | { | 1017 | { |
980 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 1018 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
981 | struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver); | 1019 | struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver); |
982 | int ret; | 1020 | int ret; |
983 | 1021 | ||
984 | if (acpi_dev->handler && !acpi_is_pnp_device(acpi_dev)) | 1022 | if (acpi_dev->handler && !acpi_is_pnp_device(acpi_dev)) |
985 | return -EINVAL; | 1023 | return -EINVAL; |
986 | 1024 | ||
987 | if (!acpi_drv->ops.add) | 1025 | if (!acpi_drv->ops.add) |
988 | return -ENOSYS; | 1026 | return -ENOSYS; |
989 | 1027 | ||
990 | ret = acpi_drv->ops.add(acpi_dev); | 1028 | ret = acpi_drv->ops.add(acpi_dev); |
991 | if (ret) | 1029 | if (ret) |
992 | return ret; | 1030 | return ret; |
993 | 1031 | ||
994 | acpi_dev->driver = acpi_drv; | 1032 | acpi_dev->driver = acpi_drv; |
995 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 1033 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
996 | "Driver [%s] successfully bound to device [%s]\n", | 1034 | "Driver [%s] successfully bound to device [%s]\n", |
997 | acpi_drv->name, acpi_dev->pnp.bus_id)); | 1035 | acpi_drv->name, acpi_dev->pnp.bus_id)); |
998 | 1036 | ||
999 | if (acpi_drv->ops.notify) { | 1037 | if (acpi_drv->ops.notify) { |
1000 | ret = acpi_device_install_notify_handler(acpi_dev); | 1038 | ret = acpi_device_install_notify_handler(acpi_dev); |
1001 | if (ret) { | 1039 | if (ret) { |
1002 | if (acpi_drv->ops.remove) | 1040 | if (acpi_drv->ops.remove) |
1003 | acpi_drv->ops.remove(acpi_dev); | 1041 | acpi_drv->ops.remove(acpi_dev); |
1004 | 1042 | ||
1005 | acpi_dev->driver = NULL; | 1043 | acpi_dev->driver = NULL; |
1006 | acpi_dev->driver_data = NULL; | 1044 | acpi_dev->driver_data = NULL; |
1007 | return ret; | 1045 | return ret; |
1008 | } | 1046 | } |
1009 | } | 1047 | } |
1010 | 1048 | ||
1011 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n", | 1049 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n", |
1012 | acpi_drv->name, acpi_dev->pnp.bus_id)); | 1050 | acpi_drv->name, acpi_dev->pnp.bus_id)); |
1013 | get_device(dev); | 1051 | get_device(dev); |
1014 | return 0; | 1052 | return 0; |
1015 | } | 1053 | } |
1016 | 1054 | ||
1017 | static int acpi_device_remove(struct device * dev) | 1055 | static int acpi_device_remove(struct device * dev) |
1018 | { | 1056 | { |
1019 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 1057 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
1020 | struct acpi_driver *acpi_drv = acpi_dev->driver; | 1058 | struct acpi_driver *acpi_drv = acpi_dev->driver; |
1021 | 1059 | ||
1022 | if (acpi_drv) { | 1060 | if (acpi_drv) { |
1023 | if (acpi_drv->ops.notify) | 1061 | if (acpi_drv->ops.notify) |
1024 | acpi_device_remove_notify_handler(acpi_dev); | 1062 | acpi_device_remove_notify_handler(acpi_dev); |
1025 | if (acpi_drv->ops.remove) | 1063 | if (acpi_drv->ops.remove) |
1026 | acpi_drv->ops.remove(acpi_dev); | 1064 | acpi_drv->ops.remove(acpi_dev); |
1027 | } | 1065 | } |
1028 | acpi_dev->driver = NULL; | 1066 | acpi_dev->driver = NULL; |
1029 | acpi_dev->driver_data = NULL; | 1067 | acpi_dev->driver_data = NULL; |
1030 | 1068 | ||
1031 | put_device(dev); | 1069 | put_device(dev); |
1032 | return 0; | 1070 | return 0; |
1033 | } | 1071 | } |
1034 | 1072 | ||
1035 | struct bus_type acpi_bus_type = { | 1073 | struct bus_type acpi_bus_type = { |
1036 | .name = "acpi", | 1074 | .name = "acpi", |
1037 | .match = acpi_bus_match, | 1075 | .match = acpi_bus_match, |
1038 | .probe = acpi_device_probe, | 1076 | .probe = acpi_device_probe, |
1039 | .remove = acpi_device_remove, | 1077 | .remove = acpi_device_remove, |
1040 | .uevent = acpi_device_uevent, | 1078 | .uevent = acpi_device_uevent, |
1041 | }; | 1079 | }; |
1042 | 1080 | ||
1043 | static void acpi_device_del(struct acpi_device *device) | 1081 | static void acpi_device_del(struct acpi_device *device) |
1044 | { | 1082 | { |
1045 | mutex_lock(&acpi_device_lock); | 1083 | mutex_lock(&acpi_device_lock); |
1046 | if (device->parent) | 1084 | if (device->parent) |
1047 | list_del(&device->node); | 1085 | list_del(&device->node); |
1048 | 1086 | ||
1049 | list_del(&device->wakeup_list); | 1087 | list_del(&device->wakeup_list); |
1050 | mutex_unlock(&acpi_device_lock); | 1088 | mutex_unlock(&acpi_device_lock); |
1051 | 1089 | ||
1052 | acpi_power_add_remove_device(device, false); | 1090 | acpi_power_add_remove_device(device, false); |
1053 | acpi_device_remove_files(device); | 1091 | acpi_device_remove_files(device); |
1054 | if (device->remove) | 1092 | if (device->remove) |
1055 | device->remove(device); | 1093 | device->remove(device); |
1056 | 1094 | ||
1057 | device_del(&device->dev); | 1095 | device_del(&device->dev); |
1058 | } | 1096 | } |
1059 | 1097 | ||
1060 | static LIST_HEAD(acpi_device_del_list); | 1098 | static LIST_HEAD(acpi_device_del_list); |
1061 | static DEFINE_MUTEX(acpi_device_del_lock); | 1099 | static DEFINE_MUTEX(acpi_device_del_lock); |
1062 | 1100 | ||
1063 | static void acpi_device_del_work_fn(struct work_struct *work_not_used) | 1101 | static void acpi_device_del_work_fn(struct work_struct *work_not_used) |
1064 | { | 1102 | { |
1065 | for (;;) { | 1103 | for (;;) { |
1066 | struct acpi_device *adev; | 1104 | struct acpi_device *adev; |
1067 | 1105 | ||
1068 | mutex_lock(&acpi_device_del_lock); | 1106 | mutex_lock(&acpi_device_del_lock); |
1069 | 1107 | ||
1070 | if (list_empty(&acpi_device_del_list)) { | 1108 | if (list_empty(&acpi_device_del_list)) { |
1071 | mutex_unlock(&acpi_device_del_lock); | 1109 | mutex_unlock(&acpi_device_del_lock); |
1072 | break; | 1110 | break; |
1073 | } | 1111 | } |
1074 | adev = list_first_entry(&acpi_device_del_list, | 1112 | adev = list_first_entry(&acpi_device_del_list, |
1075 | struct acpi_device, del_list); | 1113 | struct acpi_device, del_list); |
1076 | list_del(&adev->del_list); | 1114 | list_del(&adev->del_list); |
1077 | 1115 | ||
1078 | mutex_unlock(&acpi_device_del_lock); | 1116 | mutex_unlock(&acpi_device_del_lock); |
1079 | 1117 | ||
1080 | acpi_device_del(adev); | 1118 | acpi_device_del(adev); |
1081 | /* | 1119 | /* |
1082 | * Drop references to all power resources that might have been | 1120 | * Drop references to all power resources that might have been |
1083 | * used by the device. | 1121 | * used by the device. |
1084 | */ | 1122 | */ |
1085 | acpi_power_transition(adev, ACPI_STATE_D3_COLD); | 1123 | acpi_power_transition(adev, ACPI_STATE_D3_COLD); |
1086 | put_device(&adev->dev); | 1124 | put_device(&adev->dev); |
1087 | } | 1125 | } |
1088 | } | 1126 | } |
1089 | 1127 | ||
1090 | /** | 1128 | /** |
1091 | * acpi_scan_drop_device - Drop an ACPI device object. | 1129 | * acpi_scan_drop_device - Drop an ACPI device object. |
1092 | * @handle: Handle of an ACPI namespace node, not used. | 1130 | * @handle: Handle of an ACPI namespace node, not used. |
1093 | * @context: Address of the ACPI device object to drop. | 1131 | * @context: Address of the ACPI device object to drop. |
1094 | * | 1132 | * |
1095 | * This is invoked by acpi_ns_delete_node() during the removal of the ACPI | 1133 | * This is invoked by acpi_ns_delete_node() during the removal of the ACPI |
1096 | * namespace node the device object pointed to by @context is attached to. | 1134 | * namespace node the device object pointed to by @context is attached to. |
1097 | * | 1135 | * |
1098 | * The unregistration is carried out asynchronously to avoid running | 1136 | * The unregistration is carried out asynchronously to avoid running |
1099 | * acpi_device_del() under the ACPICA's namespace mutex and the list is used to | 1137 | * acpi_device_del() under the ACPICA's namespace mutex and the list is used to |
1100 | * ensure the correct ordering (the device objects must be unregistered in the | 1138 | * ensure the correct ordering (the device objects must be unregistered in the |
1101 | * same order in which the corresponding namespace nodes are deleted). | 1139 | * same order in which the corresponding namespace nodes are deleted). |
1102 | */ | 1140 | */ |
1103 | static void acpi_scan_drop_device(acpi_handle handle, void *context) | 1141 | static void acpi_scan_drop_device(acpi_handle handle, void *context) |
1104 | { | 1142 | { |
1105 | static DECLARE_WORK(work, acpi_device_del_work_fn); | 1143 | static DECLARE_WORK(work, acpi_device_del_work_fn); |
1106 | struct acpi_device *adev = context; | 1144 | struct acpi_device *adev = context; |
1107 | 1145 | ||
1108 | mutex_lock(&acpi_device_del_lock); | 1146 | mutex_lock(&acpi_device_del_lock); |
1109 | 1147 | ||
1110 | /* | 1148 | /* |
1111 | * Use the ACPI hotplug workqueue which is ordered, so this work item | 1149 | * Use the ACPI hotplug workqueue which is ordered, so this work item |
1112 | * won't run after any hotplug work items submitted subsequently. That | 1150 | * won't run after any hotplug work items submitted subsequently. That |
1113 | * prevents attempts to register device objects identical to those being | 1151 | * prevents attempts to register device objects identical to those being |
1114 | * deleted from happening concurrently (such attempts result from | 1152 | * deleted from happening concurrently (such attempts result from |
1115 | * hotplug events handled via the ACPI hotplug workqueue). It also will | 1153 | * hotplug events handled via the ACPI hotplug workqueue). It also will |
1116 | * run after all of the work items submitted previosuly, which helps | 1154 | * run after all of the work items submitted previosuly, which helps |
1117 | * those work items to ensure that they are not accessing stale device | 1155 | * those work items to ensure that they are not accessing stale device |
1118 | * objects. | 1156 | * objects. |
1119 | */ | 1157 | */ |
1120 | if (list_empty(&acpi_device_del_list)) | 1158 | if (list_empty(&acpi_device_del_list)) |
1121 | acpi_queue_hotplug_work(&work); | 1159 | acpi_queue_hotplug_work(&work); |
1122 | 1160 | ||
1123 | list_add_tail(&adev->del_list, &acpi_device_del_list); | 1161 | list_add_tail(&adev->del_list, &acpi_device_del_list); |
1124 | /* Make acpi_ns_validate_handle() return NULL for this handle. */ | 1162 | /* Make acpi_ns_validate_handle() return NULL for this handle. */ |
1125 | adev->handle = INVALID_ACPI_HANDLE; | 1163 | adev->handle = INVALID_ACPI_HANDLE; |
1126 | 1164 | ||
1127 | mutex_unlock(&acpi_device_del_lock); | 1165 | mutex_unlock(&acpi_device_del_lock); |
1128 | } | 1166 | } |
1129 | 1167 | ||
1130 | static int acpi_get_device_data(acpi_handle handle, struct acpi_device **device, | 1168 | static int acpi_get_device_data(acpi_handle handle, struct acpi_device **device, |
1131 | void (*callback)(void *)) | 1169 | void (*callback)(void *)) |
1132 | { | 1170 | { |
1133 | acpi_status status; | 1171 | acpi_status status; |
1134 | 1172 | ||
1135 | if (!device) | 1173 | if (!device) |
1136 | return -EINVAL; | 1174 | return -EINVAL; |
1137 | 1175 | ||
1138 | status = acpi_get_data_full(handle, acpi_scan_drop_device, | 1176 | status = acpi_get_data_full(handle, acpi_scan_drop_device, |
1139 | (void **)device, callback); | 1177 | (void **)device, callback); |
1140 | if (ACPI_FAILURE(status) || !*device) { | 1178 | if (ACPI_FAILURE(status) || !*device) { |
1141 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n", | 1179 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n", |
1142 | handle)); | 1180 | handle)); |
1143 | return -ENODEV; | 1181 | return -ENODEV; |
1144 | } | 1182 | } |
1145 | return 0; | 1183 | return 0; |
1146 | } | 1184 | } |
1147 | 1185 | ||
1148 | int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) | 1186 | int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) |
1149 | { | 1187 | { |
1150 | return acpi_get_device_data(handle, device, NULL); | 1188 | return acpi_get_device_data(handle, device, NULL); |
1151 | } | 1189 | } |
1152 | EXPORT_SYMBOL(acpi_bus_get_device); | 1190 | EXPORT_SYMBOL(acpi_bus_get_device); |
1153 | 1191 | ||
1154 | static void get_acpi_device(void *dev) | 1192 | static void get_acpi_device(void *dev) |
1155 | { | 1193 | { |
1156 | if (dev) | 1194 | if (dev) |
1157 | get_device(&((struct acpi_device *)dev)->dev); | 1195 | get_device(&((struct acpi_device *)dev)->dev); |
1158 | } | 1196 | } |
1159 | 1197 | ||
1160 | struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle) | 1198 | struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle) |
1161 | { | 1199 | { |
1162 | struct acpi_device *adev = NULL; | 1200 | struct acpi_device *adev = NULL; |
1163 | 1201 | ||
1164 | acpi_get_device_data(handle, &adev, get_acpi_device); | 1202 | acpi_get_device_data(handle, &adev, get_acpi_device); |
1165 | return adev; | 1203 | return adev; |
1166 | } | 1204 | } |
1167 | 1205 | ||
1168 | void acpi_bus_put_acpi_device(struct acpi_device *adev) | 1206 | void acpi_bus_put_acpi_device(struct acpi_device *adev) |
1169 | { | 1207 | { |
1170 | put_device(&adev->dev); | 1208 | put_device(&adev->dev); |
1171 | } | 1209 | } |
1172 | 1210 | ||
1173 | int acpi_device_add(struct acpi_device *device, | 1211 | int acpi_device_add(struct acpi_device *device, |
1174 | void (*release)(struct device *)) | 1212 | void (*release)(struct device *)) |
1175 | { | 1213 | { |
1176 | int result; | 1214 | int result; |
1177 | struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id; | 1215 | struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id; |
1178 | int found = 0; | 1216 | int found = 0; |
1179 | 1217 | ||
1180 | if (device->handle) { | 1218 | if (device->handle) { |
1181 | acpi_status status; | 1219 | acpi_status status; |
1182 | 1220 | ||
1183 | status = acpi_attach_data(device->handle, acpi_scan_drop_device, | 1221 | status = acpi_attach_data(device->handle, acpi_scan_drop_device, |
1184 | device); | 1222 | device); |
1185 | if (ACPI_FAILURE(status)) { | 1223 | if (ACPI_FAILURE(status)) { |
1186 | acpi_handle_err(device->handle, | 1224 | acpi_handle_err(device->handle, |
1187 | "Unable to attach device data\n"); | 1225 | "Unable to attach device data\n"); |
1188 | return -ENODEV; | 1226 | return -ENODEV; |
1189 | } | 1227 | } |
1190 | } | 1228 | } |
1191 | 1229 | ||
1192 | /* | 1230 | /* |
1193 | * Linkage | 1231 | * Linkage |
1194 | * ------- | 1232 | * ------- |
1195 | * Link this device to its parent and siblings. | 1233 | * Link this device to its parent and siblings. |
1196 | */ | 1234 | */ |
1197 | INIT_LIST_HEAD(&device->children); | 1235 | INIT_LIST_HEAD(&device->children); |
1198 | INIT_LIST_HEAD(&device->node); | 1236 | INIT_LIST_HEAD(&device->node); |
1199 | INIT_LIST_HEAD(&device->wakeup_list); | 1237 | INIT_LIST_HEAD(&device->wakeup_list); |
1200 | INIT_LIST_HEAD(&device->physical_node_list); | 1238 | INIT_LIST_HEAD(&device->physical_node_list); |
1201 | INIT_LIST_HEAD(&device->del_list); | 1239 | INIT_LIST_HEAD(&device->del_list); |
1202 | mutex_init(&device->physical_node_lock); | 1240 | mutex_init(&device->physical_node_lock); |
1203 | 1241 | ||
1204 | new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL); | 1242 | new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL); |
1205 | if (!new_bus_id) { | 1243 | if (!new_bus_id) { |
1206 | pr_err(PREFIX "Memory allocation error\n"); | 1244 | pr_err(PREFIX "Memory allocation error\n"); |
1207 | result = -ENOMEM; | 1245 | result = -ENOMEM; |
1208 | goto err_detach; | 1246 | goto err_detach; |
1209 | } | 1247 | } |
1210 | 1248 | ||
1211 | mutex_lock(&acpi_device_lock); | 1249 | mutex_lock(&acpi_device_lock); |
1212 | /* | 1250 | /* |
1213 | * Find suitable bus_id and instance number in acpi_bus_id_list | 1251 | * Find suitable bus_id and instance number in acpi_bus_id_list |
1214 | * If failed, create one and link it into acpi_bus_id_list | 1252 | * If failed, create one and link it into acpi_bus_id_list |
1215 | */ | 1253 | */ |
1216 | list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) { | 1254 | list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) { |
1217 | if (!strcmp(acpi_device_bus_id->bus_id, | 1255 | if (!strcmp(acpi_device_bus_id->bus_id, |
1218 | acpi_device_hid(device))) { | 1256 | acpi_device_hid(device))) { |
1219 | acpi_device_bus_id->instance_no++; | 1257 | acpi_device_bus_id->instance_no++; |
1220 | found = 1; | 1258 | found = 1; |
1221 | kfree(new_bus_id); | 1259 | kfree(new_bus_id); |
1222 | break; | 1260 | break; |
1223 | } | 1261 | } |
1224 | } | 1262 | } |
1225 | if (!found) { | 1263 | if (!found) { |
1226 | acpi_device_bus_id = new_bus_id; | 1264 | acpi_device_bus_id = new_bus_id; |
1227 | strcpy(acpi_device_bus_id->bus_id, acpi_device_hid(device)); | 1265 | strcpy(acpi_device_bus_id->bus_id, acpi_device_hid(device)); |
1228 | acpi_device_bus_id->instance_no = 0; | 1266 | acpi_device_bus_id->instance_no = 0; |
1229 | list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); | 1267 | list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); |
1230 | } | 1268 | } |
1231 | dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); | 1269 | dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); |
1232 | 1270 | ||
1233 | if (device->parent) | 1271 | if (device->parent) |
1234 | list_add_tail(&device->node, &device->parent->children); | 1272 | list_add_tail(&device->node, &device->parent->children); |
1235 | 1273 | ||
1236 | if (device->wakeup.flags.valid) | 1274 | if (device->wakeup.flags.valid) |
1237 | list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list); | 1275 | list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list); |
1238 | mutex_unlock(&acpi_device_lock); | 1276 | mutex_unlock(&acpi_device_lock); |
1239 | 1277 | ||
1240 | if (device->parent) | 1278 | if (device->parent) |
1241 | device->dev.parent = &device->parent->dev; | 1279 | device->dev.parent = &device->parent->dev; |
1242 | device->dev.bus = &acpi_bus_type; | 1280 | device->dev.bus = &acpi_bus_type; |
1243 | device->dev.release = release; | 1281 | device->dev.release = release; |
1244 | result = device_add(&device->dev); | 1282 | result = device_add(&device->dev); |
1245 | if (result) { | 1283 | if (result) { |
1246 | dev_err(&device->dev, "Error registering device\n"); | 1284 | dev_err(&device->dev, "Error registering device\n"); |
1247 | goto err; | 1285 | goto err; |
1248 | } | 1286 | } |
1249 | 1287 | ||
1250 | result = acpi_device_setup_files(device); | 1288 | result = acpi_device_setup_files(device); |
1251 | if (result) | 1289 | if (result) |
1252 | printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", | 1290 | printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", |
1253 | dev_name(&device->dev)); | 1291 | dev_name(&device->dev)); |
1254 | 1292 | ||
1255 | return 0; | 1293 | return 0; |
1256 | 1294 | ||
1257 | err: | 1295 | err: |
1258 | mutex_lock(&acpi_device_lock); | 1296 | mutex_lock(&acpi_device_lock); |
1259 | if (device->parent) | 1297 | if (device->parent) |
1260 | list_del(&device->node); | 1298 | list_del(&device->node); |
1261 | list_del(&device->wakeup_list); | 1299 | list_del(&device->wakeup_list); |
1262 | mutex_unlock(&acpi_device_lock); | 1300 | mutex_unlock(&acpi_device_lock); |
1263 | 1301 | ||
1264 | err_detach: | 1302 | err_detach: |
1265 | acpi_detach_data(device->handle, acpi_scan_drop_device); | 1303 | acpi_detach_data(device->handle, acpi_scan_drop_device); |
1266 | return result; | 1304 | return result; |
1267 | } | 1305 | } |
1268 | 1306 | ||
1269 | /* -------------------------------------------------------------------------- | 1307 | /* -------------------------------------------------------------------------- |
1270 | Driver Management | 1308 | Driver Management |
1271 | -------------------------------------------------------------------------- */ | 1309 | -------------------------------------------------------------------------- */ |
1272 | /** | 1310 | /** |
1273 | * acpi_bus_register_driver - register a driver with the ACPI bus | 1311 | * acpi_bus_register_driver - register a driver with the ACPI bus |
1274 | * @driver: driver being registered | 1312 | * @driver: driver being registered |
1275 | * | 1313 | * |
1276 | * Registers a driver with the ACPI bus. Searches the namespace for all | 1314 | * Registers a driver with the ACPI bus. Searches the namespace for all |
1277 | * devices that match the driver's criteria and binds. Returns zero for | 1315 | * devices that match the driver's criteria and binds. Returns zero for |
1278 | * success or a negative error status for failure. | 1316 | * success or a negative error status for failure. |
1279 | */ | 1317 | */ |
1280 | int acpi_bus_register_driver(struct acpi_driver *driver) | 1318 | int acpi_bus_register_driver(struct acpi_driver *driver) |
1281 | { | 1319 | { |
1282 | int ret; | 1320 | int ret; |
1283 | 1321 | ||
1284 | if (acpi_disabled) | 1322 | if (acpi_disabled) |
1285 | return -ENODEV; | 1323 | return -ENODEV; |
1286 | driver->drv.name = driver->name; | 1324 | driver->drv.name = driver->name; |
1287 | driver->drv.bus = &acpi_bus_type; | 1325 | driver->drv.bus = &acpi_bus_type; |
1288 | driver->drv.owner = driver->owner; | 1326 | driver->drv.owner = driver->owner; |
1289 | 1327 | ||
1290 | ret = driver_register(&driver->drv); | 1328 | ret = driver_register(&driver->drv); |
1291 | return ret; | 1329 | return ret; |
1292 | } | 1330 | } |
1293 | 1331 | ||
1294 | EXPORT_SYMBOL(acpi_bus_register_driver); | 1332 | EXPORT_SYMBOL(acpi_bus_register_driver); |
1295 | 1333 | ||
1296 | /** | 1334 | /** |
1297 | * acpi_bus_unregister_driver - unregisters a driver with the ACPI bus | 1335 | * acpi_bus_unregister_driver - unregisters a driver with the ACPI bus |
1298 | * @driver: driver to unregister | 1336 | * @driver: driver to unregister |
1299 | * | 1337 | * |
1300 | * Unregisters a driver with the ACPI bus. Searches the namespace for all | 1338 | * Unregisters a driver with the ACPI bus. Searches the namespace for all |
1301 | * devices that match the driver's criteria and unbinds. | 1339 | * devices that match the driver's criteria and unbinds. |
1302 | */ | 1340 | */ |
1303 | void acpi_bus_unregister_driver(struct acpi_driver *driver) | 1341 | void acpi_bus_unregister_driver(struct acpi_driver *driver) |
1304 | { | 1342 | { |
1305 | driver_unregister(&driver->drv); | 1343 | driver_unregister(&driver->drv); |
1306 | } | 1344 | } |
1307 | 1345 | ||
1308 | EXPORT_SYMBOL(acpi_bus_unregister_driver); | 1346 | EXPORT_SYMBOL(acpi_bus_unregister_driver); |
1309 | 1347 | ||
1310 | /* -------------------------------------------------------------------------- | 1348 | /* -------------------------------------------------------------------------- |
1311 | Device Enumeration | 1349 | Device Enumeration |
1312 | -------------------------------------------------------------------------- */ | 1350 | -------------------------------------------------------------------------- */ |
1313 | static struct acpi_device *acpi_bus_get_parent(acpi_handle handle) | 1351 | static struct acpi_device *acpi_bus_get_parent(acpi_handle handle) |
1314 | { | 1352 | { |
1315 | struct acpi_device *device = NULL; | 1353 | struct acpi_device *device = NULL; |
1316 | acpi_status status; | 1354 | acpi_status status; |
1317 | 1355 | ||
1318 | /* | 1356 | /* |
1319 | * Fixed hardware devices do not appear in the namespace and do not | 1357 | * Fixed hardware devices do not appear in the namespace and do not |
1320 | * have handles, but we fabricate acpi_devices for them, so we have | 1358 | * have handles, but we fabricate acpi_devices for them, so we have |
1321 | * to deal with them specially. | 1359 | * to deal with them specially. |
1322 | */ | 1360 | */ |
1323 | if (!handle) | 1361 | if (!handle) |
1324 | return acpi_root; | 1362 | return acpi_root; |
1325 | 1363 | ||
1326 | do { | 1364 | do { |
1327 | status = acpi_get_parent(handle, &handle); | 1365 | status = acpi_get_parent(handle, &handle); |
1328 | if (ACPI_FAILURE(status)) | 1366 | if (ACPI_FAILURE(status)) |
1329 | return status == AE_NULL_ENTRY ? NULL : acpi_root; | 1367 | return status == AE_NULL_ENTRY ? NULL : acpi_root; |
1330 | } while (acpi_bus_get_device(handle, &device)); | 1368 | } while (acpi_bus_get_device(handle, &device)); |
1331 | return device; | 1369 | return device; |
1332 | } | 1370 | } |
1333 | 1371 | ||
1334 | acpi_status | 1372 | acpi_status |
1335 | acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) | 1373 | acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) |
1336 | { | 1374 | { |
1337 | acpi_status status; | 1375 | acpi_status status; |
1338 | acpi_handle tmp; | 1376 | acpi_handle tmp; |
1339 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | 1377 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; |
1340 | union acpi_object *obj; | 1378 | union acpi_object *obj; |
1341 | 1379 | ||
1342 | status = acpi_get_handle(handle, "_EJD", &tmp); | 1380 | status = acpi_get_handle(handle, "_EJD", &tmp); |
1343 | if (ACPI_FAILURE(status)) | 1381 | if (ACPI_FAILURE(status)) |
1344 | return status; | 1382 | return status; |
1345 | 1383 | ||
1346 | status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer); | 1384 | status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer); |
1347 | if (ACPI_SUCCESS(status)) { | 1385 | if (ACPI_SUCCESS(status)) { |
1348 | obj = buffer.pointer; | 1386 | obj = buffer.pointer; |
1349 | status = acpi_get_handle(ACPI_ROOT_OBJECT, obj->string.pointer, | 1387 | status = acpi_get_handle(ACPI_ROOT_OBJECT, obj->string.pointer, |
1350 | ejd); | 1388 | ejd); |
1351 | kfree(buffer.pointer); | 1389 | kfree(buffer.pointer); |
1352 | } | 1390 | } |
1353 | return status; | 1391 | return status; |
1354 | } | 1392 | } |
1355 | EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); | 1393 | EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); |
1356 | 1394 | ||
1357 | static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle, | 1395 | static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle, |
1358 | struct acpi_device_wakeup *wakeup) | 1396 | struct acpi_device_wakeup *wakeup) |
1359 | { | 1397 | { |
1360 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 1398 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
1361 | union acpi_object *package = NULL; | 1399 | union acpi_object *package = NULL; |
1362 | union acpi_object *element = NULL; | 1400 | union acpi_object *element = NULL; |
1363 | acpi_status status; | 1401 | acpi_status status; |
1364 | int err = -ENODATA; | 1402 | int err = -ENODATA; |
1365 | 1403 | ||
1366 | if (!wakeup) | 1404 | if (!wakeup) |
1367 | return -EINVAL; | 1405 | return -EINVAL; |
1368 | 1406 | ||
1369 | INIT_LIST_HEAD(&wakeup->resources); | 1407 | INIT_LIST_HEAD(&wakeup->resources); |
1370 | 1408 | ||
1371 | /* _PRW */ | 1409 | /* _PRW */ |
1372 | status = acpi_evaluate_object(handle, "_PRW", NULL, &buffer); | 1410 | status = acpi_evaluate_object(handle, "_PRW", NULL, &buffer); |
1373 | if (ACPI_FAILURE(status)) { | 1411 | if (ACPI_FAILURE(status)) { |
1374 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW")); | 1412 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW")); |
1375 | return err; | 1413 | return err; |
1376 | } | 1414 | } |
1377 | 1415 | ||
1378 | package = (union acpi_object *)buffer.pointer; | 1416 | package = (union acpi_object *)buffer.pointer; |
1379 | 1417 | ||
1380 | if (!package || package->package.count < 2) | 1418 | if (!package || package->package.count < 2) |
1381 | goto out; | 1419 | goto out; |
1382 | 1420 | ||
1383 | element = &(package->package.elements[0]); | 1421 | element = &(package->package.elements[0]); |
1384 | if (!element) | 1422 | if (!element) |
1385 | goto out; | 1423 | goto out; |
1386 | 1424 | ||
1387 | if (element->type == ACPI_TYPE_PACKAGE) { | 1425 | if (element->type == ACPI_TYPE_PACKAGE) { |
1388 | if ((element->package.count < 2) || | 1426 | if ((element->package.count < 2) || |
1389 | (element->package.elements[0].type != | 1427 | (element->package.elements[0].type != |
1390 | ACPI_TYPE_LOCAL_REFERENCE) | 1428 | ACPI_TYPE_LOCAL_REFERENCE) |
1391 | || (element->package.elements[1].type != ACPI_TYPE_INTEGER)) | 1429 | || (element->package.elements[1].type != ACPI_TYPE_INTEGER)) |
1392 | goto out; | 1430 | goto out; |
1393 | 1431 | ||
1394 | wakeup->gpe_device = | 1432 | wakeup->gpe_device = |
1395 | element->package.elements[0].reference.handle; | 1433 | element->package.elements[0].reference.handle; |
1396 | wakeup->gpe_number = | 1434 | wakeup->gpe_number = |
1397 | (u32) element->package.elements[1].integer.value; | 1435 | (u32) element->package.elements[1].integer.value; |
1398 | } else if (element->type == ACPI_TYPE_INTEGER) { | 1436 | } else if (element->type == ACPI_TYPE_INTEGER) { |
1399 | wakeup->gpe_device = NULL; | 1437 | wakeup->gpe_device = NULL; |
1400 | wakeup->gpe_number = element->integer.value; | 1438 | wakeup->gpe_number = element->integer.value; |
1401 | } else { | 1439 | } else { |
1402 | goto out; | 1440 | goto out; |
1403 | } | 1441 | } |
1404 | 1442 | ||
1405 | element = &(package->package.elements[1]); | 1443 | element = &(package->package.elements[1]); |
1406 | if (element->type != ACPI_TYPE_INTEGER) | 1444 | if (element->type != ACPI_TYPE_INTEGER) |
1407 | goto out; | 1445 | goto out; |
1408 | 1446 | ||
1409 | wakeup->sleep_state = element->integer.value; | 1447 | wakeup->sleep_state = element->integer.value; |
1410 | 1448 | ||
1411 | err = acpi_extract_power_resources(package, 2, &wakeup->resources); | 1449 | err = acpi_extract_power_resources(package, 2, &wakeup->resources); |
1412 | if (err) | 1450 | if (err) |
1413 | goto out; | 1451 | goto out; |
1414 | 1452 | ||
1415 | if (!list_empty(&wakeup->resources)) { | 1453 | if (!list_empty(&wakeup->resources)) { |
1416 | int sleep_state; | 1454 | int sleep_state; |
1417 | 1455 | ||
1418 | err = acpi_power_wakeup_list_init(&wakeup->resources, | 1456 | err = acpi_power_wakeup_list_init(&wakeup->resources, |
1419 | &sleep_state); | 1457 | &sleep_state); |
1420 | if (err) { | 1458 | if (err) { |
1421 | acpi_handle_warn(handle, "Retrieving current states " | 1459 | acpi_handle_warn(handle, "Retrieving current states " |
1422 | "of wakeup power resources failed\n"); | 1460 | "of wakeup power resources failed\n"); |
1423 | acpi_power_resources_list_free(&wakeup->resources); | 1461 | acpi_power_resources_list_free(&wakeup->resources); |
1424 | goto out; | 1462 | goto out; |
1425 | } | 1463 | } |
1426 | if (sleep_state < wakeup->sleep_state) { | 1464 | if (sleep_state < wakeup->sleep_state) { |
1427 | acpi_handle_warn(handle, "Overriding _PRW sleep state " | 1465 | acpi_handle_warn(handle, "Overriding _PRW sleep state " |
1428 | "(S%d) by S%d from power resources\n", | 1466 | "(S%d) by S%d from power resources\n", |
1429 | (int)wakeup->sleep_state, sleep_state); | 1467 | (int)wakeup->sleep_state, sleep_state); |
1430 | wakeup->sleep_state = sleep_state; | 1468 | wakeup->sleep_state = sleep_state; |
1431 | } | 1469 | } |
1432 | } | 1470 | } |
1433 | 1471 | ||
1434 | out: | 1472 | out: |
1435 | kfree(buffer.pointer); | 1473 | kfree(buffer.pointer); |
1436 | return err; | 1474 | return err; |
1437 | } | 1475 | } |
1438 | 1476 | ||
1439 | static void acpi_wakeup_gpe_init(struct acpi_device *device) | 1477 | static void acpi_wakeup_gpe_init(struct acpi_device *device) |
1440 | { | 1478 | { |
1441 | struct acpi_device_id button_device_ids[] = { | 1479 | struct acpi_device_id button_device_ids[] = { |
1442 | {"PNP0C0C", 0}, | 1480 | {"PNP0C0C", 0}, |
1443 | {"PNP0C0D", 0}, | 1481 | {"PNP0C0D", 0}, |
1444 | {"PNP0C0E", 0}, | 1482 | {"PNP0C0E", 0}, |
1445 | {"", 0}, | 1483 | {"", 0}, |
1446 | }; | 1484 | }; |
1447 | struct acpi_device_wakeup *wakeup = &device->wakeup; | 1485 | struct acpi_device_wakeup *wakeup = &device->wakeup; |
1448 | acpi_status status; | 1486 | acpi_status status; |
1449 | acpi_event_status event_status; | 1487 | acpi_event_status event_status; |
1450 | 1488 | ||
1451 | wakeup->flags.notifier_present = 0; | 1489 | wakeup->flags.notifier_present = 0; |
1452 | 1490 | ||
1453 | /* Power button, Lid switch always enable wakeup */ | 1491 | /* Power button, Lid switch always enable wakeup */ |
1454 | if (!acpi_match_device_ids(device, button_device_ids)) { | 1492 | if (!acpi_match_device_ids(device, button_device_ids)) { |
1455 | wakeup->flags.run_wake = 1; | 1493 | wakeup->flags.run_wake = 1; |
1456 | if (!acpi_match_device_ids(device, &button_device_ids[1])) { | 1494 | if (!acpi_match_device_ids(device, &button_device_ids[1])) { |
1457 | /* Do not use Lid/sleep button for S5 wakeup */ | 1495 | /* Do not use Lid/sleep button for S5 wakeup */ |
1458 | if (wakeup->sleep_state == ACPI_STATE_S5) | 1496 | if (wakeup->sleep_state == ACPI_STATE_S5) |
1459 | wakeup->sleep_state = ACPI_STATE_S4; | 1497 | wakeup->sleep_state = ACPI_STATE_S4; |
1460 | } | 1498 | } |
1461 | acpi_mark_gpe_for_wake(wakeup->gpe_device, wakeup->gpe_number); | 1499 | acpi_mark_gpe_for_wake(wakeup->gpe_device, wakeup->gpe_number); |
1462 | device_set_wakeup_capable(&device->dev, true); | 1500 | device_set_wakeup_capable(&device->dev, true); |
1463 | return; | 1501 | return; |
1464 | } | 1502 | } |
1465 | 1503 | ||
1466 | acpi_setup_gpe_for_wake(device->handle, wakeup->gpe_device, | 1504 | acpi_setup_gpe_for_wake(device->handle, wakeup->gpe_device, |
1467 | wakeup->gpe_number); | 1505 | wakeup->gpe_number); |
1468 | status = acpi_get_gpe_status(wakeup->gpe_device, wakeup->gpe_number, | 1506 | status = acpi_get_gpe_status(wakeup->gpe_device, wakeup->gpe_number, |
1469 | &event_status); | 1507 | &event_status); |
1470 | if (ACPI_FAILURE(status)) | 1508 | if (ACPI_FAILURE(status)) |
1471 | return; | 1509 | return; |
1472 | 1510 | ||
1473 | wakeup->flags.run_wake = !!(event_status & ACPI_EVENT_FLAG_HAS_HANDLER); | 1511 | wakeup->flags.run_wake = !!(event_status & ACPI_EVENT_FLAG_HAS_HANDLER); |
1474 | } | 1512 | } |
1475 | 1513 | ||
1476 | static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | 1514 | static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) |
1477 | { | 1515 | { |
1478 | int err; | 1516 | int err; |
1479 | 1517 | ||
1480 | /* Presence of _PRW indicates wake capable */ | 1518 | /* Presence of _PRW indicates wake capable */ |
1481 | if (!acpi_has_method(device->handle, "_PRW")) | 1519 | if (!acpi_has_method(device->handle, "_PRW")) |
1482 | return; | 1520 | return; |
1483 | 1521 | ||
1484 | err = acpi_bus_extract_wakeup_device_power_package(device->handle, | 1522 | err = acpi_bus_extract_wakeup_device_power_package(device->handle, |
1485 | &device->wakeup); | 1523 | &device->wakeup); |
1486 | if (err) { | 1524 | if (err) { |
1487 | dev_err(&device->dev, "_PRW evaluation error: %d\n", err); | 1525 | dev_err(&device->dev, "_PRW evaluation error: %d\n", err); |
1488 | return; | 1526 | return; |
1489 | } | 1527 | } |
1490 | 1528 | ||
1491 | device->wakeup.flags.valid = 1; | 1529 | device->wakeup.flags.valid = 1; |
1492 | device->wakeup.prepare_count = 0; | 1530 | device->wakeup.prepare_count = 0; |
1493 | acpi_wakeup_gpe_init(device); | 1531 | acpi_wakeup_gpe_init(device); |
1494 | /* Call _PSW/_DSW object to disable its ability to wake the sleeping | 1532 | /* Call _PSW/_DSW object to disable its ability to wake the sleeping |
1495 | * system for the ACPI device with the _PRW object. | 1533 | * system for the ACPI device with the _PRW object. |
1496 | * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. | 1534 | * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. |
1497 | * So it is necessary to call _DSW object first. Only when it is not | 1535 | * So it is necessary to call _DSW object first. Only when it is not |
1498 | * present will the _PSW object used. | 1536 | * present will the _PSW object used. |
1499 | */ | 1537 | */ |
1500 | err = acpi_device_sleep_wake(device, 0, 0, 0); | 1538 | err = acpi_device_sleep_wake(device, 0, 0, 0); |
1501 | if (err) | 1539 | if (err) |
1502 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 1540 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
1503 | "error in _DSW or _PSW evaluation\n")); | 1541 | "error in _DSW or _PSW evaluation\n")); |
1504 | } | 1542 | } |
1505 | 1543 | ||
1506 | static void acpi_bus_init_power_state(struct acpi_device *device, int state) | 1544 | static void acpi_bus_init_power_state(struct acpi_device *device, int state) |
1507 | { | 1545 | { |
1508 | struct acpi_device_power_state *ps = &device->power.states[state]; | 1546 | struct acpi_device_power_state *ps = &device->power.states[state]; |
1509 | char pathname[5] = { '_', 'P', 'R', '0' + state, '\0' }; | 1547 | char pathname[5] = { '_', 'P', 'R', '0' + state, '\0' }; |
1510 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 1548 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
1511 | acpi_status status; | 1549 | acpi_status status; |
1512 | 1550 | ||
1513 | INIT_LIST_HEAD(&ps->resources); | 1551 | INIT_LIST_HEAD(&ps->resources); |
1514 | 1552 | ||
1515 | /* Evaluate "_PRx" to get referenced power resources */ | 1553 | /* Evaluate "_PRx" to get referenced power resources */ |
1516 | status = acpi_evaluate_object(device->handle, pathname, NULL, &buffer); | 1554 | status = acpi_evaluate_object(device->handle, pathname, NULL, &buffer); |
1517 | if (ACPI_SUCCESS(status)) { | 1555 | if (ACPI_SUCCESS(status)) { |
1518 | union acpi_object *package = buffer.pointer; | 1556 | union acpi_object *package = buffer.pointer; |
1519 | 1557 | ||
1520 | if (buffer.length && package | 1558 | if (buffer.length && package |
1521 | && package->type == ACPI_TYPE_PACKAGE | 1559 | && package->type == ACPI_TYPE_PACKAGE |
1522 | && package->package.count) { | 1560 | && package->package.count) { |
1523 | int err = acpi_extract_power_resources(package, 0, | 1561 | int err = acpi_extract_power_resources(package, 0, |
1524 | &ps->resources); | 1562 | &ps->resources); |
1525 | if (!err) | 1563 | if (!err) |
1526 | device->power.flags.power_resources = 1; | 1564 | device->power.flags.power_resources = 1; |
1527 | } | 1565 | } |
1528 | ACPI_FREE(buffer.pointer); | 1566 | ACPI_FREE(buffer.pointer); |
1529 | } | 1567 | } |
1530 | 1568 | ||
1531 | /* Evaluate "_PSx" to see if we can do explicit sets */ | 1569 | /* Evaluate "_PSx" to see if we can do explicit sets */ |
1532 | pathname[2] = 'S'; | 1570 | pathname[2] = 'S'; |
1533 | if (acpi_has_method(device->handle, pathname)) | 1571 | if (acpi_has_method(device->handle, pathname)) |
1534 | ps->flags.explicit_set = 1; | 1572 | ps->flags.explicit_set = 1; |
1535 | 1573 | ||
1536 | /* | 1574 | /* |
1537 | * State is valid if there are means to put the device into it. | 1575 | * State is valid if there are means to put the device into it. |
1538 | * D3hot is only valid if _PR3 present. | 1576 | * D3hot is only valid if _PR3 present. |
1539 | */ | 1577 | */ |
1540 | if (!list_empty(&ps->resources) | 1578 | if (!list_empty(&ps->resources) |
1541 | || (ps->flags.explicit_set && state < ACPI_STATE_D3_HOT)) { | 1579 | || (ps->flags.explicit_set && state < ACPI_STATE_D3_HOT)) { |
1542 | ps->flags.valid = 1; | 1580 | ps->flags.valid = 1; |
1543 | ps->flags.os_accessible = 1; | 1581 | ps->flags.os_accessible = 1; |
1544 | } | 1582 | } |
1545 | 1583 | ||
1546 | ps->power = -1; /* Unknown - driver assigned */ | 1584 | ps->power = -1; /* Unknown - driver assigned */ |
1547 | ps->latency = -1; /* Unknown - driver assigned */ | 1585 | ps->latency = -1; /* Unknown - driver assigned */ |
1548 | } | 1586 | } |
1549 | 1587 | ||
1550 | static void acpi_bus_get_power_flags(struct acpi_device *device) | 1588 | static void acpi_bus_get_power_flags(struct acpi_device *device) |
1551 | { | 1589 | { |
1552 | u32 i; | 1590 | u32 i; |
1553 | 1591 | ||
1554 | /* Presence of _PS0|_PR0 indicates 'power manageable' */ | 1592 | /* Presence of _PS0|_PR0 indicates 'power manageable' */ |
1555 | if (!acpi_has_method(device->handle, "_PS0") && | 1593 | if (!acpi_has_method(device->handle, "_PS0") && |
1556 | !acpi_has_method(device->handle, "_PR0")) | 1594 | !acpi_has_method(device->handle, "_PR0")) |
1557 | return; | 1595 | return; |
1558 | 1596 | ||
1559 | device->flags.power_manageable = 1; | 1597 | device->flags.power_manageable = 1; |
1560 | 1598 | ||
1561 | /* | 1599 | /* |
1562 | * Power Management Flags | 1600 | * Power Management Flags |
1563 | */ | 1601 | */ |
1564 | if (acpi_has_method(device->handle, "_PSC")) | 1602 | if (acpi_has_method(device->handle, "_PSC")) |
1565 | device->power.flags.explicit_get = 1; | 1603 | device->power.flags.explicit_get = 1; |
1566 | 1604 | ||
1567 | if (acpi_has_method(device->handle, "_IRC")) | 1605 | if (acpi_has_method(device->handle, "_IRC")) |
1568 | device->power.flags.inrush_current = 1; | 1606 | device->power.flags.inrush_current = 1; |
1569 | 1607 | ||
1570 | if (acpi_has_method(device->handle, "_DSW")) | 1608 | if (acpi_has_method(device->handle, "_DSW")) |
1571 | device->power.flags.dsw_present = 1; | 1609 | device->power.flags.dsw_present = 1; |
1572 | 1610 | ||
1573 | /* | 1611 | /* |
1574 | * Enumerate supported power management states | 1612 | * Enumerate supported power management states |
1575 | */ | 1613 | */ |
1576 | for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) | 1614 | for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) |
1577 | acpi_bus_init_power_state(device, i); | 1615 | acpi_bus_init_power_state(device, i); |
1578 | 1616 | ||
1579 | INIT_LIST_HEAD(&device->power.states[ACPI_STATE_D3_COLD].resources); | 1617 | INIT_LIST_HEAD(&device->power.states[ACPI_STATE_D3_COLD].resources); |
1580 | 1618 | ||
1581 | /* Set defaults for D0 and D3 states (always valid) */ | 1619 | /* Set defaults for D0 and D3 states (always valid) */ |
1582 | device->power.states[ACPI_STATE_D0].flags.valid = 1; | 1620 | device->power.states[ACPI_STATE_D0].flags.valid = 1; |
1583 | device->power.states[ACPI_STATE_D0].power = 100; | 1621 | device->power.states[ACPI_STATE_D0].power = 100; |
1584 | device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1; | 1622 | device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1; |
1585 | device->power.states[ACPI_STATE_D3_COLD].power = 0; | 1623 | device->power.states[ACPI_STATE_D3_COLD].power = 0; |
1586 | 1624 | ||
1587 | /* Set D3cold's explicit_set flag if _PS3 exists. */ | 1625 | /* Set D3cold's explicit_set flag if _PS3 exists. */ |
1588 | if (device->power.states[ACPI_STATE_D3_HOT].flags.explicit_set) | 1626 | if (device->power.states[ACPI_STATE_D3_HOT].flags.explicit_set) |
1589 | device->power.states[ACPI_STATE_D3_COLD].flags.explicit_set = 1; | 1627 | device->power.states[ACPI_STATE_D3_COLD].flags.explicit_set = 1; |
1590 | 1628 | ||
1591 | /* Presence of _PS3 or _PRx means we can put the device into D3 cold */ | 1629 | /* Presence of _PS3 or _PRx means we can put the device into D3 cold */ |
1592 | if (device->power.states[ACPI_STATE_D3_HOT].flags.explicit_set || | 1630 | if (device->power.states[ACPI_STATE_D3_HOT].flags.explicit_set || |
1593 | device->power.flags.power_resources) | 1631 | device->power.flags.power_resources) |
1594 | device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible = 1; | 1632 | device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible = 1; |
1595 | 1633 | ||
1596 | if (acpi_bus_init_power(device)) { | 1634 | if (acpi_bus_init_power(device)) { |
1597 | acpi_free_power_resources_lists(device); | 1635 | acpi_free_power_resources_lists(device); |
1598 | device->flags.power_manageable = 0; | 1636 | device->flags.power_manageable = 0; |
1599 | } | 1637 | } |
1600 | } | 1638 | } |
1601 | 1639 | ||
1602 | static void acpi_bus_get_flags(struct acpi_device *device) | 1640 | static void acpi_bus_get_flags(struct acpi_device *device) |
1603 | { | 1641 | { |
1604 | /* Presence of _STA indicates 'dynamic_status' */ | 1642 | /* Presence of _STA indicates 'dynamic_status' */ |
1605 | if (acpi_has_method(device->handle, "_STA")) | 1643 | if (acpi_has_method(device->handle, "_STA")) |
1606 | device->flags.dynamic_status = 1; | 1644 | device->flags.dynamic_status = 1; |
1607 | 1645 | ||
1608 | /* Presence of _RMV indicates 'removable' */ | 1646 | /* Presence of _RMV indicates 'removable' */ |
1609 | if (acpi_has_method(device->handle, "_RMV")) | 1647 | if (acpi_has_method(device->handle, "_RMV")) |
1610 | device->flags.removable = 1; | 1648 | device->flags.removable = 1; |
1611 | 1649 | ||
1612 | /* Presence of _EJD|_EJ0 indicates 'ejectable' */ | 1650 | /* Presence of _EJD|_EJ0 indicates 'ejectable' */ |
1613 | if (acpi_has_method(device->handle, "_EJD") || | 1651 | if (acpi_has_method(device->handle, "_EJD") || |
1614 | acpi_has_method(device->handle, "_EJ0")) | 1652 | acpi_has_method(device->handle, "_EJ0")) |
1615 | device->flags.ejectable = 1; | 1653 | device->flags.ejectable = 1; |
1616 | } | 1654 | } |
1617 | 1655 | ||
1618 | static void acpi_device_get_busid(struct acpi_device *device) | 1656 | static void acpi_device_get_busid(struct acpi_device *device) |
1619 | { | 1657 | { |
1620 | char bus_id[5] = { '?', 0 }; | 1658 | char bus_id[5] = { '?', 0 }; |
1621 | struct acpi_buffer buffer = { sizeof(bus_id), bus_id }; | 1659 | struct acpi_buffer buffer = { sizeof(bus_id), bus_id }; |
1622 | int i = 0; | 1660 | int i = 0; |
1623 | 1661 | ||
1624 | /* | 1662 | /* |
1625 | * Bus ID | 1663 | * Bus ID |
1626 | * ------ | 1664 | * ------ |
1627 | * The device's Bus ID is simply the object name. | 1665 | * The device's Bus ID is simply the object name. |
1628 | * TBD: Shouldn't this value be unique (within the ACPI namespace)? | 1666 | * TBD: Shouldn't this value be unique (within the ACPI namespace)? |
1629 | */ | 1667 | */ |
1630 | if (ACPI_IS_ROOT_DEVICE(device)) { | 1668 | if (ACPI_IS_ROOT_DEVICE(device)) { |
1631 | strcpy(device->pnp.bus_id, "ACPI"); | 1669 | strcpy(device->pnp.bus_id, "ACPI"); |
1632 | return; | 1670 | return; |
1633 | } | 1671 | } |
1634 | 1672 | ||
1635 | switch (device->device_type) { | 1673 | switch (device->device_type) { |
1636 | case ACPI_BUS_TYPE_POWER_BUTTON: | 1674 | case ACPI_BUS_TYPE_POWER_BUTTON: |
1637 | strcpy(device->pnp.bus_id, "PWRF"); | 1675 | strcpy(device->pnp.bus_id, "PWRF"); |
1638 | break; | 1676 | break; |
1639 | case ACPI_BUS_TYPE_SLEEP_BUTTON: | 1677 | case ACPI_BUS_TYPE_SLEEP_BUTTON: |
1640 | strcpy(device->pnp.bus_id, "SLPF"); | 1678 | strcpy(device->pnp.bus_id, "SLPF"); |
1641 | break; | 1679 | break; |
1642 | default: | 1680 | default: |
1643 | acpi_get_name(device->handle, ACPI_SINGLE_NAME, &buffer); | 1681 | acpi_get_name(device->handle, ACPI_SINGLE_NAME, &buffer); |
1644 | /* Clean up trailing underscores (if any) */ | 1682 | /* Clean up trailing underscores (if any) */ |
1645 | for (i = 3; i > 1; i--) { | 1683 | for (i = 3; i > 1; i--) { |
1646 | if (bus_id[i] == '_') | 1684 | if (bus_id[i] == '_') |
1647 | bus_id[i] = '\0'; | 1685 | bus_id[i] = '\0'; |
1648 | else | 1686 | else |
1649 | break; | 1687 | break; |
1650 | } | 1688 | } |
1651 | strcpy(device->pnp.bus_id, bus_id); | 1689 | strcpy(device->pnp.bus_id, bus_id); |
1652 | break; | 1690 | break; |
1653 | } | 1691 | } |
1654 | } | 1692 | } |
1655 | 1693 | ||
1656 | /* | 1694 | /* |
1657 | * acpi_ata_match - see if an acpi object is an ATA device | 1695 | * acpi_ata_match - see if an acpi object is an ATA device |
1658 | * | 1696 | * |
1659 | * If an acpi object has one of the ACPI ATA methods defined, | 1697 | * If an acpi object has one of the ACPI ATA methods defined, |
1660 | * then we can safely call it an ATA device. | 1698 | * then we can safely call it an ATA device. |
1661 | */ | 1699 | */ |
1662 | bool acpi_ata_match(acpi_handle handle) | 1700 | bool acpi_ata_match(acpi_handle handle) |
1663 | { | 1701 | { |
1664 | return acpi_has_method(handle, "_GTF") || | 1702 | return acpi_has_method(handle, "_GTF") || |
1665 | acpi_has_method(handle, "_GTM") || | 1703 | acpi_has_method(handle, "_GTM") || |
1666 | acpi_has_method(handle, "_STM") || | 1704 | acpi_has_method(handle, "_STM") || |
1667 | acpi_has_method(handle, "_SDD"); | 1705 | acpi_has_method(handle, "_SDD"); |
1668 | } | 1706 | } |
1669 | 1707 | ||
1670 | /* | 1708 | /* |
1671 | * acpi_bay_match - see if an acpi object is an ejectable driver bay | 1709 | * acpi_bay_match - see if an acpi object is an ejectable driver bay |
1672 | * | 1710 | * |
1673 | * If an acpi object is ejectable and has one of the ACPI ATA methods defined, | 1711 | * If an acpi object is ejectable and has one of the ACPI ATA methods defined, |
1674 | * then we can safely call it an ejectable drive bay | 1712 | * then we can safely call it an ejectable drive bay |
1675 | */ | 1713 | */ |
1676 | bool acpi_bay_match(acpi_handle handle) | 1714 | bool acpi_bay_match(acpi_handle handle) |
1677 | { | 1715 | { |
1678 | acpi_handle phandle; | 1716 | acpi_handle phandle; |
1679 | 1717 | ||
1680 | if (!acpi_has_method(handle, "_EJ0")) | 1718 | if (!acpi_has_method(handle, "_EJ0")) |
1681 | return false; | 1719 | return false; |
1682 | if (acpi_ata_match(handle)) | 1720 | if (acpi_ata_match(handle)) |
1683 | return true; | 1721 | return true; |
1684 | if (ACPI_FAILURE(acpi_get_parent(handle, &phandle))) | 1722 | if (ACPI_FAILURE(acpi_get_parent(handle, &phandle))) |
1685 | return false; | 1723 | return false; |
1686 | 1724 | ||
1687 | return acpi_ata_match(phandle); | 1725 | return acpi_ata_match(phandle); |
1688 | } | 1726 | } |
1689 | 1727 | ||
1690 | bool acpi_device_is_battery(struct acpi_device *adev) | 1728 | bool acpi_device_is_battery(struct acpi_device *adev) |
1691 | { | 1729 | { |
1692 | struct acpi_hardware_id *hwid; | 1730 | struct acpi_hardware_id *hwid; |
1693 | 1731 | ||
1694 | list_for_each_entry(hwid, &adev->pnp.ids, list) | 1732 | list_for_each_entry(hwid, &adev->pnp.ids, list) |
1695 | if (!strcmp("PNP0C0A", hwid->id)) | 1733 | if (!strcmp("PNP0C0A", hwid->id)) |
1696 | return true; | 1734 | return true; |
1697 | 1735 | ||
1698 | return false; | 1736 | return false; |
1699 | } | 1737 | } |
1700 | 1738 | ||
1701 | static bool is_ejectable_bay(struct acpi_device *adev) | 1739 | static bool is_ejectable_bay(struct acpi_device *adev) |
1702 | { | 1740 | { |
1703 | acpi_handle handle = adev->handle; | 1741 | acpi_handle handle = adev->handle; |
1704 | 1742 | ||
1705 | if (acpi_has_method(handle, "_EJ0") && acpi_device_is_battery(adev)) | 1743 | if (acpi_has_method(handle, "_EJ0") && acpi_device_is_battery(adev)) |
1706 | return true; | 1744 | return true; |
1707 | 1745 | ||
1708 | return acpi_bay_match(handle); | 1746 | return acpi_bay_match(handle); |
1709 | } | 1747 | } |
1710 | 1748 | ||
1711 | /* | 1749 | /* |
1712 | * acpi_dock_match - see if an acpi object has a _DCK method | 1750 | * acpi_dock_match - see if an acpi object has a _DCK method |
1713 | */ | 1751 | */ |
1714 | bool acpi_dock_match(acpi_handle handle) | 1752 | bool acpi_dock_match(acpi_handle handle) |
1715 | { | 1753 | { |
1716 | return acpi_has_method(handle, "_DCK"); | 1754 | return acpi_has_method(handle, "_DCK"); |
1717 | } | 1755 | } |
1718 | 1756 | ||
1719 | const char *acpi_device_hid(struct acpi_device *device) | 1757 | const char *acpi_device_hid(struct acpi_device *device) |
1720 | { | 1758 | { |
1721 | struct acpi_hardware_id *hid; | 1759 | struct acpi_hardware_id *hid; |
1722 | 1760 | ||
1723 | if (list_empty(&device->pnp.ids)) | 1761 | if (list_empty(&device->pnp.ids)) |
1724 | return dummy_hid; | 1762 | return dummy_hid; |
1725 | 1763 | ||
1726 | hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list); | 1764 | hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list); |
1727 | return hid->id; | 1765 | return hid->id; |
1728 | } | 1766 | } |
1729 | EXPORT_SYMBOL(acpi_device_hid); | 1767 | EXPORT_SYMBOL(acpi_device_hid); |
1730 | 1768 | ||
1731 | static void acpi_add_id(struct acpi_device_pnp *pnp, const char *dev_id) | 1769 | static void acpi_add_id(struct acpi_device_pnp *pnp, const char *dev_id) |
1732 | { | 1770 | { |
1733 | struct acpi_hardware_id *id; | 1771 | struct acpi_hardware_id *id; |
1734 | 1772 | ||
1735 | id = kmalloc(sizeof(*id), GFP_KERNEL); | 1773 | id = kmalloc(sizeof(*id), GFP_KERNEL); |
1736 | if (!id) | 1774 | if (!id) |
1737 | return; | 1775 | return; |
1738 | 1776 | ||
1739 | id->id = kstrdup(dev_id, GFP_KERNEL); | 1777 | id->id = kstrdup(dev_id, GFP_KERNEL); |
1740 | if (!id->id) { | 1778 | if (!id->id) { |
1741 | kfree(id); | 1779 | kfree(id); |
1742 | return; | 1780 | return; |
1743 | } | 1781 | } |
1744 | 1782 | ||
1745 | list_add_tail(&id->list, &pnp->ids); | 1783 | list_add_tail(&id->list, &pnp->ids); |
1746 | pnp->type.hardware_id = 1; | 1784 | pnp->type.hardware_id = 1; |
1747 | } | 1785 | } |
1748 | 1786 | ||
1749 | /* | 1787 | /* |
1750 | * Old IBM workstations have a DSDT bug wherein the SMBus object | 1788 | * Old IBM workstations have a DSDT bug wherein the SMBus object |
1751 | * lacks the SMBUS01 HID and the methods do not have the necessary "_" | 1789 | * lacks the SMBUS01 HID and the methods do not have the necessary "_" |
1752 | * prefix. Work around this. | 1790 | * prefix. Work around this. |
1753 | */ | 1791 | */ |
1754 | static bool acpi_ibm_smbus_match(acpi_handle handle) | 1792 | static bool acpi_ibm_smbus_match(acpi_handle handle) |
1755 | { | 1793 | { |
1756 | char node_name[ACPI_PATH_SEGMENT_LENGTH]; | 1794 | char node_name[ACPI_PATH_SEGMENT_LENGTH]; |
1757 | struct acpi_buffer path = { sizeof(node_name), node_name }; | 1795 | struct acpi_buffer path = { sizeof(node_name), node_name }; |
1758 | 1796 | ||
1759 | if (!dmi_name_in_vendors("IBM")) | 1797 | if (!dmi_name_in_vendors("IBM")) |
1760 | return false; | 1798 | return false; |
1761 | 1799 | ||
1762 | /* Look for SMBS object */ | 1800 | /* Look for SMBS object */ |
1763 | if (ACPI_FAILURE(acpi_get_name(handle, ACPI_SINGLE_NAME, &path)) || | 1801 | if (ACPI_FAILURE(acpi_get_name(handle, ACPI_SINGLE_NAME, &path)) || |
1764 | strcmp("SMBS", path.pointer)) | 1802 | strcmp("SMBS", path.pointer)) |
1765 | return false; | 1803 | return false; |
1766 | 1804 | ||
1767 | /* Does it have the necessary (but misnamed) methods? */ | 1805 | /* Does it have the necessary (but misnamed) methods? */ |
1768 | if (acpi_has_method(handle, "SBI") && | 1806 | if (acpi_has_method(handle, "SBI") && |
1769 | acpi_has_method(handle, "SBR") && | 1807 | acpi_has_method(handle, "SBR") && |
1770 | acpi_has_method(handle, "SBW")) | 1808 | acpi_has_method(handle, "SBW")) |
1771 | return true; | 1809 | return true; |
1772 | 1810 | ||
1773 | return false; | 1811 | return false; |
1774 | } | 1812 | } |
1775 | 1813 | ||
1776 | static bool acpi_object_is_system_bus(acpi_handle handle) | 1814 | static bool acpi_object_is_system_bus(acpi_handle handle) |
1777 | { | 1815 | { |
1778 | acpi_handle tmp; | 1816 | acpi_handle tmp; |
1779 | 1817 | ||
1780 | if (ACPI_SUCCESS(acpi_get_handle(NULL, "\\_SB", &tmp)) && | 1818 | if (ACPI_SUCCESS(acpi_get_handle(NULL, "\\_SB", &tmp)) && |
1781 | tmp == handle) | 1819 | tmp == handle) |
1782 | return true; | 1820 | return true; |
1783 | if (ACPI_SUCCESS(acpi_get_handle(NULL, "\\_TZ", &tmp)) && | 1821 | if (ACPI_SUCCESS(acpi_get_handle(NULL, "\\_TZ", &tmp)) && |
1784 | tmp == handle) | 1822 | tmp == handle) |
1785 | return true; | 1823 | return true; |
1786 | 1824 | ||
1787 | return false; | 1825 | return false; |
1788 | } | 1826 | } |
1789 | 1827 | ||
1790 | static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, | 1828 | static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, |
1791 | int device_type) | 1829 | int device_type) |
1792 | { | 1830 | { |
1793 | acpi_status status; | 1831 | acpi_status status; |
1794 | struct acpi_device_info *info; | 1832 | struct acpi_device_info *info; |
1795 | struct acpi_pnp_device_id_list *cid_list; | 1833 | struct acpi_pnp_device_id_list *cid_list; |
1796 | int i; | 1834 | int i; |
1797 | 1835 | ||
1798 | switch (device_type) { | 1836 | switch (device_type) { |
1799 | case ACPI_BUS_TYPE_DEVICE: | 1837 | case ACPI_BUS_TYPE_DEVICE: |
1800 | if (handle == ACPI_ROOT_OBJECT) { | 1838 | if (handle == ACPI_ROOT_OBJECT) { |
1801 | acpi_add_id(pnp, ACPI_SYSTEM_HID); | 1839 | acpi_add_id(pnp, ACPI_SYSTEM_HID); |
1802 | break; | 1840 | break; |
1803 | } | 1841 | } |
1804 | 1842 | ||
1805 | status = acpi_get_object_info(handle, &info); | 1843 | status = acpi_get_object_info(handle, &info); |
1806 | if (ACPI_FAILURE(status)) { | 1844 | if (ACPI_FAILURE(status)) { |
1807 | pr_err(PREFIX "%s: Error reading device info\n", | 1845 | pr_err(PREFIX "%s: Error reading device info\n", |
1808 | __func__); | 1846 | __func__); |
1809 | return; | 1847 | return; |
1810 | } | 1848 | } |
1811 | 1849 | ||
1812 | if (info->valid & ACPI_VALID_HID) { | 1850 | if (info->valid & ACPI_VALID_HID) { |
1813 | acpi_add_id(pnp, info->hardware_id.string); | 1851 | acpi_add_id(pnp, info->hardware_id.string); |
1814 | pnp->type.platform_id = 1; | 1852 | pnp->type.platform_id = 1; |
1815 | } | 1853 | } |
1816 | if (info->valid & ACPI_VALID_CID) { | 1854 | if (info->valid & ACPI_VALID_CID) { |
1817 | cid_list = &info->compatible_id_list; | 1855 | cid_list = &info->compatible_id_list; |
1818 | for (i = 0; i < cid_list->count; i++) | 1856 | for (i = 0; i < cid_list->count; i++) |
1819 | acpi_add_id(pnp, cid_list->ids[i].string); | 1857 | acpi_add_id(pnp, cid_list->ids[i].string); |
1820 | } | 1858 | } |
1821 | if (info->valid & ACPI_VALID_ADR) { | 1859 | if (info->valid & ACPI_VALID_ADR) { |
1822 | pnp->bus_address = info->address; | 1860 | pnp->bus_address = info->address; |
1823 | pnp->type.bus_address = 1; | 1861 | pnp->type.bus_address = 1; |
1824 | } | 1862 | } |
1825 | if (info->valid & ACPI_VALID_UID) | 1863 | if (info->valid & ACPI_VALID_UID) |
1826 | pnp->unique_id = kstrdup(info->unique_id.string, | 1864 | pnp->unique_id = kstrdup(info->unique_id.string, |
1827 | GFP_KERNEL); | 1865 | GFP_KERNEL); |
1828 | 1866 | ||
1829 | kfree(info); | 1867 | kfree(info); |
1830 | 1868 | ||
1831 | /* | 1869 | /* |
1832 | * Some devices don't reliably have _HIDs & _CIDs, so add | 1870 | * Some devices don't reliably have _HIDs & _CIDs, so add |
1833 | * synthetic HIDs to make sure drivers can find them. | 1871 | * synthetic HIDs to make sure drivers can find them. |
1834 | */ | 1872 | */ |
1835 | if (acpi_is_video_device(handle)) | 1873 | if (acpi_is_video_device(handle)) |
1836 | acpi_add_id(pnp, ACPI_VIDEO_HID); | 1874 | acpi_add_id(pnp, ACPI_VIDEO_HID); |
1837 | else if (acpi_bay_match(handle)) | 1875 | else if (acpi_bay_match(handle)) |
1838 | acpi_add_id(pnp, ACPI_BAY_HID); | 1876 | acpi_add_id(pnp, ACPI_BAY_HID); |
1839 | else if (acpi_dock_match(handle)) | 1877 | else if (acpi_dock_match(handle)) |
1840 | acpi_add_id(pnp, ACPI_DOCK_HID); | 1878 | acpi_add_id(pnp, ACPI_DOCK_HID); |
1841 | else if (acpi_ibm_smbus_match(handle)) | 1879 | else if (acpi_ibm_smbus_match(handle)) |
1842 | acpi_add_id(pnp, ACPI_SMBUS_IBM_HID); | 1880 | acpi_add_id(pnp, ACPI_SMBUS_IBM_HID); |
1843 | else if (list_empty(&pnp->ids) && | 1881 | else if (list_empty(&pnp->ids) && |
1844 | acpi_object_is_system_bus(handle)) { | 1882 | acpi_object_is_system_bus(handle)) { |
1845 | /* \_SB, \_TZ, LNXSYBUS */ | 1883 | /* \_SB, \_TZ, LNXSYBUS */ |
1846 | acpi_add_id(pnp, ACPI_BUS_HID); | 1884 | acpi_add_id(pnp, ACPI_BUS_HID); |
1847 | strcpy(pnp->device_name, ACPI_BUS_DEVICE_NAME); | 1885 | strcpy(pnp->device_name, ACPI_BUS_DEVICE_NAME); |
1848 | strcpy(pnp->device_class, ACPI_BUS_CLASS); | 1886 | strcpy(pnp->device_class, ACPI_BUS_CLASS); |
1849 | } | 1887 | } |
1850 | 1888 | ||
1851 | break; | 1889 | break; |
1852 | case ACPI_BUS_TYPE_POWER: | 1890 | case ACPI_BUS_TYPE_POWER: |
1853 | acpi_add_id(pnp, ACPI_POWER_HID); | 1891 | acpi_add_id(pnp, ACPI_POWER_HID); |
1854 | break; | 1892 | break; |
1855 | case ACPI_BUS_TYPE_PROCESSOR: | 1893 | case ACPI_BUS_TYPE_PROCESSOR: |
1856 | acpi_add_id(pnp, ACPI_PROCESSOR_OBJECT_HID); | 1894 | acpi_add_id(pnp, ACPI_PROCESSOR_OBJECT_HID); |
1857 | break; | 1895 | break; |
1858 | case ACPI_BUS_TYPE_THERMAL: | 1896 | case ACPI_BUS_TYPE_THERMAL: |
1859 | acpi_add_id(pnp, ACPI_THERMAL_HID); | 1897 | acpi_add_id(pnp, ACPI_THERMAL_HID); |
1860 | break; | 1898 | break; |
1861 | case ACPI_BUS_TYPE_POWER_BUTTON: | 1899 | case ACPI_BUS_TYPE_POWER_BUTTON: |
1862 | acpi_add_id(pnp, ACPI_BUTTON_HID_POWERF); | 1900 | acpi_add_id(pnp, ACPI_BUTTON_HID_POWERF); |
1863 | break; | 1901 | break; |
1864 | case ACPI_BUS_TYPE_SLEEP_BUTTON: | 1902 | case ACPI_BUS_TYPE_SLEEP_BUTTON: |
1865 | acpi_add_id(pnp, ACPI_BUTTON_HID_SLEEPF); | 1903 | acpi_add_id(pnp, ACPI_BUTTON_HID_SLEEPF); |
1866 | break; | 1904 | break; |
1867 | } | 1905 | } |
1868 | } | 1906 | } |
1869 | 1907 | ||
1870 | void acpi_free_pnp_ids(struct acpi_device_pnp *pnp) | 1908 | void acpi_free_pnp_ids(struct acpi_device_pnp *pnp) |
1871 | { | 1909 | { |
1872 | struct acpi_hardware_id *id, *tmp; | 1910 | struct acpi_hardware_id *id, *tmp; |
1873 | 1911 | ||
1874 | list_for_each_entry_safe(id, tmp, &pnp->ids, list) { | 1912 | list_for_each_entry_safe(id, tmp, &pnp->ids, list) { |
1875 | kfree(id->id); | 1913 | kfree(id->id); |
1876 | kfree(id); | 1914 | kfree(id); |
1877 | } | 1915 | } |
1878 | kfree(pnp->unique_id); | 1916 | kfree(pnp->unique_id); |
1879 | } | 1917 | } |
1880 | 1918 | ||
1881 | void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, | 1919 | void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, |
1882 | int type, unsigned long long sta) | 1920 | int type, unsigned long long sta) |
1883 | { | 1921 | { |
1884 | INIT_LIST_HEAD(&device->pnp.ids); | 1922 | INIT_LIST_HEAD(&device->pnp.ids); |
1885 | device->device_type = type; | 1923 | device->device_type = type; |
1886 | device->handle = handle; | 1924 | device->handle = handle; |
1887 | device->parent = acpi_bus_get_parent(handle); | 1925 | device->parent = acpi_bus_get_parent(handle); |
1888 | acpi_set_device_status(device, sta); | 1926 | acpi_set_device_status(device, sta); |
1889 | acpi_device_get_busid(device); | 1927 | acpi_device_get_busid(device); |
1890 | acpi_set_pnp_ids(handle, &device->pnp, type); | 1928 | acpi_set_pnp_ids(handle, &device->pnp, type); |
1891 | acpi_bus_get_flags(device); | 1929 | acpi_bus_get_flags(device); |
1892 | device->flags.match_driver = false; | 1930 | device->flags.match_driver = false; |
1893 | device->flags.initialized = true; | 1931 | device->flags.initialized = true; |
1894 | device->flags.visited = false; | 1932 | device->flags.visited = false; |
1895 | device_initialize(&device->dev); | 1933 | device_initialize(&device->dev); |
1896 | dev_set_uevent_suppress(&device->dev, true); | 1934 | dev_set_uevent_suppress(&device->dev, true); |
1897 | } | 1935 | } |
1898 | 1936 | ||
1899 | void acpi_device_add_finalize(struct acpi_device *device) | 1937 | void acpi_device_add_finalize(struct acpi_device *device) |
1900 | { | 1938 | { |
1901 | dev_set_uevent_suppress(&device->dev, false); | 1939 | dev_set_uevent_suppress(&device->dev, false); |
1902 | kobject_uevent(&device->dev.kobj, KOBJ_ADD); | 1940 | kobject_uevent(&device->dev.kobj, KOBJ_ADD); |
1903 | } | 1941 | } |
1904 | 1942 | ||
1905 | static int acpi_add_single_object(struct acpi_device **child, | 1943 | static int acpi_add_single_object(struct acpi_device **child, |
1906 | acpi_handle handle, int type, | 1944 | acpi_handle handle, int type, |
1907 | unsigned long long sta) | 1945 | unsigned long long sta) |
1908 | { | 1946 | { |
1909 | int result; | 1947 | int result; |
1910 | struct acpi_device *device; | 1948 | struct acpi_device *device; |
1911 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 1949 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
1912 | 1950 | ||
1913 | device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL); | 1951 | device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL); |
1914 | if (!device) { | 1952 | if (!device) { |
1915 | printk(KERN_ERR PREFIX "Memory allocation error\n"); | 1953 | printk(KERN_ERR PREFIX "Memory allocation error\n"); |
1916 | return -ENOMEM; | 1954 | return -ENOMEM; |
1917 | } | 1955 | } |
1918 | 1956 | ||
1919 | acpi_init_device_object(device, handle, type, sta); | 1957 | acpi_init_device_object(device, handle, type, sta); |
1920 | acpi_bus_get_power_flags(device); | 1958 | acpi_bus_get_power_flags(device); |
1921 | acpi_bus_get_wakeup_device_flags(device); | 1959 | acpi_bus_get_wakeup_device_flags(device); |
1922 | 1960 | ||
1923 | result = acpi_device_add(device, acpi_device_release); | 1961 | result = acpi_device_add(device, acpi_device_release); |
1924 | if (result) { | 1962 | if (result) { |
1925 | acpi_device_release(&device->dev); | 1963 | acpi_device_release(&device->dev); |
1926 | return result; | 1964 | return result; |
1927 | } | 1965 | } |
1928 | 1966 | ||
1929 | acpi_power_add_remove_device(device, true); | 1967 | acpi_power_add_remove_device(device, true); |
1930 | acpi_device_add_finalize(device); | 1968 | acpi_device_add_finalize(device); |
1931 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | 1969 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); |
1932 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Added %s [%s] parent %s\n", | 1970 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Added %s [%s] parent %s\n", |
1933 | dev_name(&device->dev), (char *) buffer.pointer, | 1971 | dev_name(&device->dev), (char *) buffer.pointer, |
1934 | device->parent ? dev_name(&device->parent->dev) : "(null)")); | 1972 | device->parent ? dev_name(&device->parent->dev) : "(null)")); |
1935 | kfree(buffer.pointer); | 1973 | kfree(buffer.pointer); |
1936 | *child = device; | 1974 | *child = device; |
1937 | return 0; | 1975 | return 0; |
1938 | } | 1976 | } |
1939 | 1977 | ||
1940 | static int acpi_bus_type_and_status(acpi_handle handle, int *type, | 1978 | static int acpi_bus_type_and_status(acpi_handle handle, int *type, |
1941 | unsigned long long *sta) | 1979 | unsigned long long *sta) |
1942 | { | 1980 | { |
1943 | acpi_status status; | 1981 | acpi_status status; |
1944 | acpi_object_type acpi_type; | 1982 | acpi_object_type acpi_type; |
1945 | 1983 | ||
1946 | status = acpi_get_type(handle, &acpi_type); | 1984 | status = acpi_get_type(handle, &acpi_type); |
1947 | if (ACPI_FAILURE(status)) | 1985 | if (ACPI_FAILURE(status)) |
1948 | return -ENODEV; | 1986 | return -ENODEV; |
1949 | 1987 | ||
1950 | switch (acpi_type) { | 1988 | switch (acpi_type) { |
1951 | case ACPI_TYPE_ANY: /* for ACPI_ROOT_OBJECT */ | 1989 | case ACPI_TYPE_ANY: /* for ACPI_ROOT_OBJECT */ |
1952 | case ACPI_TYPE_DEVICE: | 1990 | case ACPI_TYPE_DEVICE: |
1953 | *type = ACPI_BUS_TYPE_DEVICE; | 1991 | *type = ACPI_BUS_TYPE_DEVICE; |
1954 | status = acpi_bus_get_status_handle(handle, sta); | 1992 | status = acpi_bus_get_status_handle(handle, sta); |
1955 | if (ACPI_FAILURE(status)) | 1993 | if (ACPI_FAILURE(status)) |
1956 | return -ENODEV; | 1994 | return -ENODEV; |
1957 | break; | 1995 | break; |
1958 | case ACPI_TYPE_PROCESSOR: | 1996 | case ACPI_TYPE_PROCESSOR: |
1959 | *type = ACPI_BUS_TYPE_PROCESSOR; | 1997 | *type = ACPI_BUS_TYPE_PROCESSOR; |
1960 | status = acpi_bus_get_status_handle(handle, sta); | 1998 | status = acpi_bus_get_status_handle(handle, sta); |
1961 | if (ACPI_FAILURE(status)) | 1999 | if (ACPI_FAILURE(status)) |
1962 | return -ENODEV; | 2000 | return -ENODEV; |
1963 | break; | 2001 | break; |
1964 | case ACPI_TYPE_THERMAL: | 2002 | case ACPI_TYPE_THERMAL: |
1965 | *type = ACPI_BUS_TYPE_THERMAL; | 2003 | *type = ACPI_BUS_TYPE_THERMAL; |
1966 | *sta = ACPI_STA_DEFAULT; | 2004 | *sta = ACPI_STA_DEFAULT; |
1967 | break; | 2005 | break; |
1968 | case ACPI_TYPE_POWER: | 2006 | case ACPI_TYPE_POWER: |
1969 | *type = ACPI_BUS_TYPE_POWER; | 2007 | *type = ACPI_BUS_TYPE_POWER; |
1970 | *sta = ACPI_STA_DEFAULT; | 2008 | *sta = ACPI_STA_DEFAULT; |
1971 | break; | 2009 | break; |
1972 | default: | 2010 | default: |
1973 | return -ENODEV; | 2011 | return -ENODEV; |
1974 | } | 2012 | } |
1975 | 2013 | ||
1976 | return 0; | 2014 | return 0; |
1977 | } | 2015 | } |
1978 | 2016 | ||
1979 | bool acpi_device_is_present(struct acpi_device *adev) | 2017 | bool acpi_device_is_present(struct acpi_device *adev) |
1980 | { | 2018 | { |
1981 | if (adev->status.present || adev->status.functional) | 2019 | if (adev->status.present || adev->status.functional) |
1982 | return true; | 2020 | return true; |
1983 | 2021 | ||
1984 | adev->flags.initialized = false; | 2022 | adev->flags.initialized = false; |
1985 | return false; | 2023 | return false; |
1986 | } | 2024 | } |
1987 | 2025 | ||
1988 | static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler, | 2026 | static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler, |
1989 | char *idstr, | 2027 | char *idstr, |
1990 | const struct acpi_device_id **matchid) | 2028 | const struct acpi_device_id **matchid) |
1991 | { | 2029 | { |
1992 | const struct acpi_device_id *devid; | 2030 | const struct acpi_device_id *devid; |
1993 | 2031 | ||
1994 | if (handler->match) | 2032 | if (handler->match) |
1995 | return handler->match(idstr, matchid); | 2033 | return handler->match(idstr, matchid); |
1996 | 2034 | ||
1997 | for (devid = handler->ids; devid->id[0]; devid++) | 2035 | for (devid = handler->ids; devid->id[0]; devid++) |
1998 | if (!strcmp((char *)devid->id, idstr)) { | 2036 | if (!strcmp((char *)devid->id, idstr)) { |
1999 | if (matchid) | 2037 | if (matchid) |
2000 | *matchid = devid; | 2038 | *matchid = devid; |
2001 | 2039 | ||
2002 | return true; | 2040 | return true; |
2003 | } | 2041 | } |
2004 | 2042 | ||
2005 | return false; | 2043 | return false; |
2006 | } | 2044 | } |
2007 | 2045 | ||
2008 | static struct acpi_scan_handler *acpi_scan_match_handler(char *idstr, | 2046 | static struct acpi_scan_handler *acpi_scan_match_handler(char *idstr, |
2009 | const struct acpi_device_id **matchid) | 2047 | const struct acpi_device_id **matchid) |
2010 | { | 2048 | { |
2011 | struct acpi_scan_handler *handler; | 2049 | struct acpi_scan_handler *handler; |
2012 | 2050 | ||
2013 | list_for_each_entry(handler, &acpi_scan_handlers_list, list_node) | 2051 | list_for_each_entry(handler, &acpi_scan_handlers_list, list_node) |
2014 | if (acpi_scan_handler_matching(handler, idstr, matchid)) | 2052 | if (acpi_scan_handler_matching(handler, idstr, matchid)) |
2015 | return handler; | 2053 | return handler; |
2016 | 2054 | ||
2017 | return NULL; | 2055 | return NULL; |
2018 | } | 2056 | } |
2019 | 2057 | ||
2020 | void acpi_scan_hotplug_enabled(struct acpi_hotplug_profile *hotplug, bool val) | 2058 | void acpi_scan_hotplug_enabled(struct acpi_hotplug_profile *hotplug, bool val) |
2021 | { | 2059 | { |
2022 | if (!!hotplug->enabled == !!val) | 2060 | if (!!hotplug->enabled == !!val) |
2023 | return; | 2061 | return; |
2024 | 2062 | ||
2025 | mutex_lock(&acpi_scan_lock); | 2063 | mutex_lock(&acpi_scan_lock); |
2026 | 2064 | ||
2027 | hotplug->enabled = val; | 2065 | hotplug->enabled = val; |
2028 | 2066 | ||
2029 | mutex_unlock(&acpi_scan_lock); | 2067 | mutex_unlock(&acpi_scan_lock); |
2030 | } | 2068 | } |
2031 | 2069 | ||
2032 | static void acpi_scan_init_hotplug(struct acpi_device *adev) | 2070 | static void acpi_scan_init_hotplug(struct acpi_device *adev) |
2033 | { | 2071 | { |
2034 | struct acpi_hardware_id *hwid; | 2072 | struct acpi_hardware_id *hwid; |
2035 | 2073 | ||
2036 | if (acpi_dock_match(adev->handle) || is_ejectable_bay(adev)) { | 2074 | if (acpi_dock_match(adev->handle) || is_ejectable_bay(adev)) { |
2037 | acpi_dock_add(adev); | 2075 | acpi_dock_add(adev); |
2038 | return; | 2076 | return; |
2039 | } | 2077 | } |
2040 | list_for_each_entry(hwid, &adev->pnp.ids, list) { | 2078 | list_for_each_entry(hwid, &adev->pnp.ids, list) { |
2041 | struct acpi_scan_handler *handler; | 2079 | struct acpi_scan_handler *handler; |
2042 | 2080 | ||
2043 | handler = acpi_scan_match_handler(hwid->id, NULL); | 2081 | handler = acpi_scan_match_handler(hwid->id, NULL); |
2044 | if (handler) { | 2082 | if (handler) { |
2045 | adev->flags.hotplug_notify = true; | 2083 | adev->flags.hotplug_notify = true; |
2046 | break; | 2084 | break; |
2047 | } | 2085 | } |
2048 | } | 2086 | } |
2049 | } | 2087 | } |
2050 | 2088 | ||
2051 | static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, | 2089 | static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, |
2052 | void *not_used, void **return_value) | 2090 | void *not_used, void **return_value) |
2053 | { | 2091 | { |
2054 | struct acpi_device *device = NULL; | 2092 | struct acpi_device *device = NULL; |
2055 | int type; | 2093 | int type; |
2056 | unsigned long long sta; | 2094 | unsigned long long sta; |
2057 | int result; | 2095 | int result; |
2058 | 2096 | ||
2059 | acpi_bus_get_device(handle, &device); | 2097 | acpi_bus_get_device(handle, &device); |
2060 | if (device) | 2098 | if (device) |
2061 | goto out; | 2099 | goto out; |
2062 | 2100 | ||
2063 | result = acpi_bus_type_and_status(handle, &type, &sta); | 2101 | result = acpi_bus_type_and_status(handle, &type, &sta); |
2064 | if (result) | 2102 | if (result) |
2065 | return AE_OK; | 2103 | return AE_OK; |
2066 | 2104 | ||
2067 | if (type == ACPI_BUS_TYPE_POWER) { | 2105 | if (type == ACPI_BUS_TYPE_POWER) { |
2068 | acpi_add_power_resource(handle); | 2106 | acpi_add_power_resource(handle); |
2069 | return AE_OK; | 2107 | return AE_OK; |
2070 | } | 2108 | } |
2071 | 2109 | ||
2072 | acpi_add_single_object(&device, handle, type, sta); | 2110 | acpi_add_single_object(&device, handle, type, sta); |
2073 | if (!device) | 2111 | if (!device) |
2074 | return AE_CTRL_DEPTH; | 2112 | return AE_CTRL_DEPTH; |
2075 | 2113 | ||
2076 | acpi_scan_init_hotplug(device); | 2114 | acpi_scan_init_hotplug(device); |
2077 | 2115 | ||
2078 | out: | 2116 | out: |
2079 | if (!*return_value) | 2117 | if (!*return_value) |
2080 | *return_value = device; | 2118 | *return_value = device; |
2081 | 2119 | ||
2082 | return AE_OK; | 2120 | return AE_OK; |
2083 | } | 2121 | } |
2084 | 2122 | ||
2085 | static int acpi_check_spi_i2c_slave(struct acpi_resource *ares, void *data) | 2123 | static int acpi_check_spi_i2c_slave(struct acpi_resource *ares, void *data) |
2086 | { | 2124 | { |
2087 | bool *is_spi_i2c_slave_p = data; | 2125 | bool *is_spi_i2c_slave_p = data; |
2088 | 2126 | ||
2089 | if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) | 2127 | if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) |
2090 | return 1; | 2128 | return 1; |
2091 | 2129 | ||
2092 | /* | 2130 | /* |
2093 | * devices that are connected to UART still need to be enumerated to | 2131 | * devices that are connected to UART still need to be enumerated to |
2094 | * platform bus | 2132 | * platform bus |
2095 | */ | 2133 | */ |
2096 | if (ares->data.common_serial_bus.type != ACPI_RESOURCE_SERIAL_TYPE_UART) | 2134 | if (ares->data.common_serial_bus.type != ACPI_RESOURCE_SERIAL_TYPE_UART) |
2097 | *is_spi_i2c_slave_p = true; | 2135 | *is_spi_i2c_slave_p = true; |
2098 | 2136 | ||
2099 | /* no need to do more checking */ | 2137 | /* no need to do more checking */ |
2100 | return -1; | 2138 | return -1; |
2101 | } | 2139 | } |
2102 | 2140 | ||
2103 | static void acpi_default_enumeration(struct acpi_device *device) | 2141 | static void acpi_default_enumeration(struct acpi_device *device) |
2104 | { | 2142 | { |
2105 | struct list_head resource_list; | 2143 | struct list_head resource_list; |
2106 | bool is_spi_i2c_slave = false; | 2144 | bool is_spi_i2c_slave = false; |
2107 | 2145 | ||
2108 | if (!device->pnp.type.platform_id || device->handler) | 2146 | if (!device->pnp.type.platform_id || device->handler) |
2109 | return; | 2147 | return; |
2110 | 2148 | ||
2111 | /* | 2149 | /* |
2112 | * Do not enemerate SPI/I2C slaves as they will be enuerated by their | 2150 | * Do not enemerate SPI/I2C slaves as they will be enuerated by their |
2113 | * respective parents. | 2151 | * respective parents. |
2114 | */ | 2152 | */ |
2115 | INIT_LIST_HEAD(&resource_list); | 2153 | INIT_LIST_HEAD(&resource_list); |
2116 | acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave, | 2154 | acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave, |
2117 | &is_spi_i2c_slave); | 2155 | &is_spi_i2c_slave); |
2118 | acpi_dev_free_resource_list(&resource_list); | 2156 | acpi_dev_free_resource_list(&resource_list); |
2119 | if (!is_spi_i2c_slave) | 2157 | if (!is_spi_i2c_slave) |
2120 | acpi_create_platform_device(device); | 2158 | acpi_create_platform_device(device); |
2121 | } | 2159 | } |
2122 | 2160 | ||
2123 | static int acpi_scan_attach_handler(struct acpi_device *device) | 2161 | static int acpi_scan_attach_handler(struct acpi_device *device) |
2124 | { | 2162 | { |
2125 | struct acpi_hardware_id *hwid; | 2163 | struct acpi_hardware_id *hwid; |
2126 | int ret = 0; | 2164 | int ret = 0; |
2127 | 2165 | ||
2128 | list_for_each_entry(hwid, &device->pnp.ids, list) { | 2166 | list_for_each_entry(hwid, &device->pnp.ids, list) { |
2129 | const struct acpi_device_id *devid; | 2167 | const struct acpi_device_id *devid; |
2130 | struct acpi_scan_handler *handler; | 2168 | struct acpi_scan_handler *handler; |
2131 | 2169 | ||
2132 | handler = acpi_scan_match_handler(hwid->id, &devid); | 2170 | handler = acpi_scan_match_handler(hwid->id, &devid); |
2133 | if (handler) { | 2171 | if (handler) { |
2134 | if (!handler->attach) { | 2172 | if (!handler->attach) { |
2135 | device->pnp.type.platform_id = 0; | 2173 | device->pnp.type.platform_id = 0; |
2136 | continue; | 2174 | continue; |
2137 | } | 2175 | } |
2138 | device->handler = handler; | 2176 | device->handler = handler; |
2139 | ret = handler->attach(device, devid); | 2177 | ret = handler->attach(device, devid); |
2140 | if (ret > 0) | 2178 | if (ret > 0) |
2141 | break; | 2179 | break; |
2142 | 2180 | ||
2143 | device->handler = NULL; | 2181 | device->handler = NULL; |
2144 | if (ret < 0) | 2182 | if (ret < 0) |
2145 | break; | 2183 | break; |
2146 | } | 2184 | } |
2147 | } | 2185 | } |
2148 | if (!ret) | 2186 | if (!ret) |
2149 | acpi_default_enumeration(device); | 2187 | acpi_default_enumeration(device); |
2150 | 2188 | ||
2151 | return ret; | 2189 | return ret; |
2152 | } | 2190 | } |
2153 | 2191 | ||
2154 | static void acpi_bus_attach(struct acpi_device *device) | 2192 | static void acpi_bus_attach(struct acpi_device *device) |
2155 | { | 2193 | { |
2156 | struct acpi_device *child; | 2194 | struct acpi_device *child; |
2157 | acpi_handle ejd; | 2195 | acpi_handle ejd; |
2158 | int ret; | 2196 | int ret; |
2159 | 2197 | ||
2160 | if (ACPI_SUCCESS(acpi_bus_get_ejd(device->handle, &ejd))) | 2198 | if (ACPI_SUCCESS(acpi_bus_get_ejd(device->handle, &ejd))) |
2161 | register_dock_dependent_device(device, ejd); | 2199 | register_dock_dependent_device(device, ejd); |
2162 | 2200 | ||
2163 | acpi_bus_get_status(device); | 2201 | acpi_bus_get_status(device); |
2164 | /* Skip devices that are not present. */ | 2202 | /* Skip devices that are not present. */ |
2165 | if (!acpi_device_is_present(device)) { | 2203 | if (!acpi_device_is_present(device)) { |
2166 | device->flags.visited = false; | 2204 | device->flags.visited = false; |
2167 | return; | 2205 | return; |
2168 | } | 2206 | } |
2169 | if (device->handler) | 2207 | if (device->handler) |
2170 | goto ok; | 2208 | goto ok; |
2171 | 2209 | ||
2172 | if (!device->flags.initialized) { | 2210 | if (!device->flags.initialized) { |
2173 | acpi_bus_update_power(device, NULL); | 2211 | acpi_bus_update_power(device, NULL); |
2174 | device->flags.initialized = true; | 2212 | device->flags.initialized = true; |
2175 | } | 2213 | } |
2176 | device->flags.visited = false; | 2214 | device->flags.visited = false; |
2177 | ret = acpi_scan_attach_handler(device); | 2215 | ret = acpi_scan_attach_handler(device); |
2178 | if (ret < 0) | 2216 | if (ret < 0) |
2179 | return; | 2217 | return; |
2180 | 2218 | ||
2181 | device->flags.match_driver = true; | 2219 | device->flags.match_driver = true; |
2182 | if (!ret) { | 2220 | if (!ret) { |
2183 | ret = device_attach(&device->dev); | 2221 | ret = device_attach(&device->dev); |
2184 | if (ret < 0) | 2222 | if (ret < 0) |
2185 | return; | 2223 | return; |
2186 | } | 2224 | } |
2187 | device->flags.visited = true; | 2225 | device->flags.visited = true; |
2188 | 2226 | ||
2189 | ok: | 2227 | ok: |
2190 | list_for_each_entry(child, &device->children, node) | 2228 | list_for_each_entry(child, &device->children, node) |
2191 | acpi_bus_attach(child); | 2229 | acpi_bus_attach(child); |
2192 | 2230 | ||
2193 | if (device->handler && device->handler->hotplug.notify_online) | 2231 | if (device->handler && device->handler->hotplug.notify_online) |
2194 | device->handler->hotplug.notify_online(device); | 2232 | device->handler->hotplug.notify_online(device); |
2195 | } | 2233 | } |
2196 | 2234 | ||
2197 | /** | 2235 | /** |
2198 | * acpi_bus_scan - Add ACPI device node objects in a given namespace scope. | 2236 | * acpi_bus_scan - Add ACPI device node objects in a given namespace scope. |
2199 | * @handle: Root of the namespace scope to scan. | 2237 | * @handle: Root of the namespace scope to scan. |
2200 | * | 2238 | * |
2201 | * Scan a given ACPI tree (probably recently hot-plugged) and create and add | 2239 | * Scan a given ACPI tree (probably recently hot-plugged) and create and add |
2202 | * found devices. | 2240 | * found devices. |
2203 | * | 2241 | * |
2204 | * If no devices were found, -ENODEV is returned, but it does not mean that | 2242 | * If no devices were found, -ENODEV is returned, but it does not mean that |
2205 | * there has been a real error. There just have been no suitable ACPI objects | 2243 | * there has been a real error. There just have been no suitable ACPI objects |
2206 | * in the table trunk from which the kernel could create a device and add an | 2244 | * in the table trunk from which the kernel could create a device and add an |
2207 | * appropriate driver. | 2245 | * appropriate driver. |
2208 | * | 2246 | * |
2209 | * Must be called under acpi_scan_lock. | 2247 | * Must be called under acpi_scan_lock. |
2210 | */ | 2248 | */ |
2211 | int acpi_bus_scan(acpi_handle handle) | 2249 | int acpi_bus_scan(acpi_handle handle) |
2212 | { | 2250 | { |
2213 | void *device = NULL; | 2251 | void *device = NULL; |
2214 | 2252 | ||
2215 | if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device))) | 2253 | if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device))) |
2216 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | 2254 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, |
2217 | acpi_bus_check_add, NULL, NULL, &device); | 2255 | acpi_bus_check_add, NULL, NULL, &device); |
2218 | 2256 | ||
2219 | if (device) { | 2257 | if (device) { |
2220 | acpi_bus_attach(device); | 2258 | acpi_bus_attach(device); |
2221 | return 0; | 2259 | return 0; |
2222 | } | 2260 | } |
2223 | return -ENODEV; | 2261 | return -ENODEV; |
2224 | } | 2262 | } |
2225 | EXPORT_SYMBOL(acpi_bus_scan); | 2263 | EXPORT_SYMBOL(acpi_bus_scan); |
2226 | 2264 | ||
2227 | /** | 2265 | /** |
2228 | * acpi_bus_trim - Detach scan handlers and drivers from ACPI device objects. | 2266 | * acpi_bus_trim - Detach scan handlers and drivers from ACPI device objects. |
2229 | * @adev: Root of the ACPI namespace scope to walk. | 2267 | * @adev: Root of the ACPI namespace scope to walk. |
2230 | * | 2268 | * |
2231 | * Must be called under acpi_scan_lock. | 2269 | * Must be called under acpi_scan_lock. |
2232 | */ | 2270 | */ |
2233 | void acpi_bus_trim(struct acpi_device *adev) | 2271 | void acpi_bus_trim(struct acpi_device *adev) |
2234 | { | 2272 | { |
2235 | struct acpi_scan_handler *handler = adev->handler; | 2273 | struct acpi_scan_handler *handler = adev->handler; |
2236 | struct acpi_device *child; | 2274 | struct acpi_device *child; |
2237 | 2275 | ||
2238 | list_for_each_entry_reverse(child, &adev->children, node) | 2276 | list_for_each_entry_reverse(child, &adev->children, node) |
2239 | acpi_bus_trim(child); | 2277 | acpi_bus_trim(child); |
2240 | 2278 | ||
2241 | adev->flags.match_driver = false; | 2279 | adev->flags.match_driver = false; |
2242 | if (handler) { | 2280 | if (handler) { |
2243 | if (handler->detach) | 2281 | if (handler->detach) |
2244 | handler->detach(adev); | 2282 | handler->detach(adev); |
2245 | 2283 | ||
2246 | adev->handler = NULL; | 2284 | adev->handler = NULL; |
2247 | } else { | 2285 | } else { |
2248 | device_release_driver(&adev->dev); | 2286 | device_release_driver(&adev->dev); |
2249 | } | 2287 | } |
2250 | /* | 2288 | /* |
2251 | * Most likely, the device is going away, so put it into D3cold before | 2289 | * Most likely, the device is going away, so put it into D3cold before |
2252 | * that. | 2290 | * that. |
2253 | */ | 2291 | */ |
2254 | acpi_device_set_power(adev, ACPI_STATE_D3_COLD); | 2292 | acpi_device_set_power(adev, ACPI_STATE_D3_COLD); |
2255 | adev->flags.initialized = false; | 2293 | adev->flags.initialized = false; |
2256 | adev->flags.visited = false; | 2294 | adev->flags.visited = false; |
2257 | } | 2295 | } |
2258 | EXPORT_SYMBOL_GPL(acpi_bus_trim); | 2296 | EXPORT_SYMBOL_GPL(acpi_bus_trim); |
2259 | 2297 | ||
2260 | static int acpi_bus_scan_fixed(void) | 2298 | static int acpi_bus_scan_fixed(void) |
2261 | { | 2299 | { |
2262 | int result = 0; | 2300 | int result = 0; |
2263 | 2301 | ||
2264 | /* | 2302 | /* |
2265 | * Enumerate all fixed-feature devices. | 2303 | * Enumerate all fixed-feature devices. |
2266 | */ | 2304 | */ |
2267 | if (!(acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON)) { | 2305 | if (!(acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON)) { |
2268 | struct acpi_device *device = NULL; | 2306 | struct acpi_device *device = NULL; |
2269 | 2307 | ||
2270 | result = acpi_add_single_object(&device, NULL, | 2308 | result = acpi_add_single_object(&device, NULL, |
2271 | ACPI_BUS_TYPE_POWER_BUTTON, | 2309 | ACPI_BUS_TYPE_POWER_BUTTON, |
2272 | ACPI_STA_DEFAULT); | 2310 | ACPI_STA_DEFAULT); |
2273 | if (result) | 2311 | if (result) |
2274 | return result; | 2312 | return result; |
2275 | 2313 | ||
2276 | device->flags.match_driver = true; | 2314 | device->flags.match_driver = true; |
2277 | result = device_attach(&device->dev); | 2315 | result = device_attach(&device->dev); |
2278 | if (result < 0) | 2316 | if (result < 0) |
2279 | return result; | 2317 | return result; |
2280 | 2318 | ||
2281 | device_init_wakeup(&device->dev, true); | 2319 | device_init_wakeup(&device->dev, true); |
2282 | } | 2320 | } |
2283 | 2321 | ||
2284 | if (!(acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON)) { | 2322 | if (!(acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON)) { |
2285 | struct acpi_device *device = NULL; | 2323 | struct acpi_device *device = NULL; |
2286 | 2324 | ||
2287 | result = acpi_add_single_object(&device, NULL, | 2325 | result = acpi_add_single_object(&device, NULL, |
2288 | ACPI_BUS_TYPE_SLEEP_BUTTON, | 2326 | ACPI_BUS_TYPE_SLEEP_BUTTON, |
2289 | ACPI_STA_DEFAULT); | 2327 | ACPI_STA_DEFAULT); |
2290 | if (result) | 2328 | if (result) |
2291 | return result; | 2329 | return result; |
2292 | 2330 | ||
2293 | device->flags.match_driver = true; | 2331 | device->flags.match_driver = true; |
2294 | result = device_attach(&device->dev); | 2332 | result = device_attach(&device->dev); |
2295 | } | 2333 | } |
2296 | 2334 | ||
2297 | return result < 0 ? result : 0; | 2335 | return result < 0 ? result : 0; |
2298 | } | 2336 | } |
2299 | 2337 | ||
2300 | int __init acpi_scan_init(void) | 2338 | int __init acpi_scan_init(void) |
2301 | { | 2339 | { |
2302 | int result; | 2340 | int result; |
2303 | 2341 | ||
2304 | result = bus_register(&acpi_bus_type); | 2342 | result = bus_register(&acpi_bus_type); |
2305 | if (result) { | 2343 | if (result) { |
2306 | /* We don't want to quit even if we failed to add suspend/resume */ | 2344 | /* We don't want to quit even if we failed to add suspend/resume */ |
2307 | printk(KERN_ERR PREFIX "Could not register bus type\n"); | 2345 | printk(KERN_ERR PREFIX "Could not register bus type\n"); |
2308 | } | 2346 | } |
2309 | 2347 | ||
2310 | acpi_pci_root_init(); | 2348 | acpi_pci_root_init(); |
2311 | acpi_pci_link_init(); | 2349 | acpi_pci_link_init(); |
2312 | acpi_processor_init(); | 2350 | acpi_processor_init(); |
2313 | acpi_lpss_init(); | 2351 | acpi_lpss_init(); |
2314 | acpi_cmos_rtc_init(); | 2352 | acpi_cmos_rtc_init(); |
2315 | acpi_container_init(); | 2353 | acpi_container_init(); |
2316 | acpi_memory_hotplug_init(); | 2354 | acpi_memory_hotplug_init(); |
2317 | acpi_pnp_init(); | 2355 | acpi_pnp_init(); |
2318 | acpi_int340x_thermal_init(); | 2356 | acpi_int340x_thermal_init(); |
2319 | 2357 | ||
2320 | mutex_lock(&acpi_scan_lock); | 2358 | mutex_lock(&acpi_scan_lock); |
2321 | /* | 2359 | /* |
2322 | * Enumerate devices in the ACPI namespace. | 2360 | * Enumerate devices in the ACPI namespace. |
2323 | */ | 2361 | */ |
2324 | result = acpi_bus_scan(ACPI_ROOT_OBJECT); | 2362 | result = acpi_bus_scan(ACPI_ROOT_OBJECT); |
2325 | if (result) | 2363 | if (result) |
2326 | goto out; | 2364 | goto out; |
2327 | 2365 | ||
2328 | result = acpi_bus_get_device(ACPI_ROOT_OBJECT, &acpi_root); | 2366 | result = acpi_bus_get_device(ACPI_ROOT_OBJECT, &acpi_root); |
2329 | if (result) | 2367 | if (result) |
2330 | goto out; | 2368 | goto out; |
2331 | 2369 | ||
2332 | /* Fixed feature devices do not exist on HW-reduced platform */ | 2370 | /* Fixed feature devices do not exist on HW-reduced platform */ |
2333 | if (!acpi_gbl_reduced_hardware) { | 2371 | if (!acpi_gbl_reduced_hardware) { |
2334 | result = acpi_bus_scan_fixed(); | 2372 | result = acpi_bus_scan_fixed(); |
2335 | if (result) { | 2373 | if (result) { |
2336 | acpi_detach_data(acpi_root->handle, | 2374 | acpi_detach_data(acpi_root->handle, |
2337 | acpi_scan_drop_device); | 2375 | acpi_scan_drop_device); |
2338 | acpi_device_del(acpi_root); | 2376 | acpi_device_del(acpi_root); |