Skip to content

Commit 734b5de

Browse files
AaronDotdlezcano
authored andcommitted
thermal/drivers/loongson2: Add Loongson-2K2000 support
The Loongson-2K2000 and Loongson-2K1000 have similar thermal sensors, except that the temperature is read differently. In particular, the temperature output registers of the Loongson-2K2000 are defined in the chip configuration domain and are read in a different way. Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn> Acked-by: Huacai Chen <chenhuacai@loongson.cn> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> Link: https://lore.kernel.org/r/fdbfdcc3231a36a4ee0bcf1377ddcbd6f8c944b5.1713837379.git.zhoubinbin@loongson.cn
1 parent c8c4353 commit 734b5de

File tree

1 file changed

+51
-13
lines changed

1 file changed

+51
-13
lines changed

drivers/thermal/loongson2_thermal.c

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,20 @@
3030
LOONGSON2_THSENS_INT_HIGH)
3131
#define LOONGSON2_THSENS_OUT_MASK 0xFF
3232

33+
/*
34+
* This flag is used to indicate the temperature reading
35+
* method of the Loongson-2K2000
36+
*/
37+
#define LS2K2000_THSENS_OUT_FLAG BIT(0)
38+
3339
struct loongson2_thermal_chip_data {
3440
unsigned int thermal_sensor_sel;
41+
unsigned int flags;
3542
};
3643

3744
struct loongson2_thermal_data {
38-
void __iomem *regs;
45+
void __iomem *ctrl_reg;
46+
void __iomem *temp_reg;
3947
const struct loongson2_thermal_chip_data *chip_data;
4048
};
4149

@@ -48,7 +56,7 @@ static void loongson2_set_ctrl_regs(struct loongson2_thermal_data *data,
4856

4957
reg_ctrl = ctrl_data + HECTO;
5058
reg_ctrl |= enable ? 0x100 : 0;
51-
writew(reg_ctrl, data->regs + ctrl_reg + reg_off);
59+
writew(reg_ctrl, data->ctrl_reg + ctrl_reg + reg_off);
5260
}
5361

5462
static int loongson2_thermal_set(struct loongson2_thermal_data *data,
@@ -63,13 +71,24 @@ static int loongson2_thermal_set(struct loongson2_thermal_data *data,
6371
return 0;
6472
}
6573

66-
static int loongson2_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
74+
static int loongson2_2k1000_get_temp(struct thermal_zone_device *tz, int *temp)
75+
{
76+
int val;
77+
struct loongson2_thermal_data *data = thermal_zone_device_priv(tz);
78+
79+
val = readl(data->ctrl_reg + LOONGSON2_THSENS_OUT_REG);
80+
*temp = ((val & LOONGSON2_THSENS_OUT_MASK) - HECTO) * KILO;
81+
82+
return 0;
83+
}
84+
85+
static int loongson2_2k2000_get_temp(struct thermal_zone_device *tz, int *temp)
6786
{
68-
u32 reg_val;
87+
int val;
6988
struct loongson2_thermal_data *data = thermal_zone_device_priv(tz);
7089

71-
reg_val = readl(data->regs + LOONGSON2_THSENS_OUT_REG);
72-
*temp = ((reg_val & LOONGSON2_THSENS_OUT_MASK) - HECTO) * KILO;
90+
val = readl(data->temp_reg);
91+
*temp = ((val & 0xffff) * 820 / 0x4000 - 311) * KILO;
7392

7493
return 0;
7594
}
@@ -79,7 +98,7 @@ static irqreturn_t loongson2_thermal_irq_thread(int irq, void *dev)
7998
struct thermal_zone_device *tzd = dev;
8099
struct loongson2_thermal_data *data = thermal_zone_device_priv(tzd);
81100

82-
writeb(LOONGSON2_THSENS_INT_EN, data->regs + LOONGSON2_THSENS_STATUS_REG);
101+
writeb(LOONGSON2_THSENS_INT_EN, data->ctrl_reg + LOONGSON2_THSENS_STATUS_REG);
83102

84103
thermal_zone_device_update(tzd, THERMAL_EVENT_UNSPECIFIED);
85104

@@ -93,8 +112,8 @@ static int loongson2_thermal_set_trips(struct thermal_zone_device *tz, int low,
93112
return loongson2_thermal_set(data, low/MILLI, high/MILLI, true);
94113
}
95114

96-
static const struct thermal_zone_device_ops loongson2_of_thermal_ops = {
97-
.get_temp = loongson2_thermal_get_temp,
115+
static struct thermal_zone_device_ops loongson2_of_thermal_ops = {
116+
.get_temp = loongson2_2k1000_get_temp,
98117
.set_trips = loongson2_thermal_set_trips,
99118
};
100119

@@ -111,15 +130,24 @@ static int loongson2_thermal_probe(struct platform_device *pdev)
111130

112131
data->chip_data = device_get_match_data(dev);
113132

114-
data->regs = devm_platform_ioremap_resource(pdev, 0);
115-
if (IS_ERR(data->regs))
116-
return PTR_ERR(data->regs);
133+
data->ctrl_reg = devm_platform_ioremap_resource(pdev, 0);
134+
if (IS_ERR(data->ctrl_reg))
135+
return PTR_ERR(data->ctrl_reg);
136+
137+
/* The temperature output register is separate for Loongson-2K2000 */
138+
if (data->chip_data->flags & LS2K2000_THSENS_OUT_FLAG) {
139+
data->temp_reg = devm_platform_ioremap_resource(pdev, 1);
140+
if (IS_ERR(data->temp_reg))
141+
return PTR_ERR(data->temp_reg);
142+
143+
loongson2_of_thermal_ops.get_temp = loongson2_2k2000_get_temp;
144+
}
117145

118146
irq = platform_get_irq(pdev, 0);
119147
if (irq < 0)
120148
return irq;
121149

122-
writeb(LOONGSON2_THSENS_INT_EN, data->regs + LOONGSON2_THSENS_STATUS_REG);
150+
writeb(LOONGSON2_THSENS_INT_EN, data->ctrl_reg + LOONGSON2_THSENS_STATUS_REG);
123151

124152
loongson2_thermal_set(data, 0, 0, false);
125153

@@ -148,13 +176,23 @@ static int loongson2_thermal_probe(struct platform_device *pdev)
148176

149177
static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k1000_data = {
150178
.thermal_sensor_sel = 0,
179+
.flags = 0,
180+
};
181+
182+
static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k2000_data = {
183+
.thermal_sensor_sel = 0,
184+
.flags = LS2K2000_THSENS_OUT_FLAG,
151185
};
152186

153187
static const struct of_device_id of_loongson2_thermal_match[] = {
154188
{
155189
.compatible = "loongson,ls2k1000-thermal",
156190
.data = &loongson2_thermal_ls2k1000_data,
157191
},
192+
{
193+
.compatible = "loongson,ls2k2000-thermal",
194+
.data = &loongson2_thermal_ls2k2000_data,
195+
},
158196
{ /* end */ }
159197
};
160198
MODULE_DEVICE_TABLE(of, of_loongson2_thermal_match);

0 commit comments

Comments
 (0)