aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2009-04-05 01:39:12 -0400
committerLen Brown <len.brown@intel.com>2009-04-05 01:39:12 -0400
commit4f3bff70a64b105921dac8630bc4381567b21ebd (patch)
tree2601d581e21c4ca9392bbf85dfb981a2181ecba6
parent2ddb9f17ba026122b53b34fb4182ece91e24cf92 (diff)
parent03a971a2899886006f19f3495973bbd646d8bdae (diff)
Merge branch 'thermal' into release
-rw-r--r--drivers/acpi/fan.c20
-rw-r--r--drivers/acpi/processor_thermal.c20
-rw-r--r--drivers/acpi/thermal.c539
-rw-r--r--drivers/acpi/video.c22
-rw-r--r--drivers/platform/x86/intel_menlow.c29
-rw-r--r--drivers/thermal/thermal_sys.c356
-rw-r--r--include/linux/thermal.h48
7 files changed, 525 insertions, 509 deletions
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index eaaee1660bdf..ae41cf3cf4e5 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -68,31 +68,35 @@ static struct acpi_driver acpi_fan_driver = {
68}; 68};
69 69
70/* thermal cooling device callbacks */ 70/* thermal cooling device callbacks */
71static int fan_get_max_state(struct thermal_cooling_device *cdev, char *buf) 71static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long
72 *state)
72{ 73{
73 /* ACPI fan device only support two states: ON/OFF */ 74 /* ACPI fan device only support two states: ON/OFF */
74 return sprintf(buf, "1\n"); 75 *state = 1;
76 return 0;
75} 77}
76 78
77static int fan_get_cur_state(struct thermal_cooling_device *cdev, char *buf) 79static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
80 *state)
78{ 81{
79 struct acpi_device *device = cdev->devdata; 82 struct acpi_device *device = cdev->devdata;
80 int state;
81 int result; 83 int result;
84 int acpi_state;
82 85
83 if (!device) 86 if (!device)
84 return -EINVAL; 87 return -EINVAL;
85 88
86 result = acpi_bus_get_power(device->handle, &state); 89 result = acpi_bus_get_power(device->handle, &acpi_state);
87 if (result) 90 if (result)
88 return result; 91 return result;
89 92
90 return sprintf(buf, "%s\n", state == ACPI_STATE_D3 ? "0" : 93 *state = (acpi_state == ACPI_STATE_D3 ? 0 :
91 (state == ACPI_STATE_D0 ? "1" : "unknown")); 94 (acpi_state == ACPI_STATE_D0 ? 1 : -1));
95 return 0;
92} 96}
93 97
94static int 98static int
95fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state) 99fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
96{ 100{
97 struct acpi_device *device = cdev->devdata; 101 struct acpi_device *device = cdev->devdata;
98 int result; 102 int result;
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index b1eb376fae45..0e47e299a9ac 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -373,7 +373,8 @@ static int acpi_processor_max_state(struct acpi_processor *pr)
373 return max_state; 373 return max_state;
374} 374}
375static int 375static int
376processor_get_max_state(struct thermal_cooling_device *cdev, char *buf) 376processor_get_max_state(struct thermal_cooling_device *cdev,
377 unsigned long *state)
377{ 378{
378 struct acpi_device *device = cdev->devdata; 379 struct acpi_device *device = cdev->devdata;
379 struct acpi_processor *pr = acpi_driver_data(device); 380 struct acpi_processor *pr = acpi_driver_data(device);
@@ -381,28 +382,29 @@ processor_get_max_state(struct thermal_cooling_device *cdev, char *buf)
381 if (!device || !pr) 382 if (!device || !pr)
382 return -EINVAL; 383 return -EINVAL;
383 384
384 return sprintf(buf, "%d\n", acpi_processor_max_state(pr)); 385 *state = acpi_processor_max_state(pr);
386 return 0;
385} 387}
386 388
387static int 389static int
388processor_get_cur_state(struct thermal_cooling_device *cdev, char *buf) 390processor_get_cur_state(struct thermal_cooling_device *cdev,
391 unsigned long *cur_state)
389{ 392{
390 struct acpi_device *device = cdev->devdata; 393 struct acpi_device *device = cdev->devdata;
391 struct acpi_processor *pr = acpi_driver_data(device); 394 struct acpi_processor *pr = acpi_driver_data(device);
392 int cur_state;
393 395
394 if (!device || !pr) 396 if (!device || !pr)
395 return -EINVAL; 397 return -EINVAL;
396 398
397 cur_state = cpufreq_get_cur_state(pr->id); 399 *cur_state = cpufreq_get_cur_state(pr->id);
398 if (pr->flags.throttling) 400 if (pr->flags.throttling)
399 cur_state += pr->throttling.state; 401 *cur_state += pr->throttling.state;
400 402 return 0;
401 return sprintf(buf, "%d\n", cur_state);
402} 403}
403 404
404static int 405static int
405processor_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state) 406processor_set_cur_state(struct thermal_cooling_device *cdev,
407 unsigned long state)
406{ 408{
407 struct acpi_device *device = cdev->devdata; 409 struct acpi_device *device = cdev->devdata;
408 struct acpi_processor *pr = acpi_driver_data(device); 410 struct acpi_processor *pr = acpi_driver_data(device);
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 99e6f1f8ea45..6b959976b7a4 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -37,11 +37,11 @@
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>
44#include <linux/reboot.h> 43#include <linux/reboot.h>
44#include <linux/device.h>
45#include <asm/uaccess.h> 45#include <asm/uaccess.h>
46#include <linux/thermal.h> 46#include <linux/thermal.h>
47#include <acpi/acpi_bus.h> 47#include <acpi/acpi_bus.h>
@@ -190,7 +190,6 @@ struct acpi_thermal {
190 struct acpi_thermal_state state; 190 struct acpi_thermal_state state;
191 struct acpi_thermal_trips trips; 191 struct acpi_thermal_trips trips;
192 struct acpi_handle_list devices; 192 struct acpi_handle_list devices;
193 struct timer_list timer;
194 struct thermal_zone_device *thermal_zone; 193 struct thermal_zone_device *thermal_zone;
195 int tz_enabled; 194 int tz_enabled;
196 struct mutex lock; 195 struct mutex lock;
@@ -290,6 +289,11 @@ static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds)
290 289
291 tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */ 290 tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */
292 291
292 tz->thermal_zone->polling_delay = seconds * 1000;
293
294 if (tz->tz_enabled)
295 thermal_zone_device_update(tz->thermal_zone);
296
293 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 297 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
294 "Polling frequency set to %lu seconds\n", 298 "Polling frequency set to %lu seconds\n",
295 tz->polling_frequency/10)); 299 tz->polling_frequency/10));
@@ -569,392 +573,18 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
569 return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); 573 return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
570} 574}
571 575
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) 576static void acpi_thermal_check(void *data)
834{ 577{
835 int result = 0;
836 struct acpi_thermal *tz = data; 578 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 579
930 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n", 580 thermal_zone_device_update(tz->thermal_zone);
931 tz->name, tz->temperature, sleep_time));
932
933 /*
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} 581}
953 582
954/* sys I/F for generic thermal sysfs support */ 583/* sys I/F for generic thermal sysfs support */
955#define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200) 584#define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200)
956 585
957static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf) 586static int thermal_get_temp(struct thermal_zone_device *thermal,
587 unsigned long *temp)
958{ 588{
959 struct acpi_thermal *tz = thermal->devdata; 589 struct acpi_thermal *tz = thermal->devdata;
960 int result; 590 int result;
@@ -966,25 +596,28 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
966 if (result) 596 if (result)
967 return result; 597 return result;
968 598
969 return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature)); 599 *temp = KELVIN_TO_MILLICELSIUS(tz->temperature);
600 return 0;
970} 601}
971 602
972static const char enabled[] = "kernel"; 603static const char enabled[] = "kernel";
973static const char disabled[] = "user"; 604static const char disabled[] = "user";
974static int thermal_get_mode(struct thermal_zone_device *thermal, 605static int thermal_get_mode(struct thermal_zone_device *thermal,
975 char *buf) 606 enum thermal_device_mode *mode)
976{ 607{
977 struct acpi_thermal *tz = thermal->devdata; 608 struct acpi_thermal *tz = thermal->devdata;
978 609
979 if (!tz) 610 if (!tz)
980 return -EINVAL; 611 return -EINVAL;
981 612
982 return sprintf(buf, "%s\n", tz->tz_enabled ? 613 *mode = tz->tz_enabled ? THERMAL_DEVICE_ENABLED :
983 enabled : disabled); 614 THERMAL_DEVICE_DISABLED;
615
616 return 0;
984} 617}
985 618
986static int thermal_set_mode(struct thermal_zone_device *thermal, 619static int thermal_set_mode(struct thermal_zone_device *thermal,
987 const char *buf) 620 enum thermal_device_mode mode)
988{ 621{
989 struct acpi_thermal *tz = thermal->devdata; 622 struct acpi_thermal *tz = thermal->devdata;
990 int enable; 623 int enable;
@@ -995,9 +628,9 @@ static int thermal_set_mode(struct thermal_zone_device *thermal,
995 /* 628 /*
996 * enable/disable thermal management from ACPI thermal driver 629 * enable/disable thermal management from ACPI thermal driver
997 */ 630 */
998 if (!strncmp(buf, enabled, sizeof enabled - 1)) 631 if (mode == THERMAL_DEVICE_ENABLED)
999 enable = 1; 632 enable = 1;
1000 else if (!strncmp(buf, disabled, sizeof disabled - 1)) 633 else if (mode == THERMAL_DEVICE_DISABLED)
1001 enable = 0; 634 enable = 0;
1002 else 635 else
1003 return -EINVAL; 636 return -EINVAL;
@@ -1013,7 +646,7 @@ static int thermal_set_mode(struct thermal_zone_device *thermal,
1013} 646}
1014 647
1015static int thermal_get_trip_type(struct thermal_zone_device *thermal, 648static int thermal_get_trip_type(struct thermal_zone_device *thermal,
1016 int trip, char *buf) 649 int trip, enum thermal_trip_type *type)
1017{ 650{
1018 struct acpi_thermal *tz = thermal->devdata; 651 struct acpi_thermal *tz = thermal->devdata;
1019 int i; 652 int i;
@@ -1022,27 +655,35 @@ static int thermal_get_trip_type(struct thermal_zone_device *thermal,
1022 return -EINVAL; 655 return -EINVAL;
1023 656
1024 if (tz->trips.critical.flags.valid) { 657 if (tz->trips.critical.flags.valid) {
1025 if (!trip) 658 if (!trip) {
1026 return sprintf(buf, "critical\n"); 659 *type = THERMAL_TRIP_CRITICAL;
660 return 0;
661 }
1027 trip--; 662 trip--;
1028 } 663 }
1029 664
1030 if (tz->trips.hot.flags.valid) { 665 if (tz->trips.hot.flags.valid) {
1031 if (!trip) 666 if (!trip) {
1032 return sprintf(buf, "hot\n"); 667 *type = THERMAL_TRIP_HOT;
668 return 0;
669 }
1033 trip--; 670 trip--;
1034 } 671 }
1035 672
1036 if (tz->trips.passive.flags.valid) { 673 if (tz->trips.passive.flags.valid) {
1037 if (!trip) 674 if (!trip) {
1038 return sprintf(buf, "passive\n"); 675 *type = THERMAL_TRIP_PASSIVE;
676 return 0;
677 }
1039 trip--; 678 trip--;
1040 } 679 }
1041 680
1042 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && 681 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
1043 tz->trips.active[i].flags.valid; i++) { 682 tz->trips.active[i].flags.valid; i++) {
1044 if (!trip) 683 if (!trip) {
1045 return sprintf(buf, "active%d\n", i); 684 *type = THERMAL_TRIP_ACTIVE;
685 return 0;
686 }
1046 trip--; 687 trip--;
1047 } 688 }
1048 689
@@ -1050,7 +691,7 @@ static int thermal_get_trip_type(struct thermal_zone_device *thermal,
1050} 691}
1051 692
1052static int thermal_get_trip_temp(struct thermal_zone_device *thermal, 693static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
1053 int trip, char *buf) 694 int trip, unsigned long *temp)
1054{ 695{
1055 struct acpi_thermal *tz = thermal->devdata; 696 struct acpi_thermal *tz = thermal->devdata;
1056 int i; 697 int i;
@@ -1059,31 +700,39 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
1059 return -EINVAL; 700 return -EINVAL;
1060 701
1061 if (tz->trips.critical.flags.valid) { 702 if (tz->trips.critical.flags.valid) {
1062 if (!trip) 703 if (!trip) {
1063 return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS( 704 *temp = KELVIN_TO_MILLICELSIUS(
1064 tz->trips.critical.temperature)); 705 tz->trips.critical.temperature);
706 return 0;
707 }
1065 trip--; 708 trip--;
1066 } 709 }
1067 710
1068 if (tz->trips.hot.flags.valid) { 711 if (tz->trips.hot.flags.valid) {
1069 if (!trip) 712 if (!trip) {
1070 return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS( 713 *temp = KELVIN_TO_MILLICELSIUS(
1071 tz->trips.hot.temperature)); 714 tz->trips.hot.temperature);
715 return 0;
716 }
1072 trip--; 717 trip--;
1073 } 718 }
1074 719
1075 if (tz->trips.passive.flags.valid) { 720 if (tz->trips.passive.flags.valid) {
1076 if (!trip) 721 if (!trip) {
1077 return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS( 722 *temp = KELVIN_TO_MILLICELSIUS(
1078 tz->trips.passive.temperature)); 723 tz->trips.passive.temperature);
724 return 0;
725 }
1079 trip--; 726 trip--;
1080 } 727 }
1081 728
1082 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && 729 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
1083 tz->trips.active[i].flags.valid; i++) { 730 tz->trips.active[i].flags.valid; i++) {
1084 if (!trip) 731 if (!trip) {
1085 return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS( 732 *temp = KELVIN_TO_MILLICELSIUS(
1086 tz->trips.active[i].temperature)); 733 tz->trips.active[i].temperature);
734 return 0;
735 }
1087 trip--; 736 trip--;
1088 } 737 }
1089 738
@@ -1102,6 +751,29 @@ static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
1102 return -EINVAL; 751 return -EINVAL;
1103} 752}
1104 753
754static int thermal_notify(struct thermal_zone_device *thermal, int trip,
755 enum thermal_trip_type trip_type)
756{
757 u8 type = 0;
758 struct acpi_thermal *tz = thermal->devdata;
759
760 if (trip_type == THERMAL_TRIP_CRITICAL)
761 type = ACPI_THERMAL_NOTIFY_CRITICAL;
762 else if (trip_type == THERMAL_TRIP_HOT)
763 type = ACPI_THERMAL_NOTIFY_HOT;
764 else
765 return 0;
766
767 acpi_bus_generate_proc_event(tz->device, type, 1);
768 acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
769 dev_name(&tz->device->dev), type, 1);
770
771 if (trip_type == THERMAL_TRIP_CRITICAL && nocrt)
772 return 1;
773
774 return 0;
775}
776
1105typedef int (*cb)(struct thermal_zone_device *, int, 777typedef int (*cb)(struct thermal_zone_device *, int,
1106 struct thermal_cooling_device *); 778 struct thermal_cooling_device *);
1107static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, 779static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
@@ -1194,6 +866,7 @@ static struct thermal_zone_device_ops acpi_thermal_zone_ops = {
1194 .get_trip_type = thermal_get_trip_type, 866 .get_trip_type = thermal_get_trip_type,
1195 .get_trip_temp = thermal_get_trip_temp, 867 .get_trip_temp = thermal_get_trip_temp,
1196 .get_crit_temp = thermal_get_crit_temp, 868 .get_crit_temp = thermal_get_crit_temp,
869 .notify = thermal_notify,
1197}; 870};
1198 871
1199static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) 872static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
@@ -1214,8 +887,21 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
1214 887
1215 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && 888 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
1216 tz->trips.active[i].flags.valid; i++, trips++); 889 tz->trips.active[i].flags.valid; i++, trips++);
1217 tz->thermal_zone = thermal_zone_device_register("acpitz", 890
1218 trips, tz, &acpi_thermal_zone_ops); 891 if (tz->trips.passive.flags.valid)
892 tz->thermal_zone =
893 thermal_zone_device_register("acpitz", trips, tz,
894 &acpi_thermal_zone_ops,
895 tz->trips.passive.tc1,
896 tz->trips.passive.tc2,
897 tz->trips.passive.tsp*100,
898 tz->polling_frequency*100);
899 else
900 tz->thermal_zone =
901 thermal_zone_device_register("acpitz", trips, tz,
902 &acpi_thermal_zone_ops,
903 0, 0, 0,
904 tz->polling_frequency);
1219 if (IS_ERR(tz->thermal_zone)) 905 if (IS_ERR(tz->thermal_zone))
1220 return -ENODEV; 906 return -ENODEV;
1221 907
@@ -1447,13 +1133,13 @@ static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset)
1447 if (!tz) 1133 if (!tz)
1448 goto end; 1134 goto end;
1449 1135
1450 if (!tz->polling_frequency) { 1136 if (!tz->thermal_zone->polling_delay) {
1451 seq_puts(seq, "<polling disabled>\n"); 1137 seq_puts(seq, "<polling disabled>\n");
1452 goto end; 1138 goto end;
1453 } 1139 }
1454 1140
1455 seq_printf(seq, "polling frequency: %lu seconds\n", 1141 seq_printf(seq, "polling frequency: %d seconds\n",
1456 (tz->polling_frequency / 10)); 1142 (tz->thermal_zone->polling_delay / 1000));
1457 1143
1458 end: 1144 end:
1459 return 0; 1145 return 0;
@@ -1683,12 +1369,6 @@ static int acpi_thermal_add(struct acpi_device *device)
1683 if (result) 1369 if (result)
1684 goto unregister_thermal_zone; 1370 goto unregister_thermal_zone;
1685 1371
1686 init_timer(&tz->timer);
1687
1688 acpi_thermal_active_off(tz);
1689
1690 acpi_thermal_check(tz);
1691
1692 status = acpi_install_notify_handler(device->handle, 1372 status = acpi_install_notify_handler(device->handle,
1693 ACPI_DEVICE_NOTIFY, 1373 ACPI_DEVICE_NOTIFY,
1694 acpi_thermal_notify, tz); 1374 acpi_thermal_notify, tz);
@@ -1717,36 +1397,15 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
1717 acpi_status status = AE_OK; 1397 acpi_status status = AE_OK;
1718 struct acpi_thermal *tz = NULL; 1398 struct acpi_thermal *tz = NULL;
1719 1399
1720
1721 if (!device || !acpi_driver_data(device)) 1400 if (!device || !acpi_driver_data(device))
1722 return -EINVAL; 1401 return -EINVAL;
1723 1402
1724 tz = acpi_driver_data(device); 1403 tz = acpi_driver_data(device);
1725 1404
1726 /* avoid timer adding new defer task */
1727 tz->zombie = 1;
1728 /* wait for running timer (on other CPUs) finish */
1729 del_timer_sync(&(tz->timer));
1730 /* synchronize deferred task */
1731 acpi_os_wait_events_complete(NULL);
1732 /* deferred task may reinsert timer */
1733 del_timer_sync(&(tz->timer));
1734
1735 status = acpi_remove_notify_handler(device->handle, 1405 status = acpi_remove_notify_handler(device->handle,
1736 ACPI_DEVICE_NOTIFY, 1406 ACPI_DEVICE_NOTIFY,
1737 acpi_thermal_notify); 1407 acpi_thermal_notify);
1738 1408
1739 /* Terminate policy */
1740 if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) {
1741 tz->trips.passive.flags.enabled = 0;
1742 acpi_thermal_passive(tz);
1743 }
1744 if (tz->trips.active[0].flags.valid
1745 && tz->trips.active[0].flags.enabled) {
1746 tz->trips.active[0].flags.enabled = 0;
1747 acpi_thermal_active(tz);
1748 }
1749
1750 acpi_thermal_remove_fs(device); 1409 acpi_thermal_remove_fs(device);
1751 acpi_thermal_unregister_thermal_zone(tz); 1410 acpi_thermal_unregister_thermal_zone(tz);
1752 mutex_destroy(&tz->lock); 1411 mutex_destroy(&tz->lock);
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index bb5ed059114a..5259d502add6 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -358,32 +358,36 @@ static struct output_properties acpi_output_properties = {
358 358
359 359
360/* thermal cooling device callbacks */ 360/* thermal cooling device callbacks */
361static int video_get_max_state(struct thermal_cooling_device *cdev, char *buf) 361static int video_get_max_state(struct thermal_cooling_device *cdev, unsigned
362 long *state)
362{ 363{
363 struct acpi_device *device = cdev->devdata; 364 struct acpi_device *device = cdev->devdata;
364 struct acpi_video_device *video = acpi_driver_data(device); 365 struct acpi_video_device *video = acpi_driver_data(device);
365 366
366 return sprintf(buf, "%d\n", video->brightness->count - 3); 367 *state = video->brightness->count - 3;
368 return 0;
367} 369}
368 370
369static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf) 371static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned
372 long *state)
370{ 373{
371 struct acpi_device *device = cdev->devdata; 374 struct acpi_device *device = cdev->devdata;
372 struct acpi_video_device *video = acpi_driver_data(device); 375 struct acpi_video_device *video = acpi_driver_data(device);
373 unsigned long long level; 376 unsigned long long level;
374 int state; 377 int offset;
375 378
376 acpi_video_device_lcd_get_level_current(video, &level); 379 acpi_video_device_lcd_get_level_current(video, &level);
377 for (state = 2; state < video->brightness->count; state++) 380 for (offset = 2; offset < video->brightness->count; offset++)
378 if (level == video->brightness->levels[state]) 381 if (level == video->brightness->levels[offset]) {
379 return sprintf(buf, "%d\n", 382 *state = video->brightness->count - offset - 1;
380 video->brightness->count - state - 1); 383 return 0;
384 }
381 385
382 return -EINVAL; 386 return -EINVAL;
383} 387}
384 388
385static int 389static int
386video_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state) 390video_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
387{ 391{
388 struct acpi_device *device = cdev->devdata; 392 struct acpi_device *device = cdev->devdata;
389 struct acpi_video_device *video = acpi_driver_data(device); 393 struct acpi_video_device *video = acpi_driver_data(device);
diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c
index 27b7662955bb..29432a50be45 100644
--- a/drivers/platform/x86/intel_menlow.c
+++ b/drivers/platform/x86/intel_menlow.c
@@ -57,8 +57,8 @@ MODULE_LICENSE("GPL");
57 * In that case max_cstate would be n-1 57 * In that case max_cstate would be n-1
58 * GTHS returning '0' would mean that no bandwidth control states are supported 58 * GTHS returning '0' would mean that no bandwidth control states are supported
59 */ 59 */
60static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev, 60static int memory_get_max_bandwidth(struct thermal_cooling_device *cdev,
61 unsigned long *max_state) 61 unsigned long *max_state)
62{ 62{
63 struct acpi_device *device = cdev->devdata; 63 struct acpi_device *device = cdev->devdata;
64 acpi_handle handle = device->handle; 64 acpi_handle handle = device->handle;
@@ -83,22 +83,12 @@ static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev,
83 return 0; 83 return 0;
84} 84}
85 85
86static int memory_get_max_bandwidth(struct thermal_cooling_device *cdev,
87 char *buf)
88{
89 unsigned long value;
90 if (memory_get_int_max_bandwidth(cdev, &value))
91 return -EINVAL;
92
93 return sprintf(buf, "%ld\n", value);
94}
95
96static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev, 86static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev,
97 char *buf) 87 unsigned long *value)
98{ 88{
99 struct acpi_device *device = cdev->devdata; 89 struct acpi_device *device = cdev->devdata;
100 acpi_handle handle = device->handle; 90 acpi_handle handle = device->handle;
101 unsigned long long value; 91 unsigned long long result;
102 struct acpi_object_list arg_list; 92 struct acpi_object_list arg_list;
103 union acpi_object arg; 93 union acpi_object arg;
104 acpi_status status = AE_OK; 94 acpi_status status = AE_OK;
@@ -108,15 +98,16 @@ static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev,
108 arg.type = ACPI_TYPE_INTEGER; 98 arg.type = ACPI_TYPE_INTEGER;
109 arg.integer.value = MEMORY_ARG_CUR_BANDWIDTH; 99 arg.integer.value = MEMORY_ARG_CUR_BANDWIDTH;
110 status = acpi_evaluate_integer(handle, MEMORY_GET_BANDWIDTH, 100 status = acpi_evaluate_integer(handle, MEMORY_GET_BANDWIDTH,
111 &arg_list, &value); 101 &arg_list, &result);
112 if (ACPI_FAILURE(status)) 102 if (ACPI_FAILURE(status))
113 return -EFAULT; 103 return -EFAULT;
114 104
115 return sprintf(buf, "%llu\n", value); 105 *value = result;
106 return 0;
116} 107}
117 108
118static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev, 109static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
119 unsigned int state) 110 unsigned long state)
120{ 111{
121 struct acpi_device *device = cdev->devdata; 112 struct acpi_device *device = cdev->devdata;
122 acpi_handle handle = device->handle; 113 acpi_handle handle = device->handle;
@@ -126,7 +117,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
126 unsigned long long temp; 117 unsigned long long temp;
127 unsigned long max_state; 118 unsigned long max_state;
128 119
129 if (memory_get_int_max_bandwidth(cdev, &max_state)) 120 if (memory_get_max_bandwidth(cdev, &max_state))
130 return -EFAULT; 121 return -EFAULT;
131 122
132 if (state > max_state) 123 if (state > max_state)
@@ -142,7 +133,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
142 &temp); 133 &temp);
143 134
144 printk(KERN_INFO 135 printk(KERN_INFO
145 "Bandwidth value was %d: status is %d\n", state, status); 136 "Bandwidth value was %ld: status is %d\n", state, status);
146 if (ACPI_FAILURE(status)) 137 if (ACPI_FAILURE(status))
147 return -EFAULT; 138 return -EFAULT;
148 139
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 8171ca17b936..d0b093b66adc 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");
@@ -104,22 +105,36 @@ static ssize_t
104temp_show(struct device *dev, struct device_attribute *attr, char *buf) 105temp_show(struct device *dev, struct device_attribute *attr, char *buf)
105{ 106{
106 struct thermal_zone_device *tz = to_thermal_zone(dev); 107 struct thermal_zone_device *tz = to_thermal_zone(dev);
108 long temperature;
109 int ret;
107 110
108 if (!tz->ops->get_temp) 111 if (!tz->ops->get_temp)
109 return -EPERM; 112 return -EPERM;
110 113
111 return tz->ops->get_temp(tz, buf); 114 ret = tz->ops->get_temp(tz, &temperature);
115
116 if (ret)
117 return ret;
118
119 return sprintf(buf, "%ld\n", temperature);
112} 120}
113 121
114static ssize_t 122static ssize_t
115mode_show(struct device *dev, struct device_attribute *attr, char *buf) 123mode_show(struct device *dev, struct device_attribute *attr, char *buf)
116{ 124{
117 struct thermal_zone_device *tz = to_thermal_zone(dev); 125 struct thermal_zone_device *tz = to_thermal_zone(dev);
126 enum thermal_device_mode mode;
127 int result;
118 128
119 if (!tz->ops->get_mode) 129 if (!tz->ops->get_mode)
120 return -EPERM; 130 return -EPERM;
121 131
122 return tz->ops->get_mode(tz, buf); 132 result = tz->ops->get_mode(tz, &mode);
133 if (result)
134 return result;
135
136 return sprintf(buf, "%s\n", mode == THERMAL_DEVICE_ENABLED ? "enabled"
137 : "disabled");
123} 138}
124 139
125static ssize_t 140static ssize_t
@@ -132,7 +147,13 @@ mode_store(struct device *dev, struct device_attribute *attr,
132 if (!tz->ops->set_mode) 147 if (!tz->ops->set_mode)
133 return -EPERM; 148 return -EPERM;
134 149
135 result = tz->ops->set_mode(tz, buf); 150 if (!strncmp(buf, "enabled", sizeof("enabled")))
151 result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
152 else if (!strncmp(buf, "disabled", sizeof("disabled")))
153 result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
154 else
155 result = -EINVAL;
156
136 if (result) 157 if (result)
137 return result; 158 return result;
138 159
@@ -144,7 +165,8 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
144 char *buf) 165 char *buf)
145{ 166{
146 struct thermal_zone_device *tz = to_thermal_zone(dev); 167 struct thermal_zone_device *tz = to_thermal_zone(dev);
147 int trip; 168 enum thermal_trip_type type;
169 int trip, result;
148 170
149 if (!tz->ops->get_trip_type) 171 if (!tz->ops->get_trip_type)
150 return -EPERM; 172 return -EPERM;
@@ -152,7 +174,22 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
152 if (!sscanf(attr->attr.name, "trip_point_%d_type", &trip)) 174 if (!sscanf(attr->attr.name, "trip_point_%d_type", &trip))
153 return -EINVAL; 175 return -EINVAL;
154 176
155 return tz->ops->get_trip_type(tz, trip, buf); 177 result = tz->ops->get_trip_type(tz, trip, &type);
178 if (result)
179 return result;
180
181 switch (type) {
182 case THERMAL_TRIP_CRITICAL:
183 return sprintf(buf, "critical");
184 case THERMAL_TRIP_HOT:
185 return sprintf(buf, "hot");
186 case THERMAL_TRIP_PASSIVE:
187 return sprintf(buf, "passive");
188 case THERMAL_TRIP_ACTIVE:
189 return sprintf(buf, "active");
190 default:
191 return sprintf(buf, "unknown");
192 }
156} 193}
157 194
158static ssize_t 195static ssize_t
@@ -160,7 +197,8 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
160 char *buf) 197 char *buf)
161{ 198{
162 struct thermal_zone_device *tz = to_thermal_zone(dev); 199 struct thermal_zone_device *tz = to_thermal_zone(dev);
163 int trip; 200 int trip, ret;
201 long temperature;
164 202
165 if (!tz->ops->get_trip_temp) 203 if (!tz->ops->get_trip_temp)
166 return -EPERM; 204 return -EPERM;
@@ -168,12 +206,77 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
168 if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip)) 206 if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip))
169 return -EINVAL; 207 return -EINVAL;
170 208
171 return tz->ops->get_trip_temp(tz, trip, buf); 209 ret = tz->ops->get_trip_temp(tz, trip, &temperature);
210
211 if (ret)
212 return ret;
213
214 return sprintf(buf, "%ld\n", temperature);
215}
216
217static ssize_t
218passive_store(struct device *dev, struct device_attribute *attr,
219 const char *buf, size_t count)
220{
221 struct thermal_zone_device *tz = to_thermal_zone(dev);
222 struct thermal_cooling_device *cdev = NULL;
223 int state;
224
225 if (!sscanf(buf, "%d\n", &state))
226 return -EINVAL;
227
228 if (state && !tz->forced_passive) {
229 mutex_lock(&thermal_list_lock);
230 list_for_each_entry(cdev, &thermal_cdev_list, node) {
231 if (!strncmp("Processor", cdev->type,
232 sizeof("Processor")))
233 thermal_zone_bind_cooling_device(tz,
234 THERMAL_TRIPS_NONE,
235 cdev);
236 }
237 mutex_unlock(&thermal_list_lock);
238 } else if (!state && tz->forced_passive) {
239 mutex_lock(&thermal_list_lock);
240 list_for_each_entry(cdev, &thermal_cdev_list, node) {
241 if (!strncmp("Processor", cdev->type,
242 sizeof("Processor")))
243 thermal_zone_unbind_cooling_device(tz,
244 THERMAL_TRIPS_NONE,
245 cdev);
246 }
247 mutex_unlock(&thermal_list_lock);
248 }
249
250 tz->tc1 = 1;
251 tz->tc2 = 1;
252
253 if (!tz->passive_delay)
254 tz->passive_delay = 1000;
255
256 if (!tz->polling_delay)
257 tz->polling_delay = 10000;
258
259 tz->forced_passive = state;
260
261 thermal_zone_device_update(tz);
262
263 return count;
264}
265
266static ssize_t
267passive_show(struct device *dev, struct device_attribute *attr,
268 char *buf)
269{
270 struct thermal_zone_device *tz = to_thermal_zone(dev);
271
272 return sprintf(buf, "%d\n", tz->forced_passive);
172} 273}
173 274
174static DEVICE_ATTR(type, 0444, type_show, NULL); 275static DEVICE_ATTR(type, 0444, type_show, NULL);
175static DEVICE_ATTR(temp, 0444, temp_show, NULL); 276static DEVICE_ATTR(temp, 0444, temp_show, NULL);
176static DEVICE_ATTR(mode, 0644, mode_show, mode_store); 277static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
278static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, \
279 passive_store);
177 280
178static struct device_attribute trip_point_attrs[] = { 281static struct device_attribute trip_point_attrs[] = {
179 __ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL), 282 __ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL),
@@ -236,8 +339,13 @@ thermal_cooling_device_max_state_show(struct device *dev,
236 struct device_attribute *attr, char *buf) 339 struct device_attribute *attr, char *buf)
237{ 340{
238 struct thermal_cooling_device *cdev = to_cooling_device(dev); 341 struct thermal_cooling_device *cdev = to_cooling_device(dev);
342 unsigned long state;
343 int ret;
239 344
240 return cdev->ops->get_max_state(cdev, buf); 345 ret = cdev->ops->get_max_state(cdev, &state);
346 if (ret)
347 return ret;
348 return sprintf(buf, "%ld\n", state);
241} 349}
242 350
243static ssize_t 351static ssize_t
@@ -245,8 +353,13 @@ thermal_cooling_device_cur_state_show(struct device *dev,
245 struct device_attribute *attr, char *buf) 353 struct device_attribute *attr, char *buf)
246{ 354{
247 struct thermal_cooling_device *cdev = to_cooling_device(dev); 355 struct thermal_cooling_device *cdev = to_cooling_device(dev);
356 unsigned long state;
357 int ret;
248 358
249 return cdev->ops->get_cur_state(cdev, buf); 359 ret = cdev->ops->get_cur_state(cdev, &state);
360 if (ret)
361 return ret;
362 return sprintf(buf, "%ld\n", state);
250} 363}
251 364
252static ssize_t 365static ssize_t
@@ -255,10 +368,10 @@ thermal_cooling_device_cur_state_store(struct device *dev,
255 const char *buf, size_t count) 368 const char *buf, size_t count)
256{ 369{
257 struct thermal_cooling_device *cdev = to_cooling_device(dev); 370 struct thermal_cooling_device *cdev = to_cooling_device(dev);
258 int state; 371 unsigned long state;
259 int result; 372 int result;
260 373
261 if (!sscanf(buf, "%d\n", &state)) 374 if (!sscanf(buf, "%ld\n", &state))
262 return -EINVAL; 375 return -EINVAL;
263 376
264 if (state < 0) 377 if (state < 0)
@@ -312,13 +425,20 @@ static DEVICE_ATTR(name, 0444, name_show, NULL);
312static ssize_t 425static ssize_t
313temp_input_show(struct device *dev, struct device_attribute *attr, char *buf) 426temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
314{ 427{
428 long temperature;
429 int ret;
315 struct thermal_hwmon_attr *hwmon_attr 430 struct thermal_hwmon_attr *hwmon_attr
316 = container_of(attr, struct thermal_hwmon_attr, attr); 431 = container_of(attr, struct thermal_hwmon_attr, attr);
317 struct thermal_zone_device *tz 432 struct thermal_zone_device *tz
318 = container_of(hwmon_attr, struct thermal_zone_device, 433 = container_of(hwmon_attr, struct thermal_zone_device,
319 temp_input); 434 temp_input);
320 435
321 return tz->ops->get_temp(tz, buf); 436 ret = tz->ops->get_temp(tz, &temperature);
437
438 if (ret)
439 return ret;
440
441 return sprintf(buf, "%ld\n", temperature);
322} 442}
323 443
324static ssize_t 444static ssize_t
@@ -330,8 +450,14 @@ temp_crit_show(struct device *dev, struct device_attribute *attr,
330 struct thermal_zone_device *tz 450 struct thermal_zone_device *tz
331 = container_of(hwmon_attr, struct thermal_zone_device, 451 = container_of(hwmon_attr, struct thermal_zone_device,
332 temp_crit); 452 temp_crit);
453 long temperature;
454 int ret;
455
456 ret = tz->ops->get_trip_temp(tz, 0, &temperature);
457 if (ret)
458 return ret;
333 459
334 return tz->ops->get_trip_temp(tz, 0, buf); 460 return sprintf(buf, "%ld\n", temperature);
335} 461}
336 462
337 463
@@ -452,6 +578,97 @@ thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
452} 578}
453#endif 579#endif
454 580
581static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
582 int delay)
583{
584 cancel_delayed_work(&(tz->poll_queue));
585
586 if (!delay)
587 return;
588
589 if (delay > 1000)
590 schedule_delayed_work(&(tz->poll_queue),
591 round_jiffies(msecs_to_jiffies(delay)));
592 else
593 schedule_delayed_work(&(tz->poll_queue),
594 msecs_to_jiffies(delay));
595}
596
597static void thermal_zone_device_passive(struct thermal_zone_device *tz,
598 int temp, int trip_temp, int trip)
599{
600 int trend = 0;
601 struct thermal_cooling_device_instance *instance;
602 struct thermal_cooling_device *cdev;
603 long state, max_state;
604
605 /*
606 * Above Trip?
607 * -----------
608 * Calculate the thermal trend (using the passive cooling equation)
609 * and modify the performance limit for all passive cooling devices
610 * accordingly. Note that we assume symmetry.
611 */
612 if (temp >= trip_temp) {
613 tz->passive = true;
614
615 trend = (tz->tc1 * (temp - tz->last_temperature)) +
616 (tz->tc2 * (temp - trip_temp));
617
618 /* Heating up? */
619 if (trend > 0) {
620 list_for_each_entry(instance, &tz->cooling_devices,
621 node) {
622 if (instance->trip != trip)
623 continue;
624 cdev = instance->cdev;
625 cdev->ops->get_cur_state(cdev, &state);
626 cdev->ops->get_max_state(cdev, &max_state);
627 if (state++ < max_state)
628 cdev->ops->set_cur_state(cdev, state);
629 }
630 } else if (trend < 0) { /* Cooling off? */
631 list_for_each_entry(instance, &tz->cooling_devices,
632 node) {
633 if (instance->trip != trip)
634 continue;
635 cdev = instance->cdev;
636 cdev->ops->get_cur_state(cdev, &state);
637 cdev->ops->get_max_state(cdev, &max_state);
638 if (state > 0)
639 cdev->ops->set_cur_state(cdev, --state);
640 }
641 }
642 return;
643 }
644
645 /*
646 * Below Trip?
647 * -----------
648 * Implement passive cooling hysteresis to slowly increase performance
649 * and avoid thrashing around the passive trip point. Note that we
650 * assume symmetry.
651 */
652 list_for_each_entry(instance, &tz->cooling_devices, node) {
653 if (instance->trip != trip)
654 continue;
655 cdev = instance->cdev;
656 cdev->ops->get_cur_state(cdev, &state);
657 cdev->ops->get_max_state(cdev, &max_state);
658 if (state > 0)
659 cdev->ops->set_cur_state(cdev, --state);
660 if (state == 0)
661 tz->passive = false;
662 }
663}
664
665static void thermal_zone_device_check(struct work_struct *work)
666{
667 struct thermal_zone_device *tz = container_of(work, struct
668 thermal_zone_device,
669 poll_queue.work);
670 thermal_zone_device_update(tz);
671}
455 672
456/** 673/**
457 * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone 674 * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone
@@ -722,25 +939,113 @@ void thermal_cooling_device_unregister(struct
722EXPORT_SYMBOL(thermal_cooling_device_unregister); 939EXPORT_SYMBOL(thermal_cooling_device_unregister);
723 940
724/** 941/**
942 * thermal_zone_device_update - force an update of a thermal zone's state
943 * @ttz: the thermal zone to update
944 */
945
946void thermal_zone_device_update(struct thermal_zone_device *tz)
947{
948 int count, ret = 0;
949 long temp, trip_temp;
950 enum thermal_trip_type trip_type;
951 struct thermal_cooling_device_instance *instance;
952 struct thermal_cooling_device *cdev;
953
954 mutex_lock(&tz->lock);
955
956 tz->ops->get_temp(tz, &temp);
957
958 for (count = 0; count < tz->trips; count++) {
959 tz->ops->get_trip_type(tz, count, &trip_type);
960 tz->ops->get_trip_temp(tz, count, &trip_temp);
961
962 switch (trip_type) {
963 case THERMAL_TRIP_CRITICAL:
964 if (temp > trip_temp) {
965 if (tz->ops->notify)
966 ret = tz->ops->notify(tz, count,
967 trip_type);
968 if (!ret) {
969 printk(KERN_EMERG
970 "Critical temperature reached (%ld C), shutting down.\n",
971 temp/1000);
972 orderly_poweroff(true);
973 }
974 }
975 break;
976 case THERMAL_TRIP_HOT:
977 if (temp > trip_temp)
978 if (tz->ops->notify)
979 tz->ops->notify(tz, count, trip_type);
980 break;
981 case THERMAL_TRIP_ACTIVE:
982 list_for_each_entry(instance, &tz->cooling_devices,
983 node) {
984 if (instance->trip != count)
985 continue;
986
987 cdev = instance->cdev;
988
989 if (temp > trip_temp)
990 cdev->ops->set_cur_state(cdev, 1);
991 else
992 cdev->ops->set_cur_state(cdev, 0);
993 }
994 break;
995 case THERMAL_TRIP_PASSIVE:
996 if (temp > trip_temp || tz->passive)
997 thermal_zone_device_passive(tz, temp,
998 trip_temp, count);
999 break;
1000 }
1001 }
1002
1003 if (tz->forced_passive)
1004 thermal_zone_device_passive(tz, temp, tz->forced_passive,
1005 THERMAL_TRIPS_NONE);
1006
1007 tz->last_temperature = temp;
1008 if (tz->passive)
1009 thermal_zone_device_set_polling(tz, tz->passive_delay);
1010 else if (tz->polling_delay)
1011 thermal_zone_device_set_polling(tz, tz->polling_delay);
1012 mutex_unlock(&tz->lock);
1013}
1014EXPORT_SYMBOL(thermal_zone_device_update);
1015
1016/**
725 * thermal_zone_device_register - register a new thermal zone device 1017 * thermal_zone_device_register - register a new thermal zone device
726 * @type: the thermal zone device type 1018 * @type: the thermal zone device type
727 * @trips: the number of trip points the thermal zone support 1019 * @trips: the number of trip points the thermal zone support
728 * @devdata: private device data 1020 * @devdata: private device data
729 * @ops: standard thermal zone device callbacks 1021 * @ops: standard thermal zone device callbacks
1022 * @tc1: thermal coefficient 1 for passive calculations
1023 * @tc2: thermal coefficient 2 for passive calculations
1024 * @passive_delay: number of milliseconds to wait between polls when
1025 * performing passive cooling
1026 * @polling_delay: number of milliseconds to wait between polls when checking
1027 * whether trip points have been crossed (0 for interrupt
1028 * driven systems)
730 * 1029 *
731 * thermal_zone_device_unregister() must be called when the device is no 1030 * thermal_zone_device_unregister() must be called when the device is no
732 * longer needed. 1031 * longer needed. The passive cooling formula uses tc1 and tc2 as described in
1032 * section 11.1.5.1 of the ACPI specification 3.0.
733 */ 1033 */
734struct thermal_zone_device *thermal_zone_device_register(char *type, 1034struct thermal_zone_device *thermal_zone_device_register(char *type,
735 int trips, 1035 int trips,
736 void *devdata, struct 1036 void *devdata, struct
737 thermal_zone_device_ops 1037 thermal_zone_device_ops
738 *ops) 1038 *ops, int tc1, int
1039 tc2,
1040 int passive_delay,
1041 int polling_delay)
739{ 1042{
740 struct thermal_zone_device *tz; 1043 struct thermal_zone_device *tz;
741 struct thermal_cooling_device *pos; 1044 struct thermal_cooling_device *pos;
1045 enum thermal_trip_type trip_type;
742 int result; 1046 int result;
743 int count; 1047 int count;
1048 int passive = 0;
744 1049
745 if (strlen(type) >= THERMAL_NAME_LENGTH) 1050 if (strlen(type) >= THERMAL_NAME_LENGTH)
746 return ERR_PTR(-EINVAL); 1051 return ERR_PTR(-EINVAL);
@@ -769,6 +1074,11 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
769 tz->device.class = &thermal_class; 1074 tz->device.class = &thermal_class;
770 tz->devdata = devdata; 1075 tz->devdata = devdata;
771 tz->trips = trips; 1076 tz->trips = trips;
1077 tz->tc1 = tc1;
1078 tz->tc2 = tc2;
1079 tz->passive_delay = passive_delay;
1080 tz->polling_delay = polling_delay;
1081
772 dev_set_name(&tz->device, "thermal_zone%d", tz->id); 1082 dev_set_name(&tz->device, "thermal_zone%d", tz->id);
773 result = device_register(&tz->device); 1083 result = device_register(&tz->device);
774 if (result) { 1084 if (result) {
@@ -798,8 +1108,18 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
798 TRIP_POINT_ATTR_ADD(&tz->device, count, result); 1108 TRIP_POINT_ATTR_ADD(&tz->device, count, result);
799 if (result) 1109 if (result)
800 goto unregister; 1110 goto unregister;
1111 tz->ops->get_trip_type(tz, count, &trip_type);
1112 if (trip_type == THERMAL_TRIP_PASSIVE)
1113 passive = 1;
801 } 1114 }
802 1115
1116 if (!passive)
1117 result = device_create_file(&tz->device,
1118 &dev_attr_passive);
1119
1120 if (result)
1121 goto unregister;
1122
803 result = thermal_add_hwmon_sysfs(tz); 1123 result = thermal_add_hwmon_sysfs(tz);
804 if (result) 1124 if (result)
805 goto unregister; 1125 goto unregister;
@@ -814,6 +1134,10 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
814 } 1134 }
815 mutex_unlock(&thermal_list_lock); 1135 mutex_unlock(&thermal_list_lock);
816 1136
1137 INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
1138
1139 thermal_zone_device_update(tz);
1140
817 if (!result) 1141 if (!result)
818 return tz; 1142 return tz;
819 1143
@@ -853,6 +1177,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
853 tz->ops->unbind(tz, cdev); 1177 tz->ops->unbind(tz, cdev);
854 mutex_unlock(&thermal_list_lock); 1178 mutex_unlock(&thermal_list_lock);
855 1179
1180 thermal_zone_device_set_polling(tz, 0);
1181
856 if (tz->type[0]) 1182 if (tz->type[0])
857 device_remove_file(&tz->device, &dev_attr_type); 1183 device_remove_file(&tz->device, &dev_attr_type);
858 device_remove_file(&tz->device, &dev_attr_temp); 1184 device_remove_file(&tz->device, &dev_attr_temp);
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 917707e6151d..1de8b9eb841b 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -27,27 +27,46 @@
27 27
28#include <linux/idr.h> 28#include <linux/idr.h>
29#include <linux/device.h> 29#include <linux/device.h>
30#include <linux/workqueue.h>
30 31
31struct thermal_zone_device; 32struct thermal_zone_device;
32struct thermal_cooling_device; 33struct thermal_cooling_device;
33 34
35enum thermal_device_mode {
36 THERMAL_DEVICE_DISABLED = 0,
37 THERMAL_DEVICE_ENABLED,
38};
39
40enum thermal_trip_type {
41 THERMAL_TRIP_ACTIVE = 0,
42 THERMAL_TRIP_PASSIVE,
43 THERMAL_TRIP_HOT,
44 THERMAL_TRIP_CRITICAL,
45};
46
34struct thermal_zone_device_ops { 47struct thermal_zone_device_ops {
35 int (*bind) (struct thermal_zone_device *, 48 int (*bind) (struct thermal_zone_device *,
36 struct thermal_cooling_device *); 49 struct thermal_cooling_device *);
37 int (*unbind) (struct thermal_zone_device *, 50 int (*unbind) (struct thermal_zone_device *,
38 struct thermal_cooling_device *); 51 struct thermal_cooling_device *);
39 int (*get_temp) (struct thermal_zone_device *, char *); 52 int (*get_temp) (struct thermal_zone_device *, unsigned long *);
40 int (*get_mode) (struct thermal_zone_device *, char *); 53 int (*get_mode) (struct thermal_zone_device *,
41 int (*set_mode) (struct thermal_zone_device *, const char *); 54 enum thermal_device_mode *);
42 int (*get_trip_type) (struct thermal_zone_device *, int, char *); 55 int (*set_mode) (struct thermal_zone_device *,
43 int (*get_trip_temp) (struct thermal_zone_device *, int, char *); 56 enum thermal_device_mode);
57 int (*get_trip_type) (struct thermal_zone_device *, int,
58 enum thermal_trip_type *);
59 int (*get_trip_temp) (struct thermal_zone_device *, int,
60 unsigned long *);
44 int (*get_crit_temp) (struct thermal_zone_device *, unsigned long *); 61 int (*get_crit_temp) (struct thermal_zone_device *, unsigned long *);
62 int (*notify) (struct thermal_zone_device *, int,
63 enum thermal_trip_type);
45}; 64};
46 65
47struct thermal_cooling_device_ops { 66struct thermal_cooling_device_ops {
48 int (*get_max_state) (struct thermal_cooling_device *, char *); 67 int (*get_max_state) (struct thermal_cooling_device *, unsigned long *);
49 int (*get_cur_state) (struct thermal_cooling_device *, char *); 68 int (*get_cur_state) (struct thermal_cooling_device *, unsigned long *);
50 int (*set_cur_state) (struct thermal_cooling_device *, unsigned int); 69 int (*set_cur_state) (struct thermal_cooling_device *, unsigned long);
51}; 70};
52 71
53#define THERMAL_TRIPS_NONE -1 72#define THERMAL_TRIPS_NONE -1
@@ -88,11 +107,19 @@ struct thermal_zone_device {
88 struct device device; 107 struct device device;
89 void *devdata; 108 void *devdata;
90 int trips; 109 int trips;
110 int tc1;
111 int tc2;
112 int passive_delay;
113 int polling_delay;
114 int last_temperature;
115 bool passive;
116 unsigned int forced_passive;
91 struct thermal_zone_device_ops *ops; 117 struct thermal_zone_device_ops *ops;
92 struct list_head cooling_devices; 118 struct list_head cooling_devices;
93 struct idr idr; 119 struct idr idr;
94 struct mutex lock; /* protect cooling devices list */ 120 struct mutex lock; /* protect cooling devices list */
95 struct list_head node; 121 struct list_head node;
122 struct delayed_work poll_queue;
96#if defined(CONFIG_THERMAL_HWMON) 123#if defined(CONFIG_THERMAL_HWMON)
97 struct list_head hwmon_node; 124 struct list_head hwmon_node;
98 struct thermal_hwmon_device *hwmon; 125 struct thermal_hwmon_device *hwmon;
@@ -104,13 +131,16 @@ struct thermal_zone_device {
104struct thermal_zone_device *thermal_zone_device_register(char *, int, void *, 131struct thermal_zone_device *thermal_zone_device_register(char *, int, void *,
105 struct 132 struct
106 thermal_zone_device_ops 133 thermal_zone_device_ops
107 *); 134 *, int tc1, int tc2,
135 int passive_freq,
136 int polling_freq);
108void thermal_zone_device_unregister(struct thermal_zone_device *); 137void thermal_zone_device_unregister(struct thermal_zone_device *);
109 138
110int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int, 139int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
111 struct thermal_cooling_device *); 140 struct thermal_cooling_device *);
112int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int, 141int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int,
113 struct thermal_cooling_device *); 142 struct thermal_cooling_device *);
143void thermal_zone_device_update(struct thermal_zone_device *);
114struct thermal_cooling_device *thermal_cooling_device_register(char *, void *, 144struct thermal_cooling_device *thermal_cooling_device_register(char *, void *,
115 struct 145 struct
116 thermal_cooling_device_ops 146 thermal_cooling_device_ops