ACPI: delete tracing macros from drivers/acpi/*.c
[deliverable/linux.git] / drivers / acpi / ec.c
CommitLineData
1da177e4
LT
1/*
2 * acpi_ec.c - ACPI Embedded Controller Driver ($Revision: 38 $)
3 *
4 * Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
5 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
6 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
7 *
8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23 *
24 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25 */
26
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/types.h>
31#include <linux/delay.h>
32#include <linux/proc_fs.h>
33#include <linux/seq_file.h>
451566f4 34#include <linux/interrupt.h>
1da177e4
LT
35#include <asm/io.h>
36#include <acpi/acpi_bus.h>
37#include <acpi/acpi_drivers.h>
38#include <acpi/actypes.h>
39
40#define _COMPONENT ACPI_EC_COMPONENT
50526df6 41ACPI_MODULE_NAME("acpi_ec")
1da177e4
LT
42#define ACPI_EC_COMPONENT 0x00100000
43#define ACPI_EC_CLASS "embedded_controller"
44#define ACPI_EC_HID "PNP0C09"
45#define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver"
46#define ACPI_EC_DEVICE_NAME "Embedded Controller"
47#define ACPI_EC_FILE_INFO "info"
1da177e4
LT
48#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */
49#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */
451566f4 50#define ACPI_EC_FLAG_BURST 0x10 /* burst mode */
1da177e4 51#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */
1da177e4
LT
52#define ACPI_EC_EVENT_OBF 0x01 /* Output buffer full */
53#define ACPI_EC_EVENT_IBE 0x02 /* Input buffer empty */
451566f4 54#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */
1da177e4 55#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
50526df6
LB
56#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */
57#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */
1da177e4
LT
58#define ACPI_EC_COMMAND_READ 0x80
59#define ACPI_EC_COMMAND_WRITE 0x81
451566f4
DT
60#define ACPI_EC_BURST_ENABLE 0x82
61#define ACPI_EC_BURST_DISABLE 0x83
1da177e4 62#define ACPI_EC_COMMAND_QUERY 0x84
02b28a33
LB
63#define EC_POLL 0xFF
64#define EC_INTR 0x00
50526df6
LB
65static int acpi_ec_remove(struct acpi_device *device, int type);
66static int acpi_ec_start(struct acpi_device *device);
67static int acpi_ec_stop(struct acpi_device *device, int type);
02b28a33
LB
68static int acpi_ec_intr_add(struct acpi_device *device);
69static int acpi_ec_poll_add(struct acpi_device *device);
1da177e4
LT
70
71static struct acpi_driver acpi_ec_driver = {
50526df6
LB
72 .name = ACPI_EC_DRIVER_NAME,
73 .class = ACPI_EC_CLASS,
74 .ids = ACPI_EC_HID,
75 .ops = {
53f11d4f 76 .add = acpi_ec_intr_add,
50526df6
LB
77 .remove = acpi_ec_remove,
78 .start = acpi_ec_start,
79 .stop = acpi_ec_stop,
80 },
1da177e4 81};
45bea155
LY
82union acpi_ec {
83 struct {
50526df6
LB
84 u32 mode;
85 acpi_handle handle;
86 unsigned long uid;
87 unsigned long gpe_bit;
88 struct acpi_generic_address status_addr;
89 struct acpi_generic_address command_addr;
90 struct acpi_generic_address data_addr;
91 unsigned long global_lock;
45bea155
LY
92 } common;
93
94 struct {
50526df6
LB
95 u32 mode;
96 acpi_handle handle;
97 unsigned long uid;
98 unsigned long gpe_bit;
99 struct acpi_generic_address status_addr;
100 struct acpi_generic_address command_addr;
101 struct acpi_generic_address data_addr;
102 unsigned long global_lock;
103 unsigned int expect_event;
104 atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */
105 atomic_t pending_gpe;
106 struct semaphore sem;
107 wait_queue_head_t wait;
02b28a33 108 } intr;
45bea155
LY
109
110 struct {
50526df6
LB
111 u32 mode;
112 acpi_handle handle;
113 unsigned long uid;
114 unsigned long gpe_bit;
115 struct acpi_generic_address status_addr;
116 struct acpi_generic_address command_addr;
117 struct acpi_generic_address data_addr;
118 unsigned long global_lock;
f9a6ee1a 119 struct semaphore sem;
02b28a33 120 } poll;
1da177e4
LT
121};
122
02b28a33
LB
123static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event);
124static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event);
125static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data);
126static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data);
127static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data);
128static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data);
129static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data);
130static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data);
131static void acpi_ec_gpe_poll_query(void *ec_cxt);
132static void acpi_ec_gpe_intr_query(void *ec_cxt);
133static u32 acpi_ec_gpe_poll_handler(void *data);
134static u32 acpi_ec_gpe_intr_handler(void *data);
45bea155 135static acpi_status __init
02b28a33 136acpi_fake_ecdt_poll_callback(acpi_handle handle,
50526df6 137 u32 Level, void *context, void **retval);
45bea155
LY
138
139static acpi_status __init
02b28a33 140acpi_fake_ecdt_intr_callback(acpi_handle handle,
50526df6
LB
141 u32 Level, void *context, void **retval);
142
02b28a33
LB
143static int __init acpi_ec_poll_get_real_ecdt(void);
144static int __init acpi_ec_intr_get_real_ecdt(void);
1da177e4 145/* If we find an EC via the ECDT, we need to keep a ptr to its context */
50526df6 146static union acpi_ec *ec_ecdt;
1da177e4
LT
147
148/* External interfaces use first EC only, so remember */
149static struct acpi_device *first_ec;
53f11d4f 150static int acpi_ec_poll_mode = EC_INTR;
1da177e4
LT
151
152/* --------------------------------------------------------------------------
153 Transaction Management
154 -------------------------------------------------------------------------- */
155
858119e1 156static u32 acpi_ec_read_status(union acpi_ec *ec)
1da177e4 157{
50526df6 158 u32 status = 0;
1da177e4 159
45bea155 160 acpi_hw_low_level_read(8, &status, &ec->common.status_addr);
451566f4
DT
161 return status;
162}
163
50526df6 164static int acpi_ec_wait(union acpi_ec *ec, u8 event)
45bea155 165{
02b28a33
LB
166 if (acpi_ec_poll_mode)
167 return acpi_ec_poll_wait(ec, event);
45bea155 168 else
02b28a33 169 return acpi_ec_intr_wait(ec, event);
45bea155
LY
170}
171
02b28a33 172static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event)
45bea155 173{
50526df6
LB
174 u32 acpi_ec_status = 0;
175 u32 i = ACPI_EC_UDELAY_COUNT;
45bea155
LY
176
177 if (!ec)
178 return -EINVAL;
179
180 /* Poll the EC status register waiting for the event to occur. */
181 switch (event) {
182 case ACPI_EC_EVENT_OBF:
183 do {
50526df6
LB
184 acpi_hw_low_level_read(8, &acpi_ec_status,
185 &ec->common.status_addr);
45bea155
LY
186 if (acpi_ec_status & ACPI_EC_FLAG_OBF)
187 return 0;
188 udelay(ACPI_EC_UDELAY);
50526df6 189 } while (--i > 0);
45bea155
LY
190 break;
191 case ACPI_EC_EVENT_IBE:
192 do {
50526df6
LB
193 acpi_hw_low_level_read(8, &acpi_ec_status,
194 &ec->common.status_addr);
45bea155
LY
195 if (!(acpi_ec_status & ACPI_EC_FLAG_IBF))
196 return 0;
197 udelay(ACPI_EC_UDELAY);
50526df6 198 } while (--i > 0);
45bea155
LY
199 break;
200 default:
201 return -EINVAL;
202 }
203
204 return -ETIME;
205}
02b28a33 206static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event)
451566f4 207{
50526df6 208 int result = 0;
451566f4 209
1da177e4 210
02b28a33 211 ec->intr.expect_event = event;
451566f4
DT
212 smp_mb();
213
716e084e 214 switch (event) {
716e084e
LY
215 case ACPI_EC_EVENT_IBE:
216 if (~acpi_ec_read_status(ec) & event) {
02b28a33 217 ec->intr.expect_event = 0;
d550d98d 218 return 0;
716e084e
LY
219 }
220 break;
06a2a385
LY
221 default:
222 break;
716e084e
LY
223 }
224
02b28a33
LB
225 result = wait_event_timeout(ec->intr.wait,
226 !ec->intr.expect_event,
50526df6
LB
227 msecs_to_jiffies(ACPI_EC_DELAY));
228
02b28a33 229 ec->intr.expect_event = 0;
451566f4
DT
230 smp_mb();
231
451566f4
DT
232 /*
233 * Verify that the event in question has actually happened by
234 * querying EC status. Do the check even if operation timed-out
235 * to make sure that we did not miss interrupt.
236 */
1da177e4
LT
237 switch (event) {
238 case ACPI_EC_EVENT_OBF:
451566f4 239 if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
d550d98d 240 return 0;
1da177e4 241 break;
451566f4 242
1da177e4 243 case ACPI_EC_EVENT_IBE:
451566f4 244 if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
d550d98d 245 return 0;
1da177e4 246 break;
1da177e4
LT
247 }
248
d550d98d 249 return -ETIME;
1da177e4
LT
250}
251
02b28a33 252#ifdef ACPI_FUTURE_USAGE
06a2a385
LY
253/*
254 * Note: samsung nv5000 doesn't work with ec burst mode.
255 * http://bugzilla.kernel.org/show_bug.cgi?id=4980
256 */
257int acpi_ec_enter_burst_mode(union acpi_ec *ec)
451566f4 258{
50526df6
LB
259 u32 tmp = 0;
260 int status = 0;
451566f4 261
451566f4
DT
262
263 status = acpi_ec_read_status(ec);
50526df6 264 if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) {
716e084e 265 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
50526df6 266 if (status)
716e084e 267 goto end;
50526df6
LB
268 acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE,
269 &ec->common.command_addr);
451566f4 270 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
45bea155 271 acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
50526df6 272 if (tmp != 0x90) { /* Burst ACK byte */
d550d98d 273 return -EINVAL;
451566f4 274 }
668d74c0
LY
275 }
276
02b28a33 277 atomic_set(&ec->intr.leaving_burst, 0);
d550d98d 278 return 0;
50526df6 279 end:
a6fc6720 280 ACPI_EXCEPTION ((AE_INFO, status, "EC wait, burst mode");
d550d98d 281 return -1;
451566f4
DT
282}
283
06a2a385 284int acpi_ec_leave_burst_mode(union acpi_ec *ec)
451566f4 285{
06a2a385 286 int status = 0;
451566f4 287
451566f4 288
06a2a385
LY
289 status = acpi_ec_read_status(ec);
290 if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){
291 status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
292 if(status)
293 goto end;
294 acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr);
295 acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
296 }
02b28a33 297 atomic_set(&ec->intr.leaving_burst, 1);
d550d98d 298 return 0;
06a2a385 299end:
a6fc6720 300 ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode");
d550d98d 301 return -1;
451566f4 302}
02b28a33 303#endif /* ACPI_FUTURE_USAGE */
451566f4 304
50526df6 305static int acpi_ec_read(union acpi_ec *ec, u8 address, u32 * data)
45bea155 306{
02b28a33
LB
307 if (acpi_ec_poll_mode)
308 return acpi_ec_poll_read(ec, address, data);
45bea155 309 else
02b28a33 310 return acpi_ec_intr_read(ec, address, data);
45bea155 311}
50526df6 312static int acpi_ec_write(union acpi_ec *ec, u8 address, u8 data)
45bea155 313{
02b28a33
LB
314 if (acpi_ec_poll_mode)
315 return acpi_ec_poll_write(ec, address, data);
45bea155 316 else
02b28a33 317 return acpi_ec_intr_write(ec, address, data);
45bea155 318}
02b28a33 319static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data)
45bea155 320{
50526df6
LB
321 acpi_status status = AE_OK;
322 int result = 0;
50526df6 323 u32 glk = 0;
45bea155 324
45bea155
LY
325
326 if (!ec || !data)
d550d98d 327 return -EINVAL;
45bea155
LY
328
329 *data = 0;
330
331 if (ec->common.global_lock) {
332 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
333 if (ACPI_FAILURE(status))
d550d98d 334 return -ENODEV;
45bea155
LY
335 }
336
f9a6ee1a
RT
337 if (down_interruptible(&ec->poll.sem)) {
338 result = -ERESTARTSYS;
339 goto end_nosem;
340 }
341
50526df6
LB
342 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ,
343 &ec->common.command_addr);
45bea155
LY
344 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
345 if (result)
346 goto end;
347
348 acpi_hw_low_level_write(8, address, &ec->common.data_addr);
349 result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
350 if (result)
351 goto end;
352
353 acpi_hw_low_level_read(8, data, &ec->common.data_addr);
354
355 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
50526df6
LB
356 *data, address));
357
358 end:
f9a6ee1a
RT
359 up(&ec->poll.sem);
360end_nosem:
45bea155
LY
361 if (ec->common.global_lock)
362 acpi_release_global_lock(glk);
363
d550d98d 364 return result;
45bea155
LY
365}
366
02b28a33 367static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data)
45bea155 368{
50526df6
LB
369 int result = 0;
370 acpi_status status = AE_OK;
50526df6 371 u32 glk = 0;
45bea155 372
45bea155
LY
373
374 if (!ec)
d550d98d 375 return -EINVAL;
45bea155
LY
376
377 if (ec->common.global_lock) {
378 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
379 if (ACPI_FAILURE(status))
d550d98d 380 return -ENODEV;
45bea155
LY
381 }
382
f9a6ee1a
RT
383 if (down_interruptible(&ec->poll.sem)) {
384 result = -ERESTARTSYS;
385 goto end_nosem;
386 }
387
50526df6
LB
388 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE,
389 &ec->common.command_addr);
45bea155
LY
390 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
391 if (result)
392 goto end;
393
394 acpi_hw_low_level_write(8, address, &ec->common.data_addr);
395 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
396 if (result)
397 goto end;
398
399 acpi_hw_low_level_write(8, data, &ec->common.data_addr);
400 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
401 if (result)
402 goto end;
403
404 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
50526df6 405 data, address));
45bea155 406
50526df6 407 end:
f9a6ee1a
RT
408 up(&ec->poll.sem);
409end_nosem:
45bea155
LY
410 if (ec->common.global_lock)
411 acpi_release_global_lock(glk);
412
d550d98d 413 return result;
45bea155
LY
414}
415
02b28a33 416static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data)
1da177e4 417{
50526df6
LB
418 int status = 0;
419 u32 glk;
1da177e4 420
1da177e4
LT
421
422 if (!ec || !data)
d550d98d 423 return -EINVAL;
1da177e4
LT
424
425 *data = 0;
426
45bea155 427 if (ec->common.global_lock) {
1da177e4
LT
428 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
429 if (ACPI_FAILURE(status))
d550d98d 430 return -ENODEV;
1da177e4 431 }
451566f4
DT
432
433 WARN_ON(in_interrupt());
02b28a33 434 down(&ec->intr.sem);
451566f4 435
716e084e
LY
436 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
437 if (status) {
1e8df53c 438 printk(KERN_DEBUG PREFIX "read EC, IB not empty\n");
451566f4 439 goto end;
716e084e 440 }
50526df6
LB
441 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ,
442 &ec->common.command_addr);
451566f4 443 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
451566f4 444 if (status) {
1e8df53c 445 printk(KERN_DEBUG PREFIX "read EC, IB not empty\n");
451566f4 446 }
1da177e4 447
45bea155 448 acpi_hw_low_level_write(8, address, &ec->common.data_addr);
50526df6
LB
449 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
450 if (status) {
1e8df53c 451 printk(KERN_DEBUG PREFIX "read EC, OB not full\n");
1da177e4 452 goto end;
451566f4 453 }
45bea155 454 acpi_hw_low_level_read(8, data, &ec->common.data_addr);
1da177e4 455 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
50526df6
LB
456 *data, address));
457
458 end:
02b28a33 459 up(&ec->intr.sem);
1da177e4 460
45bea155 461 if (ec->common.global_lock)
1da177e4
LT
462 acpi_release_global_lock(glk);
463
d550d98d 464 return status;
1da177e4
LT
465}
466
02b28a33 467static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data)
1da177e4 468{
50526df6
LB
469 int status = 0;
470 u32 glk;
1da177e4 471
1da177e4
LT
472
473 if (!ec)
d550d98d 474 return -EINVAL;
716e084e 475
45bea155 476 if (ec->common.global_lock) {
1da177e4
LT
477 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
478 if (ACPI_FAILURE(status))
d550d98d 479 return -ENODEV;
1da177e4
LT
480 }
481
451566f4 482 WARN_ON(in_interrupt());
02b28a33 483 down(&ec->intr.sem);
451566f4 484
716e084e 485 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
50526df6 486 if (status) {
1e8df53c 487 printk(KERN_DEBUG PREFIX "write EC, IB not empty\n");
451566f4 488 }
50526df6
LB
489 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE,
490 &ec->common.command_addr);
451566f4 491 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
716e084e 492 if (status) {
1e8df53c 493 printk(KERN_DEBUG PREFIX "write EC, IB not empty\n");
451566f4 494 }
1da177e4 495
45bea155 496 acpi_hw_low_level_write(8, address, &ec->common.data_addr);
451566f4 497 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
50526df6 498 if (status) {
1e8df53c 499 printk(KERN_DEBUG PREFIX "write EC, IB not empty\n");
451566f4 500 }
1da177e4 501
45bea155 502 acpi_hw_low_level_write(8, data, &ec->common.data_addr);
1da177e4
LT
503
504 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
50526df6 505 data, address));
1da177e4 506
02b28a33 507 up(&ec->intr.sem);
1da177e4 508
45bea155 509 if (ec->common.global_lock)
1da177e4
LT
510 acpi_release_global_lock(glk);
511
d550d98d 512 return status;
1da177e4
LT
513}
514
515/*
516 * Externally callable EC access functions. For now, assume 1 EC only
517 */
50526df6 518int ec_read(u8 addr, u8 * val)
1da177e4 519{
45bea155 520 union acpi_ec *ec;
1da177e4
LT
521 int err;
522 u32 temp_data;
523
524 if (!first_ec)
525 return -ENODEV;
526
527 ec = acpi_driver_data(first_ec);
528
529 err = acpi_ec_read(ec, addr, &temp_data);
530
531 if (!err) {
532 *val = temp_data;
533 return 0;
50526df6 534 } else
1da177e4
LT
535 return err;
536}
50526df6 537
1da177e4
LT
538EXPORT_SYMBOL(ec_read);
539
50526df6 540int ec_write(u8 addr, u8 val)
1da177e4 541{
45bea155 542 union acpi_ec *ec;
1da177e4
LT
543 int err;
544
545 if (!first_ec)
546 return -ENODEV;
547
548 ec = acpi_driver_data(first_ec);
549
550 err = acpi_ec_write(ec, addr, val);
551
552 return err;
553}
50526df6 554
1da177e4
LT
555EXPORT_SYMBOL(ec_write);
556
50526df6 557static int acpi_ec_query(union acpi_ec *ec, u32 * data)
45bea155 558{
02b28a33
LB
559 if (acpi_ec_poll_mode)
560 return acpi_ec_poll_query(ec, data);
45bea155 561 else
02b28a33 562 return acpi_ec_intr_query(ec, data);
45bea155 563}
02b28a33 564static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data)
45bea155 565{
50526df6
LB
566 int result = 0;
567 acpi_status status = AE_OK;
50526df6 568 u32 glk = 0;
45bea155 569
45bea155
LY
570
571 if (!ec || !data)
d550d98d 572 return -EINVAL;
45bea155
LY
573
574 *data = 0;
575
576 if (ec->common.global_lock) {
577 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
578 if (ACPI_FAILURE(status))
d550d98d 579 return -ENODEV;
45bea155
LY
580 }
581
582 /*
583 * Query the EC to find out which _Qxx method we need to evaluate.
584 * Note that successful completion of the query causes the ACPI_EC_SCI
585 * bit to be cleared (and thus clearing the interrupt source).
586 */
f9a6ee1a
RT
587 if (down_interruptible(&ec->poll.sem)) {
588 result = -ERESTARTSYS;
589 goto end_nosem;
590 }
591
50526df6
LB
592 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY,
593 &ec->common.command_addr);
45bea155
LY
594 result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
595 if (result)
596 goto end;
597
598 acpi_hw_low_level_read(8, data, &ec->common.data_addr);
599 if (!*data)
600 result = -ENODATA;
601
50526df6 602 end:
f9a6ee1a
RT
603 up(&ec->poll.sem);
604end_nosem:
45bea155
LY
605 if (ec->common.global_lock)
606 acpi_release_global_lock(glk);
607
d550d98d 608 return result;
45bea155 609}
02b28a33 610static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data)
1da177e4 611{
50526df6
LB
612 int status = 0;
613 u32 glk;
1da177e4 614
1da177e4
LT
615
616 if (!ec || !data)
d550d98d 617 return -EINVAL;
1da177e4
LT
618 *data = 0;
619
45bea155 620 if (ec->common.global_lock) {
1da177e4
LT
621 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
622 if (ACPI_FAILURE(status))
d550d98d 623 return -ENODEV;
1da177e4
LT
624 }
625
02b28a33 626 down(&ec->intr.sem);
716e084e
LY
627
628 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
629 if (status) {
1e8df53c 630 printk(KERN_DEBUG PREFIX "query EC, IB not empty\n");
451566f4 631 goto end;
716e084e 632 }
1da177e4
LT
633 /*
634 * Query the EC to find out which _Qxx method we need to evaluate.
635 * Note that successful completion of the query causes the ACPI_EC_SCI
636 * bit to be cleared (and thus clearing the interrupt source).
637 */
50526df6
LB
638 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY,
639 &ec->common.command_addr);
451566f4 640 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
50526df6 641 if (status) {
1e8df53c 642 printk(KERN_DEBUG PREFIX "query EC, OB not full\n");
1da177e4 643 goto end;
451566f4
DT
644 }
645
45bea155 646 acpi_hw_low_level_read(8, data, &ec->common.data_addr);
1da177e4 647 if (!*data)
451566f4 648 status = -ENODATA;
1da177e4 649
50526df6 650 end:
02b28a33 651 up(&ec->intr.sem);
1da177e4 652
45bea155 653 if (ec->common.global_lock)
1da177e4
LT
654 acpi_release_global_lock(glk);
655
d550d98d 656 return status;
1da177e4
LT
657}
658
1da177e4
LT
659/* --------------------------------------------------------------------------
660 Event Management
661 -------------------------------------------------------------------------- */
662
45bea155 663union acpi_ec_query_data {
50526df6
LB
664 acpi_handle handle;
665 u8 data;
1da177e4
LT
666};
667
50526df6 668static void acpi_ec_gpe_query(void *ec_cxt)
1da177e4 669{
02b28a33
LB
670 if (acpi_ec_poll_mode)
671 acpi_ec_gpe_poll_query(ec_cxt);
45bea155 672 else
02b28a33 673 acpi_ec_gpe_intr_query(ec_cxt);
45bea155
LY
674}
675
02b28a33 676static void acpi_ec_gpe_poll_query(void *ec_cxt)
45bea155 677{
50526df6
LB
678 union acpi_ec *ec = (union acpi_ec *)ec_cxt;
679 u32 value = 0;
50526df6
LB
680 static char object_name[5] = { '_', 'Q', '0', '0', '\0' };
681 const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
682 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
683 };
45bea155 684
45bea155
LY
685
686 if (!ec_cxt)
687 goto end;
688
f9a6ee1a 689 if (down_interruptible (&ec->poll.sem)) {
d550d98d 690 return;
f9a6ee1a 691 }
45bea155 692 acpi_hw_low_level_read(8, &value, &ec->common.command_addr);
f9a6ee1a 693 up(&ec->poll.sem);
45bea155
LY
694
695 /* TBD: Implement asynch events!
696 * NOTE: All we care about are EC-SCI's. Other EC events are
697 * handled via polling (yuck!). This is because some systems
698 * treat EC-SCIs as level (versus EDGE!) triggered, preventing
699 * a purely interrupt-driven approach (grumble, grumble).
700 */
701 if (!(value & ACPI_EC_FLAG_SCI))
702 goto end;
703
704 if (acpi_ec_query(ec, &value))
705 goto end;
706
707 object_name[2] = hex[((value >> 4) & 0x0F)];
708 object_name[3] = hex[(value & 0x0F)];
709
710 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
711
712 acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL);
713
50526df6 714 end:
45bea155
LY
715 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
716}
02b28a33 717static void acpi_ec_gpe_intr_query(void *ec_cxt)
45bea155 718{
50526df6
LB
719 union acpi_ec *ec = (union acpi_ec *)ec_cxt;
720 u32 value;
721 int result = -ENODATA;
722 static char object_name[5] = { '_', 'Q', '0', '0', '\0' };
723 const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
724 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
725 };
1da177e4 726
1da177e4 727
451566f4
DT
728 if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI)
729 result = acpi_ec_query(ec, &value);
1da177e4 730
451566f4 731 if (result)
1da177e4
LT
732 goto end;
733
1da177e4
LT
734 object_name[2] = hex[((value >> 4) & 0x0F)];
735 object_name[3] = hex[(value & 0x0F)];
736
737 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
738
45bea155 739 acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL);
50526df6 740 end:
02b28a33 741 atomic_dec(&ec->intr.pending_gpe);
451566f4 742 return;
1da177e4
LT
743}
744
50526df6 745static u32 acpi_ec_gpe_handler(void *data)
45bea155 746{
02b28a33
LB
747 if (acpi_ec_poll_mode)
748 return acpi_ec_gpe_poll_handler(data);
45bea155 749 else
02b28a33 750 return acpi_ec_gpe_intr_handler(data);
45bea155 751}
02b28a33 752static u32 acpi_ec_gpe_poll_handler(void *data)
45bea155 753{
50526df6
LB
754 acpi_status status = AE_OK;
755 union acpi_ec *ec = (union acpi_ec *)data;
45bea155
LY
756
757 if (!ec)
758 return ACPI_INTERRUPT_NOT_HANDLED;
759
760 acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
761
b8d35192 762 status = acpi_os_execute(OSL_EC_POLL_HANDLER, acpi_ec_gpe_query, ec);
45bea155
LY
763
764 if (status == AE_OK)
765 return ACPI_INTERRUPT_HANDLED;
766 else
767 return ACPI_INTERRUPT_NOT_HANDLED;
768}
02b28a33 769static u32 acpi_ec_gpe_intr_handler(void *data)
1da177e4 770{
50526df6
LB
771 acpi_status status = AE_OK;
772 u32 value;
773 union acpi_ec *ec = (union acpi_ec *)data;
1da177e4
LT
774
775 if (!ec)
776 return ACPI_INTERRUPT_NOT_HANDLED;
777
716e084e 778 acpi_clear_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
451566f4 779 value = acpi_ec_read_status(ec);
1da177e4 780
02b28a33 781 switch (ec->intr.expect_event) {
716e084e
LY
782 case ACPI_EC_EVENT_OBF:
783 if (!(value & ACPI_EC_FLAG_OBF))
784 break;
785 case ACPI_EC_EVENT_IBE:
786 if ((value & ACPI_EC_FLAG_IBF))
787 break;
02b28a33
LB
788 ec->intr.expect_event = 0;
789 wake_up(&ec->intr.wait);
716e084e
LY
790 return ACPI_INTERRUPT_HANDLED;
791 default:
792 break;
451566f4
DT
793 }
794
50526df6 795 if (value & ACPI_EC_FLAG_SCI) {
02b28a33 796 atomic_add(1, &ec->intr.pending_gpe);
b8d35192 797 status = acpi_os_execute(OSL_EC_BURST_HANDLER,
50526df6 798 acpi_ec_gpe_query, ec);
17e9c78a 799 return status == AE_OK ?
50526df6
LB
800 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
801 }
45bea155 802 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
451566f4 803 return status == AE_OK ?
50526df6 804 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
1da177e4
LT
805}
806
807/* --------------------------------------------------------------------------
808 Address Space Management
809 -------------------------------------------------------------------------- */
810
811static acpi_status
50526df6
LB
812acpi_ec_space_setup(acpi_handle region_handle,
813 u32 function, void *handler_context, void **return_context)
1da177e4
LT
814{
815 /*
816 * The EC object is in the handler context and is needed
817 * when calling the acpi_ec_space_handler.
818 */
50526df6
LB
819 *return_context = (function != ACPI_REGION_DEACTIVATE) ?
820 handler_context : NULL;
1da177e4
LT
821
822 return AE_OK;
823}
824
1da177e4 825static acpi_status
50526df6
LB
826acpi_ec_space_handler(u32 function,
827 acpi_physical_address address,
828 u32 bit_width,
829 acpi_integer * value,
830 void *handler_context, void *region_context)
1da177e4 831{
50526df6
LB
832 int result = 0;
833 union acpi_ec *ec = NULL;
834 u64 temp = *value;
835 acpi_integer f_v = 0;
836 int i = 0;
1da177e4 837
1da177e4
LT
838
839 if ((address > 0xFF) || !value || !handler_context)
d550d98d 840 return AE_BAD_PARAMETER;
1da177e4 841
fa9cd547 842 if (bit_width != 8 && acpi_strict) {
50526df6
LB
843 printk(KERN_WARNING PREFIX
844 "acpi_ec_space_handler: bit_width should be 8\n");
d550d98d 845 return AE_BAD_PARAMETER;
1da177e4
LT
846 }
847
50526df6 848 ec = (union acpi_ec *)handler_context;
1da177e4 849
50526df6 850 next_byte:
1da177e4
LT
851 switch (function) {
852 case ACPI_READ:
fa9cd547 853 temp = 0;
50526df6 854 result = acpi_ec_read(ec, (u8) address, (u32 *) & temp);
1da177e4
LT
855 break;
856 case ACPI_WRITE:
fa9cd547 857 result = acpi_ec_write(ec, (u8) address, (u8) temp);
1da177e4
LT
858 break;
859 default:
860 result = -EINVAL;
861 goto out;
862 break;
863 }
864
865 bit_width -= 8;
fa9cd547
LY
866 if (bit_width) {
867 if (function == ACPI_READ)
868 f_v |= temp << 8 * i;
869 if (function == ACPI_WRITE)
870 temp >>= 8;
1da177e4 871 i++;
83ea7445 872 address++;
1da177e4
LT
873 goto next_byte;
874 }
875
fa9cd547
LY
876 if (function == ACPI_READ) {
877 f_v |= temp << 8 * i;
1da177e4
LT
878 *value = f_v;
879 }
880
50526df6 881 out:
1da177e4
LT
882 switch (result) {
883 case -EINVAL:
d550d98d 884 return AE_BAD_PARAMETER;
1da177e4
LT
885 break;
886 case -ENODEV:
d550d98d 887 return AE_NOT_FOUND;
1da177e4
LT
888 break;
889 case -ETIME:
d550d98d 890 return AE_TIME;
1da177e4
LT
891 break;
892 default:
d550d98d 893 return AE_OK;
1da177e4 894 }
1da177e4
LT
895}
896
1da177e4
LT
897/* --------------------------------------------------------------------------
898 FS Interface (/proc)
899 -------------------------------------------------------------------------- */
900
50526df6 901static struct proc_dir_entry *acpi_ec_dir;
1da177e4 902
50526df6 903static int acpi_ec_read_info(struct seq_file *seq, void *offset)
1da177e4 904{
50526df6 905 union acpi_ec *ec = (union acpi_ec *)seq->private;
1da177e4 906
1da177e4
LT
907
908 if (!ec)
909 goto end;
910
911 seq_printf(seq, "gpe bit: 0x%02x\n",
50526df6 912 (u32) ec->common.gpe_bit);
1da177e4 913 seq_printf(seq, "ports: 0x%02x, 0x%02x\n",
50526df6
LB
914 (u32) ec->common.status_addr.address,
915 (u32) ec->common.data_addr.address);
1da177e4 916 seq_printf(seq, "use global lock: %s\n",
50526df6 917 ec->common.global_lock ? "yes" : "no");
45bea155 918 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
1da177e4 919
50526df6 920 end:
d550d98d 921 return 0;
1da177e4
LT
922}
923
924static int acpi_ec_info_open_fs(struct inode *inode, struct file *file)
925{
926 return single_open(file, acpi_ec_read_info, PDE(inode)->data);
927}
928
929static struct file_operations acpi_ec_info_ops = {
50526df6
LB
930 .open = acpi_ec_info_open_fs,
931 .read = seq_read,
932 .llseek = seq_lseek,
933 .release = single_release,
1da177e4
LT
934 .owner = THIS_MODULE,
935};
936
50526df6 937static int acpi_ec_add_fs(struct acpi_device *device)
1da177e4 938{
50526df6 939 struct proc_dir_entry *entry = NULL;
1da177e4 940
1da177e4
LT
941
942 if (!acpi_device_dir(device)) {
943 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
50526df6 944 acpi_ec_dir);
1da177e4 945 if (!acpi_device_dir(device))
d550d98d 946 return -ENODEV;
1da177e4
LT
947 }
948
949 entry = create_proc_entry(ACPI_EC_FILE_INFO, S_IRUGO,
50526df6 950 acpi_device_dir(device));
1da177e4 951 if (!entry)
d550d98d 952 return -ENODEV;
1da177e4
LT
953 else {
954 entry->proc_fops = &acpi_ec_info_ops;
955 entry->data = acpi_driver_data(device);
956 entry->owner = THIS_MODULE;
957 }
958
d550d98d 959 return 0;
1da177e4
LT
960}
961
50526df6 962static int acpi_ec_remove_fs(struct acpi_device *device)
1da177e4 963{
1da177e4
LT
964
965 if (acpi_device_dir(device)) {
966 remove_proc_entry(ACPI_EC_FILE_INFO, acpi_device_dir(device));
967 remove_proc_entry(acpi_device_bid(device), acpi_ec_dir);
968 acpi_device_dir(device) = NULL;
969 }
970
d550d98d 971 return 0;
1da177e4
LT
972}
973
1da177e4
LT
974/* --------------------------------------------------------------------------
975 Driver Interface
976 -------------------------------------------------------------------------- */
977
02b28a33 978static int acpi_ec_poll_add(struct acpi_device *device)
1da177e4 979{
50526df6
LB
980 int result = 0;
981 acpi_status status = AE_OK;
982 union acpi_ec *ec = NULL;
45bea155 983
45bea155
LY
984
985 if (!device)
d550d98d 986 return -EINVAL;
45bea155
LY
987
988 ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
989 if (!ec)
d550d98d 990 return -ENOMEM;
45bea155
LY
991 memset(ec, 0, sizeof(union acpi_ec));
992
993 ec->common.handle = device->handle;
994 ec->common.uid = -1;
f9a6ee1a 995 init_MUTEX(&ec->poll.sem);
45bea155
LY
996 strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
997 strcpy(acpi_device_class(device), ACPI_EC_CLASS);
998 acpi_driver_data(device) = ec;
999
1000 /* Use the global lock for all EC transactions? */
50526df6
LB
1001 acpi_evaluate_integer(ec->common.handle, "_GLK", NULL,
1002 &ec->common.global_lock);
45bea155 1003
ff2fc3e9
JS
1004 /* XXX we don't test uids, because on some boxes ecdt uid = 0, see:
1005 http://bugzilla.kernel.org/show_bug.cgi?id=6111 */
1006 if (ec_ecdt) {
45bea155 1007 acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
50526df6
LB
1008 ACPI_ADR_SPACE_EC,
1009 &acpi_ec_space_handler);
1010
1011 acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
1012 &acpi_ec_gpe_handler);
45bea155
LY
1013
1014 kfree(ec_ecdt);
1015 }
1016
1017 /* Get GPE bit assignment (EC events). */
1018 /* TODO: Add support for _GPE returning a package */
50526df6
LB
1019 status =
1020 acpi_evaluate_integer(ec->common.handle, "_GPE", NULL,
1021 &ec->common.gpe_bit);
45bea155 1022 if (ACPI_FAILURE(status)) {
a6fc6720 1023 ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit"));
45bea155
LY
1024 result = -ENODEV;
1025 goto end;
1026 }
1027
1028 result = acpi_ec_add_fs(device);
1029 if (result)
1030 goto end;
1031
02b28a33 1032 printk(KERN_INFO PREFIX "%s [%s] (gpe %d) polling mode.\n",
50526df6
LB
1033 acpi_device_name(device), acpi_device_bid(device),
1034 (u32) ec->common.gpe_bit);
45bea155
LY
1035
1036 if (!first_ec)
1037 first_ec = device;
1038
50526df6 1039 end:
45bea155
LY
1040 if (result)
1041 kfree(ec);
1042
d550d98d 1043 return result;
45bea155 1044}
02b28a33 1045static int acpi_ec_intr_add(struct acpi_device *device)
45bea155 1046{
50526df6
LB
1047 int result = 0;
1048 acpi_status status = AE_OK;
1049 union acpi_ec *ec = NULL;
1da177e4 1050
1da177e4
LT
1051
1052 if (!device)
d550d98d 1053 return -EINVAL;
1da177e4 1054
45bea155 1055 ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
1da177e4 1056 if (!ec)
d550d98d 1057 return -ENOMEM;
45bea155
LY
1058 memset(ec, 0, sizeof(union acpi_ec));
1059
1060 ec->common.handle = device->handle;
1061 ec->common.uid = -1;
02b28a33
LB
1062 atomic_set(&ec->intr.pending_gpe, 0);
1063 atomic_set(&ec->intr.leaving_burst, 1);
1064 init_MUTEX(&ec->intr.sem);
1065 init_waitqueue_head(&ec->intr.wait);
1da177e4
LT
1066 strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
1067 strcpy(acpi_device_class(device), ACPI_EC_CLASS);
1068 acpi_driver_data(device) = ec;
1069
1070 /* Use the global lock for all EC transactions? */
50526df6
LB
1071 acpi_evaluate_integer(ec->common.handle, "_GLK", NULL,
1072 &ec->common.global_lock);
1da177e4 1073
ff2fc3e9
JS
1074 /* XXX we don't test uids, because on some boxes ecdt uid = 0, see:
1075 http://bugzilla.kernel.org/show_bug.cgi?id=6111 */
1076 if (ec_ecdt) {
1da177e4 1077 acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
50526df6
LB
1078 ACPI_ADR_SPACE_EC,
1079 &acpi_ec_space_handler);
451566f4 1080
50526df6
LB
1081 acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
1082 &acpi_ec_gpe_handler);
1da177e4
LT
1083
1084 kfree(ec_ecdt);
1085 }
1086
1087 /* Get GPE bit assignment (EC events). */
1088 /* TODO: Add support for _GPE returning a package */
50526df6
LB
1089 status =
1090 acpi_evaluate_integer(ec->common.handle, "_GPE", NULL,
1091 &ec->common.gpe_bit);
1da177e4 1092 if (ACPI_FAILURE(status)) {
6468463a 1093 printk(KERN_ERR PREFIX "Obtaining GPE bit assignment\n");
1da177e4
LT
1094 result = -ENODEV;
1095 goto end;
1096 }
1097
1098 result = acpi_ec_add_fs(device);
1099 if (result)
1100 goto end;
1101
02b28a33 1102 printk(KERN_INFO PREFIX "%s [%s] (gpe %d) interrupt mode.\n",
50526df6
LB
1103 acpi_device_name(device), acpi_device_bid(device),
1104 (u32) ec->common.gpe_bit);
1da177e4
LT
1105
1106 if (!first_ec)
1107 first_ec = device;
1108
50526df6 1109 end:
1da177e4
LT
1110 if (result)
1111 kfree(ec);
1112
d550d98d 1113 return result;
1da177e4
LT
1114}
1115
50526df6 1116static int acpi_ec_remove(struct acpi_device *device, int type)
1da177e4 1117{
50526df6 1118 union acpi_ec *ec = NULL;
1da177e4 1119
1da177e4
LT
1120
1121 if (!device)
d550d98d 1122 return -EINVAL;
1da177e4
LT
1123
1124 ec = acpi_driver_data(device);
1125
1126 acpi_ec_remove_fs(device);
1127
1128 kfree(ec);
1129
d550d98d 1130 return 0;
1da177e4
LT
1131}
1132
1da177e4 1133static acpi_status
50526df6 1134acpi_ec_io_ports(struct acpi_resource *resource, void *context)
1da177e4 1135{
50526df6 1136 union acpi_ec *ec = (union acpi_ec *)context;
1da177e4
LT
1137 struct acpi_generic_address *addr;
1138
50eca3eb 1139 if (resource->type != ACPI_RESOURCE_TYPE_IO) {
1da177e4
LT
1140 return AE_OK;
1141 }
1142
1143 /*
1144 * The first address region returned is the data port, and
1145 * the second address region returned is the status/command
1146 * port.
1147 */
45bea155
LY
1148 if (ec->common.data_addr.register_bit_width == 0) {
1149 addr = &ec->common.data_addr;
1150 } else if (ec->common.command_addr.register_bit_width == 0) {
1151 addr = &ec->common.command_addr;
1da177e4
LT
1152 } else {
1153 return AE_CTRL_TERMINATE;
1154 }
1155
1156 addr->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
1157 addr->register_bit_width = 8;
1158 addr->register_bit_offset = 0;
50eca3eb 1159 addr->address = resource->data.io.minimum;
1da177e4
LT
1160
1161 return AE_OK;
1162}
1163
50526df6 1164static int acpi_ec_start(struct acpi_device *device)
1da177e4 1165{
50526df6
LB
1166 acpi_status status = AE_OK;
1167 union acpi_ec *ec = NULL;
1da177e4 1168
1da177e4
LT
1169
1170 if (!device)
d550d98d 1171 return -EINVAL;
1da177e4
LT
1172
1173 ec = acpi_driver_data(device);
1174
1175 if (!ec)
d550d98d 1176 return -EINVAL;
1da177e4
LT
1177
1178 /*
1179 * Get I/O port addresses. Convert to GAS format.
1180 */
45bea155 1181 status = acpi_walk_resources(ec->common.handle, METHOD_NAME__CRS,
50526df6
LB
1182 acpi_ec_io_ports, ec);
1183 if (ACPI_FAILURE(status)
1184 || ec->common.command_addr.register_bit_width == 0) {
6468463a 1185 printk(KERN_ERR PREFIX "Error getting I/O port addresses\n");
d550d98d 1186 return -ENODEV;
1da177e4
LT
1187 }
1188
45bea155 1189 ec->common.status_addr = ec->common.command_addr;
1da177e4
LT
1190
1191 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n",
50526df6
LB
1192 (u32) ec->common.gpe_bit,
1193 (u32) ec->common.command_addr.address,
1194 (u32) ec->common.data_addr.address));
1da177e4
LT
1195
1196 /*
1197 * Install GPE handler
1198 */
45bea155 1199 status = acpi_install_gpe_handler(NULL, ec->common.gpe_bit,
50526df6
LB
1200 ACPI_GPE_EDGE_TRIGGERED,
1201 &acpi_ec_gpe_handler, ec);
1da177e4 1202 if (ACPI_FAILURE(status)) {
d550d98d 1203 return -ENODEV;
1da177e4 1204 }
50526df6
LB
1205 acpi_set_gpe_type(NULL, ec->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME);
1206 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
1da177e4 1207
50526df6
LB
1208 status = acpi_install_address_space_handler(ec->common.handle,
1209 ACPI_ADR_SPACE_EC,
1210 &acpi_ec_space_handler,
1211 &acpi_ec_space_setup, ec);
1da177e4 1212 if (ACPI_FAILURE(status)) {
50526df6
LB
1213 acpi_remove_gpe_handler(NULL, ec->common.gpe_bit,
1214 &acpi_ec_gpe_handler);
d550d98d 1215 return -ENODEV;
1da177e4
LT
1216 }
1217
d550d98d 1218 return AE_OK;
1da177e4
LT
1219}
1220
50526df6 1221static int acpi_ec_stop(struct acpi_device *device, int type)
1da177e4 1222{
50526df6
LB
1223 acpi_status status = AE_OK;
1224 union acpi_ec *ec = NULL;
1da177e4 1225
1da177e4
LT
1226
1227 if (!device)
d550d98d 1228 return -EINVAL;
1da177e4
LT
1229
1230 ec = acpi_driver_data(device);
1231
45bea155 1232 status = acpi_remove_address_space_handler(ec->common.handle,
50526df6
LB
1233 ACPI_ADR_SPACE_EC,
1234 &acpi_ec_space_handler);
1da177e4 1235 if (ACPI_FAILURE(status))
d550d98d 1236 return -ENODEV;
1da177e4 1237
50526df6
LB
1238 status =
1239 acpi_remove_gpe_handler(NULL, ec->common.gpe_bit,
1240 &acpi_ec_gpe_handler);
1da177e4 1241 if (ACPI_FAILURE(status))
d550d98d 1242 return -ENODEV;
1da177e4 1243
d550d98d 1244 return 0;
1da177e4
LT
1245}
1246
1247static acpi_status __init
50526df6
LB
1248acpi_fake_ecdt_callback(acpi_handle handle,
1249 u32 Level, void *context, void **retval)
1da177e4 1250{
45bea155 1251
02b28a33
LB
1252 if (acpi_ec_poll_mode)
1253 return acpi_fake_ecdt_poll_callback(handle,
50526df6 1254 Level, context, retval);
45bea155 1255 else
02b28a33 1256 return acpi_fake_ecdt_intr_callback(handle,
50526df6 1257 Level, context, retval);
45bea155
LY
1258}
1259
1260static acpi_status __init
02b28a33 1261acpi_fake_ecdt_poll_callback(acpi_handle handle,
50526df6 1262 u32 Level, void *context, void **retval)
45bea155 1263{
50526df6 1264 acpi_status status;
45bea155
LY
1265
1266 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
50526df6 1267 acpi_ec_io_ports, ec_ecdt);
45bea155
LY
1268 if (ACPI_FAILURE(status))
1269 return status;
1270 ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;
1271
1272 ec_ecdt->common.uid = -1;
1273 acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid);
1274
50526df6
LB
1275 status =
1276 acpi_evaluate_integer(handle, "_GPE", NULL,
1277 &ec_ecdt->common.gpe_bit);
45bea155
LY
1278 if (ACPI_FAILURE(status))
1279 return status;
f9a6ee1a 1280 init_MUTEX(&ec_ecdt->poll.sem);
45bea155
LY
1281 ec_ecdt->common.global_lock = TRUE;
1282 ec_ecdt->common.handle = handle;
1283
50526df6
LB
1284 printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
1285 (u32) ec_ecdt->common.gpe_bit,
1286 (u32) ec_ecdt->common.command_addr.address,
1287 (u32) ec_ecdt->common.data_addr.address);
45bea155
LY
1288
1289 return AE_CTRL_TERMINATE;
1290}
1291
1292static acpi_status __init
02b28a33 1293acpi_fake_ecdt_intr_callback(acpi_handle handle,
50526df6 1294 u32 Level, void *context, void **retval)
45bea155 1295{
50526df6 1296 acpi_status status;
1da177e4 1297
02b28a33
LB
1298 init_MUTEX(&ec_ecdt->intr.sem);
1299 init_waitqueue_head(&ec_ecdt->intr.wait);
1da177e4 1300 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
50526df6 1301 acpi_ec_io_ports, ec_ecdt);
1da177e4
LT
1302 if (ACPI_FAILURE(status))
1303 return status;
45bea155 1304 ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;
1da177e4 1305
45bea155
LY
1306 ec_ecdt->common.uid = -1;
1307 acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid);
1da177e4 1308
50526df6
LB
1309 status =
1310 acpi_evaluate_integer(handle, "_GPE", NULL,
1311 &ec_ecdt->common.gpe_bit);
1da177e4
LT
1312 if (ACPI_FAILURE(status))
1313 return status;
45bea155
LY
1314 ec_ecdt->common.global_lock = TRUE;
1315 ec_ecdt->common.handle = handle;
1da177e4 1316
50526df6
LB
1317 printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
1318 (u32) ec_ecdt->common.gpe_bit,
1319 (u32) ec_ecdt->common.command_addr.address,
1320 (u32) ec_ecdt->common.data_addr.address);
1da177e4
LT
1321
1322 return AE_CTRL_TERMINATE;
1323}
1324
1325/*
1326 * Some BIOS (such as some from Gateway laptops) access EC region very early
1327 * such as in BAT0._INI or EC._INI before an EC device is found and
1328 * do not provide an ECDT. According to ACPI spec, ECDT isn't mandatorily
1329 * required, but if EC regison is accessed early, it is required.
1330 * The routine tries to workaround the BIOS bug by pre-scan EC device
1331 * It assumes that _CRS, _HID, _GPE, _UID methods of EC don't touch any
1332 * op region (since _REG isn't invoked yet). The assumption is true for
1333 * all systems found.
1334 */
50526df6 1335static int __init acpi_ec_fake_ecdt(void)
1da177e4 1336{
50526df6
LB
1337 acpi_status status;
1338 int ret = 0;
1da177e4
LT
1339
1340 printk(KERN_INFO PREFIX "Try to make an fake ECDT\n");
1341
45bea155 1342 ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
1da177e4
LT
1343 if (!ec_ecdt) {
1344 ret = -ENOMEM;
1345 goto error;
1346 }
45bea155 1347 memset(ec_ecdt, 0, sizeof(union acpi_ec));
1da177e4 1348
50526df6
LB
1349 status = acpi_get_devices(ACPI_EC_HID,
1350 acpi_fake_ecdt_callback, NULL, NULL);
1da177e4
LT
1351 if (ACPI_FAILURE(status)) {
1352 kfree(ec_ecdt);
1353 ec_ecdt = NULL;
1354 ret = -ENODEV;
1355 goto error;
1356 }
1357 return 0;
50526df6 1358 error:
1da177e4
LT
1359 printk(KERN_ERR PREFIX "Can't make an fake ECDT\n");
1360 return ret;
1361}
1362
50526df6 1363static int __init acpi_ec_get_real_ecdt(void)
45bea155 1364{
02b28a33
LB
1365 if (acpi_ec_poll_mode)
1366 return acpi_ec_poll_get_real_ecdt();
45bea155 1367 else
02b28a33 1368 return acpi_ec_intr_get_real_ecdt();
45bea155
LY
1369}
1370
02b28a33 1371static int __init acpi_ec_poll_get_real_ecdt(void)
45bea155 1372{
50526df6
LB
1373 acpi_status status;
1374 struct acpi_table_ecdt *ecdt_ptr;
45bea155 1375
50526df6
LB
1376 status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
1377 (struct acpi_table_header **)
1378 &ecdt_ptr);
45bea155
LY
1379 if (ACPI_FAILURE(status))
1380 return -ENODEV;
1381
1382 printk(KERN_INFO PREFIX "Found ECDT\n");
1383
1384 /*
1385 * Generate a temporary ec context to use until the namespace is scanned
1386 */
1387 ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
1388 if (!ec_ecdt)
1389 return -ENOMEM;
1390 memset(ec_ecdt, 0, sizeof(union acpi_ec));
1391
1392 ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
1393 ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
1394 ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
1395 ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
f9a6ee1a 1396 init_MUTEX(&ec_ecdt->poll.sem);
45bea155
LY
1397 /* use the GL just to be safe */
1398 ec_ecdt->common.global_lock = TRUE;
1399 ec_ecdt->common.uid = ecdt_ptr->uid;
1400
50526df6
LB
1401 status =
1402 acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle);
45bea155
LY
1403 if (ACPI_FAILURE(status)) {
1404 goto error;
1405 }
1406
1407 return 0;
50526df6 1408 error:
45bea155
LY
1409 printk(KERN_ERR PREFIX "Could not use ECDT\n");
1410 kfree(ec_ecdt);
1411 ec_ecdt = NULL;
1412
1413 return -ENODEV;
1414}
1415
02b28a33 1416static int __init acpi_ec_intr_get_real_ecdt(void)
1da177e4 1417{
50526df6
LB
1418 acpi_status status;
1419 struct acpi_table_ecdt *ecdt_ptr;
1da177e4 1420
451566f4 1421 status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
50526df6
LB
1422 (struct acpi_table_header **)
1423 &ecdt_ptr);
1da177e4
LT
1424 if (ACPI_FAILURE(status))
1425 return -ENODEV;
1426
1427 printk(KERN_INFO PREFIX "Found ECDT\n");
1428
1429 /*
1430 * Generate a temporary ec context to use until the namespace is scanned
1431 */
45bea155 1432 ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
1da177e4
LT
1433 if (!ec_ecdt)
1434 return -ENOMEM;
45bea155
LY
1435 memset(ec_ecdt, 0, sizeof(union acpi_ec));
1436
02b28a33
LB
1437 init_MUTEX(&ec_ecdt->intr.sem);
1438 init_waitqueue_head(&ec_ecdt->intr.wait);
45bea155
LY
1439 ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
1440 ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
1441 ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
1442 ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
1da177e4 1443 /* use the GL just to be safe */
45bea155
LY
1444 ec_ecdt->common.global_lock = TRUE;
1445 ec_ecdt->common.uid = ecdt_ptr->uid;
1da177e4 1446
50526df6
LB
1447 status =
1448 acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle);
1da177e4
LT
1449 if (ACPI_FAILURE(status)) {
1450 goto error;
1451 }
1452
1453 return 0;
50526df6 1454 error:
1da177e4
LT
1455 printk(KERN_ERR PREFIX "Could not use ECDT\n");
1456 kfree(ec_ecdt);
1457 ec_ecdt = NULL;
1458
1459 return -ENODEV;
1460}
1461
1462static int __initdata acpi_fake_ecdt_enabled;
50526df6 1463int __init acpi_ec_ecdt_probe(void)
1da177e4 1464{
50526df6
LB
1465 acpi_status status;
1466 int ret;
1da177e4
LT
1467
1468 ret = acpi_ec_get_real_ecdt();
1469 /* Try to make a fake ECDT */
1470 if (ret && acpi_fake_ecdt_enabled) {
1471 ret = acpi_ec_fake_ecdt();
1472 }
1473
1474 if (ret)
1475 return 0;
1476
1477 /*
1478 * Install GPE handler
1479 */
45bea155 1480 status = acpi_install_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
50526df6
LB
1481 ACPI_GPE_EDGE_TRIGGERED,
1482 &acpi_ec_gpe_handler, ec_ecdt);
1da177e4
LT
1483 if (ACPI_FAILURE(status)) {
1484 goto error;
1485 }
50526df6
LB
1486 acpi_set_gpe_type(NULL, ec_ecdt->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME);
1487 acpi_enable_gpe(NULL, ec_ecdt->common.gpe_bit, ACPI_NOT_ISR);
1488
1489 status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
1490 ACPI_ADR_SPACE_EC,
1491 &acpi_ec_space_handler,
1492 &acpi_ec_space_setup,
1493 ec_ecdt);
1da177e4 1494 if (ACPI_FAILURE(status)) {
45bea155 1495 acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
50526df6 1496 &acpi_ec_gpe_handler);
1da177e4
LT
1497 goto error;
1498 }
1499
1500 return 0;
1501
50526df6 1502 error:
1da177e4
LT
1503 printk(KERN_ERR PREFIX "Could not use ECDT\n");
1504 kfree(ec_ecdt);
1505 ec_ecdt = NULL;
1506
1507 return -ENODEV;
1508}
1509
50526df6 1510static int __init acpi_ec_init(void)
1da177e4 1511{
50526df6 1512 int result = 0;
1da177e4 1513
1da177e4
LT
1514
1515 if (acpi_disabled)
d550d98d 1516 return 0;
1da177e4
LT
1517
1518 acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir);
1519 if (!acpi_ec_dir)
d550d98d 1520 return -ENODEV;
1da177e4
LT
1521
1522 /* Now register the driver for the EC */
1523 result = acpi_bus_register_driver(&acpi_ec_driver);
1524 if (result < 0) {
1525 remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);
d550d98d 1526 return -ENODEV;
1da177e4
LT
1527 }
1528
d550d98d 1529 return result;
1da177e4
LT
1530}
1531
1532subsys_initcall(acpi_ec_init);
1533
1534/* EC driver currently not unloadable */
1535#if 0
50526df6 1536static void __exit acpi_ec_exit(void)
1da177e4 1537{
1da177e4
LT
1538
1539 acpi_bus_unregister_driver(&acpi_ec_driver);
1540
1541 remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);
1542
d550d98d 1543 return;
1da177e4 1544}
50526df6 1545#endif /* 0 */
1da177e4
LT
1546
1547static int __init acpi_fake_ecdt_setup(char *str)
1548{
1549 acpi_fake_ecdt_enabled = 1;
9b41046c 1550 return 1;
1da177e4 1551}
7b15f5e7 1552
1da177e4 1553__setup("acpi_fake_ecdt", acpi_fake_ecdt_setup);
02b28a33 1554static int __init acpi_ec_set_intr_mode(char *str)
45bea155 1555{
02b28a33 1556 int intr;
7b15f5e7 1557
02b28a33 1558 if (!get_option(&str, &intr))
7b15f5e7
LY
1559 return 0;
1560
02b28a33
LB
1561 if (intr) {
1562 acpi_ec_poll_mode = EC_INTR;
1563 acpi_ec_driver.ops.add = acpi_ec_intr_add;
7b15f5e7 1564 } else {
02b28a33
LB
1565 acpi_ec_poll_mode = EC_POLL;
1566 acpi_ec_driver.ops.add = acpi_ec_poll_add;
7b15f5e7 1567 }
02b28a33 1568 printk(KERN_INFO PREFIX "EC %s mode.\n", intr ? "interrupt" : "polling");
9b41046c 1569 return 1;
45bea155 1570}
50526df6 1571
53f11d4f 1572__setup("ec_intr=", acpi_ec_set_intr_mode);
This page took 0.275911 seconds and 5 git commands to generate.