[PATCH V2 1/2] dt-bindings: Add thermal zone to bcm2835-thermal example
Eduardo Valentin
edubezval at gmail.com
Sat Feb 18 17:13:29 PST 2017
On Mon, Feb 13, 2017 at 01:42:11PM -0800, Eric Anholt wrote:
> Stefan Wahren <stefan.wahren at i2se.com> writes:
>
> > Add a thermal zone in order to make the example complete.
> >
> > Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
>
> This looks fine to me. Eduardo, will this be enough to get the driver
> in?
Well, yes, but the driver needs to support the descriptors by
registering to of-thermal. But that would actually simplify the driver
as follows (patch on bcm2835 patch v9, so it supports the descriptors in
this thread):
------------------------8------------------------
diff --git a/drivers/thermal/bcm2835_thermal.c b/drivers/thermal/bcm2835_thermal.c
index 5e2fea9..ffcf847 100644
--- a/drivers/thermal/bcm2835_thermal.c
+++ b/drivers/thermal/bcm2835_thermal.c
@@ -61,14 +61,8 @@
#define BCM2835_TS_TSENSSTAT_VALID BIT(10)
#define BCM2835_TS_TSENSSTAT_INTERRUPT BIT(11)
-struct bcm2835_thermal_info {
- int offset;
- int slope;
- int trip_temp;
-};
-
struct bcm2835_thermal_data {
- const struct bcm2835_thermal_info *info;
+ struct thermal_zone_device *tz;
void __iomem *regs;
struct clk *clk;
struct dentry *debugfsdir;
@@ -92,40 +86,9 @@ static int bcm2835_thermal_temp2adc(int temp, int offset, int slope)
return temp;
}
-static int bcm2835_thermal_get_trip_type(
- struct thermal_zone_device *tz, int trip,
- enum thermal_trip_type *type)
+static int bcm2835_thermal_get_temp(void *d, int *temp)
{
- *type = THERMAL_TRIP_CRITICAL;
- return 0;
-}
-
-static int bcm2835_thermal_get_trip_temp(
- struct thermal_zone_device *tz, int trip, int *temp)
-{
- struct bcm2835_thermal_data *data = tz->devdata;
- u32 val = readl(data->regs + BCM2835_TS_TSENSCTL);
-
- /* get the THOLD bits */
- val &= BCM2835_TS_TSENSCTL_THOLD_MASK;
- val >>= BCM2835_TS_TSENSCTL_THOLD_SHIFT;
-
- /* if it is zero then use the info value */
- if (val)
- *temp = bcm2835_thermal_adc2temp(
- val,
- thermal_zone_get_offset(tz),
- thermal_zone_get_slope(tz));
- else
- *temp = data->info->trip_temp;
-
- return 0;
-}
-
-static int bcm2835_thermal_get_temp(struct thermal_zone_device *tz,
- int *temp)
-{
- struct bcm2835_thermal_data *data = tz->devdata;
+ struct bcm2835_thermal_data *data = d;
u32 val = readl(data->regs + BCM2835_TS_TSENSSTAT);
if (!(val & BCM2835_TS_TSENSSTAT_VALID))
@@ -135,8 +98,8 @@ static int bcm2835_thermal_get_temp(struct thermal_zone_device *tz,
*temp = bcm2835_thermal_adc2temp(
val,
- thermal_zone_get_offset(tz),
- thermal_zone_get_slope(tz));
+ thermal_zone_get_offset(data->tz),
+ thermal_zone_get_slope(data->tz));
return 0;
}
@@ -174,10 +137,8 @@ static void bcm2835_thermal_debugfs(struct platform_device *pdev)
data->debugfsdir, regset);
}
-static struct thermal_zone_device_ops bcm2835_thermal_ops = {
+static struct thermal_zone_of_device_ops bcm2835_thermal_ops = {
.get_temp = bcm2835_thermal_get_temp,
- .get_trip_temp = bcm2835_thermal_get_trip_temp,
- .get_trip_type = bcm2835_thermal_get_trip_type,
};
static const struct of_device_id bcm2835_thermal_of_match_table[];
@@ -186,10 +147,9 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
const struct of_device_id *match;
struct thermal_zone_device *tz;
struct thermal_zone_params *tzp;
- const struct bcm2835_thermal_info *ti;
struct bcm2835_thermal_data *data;
struct resource *res;
- int err;
+ int err = 0;
u32 val;
unsigned long rate;
@@ -205,10 +165,6 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
&pdev->dev);
if (!match)
return -EINVAL;
- ti = match->data;
- data->info = ti;
- tzp->slope = ti->slope;
- tzp->offset = ti->offset;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
data->regs = devm_ioremap_resource(&pdev->dev, res);
@@ -236,6 +192,17 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
"Clock %pCn running at %pCr Hz is outside of the recommended range: 1.92 to 5MHz\n",
data->clk, data->clk);
+ /* register of thermal sensor and get info from DT */
+ tz = thermal_zone_of_sensor_register(&pdev->dev, 0, data,
+ &bcm2835_thermal_ops);
+ if (IS_ERR(tz)) {
+ err = PTR_ERR(tz);
+ dev_err(&pdev->dev,
+ "Failed to register the thermal device: %d\n",
+ err);
+ goto err_clk;
+ }
+
/*
* right now the FW does set up the HW-block, so we are not
* touching the configuration registers.
@@ -244,6 +211,23 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
*/
val = readl(data->regs + BCM2835_TS_TSENSCTL);
if (!(val & BCM2835_TS_TSENSCTL_RSTB)) {
+ int trip_temp, offset, slope;
+
+ slope = thermal_zone_get_slope(tz);
+ offset = thermal_zone_get_offset(tz);
+ /*
+ * For now we deal only with critical, otherwise
+ * would need to iterate
+ */
+ err = tz->ops->get_trip_temp(tz, 0, &trip_temp);
+ if (err < 0) {
+ err = PTR_ERR(tz);
+ dev_err(&pdev->dev,
+ "Not able to read trip_temp: %d\n",
+ err);
+ goto err_tz;
+ }
+
/* the basic required flags */
val = (BCM2835_TS_TSENSCTL_CTRL_DEFAULT <<
BCM2835_TS_TSENSCTL_CTRL_SHIFT) |
@@ -256,9 +240,9 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
val |= (14 << BCM2835_TS_TSENSCTL_RSTDELAY_SHIFT);
/* trip_adc value from info */
- val |= bcm2835_thermal_temp2adc(data->info->trip_temp,
- data->info->offset,
- data->info->slope)
+ val |= bcm2835_thermal_temp2adc(trip_temp,
+ offset,
+ slope)
<< BCM2835_TS_TSENSCTL_THOLD_SHIFT;
/* write the value back to the register as 2 steps */
@@ -267,26 +251,18 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
writel(val, data->regs + BCM2835_TS_TSENSCTL);
}
- /* register thermal zone with 1 trip point an 1s polling */
- tz = thermal_zone_device_register("bcm2835_thermal",
- 1, 0, data,
- &bcm2835_thermal_ops,
- tzp,
- 0, 1000);
- if (IS_ERR(tz)) {
- clk_disable_unprepare(data->clk);
- err = PTR_ERR(tz);
- dev_err(&pdev->dev,
- "Failed to register the thermal device: %d\n",
- err);
- return err;
- }
+ data->tz = tz;
platform_set_drvdata(pdev, tz);
bcm2835_thermal_debugfs(pdev);
- return 0;
+err_tz:
+ thermal_zone_of_sensor_unregister(&pdev->dev, tz);
+err_clk:
+ clk_disable_unprepare(data->clk);
+
+ return err;
}
static int bcm2835_thermal_remove(struct platform_device *pdev)
@@ -295,7 +271,7 @@ static int bcm2835_thermal_remove(struct platform_device *pdev)
struct bcm2835_thermal_data *data = tz->devdata;
debugfs_remove_recursive(data->debugfsdir);
- thermal_zone_device_unregister(tz);
+ thermal_zone_of_sensor_unregister(&pdev->dev, tz);
clk_disable_unprepare(data->clk);
return 0;
@@ -312,28 +288,12 @@ static int bcm2835_thermal_remove(struct platform_device *pdev)
static const struct of_device_id bcm2835_thermal_of_match_table[] = {
{
.compatible = "brcm,bcm2835-thermal",
- .data = &(struct bcm2835_thermal_info) {
- .offset = 407000,
- .slope = -538,
- .trip_temp = 80000
- }
},
{
.compatible = "brcm,bcm2836-thermal",
- .data = &(struct bcm2835_thermal_info) {
- .offset = 407000,
- .slope = -538,
- .trip_temp = 80000
- }
},
{
.compatible = "brcm,bcm2837-thermal",
- .data = &(struct bcm2835_thermal_info) {
- /* the bcm2837 needs adjustment of +5C */
- .offset = 407000 + 5000,
- .slope = -538,
- .trip_temp = 80000
- }
},
{},
};
------------------------8------------------------
More information about the linux-rpi-kernel
mailing list