aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/ec.c
diff options
context:
space:
mode:
authorLuming Yu <luming.yu@intel.com>2005-09-27 00:43:00 -0400
committerLen Brown <len.brown@intel.com>2005-12-01 21:00:53 -0500
commit06a2a3855e20ed3df380d69b37130ba86bec8001 (patch)
treefc413825ef15496af219a527cbf0d21d9deff4f3 /drivers/acpi/ec.c
parent5666c0947ede0432ba5148570aa66ffb9febff5b (diff)
[ACPI] Disable EC burst mode w/o disabling EC interrupts
Need to de-couple the concept of polling/interrupts vs burst/non-burst. http://bugzilla.kernel.org/show_bug.cgi?id=4980 Signed-off-by: Luming Yu <luming.yu@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r--drivers/acpi/ec.c36
1 files changed, 20 insertions, 16 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 7e1a445955bc..6edfbe6f187c 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -213,19 +213,14 @@ static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event)
213 smp_mb(); 213 smp_mb();
214 214
215 switch (event) { 215 switch (event) {
216 case ACPI_EC_EVENT_OBF:
217 if (acpi_ec_read_status(ec) & event) {
218 ec->burst.expect_event = 0;
219 return_VALUE(0);
220 }
221 break;
222
223 case ACPI_EC_EVENT_IBE: 216 case ACPI_EC_EVENT_IBE:
224 if (~acpi_ec_read_status(ec) & event) { 217 if (~acpi_ec_read_status(ec) & event) {
225 ec->burst.expect_event = 0; 218 ec->burst.expect_event = 0;
226 return_VALUE(0); 219 return_VALUE(0);
227 } 220 }
228 break; 221 break;
222 default:
223 break;
229 } 224 }
230 225
231 result = wait_event_timeout(ec->burst.wait, 226 result = wait_event_timeout(ec->burst.wait,
@@ -255,7 +250,11 @@ static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event)
255 return_VALUE(-ETIME); 250 return_VALUE(-ETIME);
256} 251}
257 252
258static int acpi_ec_enter_burst_mode(union acpi_ec *ec) 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)
259{ 258{
260 u32 tmp = 0; 259 u32 tmp = 0;
261 int status = 0; 260 int status = 0;
@@ -270,8 +269,6 @@ static int acpi_ec_enter_burst_mode(union acpi_ec *ec)
270 acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, 269 acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE,
271 &ec->common.command_addr); 270 &ec->common.command_addr);
272 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); 271 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
273 if (status)
274 return_VALUE(-EINVAL);
275 acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr); 272 acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
276 if (tmp != 0x90) { /* Burst ACK byte */ 273 if (tmp != 0x90) { /* Burst ACK byte */
277 return_VALUE(-EINVAL); 274 return_VALUE(-EINVAL);
@@ -285,13 +282,25 @@ static int acpi_ec_enter_burst_mode(union acpi_ec *ec)
285 return_VALUE(-1); 282 return_VALUE(-1);
286} 283}
287 284
288static int acpi_ec_leave_burst_mode(union acpi_ec *ec) 285int acpi_ec_leave_burst_mode(union acpi_ec *ec)
289{ 286{
287 int status = 0;
290 288
291 ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode"); 289 ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode");
292 290
291 status = acpi_ec_read_status(ec);
292 if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){
293 status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
294 if(status)
295 goto end;
296 acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr);
297 acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
298 }
293 atomic_set(&ec->burst.leaving_burst, 1); 299 atomic_set(&ec->burst.leaving_burst, 1);
294 return_VALUE(0); 300 return_VALUE(0);
301end:
302 printk("leave burst_mode:error \n");
303 return_VALUE(-1);
295} 304}
296 305
297static int acpi_ec_read(union acpi_ec *ec, u8 address, u32 * data) 306static int acpi_ec_read(union acpi_ec *ec, u8 address, u32 * data)
@@ -424,7 +433,6 @@ static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data)
424 WARN_ON(in_interrupt()); 433 WARN_ON(in_interrupt());
425 down(&ec->burst.sem); 434 down(&ec->burst.sem);
426 435
427 acpi_ec_enter_burst_mode(ec);
428 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); 436 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
429 if (status) { 437 if (status) {
430 printk("read EC, IB not empty\n"); 438 printk("read EC, IB not empty\n");
@@ -448,7 +456,6 @@ static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data)
448 *data, address)); 456 *data, address));
449 457
450 end: 458 end:
451 acpi_ec_leave_burst_mode(ec);
452 up(&ec->burst.sem); 459 up(&ec->burst.sem);
453 460
454 if (ec->common.global_lock) 461 if (ec->common.global_lock)
@@ -476,8 +483,6 @@ static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data)
476 WARN_ON(in_interrupt()); 483 WARN_ON(in_interrupt());
477 down(&ec->burst.sem); 484 down(&ec->burst.sem);
478 485
479 acpi_ec_enter_burst_mode(ec);
480
481 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); 486 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
482 if (status) { 487 if (status) {
483 printk("write EC, IB not empty\n"); 488 printk("write EC, IB not empty\n");
@@ -500,7 +505,6 @@ static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data)
500 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", 505 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
501 data, address)); 506 data, address));
502 507
503 acpi_ec_leave_burst_mode(ec);
504 up(&ec->burst.sem); 508 up(&ec->burst.sem);
505 509
506 if (ec->common.global_lock) 510 if (ec->common.global_lock)