kernel: bump 5.4 to 5.4.24
[oweals/openwrt.git] / target / linux / bcm27xx / patches-5.4 / 950-0212-thermal-brcmstb_thermal-Add-BCM2838-support.patch
1 From d1066d775e67c33cc93178475c4485c5ef0a83c9 Mon Sep 17 00:00:00 2001
2 From: Stefan Wahren <wahrenst@gmx.net>
3 Date: Sat, 18 May 2019 12:26:11 +0200
4 Subject: [PATCH] thermal: brcmstb_thermal: Add BCM2838 support
5
6 The BCM2838 has an AVS TMON hardware block. This adds the necessary
7 support to the brcmstb_thermal driver ( no trip handling ).
8
9 Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
10 ---
11  drivers/thermal/broadcom/Kconfig           |  2 +-
12  drivers/thermal/broadcom/brcmstb_thermal.c | 61 +++++++++++++++++++---
13  2 files changed, 54 insertions(+), 9 deletions(-)
14
15 --- a/drivers/thermal/broadcom/Kconfig
16 +++ b/drivers/thermal/broadcom/Kconfig
17 @@ -9,7 +9,7 @@ config BCM2835_THERMAL
18  
19  config BRCMSTB_THERMAL
20         tristate "Broadcom STB AVS TMON thermal driver"
21 -       depends on ARCH_BRCMSTB || COMPILE_TEST
22 +       depends on ARCH_BRCMSTB || ARCH_BCM2835 || COMPILE_TEST
23         help
24           Enable this driver if you have a Broadcom STB SoC and would like
25           thermal framework support.
26 --- a/drivers/thermal/broadcom/brcmstb_thermal.c
27 +++ b/drivers/thermal/broadcom/brcmstb_thermal.c
28 @@ -10,6 +10,7 @@
29  #define pr_fmt(fmt)    DRV_NAME ": " fmt
30  
31  #include <linux/bitops.h>
32 +#include <linux/clk.h>
33  #include <linux/device.h>
34  #include <linux/err.h>
35  #include <linux/io.h>
36 @@ -22,9 +23,6 @@
37  #include <linux/thermal.h>
38  
39  #define AVS_TMON_STATUS                        0x00
40 - #define AVS_TMON_STATUS_valid_msk     BIT(11)
41 - #define AVS_TMON_STATUS_data_msk      GENMASK(10, 1)
42 - #define AVS_TMON_STATUS_data_shift    1
43  
44  #define AVS_TMON_EN_OVERTEMP_RESET     0x04
45   #define AVS_TMON_EN_OVERTEMP_RESET_msk        BIT(0)
46 @@ -102,10 +100,19 @@ static struct avs_tmon_trip avs_tmon_tri
47         },
48  };
49  
50 +struct brcmstb_thermal_of_data {
51 +       const struct thermal_zone_of_device_ops *of_ops;
52 +       u32 status_valid_mask;
53 +       u32 status_data_mask;
54 +       u32 status_data_shift;
55 +};
56 +
57  struct brcmstb_thermal_priv {
58         void __iomem *tmon_base;
59         struct device *dev;
60         struct thermal_zone_device *thermal;
61 +       struct clk *clk;
62 +       const struct brcmstb_thermal_of_data *socdata;
63  };
64  
65  /* Convert a HW code to a temperature reading (millidegree celsius) */
66 @@ -142,17 +149,18 @@ static inline u32 avs_tmon_temp_to_code(
67  static int brcmstb_get_temp(void *data, int *temp)
68  {
69         struct brcmstb_thermal_priv *priv = data;
70 +       const struct brcmstb_thermal_of_data *socdata = priv->socdata;
71         u32 val;
72         long t;
73  
74         val = __raw_readl(priv->tmon_base + AVS_TMON_STATUS);
75  
76 -       if (!(val & AVS_TMON_STATUS_valid_msk)) {
77 +       if (!(val & socdata->status_valid_mask)) {
78                 dev_err(priv->dev, "reading not valid\n");
79                 return -EIO;
80         }
81  
82 -       val = (val & AVS_TMON_STATUS_data_msk) >> AVS_TMON_STATUS_data_shift;
83 +       val = (val & socdata->status_data_mask) >> socdata->status_data_shift;
84  
85         t = avs_tmon_code_to_temp(priv->thermal, val);
86         if (t < 0)
87 @@ -277,13 +285,34 @@ static int brcmstb_set_trips(void *data,
88         return 0;
89  }
90  
91 -static const struct thermal_zone_of_device_ops of_ops = {
92 +static const struct thermal_zone_of_device_ops bcm7445_thermal_of_ops = {
93         .get_temp       = brcmstb_get_temp,
94         .set_trips      = brcmstb_set_trips,
95  };
96  
97 +static const struct thermal_zone_of_device_ops bcm2838_thermal_of_ops = {
98 +       .get_temp       = brcmstb_get_temp,
99 +};
100 +
101 +static const struct brcmstb_thermal_of_data bcm7445_thermal_of_data = {
102 +       .of_ops = &bcm7445_thermal_of_ops,
103 +       .status_valid_mask = BIT(11),
104 +       .status_data_mask = GENMASK(10, 1),
105 +       .status_data_shift = 1,
106 +};
107 +
108 +static const struct brcmstb_thermal_of_data bcm2838_thermal_of_data = {
109 +       .of_ops = &bcm2838_thermal_of_ops,
110 +       .status_valid_mask = BIT(10),
111 +       .status_data_mask = GENMASK(9, 0),
112 +       .status_data_shift = 0,
113 +};
114 +
115  static const struct of_device_id brcmstb_thermal_id_table[] = {
116 -       { .compatible = "brcm,avs-tmon" },
117 +       { .compatible = "brcm,avs-tmon",
118 +         .data = &bcm7445_thermal_of_data },
119 +       { .compatible = "brcm,avs-tmon-bcm2838",
120 +         .data = &bcm2838_thermal_of_data },
121         {},
122  };
123  MODULE_DEVICE_TABLE(of, brcmstb_thermal_id_table);
124 @@ -304,11 +333,27 @@ static int brcmstb_thermal_probe(struct
125         if (IS_ERR(priv->tmon_base))
126                 return PTR_ERR(priv->tmon_base);
127  
128 +       priv->socdata = of_device_get_match_data(&pdev->dev);
129 +       if (!priv->socdata) {
130 +               dev_err(&pdev->dev, "no device match found\n");
131 +               return -ENODEV;
132 +       }
133 +
134 +       priv->clk = devm_clk_get(&pdev->dev, NULL);
135 +       if (IS_ERR(priv->clk) && PTR_ERR(priv->clk) == -EPROBE_DEFER)
136 +               return -EPROBE_DEFER;
137 +
138 +       if (!IS_ERR(priv->clk)) {
139 +               ret = clk_prepare_enable(priv->clk);
140 +               if (ret)
141 +                       return ret;
142 +       }
143 +
144         priv->dev = &pdev->dev;
145         platform_set_drvdata(pdev, priv);
146  
147         thermal = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, priv,
148 -                                                      &of_ops);
149 +                                                      priv->socdata->of_ops);
150         if (IS_ERR(thermal)) {
151                 ret = PTR_ERR(thermal);
152                 dev_err(&pdev->dev, "could not register sensor: %d\n", ret);