aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMatthew Garrett <mjg59@srcf.ucam.org>2008-12-03 12:55:32 -0500
committerLen Brown <len.brown@intel.com>2009-02-20 18:41:56 -0500
commitb1569e99c795bf83b4ddf41c4f1c42761ab7f75e (patch)
treead45358dd111e0c4ce71d58565068c47c0171c3d /drivers
parent6503e5df08008b9a47022b5e9ebba658c8fa69af (diff)
ACPI: move thermal trip handling to generic thermal layer
The ACPI code currently carries its own thermal trip handling, meaning that any other thermal implementation will need to reimplement it. Move the code to the generic thermal layer. Signed-off-by: Matthew Garrett <mjg@redhat.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/thermal.c458
-rw-r--r--drivers/thermal/thermal_sys.c188
2 files changed, 234 insertions, 412 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);
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index bd139adc6d32..6378741882f3 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -30,6 +30,7 @@
30#include <linux/idr.h> 30#include <linux/idr.h>
31#include <linux/thermal.h> 31#include <linux/thermal.h>
32#include <linux/spinlock.h> 32#include <linux/spinlock.h>
33#include <linux/reboot.h>
33 34
34MODULE_AUTHOR("Zhang Rui"); 35MODULE_AUTHOR("Zhang Rui");
35MODULE_DESCRIPTION("Generic thermal management sysfs support"); 36MODULE_DESCRIPTION("Generic thermal management sysfs support");
@@ -517,6 +518,97 @@ thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
517} 518}
518#endif 519#endif
519 520
521static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
522 int delay)
523{
524 cancel_delayed_work(&(tz->poll_queue));
525
526 if (!delay)
527 return;
528
529 if (delay > 1000)
530 schedule_delayed_work(&(tz->poll_queue),
531 round_jiffies(msecs_to_jiffies(delay)));
532 else
533 schedule_delayed_work(&(tz->poll_queue),
534 msecs_to_jiffies(delay));
535}
536
537static void thermal_zone_device_passive(struct thermal_zone_device *tz,
538 int temp, int trip_temp, int trip)
539{
540 int trend = 0;
541 struct thermal_cooling_device_instance *instance;
542 struct thermal_cooling_device *cdev;
543 long state, max_state;
544
545 /*
546 * Above Trip?
547 * -----------
548 * Calculate the thermal trend (using the passive cooling equation)
549 * and modify the performance limit for all passive cooling devices
550 * accordingly. Note that we assume symmetry.
551 */
552 if (temp >= trip_temp) {
553 tz->passive = true;
554
555 trend = (tz->tc1 * (temp - tz->last_temperature)) +
556 (tz->tc2 * (temp - trip_temp));
557
558 /* Heating up? */
559 if (trend > 0) {
560 list_for_each_entry(instance, &tz->cooling_devices,
561 node) {
562 if (instance->trip != trip)
563 continue;
564 cdev = instance->cdev;
565 cdev->ops->get_cur_state(cdev, &state);
566 cdev->ops->get_max_state(cdev, &max_state);
567 if (state++ < max_state)
568 cdev->ops->set_cur_state(cdev, state);
569 }
570 } else if (trend < 0) { /* Cooling off? */
571 list_for_each_entry(instance, &tz->cooling_devices,
572 node) {
573 if (instance->trip != trip)
574 continue;
575 cdev = instance->cdev;
576 cdev->ops->get_cur_state(cdev, &state);
577 cdev->ops->get_max_state(cdev, &max_state);
578 if (state > 0)
579 cdev->ops->set_cur_state(cdev, --state);
580 }
581 }
582 return;
583 }
584
585 /*
586 * Below Trip?
587 * -----------
588 * Implement passive cooling hysteresis to slowly increase performance
589 * and avoid thrashing around the passive trip point. Note that we
590 * assume symmetry.
591 */
592 list_for_each_entry(instance, &tz->cooling_devices, node) {
593 if (instance->trip != trip)
594 continue;
595 cdev = instance->cdev;
596 cdev->ops->get_cur_state(cdev, &state);
597 cdev->ops->get_max_state(cdev, &max_state);
598 if (state > 0)
599 cdev->ops->set_cur_state(cdev, --state);
600 if (state == 0)
601 tz->passive = false;
602 }
603}
604
605static void thermal_zone_device_check(struct work_struct *work)
606{
607 struct thermal_zone_device *tz = container_of(work, struct
608 thermal_zone_device,
609 poll_queue.work);
610 thermal_zone_device_update(tz);
611}
520 612
521/** 613/**
522 * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone 614 * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone
@@ -787,20 +879,101 @@ void thermal_cooling_device_unregister(struct
787EXPORT_SYMBOL(thermal_cooling_device_unregister); 879EXPORT_SYMBOL(thermal_cooling_device_unregister);
788 880
789/** 881/**
882 * thermal_zone_device_update - force an update of a thermal zone's state
883 * @ttz: the thermal zone to update
884 */
885
886void thermal_zone_device_update(struct thermal_zone_device *tz)
887{
888 int count, ret = 0;
889 long temp, trip_temp;
890 enum thermal_trip_type trip_type;
891 struct thermal_cooling_device_instance *instance;
892 struct thermal_cooling_device *cdev;
893
894 mutex_lock(&tz->lock);
895
896 tz->ops->get_temp(tz, &temp);
897
898 for (count = 0; count < tz->trips; count++) {
899 tz->ops->get_trip_type(tz, count, &trip_type);
900 tz->ops->get_trip_temp(tz, count, &trip_temp);
901
902 switch (trip_type) {
903 case THERMAL_TRIP_CRITICAL:
904 if (temp > trip_temp) {
905 if (tz->ops->notify)
906 ret = tz->ops->notify(tz, count,
907 trip_type);
908 if (!ret) {
909 printk(KERN_EMERG
910 "Critical temperature reached (%ld C), shutting down.\n",
911 temp/1000);
912 orderly_poweroff(true);
913 }
914 }
915 break;
916 case THERMAL_TRIP_HOT:
917 if (temp > trip_temp)
918 if (tz->ops->notify)
919 tz->ops->notify(tz, count, trip_type);
920 break;
921 case THERMAL_TRIP_ACTIVE:
922 list_for_each_entry(instance, &tz->cooling_devices,
923 node) {
924 if (instance->trip != count)
925 continue;
926
927 cdev = instance->cdev;
928
929 if (temp > trip_temp)
930 cdev->ops->set_cur_state(cdev, 1);
931 else
932 cdev->ops->set_cur_state(cdev, 0);
933 }
934 break;
935 case THERMAL_TRIP_PASSIVE:
936 if (temp > trip_temp || tz->passive)
937 thermal_zone_device_passive(tz, temp,
938 trip_temp, count);
939 break;
940 }
941 }
942 tz->last_temperature = temp;
943 if (tz->passive)
944 thermal_zone_device_set_polling(tz, tz->passive_delay);
945 else if (tz->polling_delay)
946 thermal_zone_device_set_polling(tz, tz->polling_delay);
947 mutex_unlock(&tz->lock);
948}
949EXPORT_SYMBOL(thermal_zone_device_update);
950
951/**
790 * thermal_zone_device_register - register a new thermal zone device 952 * thermal_zone_device_register - register a new thermal zone device
791 * @type: the thermal zone device type 953 * @type: the thermal zone device type
792 * @trips: the number of trip points the thermal zone support 954 * @trips: the number of trip points the thermal zone support
793 * @devdata: private device data 955 * @devdata: private device data
794 * @ops: standard thermal zone device callbacks 956 * @ops: standard thermal zone device callbacks
957 * @tc1: thermal coefficient 1 for passive calculations
958 * @tc2: thermal coefficient 2 for passive calculations
959 * @passive_delay: number of milliseconds to wait between polls when
960 * performing passive cooling
961 * @polling_delay: number of milliseconds to wait between polls when checking
962 * whether trip points have been crossed (0 for interrupt
963 * driven systems)
795 * 964 *
796 * thermal_zone_device_unregister() must be called when the device is no 965 * thermal_zone_device_unregister() must be called when the device is no
797 * longer needed. 966 * longer needed. The passive cooling formula uses tc1 and tc2 as described in
967 * section 11.1.5.1 of the ACPI specification 3.0.
798 */ 968 */
799struct thermal_zone_device *thermal_zone_device_register(char *type, 969struct thermal_zone_device *thermal_zone_device_register(char *type,
800 int trips, 970 int trips,
801 void *devdata, struct 971 void *devdata, struct
802 thermal_zone_device_ops 972 thermal_zone_device_ops
803 *ops) 973 *ops, int tc1, int
974 tc2,
975 int passive_delay,
976 int polling_delay)
804{ 977{
805 struct thermal_zone_device *tz; 978 struct thermal_zone_device *tz;
806 struct thermal_cooling_device *pos; 979 struct thermal_cooling_device *pos;
@@ -834,6 +1007,11 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
834 tz->device.class = &thermal_class; 1007 tz->device.class = &thermal_class;
835 tz->devdata = devdata; 1008 tz->devdata = devdata;
836 tz->trips = trips; 1009 tz->trips = trips;
1010 tz->tc1 = tc1;
1011 tz->tc2 = tc2;
1012 tz->passive_delay = passive_delay;
1013 tz->polling_delay = polling_delay;
1014
837 dev_set_name(&tz->device, "thermal_zone%d", tz->id); 1015 dev_set_name(&tz->device, "thermal_zone%d", tz->id);
838 result = device_register(&tz->device); 1016 result = device_register(&tz->device);
839 if (result) { 1017 if (result) {
@@ -879,6 +1057,10 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
879 } 1057 }
880 mutex_unlock(&thermal_list_lock); 1058 mutex_unlock(&thermal_list_lock);
881 1059
1060 INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
1061
1062 thermal_zone_device_update(tz);
1063
882 if (!result) 1064 if (!result)
883 return tz; 1065 return tz;
884 1066
@@ -918,6 +1100,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
918 tz->ops->unbind(tz, cdev); 1100 tz->ops->unbind(tz, cdev);
919 mutex_unlock(&thermal_list_lock); 1101 mutex_unlock(&thermal_list_lock);
920 1102
1103 thermal_zone_device_set_polling(tz, 0);
1104
921 if (tz->type[0]) 1105 if (tz->type[0])
922 device_remove_file(&tz->device, &dev_attr_type); 1106 device_remove_file(&tz->device, &dev_attr_type);
923 device_remove_file(&tz->device, &dev_attr_temp); 1107 device_remove_file(&tz->device, &dev_attr_temp);