Loading drivers/acpi/ec.c +59 −112 Original line number Diff line number Diff line Loading @@ -212,19 +212,29 @@ static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event) ec->burst.expect_event = event; smp_mb(); result = wait_event_interruptible_timeout(ec->burst.wait, switch (event) { case ACPI_EC_EVENT_OBF: if (acpi_ec_read_status(ec) & event) { ec->burst.expect_event = 0; return_VALUE(0); } break; case ACPI_EC_EVENT_IBE: if (~acpi_ec_read_status(ec) & event) { ec->burst.expect_event = 0; return_VALUE(0); } break; } result = wait_event_timeout(ec->burst.wait, !ec->burst.expect_event, msecs_to_jiffies (ACPI_EC_DELAY)); msecs_to_jiffies(ACPI_EC_DELAY)); ec->burst.expect_event = 0; smp_mb(); if (result < 0) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, " result = %d ", result)); return_VALUE(result); } /* * Verify that the event in question has actually happened by * querying EC status. Do the check even if operation timed-out Loading Loading @@ -254,15 +264,15 @@ static int acpi_ec_enter_burst_mode(union acpi_ec *ec) status = acpi_ec_read_status(ec); if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) { status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) goto end; acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); if (status) { acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); if (status) return_VALUE(-EINVAL); } acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr); acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); if (tmp != 0x90) { /* Burst ACK byte */ return_VALUE(-EINVAL); } Loading @@ -270,30 +280,17 @@ static int acpi_ec_enter_burst_mode(union acpi_ec *ec) atomic_set(&ec->burst.leaving_burst, 0); return_VALUE(0); end: printk("Error in acpi_ec_wait\n"); return_VALUE(-1); } static int acpi_ec_leave_burst_mode(union acpi_ec *ec) { int status = 0; ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode"); atomic_set(&ec->burst.leaving_burst, 1); status = acpi_ec_read_status(ec); if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)) { acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); if (status) { acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "------->wait fail\n")); return_VALUE(-EINVAL); } acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); status = acpi_ec_read_status(ec); } return_VALUE(0); } Loading Loading @@ -416,7 +413,6 @@ static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data) if (!ec || !data) return_VALUE(-EINVAL); retry: *data = 0; if (ec->common.global_lock) { Loading @@ -428,27 +424,26 @@ static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data) WARN_ON(in_interrupt()); down(&ec->burst.sem); if (acpi_ec_enter_burst_mode(ec)) acpi_ec_enter_burst_mode(ec); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { printk("read EC, IB not empty\n"); goto end; } acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); if (status) { goto end; printk("read EC, IB not empty\n"); } acpi_hw_low_level_write(8, address, &ec->common.data_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); if (status) { acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); printk("read EC, OB not full\n"); goto end; } acpi_hw_low_level_read(8, data, &ec->common.data_addr); acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n", *data, address)); Loading @@ -459,15 +454,6 @@ static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data) if (ec->common.global_lock) acpi_release_global_lock(glk); if (atomic_read(&ec->burst.leaving_burst) == 2) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aborted, retry ...\n")); while (atomic_read(&ec->burst.pending_gpe)) { msleep(1); } acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); goto retry; } return_VALUE(status); } Loading @@ -475,13 +461,12 @@ static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data) { int status = 0; u32 glk; u32 tmp; ACPI_FUNCTION_TRACE("acpi_ec_write"); if (!ec) return_VALUE(-EINVAL); retry: if (ec->common.global_lock) { status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); if (ACPI_FAILURE(status)) Loading @@ -491,62 +476,36 @@ static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data) WARN_ON(in_interrupt()); down(&ec->burst.sem); if (acpi_ec_enter_burst_mode(ec)) goto end; acpi_ec_enter_burst_mode(ec); status = acpi_ec_read_status(ec); if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) { acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); if (status) goto end; acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr); if (tmp != 0x90) /* Burst ACK byte */ goto end; status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { printk("write EC, IB not empty\n"); } /*Now we are in burst mode */ acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); if (status) { goto end; printk("write EC, IB not empty\n"); } acpi_hw_low_level_write(8, address, &ec->common.data_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); goto end; printk("write EC, IB not empty\n"); } acpi_hw_low_level_write(8, data, &ec->common.data_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); if (status) goto end; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", data, address)); end: acpi_ec_leave_burst_mode(ec); up(&ec->burst.sem); if (ec->common.global_lock) acpi_release_global_lock(glk); if (atomic_read(&ec->burst.leaving_burst) == 2) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aborted, retry ...\n")); while (atomic_read(&ec->burst.pending_gpe)) { msleep(1); } acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); goto retry; } return_VALUE(status); } Loading Loading @@ -662,8 +621,12 @@ static int acpi_ec_burst_query(union acpi_ec *ec, u32 * data) } down(&ec->burst.sem); if (acpi_ec_enter_burst_mode(ec)) status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { printk("query EC, IB not empty\n"); goto end; } /* * Query the EC to find out which _Qxx method we need to evaluate. * Note that successful completion of the query causes the ACPI_EC_SCI Loading @@ -673,27 +636,20 @@ static int acpi_ec_burst_query(union acpi_ec *ec, u32 * data) &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); if (status) { acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); printk("query EC, OB not full\n"); goto end; } acpi_hw_low_level_read(8, data, &ec->common.data_addr); acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); if (!*data) status = -ENODATA; end: acpi_ec_leave_burst_mode(ec); up(&ec->burst.sem); if (ec->common.global_lock) acpi_release_global_lock(glk); if (atomic_read(&ec->burst.leaving_burst) == 2) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aborted, retry ...\n")); acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); status = -ENODATA; } return_VALUE(status); } Loading Loading @@ -818,31 +774,21 @@ static u32 acpi_ec_gpe_burst_handler(void *data) if (!ec) return ACPI_INTERRUPT_NOT_HANDLED; acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); acpi_clear_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); value = acpi_ec_read_status(ec); if ((value & ACPI_EC_FLAG_IBF) && !(value & ACPI_EC_FLAG_BURST) && (atomic_read(&ec->burst.leaving_burst) == 0)) { /* * the embedded controller disables * burst mode for any reason other * than the burst disable command * to process critical event. */ atomic_set(&ec->burst.leaving_burst, 2); /* block current pending transaction and retry */ wake_up(&ec->burst.wait); } else { if ((ec->burst.expect_event == ACPI_EC_EVENT_OBF && (value & ACPI_EC_FLAG_OBF)) || (ec->burst.expect_event == ACPI_EC_EVENT_IBE && !(value & ACPI_EC_FLAG_IBF))) { switch (ec->burst.expect_event) { case ACPI_EC_EVENT_OBF: if (!(value & ACPI_EC_FLAG_OBF)) break; case ACPI_EC_EVENT_IBE: if ((value & ACPI_EC_FLAG_IBF)) break; ec->burst.expect_event = 0; wake_up(&ec->burst.wait); return ACPI_INTERRUPT_HANDLED; } default: break; } if (value & ACPI_EC_FLAG_SCI) { Loading Loading @@ -1166,6 +1112,7 @@ static int acpi_ec_burst_add(struct acpi_device *device) if (result) goto end; printk("burst-mode-ec-10-Aug\n"); printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n", acpi_device_name(device), acpi_device_bid(device), (u32) ec->common.gpe_bit); Loading Loading
drivers/acpi/ec.c +59 −112 Original line number Diff line number Diff line Loading @@ -212,19 +212,29 @@ static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event) ec->burst.expect_event = event; smp_mb(); result = wait_event_interruptible_timeout(ec->burst.wait, switch (event) { case ACPI_EC_EVENT_OBF: if (acpi_ec_read_status(ec) & event) { ec->burst.expect_event = 0; return_VALUE(0); } break; case ACPI_EC_EVENT_IBE: if (~acpi_ec_read_status(ec) & event) { ec->burst.expect_event = 0; return_VALUE(0); } break; } result = wait_event_timeout(ec->burst.wait, !ec->burst.expect_event, msecs_to_jiffies (ACPI_EC_DELAY)); msecs_to_jiffies(ACPI_EC_DELAY)); ec->burst.expect_event = 0; smp_mb(); if (result < 0) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, " result = %d ", result)); return_VALUE(result); } /* * Verify that the event in question has actually happened by * querying EC status. Do the check even if operation timed-out Loading Loading @@ -254,15 +264,15 @@ static int acpi_ec_enter_burst_mode(union acpi_ec *ec) status = acpi_ec_read_status(ec); if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) { status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) goto end; acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); if (status) { acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); if (status) return_VALUE(-EINVAL); } acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr); acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); if (tmp != 0x90) { /* Burst ACK byte */ return_VALUE(-EINVAL); } Loading @@ -270,30 +280,17 @@ static int acpi_ec_enter_burst_mode(union acpi_ec *ec) atomic_set(&ec->burst.leaving_burst, 0); return_VALUE(0); end: printk("Error in acpi_ec_wait\n"); return_VALUE(-1); } static int acpi_ec_leave_burst_mode(union acpi_ec *ec) { int status = 0; ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode"); atomic_set(&ec->burst.leaving_burst, 1); status = acpi_ec_read_status(ec); if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)) { acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); if (status) { acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "------->wait fail\n")); return_VALUE(-EINVAL); } acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); status = acpi_ec_read_status(ec); } return_VALUE(0); } Loading Loading @@ -416,7 +413,6 @@ static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data) if (!ec || !data) return_VALUE(-EINVAL); retry: *data = 0; if (ec->common.global_lock) { Loading @@ -428,27 +424,26 @@ static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data) WARN_ON(in_interrupt()); down(&ec->burst.sem); if (acpi_ec_enter_burst_mode(ec)) acpi_ec_enter_burst_mode(ec); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { printk("read EC, IB not empty\n"); goto end; } acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); if (status) { goto end; printk("read EC, IB not empty\n"); } acpi_hw_low_level_write(8, address, &ec->common.data_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); if (status) { acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); printk("read EC, OB not full\n"); goto end; } acpi_hw_low_level_read(8, data, &ec->common.data_addr); acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n", *data, address)); Loading @@ -459,15 +454,6 @@ static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data) if (ec->common.global_lock) acpi_release_global_lock(glk); if (atomic_read(&ec->burst.leaving_burst) == 2) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aborted, retry ...\n")); while (atomic_read(&ec->burst.pending_gpe)) { msleep(1); } acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); goto retry; } return_VALUE(status); } Loading @@ -475,13 +461,12 @@ static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data) { int status = 0; u32 glk; u32 tmp; ACPI_FUNCTION_TRACE("acpi_ec_write"); if (!ec) return_VALUE(-EINVAL); retry: if (ec->common.global_lock) { status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); if (ACPI_FAILURE(status)) Loading @@ -491,62 +476,36 @@ static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data) WARN_ON(in_interrupt()); down(&ec->burst.sem); if (acpi_ec_enter_burst_mode(ec)) goto end; acpi_ec_enter_burst_mode(ec); status = acpi_ec_read_status(ec); if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) { acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); if (status) goto end; acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr); if (tmp != 0x90) /* Burst ACK byte */ goto end; status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { printk("write EC, IB not empty\n"); } /*Now we are in burst mode */ acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); if (status) { goto end; printk("write EC, IB not empty\n"); } acpi_hw_low_level_write(8, address, &ec->common.data_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); goto end; printk("write EC, IB not empty\n"); } acpi_hw_low_level_write(8, data, &ec->common.data_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); if (status) goto end; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", data, address)); end: acpi_ec_leave_burst_mode(ec); up(&ec->burst.sem); if (ec->common.global_lock) acpi_release_global_lock(glk); if (atomic_read(&ec->burst.leaving_burst) == 2) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aborted, retry ...\n")); while (atomic_read(&ec->burst.pending_gpe)) { msleep(1); } acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); goto retry; } return_VALUE(status); } Loading Loading @@ -662,8 +621,12 @@ static int acpi_ec_burst_query(union acpi_ec *ec, u32 * data) } down(&ec->burst.sem); if (acpi_ec_enter_burst_mode(ec)) status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { printk("query EC, IB not empty\n"); goto end; } /* * Query the EC to find out which _Qxx method we need to evaluate. * Note that successful completion of the query causes the ACPI_EC_SCI Loading @@ -673,27 +636,20 @@ static int acpi_ec_burst_query(union acpi_ec *ec, u32 * data) &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); if (status) { acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); printk("query EC, OB not full\n"); goto end; } acpi_hw_low_level_read(8, data, &ec->common.data_addr); acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); if (!*data) status = -ENODATA; end: acpi_ec_leave_burst_mode(ec); up(&ec->burst.sem); if (ec->common.global_lock) acpi_release_global_lock(glk); if (atomic_read(&ec->burst.leaving_burst) == 2) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "aborted, retry ...\n")); acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); status = -ENODATA; } return_VALUE(status); } Loading Loading @@ -818,31 +774,21 @@ static u32 acpi_ec_gpe_burst_handler(void *data) if (!ec) return ACPI_INTERRUPT_NOT_HANDLED; acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); acpi_clear_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); value = acpi_ec_read_status(ec); if ((value & ACPI_EC_FLAG_IBF) && !(value & ACPI_EC_FLAG_BURST) && (atomic_read(&ec->burst.leaving_burst) == 0)) { /* * the embedded controller disables * burst mode for any reason other * than the burst disable command * to process critical event. */ atomic_set(&ec->burst.leaving_burst, 2); /* block current pending transaction and retry */ wake_up(&ec->burst.wait); } else { if ((ec->burst.expect_event == ACPI_EC_EVENT_OBF && (value & ACPI_EC_FLAG_OBF)) || (ec->burst.expect_event == ACPI_EC_EVENT_IBE && !(value & ACPI_EC_FLAG_IBF))) { switch (ec->burst.expect_event) { case ACPI_EC_EVENT_OBF: if (!(value & ACPI_EC_FLAG_OBF)) break; case ACPI_EC_EVENT_IBE: if ((value & ACPI_EC_FLAG_IBF)) break; ec->burst.expect_event = 0; wake_up(&ec->burst.wait); return ACPI_INTERRUPT_HANDLED; } default: break; } if (value & ACPI_EC_FLAG_SCI) { Loading Loading @@ -1166,6 +1112,7 @@ static int acpi_ec_burst_add(struct acpi_device *device) if (result) goto end; printk("burst-mode-ec-10-Aug\n"); printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n", acpi_device_name(device), acpi_device_bid(device), (u32) ec->common.gpe_bit); Loading