aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/ec.c
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2005-07-12 17:21:56 -0400
committerLen Brown <len.brown@intel.com>2005-07-12 17:21:56 -0400
commit5028770a42e7bc4d15791a44c28f0ad539323807 (patch)
tree74800e35129775413c13ce7caf036ca19e3ce56c /drivers/acpi/ec.c
parent9f02d6b7b43d46a74dd385f06090104ecd0fb807 (diff)
parentd8683a0cb5d09cb7f19feefa708424a84577e68f (diff)
[ACPI] merge acpi-2.6.12 branch into latest Linux 2.6.13-rc...
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r--drivers/acpi/ec.c420
1 files changed, 288 insertions, 132 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index fdf143b405be..8e665f2e3138 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -31,6 +31,7 @@
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/proc_fs.h> 32#include <linux/proc_fs.h>
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34#include <linux/interrupt.h>
34#include <asm/io.h> 35#include <asm/io.h>
35#include <acpi/acpi_bus.h> 36#include <acpi/acpi_bus.h>
36#include <acpi/acpi_drivers.h> 37#include <acpi/acpi_drivers.h>
@@ -49,17 +50,19 @@ ACPI_MODULE_NAME ("acpi_ec")
49 50
50#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ 51#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */
51#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ 52#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */
53#define ACPI_EC_FLAG_BURST 0x10 /* burst mode */
52#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ 54#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */
53 55
54#define ACPI_EC_EVENT_OBF 0x01 /* Output buffer full */ 56#define ACPI_EC_EVENT_OBF 0x01 /* Output buffer full */
55#define ACPI_EC_EVENT_IBE 0x02 /* Input buffer empty */ 57#define ACPI_EC_EVENT_IBE 0x02 /* Input buffer empty */
56 58
57#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */ 59#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */
58#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */
59#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ 60#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
60 61
61#define ACPI_EC_COMMAND_READ 0x80 62#define ACPI_EC_COMMAND_READ 0x80
62#define ACPI_EC_COMMAND_WRITE 0x81 63#define ACPI_EC_COMMAND_WRITE 0x81
64#define ACPI_EC_BURST_ENABLE 0x82
65#define ACPI_EC_BURST_DISABLE 0x83
63#define ACPI_EC_COMMAND_QUERY 0x84 66#define ACPI_EC_COMMAND_QUERY 0x84
64 67
65static int acpi_ec_add (struct acpi_device *device); 68static int acpi_ec_add (struct acpi_device *device);
@@ -87,7 +90,11 @@ struct acpi_ec {
87 struct acpi_generic_address command_addr; 90 struct acpi_generic_address command_addr;
88 struct acpi_generic_address data_addr; 91 struct acpi_generic_address data_addr;
89 unsigned long global_lock; 92 unsigned long global_lock;
90 spinlock_t lock; 93 unsigned int expect_event;
94 atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort*/
95 atomic_t pending_gpe;
96 struct semaphore sem;
97 wait_queue_head_t wait;
91}; 98};
92 99
93/* If we find an EC via the ECDT, we need to keep a ptr to its context */ 100/* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@ -100,42 +107,122 @@ static struct acpi_device *first_ec;
100 Transaction Management 107 Transaction Management
101 -------------------------------------------------------------------------- */ 108 -------------------------------------------------------------------------- */
102 109
103static int 110static inline u32 acpi_ec_read_status(struct acpi_ec *ec)
104acpi_ec_wait (
105 struct acpi_ec *ec,
106 u8 event)
107{ 111{
108 u32 acpi_ec_status = 0; 112 u32 status = 0;
109 u32 i = ACPI_EC_UDELAY_COUNT;
110 113
111 if (!ec) 114 acpi_hw_low_level_read(8, &status, &ec->status_addr);
112 return -EINVAL; 115 return status;
116}
117
118static int acpi_ec_wait(struct acpi_ec *ec, unsigned int event)
119{
120 int result = 0;
121
122 ACPI_FUNCTION_TRACE("acpi_ec_wait");
113 123
114 /* Poll the EC status register waiting for the event to occur. */ 124 ec->expect_event = event;
125 smp_mb();
126
127 result = wait_event_interruptible_timeout(ec->wait,
128 !ec->expect_event,
129 msecs_to_jiffies(ACPI_EC_DELAY));
130
131 ec->expect_event = 0;
132 smp_mb();
133
134 if (result < 0){
135 ACPI_DEBUG_PRINT((ACPI_DB_ERROR," result = %d ", result));
136 return_VALUE(result);
137 }
138
139 /*
140 * Verify that the event in question has actually happened by
141 * querying EC status. Do the check even if operation timed-out
142 * to make sure that we did not miss interrupt.
143 */
115 switch (event) { 144 switch (event) {
116 case ACPI_EC_EVENT_OBF: 145 case ACPI_EC_EVENT_OBF:
117 do { 146 if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
118 acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr); 147 return_VALUE(0);
119 if (acpi_ec_status & ACPI_EC_FLAG_OBF)
120 return 0;
121 udelay(ACPI_EC_UDELAY);
122 } while (--i>0);
123 break; 148 break;
149
124 case ACPI_EC_EVENT_IBE: 150 case ACPI_EC_EVENT_IBE:
125 do { 151 if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
126 acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr); 152 return_VALUE(0);
127 if (!(acpi_ec_status & ACPI_EC_FLAG_IBF))
128 return 0;
129 udelay(ACPI_EC_UDELAY);
130 } while (--i>0);
131 break; 153 break;
132 default:
133 return -EINVAL;
134 } 154 }
135 155
136 return -ETIME; 156 return_VALUE(-ETIME);
157}
158
159
160
161static int
162acpi_ec_enter_burst_mode (
163 struct acpi_ec *ec)
164{
165 u32 tmp = 0;
166 int status = 0;
167
168 ACPI_FUNCTION_TRACE("acpi_ec_enter_burst_mode");
169
170 status = acpi_ec_read_status(ec);
171 if (status != -EINVAL &&
172 !(status & ACPI_EC_FLAG_BURST)){
173 ACPI_DEBUG_PRINT((ACPI_DB_INFO,"entering burst mode \n"));
174 acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->command_addr);
175 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
176 if (status){
177 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
178 ACPI_DEBUG_PRINT((ACPI_DB_ERROR," status = %d\n", status));
179 return_VALUE(-EINVAL);
180 }
181 acpi_hw_low_level_read(8, &tmp, &ec->data_addr);
182 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
183 if(tmp != 0x90 ) {/* Burst ACK byte*/
184 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"Ack failed \n"));
185 return_VALUE(-EINVAL);
186 }
187 } else
188 ACPI_DEBUG_PRINT((ACPI_DB_INFO,"already be in burst mode \n"));
189 atomic_set(&ec->leaving_burst , 0);
190 return_VALUE(0);
137} 191}
138 192
193static int
194acpi_ec_leave_burst_mode (
195 struct acpi_ec *ec)
196{
197 int status =0;
198
199 ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode");
200
201 atomic_set(&ec->leaving_burst , 1);
202 status = acpi_ec_read_status(ec);
203 if (status != -EINVAL &&
204 (status & ACPI_EC_FLAG_BURST)){
205 ACPI_DEBUG_PRINT((ACPI_DB_INFO,"leaving burst mode\n"));
206 acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->command_addr);
207 status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
208 if (status){
209 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
210 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"------->wait fail\n"));
211 return_VALUE(-EINVAL);
212 }
213 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
214 status = acpi_ec_read_status(ec);
215 if (status != -EINVAL &&
216 (status & ACPI_EC_FLAG_BURST)) {
217 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"------->status fail\n"));
218 return_VALUE(-EINVAL);
219 }
220 }else
221 ACPI_DEBUG_PRINT((ACPI_DB_INFO,"already be in Non-burst mode \n"));
222 ACPI_DEBUG_PRINT((ACPI_DB_INFO,"leaving burst mode\n"));
223
224 return_VALUE(0);
225}
139 226
140static int 227static int
141acpi_ec_read ( 228acpi_ec_read (
@@ -143,16 +230,15 @@ acpi_ec_read (
143 u8 address, 230 u8 address,
144 u32 *data) 231 u32 *data)
145{ 232{
146 acpi_status status = AE_OK; 233 int status = 0;
147 int result = 0; 234 u32 glk;
148 unsigned long flags = 0;
149 u32 glk = 0;
150 235
151 ACPI_FUNCTION_TRACE("acpi_ec_read"); 236 ACPI_FUNCTION_TRACE("acpi_ec_read");
152 237
153 if (!ec || !data) 238 if (!ec || !data)
154 return_VALUE(-EINVAL); 239 return_VALUE(-EINVAL);
155 240
241retry:
156 *data = 0; 242 *data = 0;
157 243
158 if (ec->global_lock) { 244 if (ec->global_lock) {
@@ -160,32 +246,50 @@ acpi_ec_read (
160 if (ACPI_FAILURE(status)) 246 if (ACPI_FAILURE(status))
161 return_VALUE(-ENODEV); 247 return_VALUE(-ENODEV);
162 } 248 }
163 249
164 spin_lock_irqsave(&ec->lock, flags); 250 WARN_ON(in_interrupt());
251 down(&ec->sem);
252
253 if(acpi_ec_enter_burst_mode(ec))
254 goto end;
165 255
166 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr); 256 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr);
167 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); 257 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
168 if (result) 258 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
259 if (status) {
169 goto end; 260 goto end;
261 }
170 262
171 acpi_hw_low_level_write(8, address, &ec->data_addr); 263 acpi_hw_low_level_write(8, address, &ec->data_addr);
172 result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); 264 status= acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
173 if (result) 265 if (status){
266 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
174 goto end; 267 goto end;
175 268 }
176 269
177 acpi_hw_low_level_read(8, data, &ec->data_addr); 270 acpi_hw_low_level_read(8, data, &ec->data_addr);
271 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
178 272
179 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n", 273 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
180 *data, address)); 274 *data, address));
181 275
182end: 276end:
183 spin_unlock_irqrestore(&ec->lock, flags); 277 acpi_ec_leave_burst_mode(ec);
278 up(&ec->sem);
184 279
185 if (ec->global_lock) 280 if (ec->global_lock)
186 acpi_release_global_lock(glk); 281 acpi_release_global_lock(glk);
187 282
188 return_VALUE(result); 283 if(atomic_read(&ec->leaving_burst) == 2){
284 ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
285 while(atomic_read(&ec->pending_gpe)){
286 msleep(1);
287 }
288 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
289 goto retry;
290 }
291
292 return_VALUE(status);
189} 293}
190 294
191 295
@@ -195,49 +299,80 @@ acpi_ec_write (
195 u8 address, 299 u8 address,
196 u8 data) 300 u8 data)
197{ 301{
198 int result = 0; 302 int status = 0;
199 acpi_status status = AE_OK; 303 u32 glk;
200 unsigned long flags = 0; 304 u32 tmp;
201 u32 glk = 0;
202 305
203 ACPI_FUNCTION_TRACE("acpi_ec_write"); 306 ACPI_FUNCTION_TRACE("acpi_ec_write");
204 307
205 if (!ec) 308 if (!ec)
206 return_VALUE(-EINVAL); 309 return_VALUE(-EINVAL);
207 310retry:
208 if (ec->global_lock) { 311 if (ec->global_lock) {
209 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); 312 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
210 if (ACPI_FAILURE(status)) 313 if (ACPI_FAILURE(status))
211 return_VALUE(-ENODEV); 314 return_VALUE(-ENODEV);
212 } 315 }
213 316
214 spin_lock_irqsave(&ec->lock, flags); 317 WARN_ON(in_interrupt());
318 down(&ec->sem);
319
320 if(acpi_ec_enter_burst_mode(ec))
321 goto end;
322
323 status = acpi_ec_read_status(ec);
324 if (status != -EINVAL &&
325 !(status & ACPI_EC_FLAG_BURST)){
326 acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->command_addr);
327 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
328 if (status)
329 goto end;
330 acpi_hw_low_level_read(8, &tmp, &ec->data_addr);
331 if(tmp != 0x90 ) /* Burst ACK byte*/
332 goto end;
333 }
334 /*Now we are in burst mode*/
215 335
216 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr); 336 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr);
217 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); 337 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
218 if (result) 338 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
339 if (status){
219 goto end; 340 goto end;
341 }
220 342
221 acpi_hw_low_level_write(8, address, &ec->data_addr); 343 acpi_hw_low_level_write(8, address, &ec->data_addr);
222 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); 344 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
223 if (result) 345 if (status){
346 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
224 goto end; 347 goto end;
348 }
225 349
226 acpi_hw_low_level_write(8, data, &ec->data_addr); 350 acpi_hw_low_level_write(8, data, &ec->data_addr);
227 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); 351 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
228 if (result) 352 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
353 if (status)
229 goto end; 354 goto end;
230 355
231 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", 356 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
232 data, address)); 357 data, address));
233 358
234end: 359end:
235 spin_unlock_irqrestore(&ec->lock, flags); 360 acpi_ec_leave_burst_mode(ec);
361 up(&ec->sem);
236 362
237 if (ec->global_lock) 363 if (ec->global_lock)
238 acpi_release_global_lock(glk); 364 acpi_release_global_lock(glk);
239 365
240 return_VALUE(result); 366 if(atomic_read(&ec->leaving_burst) == 2){
367 ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
368 while(atomic_read(&ec->pending_gpe)){
369 msleep(1);
370 }
371 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
372 goto retry;
373 }
374
375 return_VALUE(status);
241} 376}
242 377
243/* 378/*
@@ -289,16 +424,13 @@ acpi_ec_query (
289 struct acpi_ec *ec, 424 struct acpi_ec *ec,
290 u32 *data) 425 u32 *data)
291{ 426{
292 int result = 0; 427 int status = 0;
293 acpi_status status = AE_OK; 428 u32 glk;
294 unsigned long flags = 0;
295 u32 glk = 0;
296 429
297 ACPI_FUNCTION_TRACE("acpi_ec_query"); 430 ACPI_FUNCTION_TRACE("acpi_ec_query");
298 431
299 if (!ec || !data) 432 if (!ec || !data)
300 return_VALUE(-EINVAL); 433 return_VALUE(-EINVAL);
301
302 *data = 0; 434 *data = 0;
303 435
304 if (ec->global_lock) { 436 if (ec->global_lock) {
@@ -307,29 +439,39 @@ acpi_ec_query (
307 return_VALUE(-ENODEV); 439 return_VALUE(-ENODEV);
308 } 440 }
309 441
442 down(&ec->sem);
443 if(acpi_ec_enter_burst_mode(ec))
444 goto end;
310 /* 445 /*
311 * Query the EC to find out which _Qxx method we need to evaluate. 446 * Query the EC to find out which _Qxx method we need to evaluate.
312 * Note that successful completion of the query causes the ACPI_EC_SCI 447 * Note that successful completion of the query causes the ACPI_EC_SCI
313 * bit to be cleared (and thus clearing the interrupt source). 448 * bit to be cleared (and thus clearing the interrupt source).
314 */ 449 */
315 spin_lock_irqsave(&ec->lock, flags);
316
317 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr); 450 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr);
318 result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); 451 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
319 if (result) 452 if (status){
453 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
320 goto end; 454 goto end;
321 455 }
456
322 acpi_hw_low_level_read(8, data, &ec->data_addr); 457 acpi_hw_low_level_read(8, data, &ec->data_addr);
458 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
323 if (!*data) 459 if (!*data)
324 result = -ENODATA; 460 status = -ENODATA;
325 461
326end: 462end:
327 spin_unlock_irqrestore(&ec->lock, flags); 463 acpi_ec_leave_burst_mode(ec);
464 up(&ec->sem);
328 465
329 if (ec->global_lock) 466 if (ec->global_lock)
330 acpi_release_global_lock(glk); 467 acpi_release_global_lock(glk);
331 468
332 return_VALUE(result); 469 if(atomic_read(&ec->leaving_burst) == 2){
470 ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
471 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
472 status = -ENODATA;
473 }
474 return_VALUE(status);
333} 475}
334 476
335 477
@@ -347,42 +489,29 @@ acpi_ec_gpe_query (
347 void *ec_cxt) 489 void *ec_cxt)
348{ 490{
349 struct acpi_ec *ec = (struct acpi_ec *) ec_cxt; 491 struct acpi_ec *ec = (struct acpi_ec *) ec_cxt;
350 u32 value = 0; 492 u32 value;
351 unsigned long flags = 0; 493 int result = -ENODATA;
352 static char object_name[5] = {'_','Q','0','0','\0'}; 494 static char object_name[5] = {'_','Q','0','0','\0'};
353 const char hex[] = {'0','1','2','3','4','5','6','7', 495 const char hex[] = {'0','1','2','3','4','5','6','7',
354 '8','9','A','B','C','D','E','F'}; 496 '8','9','A','B','C','D','E','F'};
355 497
356 ACPI_FUNCTION_TRACE("acpi_ec_gpe_query"); 498 ACPI_FUNCTION_TRACE("acpi_ec_gpe_query");
357 499
358 if (!ec_cxt) 500 if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI)
359 goto end; 501 result = acpi_ec_query(ec, &value);
360
361 spin_lock_irqsave(&ec->lock, flags);
362 acpi_hw_low_level_read(8, &value, &ec->command_addr);
363 spin_unlock_irqrestore(&ec->lock, flags);
364 502
365 /* TBD: Implement asynch events! 503 if (result)
366 * NOTE: All we care about are EC-SCI's. Other EC events are
367 * handled via polling (yuck!). This is because some systems
368 * treat EC-SCIs as level (versus EDGE!) triggered, preventing
369 * a purely interrupt-driven approach (grumble, grumble).
370 */
371 if (!(value & ACPI_EC_FLAG_SCI))
372 goto end; 504 goto end;
373 505
374 if (acpi_ec_query(ec, &value))
375 goto end;
376
377 object_name[2] = hex[((value >> 4) & 0x0F)]; 506 object_name[2] = hex[((value >> 4) & 0x0F)];
378 object_name[3] = hex[(value & 0x0F)]; 507 object_name[3] = hex[(value & 0x0F)];
379 508
380 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name)); 509 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
381 510
382 acpi_evaluate_object(ec->handle, object_name, NULL, NULL); 511 acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
383 512end:
384end: 513 atomic_dec(&ec->pending_gpe);
385 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); 514 return;
386} 515}
387 516
388static u32 517static u32
@@ -390,6 +519,7 @@ acpi_ec_gpe_handler (
390 void *data) 519 void *data)
391{ 520{
392 acpi_status status = AE_OK; 521 acpi_status status = AE_OK;
522 u32 value;
393 struct acpi_ec *ec = (struct acpi_ec *) data; 523 struct acpi_ec *ec = (struct acpi_ec *) data;
394 524
395 if (!ec) 525 if (!ec)
@@ -397,13 +527,41 @@ acpi_ec_gpe_handler (
397 527
398 acpi_disable_gpe(NULL, ec->gpe_bit, ACPI_ISR); 528 acpi_disable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
399 529
400 status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, 530 value = acpi_ec_read_status(ec);
401 acpi_ec_gpe_query, ec);
402 531
403 if (status == AE_OK) 532 if((value & ACPI_EC_FLAG_IBF) &&
404 return ACPI_INTERRUPT_HANDLED; 533 !(value & ACPI_EC_FLAG_BURST) &&
405 else 534 (atomic_read(&ec->leaving_burst) == 0)) {
406 return ACPI_INTERRUPT_NOT_HANDLED; 535 /*
536 * the embedded controller disables
537 * burst mode for any reason other
538 * than the burst disable command
539 * to process critical event.
540 */
541 atomic_set(&ec->leaving_burst , 2); /* block current pending transaction
542 and retry */
543 wake_up(&ec->wait);
544 }else {
545 if ((ec->expect_event == ACPI_EC_EVENT_OBF &&
546 (value & ACPI_EC_FLAG_OBF)) ||
547 (ec->expect_event == ACPI_EC_EVENT_IBE &&
548 !(value & ACPI_EC_FLAG_IBF))) {
549 ec->expect_event = 0;
550 wake_up(&ec->wait);
551 return ACPI_INTERRUPT_HANDLED;
552 }
553 }
554
555 if (value & ACPI_EC_FLAG_SCI){
556 atomic_add(1, &ec->pending_gpe) ;
557 status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
558 acpi_ec_gpe_query, ec);
559 return status == AE_OK ?
560 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
561 }
562 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
563 return status == AE_OK ?
564 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
407} 565}
408 566
409/* -------------------------------------------------------------------------- 567/* --------------------------------------------------------------------------
@@ -421,10 +579,8 @@ acpi_ec_space_setup (
421 * The EC object is in the handler context and is needed 579 * The EC object is in the handler context and is needed
422 * when calling the acpi_ec_space_handler. 580 * when calling the acpi_ec_space_handler.
423 */ 581 */
424 if(function == ACPI_REGION_DEACTIVATE) 582 *return_context = (function != ACPI_REGION_DEACTIVATE) ?
425 *return_context = NULL; 583 handler_context : NULL;
426 else
427 *return_context = handler_context;
428 584
429 return AE_OK; 585 return AE_OK;
430} 586}
@@ -441,7 +597,7 @@ acpi_ec_space_handler (
441{ 597{
442 int result = 0; 598 int result = 0;
443 struct acpi_ec *ec = NULL; 599 struct acpi_ec *ec = NULL;
444 u32 temp = 0; 600 u64 temp = *value;
445 acpi_integer f_v = 0; 601 acpi_integer f_v = 0;
446 int i = 0; 602 int i = 0;
447 603
@@ -450,10 +606,9 @@ acpi_ec_space_handler (
450 if ((address > 0xFF) || !value || !handler_context) 606 if ((address > 0xFF) || !value || !handler_context)
451 return_VALUE(AE_BAD_PARAMETER); 607 return_VALUE(AE_BAD_PARAMETER);
452 608
453 if(bit_width != 8) { 609 if (bit_width != 8 && acpi_strict) {
454 printk(KERN_WARNING PREFIX "acpi_ec_space_handler: bit_width should be 8\n"); 610 printk(KERN_WARNING PREFIX "acpi_ec_space_handler: bit_width should be 8\n");
455 if (acpi_strict) 611 return_VALUE(AE_BAD_PARAMETER);
456 return_VALUE(AE_BAD_PARAMETER);
457 } 612 }
458 613
459 ec = (struct acpi_ec *) handler_context; 614 ec = (struct acpi_ec *) handler_context;
@@ -461,11 +616,11 @@ acpi_ec_space_handler (
461next_byte: 616next_byte:
462 switch (function) { 617 switch (function) {
463 case ACPI_READ: 618 case ACPI_READ:
464 result = acpi_ec_read(ec, (u8) address, &temp); 619 temp = 0;
465 *value = (acpi_integer) temp; 620 result = acpi_ec_read(ec, (u8) address, (u32 *)&temp);
466 break; 621 break;
467 case ACPI_WRITE: 622 case ACPI_WRITE:
468 result = acpi_ec_write(ec, (u8) address, (u8) *value); 623 result = acpi_ec_write(ec, (u8) address, (u8) temp);
469 break; 624 break;
470 default: 625 default:
471 result = -EINVAL; 626 result = -EINVAL;
@@ -474,19 +629,18 @@ next_byte:
474 } 629 }
475 630
476 bit_width -= 8; 631 bit_width -= 8;
477 if(bit_width){ 632 if (bit_width) {
478 633 if (function == ACPI_READ)
479 if(function == ACPI_READ) 634 f_v |= temp << 8 * i;
480 f_v |= (acpi_integer) (*value) << 8*i; 635 if (function == ACPI_WRITE)
481 if(function == ACPI_WRITE) 636 temp >>= 8;
482 (*value) >>=8;
483 i++; 637 i++;
638 address++;
484 goto next_byte; 639 goto next_byte;
485 } 640 }
486 641
487 642 if (function == ACPI_READ) {
488 if(function == ACPI_READ){ 643 f_v |= temp << 8 * i;
489 f_v |= (acpi_integer) (*value) << 8*i;
490 *value = f_v; 644 *value = f_v;
491 } 645 }
492 646
@@ -505,8 +659,6 @@ out:
505 default: 659 default:
506 return_VALUE(AE_OK); 660 return_VALUE(AE_OK);
507 } 661 }
508
509
510} 662}
511 663
512 664
@@ -533,6 +685,7 @@ acpi_ec_read_info (struct seq_file *seq, void *offset)
533 (u32) ec->status_addr.address, (u32) ec->data_addr.address); 685 (u32) ec->status_addr.address, (u32) ec->data_addr.address);
534 seq_printf(seq, "use global lock: %s\n", 686 seq_printf(seq, "use global lock: %s\n",
535 ec->global_lock?"yes":"no"); 687 ec->global_lock?"yes":"no");
688 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
536 689
537end: 690end:
538 return_VALUE(0); 691 return_VALUE(0);
@@ -555,7 +708,7 @@ static int
555acpi_ec_add_fs ( 708acpi_ec_add_fs (
556 struct acpi_device *device) 709 struct acpi_device *device)
557{ 710{
558 struct proc_dir_entry *entry = NULL; 711 struct proc_dir_entry *entry;
559 712
560 ACPI_FUNCTION_TRACE("acpi_ec_add_fs"); 713 ACPI_FUNCTION_TRACE("acpi_ec_add_fs");
561 714
@@ -606,9 +759,9 @@ static int
606acpi_ec_add ( 759acpi_ec_add (
607 struct acpi_device *device) 760 struct acpi_device *device)
608{ 761{
609 int result = 0; 762 int result;
610 acpi_status status = AE_OK; 763 acpi_status status;
611 struct acpi_ec *ec = NULL; 764 struct acpi_ec *ec;
612 unsigned long uid; 765 unsigned long uid;
613 766
614 ACPI_FUNCTION_TRACE("acpi_ec_add"); 767 ACPI_FUNCTION_TRACE("acpi_ec_add");
@@ -623,7 +776,10 @@ acpi_ec_add (
623 776
624 ec->handle = device->handle; 777 ec->handle = device->handle;
625 ec->uid = -1; 778 ec->uid = -1;
626 spin_lock_init(&ec->lock); 779 atomic_set(&ec->pending_gpe, 0);
780 atomic_set(&ec->leaving_burst , 1);
781 init_MUTEX(&ec->sem);
782 init_waitqueue_head(&ec->wait);
627 strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); 783 strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
628 strcpy(acpi_device_class(device), ACPI_EC_CLASS); 784 strcpy(acpi_device_class(device), ACPI_EC_CLASS);
629 acpi_driver_data(device) = ec; 785 acpi_driver_data(device) = ec;
@@ -637,7 +793,7 @@ acpi_ec_add (
637 if (ec_ecdt && ec_ecdt->uid == uid) { 793 if (ec_ecdt && ec_ecdt->uid == uid) {
638 acpi_remove_address_space_handler(ACPI_ROOT_OBJECT, 794 acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
639 ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); 795 ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
640 796
641 acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, &acpi_ec_gpe_handler); 797 acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, &acpi_ec_gpe_handler);
642 798
643 kfree(ec_ecdt); 799 kfree(ec_ecdt);
@@ -677,7 +833,7 @@ acpi_ec_remove (
677 struct acpi_device *device, 833 struct acpi_device *device,
678 int type) 834 int type)
679{ 835{
680 struct acpi_ec *ec = NULL; 836 struct acpi_ec *ec;
681 837
682 ACPI_FUNCTION_TRACE("acpi_ec_remove"); 838 ACPI_FUNCTION_TRACE("acpi_ec_remove");
683 839
@@ -732,8 +888,8 @@ static int
732acpi_ec_start ( 888acpi_ec_start (
733 struct acpi_device *device) 889 struct acpi_device *device)
734{ 890{
735 acpi_status status = AE_OK; 891 acpi_status status;
736 struct acpi_ec *ec = NULL; 892 struct acpi_ec *ec;
737 893
738 ACPI_FUNCTION_TRACE("acpi_ec_start"); 894 ACPI_FUNCTION_TRACE("acpi_ec_start");
739 895
@@ -789,8 +945,8 @@ acpi_ec_stop (
789 struct acpi_device *device, 945 struct acpi_device *device,
790 int type) 946 int type)
791{ 947{
792 acpi_status status = AE_OK; 948 acpi_status status;
793 struct acpi_ec *ec = NULL; 949 struct acpi_ec *ec;
794 950
795 ACPI_FUNCTION_TRACE("acpi_ec_stop"); 951 ACPI_FUNCTION_TRACE("acpi_ec_stop");
796 952
@@ -832,7 +988,6 @@ acpi_fake_ecdt_callback (
832 status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->gpe_bit); 988 status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->gpe_bit);
833 if (ACPI_FAILURE(status)) 989 if (ACPI_FAILURE(status))
834 return status; 990 return status;
835 spin_lock_init(&ec_ecdt->lock);
836 ec_ecdt->global_lock = TRUE; 991 ec_ecdt->global_lock = TRUE;
837 ec_ecdt->handle = handle; 992 ec_ecdt->handle = handle;
838 993
@@ -890,7 +1045,7 @@ acpi_ec_get_real_ecdt(void)
890 acpi_status status; 1045 acpi_status status;
891 struct acpi_table_ecdt *ecdt_ptr; 1046 struct acpi_table_ecdt *ecdt_ptr;
892 1047
893 status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, 1048 status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
894 (struct acpi_table_header **) &ecdt_ptr); 1049 (struct acpi_table_header **) &ecdt_ptr);
895 if (ACPI_FAILURE(status)) 1050 if (ACPI_FAILURE(status))
896 return -ENODEV; 1051 return -ENODEV;
@@ -905,11 +1060,12 @@ acpi_ec_get_real_ecdt(void)
905 return -ENOMEM; 1060 return -ENOMEM;
906 memset(ec_ecdt, 0, sizeof(struct acpi_ec)); 1061 memset(ec_ecdt, 0, sizeof(struct acpi_ec));
907 1062
1063 init_MUTEX(&ec_ecdt->sem);
1064 init_waitqueue_head(&ec_ecdt->wait);
908 ec_ecdt->command_addr = ecdt_ptr->ec_control; 1065 ec_ecdt->command_addr = ecdt_ptr->ec_control;
909 ec_ecdt->status_addr = ecdt_ptr->ec_control; 1066 ec_ecdt->status_addr = ecdt_ptr->ec_control;
910 ec_ecdt->data_addr = ecdt_ptr->ec_data; 1067 ec_ecdt->data_addr = ecdt_ptr->ec_data;
911 ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit; 1068 ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit;
912 spin_lock_init(&ec_ecdt->lock);
913 /* use the GL just to be safe */ 1069 /* use the GL just to be safe */
914 ec_ecdt->global_lock = TRUE; 1070 ec_ecdt->global_lock = TRUE;
915 ec_ecdt->uid = ecdt_ptr->uid; 1071 ec_ecdt->uid = ecdt_ptr->uid;
@@ -978,7 +1134,7 @@ error:
978 1134
979static int __init acpi_ec_init (void) 1135static int __init acpi_ec_init (void)
980{ 1136{
981 int result = 0; 1137 int result;
982 1138
983 ACPI_FUNCTION_TRACE("acpi_ec_init"); 1139 ACPI_FUNCTION_TRACE("acpi_ec_init");
984 1140