Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: (occ) Add new temperature sensor type

The latest version of the On-Chip Controller (OCC) has a different
format for the temperature sensor data. Add a new temperature sensor
version to handle this data.

Signed-off-by: Eddie James <eajames@linux.ibm.com>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Joel Stanley <joel@jms.id.au>
Link: https://lore.kernel.org/r/20201120010315.190737-4-joel@jms.id.au
Signed-off-by: Guenter Roeck <linux@roeck-us.net>

authored by

Eddie James and committed by
Guenter Roeck
db4919ec 5ec96d74

+75
+75
drivers/hwmon/occ/common.c
··· 41 41 u8 value; 42 42 } __packed; 43 43 44 + struct temp_sensor_10 { 45 + u32 sensor_id; 46 + u8 fru_type; 47 + u8 value; 48 + u8 throttle; 49 + u8 reserved; 50 + } __packed; 51 + 44 52 struct freq_sensor_1 { 45 53 u16 sensor_id; 46 54 u16 value; ··· 307 299 break; 308 300 case 3: 309 301 val = temp->value == OCC_TEMP_SENSOR_FAULT; 302 + break; 303 + default: 304 + return -EINVAL; 305 + } 306 + 307 + return snprintf(buf, PAGE_SIZE - 1, "%u\n", val); 308 + } 309 + 310 + static ssize_t occ_show_temp_10(struct device *dev, 311 + struct device_attribute *attr, char *buf) 312 + { 313 + int rc; 314 + u32 val = 0; 315 + struct temp_sensor_10 *temp; 316 + struct occ *occ = dev_get_drvdata(dev); 317 + struct occ_sensors *sensors = &occ->sensors; 318 + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 319 + 320 + rc = occ_update_response(occ); 321 + if (rc) 322 + return rc; 323 + 324 + temp = ((struct temp_sensor_10 *)sensors->temp.data) + sattr->index; 325 + 326 + switch (sattr->nr) { 327 + case 0: 328 + val = get_unaligned_be32(&temp->sensor_id); 329 + break; 330 + case 1: 331 + val = temp->value; 332 + if (val == OCC_TEMP_SENSOR_FAULT) 333 + return -EREMOTEIO; 334 + 335 + /* 336 + * VRM doesn't return temperature, only alarm bit. This 337 + * attribute maps to tempX_alarm instead of tempX_input for 338 + * VRM 339 + */ 340 + if (temp->fru_type != OCC_FRU_TYPE_VRM) { 341 + /* sensor not ready */ 342 + if (val == 0) 343 + return -EAGAIN; 344 + 345 + val *= 1000; 346 + } 347 + break; 348 + case 2: 349 + val = temp->fru_type; 350 + break; 351 + case 3: 352 + val = temp->value == OCC_TEMP_SENSOR_FAULT; 353 + break; 354 + case 4: 355 + val = temp->throttle * 1000; 310 356 break; 311 357 default: 312 358 return -EINVAL; ··· 807 745 num_attrs += (sensors->temp.num_sensors * 4); 808 746 show_temp = occ_show_temp_2; 809 747 break; 748 + case 0x10: 749 + num_attrs += (sensors->temp.num_sensors * 5); 750 + show_temp = occ_show_temp_10; 751 + break; 810 752 default: 811 753 sensors->temp.num_sensors = 0; 812 754 } ··· 910 844 attr->sensor = OCC_INIT_ATTR(attr->name, 0444, 911 845 show_temp, NULL, 3, i); 912 846 attr++; 847 + 848 + if (sensors->temp.version == 0x10) { 849 + snprintf(attr->name, sizeof(attr->name), 850 + "temp%d_max", s); 851 + attr->sensor = OCC_INIT_ATTR(attr->name, 0444, 852 + show_temp, NULL, 853 + 4, i); 854 + attr++; 855 + } 913 856 } 914 857 } 915 858