Commit 34471abf authored by Anson Huang's avatar Anson Huang Committed by Daniel Lezcano

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: default avatarAnson Huang <Anson.Huang@nxp.com>
Reviewed-by: default avatarDong Aisheng <aisheng.dong@nxp.com>
Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/1582330132-13461-2-git-send-email-Anson.Huang@nxp.com
parent 7dc6ffbd
...@@ -448,6 +448,50 @@ thermal_zone_of_add_sensor(struct device_node *zone, ...@@ -448,6 +448,50 @@ thermal_zone_of_add_sensor(struct device_node *zone,
return tzd; 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 * 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 * @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, ...@@ -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); sensor_np = of_node_get(dev->of_node);
for_each_available_child_of_node(np, child) { for_each_available_child_of_node(np, child) {
struct of_phandle_args sensor_specs;
int ret, id; int ret, id;
/* For now, thermal framework supports only 1 sensor per zone */ /* For now, thermal framework supports only 1 sensor per zone */
ret = of_parse_phandle_with_args(child, "thermal-sensors", ret = thermal_zone_of_get_sensor_id(child, sensor_np, &id);
"#thermal-sensor-cells",
0, &sensor_specs);
if (ret) if (ret)
continue; continue;
if (sensor_specs.args_count >= 1) { if (id == sensor_id) {
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) {
tzd = thermal_zone_of_add_sensor(child, sensor_np, tzd = thermal_zone_of_add_sensor(child, sensor_np,
data, ops); data, ops);
if (!IS_ERR(tzd)) if (!IS_ERR(tzd))
tzd->ops->set_mode(tzd, THERMAL_DEVICE_ENABLED); tzd->ops->set_mode(tzd, THERMAL_DEVICE_ENABLED);
of_node_put(sensor_specs.np);
of_node_put(child); of_node_put(child);
goto exit; goto exit;
} }
of_node_put(sensor_specs.np);
} }
exit: exit:
of_node_put(sensor_np); of_node_put(sensor_np);
......
...@@ -364,6 +364,9 @@ struct thermal_trip { ...@@ -364,6 +364,9 @@ struct thermal_trip {
/* Function declarations */ /* Function declarations */
#ifdef CONFIG_THERMAL_OF #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 * struct thermal_zone_device *
thermal_zone_of_sensor_register(struct device *dev, int id, void *data, thermal_zone_of_sensor_register(struct device *dev, int id, void *data,
const struct thermal_zone_of_device_ops *ops); const struct thermal_zone_of_device_ops *ops);
...@@ -375,6 +378,13 @@ struct thermal_zone_device *devm_thermal_zone_of_sensor_register( ...@@ -375,6 +378,13 @@ struct thermal_zone_device *devm_thermal_zone_of_sensor_register(
void devm_thermal_zone_of_sensor_unregister(struct device *dev, void devm_thermal_zone_of_sensor_unregister(struct device *dev,
struct thermal_zone_device *tz); struct thermal_zone_device *tz);
#else #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 * static inline struct thermal_zone_device *
thermal_zone_of_sensor_register(struct device *dev, int id, void *data, thermal_zone_of_sensor_register(struct device *dev, int id, void *data,
const struct thermal_zone_of_device_ops *ops) const struct thermal_zone_of_device_ops *ops)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment