aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/battery.c47
-rw-r--r--drivers/acpi/processor_idle.c32
2 files changed, 55 insertions, 24 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index d7b499fe0cd9..81651032791b 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -113,7 +113,7 @@ struct acpi_battery_info {
113 acpi_string oem_info; 113 acpi_string oem_info;
114}; 114};
115 115
116enum acpi_battery_files { 116enum acpi_battery_files{
117 ACPI_BATTERY_INFO = 0, 117 ACPI_BATTERY_INFO = 0,
118 ACPI_BATTERY_STATE, 118 ACPI_BATTERY_STATE,
119 ACPI_BATTERY_ALARM, 119 ACPI_BATTERY_ALARM,
@@ -129,14 +129,13 @@ struct acpi_battery_flags {
129}; 129};
130 130
131struct acpi_battery { 131struct acpi_battery {
132 struct mutex mutex;
132 struct acpi_device *device; 133 struct acpi_device *device;
133 struct acpi_battery_flags flags; 134 struct acpi_battery_flags flags;
134 struct acpi_buffer bif_data; 135 struct acpi_buffer bif_data;
135 struct acpi_buffer bst_data; 136 struct acpi_buffer bst_data;
136 struct mutex lock;
137 unsigned long alarm; 137 unsigned long alarm;
138 unsigned long update_time[ACPI_BATTERY_NUMFILES]; 138 unsigned long update_time[ACPI_BATTERY_NUMFILES];
139
140}; 139};
141 140
142inline int acpi_battery_present(struct acpi_battery *battery) 141inline int acpi_battery_present(struct acpi_battery *battery)
@@ -236,10 +235,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
236 return 0; 235 return 0;
237 236
238 /* Evaluate _BIF */ 237 /* Evaluate _BIF */
239 mutex_lock(&battery->lock); 238
240 status = acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", 239 status =
241 NULL, &buffer); 240 acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL,
242 mutex_unlock(&battery->lock); 241 &buffer);
243 if (ACPI_FAILURE(status)) { 242 if (ACPI_FAILURE(status)) {
244 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); 243 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
245 return -ENODEV; 244 return -ENODEV;
@@ -286,10 +285,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
286 return 0; 285 return 0;
287 286
288 /* Evaluate _BST */ 287 /* Evaluate _BST */
289 mutex_lock(&battery->lock); 288
290 status = acpi_evaluate_object(acpi_battery_handle(battery), "_BST", 289 status =
291 NULL, &buffer); 290 acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL,
292 mutex_unlock(&battery->lock); 291 &buffer);
293 if (ACPI_FAILURE(status)) { 292 if (ACPI_FAILURE(status)) {
294 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); 293 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
295 return -ENODEV; 294 return -ENODEV;
@@ -337,10 +336,9 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
337 336
338 arg0.integer.value = alarm; 337 arg0.integer.value = alarm;
339 338
340 mutex_lock(&battery->lock); 339 status =
341 status = acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", 340 acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
342 &arg_list, NULL); 341 &arg_list, NULL);
343 mutex_unlock(&battery->lock);
344 if (ACPI_FAILURE(status)) 342 if (ACPI_FAILURE(status))
345 return -ENODEV; 343 return -ENODEV;
346 344
@@ -660,6 +658,8 @@ acpi_battery_write_alarm(struct file *file,
660 if (!battery || (count > sizeof(alarm_string) - 1)) 658 if (!battery || (count > sizeof(alarm_string) - 1))
661 return -EINVAL; 659 return -EINVAL;
662 660
661 mutex_lock(&battery->mutex);
662
663 result = acpi_battery_update(battery, 1, &update_result); 663 result = acpi_battery_update(battery, 1, &update_result);
664 if (result) { 664 if (result) {
665 result = -ENODEV; 665 result = -ENODEV;
@@ -688,7 +688,9 @@ acpi_battery_write_alarm(struct file *file,
688 acpi_battery_check_result(battery, result); 688 acpi_battery_check_result(battery, result);
689 689
690 if (!result) 690 if (!result)
691 return count; 691 result = count;
692
693 mutex_unlock(&battery->mutex);
692 694
693 return result; 695 return result;
694} 696}
@@ -712,6 +714,8 @@ static int acpi_battery_read(int fid, struct seq_file *seq)
712 int update_result = ACPI_BATTERY_NONE_UPDATE; 714 int update_result = ACPI_BATTERY_NONE_UPDATE;
713 int update = 0; 715 int update = 0;
714 716
717 mutex_lock(&battery->mutex);
718
715 update = (get_seconds() - battery->update_time[fid] >= update_time); 719 update = (get_seconds() - battery->update_time[fid] >= update_time);
716 update = (update | battery->flags.update[fid]); 720 update = (update | battery->flags.update[fid]);
717 721
@@ -729,6 +733,7 @@ static int acpi_battery_read(int fid, struct seq_file *seq)
729 result = acpi_read_funcs[fid].print(seq, result); 733 result = acpi_read_funcs[fid].print(seq, result);
730 acpi_battery_check_result(battery, result); 734 acpi_battery_check_result(battery, result);
731 battery->flags.update[fid] = result; 735 battery->flags.update[fid] = result;
736 mutex_unlock(&battery->mutex);
732 return result; 737 return result;
733} 738}
734 739
@@ -892,7 +897,10 @@ static int acpi_battery_add(struct acpi_device *device)
892 if (!battery) 897 if (!battery)
893 return -ENOMEM; 898 return -ENOMEM;
894 899
895 mutex_init(&battery->lock); 900 mutex_init(&battery->mutex);
901
902 mutex_lock(&battery->mutex);
903
896 battery->device = device; 904 battery->device = device;
897 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); 905 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
898 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); 906 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
@@ -928,6 +936,7 @@ static int acpi_battery_add(struct acpi_device *device)
928 kfree(battery); 936 kfree(battery);
929 } 937 }
930 938
939 mutex_unlock(&battery->mutex);
931 940
932 return result; 941 return result;
933} 942}
@@ -942,6 +951,8 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
942 951
943 battery = acpi_driver_data(device); 952 battery = acpi_driver_data(device);
944 953
954 mutex_lock(&battery->mutex);
955
945 status = acpi_remove_notify_handler(device->handle, 956 status = acpi_remove_notify_handler(device->handle,
946 ACPI_ALL_NOTIFY, 957 ACPI_ALL_NOTIFY,
947 acpi_battery_notify); 958 acpi_battery_notify);
@@ -952,7 +963,9 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
952 963
953 kfree(battery->bst_data.pointer); 964 kfree(battery->bst_data.pointer);
954 965
955 mutex_destroy(&battery->lock); 966 mutex_unlock(&battery->mutex);
967
968 mutex_destroy(&battery->mutex);
956 969
957 kfree(battery); 970 kfree(battery);
958 971
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index a8634a0655fc..d9b8af763e1e 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -63,6 +63,7 @@
63ACPI_MODULE_NAME("processor_idle"); 63ACPI_MODULE_NAME("processor_idle");
64#define ACPI_PROCESSOR_FILE_POWER "power" 64#define ACPI_PROCESSOR_FILE_POWER "power"
65#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000) 65#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
66#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY)
66#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */ 67#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */
67#define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */ 68#define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */
68static void (*pm_idle_save) (void) __read_mostly; 69static void (*pm_idle_save) (void) __read_mostly;
@@ -462,6 +463,9 @@ static void acpi_processor_idle(void)
462 * TBD: Can't get time duration while in C1, as resumes 463 * TBD: Can't get time duration while in C1, as resumes
463 * go to an ISR rather than here. Need to instrument 464 * go to an ISR rather than here. Need to instrument
464 * base interrupt handler. 465 * base interrupt handler.
466 *
467 * Note: the TSC better not stop in C1, sched_clock() will
468 * skew otherwise.
465 */ 469 */
466 sleep_ticks = 0xFFFFFFFF; 470 sleep_ticks = 0xFFFFFFFF;
467 break; 471 break;
@@ -469,6 +473,8 @@ static void acpi_processor_idle(void)
469 case ACPI_STATE_C2: 473 case ACPI_STATE_C2:
470 /* Get start time (ticks) */ 474 /* Get start time (ticks) */
471 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); 475 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
476 /* Tell the scheduler that we are going deep-idle: */
477 sched_clock_idle_sleep_event();
472 /* Invoke C2 */ 478 /* Invoke C2 */
473 acpi_state_timer_broadcast(pr, cx, 1); 479 acpi_state_timer_broadcast(pr, cx, 1);
474 acpi_cstate_enter(cx); 480 acpi_cstate_enter(cx);
@@ -479,17 +485,22 @@ static void acpi_processor_idle(void)
479 /* TSC halts in C2, so notify users */ 485 /* TSC halts in C2, so notify users */
480 mark_tsc_unstable("possible TSC halt in C2"); 486 mark_tsc_unstable("possible TSC halt in C2");
481#endif 487#endif
488 /* Compute time (ticks) that we were actually asleep */
489 sleep_ticks = ticks_elapsed(t1, t2);
490
491 /* Tell the scheduler how much we idled: */
492 sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
493
482 /* Re-enable interrupts */ 494 /* Re-enable interrupts */
483 local_irq_enable(); 495 local_irq_enable();
496 /* Do not account our idle-switching overhead: */
497 sleep_ticks -= cx->latency_ticks + C2_OVERHEAD;
498
484 current_thread_info()->status |= TS_POLLING; 499 current_thread_info()->status |= TS_POLLING;
485 /* Compute time (ticks) that we were actually asleep */
486 sleep_ticks =
487 ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD;
488 acpi_state_timer_broadcast(pr, cx, 0); 500 acpi_state_timer_broadcast(pr, cx, 0);
489 break; 501 break;
490 502
491 case ACPI_STATE_C3: 503 case ACPI_STATE_C3:
492
493 /* 504 /*
494 * disable bus master 505 * disable bus master
495 * bm_check implies we need ARB_DIS 506 * bm_check implies we need ARB_DIS
@@ -518,6 +529,8 @@ static void acpi_processor_idle(void)
518 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); 529 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
519 /* Invoke C3 */ 530 /* Invoke C3 */
520 acpi_state_timer_broadcast(pr, cx, 1); 531 acpi_state_timer_broadcast(pr, cx, 1);
532 /* Tell the scheduler that we are going deep-idle: */
533 sched_clock_idle_sleep_event();
521 acpi_cstate_enter(cx); 534 acpi_cstate_enter(cx);
522 /* Get end time (ticks) */ 535 /* Get end time (ticks) */
523 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); 536 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
@@ -531,12 +544,17 @@ static void acpi_processor_idle(void)
531 /* TSC halts in C3, so notify users */ 544 /* TSC halts in C3, so notify users */
532 mark_tsc_unstable("TSC halts in C3"); 545 mark_tsc_unstable("TSC halts in C3");
533#endif 546#endif
547 /* Compute time (ticks) that we were actually asleep */
548 sleep_ticks = ticks_elapsed(t1, t2);
549 /* Tell the scheduler how much we idled: */
550 sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
551
534 /* Re-enable interrupts */ 552 /* Re-enable interrupts */
535 local_irq_enable(); 553 local_irq_enable();
554 /* Do not account our idle-switching overhead: */
555 sleep_ticks -= cx->latency_ticks + C3_OVERHEAD;
556
536 current_thread_info()->status |= TS_POLLING; 557 current_thread_info()->status |= TS_POLLING;
537 /* Compute time (ticks) that we were actually asleep */
538 sleep_ticks =
539 ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD;
540 acpi_state_timer_broadcast(pr, cx, 0); 558 acpi_state_timer_broadcast(pr, cx, 0);
541 break; 559 break;
542 560