diff options
Diffstat (limited to 'arch/arm/mach-integrator')
-rw-r--r-- | arch/arm/mach-integrator/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/mach-integrator/core.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-integrator/leds.c | 161 |
3 files changed, 99 insertions, 66 deletions
diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile index ebeef966e1f5..5521d18bf19a 100644 --- a/arch/arm/mach-integrator/Makefile +++ b/arch/arm/mach-integrator/Makefile | |||
@@ -4,11 +4,10 @@ | |||
4 | 4 | ||
5 | # Object file lists. | 5 | # Object file lists. |
6 | 6 | ||
7 | obj-y := core.o lm.o | 7 | obj-y := core.o lm.o leds.o |
8 | obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o | 8 | obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o |
9 | obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o | 9 | obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o |
10 | 10 | ||
11 | obj-$(CONFIG_LEDS) += leds.o | ||
12 | obj-$(CONFIG_PCI) += pci_v3.o pci.o | 11 | obj-$(CONFIG_PCI) += pci_v3.o pci.o |
13 | obj-$(CONFIG_CPU_FREQ_INTEGRATOR) += cpu.o | 12 | obj-$(CONFIG_CPU_FREQ_INTEGRATOR) += cpu.o |
14 | obj-$(CONFIG_INTEGRATOR_IMPD1) += impd1.o | 13 | obj-$(CONFIG_INTEGRATOR_IMPD1) += impd1.o |
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 8c5356255a59..0c7c4ef0f7c1 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <mach/cm.h> | 28 | #include <mach/cm.h> |
29 | #include <mach/irqs.h> | 29 | #include <mach/irqs.h> |
30 | 30 | ||
31 | #include <asm/leds.h> | ||
32 | #include <asm/mach-types.h> | 31 | #include <asm/mach-types.h> |
33 | #include <asm/mach/time.h> | 32 | #include <asm/mach/time.h> |
34 | #include <asm/pgtable.h> | 33 | #include <asm/pgtable.h> |
diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c index 466defa97842..7a7f6d3273bf 100644 --- a/arch/arm/mach-integrator/leds.c +++ b/arch/arm/mach-integrator/leds.c | |||
@@ -1,90 +1,125 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-integrator/leds.c | 2 | * Driver for the 4 user LEDs found on the Integrator AP/CP baseboard |
3 | * Based on Versatile and RealView machine LED code | ||
3 | * | 4 | * |
4 | * Integrator/AP and Integrator/CP LED control routines | 5 | * License terms: GNU General Public License (GPL) version 2 |
5 | * | 6 | * Author: Bryan Wu <bryan.wu@canonical.com> |
6 | * Copyright (C) 1999 ARM Limited | ||
7 | * Copyright (C) 2000 Deep Blue Solutions Ltd | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | 7 | */ |
23 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
24 | #include <linux/init.h> | 9 | #include <linux/init.h> |
25 | #include <linux/smp.h> | ||
26 | #include <linux/spinlock.h> | ||
27 | #include <linux/io.h> | 10 | #include <linux/io.h> |
11 | #include <linux/slab.h> | ||
12 | #include <linux/leds.h> | ||
28 | 13 | ||
14 | #include <mach/cm.h> | ||
29 | #include <mach/hardware.h> | 15 | #include <mach/hardware.h> |
30 | #include <mach/platform.h> | 16 | #include <mach/platform.h> |
31 | #include <asm/leds.h> | ||
32 | #include <asm/mach-types.h> | ||
33 | #include <mach/cm.h> | ||
34 | 17 | ||
35 | static int saved_leds; | 18 | #if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS) |
19 | |||
20 | #define ALPHA_REG __io_address(INTEGRATOR_DBG_BASE) | ||
21 | #define LEDREG (__io_address(INTEGRATOR_DBG_BASE) + INTEGRATOR_DBG_LEDS_OFFSET) | ||
36 | 22 | ||
37 | static void integrator_leds_event(led_event_t ledevt) | 23 | struct integrator_led { |
24 | struct led_classdev cdev; | ||
25 | u8 mask; | ||
26 | }; | ||
27 | |||
28 | /* | ||
29 | * The triggers lines up below will only be used if the | ||
30 | * LED triggers are compiled in. | ||
31 | */ | ||
32 | static const struct { | ||
33 | const char *name; | ||
34 | const char *trigger; | ||
35 | } integrator_leds[] = { | ||
36 | { "integrator:green0", "heartbeat", }, | ||
37 | { "integrator:yellow", }, | ||
38 | { "integrator:red", }, | ||
39 | { "integrator:green1", }, | ||
40 | { "integrator:core_module", "cpu0", }, | ||
41 | }; | ||
42 | |||
43 | static void integrator_led_set(struct led_classdev *cdev, | ||
44 | enum led_brightness b) | ||
38 | { | 45 | { |
39 | unsigned long flags; | 46 | struct integrator_led *led = container_of(cdev, |
40 | const unsigned int dbg_base = IO_ADDRESS(INTEGRATOR_DBG_BASE); | 47 | struct integrator_led, cdev); |
41 | unsigned int update_alpha_leds; | 48 | u32 reg = __raw_readl(LEDREG); |
42 | 49 | ||
43 | // yup, change the LEDs | 50 | if (b != LED_OFF) |
44 | local_irq_save(flags); | 51 | reg |= led->mask; |
45 | update_alpha_leds = 0; | 52 | else |
53 | reg &= ~led->mask; | ||
46 | 54 | ||
47 | switch(ledevt) { | 55 | while (__raw_readl(ALPHA_REG) & 1) |
48 | case led_idle_start: | 56 | cpu_relax(); |
49 | cm_control(CM_CTRL_LED, 0); | ||
50 | break; | ||
51 | 57 | ||
52 | case led_idle_end: | 58 | __raw_writel(reg, LEDREG); |
53 | cm_control(CM_CTRL_LED, CM_CTRL_LED); | 59 | } |
54 | break; | ||
55 | 60 | ||
56 | case led_timer: | 61 | static enum led_brightness integrator_led_get(struct led_classdev *cdev) |
57 | saved_leds ^= GREEN_LED; | 62 | { |
58 | update_alpha_leds = 1; | 63 | struct integrator_led *led = container_of(cdev, |
59 | break; | 64 | struct integrator_led, cdev); |
65 | u32 reg = __raw_readl(LEDREG); | ||
60 | 66 | ||
61 | case led_red_on: | 67 | return (reg & led->mask) ? LED_FULL : LED_OFF; |
62 | saved_leds |= RED_LED; | 68 | } |
63 | update_alpha_leds = 1; | ||
64 | break; | ||
65 | 69 | ||
66 | case led_red_off: | 70 | static void cm_led_set(struct led_classdev *cdev, |
67 | saved_leds &= ~RED_LED; | 71 | enum led_brightness b) |
68 | update_alpha_leds = 1; | 72 | { |
69 | break; | 73 | if (b != LED_OFF) |
74 | cm_control(CM_CTRL_LED, CM_CTRL_LED); | ||
75 | else | ||
76 | cm_control(CM_CTRL_LED, 0); | ||
77 | } | ||
70 | 78 | ||
71 | default: | 79 | static enum led_brightness cm_led_get(struct led_classdev *cdev) |
72 | break; | 80 | { |
73 | } | 81 | u32 reg = readl(CM_CTRL); |
74 | 82 | ||
75 | if (update_alpha_leds) { | 83 | return (reg & CM_CTRL_LED) ? LED_FULL : LED_OFF; |
76 | while (__raw_readl(dbg_base + INTEGRATOR_DBG_ALPHA_OFFSET) & 1); | ||
77 | __raw_writel(saved_leds, dbg_base + INTEGRATOR_DBG_LEDS_OFFSET); | ||
78 | } | ||
79 | local_irq_restore(flags); | ||
80 | } | 84 | } |
81 | 85 | ||
82 | static int __init leds_init(void) | 86 | static int __init integrator_leds_init(void) |
83 | { | 87 | { |
84 | if (machine_is_integrator() || machine_is_cintegrator()) | 88 | int i; |
85 | leds_event = integrator_leds_event; | 89 | |
90 | for (i = 0; i < ARRAY_SIZE(integrator_leds); i++) { | ||
91 | struct integrator_led *led; | ||
92 | |||
93 | led = kzalloc(sizeof(*led), GFP_KERNEL); | ||
94 | if (!led) | ||
95 | break; | ||
96 | |||
97 | |||
98 | led->cdev.name = integrator_leds[i].name; | ||
99 | |||
100 | if (i == 4) { /* Setting for LED in core module */ | ||
101 | led->cdev.brightness_set = cm_led_set; | ||
102 | led->cdev.brightness_get = cm_led_get; | ||
103 | } else { | ||
104 | led->cdev.brightness_set = integrator_led_set; | ||
105 | led->cdev.brightness_get = integrator_led_get; | ||
106 | } | ||
107 | |||
108 | led->cdev.default_trigger = integrator_leds[i].trigger; | ||
109 | led->mask = BIT(i); | ||
110 | |||
111 | if (led_classdev_register(NULL, &led->cdev) < 0) { | ||
112 | kfree(led); | ||
113 | break; | ||
114 | } | ||
115 | } | ||
86 | 116 | ||
87 | return 0; | 117 | return 0; |
88 | } | 118 | } |
89 | 119 | ||
90 | core_initcall(leds_init); | 120 | /* |
121 | * Since we may have triggers on any subsystem, defer registration | ||
122 | * until after subsystem_init. | ||
123 | */ | ||
124 | fs_initcall(integrator_leds_init); | ||
125 | #endif | ||