cregit-Linux how code gets into the kernel

Release 4.11 drivers/leds/led-triggers.c

Directory: drivers/leds
/*
 * 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

PersonTokensPropCommitsCommitProp
Richard Purdie11566.47%342.86%
Jacek Anaszewski4727.17%114.29%
Heiner Kallweit105.78%228.57%
Márton Németh10.58%114.29%
Total173100.00%7100.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

PersonTokensPropCommitsCommitProp
Richard Purdie16786.98%375.00%
Nathan Sullivan2513.02%125.00%
Total192100.00%4100.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

PersonTokensPropCommitsCommitProp
Richard Purdie12246.39%111.11%
Colin Cross7829.66%111.11%
Jacek Anaszewski249.13%222.22%
Fabio Baltieri134.94%111.11%
Dmitry Baryshkov114.18%111.11%
Bryan Wu83.04%111.11%
Paul Collins62.28%111.11%
Shuah Khan10.38%111.11%
Total263100.00%9100.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

PersonTokensPropCommitsCommitProp
Márton Németh33100.00%1100.00%
Total33100.00%1100.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

PersonTokensPropCommitsCommitProp
Richard Purdie82100.00%2100.00%
Total82100.00%2100.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

PersonTokensPropCommitsCommitProp
Fabio Baltieri51100.00%1100.00%
Total51100.00%1100.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

PersonTokensPropCommitsCommitProp
Richard Purdie12071.01%360.00%
Adam Nielsen3923.08%120.00%
Bryan Wu105.92%120.00%
Total169100.00%5100.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

PersonTokensPropCommitsCommitProp
Richard Purdie8685.15%360.00%
Sasha Levin1211.88%120.00%
Bryan Wu32.97%120.00%
Total101100.00%5100.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

PersonTokensPropCommitsCommitProp
Heiner Kallweit27100.00%1100.00%
Total27100.00%1100.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

PersonTokensPropCommitsCommitProp
Heiner Kallweit80100.00%1100.00%
Total80100.00%1100.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

PersonTokensPropCommitsCommitProp
Márton Németh2748.21%228.57%
Richard Purdie1832.14%228.57%
Bryan Wu58.93%114.29%
Zhao, Gang58.93%114.29%
Fabio Baltieri11.79%114.29%
Total56100.00%7100.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

PersonTokensPropCommitsCommitProp
Vasily Khoruzhick5460.67%120.00%
Fabio Baltieri2325.84%120.00%
Bryan Wu66.74%240.00%
Zhao, Gang66.74%120.00%
Total89100.00%5100.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

PersonTokensPropCommitsCommitProp
Fabio Baltieri33100.00%1100.00%
Total33100.00%1100.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

PersonTokensPropCommitsCommitProp
Fabio Baltieri36100.00%1100.00%
Total36100.00%1100.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

PersonTokensPropCommitsCommitProp
Márton Németh6263.92%120.00%
Richard Purdie1212.37%120.00%
Masakazu Mokuno99.28%120.00%
Bryan Wu88.25%120.00%
Sachin Kamat66.19%120.00%
Total97100.00%5100.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

PersonTokensPropCommitsCommitProp
Márton Németh1770.83%133.33%
Bryan Wu416.67%133.33%
Richard Purdie312.50%133.33%
Total24100.00%3100.00%

EXPORT_SYMBOL_GPL(led_trigger_unregister_simple);

Overall Contributors

PersonTokensPropCommitsCommitProp
Richard Purdie78248.18%515.62%
Márton Németh17310.66%26.25%
Fabio Baltieri16710.29%39.38%
Heiner Kallweit1227.52%39.38%
Colin Cross784.81%13.12%
Jacek Anaszewski714.37%39.38%
Vasily Khoruzhick593.64%13.12%
Bryan Wu442.71%26.25%
Adam Nielsen392.40%13.12%
Nathan Sullivan251.54%13.12%
Sasha Levin120.74%13.12%
Zhao, Gang110.68%13.12%
Dmitry Baryshkov110.68%13.12%
Masakazu Mokuno90.55%13.12%
Paul Collins60.37%13.12%
Sachin Kamat60.37%13.12%
Ingo Molnar30.18%13.12%
Tejun Heo30.18%13.12%
Shuah Khan10.06%13.12%
Paul Gortmaker10.06%13.12%
Ezequiel García0.00%00.00%
Total1623100.00%32100.00%
Directory: drivers/leds
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.