cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ledtrig-timer.c (3383B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * LED Kernel Timer Trigger
      4 *
      5 * Copyright 2005-2006 Openedhand Ltd.
      6 *
      7 * Author: Richard Purdie <rpurdie@openedhand.com>
      8 */
      9
     10#include <linux/module.h>
     11#include <linux/kernel.h>
     12#include <linux/init.h>
     13#include <linux/device.h>
     14#include <linux/ctype.h>
     15#include <linux/slab.h>
     16#include <linux/leds.h>
     17
     18static ssize_t led_delay_on_show(struct device *dev,
     19		struct device_attribute *attr, char *buf)
     20{
     21	struct led_classdev *led_cdev = led_trigger_get_led(dev);
     22
     23	return sprintf(buf, "%lu\n", led_cdev->blink_delay_on);
     24}
     25
     26static ssize_t led_delay_on_store(struct device *dev,
     27		struct device_attribute *attr, const char *buf, size_t size)
     28{
     29	struct led_classdev *led_cdev = led_trigger_get_led(dev);
     30	unsigned long state;
     31	ssize_t ret;
     32
     33	ret = kstrtoul(buf, 10, &state);
     34	if (ret)
     35		return ret;
     36
     37	led_blink_set(led_cdev, &state, &led_cdev->blink_delay_off);
     38	led_cdev->blink_delay_on = state;
     39
     40	return size;
     41}
     42
     43static ssize_t led_delay_off_show(struct device *dev,
     44		struct device_attribute *attr, char *buf)
     45{
     46	struct led_classdev *led_cdev = led_trigger_get_led(dev);
     47
     48	return sprintf(buf, "%lu\n", led_cdev->blink_delay_off);
     49}
     50
     51static ssize_t led_delay_off_store(struct device *dev,
     52		struct device_attribute *attr, const char *buf, size_t size)
     53{
     54	struct led_classdev *led_cdev = led_trigger_get_led(dev);
     55	unsigned long state;
     56	ssize_t ret;
     57
     58	ret = kstrtoul(buf, 10, &state);
     59	if (ret)
     60		return ret;
     61
     62	led_blink_set(led_cdev, &led_cdev->blink_delay_on, &state);
     63	led_cdev->blink_delay_off = state;
     64
     65	return size;
     66}
     67
     68static DEVICE_ATTR(delay_on, 0644, led_delay_on_show, led_delay_on_store);
     69static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store);
     70
     71static struct attribute *timer_trig_attrs[] = {
     72	&dev_attr_delay_on.attr,
     73	&dev_attr_delay_off.attr,
     74	NULL
     75};
     76ATTRIBUTE_GROUPS(timer_trig);
     77
     78static void pattern_init(struct led_classdev *led_cdev)
     79{
     80	u32 *pattern;
     81	unsigned int size = 0;
     82
     83	pattern = led_get_default_pattern(led_cdev, &size);
     84	if (!pattern)
     85		return;
     86
     87	if (size != 2) {
     88		dev_warn(led_cdev->dev,
     89			 "Expected 2 but got %u values for delays pattern\n",
     90			 size);
     91		goto out;
     92	}
     93
     94	led_cdev->blink_delay_on = pattern[0];
     95	led_cdev->blink_delay_off = pattern[1];
     96	/* led_blink_set() called by caller */
     97
     98out:
     99	kfree(pattern);
    100}
    101
    102static int timer_trig_activate(struct led_classdev *led_cdev)
    103{
    104	if (led_cdev->flags & LED_INIT_DEFAULT_TRIGGER) {
    105		pattern_init(led_cdev);
    106		/*
    107		 * Mark as initialized even on pattern_init() error because
    108		 * any consecutive call to it would produce the same error.
    109		 */
    110		led_cdev->flags &= ~LED_INIT_DEFAULT_TRIGGER;
    111	}
    112
    113	/*
    114	 * If "set brightness to 0" is pending in workqueue, we don't
    115	 * want that to be reordered after blink_set()
    116	 */
    117	flush_work(&led_cdev->set_brightness_work);
    118	led_blink_set(led_cdev, &led_cdev->blink_delay_on,
    119		      &led_cdev->blink_delay_off);
    120
    121	return 0;
    122}
    123
    124static void timer_trig_deactivate(struct led_classdev *led_cdev)
    125{
    126	/* Stop blinking */
    127	led_set_brightness(led_cdev, LED_OFF);
    128}
    129
    130static struct led_trigger timer_led_trigger = {
    131	.name     = "timer",
    132	.activate = timer_trig_activate,
    133	.deactivate = timer_trig_deactivate,
    134	.groups = timer_trig_groups,
    135};
    136module_led_trigger(timer_led_trigger);
    137
    138MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
    139MODULE_DESCRIPTION("Timer LED trigger");
    140MODULE_LICENSE("GPL v2");