Lines Matching refs:ec

127 static int acpi_ec_query(struct acpi_ec *ec, u8 *data);
128 static void advance_transaction(struct acpi_ec *ec);
180 #define ec_dbg_ref(ec, fmt, ...) \ argument
181 ec_dbg_raw("%lu: " fmt, ec->reference_count, ## __VA_ARGS__)
187 static bool acpi_ec_started(struct acpi_ec *ec) in acpi_ec_started() argument
189 return test_bit(EC_FLAGS_STARTED, &ec->flags) && in acpi_ec_started()
190 !test_bit(EC_FLAGS_STOPPED, &ec->flags); in acpi_ec_started()
193 static bool acpi_ec_flushed(struct acpi_ec *ec) in acpi_ec_flushed() argument
195 return ec->reference_count == 1; in acpi_ec_flushed()
202 static inline u8 acpi_ec_read_status(struct acpi_ec *ec) in acpi_ec_read_status() argument
204 u8 x = inb(ec->command_addr); in acpi_ec_read_status()
217 static inline u8 acpi_ec_read_data(struct acpi_ec *ec) in acpi_ec_read_data() argument
219 u8 x = inb(ec->data_addr); in acpi_ec_read_data()
221 ec->curr->timestamp = jiffies; in acpi_ec_read_data()
226 static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) in acpi_ec_write_cmd() argument
229 outb(command, ec->command_addr); in acpi_ec_write_cmd()
230 ec->curr->timestamp = jiffies; in acpi_ec_write_cmd()
233 static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) in acpi_ec_write_data() argument
236 outb(data, ec->data_addr); in acpi_ec_write_data()
237 ec->curr->timestamp = jiffies; in acpi_ec_write_data()
265 static inline bool acpi_ec_is_gpe_raised(struct acpi_ec *ec) in acpi_ec_is_gpe_raised() argument
269 (void)acpi_get_gpe_status(NULL, ec->gpe, &gpe_status); in acpi_ec_is_gpe_raised()
273 static inline void acpi_ec_enable_gpe(struct acpi_ec *ec, bool open) in acpi_ec_enable_gpe() argument
276 acpi_enable_gpe(NULL, ec->gpe); in acpi_ec_enable_gpe()
278 BUG_ON(ec->reference_count < 1); in acpi_ec_enable_gpe()
279 acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); in acpi_ec_enable_gpe()
281 if (acpi_ec_is_gpe_raised(ec)) { in acpi_ec_enable_gpe()
288 advance_transaction(ec); in acpi_ec_enable_gpe()
292 static inline void acpi_ec_disable_gpe(struct acpi_ec *ec, bool close) in acpi_ec_disable_gpe() argument
295 acpi_disable_gpe(NULL, ec->gpe); in acpi_ec_disable_gpe()
297 BUG_ON(ec->reference_count < 1); in acpi_ec_disable_gpe()
298 acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE); in acpi_ec_disable_gpe()
302 static inline void acpi_ec_clear_gpe(struct acpi_ec *ec) in acpi_ec_clear_gpe() argument
314 if (!acpi_ec_is_gpe_raised(ec)) in acpi_ec_clear_gpe()
316 acpi_clear_gpe(NULL, ec->gpe); in acpi_ec_clear_gpe()
323 static void acpi_ec_submit_request(struct acpi_ec *ec) in acpi_ec_submit_request() argument
325 ec->reference_count++; in acpi_ec_submit_request()
326 if (ec->reference_count == 1) in acpi_ec_submit_request()
327 acpi_ec_enable_gpe(ec, true); in acpi_ec_submit_request()
330 static void acpi_ec_complete_request(struct acpi_ec *ec) in acpi_ec_complete_request() argument
334 ec->reference_count--; in acpi_ec_complete_request()
335 if (ec->reference_count == 0) in acpi_ec_complete_request()
336 acpi_ec_disable_gpe(ec, true); in acpi_ec_complete_request()
337 flushed = acpi_ec_flushed(ec); in acpi_ec_complete_request()
339 wake_up(&ec->wait); in acpi_ec_complete_request()
342 static void acpi_ec_set_storm(struct acpi_ec *ec, u8 flag) in acpi_ec_set_storm() argument
344 if (!test_bit(flag, &ec->flags)) { in acpi_ec_set_storm()
345 acpi_ec_disable_gpe(ec, false); in acpi_ec_set_storm()
347 set_bit(flag, &ec->flags); in acpi_ec_set_storm()
351 static void acpi_ec_clear_storm(struct acpi_ec *ec, u8 flag) in acpi_ec_clear_storm() argument
353 if (test_bit(flag, &ec->flags)) { in acpi_ec_clear_storm()
354 clear_bit(flag, &ec->flags); in acpi_ec_clear_storm()
355 acpi_ec_enable_gpe(ec, false); in acpi_ec_clear_storm()
371 static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec) in acpi_ec_submit_flushable_request() argument
373 if (!acpi_ec_started(ec)) in acpi_ec_submit_flushable_request()
375 acpi_ec_submit_request(ec); in acpi_ec_submit_flushable_request()
379 static void acpi_ec_submit_query(struct acpi_ec *ec) in acpi_ec_submit_query() argument
381 if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { in acpi_ec_submit_query()
383 schedule_work(&ec->work); in acpi_ec_submit_query()
387 static void acpi_ec_complete_query(struct acpi_ec *ec) in acpi_ec_complete_query() argument
389 if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { in acpi_ec_complete_query()
390 clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); in acpi_ec_complete_query()
395 static int ec_transaction_completed(struct acpi_ec *ec) in ec_transaction_completed() argument
400 spin_lock_irqsave(&ec->lock, flags); in ec_transaction_completed()
401 if (ec->curr && (ec->curr->flags & ACPI_EC_COMMAND_COMPLETE)) in ec_transaction_completed()
403 spin_unlock_irqrestore(&ec->lock, flags); in ec_transaction_completed()
407 static void advance_transaction(struct acpi_ec *ec) in advance_transaction() argument
420 acpi_ec_clear_gpe(ec); in advance_transaction()
421 status = acpi_ec_read_status(ec); in advance_transaction()
422 t = ec->curr; in advance_transaction()
428 acpi_ec_write_data(ec, t->wdata[t->wi++]); in advance_transaction()
433 t->rdata[t->ri++] = acpi_ec_read_data(ec); in advance_transaction()
454 acpi_ec_complete_query(ec); in advance_transaction()
461 acpi_ec_write_cmd(ec, t->command); in advance_transaction()
463 acpi_ec_complete_query(ec); in advance_transaction()
479 acpi_ec_set_storm(ec, EC_FLAGS_COMMAND_STORM); in advance_transaction()
484 acpi_ec_submit_query(ec); in advance_transaction()
486 wake_up(&ec->wait); in advance_transaction()
489 static void start_transaction(struct acpi_ec *ec) in start_transaction() argument
491 ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0; in start_transaction()
492 ec->curr->flags = 0; in start_transaction()
493 ec->curr->timestamp = jiffies; in start_transaction()
494 advance_transaction(ec); in start_transaction()
497 static int ec_poll(struct acpi_ec *ec) in ec_poll() argument
511 if (ec_transaction_completed(ec)) in ec_poll()
514 if (wait_event_timeout(ec->wait, in ec_poll()
515 ec_transaction_completed(ec), in ec_poll()
519 spin_lock_irqsave(&ec->lock, flags); in ec_poll()
521 ec->curr->timestamp + in ec_poll()
523 advance_transaction(ec); in ec_poll()
524 spin_unlock_irqrestore(&ec->lock, flags); in ec_poll()
527 spin_lock_irqsave(&ec->lock, flags); in ec_poll()
528 start_transaction(ec); in ec_poll()
529 spin_unlock_irqrestore(&ec->lock, flags); in ec_poll()
534 static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, in acpi_ec_transaction_unlocked() argument
543 spin_lock_irqsave(&ec->lock, tmp); in acpi_ec_transaction_unlocked()
545 if (!acpi_ec_submit_flushable_request(ec)) { in acpi_ec_transaction_unlocked()
549 ec_dbg_ref(ec, "Increase command"); in acpi_ec_transaction_unlocked()
551 ec->curr = t; in acpi_ec_transaction_unlocked()
553 start_transaction(ec); in acpi_ec_transaction_unlocked()
554 spin_unlock_irqrestore(&ec->lock, tmp); in acpi_ec_transaction_unlocked()
555 ret = ec_poll(ec); in acpi_ec_transaction_unlocked()
556 spin_lock_irqsave(&ec->lock, tmp); in acpi_ec_transaction_unlocked()
558 acpi_ec_clear_storm(ec, EC_FLAGS_COMMAND_STORM); in acpi_ec_transaction_unlocked()
560 ec->curr = NULL; in acpi_ec_transaction_unlocked()
562 acpi_ec_complete_request(ec); in acpi_ec_transaction_unlocked()
563 ec_dbg_ref(ec, "Decrease command"); in acpi_ec_transaction_unlocked()
565 spin_unlock_irqrestore(&ec->lock, tmp); in acpi_ec_transaction_unlocked()
569 static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) in acpi_ec_transaction() argument
574 if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata)) in acpi_ec_transaction()
578 mutex_lock(&ec->mutex); in acpi_ec_transaction()
579 if (ec->global_lock) { in acpi_ec_transaction()
587 status = acpi_ec_transaction_unlocked(ec, t); in acpi_ec_transaction()
589 if (test_bit(EC_FLAGS_COMMAND_STORM, &ec->flags)) in acpi_ec_transaction()
591 if (ec->global_lock) in acpi_ec_transaction()
594 mutex_unlock(&ec->mutex); in acpi_ec_transaction()
598 static int acpi_ec_burst_enable(struct acpi_ec *ec) in acpi_ec_burst_enable() argument
605 return acpi_ec_transaction(ec, &t); in acpi_ec_burst_enable()
608 static int acpi_ec_burst_disable(struct acpi_ec *ec) in acpi_ec_burst_disable() argument
614 return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? in acpi_ec_burst_disable()
615 acpi_ec_transaction(ec, &t) : 0; in acpi_ec_burst_disable()
618 static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data) in acpi_ec_read() argument
626 result = acpi_ec_transaction(ec, &t); in acpi_ec_read()
631 static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) in acpi_ec_write() argument
638 return acpi_ec_transaction(ec, &t); in acpi_ec_write()
700 static void acpi_ec_clear(struct acpi_ec *ec) in acpi_ec_clear() argument
706 status = acpi_ec_query(ec, &value); in acpi_ec_clear()
717 static void acpi_ec_start(struct acpi_ec *ec, bool resuming) in acpi_ec_start() argument
721 spin_lock_irqsave(&ec->lock, flags); in acpi_ec_start()
722 if (!test_and_set_bit(EC_FLAGS_STARTED, &ec->flags)) { in acpi_ec_start()
726 acpi_ec_submit_request(ec); in acpi_ec_start()
727 ec_dbg_ref(ec, "Increase driver"); in acpi_ec_start()
731 spin_unlock_irqrestore(&ec->lock, flags); in acpi_ec_start()
734 static bool acpi_ec_stopped(struct acpi_ec *ec) in acpi_ec_stopped() argument
739 spin_lock_irqsave(&ec->lock, flags); in acpi_ec_stopped()
740 flushed = acpi_ec_flushed(ec); in acpi_ec_stopped()
741 spin_unlock_irqrestore(&ec->lock, flags); in acpi_ec_stopped()
745 static void acpi_ec_stop(struct acpi_ec *ec, bool suspending) in acpi_ec_stop() argument
749 spin_lock_irqsave(&ec->lock, flags); in acpi_ec_stop()
750 if (acpi_ec_started(ec)) { in acpi_ec_stop()
752 set_bit(EC_FLAGS_STOPPED, &ec->flags); in acpi_ec_stop()
753 spin_unlock_irqrestore(&ec->lock, flags); in acpi_ec_stop()
754 wait_event(ec->wait, acpi_ec_stopped(ec)); in acpi_ec_stop()
755 spin_lock_irqsave(&ec->lock, flags); in acpi_ec_stop()
758 acpi_ec_complete_request(ec); in acpi_ec_stop()
759 ec_dbg_ref(ec, "Decrease driver"); in acpi_ec_stop()
761 clear_bit(EC_FLAGS_STARTED, &ec->flags); in acpi_ec_stop()
762 clear_bit(EC_FLAGS_STOPPED, &ec->flags); in acpi_ec_stop()
765 spin_unlock_irqrestore(&ec->lock, flags); in acpi_ec_stop()
770 struct acpi_ec *ec = first_ec; in acpi_ec_block_transactions() local
772 if (!ec) in acpi_ec_block_transactions()
775 mutex_lock(&ec->mutex); in acpi_ec_block_transactions()
777 acpi_ec_stop(ec, true); in acpi_ec_block_transactions()
778 mutex_unlock(&ec->mutex); in acpi_ec_block_transactions()
783 struct acpi_ec *ec = first_ec; in acpi_ec_unblock_transactions() local
785 if (!ec) in acpi_ec_unblock_transactions()
789 acpi_ec_start(ec, true); in acpi_ec_unblock_transactions()
792 acpi_ec_clear(ec); in acpi_ec_unblock_transactions()
829 int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, in acpi_ec_add_query_handler() argument
843 mutex_lock(&ec->mutex); in acpi_ec_add_query_handler()
845 list_add(&handler->node, &ec->list); in acpi_ec_add_query_handler()
846 mutex_unlock(&ec->mutex); in acpi_ec_add_query_handler()
851 void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) in acpi_ec_remove_query_handler() argument
856 mutex_lock(&ec->mutex); in acpi_ec_remove_query_handler()
857 list_for_each_entry_safe(handler, tmp, &ec->list, node) { in acpi_ec_remove_query_handler()
863 mutex_unlock(&ec->mutex); in acpi_ec_remove_query_handler()
884 static int acpi_ec_query(struct acpi_ec *ec, u8 *data) in acpi_ec_query() argument
899 result = acpi_ec_transaction(ec, &t); in acpi_ec_query()
907 mutex_lock(&ec->mutex); in acpi_ec_query()
908 list_for_each_entry(handler, &ec->list, node) { in acpi_ec_query()
922 mutex_unlock(&ec->mutex); in acpi_ec_query()
928 struct acpi_ec *ec = container_of(work, struct acpi_ec, work); in acpi_ec_gpe_poller() local
930 acpi_ec_query(ec, NULL); in acpi_ec_gpe_poller()
937 struct acpi_ec *ec = data; in acpi_ec_gpe_handler() local
939 spin_lock_irqsave(&ec->lock, flags); in acpi_ec_gpe_handler()
940 advance_transaction(ec); in acpi_ec_gpe_handler()
941 spin_unlock_irqrestore(&ec->lock, flags); in acpi_ec_gpe_handler()
954 struct acpi_ec *ec = handler_context; in acpi_ec_space_handler() local
965 acpi_ec_burst_enable(ec); in acpi_ec_space_handler()
969 acpi_ec_read(ec, address, value) : in acpi_ec_space_handler()
970 acpi_ec_write(ec, address, *value); in acpi_ec_space_handler()
973 acpi_ec_burst_disable(ec); in acpi_ec_space_handler()
996 struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); in make_acpi_ec() local
998 if (!ec) in make_acpi_ec()
1000 ec->flags = 1 << EC_FLAGS_QUERY_PENDING; in make_acpi_ec()
1001 mutex_init(&ec->mutex); in make_acpi_ec()
1002 init_waitqueue_head(&ec->wait); in make_acpi_ec()
1003 INIT_LIST_HEAD(&ec->list); in make_acpi_ec()
1004 spin_lock_init(&ec->lock); in make_acpi_ec()
1005 INIT_WORK(&ec->work, acpi_ec_gpe_poller); in make_acpi_ec()
1006 return ec; in make_acpi_ec()
1015 struct acpi_ec *ec = context; in acpi_ec_register_query_methods() local
1022 acpi_ec_add_query_handler(ec, value, handle, NULL, NULL); in acpi_ec_register_query_methods()
1031 struct acpi_ec *ec = context; in ec_parse_device() local
1034 ec->command_addr = ec->data_addr = 0; in ec_parse_device()
1037 ec_parse_io_ports, ec); in ec_parse_device()
1046 ec->gpe = tmp; in ec_parse_device()
1050 ec->global_lock = tmp; in ec_parse_device()
1051 ec->handle = handle; in ec_parse_device()
1055 static int ec_install_handlers(struct acpi_ec *ec) in ec_install_handlers() argument
1059 if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) in ec_install_handlers()
1061 status = acpi_install_gpe_raw_handler(NULL, ec->gpe, in ec_install_handlers()
1063 &acpi_ec_gpe_handler, ec); in ec_install_handlers()
1067 acpi_ec_start(ec, false); in ec_install_handlers()
1068 status = acpi_install_address_space_handler(ec->handle, in ec_install_handlers()
1071 NULL, ec); in ec_install_handlers()
1082 acpi_ec_stop(ec, false); in ec_install_handlers()
1083 acpi_remove_gpe_handler(NULL, ec->gpe, in ec_install_handlers()
1089 set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); in ec_install_handlers()
1093 static void ec_remove_handlers(struct acpi_ec *ec) in ec_remove_handlers() argument
1095 if (!test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) in ec_remove_handlers()
1097 acpi_ec_stop(ec, false); in ec_remove_handlers()
1098 if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, in ec_remove_handlers()
1101 if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, in ec_remove_handlers()
1104 clear_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); in ec_remove_handlers()
1109 struct acpi_ec *ec = NULL; in acpi_ec_add() local
1119 ec = boot_ec; in acpi_ec_add()
1122 ec = make_acpi_ec(); in acpi_ec_add()
1123 if (!ec) in acpi_ec_add()
1126 if (ec_parse_device(device->handle, 0, ec, NULL) != in acpi_ec_add()
1128 kfree(ec); in acpi_ec_add()
1133 acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1, in acpi_ec_add()
1134 acpi_ec_register_query_methods, NULL, ec, NULL); in acpi_ec_add()
1137 first_ec = ec; in acpi_ec_add()
1138 device->driver_data = ec; in acpi_ec_add()
1140 ret = !!request_region(ec->data_addr, 1, "EC data"); in acpi_ec_add()
1141 WARN(!ret, "Could not request EC data io port 0x%lx", ec->data_addr); in acpi_ec_add()
1142 ret = !!request_region(ec->command_addr, 1, "EC cmd"); in acpi_ec_add()
1143 WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr); in acpi_ec_add()
1146 ec->gpe, ec->command_addr, ec->data_addr); in acpi_ec_add()
1148 ret = ec_install_handlers(ec); in acpi_ec_add()
1151 acpi_walk_dep_device_list(ec->handle); in acpi_ec_add()
1154 clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); in acpi_ec_add()
1158 acpi_ec_clear(ec); in acpi_ec_add()
1164 struct acpi_ec *ec; in acpi_ec_remove() local
1170 ec = acpi_driver_data(device); in acpi_ec_remove()
1171 ec_remove_handlers(ec); in acpi_ec_remove()
1172 mutex_lock(&ec->mutex); in acpi_ec_remove()
1173 list_for_each_entry_safe(handler, tmp, &ec->list, node) { in acpi_ec_remove()
1177 mutex_unlock(&ec->mutex); in acpi_ec_remove()
1178 release_region(ec->data_addr, 1); in acpi_ec_remove()
1179 release_region(ec->command_addr, 1); in acpi_ec_remove()
1181 if (ec == first_ec) in acpi_ec_remove()
1183 kfree(ec); in acpi_ec_remove()
1190 struct acpi_ec *ec = context; in ec_parse_io_ports() local
1200 if (ec->data_addr == 0) in ec_parse_io_ports()
1201 ec->data_addr = resource->data.io.minimum; in ec_parse_io_ports()
1202 else if (ec->command_addr == 0) in ec_parse_io_ports()
1203 ec->command_addr = resource->data.io.minimum; in ec_parse_io_ports()