struct mutex update_lock; bool valid; /* true if following fields are valid */ unsignedlong last_updated; /* In jiffies */
u8 in[SCH5636_NO_INS];
u8 temp_val[SCH5636_NO_TEMPS];
u8 temp_ctrl[SCH5636_NO_TEMPS];
u16 fan_val[SCH5636_NO_FANS];
u8 fan_ctrl[SCH5636_NO_FANS];
};
staticstruct sch5636_data *sch5636_update_device(struct device *dev)
{ struct sch5636_data *data = dev_get_drvdata(dev); struct sch5636_data *ret = data; int i, val;
mutex_lock(&data->update_lock);
/* Cache the values for 1 second */ if (data->valid && !time_after(jiffies, data->last_updated + HZ)) goto abort;
for (i = 0; i < SCH5636_NO_INS; i++) {
val = sch56xx_read_virtual_reg(data->addr,
SCH5636_REG_IN_VAL[i]); if (unlikely(val < 0)) {
ret = ERR_PTR(val); goto abort;
}
data->in[i] = val;
}
for (i = 0; i < SCH5636_NO_TEMPS; i++) { if (data->temp_ctrl[i] & SCH5636_TEMP_DEACTIVATED) continue;
val = sch56xx_read_virtual_reg(data->addr,
SCH5636_REG_TEMP_VAL[i]); if (unlikely(val < 0)) {
ret = ERR_PTR(val); goto abort;
}
data->temp_val[i] = val;
val = sch56xx_read_virtual_reg(data->addr,
SCH5636_REG_TEMP_CTRL(i)); if (unlikely(val < 0)) {
ret = ERR_PTR(val); goto abort;
}
data->temp_ctrl[i] = val; /* Alarms need to be explicitly write-cleared */ if (val & SCH5636_TEMP_ALARM) {
sch56xx_write_virtual_reg(data->addr,
SCH5636_REG_TEMP_CTRL(i), val);
}
}
for (i = 0; i < SCH5636_NO_FANS; i++) { if (data->fan_ctrl[i] & SCH5636_FAN_DEACTIVATED) continue;
val = sch56xx_read_virtual_reg16(data->addr,
SCH5636_REG_FAN_VAL[i]); if (unlikely(val < 0)) {
ret = ERR_PTR(val); goto abort;
}
data->fan_val[i] = val;
val = sch56xx_read_virtual_reg(data->addr,
SCH5636_REG_FAN_CTRL(i)); if (unlikely(val < 0)) {
ret = ERR_PTR(val); goto abort;
}
data->fan_ctrl[i] = val; /* Alarms need to be explicitly write-cleared */ if (val & SCH5636_FAN_ALARM) {
sch56xx_write_virtual_reg(data->addr,
SCH5636_REG_FAN_CTRL(i), val);
}
}
for (i = 0; i < 2; i++) {
val = sch56xx_read_virtual_reg(data->addr,
SCH5636_REG_FUJITSU_REV + i); if (val < 0) {
err = val; goto error;
}
revision[i] = val;
}
pr_info("Found %s chip at %#hx, revision: %d.%02d\n", DEVNAME,
data->addr, revision[0], revision[1]);
/* Read all temp + fan ctrl registers to determine which are active */ for (i = 0; i < SCH5636_NO_TEMPS; i++) {
val = sch56xx_read_virtual_reg(data->addr,
SCH5636_REG_TEMP_CTRL(i)); if (unlikely(val < 0)) {
err = val; goto error;
}
data->temp_ctrl[i] = val;
}
for (i = 0; i < SCH5636_NO_FANS; i++) {
val = sch56xx_read_virtual_reg(data->addr,
SCH5636_REG_FAN_CTRL(i)); if (unlikely(val < 0)) {
err = val; goto error;
}
data->fan_ctrl[i] = val;
}
for (i = 0; i < ARRAY_SIZE(sch5636_attr); i++) {
err = device_create_file(&pdev->dev,
&sch5636_attr[i].dev_attr); if (err) goto error;
}
for (i = 0; i < (SCH5636_NO_TEMPS * 3); i++) { if (data->temp_ctrl[i/3] & SCH5636_TEMP_DEACTIVATED) continue;
err = device_create_file(&pdev->dev,
&sch5636_temp_attr[i].dev_attr); if (err) goto error;
}
for (i = 0; i < (SCH5636_NO_FANS * 3); i++) { if (data->fan_ctrl[i/3] & SCH5636_FAN_DEACTIVATED) continue;
err = device_create_file(&pdev->dev,
&sch5636_fan_attr[i].dev_attr); if (err) goto error;
}
/* Note failing to register the watchdog is not a fatal error */
sch56xx_watchdog_register(&pdev->dev, data->addr, (revision[0] << 8) | revision[1],
&data->update_lock, 0);
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.