switch (sensor->type) { case TEMPERATURE_C: case VOLTAGE: case CURRENT:
scale += 3; break; case POWER: case ENERGY:
scale += 6; break; default: break;
}
if (scale == 0) return 0;
if (abs(scale) > 19) return -E2BIG;
f = __pow10(abs(scale)); if (scale > 0)
*value *= f; else
*value = div64_u64(*value, f);
return 0;
}
staticint scmi_hwmon_read_scaled_value(conststruct scmi_protocol_handle *ph, conststruct scmi_sensor_info *sensor, long *val)
{ int ret;
u64 value;
ret = sensor_ops->reading_get(ph, sensor->id, &value); if (ret) return ret;
ret = scmi_hwmon_scale(sensor, &value); if (!ret)
*val = value;
th_sensor = devm_kzalloc(dev, sizeof(*th_sensor), GFP_KERNEL); if (!th_sensor) return -ENOMEM;
th_sensor->ph = ph;
th_sensor->info = sensor;
/* * Try to register a temperature sensor with the Thermal Framework: * skip sensors not defined as part of any thermal zone (-ENODEV) but * report any other errors related to misconfigured zones/sensors.
*/
tzd = devm_thermal_of_zone_register(dev, th_sensor->info->id, th_sensor,
&scmi_hwmon_thermal_ops); if (IS_ERR(tzd)) {
devm_kfree(dev, th_sensor);
if (PTR_ERR(tzd) != -ENODEV) return PTR_ERR(tzd);
dev_dbg(dev, "Sensor '%s' not attached to any thermal zone.\n",
sensor->name);
} else {
dev_dbg(dev, "Sensor '%s' attached to thermal zone ID:%d\n",
sensor->name, thermal_zone_device_id(tzd));
}
sensor_ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_SENSOR, &ph); if (IS_ERR(sensor_ops)) return PTR_ERR(sensor_ops);
nr_sensors = sensor_ops->count_get(ph); if (!nr_sensors) return -EIO;
scmi_sensors = devm_kzalloc(dev, sizeof(*scmi_sensors), GFP_KERNEL); if (!scmi_sensors) return -ENOMEM;
scmi_sensors->ph = ph;
for (i = 0; i < nr_sensors; i++) {
sensor = sensor_ops->info_get(ph, i); if (!sensor) return -EINVAL;
switch (sensor->type) { case TEMPERATURE_C: case VOLTAGE: case CURRENT: case POWER: case ENERGY:
type = scmi_types[sensor->type]; if (!nr_count[type])
nr_types++;
nr_count[type]++; break;
}
}
if (nr_count[hwmon_temp])
nr_count_temp = nr_count[hwmon_temp];
scmi_hwmon_chan = devm_kcalloc(dev, nr_types, sizeof(*scmi_hwmon_chan),
GFP_KERNEL); if (!scmi_hwmon_chan) return -ENOMEM;
for (i = nr_sensors - 1; i >= 0 ; i--) {
sensor = sensor_ops->info_get(ph, i); if (!sensor) continue;
switch (sensor->type) { case TEMPERATURE_C: case VOLTAGE: case CURRENT: case POWER: case ENERGY:
type = scmi_types[sensor->type];
idx = --nr_count[type];
*(scmi_sensors->info[type] + idx) = sensor; break;
}
}
sensor = *(scmi_sensors->info[hwmon_temp] + i); if (!sensor) continue;
/* * Warn on any misconfiguration related to thermal zones but * bail out of probing only on memory errors.
*/
ret = scmi_thermal_sensor_register(dev, ph, sensor); if (ret) { if (ret == -ENOMEM) return ret;
dev_warn(dev, "Thermal zone misconfigured for %s. err=%d\n",
sensor->name, ret);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.