aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/thinkpad_acpi.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 01bed937d387..f15a58f7403f 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -3000,12 +3000,16 @@ static struct backlight_ops ibm_backlight_data = {
3000 .update_status = brightness_update_status, 3000 .update_status = brightness_update_status,
3001}; 3001};
3002 3002
3003static struct mutex brightness_mutex;
3004
3003static int __init brightness_init(struct ibm_init_struct *iibm) 3005static int __init brightness_init(struct ibm_init_struct *iibm)
3004{ 3006{
3005 int b; 3007 int b;
3006 3008
3007 vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n"); 3009 vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n");
3008 3010
3011 mutex_init(&brightness_mutex);
3012
3009 if (!brightness_mode) { 3013 if (!brightness_mode) {
3010 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) 3014 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
3011 brightness_mode = 2; 3015 brightness_mode = 2;
@@ -3092,27 +3096,44 @@ static int brightness_get(struct backlight_device *bd)
3092 3096
3093static int brightness_set(int value) 3097static int brightness_set(int value)
3094{ 3098{
3095 int cmos_cmd, inc, i; 3099 int cmos_cmd, inc, i, res;
3096 int current_value = brightness_get(NULL); 3100 int current_value;
3097 3101
3098 if (value > 7) 3102 if (value > 7)
3099 return -EINVAL; 3103 return -EINVAL;
3100 3104
3105 res = mutex_lock_interruptible(&brightness_mutex);
3106 if (res < 0)
3107 return res;
3108
3109 current_value = brightness_get(NULL);
3110 if (current_value < 0) {
3111 res = current_value;
3112 goto errout;
3113 }
3114
3101 cmos_cmd = value > current_value ? 3115 cmos_cmd = value > current_value ?
3102 TP_CMOS_BRIGHTNESS_UP : 3116 TP_CMOS_BRIGHTNESS_UP :
3103 TP_CMOS_BRIGHTNESS_DOWN; 3117 TP_CMOS_BRIGHTNESS_DOWN;
3104 inc = value > current_value ? 1 : -1; 3118 inc = value > current_value ? 1 : -1;
3105 3119
3120 res = 0;
3106 for (i = current_value; i != value; i += inc) { 3121 for (i = current_value; i != value; i += inc) {
3107 if ((brightness_mode & 2) && 3122 if ((brightness_mode & 2) &&
3108 issue_thinkpad_cmos_command(cmos_cmd)) 3123 issue_thinkpad_cmos_command(cmos_cmd)) {
3109 return -EIO; 3124 res = -EIO;
3125 goto errout;
3126 }
3110 if ((brightness_mode & 1) && 3127 if ((brightness_mode & 1) &&
3111 !acpi_ec_write(brightness_offset, i + inc)) 3128 !acpi_ec_write(brightness_offset, i + inc)) {
3112 return -EIO; 3129 res = -EIO;
3130 goto errout;;
3131 }
3113 } 3132 }
3114 3133
3115 return 0; 3134errout:
3135 mutex_unlock(&brightness_mutex);
3136 return res;
3116} 3137}
3117 3138
3118static int brightness_read(char *p) 3139static int brightness_read(char *p)