mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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>
This commit is contained in:
		
							parent
							
								
									5ec96d74cf
								
							
						
					
					
						commit
						db4919ec86
					
				
					 1 changed files with 75 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -41,6 +41,14 @@ struct temp_sensor_2 {
 | 
			
		|||
	u8 value;
 | 
			
		||||
} __packed;
 | 
			
		||||
 | 
			
		||||
struct temp_sensor_10 {
 | 
			
		||||
	u32 sensor_id;
 | 
			
		||||
	u8 fru_type;
 | 
			
		||||
	u8 value;
 | 
			
		||||
	u8 throttle;
 | 
			
		||||
	u8 reserved;
 | 
			
		||||
} __packed;
 | 
			
		||||
 | 
			
		||||
struct freq_sensor_1 {
 | 
			
		||||
	u16 sensor_id;
 | 
			
		||||
	u16 value;
 | 
			
		||||
| 
						 | 
				
			
			@ -307,6 +315,60 @@ static ssize_t occ_show_temp_2(struct device *dev,
 | 
			
		|||
	return snprintf(buf, PAGE_SIZE - 1, "%u\n", val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ssize_t occ_show_temp_10(struct device *dev,
 | 
			
		||||
				struct device_attribute *attr, char *buf)
 | 
			
		||||
{
 | 
			
		||||
	int rc;
 | 
			
		||||
	u32 val = 0;
 | 
			
		||||
	struct temp_sensor_10 *temp;
 | 
			
		||||
	struct occ *occ = dev_get_drvdata(dev);
 | 
			
		||||
	struct occ_sensors *sensors = &occ->sensors;
 | 
			
		||||
	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
 | 
			
		||||
 | 
			
		||||
	rc = occ_update_response(occ);
 | 
			
		||||
	if (rc)
 | 
			
		||||
		return rc;
 | 
			
		||||
 | 
			
		||||
	temp = ((struct temp_sensor_10 *)sensors->temp.data) + sattr->index;
 | 
			
		||||
 | 
			
		||||
	switch (sattr->nr) {
 | 
			
		||||
	case 0:
 | 
			
		||||
		val = get_unaligned_be32(&temp->sensor_id);
 | 
			
		||||
		break;
 | 
			
		||||
	case 1:
 | 
			
		||||
		val = temp->value;
 | 
			
		||||
		if (val == OCC_TEMP_SENSOR_FAULT)
 | 
			
		||||
			return -EREMOTEIO;
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * VRM doesn't return temperature, only alarm bit. This
 | 
			
		||||
		 * attribute maps to tempX_alarm instead of tempX_input for
 | 
			
		||||
		 * VRM
 | 
			
		||||
		 */
 | 
			
		||||
		if (temp->fru_type != OCC_FRU_TYPE_VRM) {
 | 
			
		||||
			/* sensor not ready */
 | 
			
		||||
			if (val == 0)
 | 
			
		||||
				return -EAGAIN;
 | 
			
		||||
 | 
			
		||||
			val *= 1000;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case 2:
 | 
			
		||||
		val = temp->fru_type;
 | 
			
		||||
		break;
 | 
			
		||||
	case 3:
 | 
			
		||||
		val = temp->value == OCC_TEMP_SENSOR_FAULT;
 | 
			
		||||
		break;
 | 
			
		||||
	case 4:
 | 
			
		||||
		val = temp->throttle * 1000;
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return snprintf(buf, PAGE_SIZE - 1, "%u\n", val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ssize_t occ_show_freq_1(struct device *dev,
 | 
			
		||||
			       struct device_attribute *attr, char *buf)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -745,6 +807,10 @@ static int occ_setup_sensor_attrs(struct occ *occ)
 | 
			
		|||
		num_attrs += (sensors->temp.num_sensors * 4);
 | 
			
		||||
		show_temp = occ_show_temp_2;
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x10:
 | 
			
		||||
		num_attrs += (sensors->temp.num_sensors * 5);
 | 
			
		||||
		show_temp = occ_show_temp_10;
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		sensors->temp.num_sensors = 0;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -844,6 +910,15 @@ static int occ_setup_sensor_attrs(struct occ *occ)
 | 
			
		|||
			attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 | 
			
		||||
						     show_temp, NULL, 3, i);
 | 
			
		||||
			attr++;
 | 
			
		||||
 | 
			
		||||
			if (sensors->temp.version == 0x10) {
 | 
			
		||||
				snprintf(attr->name, sizeof(attr->name),
 | 
			
		||||
					 "temp%d_max", s);
 | 
			
		||||
				attr->sensor = OCC_INIT_ATTR(attr->name, 0444,
 | 
			
		||||
							     show_temp, NULL,
 | 
			
		||||
							     4, i);
 | 
			
		||||
				attr++;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue