Skip to content

Commit 2f28e4c

Browse files
miquelraynalEduardo Valentin
authored andcommitted
thermal: armada: Clarify control registers accesses
Bindings were incomplete for a long time by only exposing one of the two available control registers. To ease the migration to the full bindings (already in use for the Armada 375 SoC), rename the pointers for clarification. This way, it will only be needed to add another pointer to access the other control register when the time comes. This avoids dangerous situations where the offset 0 of the control area can be either one register or the other depending on the bindings used. After this change, device trees of other SoCs could be migrated to the "full" bindings if they may benefit from features from the unaccessible register, without any change in the driver. Signed-off-by: Miquel Raynal <[email protected]> Reviewed-by: Gregory CLEMENT <[email protected]> Tested-by: Gregory CLEMENT <[email protected]> Signed-off-by: Eduardo Valentin <[email protected]>
1 parent 27d92f2 commit 2f28e4c

File tree

1 file changed

+54
-22
lines changed

1 file changed

+54
-22
lines changed

drivers/thermal/armada_thermal.c

Lines changed: 54 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,21 @@
3939
#define A375_HW_RESETn BIT(8)
4040
#define A380_HW_RESET BIT(8)
4141

42+
/* Legacy bindings */
43+
#define LEGACY_CONTROL_MEM_LEN 0x4
44+
45+
/* Current bindings with the 2 control registers under the same memory area */
46+
#define LEGACY_CONTROL1_OFFSET 0x0
47+
#define CONTROL0_OFFSET 0x0
48+
#define CONTROL1_OFFSET 0x4
49+
4250
struct armada_thermal_data;
4351

4452
/* Marvell EBU Thermal Sensor Dev Structure */
4553
struct armada_thermal_priv {
4654
void __iomem *sensor;
47-
void __iomem *control;
55+
void __iomem *control0;
56+
void __iomem *control1;
4857
struct armada_thermal_data *data;
4958
};
5059

@@ -66,27 +75,28 @@ struct armada_thermal_data {
6675
unsigned int temp_shift;
6776
unsigned int temp_mask;
6877
u32 is_valid_bit;
78+
bool needs_control0;
6979
};
7080

7181
static void armadaxp_init_sensor(struct platform_device *pdev,
7282
struct armada_thermal_priv *priv)
7383
{
74-
unsigned long reg;
84+
u32 reg;
7585

76-
reg = readl_relaxed(priv->control);
86+
reg = readl_relaxed(priv->control1);
7787
reg |= PMU_TDC0_OTF_CAL_MASK;
78-
writel(reg, priv->control);
88+
writel(reg, priv->control1);
7989

8090
/* Reference calibration value */
8191
reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
8292
reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
83-
writel(reg, priv->control);
93+
writel(reg, priv->control1);
8494

8595
/* Reset the sensor */
86-
reg = readl_relaxed(priv->control);
87-
writel((reg | PMU_TDC0_SW_RST_MASK), priv->control);
96+
reg = readl_relaxed(priv->control1);
97+
writel((reg | PMU_TDC0_SW_RST_MASK), priv->control1);
8898

89-
writel(reg, priv->control);
99+
writel(reg, priv->control1);
90100

91101
/* Enable the sensor */
92102
reg = readl_relaxed(priv->sensor);
@@ -97,50 +107,50 @@ static void armadaxp_init_sensor(struct platform_device *pdev,
97107
static void armada370_init_sensor(struct platform_device *pdev,
98108
struct armada_thermal_priv *priv)
99109
{
100-
unsigned long reg;
110+
u32 reg;
101111

102-
reg = readl_relaxed(priv->control);
112+
reg = readl_relaxed(priv->control1);
103113
reg |= PMU_TDC0_OTF_CAL_MASK;
104-
writel(reg, priv->control);
114+
writel(reg, priv->control1);
105115

106116
/* Reference calibration value */
107117
reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
108118
reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
109-
writel(reg, priv->control);
119+
writel(reg, priv->control1);
110120

111121
reg &= ~PMU_TDC0_START_CAL_MASK;
112-
writel(reg, priv->control);
122+
writel(reg, priv->control1);
113123

114124
msleep(10);
115125
}
116126

117127
static void armada375_init_sensor(struct platform_device *pdev,
118128
struct armada_thermal_priv *priv)
119129
{
120-
unsigned long reg;
130+
u32 reg;
121131

122-
reg = readl(priv->control + 4);
132+
reg = readl(priv->control1);
123133
reg &= ~(A375_UNIT_CONTROL_MASK << A375_UNIT_CONTROL_SHIFT);
124134
reg &= ~A375_READOUT_INVERT;
125135
reg &= ~A375_HW_RESETn;
126136

127-
writel(reg, priv->control + 4);
137+
writel(reg, priv->control1);
128138
msleep(20);
129139

130140
reg |= A375_HW_RESETn;
131-
writel(reg, priv->control + 4);
141+
writel(reg, priv->control1);
132142
msleep(50);
133143
}
134144

135145
static void armada380_init_sensor(struct platform_device *pdev,
136146
struct armada_thermal_priv *priv)
137147
{
138-
unsigned long reg = readl_relaxed(priv->control);
148+
u32 reg = readl_relaxed(priv->control1);
139149

140150
/* Reset hardware once */
141151
if (!(reg & A380_HW_RESET)) {
142152
reg |= A380_HW_RESET;
143-
writel(reg, priv->control);
153+
writel(reg, priv->control1);
144154
msleep(10);
145155
}
146156
}
@@ -214,6 +224,7 @@ static const struct armada_thermal_data armada375_data = {
214224
.coef_b = 3171900000UL,
215225
.coef_m = 10000000UL,
216226
.coef_div = 13616,
227+
.needs_control0 = true,
217228
};
218229

219230
static const struct armada_thermal_data armada380_data = {
@@ -253,6 +264,7 @@ MODULE_DEVICE_TABLE(of, armada_thermal_id_table);
253264

254265
static int armada_thermal_probe(struct platform_device *pdev)
255266
{
267+
void __iomem *control = NULL;
256268
struct thermal_zone_device *thermal;
257269
const struct of_device_id *match;
258270
struct armada_thermal_priv *priv;
@@ -272,11 +284,31 @@ static int armada_thermal_probe(struct platform_device *pdev)
272284
return PTR_ERR(priv->sensor);
273285

274286
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
275-
priv->control = devm_ioremap_resource(&pdev->dev, res);
276-
if (IS_ERR(priv->control))
277-
return PTR_ERR(priv->control);
287+
control = devm_ioremap_resource(&pdev->dev, res);
288+
if (IS_ERR(control))
289+
return PTR_ERR(control);
278290

279291
priv->data = (struct armada_thermal_data *)match->data;
292+
293+
/*
294+
* Legacy DT bindings only described "control1" register (also referred
295+
* as "control MSB" on old documentation). New bindings cover
296+
* "control0/control LSB" and "control1/control MSB" registers within
297+
* the same resource, which is then of size 8 instead of 4.
298+
*/
299+
if (resource_size(res) == LEGACY_CONTROL_MEM_LEN) {
300+
/* ->control0 unavailable in this configuration */
301+
if (priv->data->needs_control0) {
302+
dev_err(&pdev->dev, "No access to control0 register\n");
303+
return -EINVAL;
304+
}
305+
306+
priv->control1 = control + LEGACY_CONTROL1_OFFSET;
307+
} else {
308+
priv->control0 = control + CONTROL0_OFFSET;
309+
priv->control1 = control + CONTROL1_OFFSET;
310+
}
311+
280312
priv->data->init_sensor(pdev, priv);
281313

282314
thermal = thermal_zone_device_register("armada_thermal", 0, 0,

0 commit comments

Comments
 (0)