aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhang Rui <rui.zhang@intel.com>2012-06-26 04:35:57 -0400
committerZhang Rui <rui.zhang@intel.com>2012-09-24 02:44:36 -0400
commit9d99842f99d847191ebd0c28469d2c70fcc5bf9e (patch)
tree211624d5fbc557c1226b6270a96807acc3b383df
parent74051ba50583a5880d4536c1d9333e2493ddfd76 (diff)
Thermal: set upper and lower limits
set upper and lower limits when binding a thermal cooling device to a thermal zone device. Signed-off-by: Zhang Rui <rui.zhang@intel.com> Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl> Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>
-rw-r--r--Documentation/thermal/sysfs-api.txt9
-rw-r--r--drivers/acpi/thermal.c53
-rw-r--r--drivers/platform/x86/acerhdf.c3
-rw-r--r--drivers/thermal/thermal_sys.c23
-rw-r--r--include/linux/thermal.h5
5 files changed, 65 insertions, 28 deletions
diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt
index c087dbcf3535..ca1a1a34970e 100644
--- a/Documentation/thermal/sysfs-api.txt
+++ b/Documentation/thermal/sysfs-api.txt
@@ -84,7 +84,8 @@ temperature) and throttle appropriate devices.
84 84
851.3 interface for binding a thermal zone device with a thermal cooling device 851.3 interface for binding a thermal zone device with a thermal cooling device
861.3.1 int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, 861.3.1 int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
87 int trip, struct thermal_cooling_device *cdev); 87 int trip, struct thermal_cooling_device *cdev,
88 unsigned long upper, unsigned long lower);
88 89
89 This interface function bind a thermal cooling device to the certain trip 90 This interface function bind a thermal cooling device to the certain trip
90 point of a thermal zone device. 91 point of a thermal zone device.
@@ -93,6 +94,12 @@ temperature) and throttle appropriate devices.
93 cdev: thermal cooling device 94 cdev: thermal cooling device
94 trip: indicates which trip point the cooling devices is associated with 95 trip: indicates which trip point the cooling devices is associated with
95 in this thermal zone. 96 in this thermal zone.
97 upper:the Maximum cooling state for this trip point.
98 THERMAL_NO_LIMIT means no upper limit,
99 and the cooling device can be in max_state.
100 lower:the Minimum cooling state can be used for this trip point.
101 THERMAL_NO_LIMIT means no lower limit,
102 and the cooling device can be in cooling state 0.
96 103
971.3.2 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz, 1041.3.2 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
98 int trip, struct thermal_cooling_device *cdev); 105 int trip, struct thermal_cooling_device *cdev);
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 9fe90e9fecb5..d7ef69d835f2 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -729,11 +729,9 @@ static int thermal_notify(struct thermal_zone_device *thermal, int trip,
729 return 0; 729 return 0;
730} 730}
731 731
732typedef int (*cb)(struct thermal_zone_device *, int,
733 struct thermal_cooling_device *);
734static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, 732static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
735 struct thermal_cooling_device *cdev, 733 struct thermal_cooling_device *cdev,
736 cb action) 734 bool bind)
737{ 735{
738 struct acpi_device *device = cdev->devdata; 736 struct acpi_device *device = cdev->devdata;
739 struct acpi_thermal *tz = thermal->devdata; 737 struct acpi_thermal *tz = thermal->devdata;
@@ -757,11 +755,19 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
757 i++) { 755 i++) {
758 handle = tz->trips.passive.devices.handles[i]; 756 handle = tz->trips.passive.devices.handles[i];
759 status = acpi_bus_get_device(handle, &dev); 757 status = acpi_bus_get_device(handle, &dev);
760 if (ACPI_SUCCESS(status) && (dev == device)) { 758 if (ACPI_FAILURE(status) || dev != device)
761 result = action(thermal, trip, cdev); 759 continue;
762 if (result) 760 if (bind)
763 goto failed; 761 result =
764 } 762 thermal_zone_bind_cooling_device
763 (thermal, trip, cdev,
764 THERMAL_NO_LIMIT, THERMAL_NO_LIMIT);
765 else
766 result =
767 thermal_zone_unbind_cooling_device
768 (thermal, trip, cdev);
769 if (result)
770 goto failed;
765 } 771 }
766 } 772 }
767 773
@@ -774,11 +780,17 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
774 j++) { 780 j++) {
775 handle = tz->trips.active[i].devices.handles[j]; 781 handle = tz->trips.active[i].devices.handles[j];
776 status = acpi_bus_get_device(handle, &dev); 782 status = acpi_bus_get_device(handle, &dev);
777 if (ACPI_SUCCESS(status) && (dev == device)) { 783 if (ACPI_FAILURE(status) || dev != device)
778 result = action(thermal, trip, cdev); 784 continue;
779 if (result) 785 if (bind)
780 goto failed; 786 result = thermal_zone_bind_cooling_device
781 } 787 (thermal, trip, cdev,
788 THERMAL_NO_LIMIT, THERMAL_NO_LIMIT);
789 else
790 result = thermal_zone_unbind_cooling_device
791 (thermal, trip, cdev);
792 if (result)
793 goto failed;
782 } 794 }
783 } 795 }
784 796
@@ -786,7 +798,14 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
786 handle = tz->devices.handles[i]; 798 handle = tz->devices.handles[i];
787 status = acpi_bus_get_device(handle, &dev); 799 status = acpi_bus_get_device(handle, &dev);
788 if (ACPI_SUCCESS(status) && (dev == device)) { 800 if (ACPI_SUCCESS(status) && (dev == device)) {
789 result = action(thermal, -1, cdev); 801 if (bind)
802 result = thermal_zone_bind_cooling_device
803 (thermal, -1, cdev,
804 THERMAL_NO_LIMIT,
805 THERMAL_NO_LIMIT);
806 else
807 result = thermal_zone_unbind_cooling_device
808 (thermal, -1, cdev);
790 if (result) 809 if (result)
791 goto failed; 810 goto failed;
792 } 811 }
@@ -800,16 +819,14 @@ static int
800acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal, 819acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal,
801 struct thermal_cooling_device *cdev) 820 struct thermal_cooling_device *cdev)
802{ 821{
803 return acpi_thermal_cooling_device_cb(thermal, cdev, 822 return acpi_thermal_cooling_device_cb(thermal, cdev, true);
804 thermal_zone_bind_cooling_device);
805} 823}
806 824
807static int 825static int
808acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal, 826acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal,
809 struct thermal_cooling_device *cdev) 827 struct thermal_cooling_device *cdev)
810{ 828{
811 return acpi_thermal_cooling_device_cb(thermal, cdev, 829 return acpi_thermal_cooling_device_cb(thermal, cdev, false);
812 thermal_zone_unbind_cooling_device);
813} 830}
814 831
815static const struct thermal_zone_device_ops acpi_thermal_zone_ops = { 832static const struct thermal_zone_device_ops acpi_thermal_zone_ops = {
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
index 39abb150bdd4..a207466f4ba8 100644
--- a/drivers/platform/x86/acerhdf.c
+++ b/drivers/platform/x86/acerhdf.c
@@ -329,7 +329,8 @@ static int acerhdf_bind(struct thermal_zone_device *thermal,
329 if (cdev != cl_dev) 329 if (cdev != cl_dev)
330 return 0; 330 return 0;
331 331
332 if (thermal_zone_bind_cooling_device(thermal, 0, cdev)) { 332 if (thermal_zone_bind_cooling_device(thermal, 0, cdev,
333 THERMAL_NO_LIMIT, THERMAL_NO_LIMIT)) {
333 pr_err("error binding cooling dev\n"); 334 pr_err("error binding cooling dev\n");
334 return -EINVAL; 335 return -EINVAL;
335 } 336 }
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index d78c6dc6b00a..b04fe2c4b0d5 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -315,8 +315,9 @@ passive_store(struct device *dev, struct device_attribute *attr,
315 if (!strncmp("Processor", cdev->type, 315 if (!strncmp("Processor", cdev->type,
316 sizeof("Processor"))) 316 sizeof("Processor")))
317 thermal_zone_bind_cooling_device(tz, 317 thermal_zone_bind_cooling_device(tz,
318 THERMAL_TRIPS_NONE, 318 THERMAL_TRIPS_NONE, cdev,
319 cdev); 319 THERMAL_NO_LIMIT,
320 THERMAL_NO_LIMIT);
320 } 321 }
321 mutex_unlock(&thermal_list_lock); 322 mutex_unlock(&thermal_list_lock);
322 if (!tz->passive_delay) 323 if (!tz->passive_delay)
@@ -801,7 +802,8 @@ static void thermal_zone_device_check(struct work_struct *work)
801 */ 802 */
802int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, 803int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
803 int trip, 804 int trip,
804 struct thermal_cooling_device *cdev) 805 struct thermal_cooling_device *cdev,
806 unsigned long upper, unsigned long lower)
805{ 807{
806 struct thermal_cooling_device_instance *dev; 808 struct thermal_cooling_device_instance *dev;
807 struct thermal_cooling_device_instance *pos; 809 struct thermal_cooling_device_instance *pos;
@@ -825,6 +827,15 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
825 if (tz != pos1 || cdev != pos2) 827 if (tz != pos1 || cdev != pos2)
826 return -EINVAL; 828 return -EINVAL;
827 829
830 cdev->ops->get_max_state(cdev, &max_state);
831
832 /* lower default 0, upper default max_state */
833 lower = lower == THERMAL_NO_LIMIT ? 0 : lower;
834 upper = upper == THERMAL_NO_LIMIT ? max_state : upper;
835
836 if (lower > upper || upper > max_state)
837 return -EINVAL;
838
828 dev = 839 dev =
829 kzalloc(sizeof(struct thermal_cooling_device_instance), GFP_KERNEL); 840 kzalloc(sizeof(struct thermal_cooling_device_instance), GFP_KERNEL);
830 if (!dev) 841 if (!dev)
@@ -832,10 +843,8 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
832 dev->tz = tz; 843 dev->tz = tz;
833 dev->cdev = cdev; 844 dev->cdev = cdev;
834 dev->trip = trip; 845 dev->trip = trip;
835 846 dev->upper = upper;
836 cdev->ops->get_max_state(cdev, &max_state); 847 dev->lower = lower;
837 dev->upper = max_state;
838 dev->lower = 0;
839 848
840 result = get_idr(&tz->idr, &tz->lock, &dev->id); 849 result = get_idr(&tz->idr, &tz->lock, &dev->id);
841 if (result) 850 if (result)
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 4b94a61955df..5946a3b90bb2 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -75,6 +75,8 @@ struct thermal_cooling_device_ops {
75 int (*set_cur_state) (struct thermal_cooling_device *, unsigned long); 75 int (*set_cur_state) (struct thermal_cooling_device *, unsigned long);
76}; 76};
77 77
78#define THERMAL_NO_LIMIT -1UL /* no upper/lower limit requirement */
79
78#define THERMAL_TRIPS_NONE -1 80#define THERMAL_TRIPS_NONE -1
79#define THERMAL_MAX_TRIPS 12 81#define THERMAL_MAX_TRIPS 12
80#define THERMAL_NAME_LENGTH 20 82#define THERMAL_NAME_LENGTH 20
@@ -157,7 +159,8 @@ struct thermal_zone_device *thermal_zone_device_register(const char *, int, int,
157void thermal_zone_device_unregister(struct thermal_zone_device *); 159void thermal_zone_device_unregister(struct thermal_zone_device *);
158 160
159int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int, 161int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
160 struct thermal_cooling_device *); 162 struct thermal_cooling_device *,
163 unsigned long, unsigned long);
161int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int, 164int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int,
162 struct thermal_cooling_device *); 165 struct thermal_cooling_device *);
163void thermal_zone_device_update(struct thermal_zone_device *); 166void thermal_zone_device_update(struct thermal_zone_device *);