30
30
LOONGSON2_THSENS_INT_HIGH)
31
31
#define LOONGSON2_THSENS_OUT_MASK 0xFF
32
32
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
+
33
39
struct loongson2_thermal_chip_data {
34
40
unsigned int thermal_sensor_sel ;
41
+ unsigned int flags ;
35
42
};
36
43
37
44
struct loongson2_thermal_data {
38
- void __iomem * regs ;
45
+ void __iomem * ctrl_reg ;
46
+ void __iomem * temp_reg ;
39
47
const struct loongson2_thermal_chip_data * chip_data ;
40
48
};
41
49
@@ -48,7 +56,7 @@ static void loongson2_set_ctrl_regs(struct loongson2_thermal_data *data,
48
56
49
57
reg_ctrl = ctrl_data + HECTO ;
50
58
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 );
52
60
}
53
61
54
62
static int loongson2_thermal_set (struct loongson2_thermal_data * data ,
@@ -63,13 +71,24 @@ static int loongson2_thermal_set(struct loongson2_thermal_data *data,
63
71
return 0 ;
64
72
}
65
73
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 )
67
86
{
68
- u32 reg_val ;
87
+ int val ;
69
88
struct loongson2_thermal_data * data = thermal_zone_device_priv (tz );
70
89
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 ;
73
92
74
93
return 0 ;
75
94
}
@@ -79,7 +98,7 @@ static irqreturn_t loongson2_thermal_irq_thread(int irq, void *dev)
79
98
struct thermal_zone_device * tzd = dev ;
80
99
struct loongson2_thermal_data * data = thermal_zone_device_priv (tzd );
81
100
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 );
83
102
84
103
thermal_zone_device_update (tzd , THERMAL_EVENT_UNSPECIFIED );
85
104
@@ -93,8 +112,8 @@ static int loongson2_thermal_set_trips(struct thermal_zone_device *tz, int low,
93
112
return loongson2_thermal_set (data , low /MILLI , high /MILLI , true);
94
113
}
95
114
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 ,
98
117
.set_trips = loongson2_thermal_set_trips ,
99
118
};
100
119
@@ -111,15 +130,24 @@ static int loongson2_thermal_probe(struct platform_device *pdev)
111
130
112
131
data -> chip_data = device_get_match_data (dev );
113
132
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
+ }
117
145
118
146
irq = platform_get_irq (pdev , 0 );
119
147
if (irq < 0 )
120
148
return irq ;
121
149
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 );
123
151
124
152
loongson2_thermal_set (data , 0 , 0 , false);
125
153
@@ -148,13 +176,23 @@ static int loongson2_thermal_probe(struct platform_device *pdev)
148
176
149
177
static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k1000_data = {
150
178
.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 ,
151
185
};
152
186
153
187
static const struct of_device_id of_loongson2_thermal_match [] = {
154
188
{
155
189
.compatible = "loongson,ls2k1000-thermal" ,
156
190
.data = & loongson2_thermal_ls2k1000_data ,
157
191
},
192
+ {
193
+ .compatible = "loongson,ls2k2000-thermal" ,
194
+ .data = & loongson2_thermal_ls2k2000_data ,
195
+ },
158
196
{ /* end */ }
159
197
};
160
198
MODULE_DEVICE_TABLE (of , of_loongson2_thermal_match );
0 commit comments