aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/leds.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /arch/arm/kernel/leds.c
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'arch/arm/kernel/leds.c')
-rw-r--r--arch/arm/kernel/leds.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/arch/arm/kernel/leds.c b/arch/arm/kernel/leds.c
new file mode 100644
index 00000000000..136e8376a3e
--- /dev/null
+++ b/arch/arm/kernel/leds.c
@@ -0,0 +1,144 @@
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/module.h>
11#include <linux/init.h>
12#include <linux/notifier.h>
13#include <linux/cpu.h>
14#include <linux/sysdev.h>
15#include <linux/syscore_ops.h>
16
17#include <asm/leds.h>
18
19static void dummy_leds_event(led_event_t evt)
20{
21}
22
23void (*leds_event)(led_event_t) = dummy_leds_event;
24
25struct leds_evt_name {
26 const char name[8];
27 int on;
28 int off;
29};
30
31static const struct leds_evt_name evt_names[] = {
32 { "amber", led_amber_on, led_amber_off },
33 { "blue", led_blue_on, led_blue_off },
34 { "green", led_green_on, led_green_off },
35 { "red", led_red_on, led_red_off },
36};
37
38static ssize_t leds_store(struct sys_device *dev,
39 struct sysdev_attribute *attr,
40 const char *buf, size_t size)
41{
42 int ret = -EINVAL, len = strcspn(buf, " ");
43
44 if (len > 0 && buf[len] == '\0')
45 len--;
46
47 if (strncmp(buf, "claim", len) == 0) {
48 leds_event(led_claim);
49 ret = size;
50 } else if (strncmp(buf, "release", len) == 0) {
51 leds_event(led_release);
52 ret = size;
53 } else {
54 int i;
55
56 for (i = 0; i < ARRAY_SIZE(evt_names); i++) {
57 if (strlen(evt_names[i].name) != len ||
58 strncmp(buf, evt_names[i].name, len) != 0)
59 continue;
60 if (strncmp(buf+len, " on", 3) == 0) {
61 leds_event(evt_names[i].on);
62 ret = size;
63 } else if (strncmp(buf+len, " off", 4) == 0) {
64 leds_event(evt_names[i].off);
65 ret = size;
66 }
67 break;
68 }
69 }
70 return ret;
71}
72
73static SYSDEV_ATTR(event, 0200, NULL, leds_store);
74
75static struct sysdev_class leds_sysclass = {
76 .name = "leds",
77};
78
79static struct sys_device leds_device = {
80 .id = 0,
81 .cls = &leds_sysclass,
82};
83
84static int leds_suspend(void)
85{
86 leds_event(led_stop);
87 return 0;
88}
89
90static void leds_resume(void)
91{
92 leds_event(led_start);
93}
94
95static void leds_shutdown(void)
96{
97 leds_event(led_halted);
98}
99
100static struct syscore_ops leds_syscore_ops = {
101 .shutdown = leds_shutdown,
102 .suspend = leds_suspend,
103 .resume = leds_resume,
104};
105
106static int leds_idle_notifier(struct notifier_block *nb, unsigned long val,
107 void *data)
108{
109 switch (val) {
110 case IDLE_START:
111 leds_event(led_idle_start);
112 break;
113 case IDLE_END:
114 leds_event(led_idle_end);
115 break;
116 }
117
118 return 0;
119}
120
121static struct notifier_block leds_idle_nb = {
122 .notifier_call = leds_idle_notifier,
123};
124
125static int __init leds_init(void)
126{
127 int ret;
128 ret = sysdev_class_register(&leds_sysclass);
129 if (ret == 0)
130 ret = sysdev_register(&leds_device);
131 if (ret == 0)
132 ret = sysdev_create_file(&leds_device, &attr_event);
133
134 if (ret == 0) {
135 register_syscore_ops(&leds_syscore_ops);
136 idle_notifier_register(&leds_idle_nb);
137 }
138
139 return ret;
140}
141
142device_initcall(leds_init);
143
144EXPORT_SYMBOL(leds_event);