Lines 44-49
Link Here
|
44 |
#include <linux/slab.h> |
44 |
#include <linux/slab.h> |
45 |
#include <linux/acpi.h> |
45 |
#include <linux/acpi.h> |
46 |
#include <linux/dmi.h> |
46 |
#include <linux/dmi.h> |
|
|
47 |
#include <linux/kthread.h> |
47 |
#include <asm/io.h> |
48 |
#include <asm/io.h> |
48 |
|
49 |
|
49 |
#include "internal.h" |
50 |
#include "internal.h" |
Lines 75-81
enum ec_command {
Link Here
|
75 |
* when trying to clear the EC */ |
76 |
* when trying to clear the EC */ |
76 |
|
77 |
|
77 |
enum { |
78 |
enum { |
78 |
EC_FLAGS_QUERY_PENDING, /* Query is pending */ |
79 |
EC_FLAGS_EVENT_ENABLED, /* Event is enabled */ |
|
|
80 |
EC_FLAGS_EVENT_PENDING, /* Event is pending */ |
79 |
EC_FLAGS_GPE_STORM, /* GPE storm detected */ |
81 |
EC_FLAGS_GPE_STORM, /* GPE storm detected */ |
80 |
EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and |
82 |
EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and |
81 |
* OpReg are installed */ |
83 |
* OpReg are installed */ |
Lines 124-129
struct transaction {
Link Here
|
124 |
static struct acpi_ec_query_handler * |
126 |
static struct acpi_ec_query_handler * |
125 |
acpi_ec_get_query_handler(struct acpi_ec_query_handler *handler); |
127 |
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); |
128 |
static void acpi_ec_put_query_handler(struct acpi_ec_query_handler *handler); |
|
|
129 |
static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data); |
127 |
|
130 |
|
128 |
struct acpi_ec *boot_ec, *first_ec; |
131 |
struct acpi_ec *boot_ec, *first_ec; |
129 |
EXPORT_SYMBOL(first_ec); |
132 |
EXPORT_SYMBOL(first_ec); |
Lines 148-153
static bool acpi_ec_flushed(struct acpi_ec *ec)
Link Here
|
148 |
return ec->reference_count == 1; |
151 |
return ec->reference_count == 1; |
149 |
} |
152 |
} |
150 |
|
153 |
|
|
|
154 |
static bool acpi_ec_has_pending_event(struct acpi_ec *ec) |
155 |
{ |
156 |
return test_bit(EC_FLAGS_EVENT_ENABLED, &ec->flags) && |
157 |
test_bit(EC_FLAGS_EVENT_PENDING, &ec->flags); |
158 |
} |
159 |
|
151 |
/* -------------------------------------------------------------------------- |
160 |
/* -------------------------------------------------------------------------- |
152 |
* GPE Enhancement |
161 |
* GPE Enhancement |
153 |
* -------------------------------------------------------------------------- */ |
162 |
* -------------------------------------------------------------------------- */ |
Lines 176-195
static void acpi_ec_complete_request(struct acpi_ec *ec)
Link Here
|
176 |
* the flush operation is not in |
185 |
* the flush operation is not in |
177 |
* progress |
186 |
* progress |
178 |
* @ec: the EC device |
187 |
* @ec: the EC device |
|
|
188 |
* @check_event: check whether event is pending |
179 |
* |
189 |
* |
180 |
* This function must be used before taking a new action that should hold |
190 |
* This function must be used before taking a new action that should hold |
181 |
* the reference count. If this function returns false, then the action |
191 |
* the reference count. If this function returns false, then the action |
182 |
* must be discarded or it will prevent the flush operation from being |
192 |
* must be discarded or it will prevent the flush operation from being |
183 |
* completed. |
193 |
* completed. |
|
|
194 |
* |
195 |
* During flushing, QR_EC command need to pass this check when there is a |
196 |
* pending event, so that the reference count held for the pending event |
197 |
* can be decreased by the completion of the QR_EC command. |
184 |
*/ |
198 |
*/ |
185 |
static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec) |
199 |
static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec, |
|
|
200 |
bool check_event) |
186 |
{ |
201 |
{ |
187 |
if (!acpi_ec_started(ec)) |
202 |
if (!acpi_ec_started(ec)) { |
188 |
return false; |
203 |
if (!check_event || !acpi_ec_has_pending_event(ec)) |
|
|
204 |
return false; |
205 |
} |
189 |
acpi_ec_submit_request(ec); |
206 |
acpi_ec_submit_request(ec); |
190 |
return true; |
207 |
return true; |
191 |
} |
208 |
} |
192 |
|
209 |
|
|
|
210 |
static void acpi_ec_enable_event(struct acpi_ec *ec) |
211 |
{ |
212 |
unsigned long flags; |
213 |
|
214 |
spin_lock_irqsave(&ec->lock, flags); |
215 |
/* Hold reference for pending event */ |
216 |
if (!acpi_ec_submit_flushable_request(ec, false)) { |
217 |
spin_unlock_irqrestore(&ec->lock, flags); |
218 |
return; |
219 |
} |
220 |
set_bit(EC_FLAGS_EVENT_ENABLED, &ec->flags); |
221 |
if (test_bit(EC_FLAGS_EVENT_PENDING, &ec->flags)) { |
222 |
pr_debug("***** Event pending *****\n"); |
223 |
wake_up_process(ec->thread); |
224 |
spin_unlock_irqrestore(&ec->lock, flags); |
225 |
return; |
226 |
} |
227 |
acpi_ec_complete_request(ec); |
228 |
spin_unlock_irqrestore(&ec->lock, flags); |
229 |
} |
230 |
|
231 |
static void __acpi_ec_set_event(struct acpi_ec *ec) |
232 |
{ |
233 |
/* Hold reference for pending event */ |
234 |
if (!acpi_ec_submit_flushable_request(ec, false)) |
235 |
return; |
236 |
if (!test_and_set_bit(EC_FLAGS_EVENT_PENDING, &ec->flags)) { |
237 |
pr_debug("***** Event pending *****\n"); |
238 |
if (test_bit(EC_FLAGS_EVENT_ENABLED, &ec->flags)) { |
239 |
wake_up_process(ec->thread); |
240 |
return; |
241 |
} |
242 |
} |
243 |
acpi_ec_complete_request(ec); |
244 |
} |
245 |
|
246 |
static void __acpi_ec_complete_event(struct acpi_ec *ec) |
247 |
{ |
248 |
if (test_and_clear_bit(EC_FLAGS_EVENT_PENDING, &ec->flags)) { |
249 |
/* Unhold reference for pending event */ |
250 |
acpi_ec_complete_request(ec); |
251 |
pr_debug("***** Event running *****\n"); |
252 |
} |
253 |
} |
254 |
|
255 |
int acpi_ec_wait_for_event(struct acpi_ec *ec) |
256 |
{ |
257 |
unsigned long flags; |
258 |
|
259 |
set_current_state(TASK_INTERRUPTIBLE); |
260 |
while (!kthread_should_stop()) { |
261 |
spin_lock_irqsave(&ec->lock, flags); |
262 |
if (acpi_ec_has_pending_event(ec)) { |
263 |
spin_unlock_irqrestore(&ec->lock, flags); |
264 |
__set_current_state(TASK_RUNNING); |
265 |
return 0; |
266 |
} |
267 |
spin_unlock_irqrestore(&ec->lock, flags); |
268 |
schedule(); |
269 |
set_current_state(TASK_INTERRUPTIBLE); |
270 |
} |
271 |
__set_current_state(TASK_RUNNING); |
272 |
return -1; |
273 |
} |
274 |
|
193 |
/* -------------------------------------------------------------------------- |
275 |
/* -------------------------------------------------------------------------- |
194 |
* Transaction Management |
276 |
* Transaction Management |
195 |
* -------------------------------------------------------------------------- */ |
277 |
* -------------------------------------------------------------------------- */ |
Lines 297-303
static bool advance_transaction(struct acpi_ec *ec)
Link Here
|
297 |
t->flags |= ACPI_EC_COMMAND_COMPLETE; |
379 |
t->flags |= ACPI_EC_COMMAND_COMPLETE; |
298 |
wakeup = true; |
380 |
wakeup = true; |
299 |
} |
381 |
} |
300 |
return wakeup; |
382 |
goto out; |
301 |
} else { |
383 |
} else { |
302 |
/* |
384 |
/* |
303 |
* There is firmware refusing to respond QR_EC when SCI_EVT |
385 |
* There is firmware refusing to respond QR_EC when SCI_EVT |
Lines 319-327
static bool advance_transaction(struct acpi_ec *ec)
Link Here
|
319 |
} else if ((status & ACPI_EC_FLAG_IBF) == 0) { |
401 |
} else if ((status & ACPI_EC_FLAG_IBF) == 0) { |
320 |
acpi_ec_write_cmd(ec, t->command); |
402 |
acpi_ec_write_cmd(ec, t->command); |
321 |
t->flags |= ACPI_EC_COMMAND_POLL; |
403 |
t->flags |= ACPI_EC_COMMAND_POLL; |
|
|
404 |
if (t->command == ACPI_EC_COMMAND_QUERY) |
405 |
__acpi_ec_complete_event(ec); |
322 |
} else |
406 |
} else |
323 |
goto err; |
407 |
goto err; |
324 |
return wakeup; |
408 |
goto out; |
325 |
} |
409 |
} |
326 |
err: |
410 |
err: |
327 |
/* |
411 |
/* |
Lines 332-337
err:
Link Here
|
332 |
if (in_interrupt() && t) |
416 |
if (in_interrupt() && t) |
333 |
++t->irq_count; |
417 |
++t->irq_count; |
334 |
} |
418 |
} |
|
|
419 |
out: |
420 |
if (status & ACPI_EC_FLAG_SCI && |
421 |
(!t || t->flags & ACPI_EC_COMMAND_COMPLETE)) |
422 |
__acpi_ec_set_event(ec); |
335 |
return wakeup; |
423 |
return wakeup; |
336 |
} |
424 |
} |
337 |
|
425 |
|
Lines 342-358
static void start_transaction(struct acpi_ec *ec)
Link Here
|
342 |
(void)advance_transaction(ec); |
430 |
(void)advance_transaction(ec); |
343 |
} |
431 |
} |
344 |
|
432 |
|
345 |
static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data); |
|
|
346 |
|
347 |
static int ec_check_sci_sync(struct acpi_ec *ec, u8 state) |
348 |
{ |
349 |
if (state & ACPI_EC_FLAG_SCI) { |
350 |
if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) |
351 |
return acpi_ec_sync_query(ec, NULL); |
352 |
} |
353 |
return 0; |
354 |
} |
355 |
|
356 |
static int ec_poll(struct acpi_ec *ec) |
433 |
static int ec_poll(struct acpi_ec *ec) |
357 |
{ |
434 |
{ |
358 |
unsigned long flags; |
435 |
unsigned long flags; |
Lines 391-402
static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
Link Here
|
391 |
unsigned long tmp; |
468 |
unsigned long tmp; |
392 |
int ret = 0; |
469 |
int ret = 0; |
393 |
|
470 |
|
|
|
471 |
bool is_query = !!(t->command == ACPI_EC_COMMAND_QUERY); |
394 |
if (EC_FLAGS_MSI) |
472 |
if (EC_FLAGS_MSI) |
395 |
udelay(ACPI_EC_MSI_UDELAY); |
473 |
udelay(ACPI_EC_MSI_UDELAY); |
396 |
/* start transaction */ |
474 |
/* start transaction */ |
397 |
spin_lock_irqsave(&ec->lock, tmp); |
475 |
spin_lock_irqsave(&ec->lock, tmp); |
398 |
/* Enable GPE for command processing (IBF=0/OBF=1) */ |
476 |
/* Enable GPE for command processing (IBF=0/OBF=1) */ |
399 |
if (!acpi_ec_submit_flushable_request(ec)) { |
477 |
if (!acpi_ec_submit_flushable_request(ec, is_query)) { |
400 |
ret = -EINVAL; |
478 |
ret = -EINVAL; |
401 |
goto unlock; |
479 |
goto unlock; |
402 |
} |
480 |
} |
Lines 408-417
static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
Link Here
|
408 |
spin_unlock_irqrestore(&ec->lock, tmp); |
486 |
spin_unlock_irqrestore(&ec->lock, tmp); |
409 |
ret = ec_poll(ec); |
487 |
ret = ec_poll(ec); |
410 |
spin_lock_irqsave(&ec->lock, tmp); |
488 |
spin_lock_irqsave(&ec->lock, tmp); |
411 |
if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { |
|
|
412 |
clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
413 |
pr_debug("***** Event stopped *****\n"); |
414 |
} |
415 |
pr_debug("***** Command(%s) stopped *****\n", |
489 |
pr_debug("***** Command(%s) stopped *****\n", |
416 |
acpi_ec_cmd_string(t->command)); |
490 |
acpi_ec_cmd_string(t->command)); |
417 |
ec->curr = NULL; |
491 |
ec->curr = NULL; |
Lines 447-454
static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
Link Here
|
447 |
|
521 |
|
448 |
status = acpi_ec_transaction_unlocked(ec, t); |
522 |
status = acpi_ec_transaction_unlocked(ec, t); |
449 |
|
523 |
|
450 |
/* check if we received SCI during transaction */ |
|
|
451 |
ec_check_sci_sync(ec, acpi_ec_read_status(ec)); |
452 |
if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
524 |
if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
453 |
msleep(1); |
525 |
msleep(1); |
454 |
/* It is safe to enable the GPE outside of the transaction. */ |
526 |
/* It is safe to enable the GPE outside of the transaction. */ |
Lines 799-827
static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data)
Link Here
|
799 |
return 0; |
871 |
return 0; |
800 |
} |
872 |
} |
801 |
|
873 |
|
802 |
static void acpi_ec_gpe_query(void *ec_cxt) |
|
|
803 |
{ |
804 |
struct acpi_ec *ec = ec_cxt; |
805 |
|
806 |
if (!ec) |
807 |
return; |
808 |
mutex_lock(&ec->mutex); |
809 |
acpi_ec_sync_query(ec, NULL); |
810 |
mutex_unlock(&ec->mutex); |
811 |
} |
812 |
|
813 |
static int ec_check_sci(struct acpi_ec *ec, u8 state) |
814 |
{ |
815 |
if (state & ACPI_EC_FLAG_SCI) { |
816 |
if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { |
817 |
pr_debug("***** Event started *****\n"); |
818 |
return acpi_os_execute(OSL_NOTIFY_HANDLER, |
819 |
acpi_ec_gpe_query, ec); |
820 |
} |
821 |
} |
822 |
return 0; |
823 |
} |
824 |
|
825 |
static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, |
874 |
static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, |
826 |
u32 gpe_number, void *data) |
875 |
u32 gpe_number, void *data) |
827 |
{ |
876 |
{ |
Lines 832-841
static u32 acpi_ec_gpe_handler(acpi_handle gpe_device,
Link Here
|
832 |
if (advance_transaction(ec)) |
881 |
if (advance_transaction(ec)) |
833 |
wake_up(&ec->wait); |
882 |
wake_up(&ec->wait); |
834 |
spin_unlock_irqrestore(&ec->lock, flags); |
883 |
spin_unlock_irqrestore(&ec->lock, flags); |
835 |
ec_check_sci(ec, acpi_ec_read_status(ec)); |
|
|
836 |
return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE; |
884 |
return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE; |
837 |
} |
885 |
} |
838 |
|
886 |
|
|
|
887 |
static int acpi_ec_event_poller(void *context) |
888 |
{ |
889 |
struct acpi_ec *ec = context; |
890 |
|
891 |
while (!acpi_ec_wait_for_event(ec)) { |
892 |
pr_debug("***** Event poller started *****\n"); |
893 |
mutex_lock(&ec->mutex); |
894 |
(void)acpi_ec_sync_query(ec, NULL); |
895 |
mutex_unlock(&ec->mutex); |
896 |
pr_debug("***** Event poller stopped *****\n"); |
897 |
} |
898 |
return 0; |
899 |
} |
900 |
|
901 |
static int ec_create_event_poller(struct acpi_ec *ec) |
902 |
{ |
903 |
struct task_struct *t; |
904 |
|
905 |
t = kthread_run(acpi_ec_event_poller, ec, "ec/gpe-%lu", ec->gpe); |
906 |
if (IS_ERR(t)) { |
907 |
pr_err("failed to create event poller %lu\n", ec->gpe); |
908 |
return PTR_ERR(t); |
909 |
} |
910 |
get_task_struct(t); |
911 |
ec->thread = t; |
912 |
return 0; |
913 |
} |
914 |
|
915 |
static void ec_delete_event_poller(struct acpi_ec *ec) |
916 |
{ |
917 |
struct task_struct *t = ec->thread; |
918 |
|
919 |
ec->thread = NULL; |
920 |
kthread_stop(t); |
921 |
put_task_struct(t); |
922 |
} |
923 |
|
839 |
/* -------------------------------------------------------------------------- |
924 |
/* -------------------------------------------------------------------------- |
840 |
* Address Space Management |
925 |
* Address Space Management |
841 |
* -------------------------------------------------------------------------- */ |
926 |
* -------------------------------------------------------------------------- */ |
Lines 891-897
static struct acpi_ec *make_acpi_ec(void)
Link Here
|
891 |
|
976 |
|
892 |
if (!ec) |
977 |
if (!ec) |
893 |
return NULL; |
978 |
return NULL; |
894 |
ec->flags = 1 << EC_FLAGS_QUERY_PENDING; |
|
|
895 |
mutex_init(&ec->mutex); |
979 |
mutex_init(&ec->mutex); |
896 |
init_waitqueue_head(&ec->wait); |
980 |
init_waitqueue_head(&ec->wait); |
897 |
INIT_LIST_HEAD(&ec->list); |
981 |
INIT_LIST_HEAD(&ec->list); |
Lines 947-961
ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
Link Here
|
947 |
|
1031 |
|
948 |
static int ec_install_handlers(struct acpi_ec *ec) |
1032 |
static int ec_install_handlers(struct acpi_ec *ec) |
949 |
{ |
1033 |
{ |
|
|
1034 |
int ret; |
950 |
acpi_status status; |
1035 |
acpi_status status; |
951 |
|
1036 |
|
952 |
if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) |
1037 |
if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) |
953 |
return 0; |
1038 |
return 0; |
|
|
1039 |
ret = ec_create_event_poller(ec); |
1040 |
if (ret) |
1041 |
return ret; |
954 |
status = acpi_install_gpe_handler(NULL, ec->gpe, |
1042 |
status = acpi_install_gpe_handler(NULL, ec->gpe, |
955 |
ACPI_GPE_EDGE_TRIGGERED, |
1043 |
ACPI_GPE_EDGE_TRIGGERED, |
956 |
&acpi_ec_gpe_handler, ec); |
1044 |
&acpi_ec_gpe_handler, ec); |
957 |
if (ACPI_FAILURE(status)) |
1045 |
if (ACPI_FAILURE(status)) { |
|
|
1046 |
ec_delete_event_poller(ec); |
958 |
return -ENODEV; |
1047 |
return -ENODEV; |
|
|
1048 |
} |
959 |
|
1049 |
|
960 |
acpi_ec_start(ec); |
1050 |
acpi_ec_start(ec); |
961 |
status = acpi_install_address_space_handler(ec->handle, |
1051 |
status = acpi_install_address_space_handler(ec->handle, |
Lines 975-980
static int ec_install_handlers(struct acpi_ec *ec)
Link Here
|
975 |
acpi_ec_stop(ec); |
1065 |
acpi_ec_stop(ec); |
976 |
acpi_remove_gpe_handler(NULL, ec->gpe, |
1066 |
acpi_remove_gpe_handler(NULL, ec->gpe, |
977 |
&acpi_ec_gpe_handler); |
1067 |
&acpi_ec_gpe_handler); |
|
|
1068 |
ec_delete_event_poller(ec); |
978 |
return -ENODEV; |
1069 |
return -ENODEV; |
979 |
} |
1070 |
} |
980 |
} |
1071 |
} |
Lines 992-997
static void ec_remove_handlers(struct acpi_ec *ec)
Link Here
|
992 |
if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, |
1083 |
if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, |
993 |
&acpi_ec_gpe_handler))) |
1084 |
&acpi_ec_gpe_handler))) |
994 |
pr_err("failed to remove gpe handler\n"); |
1085 |
pr_err("failed to remove gpe handler\n"); |
|
|
1086 |
ec_delete_event_poller(ec); |
995 |
clear_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); |
1087 |
clear_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); |
996 |
} |
1088 |
} |
997 |
|
1089 |
|
Lines 1039-1045
static int acpi_ec_add(struct acpi_device *device)
Link Here
|
1039 |
ret = ec_install_handlers(ec); |
1131 |
ret = ec_install_handlers(ec); |
1040 |
|
1132 |
|
1041 |
/* EC is fully operational, allow queries */ |
1133 |
/* EC is fully operational, allow queries */ |
1042 |
clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
1134 |
acpi_ec_enable_event(ec); |
1043 |
|
1135 |
|
1044 |
/* Clear stale _Q events if hardware might require that */ |
1136 |
/* Clear stale _Q events if hardware might require that */ |
1045 |
if (EC_FLAGS_POLL_EVENTS) { |
1137 |
if (EC_FLAGS_POLL_EVENTS) { |