Commit f432255e authored by Henrique de Moraes Holschuh's avatar Henrique de Moraes Holschuh Committed by Len Brown

ACPI: thinkpad-acpi: add locking to brightness subdriver

The backlight class does all the locking needed for sysfs access, but
offers no API to interface to that locking without an layer violation.

Since we need to mutex-lock procfs access, implement in-driver locking for
brightness.  It will go away the day thinkpad-acpi procfs goes away, or the
backlight class gives us a way to use its locks without a layer violation.
Signed-off-by: default avatarHenrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent c78d5c96
...@@ -3000,12 +3000,16 @@ static struct backlight_ops ibm_backlight_data = { ...@@ -3000,12 +3000,16 @@ static struct backlight_ops ibm_backlight_data = {
.update_status = brightness_update_status, .update_status = brightness_update_status,
}; };
static struct mutex brightness_mutex;
static int __init brightness_init(struct ibm_init_struct *iibm) static int __init brightness_init(struct ibm_init_struct *iibm)
{ {
int b; int b;
vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n"); vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n");
mutex_init(&brightness_mutex);
if (!brightness_mode) { if (!brightness_mode) {
if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
brightness_mode = 2; brightness_mode = 2;
...@@ -3092,27 +3096,44 @@ static int brightness_get(struct backlight_device *bd) ...@@ -3092,27 +3096,44 @@ static int brightness_get(struct backlight_device *bd)
static int brightness_set(int value) static int brightness_set(int value)
{ {
int cmos_cmd, inc, i; int cmos_cmd, inc, i, res;
int current_value = brightness_get(NULL); int current_value;
if (value > 7) if (value > 7)
return -EINVAL; return -EINVAL;
res = mutex_lock_interruptible(&brightness_mutex);
if (res < 0)
return res;
current_value = brightness_get(NULL);
if (current_value < 0) {
res = current_value;
goto errout;
}
cmos_cmd = value > current_value ? cmos_cmd = value > current_value ?
TP_CMOS_BRIGHTNESS_UP : TP_CMOS_BRIGHTNESS_UP :
TP_CMOS_BRIGHTNESS_DOWN; TP_CMOS_BRIGHTNESS_DOWN;
inc = value > current_value ? 1 : -1; inc = value > current_value ? 1 : -1;
res = 0;
for (i = current_value; i != value; i += inc) { for (i = current_value; i != value; i += inc) {
if ((brightness_mode & 2) && if ((brightness_mode & 2) &&
issue_thinkpad_cmos_command(cmos_cmd)) issue_thinkpad_cmos_command(cmos_cmd)) {
return -EIO; res = -EIO;
goto errout;
}
if ((brightness_mode & 1) && if ((brightness_mode & 1) &&
!acpi_ec_write(brightness_offset, i + inc)) !acpi_ec_write(brightness_offset, i + inc)) {
return -EIO; res = -EIO;
goto errout;;
}
} }
return 0; errout:
mutex_unlock(&brightness_mutex);
return res;
} }
static int brightness_read(char *p) static int brightness_read(char *p)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment