/*
led-triggers.c 分析:
1. 导出13个接口:
led_trigger_register() // 用于注册一个trigger
led_trigger_unregister() // 用于注销一个trigger
led_trigger_register_simple() // 用于注册一个trigger
led_trigger_unregister_simple() // 用于注销一个trigger
led_trigger_blink() // 触发闪烁、闪烁的时间 - 调用led-core.c中的led_blink_set()
led_trigger_event() // 触发亮灭 - 调用led-core.c中led_set_brightness()
led_trigger_store()
led_trigger_show()
led_trigger_set()
led_trigger_remove()
led_trigger_set_default()
led_trigger_rename_static()
led_trigger_register()
led_trigger_unregister()
led_trigger_blink_oneshot() // 闪烁一次
*/
#include <linux/module.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);
static 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);
char trigger_name[TRIG_NAME_MAX];
struct led_trigger *trig;
size_t len;
trigger_name[sizeof(trigger_name) - 1] = '\0';
strncpy(trigger_name, buf, sizeof(trigger_name) - 1);
len = strlen(trigger_name);
if (len && trigger_name[len - 1] == '\n')
trigger_name[len - 1] = '\0';
if (!strcmp(trigger_name, "none")) {
led_trigger_remove(led_cdev);
return count;
}
down_read(&triggers_list_lock);
list_for_each_entry(trig, &trigger_list, next_trig) {
if (!strcmp(trigger_name, 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);
return count;
}
}
up_read(&triggers_list_lock);
return -EINVAL;
}
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 l