Release 4.11 drivers/leds/led-triggers.c
/*
* LED Triggers Core
*
* Copyright 2005-2007 Openedhand Ltd.
*
* Author: Richard Purdie <rpurdie@openedhand.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/device.h>
#include <linux/timer.h>
#include <linux/rwsem.h>
#include <linux/leds.h>
#include <linux/slab.h>
#include "leds.h"
/*
* Nests outside led_cdev->trigger_lock
*/
static DECLARE_RWSEM(triggers_list_lock);
LIST_HEAD(trigger_list);
/* Used by LED Class */
ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
struct led_trigger *trig;
int ret = count;
mutex_lock(&led_cdev->led_access);
if (led_sysfs_is_disabled(led_cdev)) {
ret = -EBUSY;
goto unlock;
}
if (sysfs_streq(buf, "none")) {
led_trigger_remove(led_cdev);
goto unlock;
}
down_read(&triggers_list_lock);
list_for_each_entry(trig, &trigger_list, next_trig) {
if (sysfs_streq(buf, trig->name)) {
down_write(&led_cdev->trigger_lock);
led_trigger_set(led_cdev, trig);
up_write(&led_cdev->trigger_lock);
up_read(&triggers_list_lock);
goto unlock;
}
}
/* we come here only if buf matches no trigger */
ret = -EINVAL;
up_read(&triggers_list_lock);
unlock:
mutex_unlock(&led_cdev->led_access);
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Richard Purdie | 115 | 66.47% | 3 | 42.86% |
Jacek Anaszewski | 47 | 27.17% | 1 | 14.29% |
Heiner Kallweit | 10 | 5.78% | 2 | 28.57% |
Márton Németh | 1 | 0.58% | 1 | 14.29% |
Total | 173 | 100.00% | 7 | 100.00% |
EXPORT_SYMBOL_GPL(led_trigger_store);
ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
struct led_trigger *trig;
int len = 0;
down_read(&triggers_list_lock);
down_read(&led_cdev->trigger_lock);
if (!led_cdev->trigger)
len += scnprintf(buf+len, PAGE_SIZE - len, "[none] ");
else
len += scnprintf(buf+len, PAGE_SIZE - len, "none ");
list_for_each_entry(trig, &trigger_list, next_trig) {
if (led_cdev->trigger && !strcmp(led_cdev->trigger->name,
trig->name))
len += scnprintf(buf+len, PAGE_SIZE - len, "[%s] ",
trig->name);
else
len += scnprintf(buf+len, PAGE_SIZE - len, "%s ",
trig->name);
}
up_read(&led_cdev->trigger_lock);
up_read(&triggers_list_lock);
len += scnprintf(len+buf, PAGE_SIZE - len, "\n");
return len;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Richard Purdie | 167 | 86.98% | 3 | 75.00% |
Nathan Sullivan | 25 | 13.02% | 1 | 25.00% |
Total | 192 | 100.00% | 4 | 100.00% |
EXPORT_SYMBOL_GPL(led_trigger_show);
/* Caller must ensure led_cdev->trigger_lock held */
void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
{
unsigned long flags;
char *event = NULL;
char *envp[2];
const char *name;
if (!led_cdev->trigger && !trig)
return;
name = trig ? trig->name : "none";
event = kasprintf(GFP_KERNEL, "TRIGGER=%s", name);
/* Remove any existing trigger */
if (led_cdev->trigger) {
write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags);
list_del(&led_cdev->trig_list);
write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock,
flags);
cancel_work_sync(&led_cdev->set_brightness_work);
led_stop_software_blink(led_cdev);
if (led_cdev->trigger->deactivate)
led_cdev->trigger->deactivate(led_cdev);
led_cdev->trigger = NULL;
led_set_brightness(led_cdev, LED_OFF);
}
if (trig) {
write_lock_irqsave(&trig->leddev_list_lock, flags);
list_add_tail(&led_cdev->trig_list, &trig->led_cdevs);
write_unlock_irqrestore(&trig->leddev_list_lock, flags);
led_cdev->trigger = trig;
if (trig->activate)
trig->activate(led_cdev);
}
if (event) {
envp[0] = event;
envp[1] = NULL;
if (kobject_uevent_env(&led_cdev->dev->kobj, KOBJ_CHANGE, envp))
dev_err(led_cdev->dev,
"%s: Error sending uevent\n", __func__);
kfree(event);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Richard Purdie | 122 | 46.39% | 1 | 11.11% |
Colin Cross | 78 | 29.66% | 1 | 11.11% |
Jacek Anaszewski | 24 | 9.13% | 2 | 22.22% |
Fabio Baltieri | 13 | 4.94% | 1 | 11.11% |
Dmitry Baryshkov | 11 | 4.18% | 1 | 11.11% |
Bryan Wu | 8 | 3.04% | 1 | 11.11% |
Paul Collins | 6 | 2.28% | 1 | 11.11% |
Shuah Khan | 1 | 0.38% | 1 | 11.11% |
Total | 263 | 100.00% | 9 | 100.00% |
EXPORT_SYMBOL_GPL(led_trigger_set);
void led_trigger_remove(struct led_classdev *led_cdev)
{
down_write(&led_cdev->trigger_lock);
led_trigger_set(led_cdev, NULL);
up_write(&led_cdev->trigger_lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Márton Németh | 33 | 100.00% | 1 | 100.00% |
Total | 33 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL_GPL(led_trigger_remove);
void led_trigger_set_default(struct led_classdev *led_cdev)
{
struct led_trigger *trig;
if (!led_cdev->default_trigger)
return;
down_read(&triggers_list_lock);
down_write(&led_cdev->trigger_lock);
list_for_each_entry(trig, &trigger_list, next_trig) {
if (!strcmp(led_cdev->default_trigger, trig->name))
led_trigger_set(led_cdev, trig);
}
up_write(&led_cdev->trigger_lock);
up_read(&triggers_list_lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Richard Purdie | 82 | 100.00% | 2 | 100.00% |
Total | 82 | 100.00% | 2 | 100.00% |
EXPORT_SYMBOL_GPL(led_trigger_set_default);
void led_trigger_rename_static(const char *name, struct led_trigger *trig)
{
/* new name must be on a temporary string to prevent races */
BUG_ON(name == trig->name);
down_write(&triggers_list_lock);
/* this assumes that trig->name was originaly allocated to
* non constant storage */
strcpy((char *)trig->name, name);
up_write(&triggers_list_lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Fabio Baltieri | 51 | 100.00% | 1 | 100.00% |
Total | 51 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL_GPL(led_trigger_rename_static);
/* LED Trigger Interface */
int led_trigger_register(struct led_trigger *trig)
{
struct led_classdev *led_cdev;
struct led_trigger *_trig;
rwlock_init(&trig->leddev_list_lock);
INIT_LIST_HEAD(&trig->led_cdevs);
down_write(&triggers_list_lock);
/* Make sure the trigger's name isn't already in use */
list_for_each_entry(_trig, &trigger_list, next_trig) {
if (!strcmp(_trig->name, trig->name)) {
up_write(&triggers_list_lock);
return -EEXIST;
}
}
/* Add to the list of led triggers */
list_add_tail(&trig->next_trig, &trigger_list);
up_write(&triggers_list_lock);
/* Register with any LEDs that have this as a default trigger */
down_read(&leds_list_lock);
list_for_each_entry(led_cdev, &leds_list, node) {
down_write(&led_cdev->trigger_lock);
if (!led_cdev->trigger && led_cdev->default_trigger &&
!strcmp(led_cdev->default_trigger, trig->name))
led_trigger_set(led_cdev, trig);
up_write(&led_cdev->trigger_lock);
}
up_read(&leds_list_lock);
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Richard Purdie | 120 | 71.01% | 3 | 60.00% |
Adam Nielsen | 39 | 23.08% | 1 | 20.00% |
Bryan Wu | 10 | 5.92% | 1 | 20.00% |
Total | 169 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL_GPL(led_trigger_register);
void led_trigger_unregister(struct led_trigger *trig)
{
struct led_classdev *led_cdev;
if (list_empty_careful(&trig->next_trig))
return;
/* Remove from the list of led triggers */
down_write(&triggers_list_lock);
list_del_init(&trig->next_trig);
up_write(&triggers_list_lock);
/* Remove anyone actively using this trigger */
down_read(&leds_list_lock);
list_for_each_entry(led_cdev, &leds_list, node) {
down_write(&led_cdev->trigger_lock);
if (led_cdev->trigger == trig)
led_trigger_set(led_cdev, NULL);
up_write(&led_cdev->trigger_lock);
}
up_read(&leds_list_lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Richard Purdie | 86 | 85.15% | 3 | 60.00% |
Sasha Levin | 12 | 11.88% | 1 | 20.00% |
Bryan Wu | 3 | 2.97% | 1 | 20.00% |
Total | 101 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL_GPL(led_trigger_unregister);
static void devm_led_trigger_release(struct device *dev, void *res)
{
led_trigger_unregister(*(struct led_trigger **)res);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Heiner Kallweit | 27 | 100.00% | 1 | 100.00% |
Total | 27 | 100.00% | 1 | 100.00% |
int devm_led_trigger_register(struct device *dev,
struct led_trigger *trig)
{
struct led_trigger **dr;
int rc;
dr = devres_alloc(devm_led_trigger_release, sizeof(*dr),
GFP_KERNEL);
if (!dr)
return -ENOMEM;
*dr = trig;
rc = led_trigger_register(trig);
if (rc)
devres_free(dr);
else
devres_add(dev, dr);
return rc;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Heiner Kallweit | 80 | 100.00% | 1 | 100.00% |
Total | 80 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL_GPL(devm_led_trigger_register);
/* Simple LED Tigger Interface */
void led_trigger_event(struct led_trigger *trig,
enum led_brightness brightness)
{
struct led_classdev *led_cdev;
if (!trig)
return;
read_lock(&trig->leddev_list_lock);
list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list)
led_set_brightness(led_cdev, brightness);
read_unlock(&trig->leddev_list_lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Márton Németh | 27 | 48.21% | 2 | 28.57% |
Richard Purdie | 18 | 32.14% | 2 | 28.57% |
Bryan Wu | 5 | 8.93% | 1 | 14.29% |
Zhao, Gang | 5 | 8.93% | 1 | 14.29% |
Fabio Baltieri | 1 | 1.79% | 1 | 14.29% |
Total | 56 | 100.00% | 7 | 100.00% |
EXPORT_SYMBOL_GPL(led_trigger_event);
static void led_trigger_blink_setup(struct led_trigger *trig,
unsigned long *delay_on,
unsigned long *delay_off,
int oneshot,
int invert)
{
struct led_classdev *led_cdev;
if (!trig)
return;
read_lock(&trig->leddev_list_lock);
list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list) {
if (oneshot)
led_blink_set_oneshot(led_cdev, delay_on, delay_off,
invert);
else
led_blink_set(led_cdev, delay_on, delay_off);
}
read_unlock(&trig->leddev_list_lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Vasily Khoruzhick | 54 | 60.67% | 1 | 20.00% |
Fabio Baltieri | 23 | 25.84% | 1 | 20.00% |
Bryan Wu | 6 | 6.74% | 2 | 40.00% |
Zhao, Gang | 6 | 6.74% | 1 | 20.00% |
Total | 89 | 100.00% | 5 | 100.00% |
void led_trigger_blink(struct led_trigger *trig,
unsigned long *delay_on,
unsigned long *delay_off)
{
led_trigger_blink_setup(trig, delay_on, delay_off, 0, 0);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Fabio Baltieri | 33 | 100.00% | 1 | 100.00% |
Total | 33 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL_GPL(led_trigger_blink);
void led_trigger_blink_oneshot(struct led_trigger *trig,
unsigned long *delay_on,
unsigned long *delay_off,
int invert)
{
led_trigger_blink_setup(trig, delay_on, delay_off, 1, invert);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Fabio Baltieri | 36 | 100.00% | 1 | 100.00% |
Total | 36 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL_GPL(led_trigger_blink_oneshot);
void led_trigger_register_simple(const char *name, struct led_trigger **tp)
{
struct led_trigger *trig;
int err;
trig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
if (trig) {
trig->name = name;
err = led_trigger_register(trig);
if (err < 0) {
kfree(trig);
trig = NULL;
pr_warn("LED trigger %s failed to register (%d)\n",
name, err);
}
} else {
pr_warn("LED trigger %s failed to register (no memory)\n",
name);
}
*tp = trig;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Márton Németh | 62 | 63.92% | 1 | 20.00% |
Richard Purdie | 12 | 12.37% | 1 | 20.00% |
Masakazu Mokuno | 9 | 9.28% | 1 | 20.00% |
Bryan Wu | 8 | 8.25% | 1 | 20.00% |
Sachin Kamat | 6 | 6.19% | 1 | 20.00% |
Total | 97 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL_GPL(led_trigger_register_simple);
void led_trigger_unregister_simple(struct led_trigger *trig)
{
if (trig)
led_trigger_unregister(trig);
kfree(trig);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Márton Németh | 17 | 70.83% | 1 | 33.33% |
Bryan Wu | 4 | 16.67% | 1 | 33.33% |
Richard Purdie | 3 | 12.50% | 1 | 33.33% |
Total | 24 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL_GPL(led_trigger_unregister_simple);
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Richard Purdie | 782 | 48.18% | 5 | 15.62% |
Márton Németh | 173 | 10.66% | 2 | 6.25% |
Fabio Baltieri | 167 | 10.29% | 3 | 9.38% |
Heiner Kallweit | 122 | 7.52% | 3 | 9.38% |
Colin Cross | 78 | 4.81% | 1 | 3.12% |
Jacek Anaszewski | 71 | 4.37% | 3 | 9.38% |
Vasily Khoruzhick | 59 | 3.64% | 1 | 3.12% |
Bryan Wu | 44 | 2.71% | 2 | 6.25% |
Adam Nielsen | 39 | 2.40% | 1 | 3.12% |
Nathan Sullivan | 25 | 1.54% | 1 | 3.12% |
Sasha Levin | 12 | 0.74% | 1 | 3.12% |
Zhao, Gang | 11 | 0.68% | 1 | 3.12% |
Dmitry Baryshkov | 11 | 0.68% | 1 | 3.12% |
Masakazu Mokuno | 9 | 0.55% | 1 | 3.12% |
Paul Collins | 6 | 0.37% | 1 | 3.12% |
Sachin Kamat | 6 | 0.37% | 1 | 3.12% |
Ingo Molnar | 3 | 0.18% | 1 | 3.12% |
Tejun Heo | 3 | 0.18% | 1 | 3.12% |
Shuah Khan | 1 | 0.06% | 1 | 3.12% |
Paul Gortmaker | 1 | 0.06% | 1 | 3.12% |
Ezequiel García | | 0.00% | 0 | 0.00% |
Total | 1623 | 100.00% | 32 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.