Linux 2.6.19-rc2
[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 215 case ACPI_EC_EVENT_IBE:
49fee981 216 if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) {
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;
49fee981
VL
785 ec->intr.expect_event = 0;
786 wake_up(&ec->intr.wait);
787 break;
716e084e
LY
788 case ACPI_EC_EVENT_IBE:
789 if ((value & ACPI_EC_FLAG_IBF))
790 break;
02b28a33
LB
791 ec->intr.expect_event = 0;
792 wake_up(&ec->intr.wait);
49fee981 793 break;
716e084e
LY
794 default:
795 break;
451566f4
DT
796 }
797
50526df6 798 if (value & ACPI_EC_FLAG_SCI) {
02b28a33 799 atomic_add(1, &ec->intr.pending_gpe);
b8d35192 800 status = acpi_os_execute(OSL_EC_BURST_HANDLER,
50526df6 801 acpi_ec_gpe_query, ec);
17e9c78a 802 return status == AE_OK ?
50526df6
LB
803 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
804 }
45bea155 805 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
451566f4 806 return status == AE_OK ?
50526df6 807 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
1da177e4
LT
808}
809
810/* --------------------------------------------------------------------------
811 Address Space Management
812 -------------------------------------------------------------------------- */
813
814static acpi_status
50526df6
LB
815acpi_ec_space_setup(acpi_handle region_handle,
816 u32 function, void *handler_context, void **return_context)
1da177e4
LT
817{
818 /*
819 * The EC object is in the handler context and is needed
820 * when calling the acpi_ec_space_handler.
821 */
50526df6
LB
822 *return_context = (function != ACPI_REGION_DEACTIVATE) ?
823 handler_context : NULL;
1da177e4
LT
824
825 return AE_OK;
826}
827
1da177e4 828static acpi_status
50526df6
LB
829acpi_ec_space_handler(u32 function,
830 acpi_physical_address address,
831 u32 bit_width,
832 acpi_integer * value,
833 void *handler_context, void *region_context)
1da177e4 834{
50526df6
LB
835 int result = 0;
836 union acpi_ec *ec = NULL;
837 u64 temp = *value;
838 acpi_integer f_v = 0;
839 int i = 0;
1da177e4 840
1da177e4
LT
841
842 if ((address > 0xFF) || !value || !handler_context)
d550d98d 843 return AE_BAD_PARAMETER;
1da177e4 844
fa9cd547 845 if (bit_width != 8 && acpi_strict) {
50526df6
LB
846 printk(KERN_WARNING PREFIX
847 "acpi_ec_space_handler: bit_width should be 8\n");
d550d98d 848 return AE_BAD_PARAMETER;
1da177e4
LT
849 }
850
50526df6 851 ec = (union acpi_ec *)handler_context;
1da177e4 852
50526df6 853 next_byte:
1da177e4
LT
854 switch (function) {
855 case ACPI_READ:
fa9cd547 856 temp = 0;
50526df6 857 result = acpi_ec_read(ec, (u8) address, (u32 *) & temp);
1da177e4
LT
858 break;
859 case ACPI_WRITE:
fa9cd547 860 result = acpi_ec_write(ec, (u8) address, (u8) temp);
1da177e4
LT
861 break;
862 default:
863 result = -EINVAL;
864 goto out;
865 break;
866 }
867
868 bit_width -= 8;
fa9cd547
LY
869 if (bit_width) {
870 if (function == ACPI_READ)
871 f_v |= temp << 8 * i;
872 if (function == ACPI_WRITE)
873 temp >>= 8;
1da177e4 874 i++;
83ea7445 875 address++;
1da177e4
LT
876 goto next_byte;
877 }
878
fa9cd547
LY
879 if (function == ACPI_READ) {
880 f_v |= temp << 8 * i;
1da177e4
LT
881 *value = f_v;
882 }
883
50526df6 884 out:
1da177e4
LT
885 switch (result) {
886 case -EINVAL:
d550d98d 887 return AE_BAD_PARAMETER;
1da177e4
LT
888 break;
889 case -ENODEV:
d550d98d 890 return AE_NOT_FOUND;
1da177e4
LT
891 break;
892 case -ETIME:
d550d98d 893 return AE_TIME;
1da177e4
LT
894 break;
895 default:
d550d98d 896 return AE_OK;
1da177e4 897 }
1da177e4
LT
898}
899
1da177e4
LT
900/* --------------------------------------------------------------------------
901 FS Interface (/proc)
902 -------------------------------------------------------------------------- */
903
50526df6 904static struct proc_dir_entry *acpi_ec_dir;
1da177e4 905
50526df6 906static int acpi_ec_read_info(struct seq_file *seq, void *offset)
1da177e4 907{
50526df6 908 union acpi_ec *ec = (union acpi_ec *)seq->private;
1da177e4 909
1da177e4
LT
910
911 if (!ec)
912 goto end;
913
914 seq_printf(seq, "gpe bit: 0x%02x\n",
50526df6 915 (u32) ec->common.gpe_bit);
1da177e4 916 seq_printf(seq, "ports: 0x%02x, 0x%02x\n",
50526df6
LB
917 (u32) ec->common.status_addr.address,
918 (u32) ec->common.data_addr.address);
1da177e4 919 seq_printf(seq, "use global lock: %s\n",
50526df6 920 ec->common.global_lock ? "yes" : "no");
45bea155 921 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
1da177e4 922
50526df6 923 end:
d550d98d 924 return 0;
1da177e4
LT
925}
926
927static int acpi_ec_info_open_fs(struct inode *inode, struct file *file)
928{
929 return single_open(file, acpi_ec_read_info, PDE(inode)->data);
930}
931
d7508032 932static const struct file_operations acpi_ec_info_ops = {
50526df6
LB
933 .open = acpi_ec_info_open_fs,
934 .read = seq_read,
935 .llseek = seq_lseek,
936 .release = single_release,
1da177e4
LT
937 .owner = THIS_MODULE,
938};
939
50526df6 940static int acpi_ec_add_fs(struct acpi_device *device)
1da177e4 941{
50526df6 942 struct proc_dir_entry *entry = NULL;
1da177e4 943
1da177e4
LT
944
945 if (!acpi_device_dir(device)) {
946 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
50526df6 947 acpi_ec_dir);
1da177e4 948 if (!acpi_device_dir(device))
d550d98d 949 return -ENODEV;
1da177e4
LT
950 }
951
952 entry = create_proc_entry(ACPI_EC_FILE_INFO, S_IRUGO,
50526df6 953 acpi_device_dir(device));
1da177e4 954 if (!entry)
d550d98d 955 return -ENODEV;
1da177e4
LT
956 else {
957 entry->proc_fops = &acpi_ec_info_ops;
958 entry->data = acpi_driver_data(device);
959 entry->owner = THIS_MODULE;
960 }
961
d550d98d 962 return 0;
1da177e4
LT
963}
964
50526df6 965static int acpi_ec_remove_fs(struct acpi_device *device)
1da177e4 966{
1da177e4
LT
967
968 if (acpi_device_dir(device)) {
969 remove_proc_entry(ACPI_EC_FILE_INFO, acpi_device_dir(device));
970 remove_proc_entry(acpi_device_bid(device), acpi_ec_dir);
971 acpi_device_dir(device) = NULL;
972 }
973
d550d98d 974 return 0;
1da177e4
LT
975}
976
1da177e4
LT
977/* --------------------------------------------------------------------------
978 Driver Interface
979 -------------------------------------------------------------------------- */
980
02b28a33 981static int acpi_ec_poll_add(struct acpi_device *device)
1da177e4 982{
50526df6
LB
983 int result = 0;
984 acpi_status status = AE_OK;
985 union acpi_ec *ec = NULL;
45bea155 986
45bea155
LY
987
988 if (!device)
d550d98d 989 return -EINVAL;
45bea155
LY
990
991 ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
992 if (!ec)
d550d98d 993 return -ENOMEM;
45bea155
LY
994 memset(ec, 0, sizeof(union acpi_ec));
995
996 ec->common.handle = device->handle;
997 ec->common.uid = -1;
f9a6ee1a 998 init_MUTEX(&ec->poll.sem);
45bea155
LY
999 strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
1000 strcpy(acpi_device_class(device), ACPI_EC_CLASS);
1001 acpi_driver_data(device) = ec;
1002
1003 /* Use the global lock for all EC transactions? */
50526df6
LB
1004 acpi_evaluate_integer(ec->common.handle, "_GLK", NULL,
1005 &ec->common.global_lock);
45bea155 1006
ff2fc3e9
JS
1007 /* XXX we don't test uids, because on some boxes ecdt uid = 0, see:
1008 http://bugzilla.kernel.org/show_bug.cgi?id=6111 */
1009 if (ec_ecdt) {
45bea155 1010 acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
50526df6
LB
1011 ACPI_ADR_SPACE_EC,
1012 &acpi_ec_space_handler);
1013
1014 acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
1015 &acpi_ec_gpe_handler);
45bea155
LY
1016
1017 kfree(ec_ecdt);
1018 }
1019
1020 /* Get GPE bit assignment (EC events). */
1021 /* TODO: Add support for _GPE returning a package */
50526df6
LB
1022 status =
1023 acpi_evaluate_integer(ec->common.handle, "_GPE", NULL,
1024 &ec->common.gpe_bit);
45bea155 1025 if (ACPI_FAILURE(status)) {
a6fc6720 1026 ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit"));
45bea155
LY
1027 result = -ENODEV;
1028 goto end;
1029 }
1030
1031 result = acpi_ec_add_fs(device);
1032 if (result)
1033 goto end;
1034
02b28a33 1035 printk(KERN_INFO PREFIX "%s [%s] (gpe %d) polling mode.\n",
50526df6
LB
1036 acpi_device_name(device), acpi_device_bid(device),
1037 (u32) ec->common.gpe_bit);
45bea155
LY
1038
1039 if (!first_ec)
1040 first_ec = device;
1041
50526df6 1042 end:
45bea155
LY
1043 if (result)
1044 kfree(ec);
1045
d550d98d 1046 return result;
45bea155 1047}
02b28a33 1048static int acpi_ec_intr_add(struct acpi_device *device)
45bea155 1049{
50526df6
LB
1050 int result = 0;
1051 acpi_status status = AE_OK;
1052 union acpi_ec *ec = NULL;
1da177e4 1053
1da177e4
LT
1054
1055 if (!device)
d550d98d 1056 return -EINVAL;
1da177e4 1057
45bea155 1058 ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
1da177e4 1059 if (!ec)
d550d98d 1060 return -ENOMEM;
45bea155
LY
1061 memset(ec, 0, sizeof(union acpi_ec));
1062
1063 ec->common.handle = device->handle;
1064 ec->common.uid = -1;
02b28a33
LB
1065 atomic_set(&ec->intr.pending_gpe, 0);
1066 atomic_set(&ec->intr.leaving_burst, 1);
1067 init_MUTEX(&ec->intr.sem);
1068 init_waitqueue_head(&ec->intr.wait);
1da177e4
LT
1069 strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
1070 strcpy(acpi_device_class(device), ACPI_EC_CLASS);
1071 acpi_driver_data(device) = ec;
1072
1073 /* Use the global lock for all EC transactions? */
50526df6
LB
1074 acpi_evaluate_integer(ec->common.handle, "_GLK", NULL,
1075 &ec->common.global_lock);
1da177e4 1076
ff2fc3e9
JS
1077 /* XXX we don't test uids, because on some boxes ecdt uid = 0, see:
1078 http://bugzilla.kernel.org/show_bug.cgi?id=6111 */
1079 if (ec_ecdt) {
1da177e4 1080 acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
50526df6
LB
1081 ACPI_ADR_SPACE_EC,
1082 &acpi_ec_space_handler);
451566f4 1083
50526df6
LB
1084 acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
1085 &acpi_ec_gpe_handler);
1da177e4
LT
1086
1087 kfree(ec_ecdt);
1088 }
1089
1090 /* Get GPE bit assignment (EC events). */
1091 /* TODO: Add support for _GPE returning a package */
50526df6
LB
1092 status =
1093 acpi_evaluate_integer(ec->common.handle, "_GPE", NULL,
1094 &ec->common.gpe_bit);
1da177e4 1095 if (ACPI_FAILURE(status)) {
6468463a 1096 printk(KERN_ERR PREFIX "Obtaining GPE bit assignment\n");
1da177e4
LT
1097 result = -ENODEV;
1098 goto end;
1099 }
1100
1101 result = acpi_ec_add_fs(device);
1102 if (result)
1103 goto end;
1104
02b28a33 1105 printk(KERN_INFO PREFIX "%s [%s] (gpe %d) interrupt mode.\n",
50526df6
LB
1106 acpi_device_name(device), acpi_device_bid(device),
1107 (u32) ec->common.gpe_bit);
1da177e4
LT
1108
1109 if (!first_ec)
1110 first_ec = device;
1111
50526df6 1112 end:
1da177e4
LT
1113 if (result)
1114 kfree(ec);
1115
d550d98d 1116 return result;
1da177e4
LT
1117}
1118
50526df6 1119static int acpi_ec_remove(struct acpi_device *device, int type)
1da177e4 1120{
50526df6 1121 union acpi_ec *ec = NULL;
1da177e4 1122
1da177e4
LT
1123
1124 if (!device)
d550d98d 1125 return -EINVAL;
1da177e4
LT
1126
1127 ec = acpi_driver_data(device);
1128
1129 acpi_ec_remove_fs(device);
1130
1131 kfree(ec);
1132
d550d98d 1133 return 0;
1da177e4
LT
1134}
1135
1da177e4 1136static acpi_status
50526df6 1137acpi_ec_io_ports(struct acpi_resource *resource, void *context)
1da177e4 1138{
50526df6 1139 union acpi_ec *ec = (union acpi_ec *)context;
1da177e4
LT
1140 struct acpi_generic_address *addr;
1141
50eca3eb 1142 if (resource->type != ACPI_RESOURCE_TYPE_IO) {
1da177e4
LT
1143 return AE_OK;
1144 }
1145
1146 /*
1147 * The first address region returned is the data port, and
1148 * the second address region returned is the status/command
1149 * port.
1150 */
45bea155
LY
1151 if (ec->common.data_addr.register_bit_width == 0) {
1152 addr = &ec->common.data_addr;
1153 } else if (ec->common.command_addr.register_bit_width == 0) {
1154 addr = &ec->common.command_addr;
1da177e4
LT
1155 } else {
1156 return AE_CTRL_TERMINATE;
1157 }
1158
1159 addr->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
1160 addr->register_bit_width = 8;
1161 addr->register_bit_offset = 0;
50eca3eb 1162 addr->address = resource->data.io.minimum;
1da177e4
LT
1163
1164 return AE_OK;
1165}
1166
50526df6 1167static int acpi_ec_start(struct acpi_device *device)
1da177e4 1168{
50526df6
LB
1169 acpi_status status = AE_OK;
1170 union acpi_ec *ec = NULL;
1da177e4 1171
1da177e4
LT
1172
1173 if (!device)
d550d98d 1174 return -EINVAL;
1da177e4
LT
1175
1176 ec = acpi_driver_data(device);
1177
1178 if (!ec)
d550d98d 1179 return -EINVAL;
1da177e4
LT
1180
1181 /*
1182 * Get I/O port addresses. Convert to GAS format.
1183 */
45bea155 1184 status = acpi_walk_resources(ec->common.handle, METHOD_NAME__CRS,
50526df6
LB
1185 acpi_ec_io_ports, ec);
1186 if (ACPI_FAILURE(status)
1187 || ec->common.command_addr.register_bit_width == 0) {
6468463a 1188 printk(KERN_ERR PREFIX "Error getting I/O port addresses\n");
d550d98d 1189 return -ENODEV;
1da177e4
LT
1190 }
1191
45bea155 1192 ec->common.status_addr = ec->common.command_addr;
1da177e4
LT
1193
1194 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n",
50526df6
LB
1195 (u32) ec->common.gpe_bit,
1196 (u32) ec->common.command_addr.address,
1197 (u32) ec->common.data_addr.address));
1da177e4
LT
1198
1199 /*
1200 * Install GPE handler
1201 */
45bea155 1202 status = acpi_install_gpe_handler(NULL, ec->common.gpe_bit,
50526df6
LB
1203 ACPI_GPE_EDGE_TRIGGERED,
1204 &acpi_ec_gpe_handler, ec);
1da177e4 1205 if (ACPI_FAILURE(status)) {
d550d98d 1206 return -ENODEV;
1da177e4 1207 }
50526df6
LB
1208 acpi_set_gpe_type(NULL, ec->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME);
1209 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
1da177e4 1210
50526df6
LB
1211 status = acpi_install_address_space_handler(ec->common.handle,
1212 ACPI_ADR_SPACE_EC,
1213 &acpi_ec_space_handler,
1214 &acpi_ec_space_setup, ec);
1da177e4 1215 if (ACPI_FAILURE(status)) {
50526df6
LB
1216 acpi_remove_gpe_handler(NULL, ec->common.gpe_bit,
1217 &acpi_ec_gpe_handler);
d550d98d 1218 return -ENODEV;
1da177e4
LT
1219 }
1220
d550d98d 1221 return AE_OK;
1da177e4
LT
1222}
1223
50526df6 1224static int acpi_ec_stop(struct acpi_device *device, int type)
1da177e4 1225{
50526df6
LB
1226 acpi_status status = AE_OK;
1227 union acpi_ec *ec = NULL;
1da177e4 1228
1da177e4
LT
1229
1230 if (!device)
d550d98d 1231 return -EINVAL;
1da177e4
LT
1232
1233 ec = acpi_driver_data(device);
1234
45bea155 1235 status = acpi_remove_address_space_handler(ec->common.handle,
50526df6
LB
1236 ACPI_ADR_SPACE_EC,
1237 &acpi_ec_space_handler);
1da177e4 1238 if (ACPI_FAILURE(status))
d550d98d 1239 return -ENODEV;
1da177e4 1240
50526df6
LB
1241 status =
1242 acpi_remove_gpe_handler(NULL, ec->common.gpe_bit,
1243 &acpi_ec_gpe_handler);
1da177e4 1244 if (ACPI_FAILURE(status))
d550d98d 1245 return -ENODEV;
1da177e4 1246
d550d98d 1247 return 0;
1da177e4
LT
1248}
1249
1250static acpi_status __init
50526df6
LB
1251acpi_fake_ecdt_callback(acpi_handle handle,
1252 u32 Level, void *context, void **retval)
1da177e4 1253{
45bea155 1254
02b28a33
LB
1255 if (acpi_ec_poll_mode)
1256 return acpi_fake_ecdt_poll_callback(handle,
50526df6 1257 Level, context, retval);
45bea155 1258 else
02b28a33 1259 return acpi_fake_ecdt_intr_callback(handle,
50526df6 1260 Level, context, retval);
45bea155
LY
1261}
1262
1263static acpi_status __init
02b28a33 1264acpi_fake_ecdt_poll_callback(acpi_handle handle,
50526df6 1265 u32 Level, void *context, void **retval)
45bea155 1266{
50526df6 1267 acpi_status status;
45bea155
LY
1268
1269 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
50526df6 1270 acpi_ec_io_ports, ec_ecdt);
45bea155
LY
1271 if (ACPI_FAILURE(status))
1272 return status;
1273 ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;
1274
1275 ec_ecdt->common.uid = -1;
1276 acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid);
1277
50526df6
LB
1278 status =
1279 acpi_evaluate_integer(handle, "_GPE", NULL,
1280 &ec_ecdt->common.gpe_bit);
45bea155
LY
1281 if (ACPI_FAILURE(status))
1282 return status;
f9a6ee1a 1283 init_MUTEX(&ec_ecdt->poll.sem);
45bea155
LY
1284 ec_ecdt->common.global_lock = TRUE;
1285 ec_ecdt->common.handle = handle;
1286
50526df6
LB
1287 printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
1288 (u32) ec_ecdt->common.gpe_bit,
1289 (u32) ec_ecdt->common.command_addr.address,
1290 (u32) ec_ecdt->common.data_addr.address);
45bea155
LY
1291
1292 return AE_CTRL_TERMINATE;
1293}
1294
1295static acpi_status __init
02b28a33 1296acpi_fake_ecdt_intr_callback(acpi_handle handle,
50526df6 1297 u32 Level, void *context, void **retval)
45bea155 1298{
50526df6 1299 acpi_status status;
1da177e4 1300
02b28a33
LB
1301 init_MUTEX(&ec_ecdt->intr.sem);
1302 init_waitqueue_head(&ec_ecdt->intr.wait);
1da177e4 1303 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
50526df6 1304 acpi_ec_io_ports, ec_ecdt);
1da177e4
LT
1305 if (ACPI_FAILURE(status))
1306 return status;
45bea155 1307 ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;
1da177e4 1308
45bea155
LY
1309 ec_ecdt->common.uid = -1;
1310 acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid);
1da177e4 1311
50526df6
LB
1312 status =
1313 acpi_evaluate_integer(handle, "_GPE", NULL,
1314 &ec_ecdt->common.gpe_bit);
1da177e4
LT
1315 if (ACPI_FAILURE(status))
1316 return status;
45bea155
LY
1317 ec_ecdt->common.global_lock = TRUE;
1318 ec_ecdt->common.handle = handle;
1da177e4 1319
50526df6
LB
1320 printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
1321 (u32) ec_ecdt->common.gpe_bit,
1322 (u32) ec_ecdt->common.command_addr.address,
1323 (u32) ec_ecdt->common.data_addr.address);
1da177e4
LT
1324
1325 return AE_CTRL_TERMINATE;
1326}
1327
1328/*
1329 * Some BIOS (such as some from Gateway laptops) access EC region very early
1330 * such as in BAT0._INI or EC._INI before an EC device is found and
1331 * do not provide an ECDT. According to ACPI spec, ECDT isn't mandatorily
1332 * required, but if EC regison is accessed early, it is required.
1333 * The routine tries to workaround the BIOS bug by pre-scan EC device
1334 * It assumes that _CRS, _HID, _GPE, _UID methods of EC don't touch any
1335 * op region (since _REG isn't invoked yet). The assumption is true for
1336 * all systems found.
1337 */
50526df6 1338static int __init acpi_ec_fake_ecdt(void)
1da177e4 1339{
50526df6
LB
1340 acpi_status status;
1341 int ret = 0;
1da177e4
LT
1342
1343 printk(KERN_INFO PREFIX "Try to make an fake ECDT\n");
1344
45bea155 1345 ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
1da177e4
LT
1346 if (!ec_ecdt) {
1347 ret = -ENOMEM;
1348 goto error;
1349 }
45bea155 1350 memset(ec_ecdt, 0, sizeof(union acpi_ec));
1da177e4 1351
50526df6
LB
1352 status = acpi_get_devices(ACPI_EC_HID,
1353 acpi_fake_ecdt_callback, NULL, NULL);
1da177e4
LT
1354 if (ACPI_FAILURE(status)) {
1355 kfree(ec_ecdt);
1356 ec_ecdt = NULL;
1357 ret = -ENODEV;
1358 goto error;
1359 }
1360 return 0;
50526df6 1361 error:
1da177e4
LT
1362 printk(KERN_ERR PREFIX "Can't make an fake ECDT\n");
1363 return ret;
1364}
1365
50526df6 1366static int __init acpi_ec_get_real_ecdt(void)
45bea155 1367{
02b28a33
LB
1368 if (acpi_ec_poll_mode)
1369 return acpi_ec_poll_get_real_ecdt();
45bea155 1370 else
02b28a33 1371 return acpi_ec_intr_get_real_ecdt();
45bea155
LY
1372}
1373
02b28a33 1374static int __init acpi_ec_poll_get_real_ecdt(void)
45bea155 1375{
50526df6
LB
1376 acpi_status status;
1377 struct acpi_table_ecdt *ecdt_ptr;
45bea155 1378
50526df6
LB
1379 status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
1380 (struct acpi_table_header **)
1381 &ecdt_ptr);
45bea155
LY
1382 if (ACPI_FAILURE(status))
1383 return -ENODEV;
1384
1385 printk(KERN_INFO PREFIX "Found ECDT\n");
1386
1387 /*
1388 * Generate a temporary ec context to use until the namespace is scanned
1389 */
1390 ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
1391 if (!ec_ecdt)
1392 return -ENOMEM;
1393 memset(ec_ecdt, 0, sizeof(union acpi_ec));
1394
1395 ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
1396 ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
1397 ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
1398 ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
f9a6ee1a 1399 init_MUTEX(&ec_ecdt->poll.sem);
45bea155
LY
1400 /* use the GL just to be safe */
1401 ec_ecdt->common.global_lock = TRUE;
1402 ec_ecdt->common.uid = ecdt_ptr->uid;
1403
50526df6
LB
1404 status =
1405 acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle);
45bea155
LY
1406 if (ACPI_FAILURE(status)) {
1407 goto error;
1408 }
1409
1410 return 0;
50526df6 1411 error:
45bea155
LY
1412 printk(KERN_ERR PREFIX "Could not use ECDT\n");
1413 kfree(ec_ecdt);
1414 ec_ecdt = NULL;
1415
1416 return -ENODEV;
1417}
1418
02b28a33 1419static int __init acpi_ec_intr_get_real_ecdt(void)
1da177e4 1420{
50526df6
LB
1421 acpi_status status;
1422 struct acpi_table_ecdt *ecdt_ptr;
1da177e4 1423
451566f4 1424 status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
50526df6
LB
1425 (struct acpi_table_header **)
1426 &ecdt_ptr);
1da177e4
LT
1427 if (ACPI_FAILURE(status))
1428 return -ENODEV;
1429
1430 printk(KERN_INFO PREFIX "Found ECDT\n");
1431
1432 /*
1433 * Generate a temporary ec context to use until the namespace is scanned
1434 */
45bea155 1435 ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
1da177e4
LT
1436 if (!ec_ecdt)
1437 return -ENOMEM;
45bea155
LY
1438 memset(ec_ecdt, 0, sizeof(union acpi_ec));
1439
02b28a33
LB
1440 init_MUTEX(&ec_ecdt->intr.sem);
1441 init_waitqueue_head(&ec_ecdt->intr.wait);
45bea155
LY
1442 ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
1443 ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
1444 ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
1445 ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
1da177e4 1446 /* use the GL just to be safe */
45bea155
LY
1447 ec_ecdt->common.global_lock = TRUE;
1448 ec_ecdt->common.uid = ecdt_ptr->uid;
1da177e4 1449
50526df6
LB
1450 status =
1451 acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle);
1da177e4
LT
1452 if (ACPI_FAILURE(status)) {
1453 goto error;
1454 }
1455
1456 return 0;
50526df6 1457 error:
1da177e4
LT
1458 printk(KERN_ERR PREFIX "Could not use ECDT\n");
1459 kfree(ec_ecdt);
1460 ec_ecdt = NULL;
1461
1462 return -ENODEV;
1463}
1464
1465static int __initdata acpi_fake_ecdt_enabled;
50526df6 1466int __init acpi_ec_ecdt_probe(void)
1da177e4 1467{
50526df6
LB
1468 acpi_status status;
1469 int ret;
1da177e4
LT
1470
1471 ret = acpi_ec_get_real_ecdt();
1472 /* Try to make a fake ECDT */
1473 if (ret && acpi_fake_ecdt_enabled) {
1474 ret = acpi_ec_fake_ecdt();
1475 }
1476
1477 if (ret)
1478 return 0;
1479
1480 /*
1481 * Install GPE handler
1482 */
45bea155 1483 status = acpi_install_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
50526df6
LB
1484 ACPI_GPE_EDGE_TRIGGERED,
1485 &acpi_ec_gpe_handler, ec_ecdt);
1da177e4
LT
1486 if (ACPI_FAILURE(status)) {
1487 goto error;
1488 }
50526df6
LB
1489 acpi_set_gpe_type(NULL, ec_ecdt->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME);
1490 acpi_enable_gpe(NULL, ec_ecdt->common.gpe_bit, ACPI_NOT_ISR);
1491
1492 status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
1493 ACPI_ADR_SPACE_EC,
1494 &acpi_ec_space_handler,
1495 &acpi_ec_space_setup,
1496 ec_ecdt);
1da177e4 1497 if (ACPI_FAILURE(status)) {
45bea155 1498 acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
50526df6 1499 &acpi_ec_gpe_handler);
1da177e4
LT
1500 goto error;
1501 }
1502
1503 return 0;
1504
50526df6 1505 error:
1da177e4
LT
1506 printk(KERN_ERR PREFIX "Could not use ECDT\n");
1507 kfree(ec_ecdt);
1508 ec_ecdt = NULL;
1509
1510 return -ENODEV;
1511}
1512
50526df6 1513static int __init acpi_ec_init(void)
1da177e4 1514{
50526df6 1515 int result = 0;
1da177e4 1516
1da177e4
LT
1517
1518 if (acpi_disabled)
d550d98d 1519 return 0;
1da177e4
LT
1520
1521 acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir);
1522 if (!acpi_ec_dir)
d550d98d 1523 return -ENODEV;
1da177e4
LT
1524
1525 /* Now register the driver for the EC */
1526 result = acpi_bus_register_driver(&acpi_ec_driver);
1527 if (result < 0) {
1528 remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);
d550d98d 1529 return -ENODEV;
1da177e4
LT
1530 }
1531
d550d98d 1532 return result;
1da177e4
LT
1533}
1534
1535subsys_initcall(acpi_ec_init);
1536
1537/* EC driver currently not unloadable */
1538#if 0
50526df6 1539static void __exit acpi_ec_exit(void)
1da177e4 1540{
1da177e4
LT
1541
1542 acpi_bus_unregister_driver(&acpi_ec_driver);
1543
1544 remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir);
1545
d550d98d 1546 return;
1da177e4 1547}
50526df6 1548#endif /* 0 */
1da177e4
LT
1549
1550static int __init acpi_fake_ecdt_setup(char *str)
1551{
1552 acpi_fake_ecdt_enabled = 1;
9b41046c 1553 return 1;
1da177e4 1554}
7b15f5e7 1555
1da177e4 1556__setup("acpi_fake_ecdt", acpi_fake_ecdt_setup);
02b28a33 1557static int __init acpi_ec_set_intr_mode(char *str)
45bea155 1558{
02b28a33 1559 int intr;
7b15f5e7 1560
02b28a33 1561 if (!get_option(&str, &intr))
7b15f5e7
LY
1562 return 0;
1563
02b28a33
LB
1564 if (intr) {
1565 acpi_ec_poll_mode = EC_INTR;
1566 acpi_ec_driver.ops.add = acpi_ec_intr_add;
7b15f5e7 1567 } else {
02b28a33
LB
1568 acpi_ec_poll_mode = EC_POLL;
1569 acpi_ec_driver.ops.add = acpi_ec_poll_add;
7b15f5e7 1570 }
02b28a33 1571 printk(KERN_INFO PREFIX "EC %s mode.\n", intr ? "interrupt" : "polling");
9b41046c 1572 return 1;
45bea155 1573}
50526df6 1574
53f11d4f 1575__setup("ec_intr=", acpi_ec_set_intr_mode);
This page took 0.472438 seconds and 5 git commands to generate.