mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 15:32:33 +00:00
7d7aa2fd92
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>
163 lines
4.9 KiB
Diff
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;
|
|
}
|
|
|