linux/arch/arm/kernel/leds.c
<<
>>
Prefs
   1/*
   2 * LED support code, ripped out of arch/arm/kernel/time.c
   3 *
   4 *  Copyright (C) 1994-2001 Russell King
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 */
  10#include <linux/export.h>
  11#include <linux/init.h>
  12#include <linux/sysdev.h>
  13#include <linux/syscore_ops.h>
  14#include <linux/string.h>
  15
  16#include <asm/leds.h>
  17
  18static void dummy_leds_event(led_event_t evt)
  19{
  20}
  21
  22void (*leds_event)(led_event_t) = dummy_leds_event;
  23
  24struct leds_evt_name {
  25        const char      name[8];
  26        int             on;
  27        int             off;
  28};
  29
  30static const struct leds_evt_name evt_names[] = {
  31        { "amber", led_amber_on, led_amber_off },
  32        { "blue",  led_blue_on,  led_blue_off  },
  33        { "green", led_green_on, led_green_off },
  34        { "red",   led_red_on,   led_red_off   },
  35};
  36
  37static ssize_t leds_store(struct sys_device *dev,
  38                        struct sysdev_attribute *attr,
  39                        const char *buf, size_t size)
  40{
  41        int ret = -EINVAL, len = strcspn(buf, " ");
  42
  43        if (len > 0 && buf[len] == '\0')
  44                len--;
  45
  46        if (strncmp(buf, "claim", len) == 0) {
  47                leds_event(led_claim);
  48                ret = size;
  49        } else if (strncmp(buf, "release", len) == 0) {
  50                leds_event(led_release);
  51                ret = size;
  52        } else {
  53                int i;
  54
  55                for (i = 0; i < ARRAY_SIZE(evt_names); i++) {
  56                        if (strlen(evt_names[i].name) != len ||
  57                            strncmp(buf, evt_names[i].name, len) != 0)
  58                                continue;
  59                        if (strncmp(buf+len, " on", 3) == 0) {
  60                                leds_event(evt_names[i].on);
  61                                ret = size;
  62                        } else if (strncmp(buf+len, " off", 4) == 0) {
  63                                leds_event(evt_names[i].off);
  64                                ret = size;
  65                        }
  66                        break;
  67                }
  68        }
  69        return ret;
  70}
  71
  72static SYSDEV_ATTR(event, 0200, NULL, leds_store);
  73
  74static struct sysdev_class leds_sysclass = {
  75        .name           = "leds",
  76};
  77
  78static struct sys_device leds_device = {
  79        .id             = 0,
  80        .cls            = &leds_sysclass,
  81};
  82
  83static int leds_suspend(void)
  84{
  85        leds_event(led_stop);
  86        return 0;
  87}
  88
  89static void leds_resume(void)
  90{
  91        leds_event(led_start);
  92}
  93
  94static void leds_shutdown(void)
  95{
  96        leds_event(led_halted);
  97}
  98
  99static struct syscore_ops leds_syscore_ops = {
 100        .shutdown       = leds_shutdown,
 101        .suspend        = leds_suspend,
 102        .resume         = leds_resume,
 103};
 104
 105static int __init leds_init(void)
 106{
 107        int ret;
 108        ret = sysdev_class_register(&leds_sysclass);
 109        if (ret == 0)
 110                ret = sysdev_register(&leds_device);
 111        if (ret == 0)
 112                ret = sysdev_create_file(&leds_device, &attr_event);
 113        if (ret == 0)
 114                register_syscore_ops(&leds_syscore_ops);
 115        return ret;
 116}
 117
 118device_initcall(leds_init);
 119
 120EXPORT_SYMBOL(leds_event);
 121