Lines 106-111
struct acpi_ec_query_handler {
Link Here
|
106 |
acpi_handle handle; |
106 |
acpi_handle handle; |
107 |
void *data; |
107 |
void *data; |
108 |
u8 query_bit; |
108 |
u8 query_bit; |
|
|
109 |
struct kref kref; |
109 |
}; |
110 |
}; |
110 |
|
111 |
|
111 |
struct transaction { |
112 |
struct transaction { |
Lines 120-125
struct transaction {
Link Here
|
120 |
u8 flags; |
121 |
u8 flags; |
121 |
}; |
122 |
}; |
122 |
|
123 |
|
|
|
124 |
static struct acpi_ec_query_handler * |
125 |
acpi_ec_get_query_handler(struct acpi_ec_query_handler *handler); |
126 |
static void acpi_ec_put_query_handler(struct acpi_ec_query_handler *handler); |
127 |
|
123 |
struct acpi_ec *boot_ec, *first_ec; |
128 |
struct acpi_ec *boot_ec, *first_ec; |
124 |
EXPORT_SYMBOL(first_ec); |
129 |
EXPORT_SYMBOL(first_ec); |
125 |
|
130 |
|
Lines 626-631
static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 *data)
Link Here
|
626 |
/* -------------------------------------------------------------------------- |
631 |
/* -------------------------------------------------------------------------- |
627 |
Event Management |
632 |
Event Management |
628 |
-------------------------------------------------------------------------- */ |
633 |
-------------------------------------------------------------------------- */ |
|
|
634 |
static struct acpi_ec_query_handler * |
635 |
acpi_ec_get_query_handler(struct acpi_ec_query_handler *handler) |
636 |
{ |
637 |
if (handler) |
638 |
kref_get(&handler->kref); |
639 |
return handler; |
640 |
} |
641 |
|
642 |
static void acpi_ec_query_handler_release(struct kref *kref) |
643 |
{ |
644 |
struct acpi_ec_query_handler *handler = |
645 |
container_of(kref, struct acpi_ec_query_handler, kref); |
646 |
|
647 |
kfree(handler); |
648 |
} |
649 |
|
650 |
static void acpi_ec_put_query_handler(struct acpi_ec_query_handler *handler) |
651 |
{ |
652 |
kref_put(&handler->kref, acpi_ec_query_handler_release); |
653 |
} |
654 |
|
629 |
int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, |
655 |
int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, |
630 |
acpi_handle handle, acpi_ec_query_func func, |
656 |
acpi_handle handle, acpi_ec_query_func func, |
631 |
void *data) |
657 |
void *data) |
Lines 641-646
int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
Link Here
|
641 |
handler->func = func; |
667 |
handler->func = func; |
642 |
handler->data = data; |
668 |
handler->data = data; |
643 |
mutex_lock(&ec->mutex); |
669 |
mutex_lock(&ec->mutex); |
|
|
670 |
kref_init(&handler->kref); |
644 |
list_add(&handler->node, &ec->list); |
671 |
list_add(&handler->node, &ec->list); |
645 |
mutex_unlock(&ec->mutex); |
672 |
mutex_unlock(&ec->mutex); |
646 |
return 0; |
673 |
return 0; |
Lines 650-664
EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler);
Link Here
|
650 |
void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) |
677 |
void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) |
651 |
{ |
678 |
{ |
652 |
struct acpi_ec_query_handler *handler, *tmp; |
679 |
struct acpi_ec_query_handler *handler, *tmp; |
|
|
680 |
LIST_HEAD(free_list); |
653 |
|
681 |
|
654 |
mutex_lock(&ec->mutex); |
682 |
mutex_lock(&ec->mutex); |
655 |
list_for_each_entry_safe(handler, tmp, &ec->list, node) { |
683 |
list_for_each_entry_safe(handler, tmp, &ec->list, node) { |
656 |
if (query_bit == handler->query_bit) { |
684 |
if (query_bit == handler->query_bit) { |
657 |
list_del(&handler->node); |
685 |
list_del_init(&handler->node); |
658 |
kfree(handler); |
686 |
list_add(&handler->node, &free_list); |
659 |
} |
687 |
} |
660 |
} |
688 |
} |
661 |
mutex_unlock(&ec->mutex); |
689 |
mutex_unlock(&ec->mutex); |
|
|
690 |
list_for_each_entry(handler, &free_list, node) |
691 |
acpi_ec_put_query_handler(handler); |
662 |
} |
692 |
} |
663 |
EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); |
693 |
EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); |
664 |
|
694 |
|
Lines 674-687
static void acpi_ec_run(void *cxt)
Link Here
|
674 |
else if (handler->handle) |
704 |
else if (handler->handle) |
675 |
acpi_evaluate_object(handler->handle, NULL, NULL, NULL); |
705 |
acpi_evaluate_object(handler->handle, NULL, NULL, NULL); |
676 |
pr_debug("##### Query(0x%02x) stopped #####\n", handler->query_bit); |
706 |
pr_debug("##### Query(0x%02x) stopped #####\n", handler->query_bit); |
677 |
kfree(handler); |
707 |
acpi_ec_put_query_handler(handler); |
678 |
} |
708 |
} |
679 |
|
709 |
|
680 |
static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data) |
710 |
static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data) |
681 |
{ |
711 |
{ |
682 |
u8 value = 0; |
712 |
u8 value = 0; |
683 |
int status; |
713 |
int status; |
684 |
struct acpi_ec_query_handler *handler, *copy; |
714 |
struct acpi_ec_query_handler *handler; |
685 |
|
715 |
|
686 |
status = acpi_ec_query_unlocked(ec, &value); |
716 |
status = acpi_ec_query_unlocked(ec, &value); |
687 |
if (data) |
717 |
if (data) |
Lines 692-706
static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data)
Link Here
|
692 |
list_for_each_entry(handler, &ec->list, node) { |
722 |
list_for_each_entry(handler, &ec->list, node) { |
693 |
if (value == handler->query_bit) { |
723 |
if (value == handler->query_bit) { |
694 |
/* have custom handler for this bit */ |
724 |
/* have custom handler for this bit */ |
695 |
copy = kmalloc(sizeof(*handler), GFP_KERNEL); |
725 |
handler = acpi_ec_get_query_handler(handler); |
696 |
if (!copy) |
|
|
697 |
return -ENOMEM; |
698 |
memcpy(copy, handler, sizeof(*copy)); |
699 |
pr_debug("##### Query(0x%02x) scheduled #####\n", |
726 |
pr_debug("##### Query(0x%02x) scheduled #####\n", |
700 |
handler->query_bit); |
727 |
handler->query_bit); |
701 |
return acpi_os_execute((copy->func) ? |
728 |
return acpi_os_execute((handler->func) ? |
702 |
OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER, |
729 |
OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER, |
703 |
acpi_ec_run, copy); |
730 |
acpi_ec_run, handler); |
704 |
} |
731 |
} |
705 |
} |
732 |
} |
706 |
return 0; |
733 |
return 0; |
707 |
- |
|
|