diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-01 21:46:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-01 21:46:13 -0400 |
commit | 8f446a7a069e0af0639385f67c78ee2279bca04c (patch) | |
tree | 580cf495616b36ca0af0826afa87c430cdc1e7cb /arch/arm/mach-footbridge | |
parent | 84be4ae2c038e2b03d650cbf2a7cfd9e8d6e9e51 (diff) | |
parent | 04ef037c926ddb31088c976538e29eada4fd1490 (diff) |
Merge tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM soc driver specific changes from Olof Johansson:
- A long-coming conversion of various platforms to a common LED
infrastructure
- AT91 is moved over to use the newer MCI driver for MMC
- Pincontrol conversions for samsung platforms
- DT bindings for gscaler on samsung
- i2c driver fixes for tegra, acked by i2c maintainer
Fix up conflicts as per Olof.
* tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (48 commits)
drivers: bus: omap_l3: use resources instead of hardcoded irqs
pinctrl: exynos: Fix wakeup IRQ domain registration check
pinctrl: samsung: Uninline samsung_pinctrl_get_soc_data
pinctrl: exynos: Correct the detection of wakeup-eint node
pinctrl: exynos: Mark exynos_irq_demux_eint as inline
pinctrl: exynos: Handle only unmasked wakeup interrupts
pinctrl: exynos: Fix typos in gpio/wkup _irq_mask
pinctrl: exynos: Set pin function to EINT in irq_set_type of GPIO EINTa
drivers: bus: Move the OMAP interconnect driver to drivers/bus/
i2c: tegra: dynamically control fast clk
i2c: tegra: I2_M_NOSTART functionality not supported in Tegra20
ARM: tegra: clock: remove unused clock entry for i2c
ARM: tegra: clock: add connection name in i2c clock entry
i2c: tegra: pass proper name for getting clock
ARM: tegra: clock: add i2c fast clock entry in clock table
ARM: EXYNOS: Adds G-Scaler device from Device Tree
ARM: EXYNOS: Add clock support for G-Scaler
ARM: EXYNOS: Enable pinctrl driver support for EXYNOS4 device tree enabled platform
ARM: dts: Add pinctrl node entries for SAMSUNG EXYNOS4210 SoC
ARM: EXYNOS: skip wakeup interrupt setup if pinctrl driver is used
...
Diffstat (limited to 'arch/arm/mach-footbridge')
-rw-r--r-- | arch/arm/mach-footbridge/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/mach-footbridge/ebsa285-leds.c | 138 | ||||
-rw-r--r-- | arch/arm/mach-footbridge/ebsa285.c | 81 | ||||
-rw-r--r-- | arch/arm/mach-footbridge/netwinder-hw.c | 112 | ||||
-rw-r--r-- | arch/arm/mach-footbridge/netwinder-leds.c | 138 |
5 files changed, 179 insertions, 294 deletions
diff --git a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile index 3afb1b25946f..0b64dd430d61 100644 --- a/arch/arm/mach-footbridge/Makefile +++ b/arch/arm/mach-footbridge/Makefile | |||
@@ -14,15 +14,11 @@ pci-$(CONFIG_ARCH_EBSA285_HOST) += ebsa285-pci.o | |||
14 | pci-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o | 14 | pci-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o |
15 | pci-$(CONFIG_ARCH_PERSONAL_SERVER) += personal-pci.o | 15 | pci-$(CONFIG_ARCH_PERSONAL_SERVER) += personal-pci.o |
16 | 16 | ||
17 | leds-$(CONFIG_ARCH_EBSA285) += ebsa285-leds.o | ||
18 | leds-$(CONFIG_ARCH_NETWINDER) += netwinder-leds.o | ||
19 | |||
20 | obj-$(CONFIG_ARCH_CATS) += cats-hw.o isa-timer.o | 17 | obj-$(CONFIG_ARCH_CATS) += cats-hw.o isa-timer.o |
21 | obj-$(CONFIG_ARCH_EBSA285) += ebsa285.o dc21285-timer.o | 18 | obj-$(CONFIG_ARCH_EBSA285) += ebsa285.o dc21285-timer.o |
22 | obj-$(CONFIG_ARCH_NETWINDER) += netwinder-hw.o isa-timer.o | 19 | obj-$(CONFIG_ARCH_NETWINDER) += netwinder-hw.o isa-timer.o |
23 | obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal.o dc21285-timer.o | 20 | obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal.o dc21285-timer.o |
24 | 21 | ||
25 | obj-$(CONFIG_PCI) +=$(pci-y) | 22 | obj-$(CONFIG_PCI) +=$(pci-y) |
26 | obj-$(CONFIG_LEDS) +=$(leds-y) | ||
27 | 23 | ||
28 | obj-$(CONFIG_ISA) += isa.o isa-rtc.o | 24 | obj-$(CONFIG_ISA) += isa.o isa-rtc.o |
diff --git a/arch/arm/mach-footbridge/ebsa285-leds.c b/arch/arm/mach-footbridge/ebsa285-leds.c deleted file mode 100644 index 5bd266754b95..000000000000 --- a/arch/arm/mach-footbridge/ebsa285-leds.c +++ /dev/null | |||
@@ -1,138 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-footbridge/ebsa285-leds.c | ||
3 | * | ||
4 | * Copyright (C) 1998-1999 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 | * EBSA-285 control routines. | ||
10 | * | ||
11 | * The EBSA-285 uses the leds as follows: | ||
12 | * - Green - toggles state every 50 timer interrupts | ||
13 | * - Amber - On if system is not idle | ||
14 | * - Red - currently unused | ||
15 | * | ||
16 | * Changelog: | ||
17 | * 02-05-1999 RMK Various cleanups | ||
18 | */ | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | |||
24 | #include <mach/hardware.h> | ||
25 | #include <asm/leds.h> | ||
26 | #include <asm/mach-types.h> | ||
27 | |||
28 | #define LED_STATE_ENABLED 1 | ||
29 | #define LED_STATE_CLAIMED 2 | ||
30 | static char led_state; | ||
31 | static char hw_led_state; | ||
32 | |||
33 | static DEFINE_SPINLOCK(leds_lock); | ||
34 | |||
35 | static void ebsa285_leds_event(led_event_t evt) | ||
36 | { | ||
37 | unsigned long flags; | ||
38 | |||
39 | spin_lock_irqsave(&leds_lock, flags); | ||
40 | |||
41 | switch (evt) { | ||
42 | case led_start: | ||
43 | hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN; | ||
44 | #ifndef CONFIG_LEDS_CPU | ||
45 | hw_led_state |= XBUS_LED_AMBER; | ||
46 | #endif | ||
47 | led_state |= LED_STATE_ENABLED; | ||
48 | break; | ||
49 | |||
50 | case led_stop: | ||
51 | led_state &= ~LED_STATE_ENABLED; | ||
52 | break; | ||
53 | |||
54 | case led_claim: | ||
55 | led_state |= LED_STATE_CLAIMED; | ||
56 | hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN | XBUS_LED_AMBER; | ||
57 | break; | ||
58 | |||
59 | case led_release: | ||
60 | led_state &= ~LED_STATE_CLAIMED; | ||
61 | hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN | XBUS_LED_AMBER; | ||
62 | break; | ||
63 | |||
64 | #ifdef CONFIG_LEDS_TIMER | ||
65 | case led_timer: | ||
66 | if (!(led_state & LED_STATE_CLAIMED)) | ||
67 | hw_led_state ^= XBUS_LED_GREEN; | ||
68 | break; | ||
69 | #endif | ||
70 | |||
71 | #ifdef CONFIG_LEDS_CPU | ||
72 | case led_idle_start: | ||
73 | if (!(led_state & LED_STATE_CLAIMED)) | ||
74 | hw_led_state |= XBUS_LED_AMBER; | ||
75 | break; | ||
76 | |||
77 | case led_idle_end: | ||
78 | if (!(led_state & LED_STATE_CLAIMED)) | ||
79 | hw_led_state &= ~XBUS_LED_AMBER; | ||
80 | break; | ||
81 | #endif | ||
82 | |||
83 | case led_halted: | ||
84 | if (!(led_state & LED_STATE_CLAIMED)) | ||
85 | hw_led_state &= ~XBUS_LED_RED; | ||
86 | break; | ||
87 | |||
88 | case led_green_on: | ||
89 | if (led_state & LED_STATE_CLAIMED) | ||
90 | hw_led_state &= ~XBUS_LED_GREEN; | ||
91 | break; | ||
92 | |||
93 | case led_green_off: | ||
94 | if (led_state & LED_STATE_CLAIMED) | ||
95 | hw_led_state |= XBUS_LED_GREEN; | ||
96 | break; | ||
97 | |||
98 | case led_amber_on: | ||
99 | if (led_state & LED_STATE_CLAIMED) | ||
100 | hw_led_state &= ~XBUS_LED_AMBER; | ||
101 | break; | ||
102 | |||
103 | case led_amber_off: | ||
104 | if (led_state & LED_STATE_CLAIMED) | ||
105 | hw_led_state |= XBUS_LED_AMBER; | ||
106 | break; | ||
107 | |||
108 | case led_red_on: | ||
109 | if (led_state & LED_STATE_CLAIMED) | ||
110 | hw_led_state &= ~XBUS_LED_RED; | ||
111 | break; | ||
112 | |||
113 | case led_red_off: | ||
114 | if (led_state & LED_STATE_CLAIMED) | ||
115 | hw_led_state |= XBUS_LED_RED; | ||
116 | break; | ||
117 | |||
118 | default: | ||
119 | break; | ||
120 | } | ||
121 | |||
122 | if (led_state & LED_STATE_ENABLED) | ||
123 | *XBUS_LEDS = hw_led_state; | ||
124 | |||
125 | spin_unlock_irqrestore(&leds_lock, flags); | ||
126 | } | ||
127 | |||
128 | static int __init leds_init(void) | ||
129 | { | ||
130 | if (machine_is_ebsa285()) | ||
131 | leds_event = ebsa285_leds_event; | ||
132 | |||
133 | leds_event(led_start); | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | __initcall(leds_init); | ||
diff --git a/arch/arm/mach-footbridge/ebsa285.c b/arch/arm/mach-footbridge/ebsa285.c index 27716a7e5fc1..b09551ef89ca 100644 --- a/arch/arm/mach-footbridge/ebsa285.c +++ b/arch/arm/mach-footbridge/ebsa285.c | |||
@@ -5,6 +5,8 @@ | |||
5 | */ | 5 | */ |
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/spinlock.h> | 7 | #include <linux/spinlock.h> |
8 | #include <linux/slab.h> | ||
9 | #include <linux/leds.h> | ||
8 | 10 | ||
9 | #include <asm/hardware/dec21285.h> | 11 | #include <asm/hardware/dec21285.h> |
10 | #include <asm/mach-types.h> | 12 | #include <asm/mach-types.h> |
@@ -13,6 +15,85 @@ | |||
13 | 15 | ||
14 | #include "common.h" | 16 | #include "common.h" |
15 | 17 | ||
18 | /* LEDs */ | ||
19 | #if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS) | ||
20 | struct ebsa285_led { | ||
21 | struct led_classdev cdev; | ||
22 | u8 mask; | ||
23 | }; | ||
24 | |||
25 | /* | ||
26 | * The triggers lines up below will only be used if the | ||
27 | * LED triggers are compiled in. | ||
28 | */ | ||
29 | static const struct { | ||
30 | const char *name; | ||
31 | const char *trigger; | ||
32 | } ebsa285_leds[] = { | ||
33 | { "ebsa285:amber", "heartbeat", }, | ||
34 | { "ebsa285:green", "cpu0", }, | ||
35 | { "ebsa285:red",}, | ||
36 | }; | ||
37 | |||
38 | static void ebsa285_led_set(struct led_classdev *cdev, | ||
39 | enum led_brightness b) | ||
40 | { | ||
41 | struct ebsa285_led *led = container_of(cdev, | ||
42 | struct ebsa285_led, cdev); | ||
43 | |||
44 | if (b != LED_OFF) | ||
45 | *XBUS_LEDS |= led->mask; | ||
46 | else | ||
47 | *XBUS_LEDS &= ~led->mask; | ||
48 | } | ||
49 | |||
50 | static enum led_brightness ebsa285_led_get(struct led_classdev *cdev) | ||
51 | { | ||
52 | struct ebsa285_led *led = container_of(cdev, | ||
53 | struct ebsa285_led, cdev); | ||
54 | |||
55 | return (*XBUS_LEDS & led->mask) ? LED_FULL : LED_OFF; | ||
56 | } | ||
57 | |||
58 | static int __init ebsa285_leds_init(void) | ||
59 | { | ||
60 | int i; | ||
61 | |||
62 | if (machine_is_ebsa285()) | ||
63 | return -ENODEV; | ||
64 | |||
65 | /* 3 LEDS All ON */ | ||
66 | *XBUS_LEDS |= XBUS_LED_AMBER | XBUS_LED_GREEN | XBUS_LED_RED; | ||
67 | |||
68 | for (i = 0; i < ARRAY_SIZE(ebsa285_leds); i++) { | ||
69 | struct ebsa285_led *led; | ||
70 | |||
71 | led = kzalloc(sizeof(*led), GFP_KERNEL); | ||
72 | if (!led) | ||
73 | break; | ||
74 | |||
75 | led->cdev.name = ebsa285_leds[i].name; | ||
76 | led->cdev.brightness_set = ebsa285_led_set; | ||
77 | led->cdev.brightness_get = ebsa285_led_get; | ||
78 | led->cdev.default_trigger = ebsa285_leds[i].trigger; | ||
79 | led->mask = BIT(i); | ||
80 | |||
81 | if (led_classdev_register(NULL, &led->cdev) < 0) { | ||
82 | kfree(led); | ||
83 | break; | ||
84 | } | ||
85 | } | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * Since we may have triggers on any subsystem, defer registration | ||
92 | * until after subsystem_init. | ||
93 | */ | ||
94 | fs_initcall(ebsa285_leds_init); | ||
95 | #endif | ||
96 | |||
16 | MACHINE_START(EBSA285, "EBSA285") | 97 | MACHINE_START(EBSA285, "EBSA285") |
17 | /* Maintainer: Russell King */ | 98 | /* Maintainer: Russell King */ |
18 | .atag_offset = 0x100, | 99 | .atag_offset = 0x100, |
diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c index cac9f67e7da7..d2d14339c6c4 100644 --- a/arch/arm/mach-footbridge/netwinder-hw.c +++ b/arch/arm/mach-footbridge/netwinder-hw.c | |||
@@ -12,9 +12,10 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
15 | #include <linux/slab.h> | ||
16 | #include <linux/leds.h> | ||
15 | 17 | ||
16 | #include <asm/hardware/dec21285.h> | 18 | #include <asm/hardware/dec21285.h> |
17 | #include <asm/leds.h> | ||
18 | #include <asm/mach-types.h> | 19 | #include <asm/mach-types.h> |
19 | #include <asm/setup.h> | 20 | #include <asm/setup.h> |
20 | #include <asm/system_misc.h> | 21 | #include <asm/system_misc.h> |
@@ -27,13 +28,6 @@ | |||
27 | #define GP1_IO_BASE 0x338 | 28 | #define GP1_IO_BASE 0x338 |
28 | #define GP2_IO_BASE 0x33a | 29 | #define GP2_IO_BASE 0x33a |
29 | 30 | ||
30 | |||
31 | #ifdef CONFIG_LEDS | ||
32 | #define DEFAULT_LEDS 0 | ||
33 | #else | ||
34 | #define DEFAULT_LEDS GPIO_GREEN_LED | ||
35 | #endif | ||
36 | |||
37 | /* | 31 | /* |
38 | * Winbond WB83977F accessibility stuff | 32 | * Winbond WB83977F accessibility stuff |
39 | */ | 33 | */ |
@@ -611,15 +605,9 @@ static void __init rwa010_init(void) | |||
611 | static int __init nw_hw_init(void) | 605 | static int __init nw_hw_init(void) |
612 | { | 606 | { |
613 | if (machine_is_netwinder()) { | 607 | if (machine_is_netwinder()) { |
614 | unsigned long flags; | ||
615 | |||
616 | wb977_init(); | 608 | wb977_init(); |
617 | cpld_init(); | 609 | cpld_init(); |
618 | rwa010_init(); | 610 | rwa010_init(); |
619 | |||
620 | raw_spin_lock_irqsave(&nw_gpio_lock, flags); | ||
621 | nw_gpio_modify_op(GPIO_RED_LED|GPIO_GREEN_LED, DEFAULT_LEDS); | ||
622 | raw_spin_unlock_irqrestore(&nw_gpio_lock, flags); | ||
623 | } | 611 | } |
624 | return 0; | 612 | return 0; |
625 | } | 613 | } |
@@ -672,6 +660,102 @@ static void netwinder_restart(char mode, const char *cmd) | |||
672 | } | 660 | } |
673 | } | 661 | } |
674 | 662 | ||
663 | /* LEDs */ | ||
664 | #if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS) | ||
665 | struct netwinder_led { | ||
666 | struct led_classdev cdev; | ||
667 | u8 mask; | ||
668 | }; | ||
669 | |||
670 | /* | ||
671 | * The triggers lines up below will only be used if the | ||
672 | * LED triggers are compiled in. | ||
673 | */ | ||
674 | static const struct { | ||
675 | const char *name; | ||
676 | const char *trigger; | ||
677 | } netwinder_leds[] = { | ||
678 | { "netwinder:green", "heartbeat", }, | ||
679 | { "netwinder:red", "cpu0", }, | ||
680 | }; | ||
681 | |||
682 | /* | ||
683 | * The LED control in Netwinder is reversed: | ||
684 | * - setting bit means turn off LED | ||
685 | * - clearing bit means turn on LED | ||
686 | */ | ||
687 | static void netwinder_led_set(struct led_classdev *cdev, | ||
688 | enum led_brightness b) | ||
689 | { | ||
690 | struct netwinder_led *led = container_of(cdev, | ||
691 | struct netwinder_led, cdev); | ||
692 | unsigned long flags; | ||
693 | u32 reg; | ||
694 | |||
695 | spin_lock_irqsave(&nw_gpio_lock, flags); | ||
696 | reg = nw_gpio_read(); | ||
697 | if (b != LED_OFF) | ||
698 | reg &= ~led->mask; | ||
699 | else | ||
700 | reg |= led->mask; | ||
701 | nw_gpio_modify_op(led->mask, reg); | ||
702 | spin_unlock_irqrestore(&nw_gpio_lock, flags); | ||
703 | } | ||
704 | |||
705 | static enum led_brightness netwinder_led_get(struct led_classdev *cdev) | ||
706 | { | ||
707 | struct netwinder_led *led = container_of(cdev, | ||
708 | struct netwinder_led, cdev); | ||
709 | unsigned long flags; | ||
710 | u32 reg; | ||
711 | |||
712 | spin_lock_irqsave(&nw_gpio_lock, flags); | ||
713 | reg = nw_gpio_read(); | ||
714 | spin_unlock_irqrestore(&nw_gpio_lock, flags); | ||
715 | |||
716 | return (reg & led->mask) ? LED_OFF : LED_FULL; | ||
717 | } | ||
718 | |||
719 | static int __init netwinder_leds_init(void) | ||
720 | { | ||
721 | int i; | ||
722 | |||
723 | if (!machine_is_netwinder()) | ||
724 | return -ENODEV; | ||
725 | |||
726 | for (i = 0; i < ARRAY_SIZE(netwinder_leds); i++) { | ||
727 | struct netwinder_led *led; | ||
728 | |||
729 | led = kzalloc(sizeof(*led), GFP_KERNEL); | ||
730 | if (!led) | ||
731 | break; | ||
732 | |||
733 | led->cdev.name = netwinder_leds[i].name; | ||
734 | led->cdev.brightness_set = netwinder_led_set; | ||
735 | led->cdev.brightness_get = netwinder_led_get; | ||
736 | led->cdev.default_trigger = netwinder_leds[i].trigger; | ||
737 | |||
738 | if (i == 0) | ||
739 | led->mask = GPIO_GREEN_LED; | ||
740 | else | ||
741 | led->mask = GPIO_RED_LED; | ||
742 | |||
743 | if (led_classdev_register(NULL, &led->cdev) < 0) { | ||
744 | kfree(led); | ||
745 | break; | ||
746 | } | ||
747 | } | ||
748 | |||
749 | return 0; | ||
750 | } | ||
751 | |||
752 | /* | ||
753 | * Since we may have triggers on any subsystem, defer registration | ||
754 | * until after subsystem_init. | ||
755 | */ | ||
756 | fs_initcall(netwinder_leds_init); | ||
757 | #endif | ||
758 | |||
675 | MACHINE_START(NETWINDER, "Rebel-NetWinder") | 759 | MACHINE_START(NETWINDER, "Rebel-NetWinder") |
676 | /* Maintainer: Russell King/Rebel.com */ | 760 | /* Maintainer: Russell King/Rebel.com */ |
677 | .atag_offset = 0x100, | 761 | .atag_offset = 0x100, |
diff --git a/arch/arm/mach-footbridge/netwinder-leds.c b/arch/arm/mach-footbridge/netwinder-leds.c deleted file mode 100644 index 5a2bd89cbdca..000000000000 --- a/arch/arm/mach-footbridge/netwinder-leds.c +++ /dev/null | |||
@@ -1,138 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-footbridge/netwinder-leds.c | ||
3 | * | ||
4 | * Copyright (C) 1998-1999 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 | * NetWinder LED control routines. | ||
11 | * | ||
12 | * The Netwinder uses the leds as follows: | ||
13 | * - Green - toggles state every 50 timer interrupts | ||
14 | * - Red - On if the system is not idle | ||
15 | * | ||
16 | * Changelog: | ||
17 | * 02-05-1999 RMK Various cleanups | ||
18 | */ | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | |||
24 | #include <mach/hardware.h> | ||
25 | #include <asm/leds.h> | ||
26 | #include <asm/mach-types.h> | ||
27 | |||
28 | #define LED_STATE_ENABLED 1 | ||
29 | #define LED_STATE_CLAIMED 2 | ||
30 | static char led_state; | ||
31 | static char hw_led_state; | ||
32 | |||
33 | static DEFINE_RAW_SPINLOCK(leds_lock); | ||
34 | |||
35 | static void netwinder_leds_event(led_event_t evt) | ||
36 | { | ||
37 | unsigned long flags; | ||
38 | |||
39 | raw_spin_lock_irqsave(&leds_lock, flags); | ||
40 | |||
41 | switch (evt) { | ||
42 | case led_start: | ||
43 | led_state |= LED_STATE_ENABLED; | ||
44 | hw_led_state = GPIO_GREEN_LED; | ||
45 | break; | ||
46 | |||
47 | case led_stop: | ||
48 | led_state &= ~LED_STATE_ENABLED; | ||
49 | break; | ||
50 | |||
51 | case led_claim: | ||
52 | led_state |= LED_STATE_CLAIMED; | ||
53 | hw_led_state = 0; | ||
54 | break; | ||
55 | |||
56 | case led_release: | ||
57 | led_state &= ~LED_STATE_CLAIMED; | ||
58 | hw_led_state = 0; | ||
59 | break; | ||
60 | |||
61 | #ifdef CONFIG_LEDS_TIMER | ||
62 | case led_timer: | ||
63 | if (!(led_state & LED_STATE_CLAIMED)) | ||
64 | hw_led_state ^= GPIO_GREEN_LED; | ||
65 | break; | ||
66 | #endif | ||
67 | |||
68 | #ifdef CONFIG_LEDS_CPU | ||
69 | case led_idle_start: | ||
70 | if (!(led_state & LED_STATE_CLAIMED)) | ||
71 | hw_led_state &= ~GPIO_RED_LED; | ||
72 | break; | ||
73 | |||
74 | case led_idle_end: | ||
75 | if (!(led_state & LED_STATE_CLAIMED)) | ||
76 | hw_led_state |= GPIO_RED_LED; | ||
77 | break; | ||
78 | #endif | ||
79 | |||
80 | case led_halted: | ||
81 | if (!(led_state & LED_STATE_CLAIMED)) | ||
82 | hw_led_state |= GPIO_RED_LED; | ||
83 | break; | ||
84 | |||
85 | case led_green_on: | ||
86 | if (led_state & LED_STATE_CLAIMED) | ||
87 | hw_led_state |= GPIO_GREEN_LED; | ||
88 | break; | ||
89 | |||
90 | case led_green_off: | ||
91 | if (led_state & LED_STATE_CLAIMED) | ||
92 | hw_led_state &= ~GPIO_GREEN_LED; | ||
93 | break; | ||
94 | |||
95 | case led_amber_on: | ||
96 | if (led_state & LED_STATE_CLAIMED) | ||
97 | hw_led_state |= GPIO_GREEN_LED | GPIO_RED_LED; | ||
98 | break; | ||
99 | |||
100 | case led_amber_off: | ||
101 | if (led_state & LED_STATE_CLAIMED) | ||
102 | hw_led_state &= ~(GPIO_GREEN_LED | GPIO_RED_LED); | ||
103 | break; | ||
104 | |||
105 | case led_red_on: | ||
106 | if (led_state & LED_STATE_CLAIMED) | ||
107 | hw_led_state |= GPIO_RED_LED; | ||
108 | break; | ||
109 | |||
110 | case led_red_off: | ||
111 | if (led_state & LED_STATE_CLAIMED) | ||
112 | hw_led_state &= ~GPIO_RED_LED; | ||
113 | break; | ||
114 | |||
115 | default: | ||
116 | break; | ||
117 | } | ||
118 | |||
119 | raw_spin_unlock_irqrestore(&leds_lock, flags); | ||
120 | |||
121 | if (led_state & LED_STATE_ENABLED) { | ||
122 | raw_spin_lock_irqsave(&nw_gpio_lock, flags); | ||
123 | nw_gpio_modify_op(GPIO_RED_LED | GPIO_GREEN_LED, hw_led_state); | ||
124 | raw_spin_unlock_irqrestore(&nw_gpio_lock, flags); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | static int __init leds_init(void) | ||
129 | { | ||
130 | if (machine_is_netwinder()) | ||
131 | leds_event = netwinder_leds_event; | ||
132 | |||
133 | leds_event(led_start); | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | __initcall(leds_init); | ||