Commit 7797ff42 authored by Yuantian Tang's avatar Yuantian Tang Committed by Eduardo Valentin

thermal: qoriq: add multiple sensors support

The QorIQ Layerscape SoC has several thermal sensors but the current
driver only supports one.

Massage the code to be sensor oriented and allow the support for
multiple sensors.
Signed-off-by: default avatarYuantian Tang <andy.tang@nxp.com>
Reviewed-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: default avatarEduardo Valentin <edubezval@gmail.com>
parent 250e2110
...@@ -59,14 +59,21 @@ struct qoriq_tmu_regs { ...@@ -59,14 +59,21 @@ struct qoriq_tmu_regs {
u32 ttr3cr; /* Temperature Range 3 Control Register */ u32 ttr3cr; /* Temperature Range 3 Control Register */
}; };
struct qoriq_tmu_data;
/* /*
* Thermal zone data * Thermal zone data
*/ */
struct qoriq_sensor {
struct thermal_zone_device *tzd;
struct qoriq_tmu_data *qdata;
int id;
};
struct qoriq_tmu_data { struct qoriq_tmu_data {
struct thermal_zone_device *tz;
struct qoriq_tmu_regs __iomem *regs; struct qoriq_tmu_regs __iomem *regs;
int sensor_id;
bool little_endian; bool little_endian;
struct qoriq_sensor *sensor[SITES_MAX];
}; };
static void tmu_write(struct qoriq_tmu_data *p, u32 val, void __iomem *addr) static void tmu_write(struct qoriq_tmu_data *p, u32 val, void __iomem *addr)
...@@ -87,48 +94,50 @@ static u32 tmu_read(struct qoriq_tmu_data *p, void __iomem *addr) ...@@ -87,48 +94,50 @@ static u32 tmu_read(struct qoriq_tmu_data *p, void __iomem *addr)
static int tmu_get_temp(void *p, int *temp) static int tmu_get_temp(void *p, int *temp)
{ {
struct qoriq_sensor *qsensor = p;
struct qoriq_tmu_data *qdata = qsensor->qdata;
u32 val; u32 val;
struct qoriq_tmu_data *data = p;
val = tmu_read(data, &data->regs->site[data->sensor_id].tritsr); val = tmu_read(qdata, &qdata->regs->site[qsensor->id].tritsr);
*temp = (val & 0xff) * 1000; *temp = (val & 0xff) * 1000;
return 0; return 0;
} }
static int qoriq_tmu_get_sensor_id(void) static const struct thermal_zone_of_device_ops tmu_tz_ops = {
{ .get_temp = tmu_get_temp,
int ret, id; };
struct of_phandle_args sensor_specs;
struct device_node *np, *sensor_np;
np = of_find_node_by_name(NULL, "thermal-zones");
if (!np)
return -ENODEV;
sensor_np = of_get_next_child(np, NULL);
ret = of_parse_phandle_with_args(sensor_np, "thermal-sensors",
"#thermal-sensor-cells",
0, &sensor_specs);
if (ret) {
of_node_put(np);
of_node_put(sensor_np);
return ret;
}
if (sensor_specs.args_count >= 1) { static int qoriq_tmu_register_tmu_zone(struct platform_device *pdev)
id = sensor_specs.args[0]; {
WARN(sensor_specs.args_count > 1, struct qoriq_tmu_data *qdata = platform_get_drvdata(pdev);
"%pOFn: too many cells in sensor specifier %d\n", int id, sites = 0;
sensor_specs.np, sensor_specs.args_count);
} else { for (id = 0; id < SITES_MAX; id++) {
id = 0; qdata->sensor[id] = devm_kzalloc(&pdev->dev,
sizeof(struct qoriq_sensor), GFP_KERNEL);
if (!qdata->sensor[id])
return -ENOMEM;
qdata->sensor[id]->id = id;
qdata->sensor[id]->qdata = qdata;
qdata->sensor[id]->tzd = devm_thermal_zone_of_sensor_register(
&pdev->dev, id, qdata->sensor[id], &tmu_tz_ops);
if (IS_ERR(qdata->sensor[id]->tzd)) {
if (PTR_ERR(qdata->sensor[id]->tzd) == -ENODEV)
continue;
else
return PTR_ERR(qdata->sensor[id]->tzd);
}
sites |= 0x1 << (15 - id);
} }
of_node_put(np); /* Enable monitoring */
of_node_put(sensor_np); if (sites != 0)
tmu_write(qdata, sites | TMR_ME | TMR_ALPF, &qdata->regs->tmr);
return id; return 0;
} }
static int qoriq_tmu_calibration(struct platform_device *pdev) static int qoriq_tmu_calibration(struct platform_device *pdev)
...@@ -178,16 +187,11 @@ static void qoriq_tmu_init_device(struct qoriq_tmu_data *data) ...@@ -178,16 +187,11 @@ static void qoriq_tmu_init_device(struct qoriq_tmu_data *data)
tmu_write(data, TMR_DISABLE, &data->regs->tmr); tmu_write(data, TMR_DISABLE, &data->regs->tmr);
} }
static const struct thermal_zone_of_device_ops tmu_tz_ops = {
.get_temp = tmu_get_temp,
};
static int qoriq_tmu_probe(struct platform_device *pdev) static int qoriq_tmu_probe(struct platform_device *pdev)
{ {
int ret; int ret;
struct qoriq_tmu_data *data; struct qoriq_tmu_data *data;
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
u32 site;
if (!np) { if (!np) {
dev_err(&pdev->dev, "Device OF-Node is NULL"); dev_err(&pdev->dev, "Device OF-Node is NULL");
...@@ -203,13 +207,6 @@ static int qoriq_tmu_probe(struct platform_device *pdev) ...@@ -203,13 +207,6 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
data->little_endian = of_property_read_bool(np, "little-endian"); data->little_endian = of_property_read_bool(np, "little-endian");
data->sensor_id = qoriq_tmu_get_sensor_id();
if (data->sensor_id < 0) {
dev_err(&pdev->dev, "Failed to get sensor id\n");
ret = -ENODEV;
goto err_iomap;
}
data->regs = of_iomap(np, 0); data->regs = of_iomap(np, 0);
if (!data->regs) { if (!data->regs) {
dev_err(&pdev->dev, "Failed to get memory region\n"); dev_err(&pdev->dev, "Failed to get memory region\n");
...@@ -223,20 +220,13 @@ static int qoriq_tmu_probe(struct platform_device *pdev) ...@@ -223,20 +220,13 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
if (ret < 0) if (ret < 0)
goto err_tmu; goto err_tmu;
data->tz = devm_thermal_zone_of_sensor_register(&pdev->dev, ret = qoriq_tmu_register_tmu_zone(pdev);
data->sensor_id, if (ret < 0) {
data, &tmu_tz_ops); dev_err(&pdev->dev, "Failed to register sensors\n");
if (IS_ERR(data->tz)) { ret = -ENODEV;
ret = PTR_ERR(data->tz); goto err_iomap;
dev_err(&pdev->dev,
"Failed to register thermal zone device %d\n", ret);
goto err_tmu;
} }
/* Enable monitoring */
site = 0x1 << (15 - data->sensor_id);
tmu_write(data, site | TMR_ME | TMR_ALPF, &data->regs->tmr);
return 0; return 0;
err_tmu: err_tmu:
......
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