@@ -20,6 +20,11 @@ struct scmi_sensors {
2020 const struct scmi_sensor_info * * info [hwmon_max ];
2121};
2222
23+ struct scmi_thermal_sensor {
24+ const struct scmi_protocol_handle * ph ;
25+ const struct scmi_sensor_info * info ;
26+ };
27+
2328static inline u64 __pow10 (u8 x )
2429{
2530 u64 r = 1 ;
@@ -64,16 +69,14 @@ static int scmi_hwmon_scale(const struct scmi_sensor_info *sensor, u64 *value)
6469 return 0 ;
6570}
6671
67- static int scmi_hwmon_read (struct device * dev , enum hwmon_sensor_types type ,
68- u32 attr , int channel , long * val )
72+ static int scmi_hwmon_read_scaled_value (const struct scmi_protocol_handle * ph ,
73+ const struct scmi_sensor_info * sensor ,
74+ long * val )
6975{
7076 int ret ;
7177 u64 value ;
72- const struct scmi_sensor_info * sensor ;
73- struct scmi_sensors * scmi_sensors = dev_get_drvdata (dev );
7478
75- sensor = * (scmi_sensors -> info [type ] + channel );
76- ret = sensor_ops -> reading_get (scmi_sensors -> ph , sensor -> id , & value );
79+ ret = sensor_ops -> reading_get (ph , sensor -> id , & value );
7780 if (ret )
7881 return ret ;
7982
@@ -84,6 +87,17 @@ static int scmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
8487 return ret ;
8588}
8689
90+ static int scmi_hwmon_read (struct device * dev , enum hwmon_sensor_types type ,
91+ u32 attr , int channel , long * val )
92+ {
93+ const struct scmi_sensor_info * sensor ;
94+ struct scmi_sensors * scmi_sensors = dev_get_drvdata (dev );
95+
96+ sensor = * (scmi_sensors -> info [type ] + channel );
97+
98+ return scmi_hwmon_read_scaled_value (scmi_sensors -> ph , sensor , val );
99+ }
100+
87101static int
88102scmi_hwmon_read_string (struct device * dev , enum hwmon_sensor_types type ,
89103 u32 attr , int channel , const char * * str )
@@ -122,6 +136,25 @@ static struct hwmon_chip_info scmi_chip_info = {
122136 .info = NULL ,
123137};
124138
139+ static int scmi_hwmon_thermal_get_temp (struct thermal_zone_device * tz ,
140+ int * temp )
141+ {
142+ int ret ;
143+ long value ;
144+ struct scmi_thermal_sensor * th_sensor = tz -> devdata ;
145+
146+ ret = scmi_hwmon_read_scaled_value (th_sensor -> ph , th_sensor -> info ,
147+ & value );
148+ if (!ret )
149+ * temp = value ;
150+
151+ return ret ;
152+ }
153+
154+ static const struct thermal_zone_device_ops scmi_hwmon_thermal_ops = {
155+ .get_temp = scmi_hwmon_thermal_get_temp ,
156+ };
157+
125158static int scmi_hwmon_add_chan_info (struct hwmon_channel_info * scmi_hwmon_chan ,
126159 struct device * dev , int num ,
127160 enum hwmon_sensor_types type , u32 config )
@@ -149,22 +182,58 @@ static enum hwmon_sensor_types scmi_types[] = {
149182};
150183
151184static u32 hwmon_attributes [hwmon_max ] = {
152- [hwmon_chip ] = HWMON_C_REGISTER_TZ ,
153185 [hwmon_temp ] = HWMON_T_INPUT | HWMON_T_LABEL ,
154186 [hwmon_in ] = HWMON_I_INPUT | HWMON_I_LABEL ,
155187 [hwmon_curr ] = HWMON_C_INPUT | HWMON_C_LABEL ,
156188 [hwmon_power ] = HWMON_P_INPUT | HWMON_P_LABEL ,
157189 [hwmon_energy ] = HWMON_E_INPUT | HWMON_E_LABEL ,
158190};
159191
192+ static int scmi_thermal_sensor_register (struct device * dev ,
193+ const struct scmi_protocol_handle * ph ,
194+ const struct scmi_sensor_info * sensor )
195+ {
196+ struct scmi_thermal_sensor * th_sensor ;
197+ struct thermal_zone_device * tzd ;
198+
199+ th_sensor = devm_kzalloc (dev , sizeof (* th_sensor ), GFP_KERNEL );
200+ if (!th_sensor )
201+ return - ENOMEM ;
202+
203+ th_sensor -> ph = ph ;
204+ th_sensor -> info = sensor ;
205+
206+ /*
207+ * Try to register a temperature sensor with the Thermal Framework:
208+ * skip sensors not defined as part of any thermal zone (-ENODEV) but
209+ * report any other errors related to misconfigured zones/sensors.
210+ */
211+ tzd = devm_thermal_of_zone_register (dev , th_sensor -> info -> id , th_sensor ,
212+ & scmi_hwmon_thermal_ops );
213+ if (IS_ERR (tzd )) {
214+ devm_kfree (dev , th_sensor );
215+
216+ if (PTR_ERR (tzd ) != - ENODEV )
217+ return PTR_ERR (tzd );
218+
219+ dev_dbg (dev , "Sensor '%s' not attached to any thermal zone.\n" ,
220+ sensor -> name );
221+ } else {
222+ dev_dbg (dev , "Sensor '%s' attached to thermal zone ID:%d\n" ,
223+ sensor -> name , tzd -> id );
224+ }
225+
226+ return 0 ;
227+ }
228+
160229static int scmi_hwmon_probe (struct scmi_device * sdev )
161230{
162231 int i , idx ;
163232 u16 nr_sensors ;
164233 enum hwmon_sensor_types type ;
165234 struct scmi_sensors * scmi_sensors ;
166235 const struct scmi_sensor_info * sensor ;
167- int nr_count [hwmon_max ] = {0 }, nr_types = 0 ;
236+ int nr_count [hwmon_max ] = {0 }, nr_types = 0 , nr_count_temp = 0 ;
168237 const struct hwmon_chip_info * chip_info ;
169238 struct device * hwdev , * dev = & sdev -> dev ;
170239 struct hwmon_channel_info * scmi_hwmon_chan ;
@@ -208,10 +277,8 @@ static int scmi_hwmon_probe(struct scmi_device *sdev)
208277 }
209278 }
210279
211- if (nr_count [hwmon_temp ]) {
212- nr_count [hwmon_chip ]++ ;
213- nr_types ++ ;
214- }
280+ if (nr_count [hwmon_temp ])
281+ nr_count_temp = nr_count [hwmon_temp ];
215282
216283 scmi_hwmon_chan = devm_kcalloc (dev , nr_types , sizeof (* scmi_hwmon_chan ),
217284 GFP_KERNEL );
@@ -262,8 +329,31 @@ static int scmi_hwmon_probe(struct scmi_device *sdev)
262329 hwdev = devm_hwmon_device_register_with_info (dev , "scmi_sensors" ,
263330 scmi_sensors , chip_info ,
264331 NULL );
332+ if (IS_ERR (hwdev ))
333+ return PTR_ERR (hwdev );
265334
266- return PTR_ERR_OR_ZERO (hwdev );
335+ for (i = 0 ; i < nr_count_temp ; i ++ ) {
336+ int ret ;
337+
338+ sensor = * (scmi_sensors -> info [hwmon_temp ] + i );
339+ if (!sensor )
340+ continue ;
341+
342+ /*
343+ * Warn on any misconfiguration related to thermal zones but
344+ * bail out of probing only on memory errors.
345+ */
346+ ret = scmi_thermal_sensor_register (dev , ph , sensor );
347+ if (ret ) {
348+ if (ret == - ENOMEM )
349+ return ret ;
350+ dev_warn (dev ,
351+ "Thermal zone misconfigured for %s. err=%d\n" ,
352+ sensor -> name , ret );
353+ }
354+ }
355+
356+ return 0 ;
267357}
268358
269359static const struct scmi_device_id scmi_id_table [] = {
0 commit comments