vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
IBM_ACPIHANDLE_INIT(hkey);
+ mutex_init(&hotkey_mutex);
/* hotkey not supported on 570 */
tp_features.hotkey = hkey_handle != NULL;
}
}
+/*
+ * Call with hotkey_mutex held
+ */
static int hotkey_get(int *status, int *mask)
{
if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))
return 0;
}
+/*
+ * Call with hotkey_mutex held
+ */
static int hotkey_set(int status, int mask)
{
int i;
return len;
}
+ res = mutex_lock_interruptible(&hotkey_mutex);
+ if (res < 0)
+ return res;
res = hotkey_get(&status, &mask);
+ mutex_unlock(&hotkey_mutex);
if (res)
return res;
if (!tp_features.hotkey)
return -ENODEV;
+ res = mutex_lock_interruptible(&hotkey_mutex);
+ if (res < 0)
+ return res;
+
res = hotkey_get(&status, &mask);
if (res)
- return res;
+ goto errexit;
+ res = 0;
while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "enable") == 0) {
status = 1;
/* mask set */
} else if (sscanf(cmd, "%x", &mask) == 1) {
/* mask set */
- } else
- return -EINVAL;
+ } else {
+ res = -EINVAL;
+ goto errexit;
+ }
do_cmd = 1;
}
- if (do_cmd) {
+ if (do_cmd)
res = hotkey_set(status, mask);
- if (res)
- return res;
- }
- return 0;
+errexit:
+ mutex_unlock(&hotkey_mutex);
+ return res;
}
static struct tp_acpi_drv_struct ibm_hotkey_acpidriver = {
{
vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n");
+ mutex_init(&fan_mutex);
fan_status_access_mode = TPACPI_FAN_NONE;
fan_control_access_mode = TPACPI_FAN_WR_NONE;
fan_control_commands = 0;
static int fan_set_level(int level)
{
+ int res;
+
switch (fan_control_access_mode) {
case TPACPI_FAN_WR_ACPI_SFAN:
if (level >= 0 && level <= 7) {
- if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level))
+ res = mutex_lock_interruptible(&fan_mutex);
+ if (res < 0)
+ return res;
+ res = acpi_evalf(sfan_handle, NULL, NULL, "vd", level);
+ mutex_unlock(&fan_mutex);
+ if (!res)
return -EIO;
} else
return -EINVAL;
((level < 0) || (level > 7)))
return -EINVAL;
- if (!acpi_ec_write(fan_status_offset, level))
+ res = mutex_lock_interruptible(&fan_mutex);
+ if (res < 0)
+ return res;
+ res = acpi_ec_write(fan_status_offset, level);
+ mutex_unlock(&fan_mutex);
+ if (!res)
return -EIO;
else
tp_features.fan_ctrl_status_undef = 0;
u8 s;
int rc;
+ rc = mutex_lock_interruptible(&fan_mutex);
+ if (rc < 0)
+ return rc;
+
switch (fan_control_access_mode) {
case TPACPI_FAN_WR_ACPI_FANS:
case TPACPI_FAN_WR_TPEC:
- if ((rc = fan_get_status(&s)) < 0)
- return rc;
+ rc = fan_get_status(&s);
+ if (rc < 0)
+ break;
/* Don't go out of emergency fan mode */
if (s != 7)
s = TP_EC_FAN_AUTO;
if (!acpi_ec_write(fan_status_offset, s))
- return -EIO;
- else
+ rc = -EIO;
+ else {
tp_features.fan_ctrl_status_undef = 0;
+ rc = 0;
+ }
break;
case TPACPI_FAN_WR_ACPI_SFAN:
- if ((rc = fan_get_status(&s)) < 0)
- return rc;
+ rc = fan_get_status(&s);
+ if (rc < 0)
+ break;
s &= 0x07;
s = 4;
if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s))
- return -EIO;
+ rc= -EIO;
+ else
+ rc = 0;
break;
default:
- return -ENXIO;
+ rc = -ENXIO;
}
- return 0;
+
+ mutex_unlock(&fan_mutex);
+ return rc;
}
static int fan_set_disable(void)
{
+ int rc;
+
+ rc = mutex_lock_interruptible(&fan_mutex);
+ if (rc < 0)
+ return rc;
+
+ rc = 0;
switch (fan_control_access_mode) {
case TPACPI_FAN_WR_ACPI_FANS:
case TPACPI_FAN_WR_TPEC:
if (!acpi_ec_write(fan_status_offset, 0x00))
- return -EIO;
+ rc = -EIO;
else
tp_features.fan_ctrl_status_undef = 0;
break;
case TPACPI_FAN_WR_ACPI_SFAN:
if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00))
- return -EIO;
+ rc = -EIO;
break;
default:
- return -ENXIO;
+ rc = -ENXIO;
}
- return 0;
+
+ mutex_unlock(&fan_mutex);
+ return rc;
}
static int fan_set_speed(int speed)
{
+ int rc;
+
+ rc = mutex_lock_interruptible(&fan_mutex);
+ if (rc < 0)
+ return rc;
+
+ rc = 0;
switch (fan_control_access_mode) {
case TPACPI_FAN_WR_ACPI_FANS:
if (speed >= 0 && speed <= 65535) {
if (!acpi_evalf(fans_handle, NULL, NULL, "vddd",
speed, speed, speed))
- return -EIO;
+ rc = -EIO;
} else
- return -EINVAL;
+ rc = -EINVAL;
break;
default:
- return -ENXIO;
+ rc = -ENXIO;
}
- return 0;
+
+ mutex_unlock(&fan_mutex);
+ return rc;
}
static int fan_read(char *p)