diff options
author | Jacek Anaszewski <j.anaszewski@samsung.com> | 2014-09-22 08:21:04 -0700 |
---|---|---|
committer | Bryan Wu <cooloney@gmail.com> | 2014-11-14 14:29:35 -0800 |
commit | acd899e4f3066b6662f6047da5b795cc762093cb (patch) | |
tree | 8a0cdf6849c1aec46d741ddee463067951a942ed /drivers/leds/led-triggers.c | |
parent | 3f6e42c808409c40dd0d0f8fe2022d197b27455e (diff) |
leds: implement sysfs interface locking mechanism
Add a mechanism for locking LED subsystem sysfs interface.
This patch prepares ground for addition of LED Flash Class
extension, whose API will be integrated with V4L2 Flash API.
Such a fusion enforces introducing a locking scheme, which
will secure consistent access to the LED Flash Class device.
The mechanism being introduced allows for disabling LED
subsystem sysfs interface by calling led_sysfs_disable function
and enabling it by calling led_sysfs_enable. The functions
alter the LED_SYSFS_DISABLE flag state and must be called
under mutex lock. The state of the lock is checked with use
of led_sysfs_is_disabled function. Such a design allows for
providing immediate feedback to the user space on whether
the LED Flash Class device is available or is under V4L2 Flash
sub-device control.
Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: Bryan Wu <cooloney@gmail.com>
Diffstat (limited to 'drivers/leds/led-triggers.c')
-rw-r--r-- | drivers/leds/led-triggers.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index c3734f10fdd5..e8b1120f486d 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -37,6 +37,14 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, char trigger_name[TRIG_NAME_MAX]; struct led_trigger *trig; size_t len; + int ret = count; + + mutex_lock(&led_cdev->led_access); + + if (led_sysfs_is_disabled(led_cdev)) { + ret = -EBUSY; + goto unlock; + } trigger_name[sizeof(trigger_name) - 1] = '\0'; strncpy(trigger_name, buf, sizeof(trigger_name) - 1); @@ -47,7 +55,7 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, if (!strcmp(trigger_name, "none")) { led_trigger_remove(led_cdev); - return count; + goto unlock; } down_read(&triggers_list_lock); @@ -58,12 +66,14 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, up_write(&led_cdev->trigger_lock); up_read(&triggers_list_lock); - return count; + goto unlock; } } up_read(&triggers_list_lock); - return -EINVAL; +unlock: + mutex_unlock(&led_cdev->led_access); + return ret; } EXPORT_SYMBOL_GPL(led_trigger_store); |