Loading drivers/acpi/ec.c +38 −46 Original line number Original line Diff line number Diff line Loading @@ -46,6 +46,9 @@ ACPI_MODULE_NAME("acpi_ec") #define ACPI_EC_DEVICE_NAME "Embedded Controller" #define ACPI_EC_DEVICE_NAME "Embedded Controller" #define ACPI_EC_FILE_INFO "info" #define ACPI_EC_FILE_INFO "info" #undef PREFIX #define PREFIX "ACPI: EC: " /* EC status register */ /* EC status register */ #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ Loading Loading @@ -101,7 +104,6 @@ struct acpi_ec { unsigned long data_addr; unsigned long data_addr; unsigned long global_lock; unsigned long global_lock; struct semaphore sem; struct semaphore sem; unsigned int expect_event; atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ wait_queue_head_t wait; wait_queue_head_t wait; } *ec_ecdt; } *ec_ecdt; Loading Loading @@ -155,34 +157,25 @@ static int acpi_ec_check_status(struct acpi_ec *ec, u8 event) static int acpi_ec_wait(struct acpi_ec *ec, u8 event) static int acpi_ec_wait(struct acpi_ec *ec, u8 event) { { int i = (acpi_ec_mode == EC_POLL) ? ACPI_EC_UDELAY_COUNT : 0; long time_left; ec->expect_event = event; if (acpi_ec_check_status(ec, event)) { ec->expect_event = 0; return 0; } do { if (acpi_ec_mode == EC_POLL) { if (acpi_ec_mode == EC_POLL) { int i; for (i = 0; i < ACPI_EC_UDELAY_COUNT; ++i) { if (acpi_ec_check_status(ec, event)) return 0; udelay(ACPI_EC_UDELAY); udelay(ACPI_EC_UDELAY); } } else { } else { time_left = wait_event_timeout(ec->wait, if (wait_event_timeout(ec->wait, !ec->expect_event, acpi_ec_check_status(ec, event), msecs_to_jiffies(ACPI_EC_DELAY)); msecs_to_jiffies(ACPI_EC_DELAY)) || if (time_left > 0) { acpi_ec_check_status(ec, event)) { ec->expect_event = 0; return 0; return 0; } else { printk(KERN_ERR PREFIX "acpi_ec_wait timeout," " status = %d, expect_event = %d\n", acpi_ec_read_status(ec), event); } } } } if (acpi_ec_check_status(ec, event)) { ec->expect_event = 0; return 0; } } while (--i > 0); ec->expect_event = 0; return -ETIME; return -ETIME; } } Loading Loading @@ -243,32 +236,41 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, const u8 *wdata, unsigned wdata_len, const u8 *wdata, unsigned wdata_len, u8 *rdata, unsigned rdata_len) u8 *rdata, unsigned rdata_len) { { int result; int result = 0; acpi_ec_write_cmd(ec, command); acpi_ec_write_cmd(ec, command); for (; wdata_len > 0; wdata_len --) { for (; wdata_len > 0; wdata_len --) { result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); if (result) if (result) { return result; printk(KERN_ERR PREFIX "write_cmd timeout, command = %d\n", command); goto end; } acpi_ec_write_data(ec, *(wdata++)); acpi_ec_write_data(ec, *(wdata++)); } } if (!rdata_len) { if (!rdata_len) { result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); if (result) if (result) { return result; printk(KERN_ERR PREFIX "finish-write timeout, command = %d\n", command); goto end; } } } for (; rdata_len > 0; rdata_len --) { for (; rdata_len > 0; rdata_len --) { result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1); result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1); if (result) if (result) { return result; printk(KERN_ERR PREFIX "read timeout, command = %d\n", command); goto end; } *(rdata++) = acpi_ec_read_data(ec); *(rdata++) = acpi_ec_read_data(ec); } } end: return 0; return result; } } static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, Loading Loading @@ -419,11 +421,6 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 *data) Event Management Event Management -------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */ struct acpi_ec_query_data { acpi_handle handle; u8 data; }; static void acpi_ec_gpe_query(void *ec_cxt) static void acpi_ec_gpe_query(void *ec_cxt) { { struct acpi_ec *ec = (struct acpi_ec *)ec_cxt; struct acpi_ec *ec = (struct acpi_ec *)ec_cxt; Loading @@ -443,7 +440,7 @@ static void acpi_ec_gpe_query(void *ec_cxt) snprintf(object_name, 8, "_Q%2.2X", value); snprintf(object_name, 8, "_Q%2.2X", value); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name)); printk(KERN_INFO PREFIX "evaluating %s\n", object_name); acpi_evaluate_object(ec->handle, object_name, NULL, NULL); acpi_evaluate_object(ec->handle, object_name, NULL, NULL); Loading @@ -460,17 +457,12 @@ static u32 acpi_ec_gpe_handler(void *data) acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR); acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR); if (acpi_ec_mode == EC_INTR) { if (acpi_ec_mode == EC_INTR) { if (acpi_ec_check_status(ec, ec->expect_event)) { ec->expect_event = 0; wake_up(&ec->wait); wake_up(&ec->wait); } } } value = acpi_ec_read_status(ec); value = acpi_ec_read_status(ec); if (value & ACPI_EC_FLAG_SCI) { if (value & ACPI_EC_FLAG_SCI) { status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); return status == AE_OK ? ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; } } acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR); acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR); return status == AE_OK ? return status == AE_OK ? Loading Loading
drivers/acpi/ec.c +38 −46 Original line number Original line Diff line number Diff line Loading @@ -46,6 +46,9 @@ ACPI_MODULE_NAME("acpi_ec") #define ACPI_EC_DEVICE_NAME "Embedded Controller" #define ACPI_EC_DEVICE_NAME "Embedded Controller" #define ACPI_EC_FILE_INFO "info" #define ACPI_EC_FILE_INFO "info" #undef PREFIX #define PREFIX "ACPI: EC: " /* EC status register */ /* EC status register */ #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ Loading Loading @@ -101,7 +104,6 @@ struct acpi_ec { unsigned long data_addr; unsigned long data_addr; unsigned long global_lock; unsigned long global_lock; struct semaphore sem; struct semaphore sem; unsigned int expect_event; atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ wait_queue_head_t wait; wait_queue_head_t wait; } *ec_ecdt; } *ec_ecdt; Loading Loading @@ -155,34 +157,25 @@ static int acpi_ec_check_status(struct acpi_ec *ec, u8 event) static int acpi_ec_wait(struct acpi_ec *ec, u8 event) static int acpi_ec_wait(struct acpi_ec *ec, u8 event) { { int i = (acpi_ec_mode == EC_POLL) ? ACPI_EC_UDELAY_COUNT : 0; long time_left; ec->expect_event = event; if (acpi_ec_check_status(ec, event)) { ec->expect_event = 0; return 0; } do { if (acpi_ec_mode == EC_POLL) { if (acpi_ec_mode == EC_POLL) { int i; for (i = 0; i < ACPI_EC_UDELAY_COUNT; ++i) { if (acpi_ec_check_status(ec, event)) return 0; udelay(ACPI_EC_UDELAY); udelay(ACPI_EC_UDELAY); } } else { } else { time_left = wait_event_timeout(ec->wait, if (wait_event_timeout(ec->wait, !ec->expect_event, acpi_ec_check_status(ec, event), msecs_to_jiffies(ACPI_EC_DELAY)); msecs_to_jiffies(ACPI_EC_DELAY)) || if (time_left > 0) { acpi_ec_check_status(ec, event)) { ec->expect_event = 0; return 0; return 0; } else { printk(KERN_ERR PREFIX "acpi_ec_wait timeout," " status = %d, expect_event = %d\n", acpi_ec_read_status(ec), event); } } } } if (acpi_ec_check_status(ec, event)) { ec->expect_event = 0; return 0; } } while (--i > 0); ec->expect_event = 0; return -ETIME; return -ETIME; } } Loading Loading @@ -243,32 +236,41 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, const u8 *wdata, unsigned wdata_len, const u8 *wdata, unsigned wdata_len, u8 *rdata, unsigned rdata_len) u8 *rdata, unsigned rdata_len) { { int result; int result = 0; acpi_ec_write_cmd(ec, command); acpi_ec_write_cmd(ec, command); for (; wdata_len > 0; wdata_len --) { for (; wdata_len > 0; wdata_len --) { result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); if (result) if (result) { return result; printk(KERN_ERR PREFIX "write_cmd timeout, command = %d\n", command); goto end; } acpi_ec_write_data(ec, *(wdata++)); acpi_ec_write_data(ec, *(wdata++)); } } if (!rdata_len) { if (!rdata_len) { result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); if (result) if (result) { return result; printk(KERN_ERR PREFIX "finish-write timeout, command = %d\n", command); goto end; } } } for (; rdata_len > 0; rdata_len --) { for (; rdata_len > 0; rdata_len --) { result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1); result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1); if (result) if (result) { return result; printk(KERN_ERR PREFIX "read timeout, command = %d\n", command); goto end; } *(rdata++) = acpi_ec_read_data(ec); *(rdata++) = acpi_ec_read_data(ec); } } end: return 0; return result; } } static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, Loading Loading @@ -419,11 +421,6 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 *data) Event Management Event Management -------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */ struct acpi_ec_query_data { acpi_handle handle; u8 data; }; static void acpi_ec_gpe_query(void *ec_cxt) static void acpi_ec_gpe_query(void *ec_cxt) { { struct acpi_ec *ec = (struct acpi_ec *)ec_cxt; struct acpi_ec *ec = (struct acpi_ec *)ec_cxt; Loading @@ -443,7 +440,7 @@ static void acpi_ec_gpe_query(void *ec_cxt) snprintf(object_name, 8, "_Q%2.2X", value); snprintf(object_name, 8, "_Q%2.2X", value); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name)); printk(KERN_INFO PREFIX "evaluating %s\n", object_name); acpi_evaluate_object(ec->handle, object_name, NULL, NULL); acpi_evaluate_object(ec->handle, object_name, NULL, NULL); Loading @@ -460,17 +457,12 @@ static u32 acpi_ec_gpe_handler(void *data) acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR); acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR); if (acpi_ec_mode == EC_INTR) { if (acpi_ec_mode == EC_INTR) { if (acpi_ec_check_status(ec, ec->expect_event)) { ec->expect_event = 0; wake_up(&ec->wait); wake_up(&ec->wait); } } } value = acpi_ec_read_status(ec); value = acpi_ec_read_status(ec); if (value & ACPI_EC_FLAG_SCI) { if (value & ACPI_EC_FLAG_SCI) { status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); return status == AE_OK ? ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; } } acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR); acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR); return status == AE_OK ? return status == AE_OK ? Loading