aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorHenrique de Moraes Holschuh <hmh@hmh.eng.br>2007-07-18 22:45:48 -0400
committerLen Brown <len.brown@intel.com>2007-07-21 23:50:51 -0400
commitf432255e936a892a6896e5032e2b4897423076f2 (patch)
treece32df538477acab984d079d6963e0261c0d7325 /drivers/misc
parentc78d5c96bb65b71a54b7551b404fbaf4763ed6e4 (diff)
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: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Signed-off-by: Len Brown <len.brown@intel.com>
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)