|
@@ -37,12 +37,11 @@ struct exynos_thermal_zone {
|
|
|
bool bind;
|
|
|
};
|
|
|
|
|
|
-static struct exynos_thermal_zone *th_zone;
|
|
|
-
|
|
|
/* Get mode callback functions for thermal zone */
|
|
|
static int exynos_get_mode(struct thermal_zone_device *thermal,
|
|
|
enum thermal_device_mode *mode)
|
|
|
{
|
|
|
+ struct exynos_thermal_zone *th_zone = thermal->devdata;
|
|
|
if (th_zone)
|
|
|
*mode = th_zone->mode;
|
|
|
return 0;
|
|
@@ -52,25 +51,26 @@ static int exynos_get_mode(struct thermal_zone_device *thermal,
|
|
|
static int exynos_set_mode(struct thermal_zone_device *thermal,
|
|
|
enum thermal_device_mode mode)
|
|
|
{
|
|
|
- if (!th_zone->therm_dev) {
|
|
|
+ struct exynos_thermal_zone *th_zone = thermal->devdata;
|
|
|
+ if (!th_zone) {
|
|
|
pr_notice("thermal zone not registered\n");
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- mutex_lock(&th_zone->therm_dev->lock);
|
|
|
+ mutex_lock(&thermal->lock);
|
|
|
|
|
|
if (mode == THERMAL_DEVICE_ENABLED &&
|
|
|
!th_zone->sensor_conf->trip_data.trigger_falling)
|
|
|
- th_zone->therm_dev->polling_delay = IDLE_INTERVAL;
|
|
|
+ thermal->polling_delay = IDLE_INTERVAL;
|
|
|
else
|
|
|
- th_zone->therm_dev->polling_delay = 0;
|
|
|
+ thermal->polling_delay = 0;
|
|
|
|
|
|
- mutex_unlock(&th_zone->therm_dev->lock);
|
|
|
+ mutex_unlock(&thermal->lock);
|
|
|
|
|
|
th_zone->mode = mode;
|
|
|
- thermal_zone_device_update(th_zone->therm_dev);
|
|
|
+ thermal_zone_device_update(thermal);
|
|
|
pr_info("thermal polling set for duration=%d msec\n",
|
|
|
- th_zone->therm_dev->polling_delay);
|
|
|
+ thermal->polling_delay);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -97,6 +97,8 @@ static int exynos_get_trip_type(struct thermal_zone_device *thermal, int trip,
|
|
|
static int exynos_get_trip_temp(struct thermal_zone_device *thermal, int trip,
|
|
|
unsigned long *temp)
|
|
|
{
|
|
|
+ struct exynos_thermal_zone *th_zone = thermal->devdata;
|
|
|
+
|
|
|
if (trip < GET_TRIP(MONITOR_ZONE) || trip > GET_TRIP(PANIC_ZONE))
|
|
|
return -EINVAL;
|
|
|
|
|
@@ -123,6 +125,7 @@ static int exynos_bind(struct thermal_zone_device *thermal,
|
|
|
{
|
|
|
int ret = 0, i, tab_size, level;
|
|
|
struct freq_clip_table *tab_ptr, *clip_data;
|
|
|
+ struct exynos_thermal_zone *th_zone = thermal->devdata;
|
|
|
struct thermal_sensor_conf *data = th_zone->sensor_conf;
|
|
|
|
|
|
tab_ptr = (struct freq_clip_table *)data->cooling_data.freq_data;
|
|
@@ -169,6 +172,7 @@ static int exynos_unbind(struct thermal_zone_device *thermal,
|
|
|
struct thermal_cooling_device *cdev)
|
|
|
{
|
|
|
int ret = 0, i, tab_size;
|
|
|
+ struct exynos_thermal_zone *th_zone = thermal->devdata;
|
|
|
struct thermal_sensor_conf *data = th_zone->sensor_conf;
|
|
|
|
|
|
if (th_zone->bind == false)
|
|
@@ -211,6 +215,7 @@ static int exynos_unbind(struct thermal_zone_device *thermal,
|
|
|
static int exynos_get_temp(struct thermal_zone_device *thermal,
|
|
|
unsigned long *temp)
|
|
|
{
|
|
|
+ struct exynos_thermal_zone *th_zone = thermal->devdata;
|
|
|
void *data;
|
|
|
|
|
|
if (!th_zone->sensor_conf) {
|
|
@@ -230,6 +235,7 @@ static int exynos_set_emul_temp(struct thermal_zone_device *thermal,
|
|
|
{
|
|
|
void *data;
|
|
|
int ret = -EINVAL;
|
|
|
+ struct exynos_thermal_zone *th_zone = thermal->devdata;
|
|
|
|
|
|
if (!th_zone->sensor_conf) {
|
|
|
pr_info("Temperature sensor not initialised\n");
|
|
@@ -277,14 +283,22 @@ static struct thermal_zone_device_ops const exynos_dev_ops = {
|
|
|
* This function may be called from interrupt based temperature sensor
|
|
|
* when threshold is changed.
|
|
|
*/
|
|
|
-void exynos_report_trigger(void)
|
|
|
+void exynos_report_trigger(struct thermal_sensor_conf *conf)
|
|
|
{
|
|
|
unsigned int i;
|
|
|
char data[10];
|
|
|
char *envp[] = { data, NULL };
|
|
|
+ struct exynos_thermal_zone *th_zone;
|
|
|
|
|
|
- if (!th_zone || !th_zone->therm_dev)
|
|
|
+ if (!conf || !conf->pzone_data) {
|
|
|
+ pr_err("Invalid temperature sensor configuration data\n");
|
|
|
return;
|
|
|
+ }
|
|
|
+
|
|
|
+ th_zone = conf->pzone_data;
|
|
|
+ if (th_zone->therm_dev)
|
|
|
+ return;
|
|
|
+
|
|
|
if (th_zone->bind == false) {
|
|
|
for (i = 0; i < th_zone->cool_dev_size; i++) {
|
|
|
if (!th_zone->cool_dev[i])
|
|
@@ -322,6 +336,7 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
|
|
|
{
|
|
|
int ret;
|
|
|
struct cpumask mask_val;
|
|
|
+ struct exynos_thermal_zone *th_zone;
|
|
|
|
|
|
if (!sensor_conf || !sensor_conf->read_temperature) {
|
|
|
pr_err("Temperature sensor not initialised\n");
|
|
@@ -343,7 +358,7 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
|
|
|
th_zone->cool_dev_size++;
|
|
|
|
|
|
th_zone->therm_dev = thermal_zone_device_register(sensor_conf->name,
|
|
|
- EXYNOS_ZONE_COUNT, 0, NULL, &exynos_dev_ops, NULL, 0,
|
|
|
+ EXYNOS_ZONE_COUNT, 0, th_zone, &exynos_dev_ops, NULL, 0,
|
|
|
sensor_conf->trip_data.trigger_falling ?
|
|
|
0 : IDLE_INTERVAL);
|
|
|
|
|
@@ -353,23 +368,29 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf)
|
|
|
goto err_unregister;
|
|
|
}
|
|
|
th_zone->mode = THERMAL_DEVICE_ENABLED;
|
|
|
+ sensor_conf->pzone_data = th_zone;
|
|
|
|
|
|
pr_info("Exynos: Kernel Thermal management registered\n");
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
err_unregister:
|
|
|
- exynos_unregister_thermal();
|
|
|
+ exynos_unregister_thermal(sensor_conf);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
/* Un-Register with the in-kernel thermal management */
|
|
|
-void exynos_unregister_thermal(void)
|
|
|
+void exynos_unregister_thermal(struct thermal_sensor_conf *sensor_conf)
|
|
|
{
|
|
|
int i;
|
|
|
+ struct exynos_thermal_zone *th_zone;
|
|
|
|
|
|
- if (!th_zone)
|
|
|
+ if (!sensor_conf || !sensor_conf->pzone_data) {
|
|
|
+ pr_err("Invalid temperature sensor configuration data\n");
|
|
|
return;
|
|
|
+ }
|
|
|
+
|
|
|
+ th_zone = sensor_conf->pzone_data;
|
|
|
|
|
|
if (th_zone->therm_dev)
|
|
|
thermal_zone_device_unregister(th_zone->therm_dev);
|