aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/thermal.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/thermal.c')
-rw-r--r--drivers/acpi/thermal.c458
1 files changed, 48 insertions, 410 deletions
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 1c410ef859c6..0ec48d2f85c5 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -37,7 +37,6 @@
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/types.h> 38#include <linux/types.h>
39#include <linux/proc_fs.h> 39#include <linux/proc_fs.h>
40#include <linux/timer.h>
41#include <linux/jiffies.h> 40#include <linux/jiffies.h>
42#include <linux/kmod.h> 41#include <linux/kmod.h>
43#include <linux/seq_file.h> 42#include <linux/seq_file.h>
@@ -190,7 +189,6 @@ struct acpi_thermal {
190 struct acpi_thermal_state state; 189 struct acpi_thermal_state state;
191 struct acpi_thermal_trips trips; 190 struct acpi_thermal_trips trips;
192 struct acpi_handle_list devices; 191 struct acpi_handle_list devices;
193 struct timer_list timer;
194 struct thermal_zone_device *thermal_zone; 192 struct thermal_zone_device *thermal_zone;
195 int tz_enabled; 193 int tz_enabled;
196 struct mutex lock; 194 struct mutex lock;
@@ -290,6 +288,11 @@ static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds)
290 288
291 tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */ 289 tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */
292 290
291 tz->thermal_zone->polling_delay = seconds * 1000;
292
293 if (tz->tz_enabled)
294 thermal_zone_device_update(tz->thermal_zone);
295
293 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 296 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
294 "Polling frequency set to %lu seconds\n", 297 "Polling frequency set to %lu seconds\n",
295 tz->polling_frequency/10)); 298 tz->polling_frequency/10));
@@ -569,386 +572,11 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
569 return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); 572 return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
570} 573}
571 574
572static int acpi_thermal_critical(struct acpi_thermal *tz)
573{
574 if (!tz || !tz->trips.critical.flags.valid)
575 return -EINVAL;
576
577 if (tz->temperature >= tz->trips.critical.temperature) {
578 printk(KERN_WARNING PREFIX "Critical trip point\n");
579 tz->trips.critical.flags.enabled = 1;
580 } else if (tz->trips.critical.flags.enabled)
581 tz->trips.critical.flags.enabled = 0;
582
583 acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
584 tz->trips.critical.flags.enabled);
585 acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
586 dev_name(&tz->device->dev),
587 ACPI_THERMAL_NOTIFY_CRITICAL,
588 tz->trips.critical.flags.enabled);
589
590 /* take no action if nocrt is set */
591 if(!nocrt) {
592 printk(KERN_EMERG
593 "Critical temperature reached (%ld C), shutting down.\n",
594 KELVIN_TO_CELSIUS(tz->temperature));
595 orderly_poweroff(true);
596 }
597
598 return 0;
599}
600
601static int acpi_thermal_hot(struct acpi_thermal *tz)
602{
603 if (!tz || !tz->trips.hot.flags.valid)
604 return -EINVAL;
605
606 if (tz->temperature >= tz->trips.hot.temperature) {
607 printk(KERN_WARNING PREFIX "Hot trip point\n");
608 tz->trips.hot.flags.enabled = 1;
609 } else if (tz->trips.hot.flags.enabled)
610 tz->trips.hot.flags.enabled = 0;
611
612 acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT,
613 tz->trips.hot.flags.enabled);
614 acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
615 dev_name(&tz->device->dev),
616 ACPI_THERMAL_NOTIFY_HOT,
617 tz->trips.hot.flags.enabled);
618
619 /* TBD: Call user-mode "sleep(S4)" function if nocrt is cleared */
620
621 return 0;
622}
623
624static void acpi_thermal_passive(struct acpi_thermal *tz)
625{
626 int result = 1;
627 struct acpi_thermal_passive *passive = NULL;
628 int trend = 0;
629 int i = 0;
630
631
632 if (!tz || !tz->trips.passive.flags.valid)
633 return;
634
635 passive = &(tz->trips.passive);
636
637 /*
638 * Above Trip?
639 * -----------
640 * Calculate the thermal trend (using the passive cooling equation)
641 * and modify the performance limit for all passive cooling devices
642 * accordingly. Note that we assume symmetry.
643 */
644 if (tz->temperature >= passive->temperature) {
645 trend =
646 (passive->tc1 * (tz->temperature - tz->last_temperature)) +
647 (passive->tc2 * (tz->temperature - passive->temperature));
648 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
649 "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n",
650 trend, passive->tc1, tz->temperature,
651 tz->last_temperature, passive->tc2,
652 tz->temperature, passive->temperature));
653 passive->flags.enabled = 1;
654 /* Heating up? */
655 if (trend > 0)
656 for (i = 0; i < passive->devices.count; i++)
657 acpi_processor_set_thermal_limit(passive->
658 devices.
659 handles[i],
660 ACPI_PROCESSOR_LIMIT_INCREMENT);
661 /* Cooling off? */
662 else if (trend < 0) {
663 for (i = 0; i < passive->devices.count; i++)
664 /*
665 * assume that we are on highest
666 * freq/lowest thrott and can leave
667 * passive mode, even in error case
668 */
669 if (!acpi_processor_set_thermal_limit
670 (passive->devices.handles[i],
671 ACPI_PROCESSOR_LIMIT_DECREMENT))
672 result = 0;
673 /*
674 * Leave cooling mode, even if the temp might
675 * higher than trip point This is because some
676 * machines might have long thermal polling
677 * frequencies (tsp) defined. We will fall back
678 * into passive mode in next cycle (probably quicker)
679 */
680 if (result) {
681 passive->flags.enabled = 0;
682 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
683 "Disabling passive cooling, still above threshold,"
684 " but we are cooling down\n"));
685 }
686 }
687 return;
688 }
689
690 /*
691 * Below Trip?
692 * -----------
693 * Implement passive cooling hysteresis to slowly increase performance
694 * and avoid thrashing around the passive trip point. Note that we
695 * assume symmetry.
696 */
697 if (!passive->flags.enabled)
698 return;
699 for (i = 0; i < passive->devices.count; i++)
700 if (!acpi_processor_set_thermal_limit
701 (passive->devices.handles[i],
702 ACPI_PROCESSOR_LIMIT_DECREMENT))
703 result = 0;
704 if (result) {
705 passive->flags.enabled = 0;
706 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
707 "Disabling passive cooling (zone is cool)\n"));
708 }
709}
710
711static void acpi_thermal_active(struct acpi_thermal *tz)
712{
713 int result = 0;
714 struct acpi_thermal_active *active = NULL;
715 int i = 0;
716 int j = 0;
717 unsigned long maxtemp = 0;
718
719
720 if (!tz)
721 return;
722
723 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
724 active = &(tz->trips.active[i]);
725 if (!active || !active->flags.valid)
726 break;
727 if (tz->temperature >= active->temperature) {
728 /*
729 * Above Threshold?
730 * ----------------
731 * If not already enabled, turn ON all cooling devices
732 * associated with this active threshold.
733 */
734 if (active->temperature > maxtemp)
735 tz->state.active_index = i;
736 maxtemp = active->temperature;
737 if (active->flags.enabled)
738 continue;
739 for (j = 0; j < active->devices.count; j++) {
740 result =
741 acpi_bus_set_power(active->devices.
742 handles[j],
743 ACPI_STATE_D0);
744 if (result) {
745 printk(KERN_WARNING PREFIX
746 "Unable to turn cooling device [%p] 'on'\n",
747 active->devices.
748 handles[j]);
749 continue;
750 }
751 active->flags.enabled = 1;
752 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
753 "Cooling device [%p] now 'on'\n",
754 active->devices.handles[j]));
755 }
756 continue;
757 }
758 if (!active->flags.enabled)
759 continue;
760 /*
761 * Below Threshold?
762 * ----------------
763 * Turn OFF all cooling devices associated with this
764 * threshold.
765 */
766 for (j = 0; j < active->devices.count; j++) {
767 result = acpi_bus_set_power(active->devices.handles[j],
768 ACPI_STATE_D3);
769 if (result) {
770 printk(KERN_WARNING PREFIX
771 "Unable to turn cooling device [%p] 'off'\n",
772 active->devices.handles[j]);
773 continue;
774 }
775 active->flags.enabled = 0;
776 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
777 "Cooling device [%p] now 'off'\n",
778 active->devices.handles[j]));
779 }
780 }
781}
782
783static void acpi_thermal_check(void *context);
784
785static void acpi_thermal_run(unsigned long data)
786{
787 struct acpi_thermal *tz = (struct acpi_thermal *)data;
788 if (!tz->zombie)
789 acpi_os_execute(OSL_GPE_HANDLER, acpi_thermal_check, (void *)data);
790}
791
792static void acpi_thermal_active_off(void *data)
793{
794 int result = 0;
795 struct acpi_thermal *tz = data;
796 int i = 0;
797 int j = 0;
798 struct acpi_thermal_active *active = NULL;
799
800 if (!tz) {
801 printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
802 return;
803 }
804
805 result = acpi_thermal_get_temperature(tz);
806 if (result)
807 return;
808
809 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
810 active = &(tz->trips.active[i]);
811 if (!active || !active->flags.valid)
812 break;
813 if (tz->temperature >= active->temperature) {
814 /*
815 * If the thermal temperature is greater than the
816 * active threshod, unnecessary to turn off the
817 * the active cooling device.
818 */
819 continue;
820 }
821 /*
822 * Below Threshold?
823 * ----------------
824 * Turn OFF all cooling devices associated with this
825 * threshold.
826 */
827 for (j = 0; j < active->devices.count; j++)
828 result = acpi_bus_set_power(active->devices.handles[j],
829 ACPI_STATE_D3);
830 }
831}
832
833static void acpi_thermal_check(void *data) 575static void acpi_thermal_check(void *data)
834{ 576{
835 int result = 0;
836 struct acpi_thermal *tz = data; 577 struct acpi_thermal *tz = data;
837 unsigned long sleep_time = 0;
838 unsigned long timeout_jiffies = 0;
839 int i = 0;
840 struct acpi_thermal_state state;
841
842
843 if (!tz) {
844 printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
845 return;
846 }
847
848 /* Check if someone else is already running */
849 if (!mutex_trylock(&tz->lock))
850 return;
851
852 state = tz->state;
853
854 result = acpi_thermal_get_temperature(tz);
855 if (result)
856 goto unlock;
857
858 if (!tz->tz_enabled)
859 goto unlock;
860
861 memset(&tz->state, 0, sizeof(tz->state));
862
863 /*
864 * Check Trip Points
865 * -----------------
866 * Compare the current temperature to the trip point values to see
867 * if we've entered one of the thermal policy states. Note that
868 * this function determines when a state is entered, but the
869 * individual policy decides when it is exited (e.g. hysteresis).
870 */
871 if (tz->trips.critical.flags.valid)
872 state.critical |=
873 (tz->temperature >= tz->trips.critical.temperature);
874 if (tz->trips.hot.flags.valid)
875 state.hot |= (tz->temperature >= tz->trips.hot.temperature);
876 if (tz->trips.passive.flags.valid)
877 state.passive |=
878 (tz->temperature >= tz->trips.passive.temperature);
879 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
880 if (tz->trips.active[i].flags.valid)
881 state.active |=
882 (tz->temperature >=
883 tz->trips.active[i].temperature);
884
885 /*
886 * Invoke Policy
887 * -------------
888 * Separated from the above check to allow individual policy to
889 * determine when to exit a given state.
890 */
891 if (state.critical)
892 acpi_thermal_critical(tz);
893 if (state.hot)
894 acpi_thermal_hot(tz);
895 if (state.passive)
896 acpi_thermal_passive(tz);
897 if (state.active)
898 acpi_thermal_active(tz);
899
900 /*
901 * Calculate State
902 * ---------------
903 * Again, separated from the above two to allow independent policy
904 * decisions.
905 */
906 tz->state.critical = tz->trips.critical.flags.enabled;
907 tz->state.hot = tz->trips.hot.flags.enabled;
908 tz->state.passive = tz->trips.passive.flags.enabled;
909 tz->state.active = 0;
910 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
911 tz->state.active |= tz->trips.active[i].flags.enabled;
912
913 /*
914 * Calculate Sleep Time
915 * --------------------
916 * If we're in the passive state, use _TSP's value. Otherwise
917 * use the default polling frequency (e.g. _TZP). If no polling
918 * frequency is specified then we'll wait forever (at least until
919 * a thermal event occurs). Note that _TSP and _TZD values are
920 * given in 1/10th seconds (we must covert to milliseconds).
921 */
922 if (tz->state.passive) {
923 sleep_time = tz->trips.passive.tsp * 100;
924 timeout_jiffies = jiffies + (HZ * sleep_time) / 1000;
925 } else if (tz->polling_frequency > 0) {
926 sleep_time = tz->polling_frequency * 100;
927 timeout_jiffies = round_jiffies(jiffies + (HZ * sleep_time) / 1000);
928 }
929
930 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
931 tz->name, tz->temperature, sleep_time));
932 578
933 /* 579 thermal_zone_device_update(tz->thermal_zone);
934 * Schedule Next Poll
935 * ------------------
936 */
937 if (!sleep_time) {
938 if (timer_pending(&(tz->timer)))
939 del_timer(&(tz->timer));
940 } else {
941 if (timer_pending(&(tz->timer)))
942 mod_timer(&(tz->timer), timeout_jiffies);
943 else {
944 tz->timer.data = (unsigned long)tz;
945 tz->timer.function = acpi_thermal_run;
946 tz->timer.expires = timeout_jiffies;
947 add_timer(&(tz->timer));
948 }
949 }
950 unlock:
951 mutex_unlock(&tz->lock);
952} 580}
953 581
954/* sys I/F for generic thermal sysfs support */ 582/* sys I/F for generic thermal sysfs support */
@@ -1122,6 +750,29 @@ static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
1122 return -EINVAL; 750 return -EINVAL;
1123} 751}
1124 752
753static int thermal_notify(struct thermal_zone_device *thermal, int trip,
754 enum thermal_trip_type trip_type)
755{
756 u8 type = 0;
757 struct acpi_thermal *tz = thermal->devdata;
758
759 if (trip_type == THERMAL_TRIP_CRITICAL)
760 type = ACPI_THERMAL_NOTIFY_CRITICAL;
761 else if (trip_type == THERMAL_TRIP_HOT)
762 type = ACPI_THERMAL_NOTIFY_HOT;
763 else
764 return 0;
765
766 acpi_bus_generate_proc_event(tz->device, type, 1);
767 acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
768 tz->device->dev.bus_id, type, 1);
769
770 if (trip_type == THERMAL_TRIP_CRITICAL && nocrt)
771 return 1;
772
773 return 0;
774}
775
1125typedef int (*cb)(struct thermal_zone_device *, int, 776typedef int (*cb)(struct thermal_zone_device *, int,
1126 struct thermal_cooling_device *); 777 struct thermal_cooling_device *);
1127static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, 778static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
@@ -1214,6 +865,7 @@ static struct thermal_zone_device_ops acpi_thermal_zone_ops = {
1214 .get_trip_type = thermal_get_trip_type, 865 .get_trip_type = thermal_get_trip_type,
1215 .get_trip_temp = thermal_get_trip_temp, 866 .get_trip_temp = thermal_get_trip_temp,
1216 .get_crit_temp = thermal_get_crit_temp, 867 .get_crit_temp = thermal_get_crit_temp,
868 .notify = thermal_notify,
1217}; 869};
1218 870
1219static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) 871static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
@@ -1234,8 +886,21 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
1234 886
1235 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && 887 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
1236 tz->trips.active[i].flags.valid; i++, trips++); 888 tz->trips.active[i].flags.valid; i++, trips++);
1237 tz->thermal_zone = thermal_zone_device_register("acpitz", 889
1238 trips, tz, &acpi_thermal_zone_ops); 890 if (tz->trips.passive.flags.valid)
891 tz->thermal_zone =
892 thermal_zone_device_register("acpitz", trips, tz,
893 &acpi_thermal_zone_ops,
894 tz->trips.passive.tc1,
895 tz->trips.passive.tc2,
896 tz->trips.passive.tsp*100,
897 tz->polling_frequency*100);
898 else
899 tz->thermal_zone =
900 thermal_zone_device_register("acpitz", trips, tz,
901 &acpi_thermal_zone_ops,
902 0, 0, 0,
903 tz->polling_frequency);
1239 if (IS_ERR(tz->thermal_zone)) 904 if (IS_ERR(tz->thermal_zone))
1240 return -ENODEV; 905 return -ENODEV;
1241 906
@@ -1467,13 +1132,13 @@ static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset)
1467 if (!tz) 1132 if (!tz)
1468 goto end; 1133 goto end;
1469 1134
1470 if (!tz->polling_frequency) { 1135 if (!tz->thermal_zone->polling_delay) {
1471 seq_puts(seq, "<polling disabled>\n"); 1136 seq_puts(seq, "<polling disabled>\n");
1472 goto end; 1137 goto end;
1473 } 1138 }
1474 1139
1475 seq_printf(seq, "polling frequency: %lu seconds\n", 1140 seq_printf(seq, "polling frequency: %d seconds\n",
1476 (tz->polling_frequency / 10)); 1141 (tz->thermal_zone->polling_delay / 1000));
1477 1142
1478 end: 1143 end:
1479 return 0; 1144 return 0;
@@ -1703,12 +1368,6 @@ static int acpi_thermal_add(struct acpi_device *device)
1703 if (result) 1368 if (result)
1704 goto unregister_thermal_zone; 1369 goto unregister_thermal_zone;
1705 1370
1706 init_timer(&tz->timer);
1707
1708 acpi_thermal_active_off(tz);
1709
1710 acpi_thermal_check(tz);
1711
1712 status = acpi_install_notify_handler(device->handle, 1371 status = acpi_install_notify_handler(device->handle,
1713 ACPI_DEVICE_NOTIFY, 1372 ACPI_DEVICE_NOTIFY,
1714 acpi_thermal_notify, tz); 1373 acpi_thermal_notify, tz);
@@ -1737,36 +1396,15 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
1737 acpi_status status = AE_OK; 1396 acpi_status status = AE_OK;
1738 struct acpi_thermal *tz = NULL; 1397 struct acpi_thermal *tz = NULL;
1739 1398
1740
1741 if (!device || !acpi_driver_data(device)) 1399 if (!device || !acpi_driver_data(device))
1742 return -EINVAL; 1400 return -EINVAL;
1743 1401
1744 tz = acpi_driver_data(device); 1402 tz = acpi_driver_data(device);
1745 1403
1746 /* avoid timer adding new defer task */
1747 tz->zombie = 1;
1748 /* wait for running timer (on other CPUs) finish */
1749 del_timer_sync(&(tz->timer));
1750 /* synchronize deferred task */
1751 acpi_os_wait_events_complete(NULL);
1752 /* deferred task may reinsert timer */
1753 del_timer_sync(&(tz->timer));
1754
1755 status = acpi_remove_notify_handler(device->handle, 1404 status = acpi_remove_notify_handler(device->handle,
1756 ACPI_DEVICE_NOTIFY, 1405 ACPI_DEVICE_NOTIFY,
1757 acpi_thermal_notify); 1406 acpi_thermal_notify);
1758 1407
1759 /* Terminate policy */
1760 if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) {
1761 tz->trips.passive.flags.enabled = 0;
1762 acpi_thermal_passive(tz);
1763 }
1764 if (tz->trips.active[0].flags.valid
1765 && tz->trips.active[0].flags.enabled) {
1766 tz->trips.active[0].flags.enabled = 0;
1767 acpi_thermal_active(tz);
1768 }
1769
1770 acpi_thermal_remove_fs(device); 1408 acpi_thermal_remove_fs(device);
1771 acpi_thermal_unregister_thermal_zone(tz); 1409 acpi_thermal_unregister_thermal_zone(tz);
1772 mutex_destroy(&tz->lock); 1410 mutex_destroy(&tz->lock);