summaryrefslogtreecommitdiff
path: root/drivers/thermal/thermal_of.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/thermal/thermal_of.c')
-rw-r--r--drivers/thermal/thermal_of.c201
1 files changed, 111 insertions, 90 deletions
diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c
index b65d435cb92f..802c30b72a92 100644
--- a/drivers/thermal/thermal_of.c
+++ b/drivers/thermal/thermal_of.c
@@ -118,12 +118,7 @@ static int of_thermal_set_trips(struct thermal_zone_device *tz,
*/
int of_thermal_get_ntrips(struct thermal_zone_device *tz)
{
- struct __thermal_zone *data = tz->devdata;
-
- if (!data || IS_ERR(data))
- return -ENODEV;
-
- return data->ntrips;
+ return tz->num_trips;
}
EXPORT_SYMBOL_GPL(of_thermal_get_ntrips);
@@ -139,9 +134,7 @@ EXPORT_SYMBOL_GPL(of_thermal_get_ntrips);
*/
bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, int trip)
{
- struct __thermal_zone *data = tz->devdata;
-
- if (!data || trip >= data->ntrips || trip < 0)
+ if (trip >= tz->num_trips || trip < 0)
return false;
return true;
@@ -161,12 +154,7 @@ EXPORT_SYMBOL_GPL(of_thermal_is_trip_valid);
const struct thermal_trip *
of_thermal_get_trip_points(struct thermal_zone_device *tz)
{
- struct __thermal_zone *data = tz->devdata;
-
- if (!data)
- return NULL;
-
- return data->trips;
+ return tz->trips;
}
EXPORT_SYMBOL_GPL(of_thermal_get_trip_points);
@@ -281,12 +269,10 @@ static int of_thermal_unbind(struct thermal_zone_device *thermal,
static int of_thermal_get_trip_type(struct thermal_zone_device *tz, int trip,
enum thermal_trip_type *type)
{
- struct __thermal_zone *data = tz->devdata;
-
- if (trip >= data->ntrips || trip < 0)
+ if (trip >= tz->num_trips || trip < 0)
return -EDOM;
- *type = data->trips[trip].type;
+ *type = tz->trips[trip].type;
return 0;
}
@@ -294,12 +280,10 @@ static int of_thermal_get_trip_type(struct thermal_zone_device *tz, int trip,
static int of_thermal_get_trip_temp(struct thermal_zone_device *tz, int trip,
int *temp)
{
- struct __thermal_zone *data = tz->devdata;
-
- if (trip >= data->ntrips || trip < 0)
+ if (trip >= tz->num_trips || trip < 0)
return -EDOM;
- *temp = data->trips[trip].temperature;
+ *temp = tz->trips[trip].temperature;
return 0;
}
@@ -309,7 +293,7 @@ static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip,
{
struct __thermal_zone *data = tz->devdata;
- if (trip >= data->ntrips || trip < 0)
+ if (trip >= tz->num_trips || trip < 0)
return -EDOM;
if (data->ops && data->ops->set_trip_temp) {
@@ -321,7 +305,7 @@ static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip,
}
/* thermal framework should take care of data->mask & (1 << trip) */
- data->trips[trip].temperature = temp;
+ tz->trips[trip].temperature = temp;
return 0;
}
@@ -329,12 +313,10 @@ static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip,
static int of_thermal_get_trip_hyst(struct thermal_zone_device *tz, int trip,
int *hyst)
{
- struct __thermal_zone *data = tz->devdata;
-
- if (trip >= data->ntrips || trip < 0)
+ if (trip >= tz->num_trips || trip < 0)
return -EDOM;
- *hyst = data->trips[trip].hysteresis;
+ *hyst = tz->trips[trip].hysteresis;
return 0;
}
@@ -342,13 +324,11 @@ static int of_thermal_get_trip_hyst(struct thermal_zone_device *tz, int trip,
static int of_thermal_set_trip_hyst(struct thermal_zone_device *tz, int trip,
int hyst)
{
- struct __thermal_zone *data = tz->devdata;
-
- if (trip >= data->ntrips || trip < 0)
+ if (trip >= tz->num_trips || trip < 0)
return -EDOM;
/* thermal framework should take care of data->mask & (1 << trip) */
- data->trips[trip].hysteresis = hyst;
+ tz->trips[trip].hysteresis = hyst;
return 0;
}
@@ -356,12 +336,11 @@ static int of_thermal_set_trip_hyst(struct thermal_zone_device *tz, int trip,
static int of_thermal_get_crit_temp(struct thermal_zone_device *tz,
int *temp)
{
- struct __thermal_zone *data = tz->devdata;
int i;
- for (i = 0; i < data->ntrips; i++)
- if (data->trips[i].type == THERMAL_TRIP_CRITICAL) {
- *temp = data->trips[i].temperature;
+ for (i = 0; i < tz->num_trips; i++)
+ if (tz->trips[i].type == THERMAL_TRIP_CRITICAL) {
+ *temp = tz->trips[i].temperature;
return 0;
}
@@ -671,6 +650,35 @@ EXPORT_SYMBOL_GPL(devm_thermal_zone_of_sensor_unregister);
/*** functions parsing device tree nodes ***/
+static int of_find_trip_id(struct device_node *np, struct device_node *trip)
+{
+ struct device_node *trips;
+ struct device_node *t;
+ int i = 0;
+
+ trips = of_get_child_by_name(np, "trips");
+ if (!trips) {
+ pr_err("Failed to find 'trips' node\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Find the trip id point associated with the cooling device map
+ */
+ for_each_child_of_node(trips, t) {
+
+ if (t == trip)
+ goto out;
+ i++;
+ }
+
+ i = -ENXIO;
+out:
+ of_node_put(trips);
+
+ return i;
+}
+
/**
* thermal_of_populate_bind_params - parse and fill cooling map data
* @np: DT node containing a cooling-map node
@@ -685,15 +693,15 @@ EXPORT_SYMBOL_GPL(devm_thermal_zone_of_sensor_unregister);
*
* Return: 0 on success, proper error code otherwise
*/
-static int thermal_of_populate_bind_params(struct device_node *np,
- struct __thermal_bind_params *__tbp,
- struct thermal_trip *trips,
- int ntrips)
+static int thermal_of_populate_bind_params(struct device_node *tz_np,
+ struct device_node *np,
+ struct __thermal_bind_params *__tbp)
{
struct of_phandle_args cooling_spec;
struct __thermal_cooling_bind_param *__tcbp;
struct device_node *trip;
int ret, i, count;
+ int trip_id;
u32 prop;
/* Default weight. Usage is optional */
@@ -708,18 +716,14 @@ static int thermal_of_populate_bind_params(struct device_node *np,
return -ENODEV;
}
- /* match using device_node */
- for (i = 0; i < ntrips; i++)
- if (trip == trips[i].np) {
- __tbp->trip_id = i;
- break;
- }
-
- if (i == ntrips) {
- ret = -ENODEV;
+ trip_id = of_find_trip_id(tz_np, trip);
+ if (trip_id < 0) {
+ ret = trip_id;
goto end;
}
+ __tbp->trip_id = trip_id;
+
count = of_count_phandle_with_args(np, "cooling-device",
"#cooling-cells");
if (count <= 0) {
@@ -843,13 +847,56 @@ static int thermal_of_populate_trip(struct device_node *np,
return ret;
}
- /* Required for cooling map matching */
- trip->np = np;
- of_node_get(np);
-
return 0;
}
+static struct thermal_trip *thermal_of_trips_init(struct device_node *np, int *ntrips)
+{
+ struct thermal_trip *tt;
+ struct device_node *trips, *trip;
+ int ret, count;
+
+ trips = of_get_child_by_name(np, "trips");
+ if (!trips) {
+ pr_err("Failed to find 'trips' node\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ count = of_get_child_count(trips);
+ if (!count) {
+ pr_err("No trip point defined\n");
+ ret = -EINVAL;
+ goto out_of_node_put;
+ }
+
+ tt = kzalloc(sizeof(*tt) * count, GFP_KERNEL);
+ if (!tt) {
+ ret = -ENOMEM;
+ goto out_of_node_put;
+ }
+
+ *ntrips = count;
+
+ count = 0;
+ for_each_child_of_node(trips, trip) {
+ ret = thermal_of_populate_trip(trip, &tt[count++]);
+ if (ret)
+ goto out_kfree;
+ }
+
+ of_node_put(trips);
+
+ return tt;
+
+out_kfree:
+ kfree(tt);
+ *ntrips = 0;
+out_of_node_put:
+ of_node_put(trips);
+
+ return ERR_PTR(ret);
+}
+
/**
* thermal_of_build_thermal_zone - parse and fill one thermal zone data
* @np: DT node containing a thermal zone node
@@ -909,32 +956,12 @@ __init *thermal_of_build_thermal_zone(struct device_node *np)
tz->offset = 0;
}
- /* trips */
- child = of_get_child_by_name(np, "trips");
-
- /* No trips provided */
- if (!child)
+ tz->trips = thermal_of_trips_init(np, &tz->ntrips);
+ if (IS_ERR(tz->trips)) {
+ ret = PTR_ERR(tz->trips);
goto finish;
-
- tz->ntrips = of_get_child_count(child);
- if (tz->ntrips == 0) /* must have at least one child */
- goto finish;
-
- tz->trips = kcalloc(tz->ntrips, sizeof(*tz->trips), GFP_KERNEL);
- if (!tz->trips) {
- ret = -ENOMEM;
- goto free_tz;
}
- i = 0;
- for_each_child_of_node(child, gchild) {
- ret = thermal_of_populate_trip(gchild, &tz->trips[i++]);
- if (ret)
- goto free_trips;
- }
-
- of_node_put(child);
-
/* cooling-maps */
child = of_get_child_by_name(np, "cooling-maps");
@@ -954,10 +981,11 @@ __init *thermal_of_build_thermal_zone(struct device_node *np)
i = 0;
for_each_child_of_node(child, gchild) {
- ret = thermal_of_populate_bind_params(gchild, &tz->tbps[i++],
- tz->trips, tz->ntrips);
- if (ret)
+ ret = thermal_of_populate_bind_params(np, gchild, &tz->tbps[i++]);
+ if (ret) {
+ of_node_put(gchild);
goto free_tbps;
+ }
}
finish:
@@ -978,10 +1006,7 @@ free_tbps:
kfree(tz->tbps);
free_trips:
- for (i = 0; i < tz->ntrips; i++)
- of_node_put(tz->trips[i].np);
kfree(tz->trips);
- of_node_put(gchild);
free_tz:
kfree(tz);
of_node_put(child);
@@ -1004,8 +1029,6 @@ static __init void of_thermal_free_zone(struct __thermal_zone *tz)
}
kfree(tz->tbps);
- for (i = 0; i < tz->ntrips; i++)
- of_node_put(tz->trips[i].np);
kfree(tz->trips);
kfree(tz);
}
@@ -1103,11 +1126,9 @@ int __init of_parse_thermal_zones(void)
tzp->slope = tz->slope;
tzp->offset = tz->offset;
- zone = thermal_zone_device_register(child->name, tz->ntrips,
- mask, tz,
- ops, tzp,
- tz->passive_delay,
- tz->polling_delay);
+ zone = thermal_zone_device_register_with_trips(child->name, tz->trips, tz->ntrips,
+ mask, tz, ops, tzp, tz->passive_delay,
+ tz->polling_delay);
if (IS_ERR(zone)) {
pr_err("Failed to build %pOFn zone %ld\n", child,
PTR_ERR(zone));