Loading drivers/acpi/ec.c +389 −480 Original line number Diff line number Diff line Loading @@ -39,39 +39,29 @@ #define _COMPONENT ACPI_EC_COMPONENT ACPI_MODULE_NAME("acpi_ec") #define ACPI_EC_COMPONENT 0x00100000 #define ACPI_EC_CLASS "embedded_controller" #define ACPI_EC_HID "PNP0C09" #define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver" #define ACPI_EC_DEVICE_NAME "Embedded Controller" #define ACPI_EC_FILE_INFO "info" #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ #define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ #define ACPI_EC_EVENT_OBF 0x01 /* Output buffer full */ #define ACPI_EC_EVENT_IBE 0x02 /* Input buffer empty */ #define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */ #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ #define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */ #define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */ #define ACPI_EC_COMMAND_READ 0x80 #define ACPI_EC_COMMAND_WRITE 0x81 #define ACPI_EC_BURST_ENABLE 0x82 #define ACPI_EC_BURST_DISABLE 0x83 #define ACPI_EC_COMMAND_QUERY 0x84 #define EC_POLLING 0xFF #define EC_BURST 0x00 static int acpi_ec_remove(struct acpi_device *device, int type); static int acpi_ec_start(struct acpi_device *device); static int acpi_ec_stop(struct acpi_device *device, int type); Loading Loading @@ -143,23 +133,15 @@ static void acpi_ec_gpe_burst_query ( void *ec_cxt); static u32 acpi_ec_gpe_polling_handler(void *data); static u32 acpi_ec_gpe_burst_handler(void *data); static acpi_status __init acpi_fake_ecdt_polling_callback ( acpi_handle handle, u32 Level, void *context, void **retval); acpi_fake_ecdt_polling_callback(acpi_handle handle, u32 Level, void *context, void **retval); static acpi_status __init acpi_fake_ecdt_burst_callback ( acpi_handle handle, u32 Level, void *context, void **retval); static int __init acpi_ec_polling_get_real_ecdt(void); static int __init acpi_ec_burst_get_real_ecdt(void); acpi_fake_ecdt_burst_callback(acpi_handle handle, u32 Level, void *context, void **retval); static int __init acpi_ec_polling_get_real_ecdt(void); static int __init acpi_ec_burst_get_real_ecdt(void); /* If we find an EC via the ECDT, we need to keep a ptr to its context */ static union acpi_ec *ec_ecdt; Loading @@ -179,10 +161,7 @@ static inline u32 acpi_ec_read_status(union acpi_ec *ec) return status; } static int acpi_ec_wait ( union acpi_ec *ec, u8 event) static int acpi_ec_wait(union acpi_ec *ec, u8 event) { if (acpi_ec_polling_mode) return acpi_ec_polling_wait(ec, event); Loading @@ -190,10 +169,7 @@ acpi_ec_wait ( return acpi_ec_burst_wait(ec, event); } static int acpi_ec_polling_wait ( union acpi_ec *ec, u8 event) static int acpi_ec_polling_wait(union acpi_ec *ec, u8 event) { u32 acpi_ec_status = 0; u32 i = ACPI_EC_UDELAY_COUNT; Loading @@ -205,7 +181,8 @@ acpi_ec_polling_wait ( switch (event) { case ACPI_EC_EVENT_OBF: do { acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr); acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr); if (acpi_ec_status & ACPI_EC_FLAG_OBF) return 0; udelay(ACPI_EC_UDELAY); Loading @@ -213,7 +190,8 @@ acpi_ec_polling_wait ( break; case ACPI_EC_EVENT_IBE: do { acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr); acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr); if (!(acpi_ec_status & ACPI_EC_FLAG_IBF)) return 0; udelay(ACPI_EC_UDELAY); Loading Loading @@ -277,11 +255,7 @@ static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event) return_VALUE(-ETIME); } static int acpi_ec_enter_burst_mode ( union acpi_ec *ec) static int acpi_ec_enter_burst_mode(union acpi_ec *ec) { u32 tmp = 0; int status = 0; Loading @@ -289,12 +263,12 @@ acpi_ec_enter_burst_mode ( ACPI_FUNCTION_TRACE("acpi_ec_enter_burst_mode"); status = acpi_ec_read_status(ec); if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)){ 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); 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) return_VALUE(-EINVAL); Loading @@ -311,9 +285,7 @@ acpi_ec_enter_burst_mode ( return_VALUE(-1); } static int acpi_ec_leave_burst_mode ( union acpi_ec *ec) static int acpi_ec_leave_burst_mode(union acpi_ec *ec) { ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode"); Loading @@ -322,33 +294,21 @@ acpi_ec_leave_burst_mode ( return_VALUE(0); } static int acpi_ec_read ( union acpi_ec *ec, u8 address, u32 *data) static int acpi_ec_read(union acpi_ec *ec, u8 address, u32 * data) { if (acpi_ec_polling_mode) return acpi_ec_polling_read(ec, address, data); else return acpi_ec_burst_read(ec, address, data); } static int acpi_ec_write ( union acpi_ec *ec, u8 address, u8 data) static int acpi_ec_write(union acpi_ec *ec, u8 address, u8 data) { if (acpi_ec_polling_mode) return acpi_ec_polling_write(ec, address, data); else return acpi_ec_burst_write(ec, address, data); } static int acpi_ec_polling_read ( union acpi_ec *ec, u8 address, u32 *data) static int acpi_ec_polling_read(union acpi_ec *ec, u8 address, u32 * data) { acpi_status status = AE_OK; int result = 0; Loading @@ -370,7 +330,8 @@ acpi_ec_polling_read ( spin_lock_irqsave(&ec->polling.lock, flags); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr); result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (result) goto end; Loading @@ -394,12 +355,7 @@ acpi_ec_polling_read ( return_VALUE(result); } static int acpi_ec_polling_write ( union acpi_ec *ec, u8 address, u8 data) static int acpi_ec_polling_write(union acpi_ec *ec, u8 address, u8 data) { int result = 0; acpi_status status = AE_OK; Loading @@ -419,7 +375,8 @@ acpi_ec_polling_write ( spin_lock_irqsave(&ec->polling.lock, flags); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr); result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (result) goto end; Loading @@ -446,11 +403,7 @@ acpi_ec_polling_write ( return_VALUE(result); } static int acpi_ec_burst_read ( union acpi_ec *ec, u8 address, u32 *data) static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data) { int status = 0; u32 glk; Loading @@ -477,7 +430,8 @@ acpi_ec_burst_read ( printk("read EC, IB not empty\n"); goto end; } acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { printk("read EC, IB not empty\n"); Loading @@ -503,12 +457,7 @@ acpi_ec_burst_read ( return_VALUE(status); } static int acpi_ec_burst_write ( union acpi_ec *ec, u8 address, u8 data) static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data) { int status = 0; u32 glk; Loading @@ -533,7 +482,8 @@ acpi_ec_burst_write ( if (status) { printk("write EC, IB not empty\n"); } acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { printk("write EC, IB not empty\n"); Loading Loading @@ -562,8 +512,7 @@ acpi_ec_burst_write ( /* * Externally callable EC access functions. For now, assume 1 EC only */ int ec_read(u8 addr, u8 *val) int ec_read(u8 addr, u8 * val) { union acpi_ec *ec; int err; Loading @@ -579,14 +528,13 @@ ec_read(u8 addr, u8 *val) if (!err) { *val = temp_data; return 0; } else } else return err; } EXPORT_SYMBOL(ec_read); int ec_write(u8 addr, u8 val) int ec_write(u8 addr, u8 val) { union acpi_ec *ec; int err; Loading @@ -600,22 +548,17 @@ ec_write(u8 addr, u8 val) return err; } EXPORT_SYMBOL(ec_write); static int acpi_ec_query ( union acpi_ec *ec, u32 *data) static int acpi_ec_query(union acpi_ec *ec, u32 * data) { if (acpi_ec_polling_mode) return acpi_ec_polling_query(ec, data); else return acpi_ec_burst_query(ec, data); } static int acpi_ec_polling_query ( union acpi_ec *ec, u32 *data) static int acpi_ec_polling_query(union acpi_ec *ec, u32 * data) { int result = 0; acpi_status status = AE_OK; Loading @@ -642,7 +585,8 @@ acpi_ec_polling_query ( */ spin_lock_irqsave(&ec->polling.lock, flags); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr); result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); if (result) goto end; Loading @@ -659,10 +603,7 @@ acpi_ec_polling_query ( return_VALUE(result); } static int acpi_ec_burst_query ( union acpi_ec *ec, u32 *data) static int acpi_ec_burst_query(union acpi_ec *ec, u32 * data) { int status = 0; u32 glk; Loading Loading @@ -691,7 +632,8 @@ acpi_ec_burst_query ( * Note that successful completion of the query causes the ACPI_EC_SCI * bit to be cleared (and thus clearing the interrupt source). */ acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); if (status) { printk("query EC, OB not full\n"); Loading @@ -711,7 +653,6 @@ acpi_ec_burst_query ( return_VALUE(status); } /* -------------------------------------------------------------------------- Event Management -------------------------------------------------------------------------- */ Loading @@ -721,9 +662,7 @@ union acpi_ec_query_data { u8 data; }; static void acpi_ec_gpe_query ( void *ec_cxt) static void acpi_ec_gpe_query(void *ec_cxt) { if (acpi_ec_polling_mode) acpi_ec_gpe_polling_query(ec_cxt); Loading @@ -731,16 +670,15 @@ acpi_ec_gpe_query ( acpi_ec_gpe_burst_query(ec_cxt); } static void acpi_ec_gpe_polling_query ( void *ec_cxt) static void acpi_ec_gpe_polling_query(void *ec_cxt) { union acpi_ec *ec = (union acpi_ec *)ec_cxt; u32 value = 0; unsigned long flags = 0; static char object_name[5] = { '_', 'Q', '0', '0', '\0' }; const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8','9','A','B','C','D','E','F'}; '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; ACPI_FUNCTION_TRACE("acpi_ec_gpe_query"); Loading Loading @@ -773,16 +711,15 @@ acpi_ec_gpe_polling_query ( end: acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); } static void acpi_ec_gpe_burst_query ( void *ec_cxt) static void acpi_ec_gpe_burst_query(void *ec_cxt) { union acpi_ec *ec = (union acpi_ec *)ec_cxt; u32 value; int result = -ENODATA; static char object_name[5] = { '_', 'Q', '0', '0', '\0' }; const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8','9','A','B','C','D','E','F'}; '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; ACPI_FUNCTION_TRACE("acpi_ec_gpe_query"); Loading @@ -803,18 +740,14 @@ acpi_ec_gpe_burst_query ( return; } static u32 acpi_ec_gpe_handler ( void *data) static u32 acpi_ec_gpe_handler(void *data) { if (acpi_ec_polling_mode) return acpi_ec_gpe_polling_handler(data); else return acpi_ec_gpe_burst_handler(data); } static u32 acpi_ec_gpe_polling_handler ( void *data) static u32 acpi_ec_gpe_polling_handler(void *data) { acpi_status status = AE_OK; union acpi_ec *ec = (union acpi_ec *)data; Loading @@ -832,9 +765,7 @@ acpi_ec_gpe_polling_handler ( else return ACPI_INTERRUPT_NOT_HANDLED; } static u32 acpi_ec_gpe_burst_handler ( void *data) static u32 acpi_ec_gpe_burst_handler(void *data) { acpi_status status = AE_OK; u32 value; Loading Loading @@ -877,11 +808,8 @@ acpi_ec_gpe_burst_handler ( -------------------------------------------------------------------------- */ static acpi_status acpi_ec_space_setup ( acpi_handle region_handle, u32 function, void *handler_context, void **return_context) acpi_ec_space_setup(acpi_handle region_handle, u32 function, void *handler_context, void **return_context) { /* * The EC object is in the handler context and is needed Loading @@ -893,15 +821,12 @@ acpi_ec_space_setup ( return AE_OK; } static acpi_status acpi_ec_space_handler ( u32 function, acpi_ec_space_handler(u32 function, acpi_physical_address address, u32 bit_width, acpi_integer * value, void *handler_context, void *region_context) void *handler_context, void *region_context) { int result = 0; union acpi_ec *ec = NULL; Loading @@ -915,7 +840,8 @@ acpi_ec_space_handler ( return_VALUE(AE_BAD_PARAMETER); if (bit_width != 8 && acpi_strict) { printk(KERN_WARNING PREFIX "acpi_ec_space_handler: bit_width should be 8\n"); printk(KERN_WARNING PREFIX "acpi_ec_space_handler: bit_width should be 8\n"); return_VALUE(AE_BAD_PARAMETER); } Loading Loading @@ -952,7 +878,6 @@ acpi_ec_space_handler ( *value = f_v; } out: switch (result) { case -EINVAL: Loading @@ -969,16 +894,13 @@ acpi_ec_space_handler ( } } /* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ static struct proc_dir_entry *acpi_ec_dir; static int acpi_ec_read_info (struct seq_file *seq, void *offset) static int acpi_ec_read_info(struct seq_file *seq, void *offset) { union acpi_ec *ec = (union acpi_ec *)seq->private; Loading @@ -990,7 +912,8 @@ acpi_ec_read_info (struct seq_file *seq, void *offset) seq_printf(seq, "gpe bit: 0x%02x\n", (u32) ec->common.gpe_bit); seq_printf(seq, "ports: 0x%02x, 0x%02x\n", (u32) ec->common.status_addr.address, (u32) ec->common.data_addr.address); (u32) ec->common.status_addr.address, (u32) ec->common.data_addr.address); seq_printf(seq, "use global lock: %s\n", ec->common.global_lock ? "yes" : "no"); acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); Loading @@ -1012,9 +935,7 @@ static struct file_operations acpi_ec_info_ops = { .owner = THIS_MODULE, }; static int acpi_ec_add_fs ( struct acpi_device *device) static int acpi_ec_add_fs(struct acpi_device *device) { struct proc_dir_entry *entry = NULL; Loading Loading @@ -1042,10 +963,7 @@ acpi_ec_add_fs ( return_VALUE(0); } static int acpi_ec_remove_fs ( struct acpi_device *device) static int acpi_ec_remove_fs(struct acpi_device *device) { ACPI_FUNCTION_TRACE("acpi_ec_remove_fs"); Loading @@ -1058,15 +976,11 @@ acpi_ec_remove_fs ( return_VALUE(0); } /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ static int acpi_ec_polling_add ( struct acpi_device *device) static int acpi_ec_polling_add(struct acpi_device *device) { int result = 0; acpi_status status = AE_OK; Loading @@ -1091,23 +1005,28 @@ acpi_ec_polling_add ( acpi_driver_data(device) = ec; /* Use the global lock for all EC transactions? */ acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock); acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock); /* If our UID matches the UID for the ECDT-enumerated EC, we now have the *real* EC info, so kill the makeshift one. */ acpi_evaluate_integer(ec->common.handle, "_UID", NULL, &uid); if (ec_ecdt && ec_ecdt->common.uid == uid) { acpi_remove_address_space_handler(ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler); acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler); kfree(ec_ecdt); } /* Get GPE bit assignment (EC events). */ /* TODO: Add support for _GPE returning a package */ status = acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, &ec->common.gpe_bit); status = acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, &ec->common.gpe_bit); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error obtaining GPE bit assignment\n")); Loading @@ -1132,9 +1051,7 @@ acpi_ec_polling_add ( return_VALUE(result); } static int acpi_ec_burst_add ( struct acpi_device *device) static int acpi_ec_burst_add(struct acpi_device *device) { int result = 0; acpi_status status = AE_OK; Loading Loading @@ -1162,23 +1079,28 @@ acpi_ec_burst_add ( acpi_driver_data(device) = ec; /* Use the global lock for all EC transactions? */ acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock); acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock); /* If our UID matches the UID for the ECDT-enumerated EC, we now have the *real* EC info, so kill the makeshift one. */ acpi_evaluate_integer(ec->common.handle, "_UID", NULL, &uid); if (ec_ecdt && ec_ecdt->common.uid == uid) { acpi_remove_address_space_handler(ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler); acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler); kfree(ec_ecdt); } /* Get GPE bit assignment (EC events). */ /* TODO: Add support for _GPE returning a package */ status = acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, &ec->common.gpe_bit); status = acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, &ec->common.gpe_bit); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error obtaining GPE bit assignment\n")); Loading @@ -1205,11 +1127,7 @@ acpi_ec_burst_add ( return_VALUE(result); } static int acpi_ec_remove ( struct acpi_device *device, int type) static int acpi_ec_remove(struct acpi_device *device, int type) { union acpi_ec *ec = NULL; Loading @@ -1227,11 +1145,8 @@ acpi_ec_remove ( return_VALUE(0); } static acpi_status acpi_ec_io_ports ( struct acpi_resource *resource, void *context) acpi_ec_io_ports(struct acpi_resource *resource, void *context) { union acpi_ec *ec = (union acpi_ec *)context; struct acpi_generic_address *addr; Loading Loading @@ -1261,10 +1176,7 @@ acpi_ec_io_ports ( return AE_OK; } static int acpi_ec_start ( struct acpi_device *device) static int acpi_ec_start(struct acpi_device *device) { acpi_status status = AE_OK; union acpi_ec *ec = NULL; Loading @@ -1284,23 +1196,26 @@ acpi_ec_start ( */ status = acpi_walk_resources(ec->common.handle, METHOD_NAME__CRS, acpi_ec_io_ports, ec); if (ACPI_FAILURE(status) || ec->common.command_addr.register_bit_width == 0) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses")); if (ACPI_FAILURE(status) || ec->common.command_addr.register_bit_width == 0) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses")); return_VALUE(-ENODEV); } ec->common.status_addr = ec->common.command_addr; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n", (u32) ec->common.gpe_bit, (u32) ec->common.command_addr.address, (u32) ec->common.gpe_bit, (u32) ec->common.command_addr.address, (u32) ec->common.data_addr.address)); /* * Install GPE handler */ status = acpi_install_gpe_handler(NULL, ec->common.gpe_bit, ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec); ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec); if (ACPI_FAILURE(status)) { return_VALUE(-ENODEV); } Loading @@ -1308,21 +1223,19 @@ acpi_ec_start ( acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); status = acpi_install_address_space_handler(ec->common.handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, &acpi_ec_space_setup, ec); if (ACPI_FAILURE(status)) { acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler); acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler); return_VALUE(-ENODEV); } return_VALUE(AE_OK); } static int acpi_ec_stop ( struct acpi_device *device, int type) static int acpi_ec_stop(struct acpi_device *device, int type) { acpi_status status = AE_OK; union acpi_ec *ec = NULL; Loading @@ -1335,11 +1248,14 @@ acpi_ec_stop ( ec = acpi_driver_data(device); status = acpi_remove_address_space_handler(ec->common.handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); if (ACPI_FAILURE(status)) return_VALUE(-ENODEV); status = acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler); status = acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler); if (ACPI_FAILURE(status)) return_VALUE(-ENODEV); Loading @@ -1347,11 +1263,8 @@ acpi_ec_stop ( } static acpi_status __init acpi_fake_ecdt_callback ( acpi_handle handle, u32 Level, void *context, void **retval) acpi_fake_ecdt_callback(acpi_handle handle, u32 Level, void *context, void **retval) { if (acpi_ec_polling_mode) Loading @@ -1363,11 +1276,8 @@ acpi_fake_ecdt_callback ( } static acpi_status __init acpi_fake_ecdt_polling_callback ( acpi_handle handle, u32 Level, void *context, void **retval) acpi_fake_ecdt_polling_callback(acpi_handle handle, u32 Level, void *context, void **retval) { acpi_status status; Loading @@ -1380,7 +1290,9 @@ acpi_fake_ecdt_polling_callback ( ec_ecdt->common.uid = -1; acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid); status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit); status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit); if (ACPI_FAILURE(status)) return status; spin_lock_init(&ec_ecdt->polling.lock); Loading @@ -1388,18 +1300,16 @@ acpi_fake_ecdt_polling_callback ( ec_ecdt->common.handle = handle; printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n", (u32) ec_ecdt->common.gpe_bit, (u32) ec_ecdt->common.command_addr.address, (u32) ec_ecdt->common.gpe_bit, (u32) ec_ecdt->common.command_addr.address, (u32) ec_ecdt->common.data_addr.address); return AE_CTRL_TERMINATE; } static acpi_status __init acpi_fake_ecdt_burst_callback ( acpi_handle handle, u32 Level, void *context, void **retval) acpi_fake_ecdt_burst_callback(acpi_handle handle, u32 Level, void *context, void **retval) { acpi_status status; Loading @@ -1414,14 +1324,17 @@ acpi_fake_ecdt_burst_callback ( ec_ecdt->common.uid = -1; acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid); status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit); status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit); if (ACPI_FAILURE(status)) return status; ec_ecdt->common.global_lock = TRUE; ec_ecdt->common.handle = handle; printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n", (u32) ec_ecdt->common.gpe_bit, (u32) ec_ecdt->common.command_addr.address, (u32) ec_ecdt->common.gpe_bit, (u32) ec_ecdt->common.command_addr.address, (u32) ec_ecdt->common.data_addr.address); return AE_CTRL_TERMINATE; Loading @@ -1437,8 +1350,7 @@ acpi_fake_ecdt_burst_callback ( * op region (since _REG isn't invoked yet). The assumption is true for * all systems found. */ static int __init acpi_ec_fake_ecdt(void) static int __init acpi_ec_fake_ecdt(void) { acpi_status status; int ret = 0; Loading @@ -1453,9 +1365,7 @@ acpi_ec_fake_ecdt(void) memset(ec_ecdt, 0, sizeof(union acpi_ec)); status = acpi_get_devices(ACPI_EC_HID, acpi_fake_ecdt_callback, NULL, NULL); acpi_fake_ecdt_callback, NULL, NULL); if (ACPI_FAILURE(status)) { kfree(ec_ecdt); ec_ecdt = NULL; Loading @@ -1468,8 +1378,7 @@ acpi_ec_fake_ecdt(void) return ret; } static int __init acpi_ec_get_real_ecdt(void) static int __init acpi_ec_get_real_ecdt(void) { if (acpi_ec_polling_mode) return acpi_ec_polling_get_real_ecdt(); Loading @@ -1477,14 +1386,14 @@ acpi_ec_get_real_ecdt(void) return acpi_ec_burst_get_real_ecdt(); } static int __init acpi_ec_polling_get_real_ecdt(void) static int __init acpi_ec_polling_get_real_ecdt(void) { acpi_status status; struct acpi_table_ecdt *ecdt_ptr; status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, (struct acpi_table_header **) &ecdt_ptr); (struct acpi_table_header **) &ecdt_ptr); if (ACPI_FAILURE(status)) return -ENODEV; Loading @@ -1507,7 +1416,8 @@ acpi_ec_polling_get_real_ecdt(void) ec_ecdt->common.global_lock = TRUE; ec_ecdt->common.uid = ecdt_ptr->uid; status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); if (ACPI_FAILURE(status)) { goto error; } Loading @@ -1521,15 +1431,14 @@ acpi_ec_polling_get_real_ecdt(void) return -ENODEV; } static int __init acpi_ec_burst_get_real_ecdt(void) static int __init acpi_ec_burst_get_real_ecdt(void) { acpi_status status; struct acpi_table_ecdt *ecdt_ptr; status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, (struct acpi_table_header **) &ecdt_ptr); (struct acpi_table_header **) &ecdt_ptr); if (ACPI_FAILURE(status)) return -ENODEV; Loading @@ -1553,7 +1462,8 @@ acpi_ec_burst_get_real_ecdt(void) ec_ecdt->common.global_lock = TRUE; ec_ecdt->common.uid = ecdt_ptr->uid; status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); if (ACPI_FAILURE(status)) { goto error; } Loading @@ -1568,8 +1478,7 @@ acpi_ec_burst_get_real_ecdt(void) } static int __initdata acpi_fake_ecdt_enabled; int __init acpi_ec_ecdt_probe (void) int __init acpi_ec_ecdt_probe(void) { acpi_status status; int ret; Loading @@ -1587,8 +1496,8 @@ acpi_ec_ecdt_probe (void) * Install GPE handler */ status = acpi_install_gpe_handler(NULL, ec_ecdt->common.gpe_bit, ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec_ecdt); ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec_ecdt); if (ACPI_FAILURE(status)) { goto error; } Loading @@ -1596,8 +1505,10 @@ acpi_ec_ecdt_probe (void) acpi_enable_gpe(NULL, ec_ecdt->common.gpe_bit, ACPI_NOT_ISR); status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, &acpi_ec_space_setup, ec_ecdt); ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, &acpi_ec_space_setup, ec_ecdt); if (ACPI_FAILURE(status)) { acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler); Loading @@ -1614,7 +1525,6 @@ acpi_ec_ecdt_probe (void) return -ENODEV; } static int __init acpi_ec_init(void) { int result = 0; Loading Loading @@ -1642,8 +1552,7 @@ subsys_initcall(acpi_ec_init); /* EC driver currently not unloadable */ #if 0 static void __exit acpi_ec_exit (void) static void __exit acpi_ec_exit(void) { ACPI_FUNCTION_TRACE("acpi_ec_exit"); Loading Loading @@ -1676,8 +1585,8 @@ static int __init acpi_ec_set_polling_mode(char *str) acpi_ec_polling_mode = EC_POLLING; acpi_ec_driver.ops.add = acpi_ec_polling_add; } printk(KERN_INFO PREFIX "EC %s mode.\n", burst ? "burst": "polling"); printk(KERN_INFO PREFIX "EC %s mode.\n", burst ? "burst" : "polling"); return 0; } __setup("ec_burst=", acpi_ec_set_polling_mode); Loading
drivers/acpi/ec.c +389 −480 Original line number Diff line number Diff line Loading @@ -39,39 +39,29 @@ #define _COMPONENT ACPI_EC_COMPONENT ACPI_MODULE_NAME("acpi_ec") #define ACPI_EC_COMPONENT 0x00100000 #define ACPI_EC_CLASS "embedded_controller" #define ACPI_EC_HID "PNP0C09" #define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver" #define ACPI_EC_DEVICE_NAME "Embedded Controller" #define ACPI_EC_FILE_INFO "info" #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ #define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ #define ACPI_EC_EVENT_OBF 0x01 /* Output buffer full */ #define ACPI_EC_EVENT_IBE 0x02 /* Input buffer empty */ #define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */ #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ #define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */ #define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */ #define ACPI_EC_COMMAND_READ 0x80 #define ACPI_EC_COMMAND_WRITE 0x81 #define ACPI_EC_BURST_ENABLE 0x82 #define ACPI_EC_BURST_DISABLE 0x83 #define ACPI_EC_COMMAND_QUERY 0x84 #define EC_POLLING 0xFF #define EC_BURST 0x00 static int acpi_ec_remove(struct acpi_device *device, int type); static int acpi_ec_start(struct acpi_device *device); static int acpi_ec_stop(struct acpi_device *device, int type); Loading Loading @@ -143,23 +133,15 @@ static void acpi_ec_gpe_burst_query ( void *ec_cxt); static u32 acpi_ec_gpe_polling_handler(void *data); static u32 acpi_ec_gpe_burst_handler(void *data); static acpi_status __init acpi_fake_ecdt_polling_callback ( acpi_handle handle, u32 Level, void *context, void **retval); acpi_fake_ecdt_polling_callback(acpi_handle handle, u32 Level, void *context, void **retval); static acpi_status __init acpi_fake_ecdt_burst_callback ( acpi_handle handle, u32 Level, void *context, void **retval); static int __init acpi_ec_polling_get_real_ecdt(void); static int __init acpi_ec_burst_get_real_ecdt(void); acpi_fake_ecdt_burst_callback(acpi_handle handle, u32 Level, void *context, void **retval); static int __init acpi_ec_polling_get_real_ecdt(void); static int __init acpi_ec_burst_get_real_ecdt(void); /* If we find an EC via the ECDT, we need to keep a ptr to its context */ static union acpi_ec *ec_ecdt; Loading @@ -179,10 +161,7 @@ static inline u32 acpi_ec_read_status(union acpi_ec *ec) return status; } static int acpi_ec_wait ( union acpi_ec *ec, u8 event) static int acpi_ec_wait(union acpi_ec *ec, u8 event) { if (acpi_ec_polling_mode) return acpi_ec_polling_wait(ec, event); Loading @@ -190,10 +169,7 @@ acpi_ec_wait ( return acpi_ec_burst_wait(ec, event); } static int acpi_ec_polling_wait ( union acpi_ec *ec, u8 event) static int acpi_ec_polling_wait(union acpi_ec *ec, u8 event) { u32 acpi_ec_status = 0; u32 i = ACPI_EC_UDELAY_COUNT; Loading @@ -205,7 +181,8 @@ acpi_ec_polling_wait ( switch (event) { case ACPI_EC_EVENT_OBF: do { acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr); acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr); if (acpi_ec_status & ACPI_EC_FLAG_OBF) return 0; udelay(ACPI_EC_UDELAY); Loading @@ -213,7 +190,8 @@ acpi_ec_polling_wait ( break; case ACPI_EC_EVENT_IBE: do { acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr); acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr); if (!(acpi_ec_status & ACPI_EC_FLAG_IBF)) return 0; udelay(ACPI_EC_UDELAY); Loading Loading @@ -277,11 +255,7 @@ static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event) return_VALUE(-ETIME); } static int acpi_ec_enter_burst_mode ( union acpi_ec *ec) static int acpi_ec_enter_burst_mode(union acpi_ec *ec) { u32 tmp = 0; int status = 0; Loading @@ -289,12 +263,12 @@ acpi_ec_enter_burst_mode ( ACPI_FUNCTION_TRACE("acpi_ec_enter_burst_mode"); status = acpi_ec_read_status(ec); if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)){ 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); 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) return_VALUE(-EINVAL); Loading @@ -311,9 +285,7 @@ acpi_ec_enter_burst_mode ( return_VALUE(-1); } static int acpi_ec_leave_burst_mode ( union acpi_ec *ec) static int acpi_ec_leave_burst_mode(union acpi_ec *ec) { ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode"); Loading @@ -322,33 +294,21 @@ acpi_ec_leave_burst_mode ( return_VALUE(0); } static int acpi_ec_read ( union acpi_ec *ec, u8 address, u32 *data) static int acpi_ec_read(union acpi_ec *ec, u8 address, u32 * data) { if (acpi_ec_polling_mode) return acpi_ec_polling_read(ec, address, data); else return acpi_ec_burst_read(ec, address, data); } static int acpi_ec_write ( union acpi_ec *ec, u8 address, u8 data) static int acpi_ec_write(union acpi_ec *ec, u8 address, u8 data) { if (acpi_ec_polling_mode) return acpi_ec_polling_write(ec, address, data); else return acpi_ec_burst_write(ec, address, data); } static int acpi_ec_polling_read ( union acpi_ec *ec, u8 address, u32 *data) static int acpi_ec_polling_read(union acpi_ec *ec, u8 address, u32 * data) { acpi_status status = AE_OK; int result = 0; Loading @@ -370,7 +330,8 @@ acpi_ec_polling_read ( spin_lock_irqsave(&ec->polling.lock, flags); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr); result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (result) goto end; Loading @@ -394,12 +355,7 @@ acpi_ec_polling_read ( return_VALUE(result); } static int acpi_ec_polling_write ( union acpi_ec *ec, u8 address, u8 data) static int acpi_ec_polling_write(union acpi_ec *ec, u8 address, u8 data) { int result = 0; acpi_status status = AE_OK; Loading @@ -419,7 +375,8 @@ acpi_ec_polling_write ( spin_lock_irqsave(&ec->polling.lock, flags); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr); result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (result) goto end; Loading @@ -446,11 +403,7 @@ acpi_ec_polling_write ( return_VALUE(result); } static int acpi_ec_burst_read ( union acpi_ec *ec, u8 address, u32 *data) static int acpi_ec_burst_read(union acpi_ec *ec, u8 address, u32 * data) { int status = 0; u32 glk; Loading @@ -477,7 +430,8 @@ acpi_ec_burst_read ( printk("read EC, IB not empty\n"); goto end; } acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { printk("read EC, IB not empty\n"); Loading @@ -503,12 +457,7 @@ acpi_ec_burst_read ( return_VALUE(status); } static int acpi_ec_burst_write ( union acpi_ec *ec, u8 address, u8 data) static int acpi_ec_burst_write(union acpi_ec *ec, u8 address, u8 data) { int status = 0; u32 glk; Loading @@ -533,7 +482,8 @@ acpi_ec_burst_write ( if (status) { printk("write EC, IB not empty\n"); } acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (status) { printk("write EC, IB not empty\n"); Loading Loading @@ -562,8 +512,7 @@ acpi_ec_burst_write ( /* * Externally callable EC access functions. For now, assume 1 EC only */ int ec_read(u8 addr, u8 *val) int ec_read(u8 addr, u8 * val) { union acpi_ec *ec; int err; Loading @@ -579,14 +528,13 @@ ec_read(u8 addr, u8 *val) if (!err) { *val = temp_data; return 0; } else } else return err; } EXPORT_SYMBOL(ec_read); int ec_write(u8 addr, u8 val) int ec_write(u8 addr, u8 val) { union acpi_ec *ec; int err; Loading @@ -600,22 +548,17 @@ ec_write(u8 addr, u8 val) return err; } EXPORT_SYMBOL(ec_write); static int acpi_ec_query ( union acpi_ec *ec, u32 *data) static int acpi_ec_query(union acpi_ec *ec, u32 * data) { if (acpi_ec_polling_mode) return acpi_ec_polling_query(ec, data); else return acpi_ec_burst_query(ec, data); } static int acpi_ec_polling_query ( union acpi_ec *ec, u32 *data) static int acpi_ec_polling_query(union acpi_ec *ec, u32 * data) { int result = 0; acpi_status status = AE_OK; Loading @@ -642,7 +585,8 @@ acpi_ec_polling_query ( */ spin_lock_irqsave(&ec->polling.lock, flags); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr); result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); if (result) goto end; Loading @@ -659,10 +603,7 @@ acpi_ec_polling_query ( return_VALUE(result); } static int acpi_ec_burst_query ( union acpi_ec *ec, u32 *data) static int acpi_ec_burst_query(union acpi_ec *ec, u32 * data) { int status = 0; u32 glk; Loading Loading @@ -691,7 +632,8 @@ acpi_ec_burst_query ( * Note that successful completion of the query causes the ACPI_EC_SCI * bit to be cleared (and thus clearing the interrupt source). */ acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr); acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr); status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); if (status) { printk("query EC, OB not full\n"); Loading @@ -711,7 +653,6 @@ acpi_ec_burst_query ( return_VALUE(status); } /* -------------------------------------------------------------------------- Event Management -------------------------------------------------------------------------- */ Loading @@ -721,9 +662,7 @@ union acpi_ec_query_data { u8 data; }; static void acpi_ec_gpe_query ( void *ec_cxt) static void acpi_ec_gpe_query(void *ec_cxt) { if (acpi_ec_polling_mode) acpi_ec_gpe_polling_query(ec_cxt); Loading @@ -731,16 +670,15 @@ acpi_ec_gpe_query ( acpi_ec_gpe_burst_query(ec_cxt); } static void acpi_ec_gpe_polling_query ( void *ec_cxt) static void acpi_ec_gpe_polling_query(void *ec_cxt) { union acpi_ec *ec = (union acpi_ec *)ec_cxt; u32 value = 0; unsigned long flags = 0; static char object_name[5] = { '_', 'Q', '0', '0', '\0' }; const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8','9','A','B','C','D','E','F'}; '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; ACPI_FUNCTION_TRACE("acpi_ec_gpe_query"); Loading Loading @@ -773,16 +711,15 @@ acpi_ec_gpe_polling_query ( end: acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); } static void acpi_ec_gpe_burst_query ( void *ec_cxt) static void acpi_ec_gpe_burst_query(void *ec_cxt) { union acpi_ec *ec = (union acpi_ec *)ec_cxt; u32 value; int result = -ENODATA; static char object_name[5] = { '_', 'Q', '0', '0', '\0' }; const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8','9','A','B','C','D','E','F'}; '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; ACPI_FUNCTION_TRACE("acpi_ec_gpe_query"); Loading @@ -803,18 +740,14 @@ acpi_ec_gpe_burst_query ( return; } static u32 acpi_ec_gpe_handler ( void *data) static u32 acpi_ec_gpe_handler(void *data) { if (acpi_ec_polling_mode) return acpi_ec_gpe_polling_handler(data); else return acpi_ec_gpe_burst_handler(data); } static u32 acpi_ec_gpe_polling_handler ( void *data) static u32 acpi_ec_gpe_polling_handler(void *data) { acpi_status status = AE_OK; union acpi_ec *ec = (union acpi_ec *)data; Loading @@ -832,9 +765,7 @@ acpi_ec_gpe_polling_handler ( else return ACPI_INTERRUPT_NOT_HANDLED; } static u32 acpi_ec_gpe_burst_handler ( void *data) static u32 acpi_ec_gpe_burst_handler(void *data) { acpi_status status = AE_OK; u32 value; Loading Loading @@ -877,11 +808,8 @@ acpi_ec_gpe_burst_handler ( -------------------------------------------------------------------------- */ static acpi_status acpi_ec_space_setup ( acpi_handle region_handle, u32 function, void *handler_context, void **return_context) acpi_ec_space_setup(acpi_handle region_handle, u32 function, void *handler_context, void **return_context) { /* * The EC object is in the handler context and is needed Loading @@ -893,15 +821,12 @@ acpi_ec_space_setup ( return AE_OK; } static acpi_status acpi_ec_space_handler ( u32 function, acpi_ec_space_handler(u32 function, acpi_physical_address address, u32 bit_width, acpi_integer * value, void *handler_context, void *region_context) void *handler_context, void *region_context) { int result = 0; union acpi_ec *ec = NULL; Loading @@ -915,7 +840,8 @@ acpi_ec_space_handler ( return_VALUE(AE_BAD_PARAMETER); if (bit_width != 8 && acpi_strict) { printk(KERN_WARNING PREFIX "acpi_ec_space_handler: bit_width should be 8\n"); printk(KERN_WARNING PREFIX "acpi_ec_space_handler: bit_width should be 8\n"); return_VALUE(AE_BAD_PARAMETER); } Loading Loading @@ -952,7 +878,6 @@ acpi_ec_space_handler ( *value = f_v; } out: switch (result) { case -EINVAL: Loading @@ -969,16 +894,13 @@ acpi_ec_space_handler ( } } /* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ static struct proc_dir_entry *acpi_ec_dir; static int acpi_ec_read_info (struct seq_file *seq, void *offset) static int acpi_ec_read_info(struct seq_file *seq, void *offset) { union acpi_ec *ec = (union acpi_ec *)seq->private; Loading @@ -990,7 +912,8 @@ acpi_ec_read_info (struct seq_file *seq, void *offset) seq_printf(seq, "gpe bit: 0x%02x\n", (u32) ec->common.gpe_bit); seq_printf(seq, "ports: 0x%02x, 0x%02x\n", (u32) ec->common.status_addr.address, (u32) ec->common.data_addr.address); (u32) ec->common.status_addr.address, (u32) ec->common.data_addr.address); seq_printf(seq, "use global lock: %s\n", ec->common.global_lock ? "yes" : "no"); acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); Loading @@ -1012,9 +935,7 @@ static struct file_operations acpi_ec_info_ops = { .owner = THIS_MODULE, }; static int acpi_ec_add_fs ( struct acpi_device *device) static int acpi_ec_add_fs(struct acpi_device *device) { struct proc_dir_entry *entry = NULL; Loading Loading @@ -1042,10 +963,7 @@ acpi_ec_add_fs ( return_VALUE(0); } static int acpi_ec_remove_fs ( struct acpi_device *device) static int acpi_ec_remove_fs(struct acpi_device *device) { ACPI_FUNCTION_TRACE("acpi_ec_remove_fs"); Loading @@ -1058,15 +976,11 @@ acpi_ec_remove_fs ( return_VALUE(0); } /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ static int acpi_ec_polling_add ( struct acpi_device *device) static int acpi_ec_polling_add(struct acpi_device *device) { int result = 0; acpi_status status = AE_OK; Loading @@ -1091,23 +1005,28 @@ acpi_ec_polling_add ( acpi_driver_data(device) = ec; /* Use the global lock for all EC transactions? */ acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock); acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock); /* If our UID matches the UID for the ECDT-enumerated EC, we now have the *real* EC info, so kill the makeshift one. */ acpi_evaluate_integer(ec->common.handle, "_UID", NULL, &uid); if (ec_ecdt && ec_ecdt->common.uid == uid) { acpi_remove_address_space_handler(ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler); acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler); kfree(ec_ecdt); } /* Get GPE bit assignment (EC events). */ /* TODO: Add support for _GPE returning a package */ status = acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, &ec->common.gpe_bit); status = acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, &ec->common.gpe_bit); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error obtaining GPE bit assignment\n")); Loading @@ -1132,9 +1051,7 @@ acpi_ec_polling_add ( return_VALUE(result); } static int acpi_ec_burst_add ( struct acpi_device *device) static int acpi_ec_burst_add(struct acpi_device *device) { int result = 0; acpi_status status = AE_OK; Loading Loading @@ -1162,23 +1079,28 @@ acpi_ec_burst_add ( acpi_driver_data(device) = ec; /* Use the global lock for all EC transactions? */ acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock); acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock); /* If our UID matches the UID for the ECDT-enumerated EC, we now have the *real* EC info, so kill the makeshift one. */ acpi_evaluate_integer(ec->common.handle, "_UID", NULL, &uid); if (ec_ecdt && ec_ecdt->common.uid == uid) { acpi_remove_address_space_handler(ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler); acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler); kfree(ec_ecdt); } /* Get GPE bit assignment (EC events). */ /* TODO: Add support for _GPE returning a package */ status = acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, &ec->common.gpe_bit); status = acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, &ec->common.gpe_bit); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error obtaining GPE bit assignment\n")); Loading @@ -1205,11 +1127,7 @@ acpi_ec_burst_add ( return_VALUE(result); } static int acpi_ec_remove ( struct acpi_device *device, int type) static int acpi_ec_remove(struct acpi_device *device, int type) { union acpi_ec *ec = NULL; Loading @@ -1227,11 +1145,8 @@ acpi_ec_remove ( return_VALUE(0); } static acpi_status acpi_ec_io_ports ( struct acpi_resource *resource, void *context) acpi_ec_io_ports(struct acpi_resource *resource, void *context) { union acpi_ec *ec = (union acpi_ec *)context; struct acpi_generic_address *addr; Loading Loading @@ -1261,10 +1176,7 @@ acpi_ec_io_ports ( return AE_OK; } static int acpi_ec_start ( struct acpi_device *device) static int acpi_ec_start(struct acpi_device *device) { acpi_status status = AE_OK; union acpi_ec *ec = NULL; Loading @@ -1284,23 +1196,26 @@ acpi_ec_start ( */ status = acpi_walk_resources(ec->common.handle, METHOD_NAME__CRS, acpi_ec_io_ports, ec); if (ACPI_FAILURE(status) || ec->common.command_addr.register_bit_width == 0) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses")); if (ACPI_FAILURE(status) || ec->common.command_addr.register_bit_width == 0) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses")); return_VALUE(-ENODEV); } ec->common.status_addr = ec->common.command_addr; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n", (u32) ec->common.gpe_bit, (u32) ec->common.command_addr.address, (u32) ec->common.gpe_bit, (u32) ec->common.command_addr.address, (u32) ec->common.data_addr.address)); /* * Install GPE handler */ status = acpi_install_gpe_handler(NULL, ec->common.gpe_bit, ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec); ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec); if (ACPI_FAILURE(status)) { return_VALUE(-ENODEV); } Loading @@ -1308,21 +1223,19 @@ acpi_ec_start ( acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); status = acpi_install_address_space_handler(ec->common.handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, &acpi_ec_space_setup, ec); if (ACPI_FAILURE(status)) { acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler); acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler); return_VALUE(-ENODEV); } return_VALUE(AE_OK); } static int acpi_ec_stop ( struct acpi_device *device, int type) static int acpi_ec_stop(struct acpi_device *device, int type) { acpi_status status = AE_OK; union acpi_ec *ec = NULL; Loading @@ -1335,11 +1248,14 @@ acpi_ec_stop ( ec = acpi_driver_data(device); status = acpi_remove_address_space_handler(ec->common.handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); if (ACPI_FAILURE(status)) return_VALUE(-ENODEV); status = acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler); status = acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler); if (ACPI_FAILURE(status)) return_VALUE(-ENODEV); Loading @@ -1347,11 +1263,8 @@ acpi_ec_stop ( } static acpi_status __init acpi_fake_ecdt_callback ( acpi_handle handle, u32 Level, void *context, void **retval) acpi_fake_ecdt_callback(acpi_handle handle, u32 Level, void *context, void **retval) { if (acpi_ec_polling_mode) Loading @@ -1363,11 +1276,8 @@ acpi_fake_ecdt_callback ( } static acpi_status __init acpi_fake_ecdt_polling_callback ( acpi_handle handle, u32 Level, void *context, void **retval) acpi_fake_ecdt_polling_callback(acpi_handle handle, u32 Level, void *context, void **retval) { acpi_status status; Loading @@ -1380,7 +1290,9 @@ acpi_fake_ecdt_polling_callback ( ec_ecdt->common.uid = -1; acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid); status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit); status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit); if (ACPI_FAILURE(status)) return status; spin_lock_init(&ec_ecdt->polling.lock); Loading @@ -1388,18 +1300,16 @@ acpi_fake_ecdt_polling_callback ( ec_ecdt->common.handle = handle; printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n", (u32) ec_ecdt->common.gpe_bit, (u32) ec_ecdt->common.command_addr.address, (u32) ec_ecdt->common.gpe_bit, (u32) ec_ecdt->common.command_addr.address, (u32) ec_ecdt->common.data_addr.address); return AE_CTRL_TERMINATE; } static acpi_status __init acpi_fake_ecdt_burst_callback ( acpi_handle handle, u32 Level, void *context, void **retval) acpi_fake_ecdt_burst_callback(acpi_handle handle, u32 Level, void *context, void **retval) { acpi_status status; Loading @@ -1414,14 +1324,17 @@ acpi_fake_ecdt_burst_callback ( ec_ecdt->common.uid = -1; acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid); status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit); status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit); if (ACPI_FAILURE(status)) return status; ec_ecdt->common.global_lock = TRUE; ec_ecdt->common.handle = handle; printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n", (u32) ec_ecdt->common.gpe_bit, (u32) ec_ecdt->common.command_addr.address, (u32) ec_ecdt->common.gpe_bit, (u32) ec_ecdt->common.command_addr.address, (u32) ec_ecdt->common.data_addr.address); return AE_CTRL_TERMINATE; Loading @@ -1437,8 +1350,7 @@ acpi_fake_ecdt_burst_callback ( * op region (since _REG isn't invoked yet). The assumption is true for * all systems found. */ static int __init acpi_ec_fake_ecdt(void) static int __init acpi_ec_fake_ecdt(void) { acpi_status status; int ret = 0; Loading @@ -1453,9 +1365,7 @@ acpi_ec_fake_ecdt(void) memset(ec_ecdt, 0, sizeof(union acpi_ec)); status = acpi_get_devices(ACPI_EC_HID, acpi_fake_ecdt_callback, NULL, NULL); acpi_fake_ecdt_callback, NULL, NULL); if (ACPI_FAILURE(status)) { kfree(ec_ecdt); ec_ecdt = NULL; Loading @@ -1468,8 +1378,7 @@ acpi_ec_fake_ecdt(void) return ret; } static int __init acpi_ec_get_real_ecdt(void) static int __init acpi_ec_get_real_ecdt(void) { if (acpi_ec_polling_mode) return acpi_ec_polling_get_real_ecdt(); Loading @@ -1477,14 +1386,14 @@ acpi_ec_get_real_ecdt(void) return acpi_ec_burst_get_real_ecdt(); } static int __init acpi_ec_polling_get_real_ecdt(void) static int __init acpi_ec_polling_get_real_ecdt(void) { acpi_status status; struct acpi_table_ecdt *ecdt_ptr; status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, (struct acpi_table_header **) &ecdt_ptr); (struct acpi_table_header **) &ecdt_ptr); if (ACPI_FAILURE(status)) return -ENODEV; Loading @@ -1507,7 +1416,8 @@ acpi_ec_polling_get_real_ecdt(void) ec_ecdt->common.global_lock = TRUE; ec_ecdt->common.uid = ecdt_ptr->uid; status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); if (ACPI_FAILURE(status)) { goto error; } Loading @@ -1521,15 +1431,14 @@ acpi_ec_polling_get_real_ecdt(void) return -ENODEV; } static int __init acpi_ec_burst_get_real_ecdt(void) static int __init acpi_ec_burst_get_real_ecdt(void) { acpi_status status; struct acpi_table_ecdt *ecdt_ptr; status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, (struct acpi_table_header **) &ecdt_ptr); (struct acpi_table_header **) &ecdt_ptr); if (ACPI_FAILURE(status)) return -ENODEV; Loading @@ -1553,7 +1462,8 @@ acpi_ec_burst_get_real_ecdt(void) ec_ecdt->common.global_lock = TRUE; ec_ecdt->common.uid = ecdt_ptr->uid; status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); if (ACPI_FAILURE(status)) { goto error; } Loading @@ -1568,8 +1478,7 @@ acpi_ec_burst_get_real_ecdt(void) } static int __initdata acpi_fake_ecdt_enabled; int __init acpi_ec_ecdt_probe (void) int __init acpi_ec_ecdt_probe(void) { acpi_status status; int ret; Loading @@ -1587,8 +1496,8 @@ acpi_ec_ecdt_probe (void) * Install GPE handler */ status = acpi_install_gpe_handler(NULL, ec_ecdt->common.gpe_bit, ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec_ecdt); ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec_ecdt); if (ACPI_FAILURE(status)) { goto error; } Loading @@ -1596,8 +1505,10 @@ acpi_ec_ecdt_probe (void) acpi_enable_gpe(NULL, ec_ecdt->common.gpe_bit, ACPI_NOT_ISR); status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, &acpi_ec_space_setup, ec_ecdt); ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, &acpi_ec_space_setup, ec_ecdt); if (ACPI_FAILURE(status)) { acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler); Loading @@ -1614,7 +1525,6 @@ acpi_ec_ecdt_probe (void) return -ENODEV; } static int __init acpi_ec_init(void) { int result = 0; Loading Loading @@ -1642,8 +1552,7 @@ subsys_initcall(acpi_ec_init); /* EC driver currently not unloadable */ #if 0 static void __exit acpi_ec_exit (void) static void __exit acpi_ec_exit(void) { ACPI_FUNCTION_TRACE("acpi_ec_exit"); Loading Loading @@ -1676,8 +1585,8 @@ static int __init acpi_ec_set_polling_mode(char *str) acpi_ec_polling_mode = EC_POLLING; acpi_ec_driver.ops.add = acpi_ec_polling_add; } printk(KERN_INFO PREFIX "EC %s mode.\n", burst ? "burst": "polling"); printk(KERN_INFO PREFIX "EC %s mode.\n", burst ? "burst" : "polling"); return 0; } __setup("ec_burst=", acpi_ec_set_polling_mode);