thermal: of-thermal: add API for getting sensor ID from DT

This patch adds new API thermal_zone_of_get_sensor_id() to
provide the feature of getting sensor ID from DT thermal
zone's node. It's useful for thermal driver to register the
specific thermal zone devices from DT in a common way.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
Reviewed-by: Dong Aisheng <aisheng.dong@nxp.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/1582330132-13461-2-git-send-email-Anson.Huang@nxp.com
This commit is contained in:
Anson Huang 2020-02-22 08:08:49 +08:00 committed by Daniel Lezcano
parent 7dc6ffbd79
commit 34471abfc8
2 changed files with 56 additions and 16 deletions

View file

@ -448,6 +448,50 @@ thermal_zone_of_add_sensor(struct device_node *zone,
return tzd;
}
/**
* thermal_zone_of_get_sensor_id - get sensor ID from a DT thermal zone
* @tz_np: a valid thermal zone device node.
* @sensor_np: a sensor node of a valid sensor device.
* @id: the sensor ID returned if success.
*
* This function will get sensor ID from a given thermal zone node and
* the sensor node must match the temperature provider @sensor_np.
*
* Return: 0 on success, proper error code otherwise.
*/
int thermal_zone_of_get_sensor_id(struct device_node *tz_np,
struct device_node *sensor_np,
u32 *id)
{
struct of_phandle_args sensor_specs;
int ret;
ret = of_parse_phandle_with_args(tz_np,
"thermal-sensors",
"#thermal-sensor-cells",
0,
&sensor_specs);
if (ret)
return ret;
if (sensor_specs.np != sensor_np) {
of_node_put(sensor_specs.np);
return -ENODEV;
}
if (sensor_specs.args_count > 1)
pr_warn("%pOFn: too many cells in sensor specifier %d\n",
sensor_specs.np, sensor_specs.args_count);
*id = sensor_specs.args_count ? sensor_specs.args[0] : 0;
of_node_put(sensor_specs.np);
return 0;
}
EXPORT_SYMBOL_GPL(thermal_zone_of_get_sensor_id);
/**
* thermal_zone_of_sensor_register - registers a sensor to a DT thermal zone
* @dev: a valid struct device pointer of a sensor device. Must contain
@ -499,36 +543,22 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data,
sensor_np = of_node_get(dev->of_node);
for_each_available_child_of_node(np, child) {
struct of_phandle_args sensor_specs;
int ret, id;
/* For now, thermal framework supports only 1 sensor per zone */
ret = of_parse_phandle_with_args(child, "thermal-sensors",
"#thermal-sensor-cells",
0, &sensor_specs);
ret = thermal_zone_of_get_sensor_id(child, sensor_np, &id);
if (ret)
continue;
if (sensor_specs.args_count >= 1) {
id = sensor_specs.args[0];
WARN(sensor_specs.args_count > 1,
"%pOFn: too many cells in sensor specifier %d\n",
sensor_specs.np, sensor_specs.args_count);
} else {
id = 0;
}
if (sensor_specs.np == sensor_np && id == sensor_id) {
if (id == sensor_id) {
tzd = thermal_zone_of_add_sensor(child, sensor_np,
data, ops);
if (!IS_ERR(tzd))
tzd->ops->set_mode(tzd, THERMAL_DEVICE_ENABLED);
of_node_put(sensor_specs.np);
of_node_put(child);
goto exit;
}
of_node_put(sensor_specs.np);
}
exit:
of_node_put(sensor_np);

View file

@ -364,6 +364,9 @@ struct thermal_trip {
/* Function declarations */
#ifdef CONFIG_THERMAL_OF
int thermal_zone_of_get_sensor_id(struct device_node *tz_np,
struct device_node *sensor_np,
u32 *id);
struct thermal_zone_device *
thermal_zone_of_sensor_register(struct device *dev, int id, void *data,
const struct thermal_zone_of_device_ops *ops);
@ -375,6 +378,13 @@ struct thermal_zone_device *devm_thermal_zone_of_sensor_register(
void devm_thermal_zone_of_sensor_unregister(struct device *dev,
struct thermal_zone_device *tz);
#else
static int thermal_zone_of_get_sensor_id(struct device_node *tz_np,
struct device_node *sensor_np,
u32 *id)
{
return -ENOENT;
}
static inline struct thermal_zone_device *
thermal_zone_of_sensor_register(struct device *dev, int id, void *data,
const struct thermal_zone_of_device_ops *ops)