ath79/mikrotik: use routerbootpart partitions
[oweals/openwrt.git] / target / linux / layerscape / patches-5.4 / 818-thermal-0002-thermal-qoriq-Add-device-cooling-support.patch
1 From 0a5d1b571ba5bca9c6737572ea4c8b1ad896c3fc Mon Sep 17 00:00:00 2001
2 From: Anson Huang <Anson.Huang@nxp.com>
3 Date: Wed, 7 Aug 2019 13:24:26 +0800
4 Subject: [PATCH] thermal: qoriq: Add device cooling support
5
6 Register device cooling for first thermal zone manually, when
7 temperature exceeds passive trip, system wide cooling notification
8 will be triggered.
9
10 Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
11 ---
12  drivers/thermal/qoriq_thermal.c | 80 ++++++++++++++++++++++++++++++++++++++++-
13  1 file changed, 79 insertions(+), 1 deletion(-)
14
15 --- a/drivers/thermal/qoriq_thermal.c
16 +++ b/drivers/thermal/qoriq_thermal.c
17 @@ -3,6 +3,7 @@
18  // Copyright 2016 Freescale Semiconductor, Inc.
19  
20  #include <linux/clk.h>
21 +#include <linux/device_cooling.h>
22  #include <linux/module.h>
23  #include <linux/platform_device.h>
24  #include <linux/err.h>
25 @@ -14,6 +15,7 @@
26  #include "thermal_core.h"
27  
28  #define SITES_MAX      16
29 +#define TMU_TEMP_PASSIVE_COOL_DELTA    10000
30  
31  /*
32   * QorIQ TMU Registers
33 @@ -69,6 +71,9 @@ struct qoriq_sensor {
34         struct thermal_zone_device      *tzd;
35         struct qoriq_tmu_data           *qdata;
36         int                             id;
37 +       int                             temp_passive;
38 +       int                             temp_critical;
39 +       struct thermal_cooling_device   *cdev;
40  };
41  
42  struct qoriq_tmu_data {
43 @@ -78,6 +83,12 @@ struct qoriq_tmu_data {
44         struct qoriq_sensor     *sensor[SITES_MAX];
45  };
46  
47 +enum tmu_trip {
48 +       TMU_TRIP_PASSIVE,
49 +       TMU_TRIP_CRITICAL,
50 +       TMU_TRIP_NUM,
51 +};
52 +
53  static void tmu_write(struct qoriq_tmu_data *p, u32 val, void __iomem *addr)
54  {
55         if (p->little_endian)
56 @@ -106,14 +117,51 @@ static int tmu_get_temp(void *p, int *te
57         return 0;
58  }
59  
60 +static int tmu_get_trend(void *p, int trip, enum thermal_trend *trend)
61 +{
62 +       struct qoriq_sensor *qsensor = p;
63 +       int trip_temp;
64 +
65 +       if (!qsensor->tzd)
66 +               return 0;
67 +
68 +       trip_temp = (trip == TMU_TRIP_PASSIVE) ? qsensor->temp_passive :
69 +                                            qsensor->temp_critical;
70 +
71 +       if (qsensor->tzd->temperature >=
72 +               (trip_temp - TMU_TEMP_PASSIVE_COOL_DELTA))
73 +               *trend = THERMAL_TREND_RAISE_FULL;
74 +       else
75 +               *trend = THERMAL_TREND_DROP_FULL;
76 +
77 +       return 0;
78 +}
79 +
80 +static int tmu_set_trip_temp(void *p, int trip,
81 +                            int temp)
82 +{
83 +       struct qoriq_sensor *qsensor = p;
84 +
85 +       if (trip == TMU_TRIP_CRITICAL)
86 +               qsensor->temp_critical = temp;
87 +
88 +       if (trip == TMU_TRIP_PASSIVE)
89 +               qsensor->temp_passive = temp;
90 +
91 +       return 0;
92 +}
93 +
94  static const struct thermal_zone_of_device_ops tmu_tz_ops = {
95         .get_temp = tmu_get_temp,
96 +       .get_trend = tmu_get_trend,
97 +       .set_trip_temp = tmu_set_trip_temp,
98  };
99  
100  static int qoriq_tmu_register_tmu_zone(struct platform_device *pdev)
101  {
102         struct qoriq_tmu_data *qdata = platform_get_drvdata(pdev);
103 -       int id, sites = 0;
104 +       const struct thermal_trip *trip;
105 +       int id, sites = 0, ret;
106  
107         for (id = 0; id < SITES_MAX; id++) {
108                 qdata->sensor[id] = devm_kzalloc(&pdev->dev,
109 @@ -132,6 +180,36 @@ static int qoriq_tmu_register_tmu_zone(s
110                                 return PTR_ERR(qdata->sensor[id]->tzd);
111                 }
112  
113 +               /* first thermal zone takes care of system-wide device cooling */
114 +               if (id == 0) {
115 +                       qdata->sensor[id]->cdev = devfreq_cooling_register();
116 +                       if (IS_ERR(qdata->sensor[id]->cdev)) {
117 +                               ret = PTR_ERR(qdata->sensor[id]->cdev);
118 +                               pr_err("failed to register devfreq cooling device: %d\n",
119 +                                       ret);
120 +                               return ret;
121 +                       }
122 +
123 +                       ret = thermal_zone_bind_cooling_device(qdata->sensor[id]->tzd,
124 +                               TMU_TRIP_PASSIVE,
125 +                               qdata->sensor[id]->cdev,
126 +                               THERMAL_NO_LIMIT,
127 +                               THERMAL_NO_LIMIT,
128 +                               THERMAL_WEIGHT_DEFAULT);
129 +                       if (ret) {
130 +                               pr_err("binding zone %s with cdev %s failed:%d\n",
131 +                                       qdata->sensor[id]->tzd->type,
132 +                                       qdata->sensor[id]->cdev->type,
133 +                                       ret);
134 +                               devfreq_cooling_unregister(qdata->sensor[id]->cdev);
135 +                               return ret;
136 +                       }
137 +
138 +                       trip = of_thermal_get_trip_points(qdata->sensor[id]->tzd);
139 +                       qdata->sensor[id]->temp_passive = trip[0].temperature;
140 +                       qdata->sensor[id]->temp_critical = trip[1].temperature;
141 +               }
142 +
143                 sites |= 0x1 << (15 - id);
144         }
145