openwrt/target/linux/bcm27xx/patches-4.19/950-0466-thermal-brcmstb_thermal-Add-BCM2838-support.patch
Adrian Schmutzler 7d7aa2fd92 brcm2708: rename target to bcm27xx
This change makes the names of Broadcom targets consistent by using
the common notation based on SoC/CPU ID (which is used internally
anyway), bcmXXXX instead of brcmXXXX.
This is even used for target TITLE in make menuconfig already,
only the short target name used brcm so far.

Despite, since subtargets range from bcm2708 to bcm2711, it seems
appropriate to use bcm27xx instead of bcm2708 (again, as already done
for BOARDNAME).

This also renames the packages brcm2708-userland and brcm2708-gpu-fw.

Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
Acked-by: Álvaro Fernández Rojas <noltari@gmail.com>
2020-02-14 14:10:51 +01:00

163 lines
4.9 KiB
Diff

From d49649e2dcf0d5775e92677d37e229e0387fe82a Mon Sep 17 00:00:00 2001
From: Stefan Wahren <wahrenst@gmx.net>
Date: Sat, 18 May 2019 12:26:11 +0200
Subject: [PATCH] thermal: brcmstb_thermal: Add BCM2838 support
The BCM2838 has an AVS TMON hardware block. This adds the necessary
support to the brcmstb_thermal driver ( no trip handling ).
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
---
drivers/thermal/broadcom/Kconfig | 2 +-
drivers/thermal/broadcom/brcmstb_thermal.c | 65 +++++++++++++++++++---
2 files changed, 58 insertions(+), 9 deletions(-)
--- a/drivers/thermal/broadcom/Kconfig
+++ b/drivers/thermal/broadcom/Kconfig
@@ -8,7 +8,7 @@ config BCM2835_THERMAL
config BRCMSTB_THERMAL
tristate "Broadcom STB AVS TMON thermal driver"
- depends on ARCH_BRCMSTB || COMPILE_TEST
+ depends on ARCH_BRCMSTB || ARCH_BCM2835 || COMPILE_TEST
help
Enable this driver if you have a Broadcom STB SoC and would like
thermal framework support.
--- a/drivers/thermal/broadcom/brcmstb_thermal.c
+++ b/drivers/thermal/broadcom/brcmstb_thermal.c
@@ -19,6 +19,7 @@
#define pr_fmt(fmt) DRV_NAME ": " fmt
#include <linux/bitops.h>
+#include <linux/clk.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/io.h>
@@ -31,9 +32,6 @@
#include <linux/thermal.h>
#define AVS_TMON_STATUS 0x00
- #define AVS_TMON_STATUS_valid_msk BIT(11)
- #define AVS_TMON_STATUS_data_msk GENMASK(10, 1)
- #define AVS_TMON_STATUS_data_shift 1
#define AVS_TMON_EN_OVERTEMP_RESET 0x04
#define AVS_TMON_EN_OVERTEMP_RESET_msk BIT(0)
@@ -111,10 +109,19 @@ static struct avs_tmon_trip avs_tmon_tri
},
};
+struct brcmstb_thermal_of_data {
+ const struct thermal_zone_of_device_ops *of_ops;
+ u32 status_valid_mask;
+ u32 status_data_mask;
+ u32 status_data_shift;
+};
+
struct brcmstb_thermal_priv {
void __iomem *tmon_base;
struct device *dev;
struct thermal_zone_device *thermal;
+ struct clk *clk;
+ const struct brcmstb_thermal_of_data *socdata;
};
static void avs_tmon_get_coeffs(struct thermal_zone_device *tz, int *slope,
@@ -164,17 +171,18 @@ static inline u32 avs_tmon_temp_to_code(
static int brcmstb_get_temp(void *data, int *temp)
{
struct brcmstb_thermal_priv *priv = data;
+ const struct brcmstb_thermal_of_data *socdata = priv->socdata;
u32 val;
long t;
val = __raw_readl(priv->tmon_base + AVS_TMON_STATUS);
- if (!(val & AVS_TMON_STATUS_valid_msk)) {
+ if (!(val & socdata->status_valid_mask)) {
dev_err(priv->dev, "reading not valid\n");
return -EIO;
}
- val = (val & AVS_TMON_STATUS_data_msk) >> AVS_TMON_STATUS_data_shift;
+ val = (val & socdata->status_data_mask) >> socdata->status_data_shift;
t = avs_tmon_code_to_temp(priv->thermal, val);
if (t < 0)
@@ -299,13 +307,34 @@ static int brcmstb_set_trips(void *data,
return 0;
}
-static struct thermal_zone_of_device_ops of_ops = {
+static const struct thermal_zone_of_device_ops bcm7445_thermal_of_ops = {
.get_temp = brcmstb_get_temp,
.set_trips = brcmstb_set_trips,
};
+static const struct thermal_zone_of_device_ops bcm2838_thermal_of_ops = {
+ .get_temp = brcmstb_get_temp,
+};
+
+static const struct brcmstb_thermal_of_data bcm7445_thermal_of_data = {
+ .of_ops = &bcm7445_thermal_of_ops,
+ .status_valid_mask = BIT(11),
+ .status_data_mask = GENMASK(10, 1),
+ .status_data_shift = 1,
+};
+
+static const struct brcmstb_thermal_of_data bcm2838_thermal_of_data = {
+ .of_ops = &bcm2838_thermal_of_ops,
+ .status_valid_mask = BIT(10),
+ .status_data_mask = GENMASK(9, 0),
+ .status_data_shift = 0,
+};
+
static const struct of_device_id brcmstb_thermal_id_table[] = {
- { .compatible = "brcm,avs-tmon" },
+ { .compatible = "brcm,avs-tmon",
+ .data = &bcm7445_thermal_of_data },
+ { .compatible = "brcm,avs-tmon-bcm2838",
+ .data = &bcm2838_thermal_of_data },
{},
};
MODULE_DEVICE_TABLE(of, brcmstb_thermal_id_table);
@@ -326,10 +355,27 @@ static int brcmstb_thermal_probe(struct
if (IS_ERR(priv->tmon_base))
return PTR_ERR(priv->tmon_base);
+ priv->socdata = of_device_get_match_data(&pdev->dev);
+ if (!priv->socdata) {
+ dev_err(&pdev->dev, "no device match found\n");
+ return -ENODEV;
+ }
+
+ priv->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(priv->clk) && PTR_ERR(priv->clk) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+ if (!IS_ERR(priv->clk)) {
+ ret = clk_prepare_enable(priv->clk);
+ if (ret)
+ return ret;
+ }
+
priv->dev = &pdev->dev;
platform_set_drvdata(pdev, priv);
- thermal = thermal_zone_of_sensor_register(&pdev->dev, 0, priv, &of_ops);
+ thermal = thermal_zone_of_sensor_register(&pdev->dev, 0, priv,
+ priv->socdata->of_ops);
if (IS_ERR(thermal)) {
ret = PTR_ERR(thermal);
dev_err(&pdev->dev, "could not register sensor: %d\n", ret);
@@ -369,6 +415,9 @@ static int brcmstb_thermal_exit(struct p
if (thermal)
thermal_zone_of_sensor_unregister(&pdev->dev, priv->thermal);
+ if (!IS_ERR(priv->clk))
+ clk_disable_unprepare(priv->clk);
+
return 0;
}