Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  thermal_helpers.c - helper functions to handle thermal devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Copyright (C) 2016 Eduardo Valentin <edubezval@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *  Highly based on original thermal_core.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *  Copyright (C) 2008 Intel Corp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *  Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *  Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <trace/events/thermal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include "thermal_core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) int get_tz_trend(struct thermal_zone_device *tz, int trip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	enum thermal_trend trend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	if (tz->emul_temperature || !tz->ops->get_trend ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	    tz->ops->get_trend(tz, trip, &trend)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 		if (tz->temperature > tz->last_temperature)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 			trend = THERMAL_TREND_RAISING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 		else if (tz->temperature < tz->last_temperature)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 			trend = THERMAL_TREND_DROPPING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 			trend = THERMAL_TREND_STABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	return trend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) EXPORT_SYMBOL(get_tz_trend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) struct thermal_instance *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) get_thermal_instance(struct thermal_zone_device *tz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		     struct thermal_cooling_device *cdev, int trip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	struct thermal_instance *pos = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	struct thermal_instance *target_instance = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	mutex_lock(&tz->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	mutex_lock(&cdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	list_for_each_entry(pos, &tz->thermal_instances, tz_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 			target_instance = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	mutex_unlock(&cdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	mutex_unlock(&tz->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	return target_instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) EXPORT_SYMBOL(get_thermal_instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  * thermal_zone_get_temp() - returns the temperature of a thermal zone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  * @tz: a valid pointer to a struct thermal_zone_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  * @temp: a valid pointer to where to store the resulting temperature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  * When a valid thermal zone reference is passed, it will fetch its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  * temperature and fill @temp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  * Return: On success returns 0, an error code otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	int crit_temp = INT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	enum thermal_trip_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	if (!tz || IS_ERR(tz) || !tz->ops->get_temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	mutex_lock(&tz->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	ret = tz->ops->get_temp(tz, temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	if (IS_ENABLED(CONFIG_THERMAL_EMULATION) && tz->emul_temperature) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		for (count = 0; count < tz->trips; count++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 			ret = tz->ops->get_trip_type(tz, count, &type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 			if (!ret && type == THERMAL_TRIP_CRITICAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 				ret = tz->ops->get_trip_temp(tz, count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 						&crit_temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		 * Only allow emulating a temperature when the real temperature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		 * is below the critical temperature so that the emulation code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		 * cannot hide critical conditions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		if (!ret && *temp < crit_temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 			*temp = tz->emul_temperature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	mutex_unlock(&tz->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) EXPORT_SYMBOL_GPL(thermal_zone_get_temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  * thermal_zone_set_trips - Computes the next trip points for the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  * @tz: a pointer to a thermal zone device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  * The function computes the next temperature boundaries by browsing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * the trip points. The result is the closer low and high trip points
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  * to the current temperature. These values are passed to the backend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * driver to let it set its own notification mechanism (usually an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * interrupt).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  * It does not return a value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) void thermal_zone_set_trips(struct thermal_zone_device *tz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	int low = -INT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	int high = INT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	int trip_temp, hysteresis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	mutex_lock(&tz->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	if (!tz->ops->set_trips || !tz->ops->get_trip_hyst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	for (i = 0; i < tz->trips; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		int trip_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		tz->ops->get_trip_temp(tz, i, &trip_temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		tz->ops->get_trip_hyst(tz, i, &hysteresis);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		trip_low = trip_temp - hysteresis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		if (trip_low < tz->temperature && trip_low > low)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 			low = trip_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		if (trip_temp > tz->temperature && trip_temp < high)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			high = trip_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	/* No need to change trip points */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	if (tz->prev_low_trip == low && tz->prev_high_trip == high)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	tz->prev_low_trip = low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	tz->prev_high_trip = high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	dev_dbg(&tz->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		"new temperature boundaries: %d < x < %d\n", low, high);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	 * Set a temperature window. When this window is left the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	 * must inform the thermal core via thermal_zone_device_update.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	ret = tz->ops->set_trips(tz, low, high);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		dev_err(&tz->device, "Failed to set trips: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	mutex_unlock(&tz->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static void thermal_cdev_set_cur_state(struct thermal_cooling_device *cdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 				       int target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	if (cdev->ops->set_cur_state(cdev, target))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	thermal_notify_cdev_state_update(cdev->id, target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	thermal_cooling_device_stats_update(cdev, target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) void thermal_cdev_update(struct thermal_cooling_device *cdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	struct thermal_instance *instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	unsigned long target = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	mutex_lock(&cdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	/* cooling device is updated*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	if (cdev->updated) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		mutex_unlock(&cdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	/* Make sure cdev enters the deepest cooling state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		dev_dbg(&cdev->device, "zone%d->target=%lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 			instance->tz->id, instance->target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		if (instance->target == THERMAL_NO_TARGET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		if (instance->target > target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 			target = instance->target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	thermal_cdev_set_cur_state(cdev, target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	cdev->updated = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	mutex_unlock(&cdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	trace_cdev_update(cdev, target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	dev_dbg(&cdev->device, "set to state %lu\n", target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) EXPORT_SYMBOL(thermal_cdev_update);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)  * thermal_zone_get_slope - return the slope attribute of the thermal zone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)  * @tz: thermal zone device with the slope attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)  * Return: If the thermal zone device has a slope attribute, return it, else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)  * return 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) int thermal_zone_get_slope(struct thermal_zone_device *tz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	if (tz && tz->tzp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		return tz->tzp->slope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) EXPORT_SYMBOL_GPL(thermal_zone_get_slope);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)  * thermal_zone_get_offset - return the offset attribute of the thermal zone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)  * @tz: thermal zone device with the offset attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)  * Return: If the thermal zone device has a offset attribute, return it, else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)  * return 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) int thermal_zone_get_offset(struct thermal_zone_device *tz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	if (tz && tz->tzp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		return tz->tzp->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) EXPORT_SYMBOL_GPL(thermal_zone_get_offset);