cregit-Linux how code gets into the kernel

Release 4.7 drivers/leds/trigger/ledtrig-transient.c

/*
 * LED Kernel Transient Trigger
 *
 * Copyright (C) 2012 Shuah Khan <shuahkhan@gmail.com>
 *
 * Based on Richard Purdie's ledtrig-timer.c and Atsushi Nemoto's
 * ledtrig-heartbeat.c
 * Design and use-case input from Jonas Bonn <jonas@southpole.se> and
 * Neil Brown <neilb@suse.de>
 *
 * 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.
 *
 */
/*
 * Transient trigger allows one shot timer activation. Please refer to
 * Documentation/leds/ledtrig-transient.txt for details
*/

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/leds.h>
#include "../leds.h"


struct transient_trig_data {
	
int activate;
	
int state;
	
int restore_state;
	
unsigned long duration;
	
struct timer_list timer;
};


static void transient_timer_function(unsigned long data) { struct led_classdev *led_cdev = (struct led_classdev *) data; struct transient_trig_data *transient_data = led_cdev->trigger_data; transient_data->activate = 0; led_set_brightness_nosleep(led_cdev, transient_data->restore_state); }

Contributors

PersonTokensPropCommitsCommitProp
shuah khanshuah khan4597.83%150.00%
jacek anaszewskijacek anaszewski12.17%150.00%
Total46100.00%2100.00%


static ssize_t transient_activate_show(struct device *dev, struct device_attribute *attr, char *buf) { struct led_classdev *led_cdev = dev_get_drvdata(dev); struct transient_trig_data *transient_data = led_cdev->trigger_data; return sprintf(buf, "%d\n", transient_data->activate); }

Contributors

PersonTokensPropCommitsCommitProp
shuah khanshuah khan51100.00%1100.00%
Total51100.00%1100.00%


static ssize_t transient_activate_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct led_classdev *led_cdev = dev_get_drvdata(dev); struct transient_trig_data *transient_data = led_cdev->trigger_data; unsigned long state; ssize_t ret; ret = kstrtoul(buf, 10, &state); if (ret) return ret; if (state != 1 && state != 0) return -EINVAL; /* cancel the running timer */ if (state == 0 && transient_data->activate == 1) { del_timer(&transient_data->timer); transient_data->activate = state; led_set_brightness_nosleep(led_cdev, transient_data->restore_state); return size; } /* start timer if there is no active timer */ if (state == 1 && transient_data->activate == 0 && transient_data->duration != 0) { transient_data->activate = state; led_set_brightness_nosleep(led_cdev, transient_data->state); transient_data->restore_state = (transient_data->state == LED_FULL) ? LED_OFF : LED_FULL; mod_timer(&transient_data->timer, jiffies + msecs_to_jiffies(transient_data->duration)); } /* state == 0 && transient_data->activate == 0 timer is not active - just return */ /* state == 1 && transient_data->activate == 1 timer is already active - just return */ return size; }

Contributors

PersonTokensPropCommitsCommitProp
shuah khanshuah khan19397.47%133.33%
rob herringrob herring31.52%133.33%
jacek anaszewskijacek anaszewski21.01%133.33%
Total198100.00%3100.00%


static ssize_t transient_duration_show(struct device *dev, struct device_attribute *attr, char *buf) { struct led_classdev *led_cdev = dev_get_drvdata(dev); struct transient_trig_data *transient_data = led_cdev->trigger_data; return sprintf(buf, "%lu\n", transient_data->duration); }

Contributors

PersonTokensPropCommitsCommitProp
shuah khanshuah khan51100.00%1100.00%
Total51100.00%1100.00%


static ssize_t transient_duration_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct led_classdev *led_cdev = dev_get_drvdata(dev); struct transient_trig_data *transient_data = led_cdev->trigger_data; unsigned long state; ssize_t ret; ret = kstrtoul(buf, 10, &state); if (ret) return ret; transient_data->duration = state; return size; }

Contributors

PersonTokensPropCommitsCommitProp
shuah khanshuah khan78100.00%1100.00%
Total78100.00%1100.00%


static ssize_t transient_state_show(struct device *dev, struct device_attribute *attr, char *buf) { struct led_classdev *led_cdev = dev_get_drvdata(dev); struct transient_trig_data *transient_data = led_cdev->trigger_data; int state; state = (transient_data->state == LED_FULL) ? 1 : 0; return sprintf(buf, "%d\n", state); }

Contributors

PersonTokensPropCommitsCommitProp
shuah khanshuah khan66100.00%1100.00%
Total66100.00%1100.00%


static ssize_t transient_state_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct led_classdev *led_cdev = dev_get_drvdata(dev); struct transient_trig_data *transient_data = led_cdev->trigger_data; unsigned long state; ssize_t ret; ret = kstrtoul(buf, 10, &state); if (ret) return ret; if (state != 1 && state != 0) return -EINVAL; transient_data->state = (state == 1) ? LED_FULL : LED_OFF; return size; }

Contributors

PersonTokensPropCommitsCommitProp
shuah khanshuah khan100100.00%1100.00%
Total100100.00%1100.00%

static DEVICE_ATTR(activate, 0644, transient_activate_show, transient_activate_store); static DEVICE_ATTR(duration, 0644, transient_duration_show, transient_duration_store); static DEVICE_ATTR(state, 0644, transient_state_show, transient_state_store);
static void transient_trig_activate(struct led_classdev *led_cdev) { int rc; struct transient_trig_data *tdata; tdata = kzalloc(sizeof(struct transient_trig_data), GFP_KERNEL); if (!tdata) { dev_err(led_cdev->dev, "unable to allocate transient trigger\n"); return; } led_cdev->trigger_data = tdata; rc = device_create_file(led_cdev->dev, &dev_attr_activate); if (rc) goto err_out; rc = device_create_file(led_cdev->dev, &dev_attr_duration); if (rc) goto err_out_duration; rc = device_create_file(led_cdev->dev, &dev_attr_state); if (rc) goto err_out_state; setup_timer(&tdata->timer, transient_timer_function, (unsigned long) led_cdev); led_cdev->activated = true; return; err_out_state: device_remove_file(led_cdev->dev, &dev_attr_duration); err_out_duration: device_remove_file(led_cdev->dev, &dev_attr_activate); err_out: dev_err(led_cdev->dev, "unable to register transient trigger\n"); led_cdev->trigger_data = NULL; kfree(tdata); }

Contributors

PersonTokensPropCommitsCommitProp
shuah khanshuah khan181100.00%1100.00%
Total181100.00%1100.00%


static void transient_trig_deactivate(struct led_classdev *led_cdev) { struct transient_trig_data *transient_data = led_cdev->trigger_data; if (led_cdev->activated) { del_timer_sync(&transient_data->timer); led_set_brightness_nosleep(led_cdev, transient_data->restore_state); device_remove_file(led_cdev->dev, &dev_attr_activate); device_remove_file(led_cdev->dev, &dev_attr_duration); device_remove_file(led_cdev->dev, &dev_attr_state); led_cdev->trigger_data = NULL; led_cdev->activated = false; kfree(transient_data); } }

Contributors

PersonTokensPropCommitsCommitProp
shuah khanshuah khan9198.91%150.00%
jacek anaszewskijacek anaszewski11.09%150.00%
Total92100.00%2100.00%

static struct led_trigger transient_trigger = { .name = "transient", .activate = transient_trig_activate, .deactivate = transient_trig_deactivate, };
static int __init transient_trig_init(void) { return led_trigger_register(&transient_trigger); }

Contributors

PersonTokensPropCommitsCommitProp
shuah khanshuah khan16100.00%1100.00%
Total16100.00%1100.00%


static void __exit transient_trig_exit(void) { led_trigger_unregister(&transient_trigger); }

Contributors

PersonTokensPropCommitsCommitProp
shuah khanshuah khan15100.00%1100.00%
Total15100.00%1100.00%

module_init(transient_trig_init); module_exit(transient_trig_exit); MODULE_AUTHOR("Shuah Khan <shuahkhan@gmail.com>"); MODULE_DESCRIPTION("Transient LED trigger"); MODULE_LICENSE("GPL");

Overall Contributors

PersonTokensPropCommitsCommitProp
shuah khanshuah khan101799.22%125.00%
jacek anaszewskijacek anaszewski40.39%125.00%
rob herringrob herring30.29%125.00%
kim milokim milo10.10%125.00%
Total1025100.00%4100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}