diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index e8de5e349d214e1fedc522aee812f04d52557250..9275dfc130f220a54e393c6b436a30ae8888112a 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -1738,36 +1738,90 @@ static int fan_init(void) return 0; } -static int fan_read(char *p) +static int fan_get_status(u8 *status) { - int len = 0; - u8 lo, hi, status; + u8 s; switch (fan_status_access_mode) { case IBMACPI_FAN_RD_ACPI_GFAN: /* 570, 600e/x, 770e, 770x */ - if (unlikely(!acpi_evalf(gfan_handle, &status, NULL, "d"))) + + if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d"))) return -EIO; - len += sprintf(p + len, "level:\t\t%d\n", status); + if (likely(status)) + *status = s & 0x07; break; case IBMACPI_FAN_RD_TPEC: /* all except 570, 600e/x, 770e, 770x */ - if (unlikely(!acpi_ec_read(fan_status_offset, &status))) + if (unlikely(!acpi_ec_read(fan_status_offset, &s))) return -EIO; - else - len += sprintf(p + len, "status:\t\t%s\n", - enabled(status, 7)); + if (likely(status)) + *status = s; + + break; + + default: + return -ENXIO; + } + + return 0; +} + +static int fan_get_speed(unsigned int *speed) +{ + u8 hi, lo; + + switch (fan_status_access_mode) { + case IBMACPI_FAN_RD_TPEC: + /* all except 570, 600e/x, 770e, 770x */ if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) || !acpi_ec_read(fan_rpm_offset + 1, &hi))) return -EIO; - else - len += sprintf(p + len, "speed:\t\t%d\n", - (hi << 8) + lo); + if (likely(speed)) + *speed = (hi << 8) | lo; + + break; + + default: + return -ENXIO; + } + + return 0; +} + +static int fan_read(char *p) +{ + int len = 0; + int rc; + u8 status; + unsigned int speed = 0; + + switch (fan_status_access_mode) { + case IBMACPI_FAN_RD_ACPI_GFAN: + /* 570, 600e/x, 770e, 770x */ + if ((rc = fan_get_status(&status)) < 0) + return rc; + + len += sprintf(p + len, "level:\t\t%d\n", status); + + break; + + case IBMACPI_FAN_RD_TPEC: + /* all except 570, 600e/x, 770e, 770x */ + if ((rc = fan_get_status(&status)) < 0) + return rc; + + len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 7)); + + if ((rc = fan_get_speed(&speed)) < 0) + return rc; + + len += sprintf(p + len, "speed:\t\t%d\n", speed); break; case IBMACPI_FAN_NONE: