Merge branch 'for-arm-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney...
authorArnd Bergmann <arnd@arndb.de>
Mon, 13 Aug 2012 14:45:48 +0000 (16:45 +0200)
committerArnd Bergmann <arnd@arndb.de>
Mon, 13 Aug 2012 14:45:48 +0000 (16:45 +0200)
From Bryan Wu <bryan.wu@canonical.com>:

Based on Linus Walleij's ARM LED consolidation work, this patchset introduce a
new generic led trigger for CPU not only for ARM but also for others.

For enabling CPU idle event, CPU arch code should call ledtrig_cpu() stub to
trigger idle start or idle end event.

These patches convert old style LED driver in arch/arm to gpio_led or new led
driver interface. Against 3.5 release and build successfully for all the machines.

Test ledtrig-cpu driver on OMAP4 Panda board.

v9 --> v10
 * fix compiling issue on versatile_defconfig reported by Russell King
 * rebase to 3.5 kernel and move patches to new git tree

v8 --> v9:
 * use mutex to replace rw_sema pointed out by Tim Gardner
 * add a new struct led_trigger_cpu
 * add lock_is_inited to record mutex lock initialization

v6 --> v7:
 * add a patch to unify the led-trigger name
 * fix some typo pointed
 * use BUG_ON to detect CPU numbers during building stage

v5 --> v6:
 * replace  __get_cpu_var() to per_cpu()
 * remove smp_processor_id() which is wrong with for_each_possible_cpu()
 * test on real OMAP4 Panda board
 * add comments about CPU hotplug in the CPU LED trigger driver

v4 --> v5:
 * rebase all the patches on top of latest linux-next
 * replace on_each_cpu() with for_each_possible_cpu()
 * add some description of ledtrig_cpu() API
 * remove old leds code from driver nwflash.c, which should use a new led trigger then
 * this trigger driver can be built as module now

v3 --> v4:
 * fix a typo pointed by Jochen Friedrich
 * fix some building errors
 * add Reviewed-by and Tested-by into patch log

v2 --> v3:
 * almost rewrote the whole ledtrig-cpu driver, which is more simple
 * every CPU will have a per-CPU trigger
 * cpu trigger can be assigned to any leds
 * fix a lockdep issue in led-trigger common code
 * other fix according to review

v1 --> v2:
 * remove select operations in Kconfig of every machines
 * add back supporting of led in core module of mach-integrator
 * solidate name scheme in ledtrig-cpu.c
 * add comments of CPU_LED_* cpu led events
 * fold patches of RealView and Versatile together
 * add machine_is_ check during assabet led driver init
 * add some Acked-by in patch logs
 * remove code for simpad machine in machine-sa11000, since Jochen Friedrich
   introduced gpiolib and gpio-led driver for simpad
 * on Assabet and Netwinder machine, LED operations is reversed like:
   setting bit means turn off leds
   clearing bit means turn on leds
 * add a new function to read CM_CTRL register for led driver

* 'for-arm-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds:
  ARM: use new LEDS CPU trigger stub to replace old one
  ARM: mach-sa1100: retire custom LED code
  ARM: mach-omap1: retire custom LED code
  ARM: mach-pnx4008: remove including old leds event API header file
  ARM: plat-samsung: remove including old leds event API header file
  ARM: mach-pxa: retire custom LED code
  char: nwflash: remove old led event code
  ARM: mach-footbridge: retire custom LED code
  ARM: mach-ebsa110: retire custom LED code
  ARM: mach-clps711x: retire custom LED code of P720T machine
  ARM: mach-integrator: retire custom LED code
  ARM: mach-integrator: move CM_CTRL to header file for accessing by other functions
  ARM: mach-orion5x: convert custom LED code to gpio_led and LED CPU trigger
  ARM: mach-shark: retire custom LED code
  ARM: mach-ks8695: remove leds driver, since nobody use it
  ARM: mach-realview and mach-versatile: retire custom LED code
  ARM: at91: convert old leds drivers to gpio_led and led_trigger drivers
  led-triggers: create a trigger for CPU activity

Conflicts:
arch/arm/mach-clps711x/p720t.c
arch/arm/mach-sa1100/leds-cerf.c
arch/arm/mach-sa1100/leds-lart.c

Let's hope this is the last time we pull this and it doesn't cause
more trouble. I have verified that version 10 causes no build
warnings or errors any more, and the patches still look good.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
97 files changed:
arch/arm/Kconfig
arch/arm/include/asm/leds.h [deleted file]
arch/arm/kernel/Makefile
arch/arm/kernel/leds.c [deleted file]
arch/arm/kernel/process.c
arch/arm/kernel/time.c
arch/arm/mach-at91/board-csb337.c
arch/arm/mach-at91/board-ecbat91.c
arch/arm/mach-at91/board-eco920.c
arch/arm/mach-at91/board-kafa.c
arch/arm/mach-at91/board-kb9202.c
arch/arm/mach-at91/board-rm9200dk.c
arch/arm/mach-at91/board-rm9200ek.c
arch/arm/mach-at91/board-rsi-ews.c
arch/arm/mach-at91/board-sam9-l9260.c
arch/arm/mach-at91/board-sam9261ek.c
arch/arm/mach-at91/board-yl-9200.c
arch/arm/mach-at91/include/mach/board.h
arch/arm/mach-at91/leds.c
arch/arm/mach-clps711x/Makefile
arch/arm/mach-clps711x/common.c
arch/arm/mach-clps711x/p720t-leds.c [deleted file]
arch/arm/mach-clps711x/p720t.c
arch/arm/mach-ebsa110/Makefile
arch/arm/mach-ebsa110/leds.c
arch/arm/mach-footbridge/Makefile
arch/arm/mach-footbridge/ebsa285-leds.c [deleted file]
arch/arm/mach-footbridge/ebsa285.c
arch/arm/mach-footbridge/netwinder-hw.c
arch/arm/mach-footbridge/netwinder-leds.c [deleted file]
arch/arm/mach-integrator/Makefile
arch/arm/mach-integrator/core.c
arch/arm/mach-integrator/include/mach/cm.h
arch/arm/mach-integrator/leds.c
arch/arm/mach-ks8695/Makefile
arch/arm/mach-ks8695/devices.c
arch/arm/mach-ks8695/include/mach/devices.h
arch/arm/mach-ks8695/leds.c [deleted file]
arch/arm/mach-omap1/Makefile
arch/arm/mach-omap1/board-h2.c
arch/arm/mach-omap1/board-h3.c
arch/arm/mach-omap1/board-osk.c
arch/arm/mach-omap1/leds-h2p2-debug.c [deleted file]
arch/arm/mach-omap1/leds-innovator.c [deleted file]
arch/arm/mach-omap1/leds-osk.c [deleted file]
arch/arm/mach-omap1/leds.c [deleted file]
arch/arm/mach-omap1/leds.h [deleted file]
arch/arm/mach-omap1/time.c
arch/arm/mach-omap1/timer32k.c
arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
arch/arm/mach-orion5x/rd88f5182-setup.c
arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
arch/arm/mach-pnx4008/time.c
arch/arm/mach-pxa/Makefile
arch/arm/mach-pxa/idp.c
arch/arm/mach-pxa/leds-idp.c [deleted file]
arch/arm/mach-pxa/leds-lubbock.c [deleted file]
arch/arm/mach-pxa/leds-mainstone.c [deleted file]
arch/arm/mach-pxa/leds.c [deleted file]
arch/arm/mach-pxa/leds.h [deleted file]
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-realview/core.c
arch/arm/mach-realview/core.h
arch/arm/mach-realview/realview_eb.c
arch/arm/mach-realview/realview_pb1176.c
arch/arm/mach-realview/realview_pb11mp.c
arch/arm/mach-realview/realview_pba8.c
arch/arm/mach-realview/realview_pbx.c
arch/arm/mach-sa1100/Makefile
arch/arm/mach-sa1100/assabet.c
arch/arm/mach-sa1100/badge4.c
arch/arm/mach-sa1100/cerf.c
arch/arm/mach-sa1100/hackkit.c
arch/arm/mach-sa1100/lart.c
arch/arm/mach-sa1100/leds-assabet.c [deleted file]
arch/arm/mach-sa1100/leds-badge4.c [deleted file]
arch/arm/mach-sa1100/leds-cerf.c [deleted file]
arch/arm/mach-sa1100/leds-hackkit.c [deleted file]
arch/arm/mach-sa1100/leds-lart.c [deleted file]
arch/arm/mach-sa1100/leds.c [deleted file]
arch/arm/mach-sa1100/leds.h [deleted file]
arch/arm/mach-shark/Makefile
arch/arm/mach-shark/core.c
arch/arm/mach-shark/leds.c
arch/arm/mach-versatile/core.c
arch/arm/plat-omap/Kconfig
arch/arm/plat-omap/debug-leds.c
arch/arm/plat-samsung/time.c
arch/arm/plat-versatile/Kconfig
arch/arm/plat-versatile/leds.c
drivers/char/nwflash.c
drivers/leds/Kconfig
drivers/leds/Makefile
drivers/leds/ledtrig-cpu.c [new file with mode: 0644]
include/linux/leds.h

index e91c7cd..ac353cf 100644 (file)
@@ -1787,59 +1787,6 @@ config FORCE_MAX_ZONEORDER
          This config option is actually maximum order plus one. For example,
          a value of 11 means that the largest free memory block is 2^10 pages.
 
-config LEDS
-       bool "Timer and CPU usage LEDs"
-       depends on ARCH_CDB89712 || ARCH_EBSA110 || \
-                  ARCH_EBSA285 || ARCH_INTEGRATOR || \
-                  ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
-                  ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
-                  ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
-                  ARCH_AT91 || ARCH_DAVINCI || \
-                  ARCH_KS8695 || MACH_RD88F5182 || ARCH_REALVIEW
-       help
-         If you say Y here, the LEDs on your machine will be used
-         to provide useful information about your current system status.
-
-         If you are compiling a kernel for a NetWinder or EBSA-285, you will
-         be able to select which LEDs are active using the options below. If
-         you are compiling a kernel for the EBSA-110 or the LART however, the
-         red LED will simply flash regularly to indicate that the system is
-         still functional. It is safe to say Y here if you have a CATS
-         system, but the driver will do nothing.
-
-config LEDS_TIMER
-       bool "Timer LED" if (!ARCH_CDB89712 && !ARCH_OMAP) || \
-                           OMAP_OSK_MISTRAL || MACH_OMAP_H2 \
-                           || MACH_OMAP_PERSEUS2
-       depends on LEDS
-       depends on !GENERIC_CLOCKEVENTS
-       default y if ARCH_EBSA110
-       help
-         If you say Y here, one of the system LEDs (the green one on the
-         NetWinder, the amber one on the EBSA285, or the red one on the LART)
-         will flash regularly to indicate that the system is still
-         operational. This is mainly useful to kernel hackers who are
-         debugging unstable kernels.
-
-         The LART uses the same LED for both Timer LED and CPU usage LED
-         functions. You may choose to use both, but the Timer LED function
-         will overrule the CPU usage LED.
-
-config LEDS_CPU
-       bool "CPU usage LED" if (!ARCH_CDB89712 && !ARCH_EBSA110 && \
-                       !ARCH_OMAP) \
-                       || OMAP_OSK_MISTRAL || MACH_OMAP_H2 \
-                       || MACH_OMAP_PERSEUS2
-       depends on LEDS
-       help
-         If you say Y here, the red LED will be used to give a good real
-         time indication of CPU usage, by lighting whenever the idle task
-         is not currently executing.
-
-         The LART uses the same LED for both Timer LED and CPU usage LED
-         functions. You may choose to use both, but the Timer LED function
-         will overrule the CPU usage LED.
-
 config ALIGNMENT_TRAP
        bool
        depends on CPU_CP15_MMU
diff --git a/arch/arm/include/asm/leds.h b/arch/arm/include/asm/leds.h
deleted file mode 100644 (file)
index c545739..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *  arch/arm/include/asm/leds.h
- *
- *  Copyright (C) 1998 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  Event-driven interface for LEDs on machines
- *  Added led_start and led_stop- Alex Holden, 28th Dec 1998.
- */
-#ifndef ASM_ARM_LEDS_H
-#define ASM_ARM_LEDS_H
-
-
-typedef enum {
-       led_idle_start,
-       led_idle_end,
-       led_timer,
-       led_start,
-       led_stop,
-       led_claim,              /* override idle & timer leds */
-       led_release,            /* restore idle & timer leds */
-       led_start_timer_mode,
-       led_stop_timer_mode,
-       led_green_on,
-       led_green_off,
-       led_amber_on,
-       led_amber_off,
-       led_red_on,
-       led_red_off,
-       led_blue_on,
-       led_blue_off,
-       /*
-        * I want this between led_timer and led_start, but
-        * someone has decided to export this to user space
-        */
-       led_halted
-} led_event_t;
-
-/* Use this routine to handle LEDs */
-
-#ifdef CONFIG_LEDS
-extern void (*leds_event)(led_event_t);
-#else
-#define leds_event(e)
-#endif
-
-#endif
index 7ad2d5c..8951577 100644 (file)
@@ -21,7 +21,6 @@ obj-y         := elf.o entry-armv.o entry-common.o irq.o opcodes.o \
 
 obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o
 
-obj-$(CONFIG_LEDS)             += leds.o
 obj-$(CONFIG_OC_ETM)           += etm.o
 obj-$(CONFIG_CPU_IDLE)         += cpuidle.o
 obj-$(CONFIG_ISA_DMA_API)      += dma.o
diff --git a/arch/arm/kernel/leds.c b/arch/arm/kernel/leds.c
deleted file mode 100644 (file)
index 1911dae..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * LED support code, ripped out of arch/arm/kernel/time.c
- *
- *  Copyright (C) 1994-2001 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/export.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/syscore_ops.h>
-#include <linux/string.h>
-
-#include <asm/leds.h>
-
-static void dummy_leds_event(led_event_t evt)
-{
-}
-
-void (*leds_event)(led_event_t) = dummy_leds_event;
-
-struct leds_evt_name {
-       const char      name[8];
-       int             on;
-       int             off;
-};
-
-static const struct leds_evt_name evt_names[] = {
-       { "amber", led_amber_on, led_amber_off },
-       { "blue",  led_blue_on,  led_blue_off  },
-       { "green", led_green_on, led_green_off },
-       { "red",   led_red_on,   led_red_off   },
-};
-
-static ssize_t leds_store(struct device *dev,
-                       struct device_attribute *attr,
-                       const char *buf, size_t size)
-{
-       int ret = -EINVAL, len = strcspn(buf, " ");
-
-       if (len > 0 && buf[len] == '\0')
-               len--;
-
-       if (strncmp(buf, "claim", len) == 0) {
-               leds_event(led_claim);
-               ret = size;
-       } else if (strncmp(buf, "release", len) == 0) {
-               leds_event(led_release);
-               ret = size;
-       } else {
-               int i;
-
-               for (i = 0; i < ARRAY_SIZE(evt_names); i++) {
-                       if (strlen(evt_names[i].name) != len ||
-                           strncmp(buf, evt_names[i].name, len) != 0)
-                               continue;
-                       if (strncmp(buf+len, " on", 3) == 0) {
-                               leds_event(evt_names[i].on);
-                               ret = size;
-                       } else if (strncmp(buf+len, " off", 4) == 0) {
-                               leds_event(evt_names[i].off);
-                               ret = size;
-                       }
-                       break;
-               }
-       }
-       return ret;
-}
-
-static DEVICE_ATTR(event, 0200, NULL, leds_store);
-
-static struct bus_type leds_subsys = {
-       .name           = "leds",
-       .dev_name       = "leds",
-};
-
-static struct device leds_device = {
-       .id             = 0,
-       .bus            = &leds_subsys,
-};
-
-static int leds_suspend(void)
-{
-       leds_event(led_stop);
-       return 0;
-}
-
-static void leds_resume(void)
-{
-       leds_event(led_start);
-}
-
-static void leds_shutdown(void)
-{
-       leds_event(led_halted);
-}
-
-static struct syscore_ops leds_syscore_ops = {
-       .shutdown       = leds_shutdown,
-       .suspend        = leds_suspend,
-       .resume         = leds_resume,
-};
-
-static int __init leds_init(void)
-{
-       int ret;
-       ret = subsys_system_register(&leds_subsys, NULL);
-       if (ret == 0)
-               ret = device_register(&leds_device);
-       if (ret == 0)
-               ret = device_create_file(&leds_device, &dev_attr_event);
-       if (ret == 0)
-               register_syscore_ops(&leds_syscore_ops);
-       return ret;
-}
-
-device_initcall(leds_init);
-
-EXPORT_SYMBOL(leds_event);
index 693b744..04eea22 100644 (file)
@@ -31,9 +31,9 @@
 #include <linux/random.h>
 #include <linux/hw_breakpoint.h>
 #include <linux/cpuidle.h>
+#include <linux/leds.h>
 
 #include <asm/cacheflush.h>
-#include <asm/leds.h>
 #include <asm/processor.h>
 #include <asm/thread_notify.h>
 #include <asm/stacktrace.h>
@@ -189,7 +189,7 @@ void cpu_idle(void)
        while (1) {
                tick_nohz_idle_enter();
                rcu_idle_enter();
-               leds_event(led_idle_start);
+               ledtrig_cpu(CPU_LED_IDLE_START);
                while (!need_resched()) {
 #ifdef CONFIG_HOTPLUG_CPU
                        if (cpu_is_offline(smp_processor_id()))
@@ -220,7 +220,7 @@ void cpu_idle(void)
                        } else
                                local_irq_enable();
                }
-               leds_event(led_idle_end);
+               ledtrig_cpu(CPU_LED_IDLE_END);
                rcu_idle_exit();
                tick_nohz_idle_exit();
                schedule_preempt_disabled();
index af2afb0..09be0c3 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/timer.h>
 #include <linux/irq.h>
 
-#include <asm/leds.h>
 #include <asm/thread_info.h>
 #include <asm/sched_clock.h>
 #include <asm/stacktrace.h>
@@ -80,21 +79,6 @@ u32 arch_gettimeoffset(void)
 }
 #endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */
 
-#ifdef CONFIG_LEDS_TIMER
-static inline void do_leds(void)
-{
-       static unsigned int count = HZ/2;
-
-       if (--count == 0) {
-               count = HZ/2;
-               leds_event(led_timer);
-       }
-}
-#else
-#define        do_leds()
-#endif
-
-
 #ifndef CONFIG_GENERIC_CLOCKEVENTS
 /*
  * Kernel system timer support.
@@ -102,7 +86,6 @@ static inline void do_leds(void)
 void timer_tick(void)
 {
        profile_tick(CPU_PROFILING);
-       do_leds();
        xtime_update(1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode(get_irq_regs()));
index 462bc31..32396bb 100644 (file)
@@ -220,8 +220,6 @@ static struct gpio_led csb_leds[] = {
 
 static void __init csb337_board_init(void)
 {
-       /* Setup the LEDs */
-       at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1);
        /* Serial */
        /* DBGU on ttyS0 */
        at91_register_uart(0, 0, 0);
index 9c24cb2..192ec76 100644 (file)
@@ -138,11 +138,20 @@ static struct spi_board_info __initdata ecb_at91spi_devices[] = {
        },
 };
 
+/*
+ * LEDs
+ */
+static struct gpio_led ecb_leds[] = {
+       {       /* D1 */
+               .name                   = "led1",
+               .gpio                   = AT91_PIN_PC7,
+               .active_low             = 1,
+               .default_trigger        = "heartbeat",
+       }
+};
+
 static void __init ecb_at91board_init(void)
 {
-       /* Setup the LEDs */
-       at91_init_leds(AT91_PIN_PC7, AT91_PIN_PC7);
-
        /* Serial */
        /* DBGU on ttyS0. (Rx & Tx only) */
        at91_register_uart(0, 0, 0);
@@ -165,6 +174,9 @@ static void __init ecb_at91board_init(void)
 
        /* SPI */
        at91_add_device_spi(ecb_at91spi_devices, ARRAY_SIZE(ecb_at91spi_devices));
+
+       /* LEDs */
+       at91_gpio_leds(ecb_leds, ARRAY_SIZE(ecb_leds));
 }
 
 MACHINE_START(ECBAT91, "emQbit's ECB_AT91")
index 82bdfde..d2d4580 100644 (file)
@@ -93,10 +93,26 @@ static struct spi_board_info eco920_spi_devices[] = {
        },
 };
 
+/*
+ * LEDs
+ */
+static struct gpio_led eco920_leds[] = {
+       {       /* D1 */
+               .name                   = "led1",
+               .gpio                   = AT91_PIN_PB0,
+               .active_low             = 1,
+               .default_trigger        = "heartbeat",
+       },
+       {       /* D2 */
+               .name                   = "led2",
+               .gpio                   = AT91_PIN_PB1,
+               .active_low             = 1,
+               .default_trigger        = "timer",
+       }
+};
+
 static void __init eco920_board_init(void)
 {
-       /* Setup the LEDs */
-       at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1);
        /* DBGU on ttyS0. (Rx & Tx only */
        at91_register_uart(0, 0, 0);
        at91_add_device_serial();
@@ -127,6 +143,8 @@ static void __init eco920_board_init(void)
        );
 
        at91_add_device_spi(eco920_spi_devices, ARRAY_SIZE(eco920_spi_devices));
+       /* LEDs */
+       at91_gpio_leds(eco920_leds, ARRAY_SIZE(eco920_leds));
 }
 
 MACHINE_START(ECO920, "eco920")
index 64c1dbf..86050da 100644 (file)
@@ -66,11 +66,20 @@ static struct at91_udc_data __initdata kafa_udc_data = {
        .pullup_pin     = AT91_PIN_PB7,
 };
 
+/*
+ * LEDs
+ */
+static struct gpio_led kafa_leds[] = {
+       {       /* D1 */
+               .name                   = "led1",
+               .gpio                   = AT91_PIN_PB4,
+               .active_low             = 1,
+               .default_trigger        = "heartbeat",
+       },
+};
+
 static void __init kafa_board_init(void)
 {
-       /* Set up the LEDs */
-       at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4);
-
        /* Serial */
        /* DBGU on ttyS0. (Rx & Tx only) */
        at91_register_uart(0, 0, 0);
@@ -88,6 +97,8 @@ static void __init kafa_board_init(void)
        at91_add_device_i2c(NULL, 0);
        /* SPI */
        at91_add_device_spi(NULL, 0);
+       /* LEDs */
+       at91_gpio_leds(kafa_leds, ARRAY_SIZE(kafa_leds));
 }
 
 MACHINE_START(KAFA, "Sperry-Sun KAFA")
index 5d96cb8..00d6007 100644 (file)
@@ -96,11 +96,26 @@ static struct atmel_nand_data __initdata kb9202_nand_data = {
        .num_parts      = ARRAY_SIZE(kb9202_nand_partition),
 };
 
+/*
+ * LEDs
+ */
+static struct gpio_led kb9202_leds[] = {
+       {       /* D1 */
+               .name                   = "led1",
+               .gpio                   = AT91_PIN_PC19,
+               .active_low             = 1,
+               .default_trigger        = "heartbeat",
+       },
+       {       /* D2 */
+               .name                   = "led2",
+               .gpio                   = AT91_PIN_PC18,
+               .active_low             = 1,
+               .default_trigger        = "timer",
+       }
+};
+
 static void __init kb9202_board_init(void)
 {
-       /* Set up the LEDs */
-       at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18);
-
        /* Serial */
        /* DBGU on ttyS0. (Rx & Tx only) */
        at91_register_uart(0, 0, 0);
@@ -128,6 +143,8 @@ static void __init kb9202_board_init(void)
        at91_add_device_spi(NULL, 0);
        /* NAND */
        at91_add_device_nand(&kb9202_nand_data);
+       /* LEDs */
+       at91_gpio_leds(kb9202_leds, ARRAY_SIZE(kb9202_leds));
 }
 
 MACHINE_START(KB9200, "KB920x")
index cc2bf97..2526ad7 100644 (file)
@@ -177,9 +177,6 @@ static struct gpio_led dk_leds[] = {
 
 static void __init dk_board_init(void)
 {
-       /* Setup the LEDs */
-       at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
-
        /* Serial */
        /* DBGU on ttyS0. (Rx & Tx only) */
        at91_register_uart(0, 0, 0);
index 62e19e6..06f2ce5 100644 (file)
@@ -148,9 +148,6 @@ static struct gpio_led ek_leds[] = {
 
 static void __init ek_board_init(void)
 {
-       /* Setup the LEDs */
-       at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2);
-
        /* Serial */
        /* DBGU on ttyS0. (Rx & Tx only) */
        at91_register_uart(0, 0, 0);
index c3b43ae..93b8e3a 100644 (file)
@@ -185,9 +185,6 @@ static struct platform_device rsiews_nor_flash = {
  */
 static void __init rsi_ews_board_init(void)
 {
-       /* Setup the LEDs */
-       at91_init_leds(AT91_PIN_PB6, AT91_PIN_PB9);
-
        /* Serial */
        /* DBGU on ttyS0. (Rx & Tx only) */
        /* This one is for debugging */
index 7bf6da7..46e1eb5 100644 (file)
@@ -166,11 +166,26 @@ static struct at91_mmc_data __initdata ek_mmc_data = {
        .vcc_pin        = -EINVAL,
 };
 
+/*
+ * LEDs
+ */
+static struct gpio_led ek_leds[] = {
+       {       /* D1 */
+               .name                   = "led1",
+               .gpio                   = AT91_PIN_PA9,
+               .active_low             = 1,
+               .default_trigger        = "heartbeat",
+       },
+       {       /* D2 */
+               .name                   = "led2",
+               .gpio                   = AT91_PIN_PA6,
+               .active_low             = 1,
+               .default_trigger        = "timer",
+       }
+};
+
 static void __init ek_board_init(void)
 {
-       /* Setup the LEDs */
-       at91_init_leds(AT91_PIN_PA9, AT91_PIN_PA6);
-
        /* Serial */
        /* DBGU on ttyS0. (Rx & Tx only) */
        at91_register_uart(0, 0, 0);
@@ -197,6 +212,8 @@ static void __init ek_board_init(void)
        at91_add_device_mmc(0, &ek_mmc_data);
        /* I2C */
        at91_add_device_i2c(NULL, 0);
+       /* LEDs */
+       at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
 }
 
 MACHINE_START(SAM9_L9260, "Olimex SAM9-L9260")
index 2269be5..802d494 100644 (file)
@@ -569,9 +569,6 @@ static struct gpio_led ek_leds[] = {
 
 static void __init ek_board_init(void)
 {
-       /* Setup the LEDs */
-       at91_init_leds(AT91_PIN_PA13, AT91_PIN_PA14);
-
        /* Serial */
        /* DBGU on ttyS0. (Rx & Tx only) */
        at91_register_uart(0, 0, 0);
index 516d340..9fd57bc 100644 (file)
@@ -541,9 +541,6 @@ void __init yl9200_add_device_video(void) {}
 
 static void __init yl9200_board_init(void)
 {
-       /* Setup the LEDs D2=PB17 (timer), D3=PB16 (cpu) */
-       at91_init_leds(AT91_PIN_PB16, AT91_PIN_PB17);
-
        /* Serial */
        /* DBGU on ttyS0. (Rx & Tx only) */
        at91_register_uart(0, 0, 0);
index 369afc2..c55a436 100644 (file)
@@ -187,7 +187,6 @@ struct at91_can_data {
 extern void __init at91_add_device_can(struct at91_can_data *data);
 
  /* LEDs */
-extern void __init at91_init_leds(u8 cpu_led, u8 timer_led);
 extern void __init at91_gpio_leds(struct gpio_led *leds, int nr);
 extern void __init at91_pwm_leds(struct gpio_led *leds, int nr);
 
index 8dfafe7..1b1e62b 100644 (file)
@@ -90,108 +90,3 @@ void __init at91_pwm_leds(struct gpio_led *leds, int nr)
 #else
 void __init at91_pwm_leds(struct gpio_led *leds, int nr){}
 #endif
-
-
-/* ------------------------------------------------------------------------- */
-
-#if defined(CONFIG_LEDS)
-
-#include <asm/leds.h>
-
-/*
- * Old ARM-specific LED framework; not fully functional when generic time is
- * in use.
- */
-
-static u8 at91_leds_cpu;
-static u8 at91_leds_timer;
-
-static inline void at91_led_on(unsigned int led)
-{
-       at91_set_gpio_value(led, 0);
-}
-
-static inline void at91_led_off(unsigned int led)
-{
-       at91_set_gpio_value(led, 1);
-}
-
-static inline void at91_led_toggle(unsigned int led)
-{
-       unsigned long is_off = at91_get_gpio_value(led);
-       if (is_off)
-               at91_led_on(led);
-       else
-               at91_led_off(led);
-}
-
-
-/*
- * Handle LED events.
- */
-static void at91_leds_event(led_event_t evt)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-
-       switch(evt) {
-       case led_start:         /* System startup */
-               at91_led_on(at91_leds_cpu);
-               break;
-
-       case led_stop:          /* System stop / suspend */
-               at91_led_off(at91_leds_cpu);
-               break;
-
-#ifdef CONFIG_LEDS_TIMER
-       case led_timer:         /* Every 50 timer ticks */
-               at91_led_toggle(at91_leds_timer);
-               break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-       case led_idle_start:    /* Entering idle state */
-               at91_led_off(at91_leds_cpu);
-               break;
-
-       case led_idle_end:      /* Exit idle state */
-               at91_led_on(at91_leds_cpu);
-               break;
-#endif
-
-       default:
-               break;
-       }
-
-       local_irq_restore(flags);
-}
-
-
-static int __init leds_init(void)
-{
-       if (!at91_leds_timer || !at91_leds_cpu)
-               return -ENODEV;
-
-       leds_event = at91_leds_event;
-
-       leds_event(led_start);
-       return 0;
-}
-
-__initcall(leds_init);
-
-
-void __init at91_init_leds(u8 cpu_led, u8 timer_led)
-{
-       /* Enable GPIO to access the LEDs */
-       at91_set_gpio_output(cpu_led, 1);
-       at91_set_gpio_output(timer_led, 1);
-
-       at91_leds_cpu   = cpu_led;
-       at91_leds_timer = timer_led;
-}
-
-#else
-void __init at91_init_leds(u8 cpu_led, u8 timer_led) {}
-#endif
index f2f0256..5872b49 100644 (file)
@@ -16,5 +16,3 @@ obj-$(CONFIG_ARCH_CLEP7312) += clep7312.o
 obj-$(CONFIG_ARCH_EDB7211)  += edb7211-arch.o edb7211-mm.o
 obj-$(CONFIG_ARCH_FORTUNET) += fortunet.o
 obj-$(CONFIG_ARCH_P720T)    += p720t.o
-leds-$(CONFIG_ARCH_P720T)   += p720t-leds.o
-obj-$(CONFIG_LEDS)          += $(leds-y)
index f15293b..3a4af00 100644 (file)
@@ -30,7 +30,6 @@
 #include <asm/sizes.h>
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/leds.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <asm/mach/map.h>
diff --git a/arch/arm/mach-clps711x/p720t-leds.c b/arch/arm/mach-clps711x/p720t-leds.c
deleted file mode 100644 (file)
index bbc449f..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *  linux/arch/arm/mach-clps711x/leds.c
- *
- *  Integrator LED control routines
- *
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/leds.h>
-#include <asm/mach-types.h>
-
-static void p720t_leds_event(led_event_t ledevt)
-{
-       unsigned long flags;
-       u32 pddr;
-
-       local_irq_save(flags);
-       switch(ledevt) {
-       case led_idle_start:
-               break;
-
-       case led_idle_end:
-               break;
-
-       case led_timer:
-               pddr = clps_readb(PDDR);
-               clps_writeb(pddr ^ 1, PDDR);
-               break;
-
-       default:
-               break;
-       }
-
-       local_irq_restore(flags);
-}
-
-static int __init leds_init(void)
-{
-       if (machine_is_p720t())
-               leds_event = p720t_leds_event;
-
-       return 0;
-}
-
-arch_initcall(leds_init);
index f266d90..b752b58 100644 (file)
@@ -23,6 +23,8 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
 
 #include <mach/hardware.h>
 #include <asm/pgtable.h>
@@ -34,6 +36,8 @@
 #include <asm/mach/map.h>
 #include <mach/syspld.h>
 
+#include <asm/hardware/clps7111.h>
+
 #include "common.h"
 
 /*
@@ -107,6 +111,64 @@ static void __init p720t_init_early(void)
        }
 }
 
+/*
+ * LED controled by CPLD
+ */
+#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
+static void p720t_led_set(struct led_classdev *cdev,
+                             enum led_brightness b)
+{
+       u8 reg = clps_readb(PDDR);
+
+       if (b != LED_OFF)
+               reg |= 0x1;
+       else
+               reg &= ~0x1;
+
+       clps_writeb(reg, PDDR);
+}
+
+static enum led_brightness p720t_led_get(struct led_classdev *cdev)
+{
+       u8 reg = clps_readb(PDDR);
+
+       return (reg & 0x1) ? LED_FULL : LED_OFF;
+}
+
+static int __init p720t_leds_init(void)
+{
+
+       struct led_classdev *cdev;
+       int ret;
+
+       if (!machine_is_p720t())
+               return -ENODEV;
+
+       cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
+       if (!cdev)
+               return -ENOMEM;
+
+       cdev->name = "p720t:0";
+       cdev->brightness_set = p720t_led_set;
+       cdev->brightness_get = p720t_led_get;
+       cdev->default_trigger = "heartbeat";
+
+       ret = led_classdev_register(NULL, cdev);
+       if (ret < 0) {
+               kfree(cdev);
+               return ret;
+       }
+
+       return 0;
+}
+
+/*
+ * Since we may have triggers on any subsystem, defer registration
+ * until after subsystem_init.
+ */
+fs_initcall(p720t_leds_init);
+#endif
+
 MACHINE_START(P720T, "ARM-Prospector720T")
        /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
        .atag_offset    = 0x100,
index 6520ac8..935e4af 100644 (file)
@@ -4,9 +4,7 @@
 
 # Object file lists.
 
-obj-y                  := core.o io.o
+obj-y                  := core.o io.o leds.o
 obj-m                  :=
 obj-n                  :=
 obj-                   :=
-
-obj-$(CONFIG_LEDS)     += leds.o
index 99e14e3..0398258 100644 (file)
@@ -1,52 +1,71 @@
 /*
- *  linux/arch/arm/mach-ebsa110/leds.c
+ * Driver for the LED found on the EBSA110 machine
+ * Based on Versatile and RealView machine LED code
  *
- *  Copyright (C) 1998 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  EBSA-110 LED control routines.  We use the led as follows:
- *
- *   - Red - toggles state every 50 timer interrupts
+ * License terms: GNU General Public License (GPL) version 2
+ * Author: Bryan Wu <bryan.wu@canonical.com>
  */
-#include <linux/module.h>
-#include <linux/spinlock.h>
+#include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
 
-#include <mach/hardware.h>
-#include <asm/leds.h>
 #include <asm/mach-types.h>
 
 #include "core.h"
 
-static spinlock_t leds_lock;
-
-static void ebsa110_leds_event(led_event_t ledevt)
+#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
+static void ebsa110_led_set(struct led_classdev *cdev,
+                             enum led_brightness b)
 {
-       unsigned long flags;
+       u8 reg = __raw_readb(SOFT_BASE);
 
-       spin_lock_irqsave(&leds_lock, flags);
+       if (b != LED_OFF)
+               reg |= 0x80;
+       else
+               reg &= ~0x80;
 
-       switch(ledevt) {
-       case led_timer:
-               *(volatile unsigned char *)SOFT_BASE ^= 128;
-               break;
+       __raw_writeb(reg, SOFT_BASE);
+}
 
-       default:
-               break;
-       }
+static enum led_brightness ebsa110_led_get(struct led_classdev *cdev)
+{
+       u8 reg = __raw_readb(SOFT_BASE);
 
-       spin_unlock_irqrestore(&leds_lock, flags);
+       return (reg & 0x80) ? LED_FULL : LED_OFF;
 }
 
-static int __init leds_init(void)
+static int __init ebsa110_leds_init(void)
 {
-       if (machine_is_ebsa110())
-               leds_event = ebsa110_leds_event;
+
+       struct led_classdev *cdev;
+       int ret;
+
+       if (!machine_is_ebsa110())
+               return -ENODEV;
+
+       cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
+       if (!cdev)
+               return -ENOMEM;
+
+       cdev->name = "ebsa110:0";
+       cdev->brightness_set = ebsa110_led_set;
+       cdev->brightness_get = ebsa110_led_get;
+       cdev->default_trigger = "heartbeat";
+
+       ret = led_classdev_register(NULL, cdev);
+       if (ret < 0) {
+               kfree(cdev);
+               return ret;
+       }
 
        return 0;
 }
 
-__initcall(leds_init);
+/*
+ * Since we may have triggers on any subsystem, defer registration
+ * until after subsystem_init.
+ */
+fs_initcall(ebsa110_leds_init);
+#endif
index 3afb1b2..0b64dd4 100644 (file)
@@ -14,15 +14,11 @@ pci-$(CONFIG_ARCH_EBSA285_HOST) += ebsa285-pci.o
 pci-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o
 pci-$(CONFIG_ARCH_PERSONAL_SERVER) += personal-pci.o
 
-leds-$(CONFIG_ARCH_EBSA285) += ebsa285-leds.o
-leds-$(CONFIG_ARCH_NETWINDER) += netwinder-leds.o
-
 obj-$(CONFIG_ARCH_CATS) += cats-hw.o isa-timer.o
 obj-$(CONFIG_ARCH_EBSA285) += ebsa285.o dc21285-timer.o
 obj-$(CONFIG_ARCH_NETWINDER) += netwinder-hw.o isa-timer.o
 obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal.o dc21285-timer.o
 
 obj-$(CONFIG_PCI)      +=$(pci-y)
-obj-$(CONFIG_LEDS)     +=$(leds-y)
 
 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 (file)
index 5bd2667..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- *  linux/arch/arm/mach-footbridge/ebsa285-leds.c
- *
- *  Copyright (C) 1998-1999 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- * EBSA-285 control routines.
- *
- * The EBSA-285 uses the leds as follows:
- *  - Green - toggles state every 50 timer interrupts
- *  - Amber - On if system is not idle
- *  - Red   - currently unused
- *
- * Changelog:
- *   02-05-1999        RMK     Various cleanups
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-
-#include <mach/hardware.h>
-#include <asm/leds.h>
-#include <asm/mach-types.h>
-
-#define LED_STATE_ENABLED      1
-#define LED_STATE_CLAIMED      2
-static char led_state;
-static char hw_led_state;
-
-static DEFINE_SPINLOCK(leds_lock);
-
-static void ebsa285_leds_event(led_event_t evt)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&leds_lock, flags);
-
-       switch (evt) {
-       case led_start:
-               hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN;
-#ifndef CONFIG_LEDS_CPU
-               hw_led_state |= XBUS_LED_AMBER;
-#endif
-               led_state |= LED_STATE_ENABLED;
-               break;
-
-       case led_stop:
-               led_state &= ~LED_STATE_ENABLED;
-               break;
-
-       case led_claim:
-               led_state |= LED_STATE_CLAIMED;
-               hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN | XBUS_LED_AMBER;
-               break;
-
-       case led_release:
-               led_state &= ~LED_STATE_CLAIMED;
-               hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN | XBUS_LED_AMBER;
-               break;
-
-#ifdef CONFIG_LEDS_TIMER
-       case led_timer:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state ^= XBUS_LED_GREEN;
-               break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-       case led_idle_start:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state |= XBUS_LED_AMBER;
-               break;
-
-       case led_idle_end:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state &= ~XBUS_LED_AMBER;
-               break;
-#endif
-
-       case led_halted:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state &= ~XBUS_LED_RED;
-               break;
-
-       case led_green_on:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state &= ~XBUS_LED_GREEN;
-               break;
-
-       case led_green_off:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state |= XBUS_LED_GREEN;
-               break;
-
-       case led_amber_on:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state &= ~XBUS_LED_AMBER;
-               break;
-
-       case led_amber_off:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state |= XBUS_LED_AMBER;
-               break;
-
-       case led_red_on:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state &= ~XBUS_LED_RED;
-               break;
-
-       case led_red_off:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state |= XBUS_LED_RED;
-               break;
-
-       default:
-               break;
-       }
-
-       if  (led_state & LED_STATE_ENABLED)
-               *XBUS_LEDS = hw_led_state;
-
-       spin_unlock_irqrestore(&leds_lock, flags);
-}
-
-static int __init leds_init(void)
-{
-       if (machine_is_ebsa285())
-               leds_event = ebsa285_leds_event;
-
-       leds_event(led_start);
-
-       return 0;
-}
-
-__initcall(leds_init);
index 27716a7..b09551e 100644 (file)
@@ -5,6 +5,8 @@
  */
 #include <linux/init.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
 
 #include <asm/hardware/dec21285.h>
 #include <asm/mach-types.h>
 
 #include "common.h"
 
+/* LEDs */
+#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
+struct ebsa285_led {
+       struct led_classdev     cdev;
+       u8                      mask;
+};
+
+/*
+ * The triggers lines up below will only be used if the
+ * LED triggers are compiled in.
+ */
+static const struct {
+       const char *name;
+       const char *trigger;
+} ebsa285_leds[] = {
+       { "ebsa285:amber", "heartbeat", },
+       { "ebsa285:green", "cpu0", },
+       { "ebsa285:red",},
+};
+
+static void ebsa285_led_set(struct led_classdev *cdev,
+               enum led_brightness b)
+{
+       struct ebsa285_led *led = container_of(cdev,
+                       struct ebsa285_led, cdev);
+
+       if (b != LED_OFF)
+               *XBUS_LEDS |= led->mask;
+       else
+               *XBUS_LEDS &= ~led->mask;
+}
+
+static enum led_brightness ebsa285_led_get(struct led_classdev *cdev)
+{
+       struct ebsa285_led *led = container_of(cdev,
+                       struct ebsa285_led, cdev);
+
+       return (*XBUS_LEDS & led->mask) ? LED_FULL : LED_OFF;
+}
+
+static int __init ebsa285_leds_init(void)
+{
+       int i;
+
+       if (machine_is_ebsa285())
+               return -ENODEV;
+
+       /* 3 LEDS All ON */
+       *XBUS_LEDS |= XBUS_LED_AMBER | XBUS_LED_GREEN | XBUS_LED_RED;
+
+       for (i = 0; i < ARRAY_SIZE(ebsa285_leds); i++) {
+               struct ebsa285_led *led;
+
+               led = kzalloc(sizeof(*led), GFP_KERNEL);
+               if (!led)
+                       break;
+
+               led->cdev.name = ebsa285_leds[i].name;
+               led->cdev.brightness_set = ebsa285_led_set;
+               led->cdev.brightness_get = ebsa285_led_get;
+               led->cdev.default_trigger = ebsa285_leds[i].trigger;
+               led->mask = BIT(i);
+
+               if (led_classdev_register(NULL, &led->cdev) < 0) {
+                       kfree(led);
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Since we may have triggers on any subsystem, defer registration
+ * until after subsystem_init.
+ */
+fs_initcall(ebsa285_leds_init);
+#endif
+
 MACHINE_START(EBSA285, "EBSA285")
        /* Maintainer: Russell King */
        .atag_offset    = 0x100,
index cac9f67..d2d1433 100644 (file)
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
 
 #include <asm/hardware/dec21285.h>
-#include <asm/leds.h>
 #include <asm/mach-types.h>
 #include <asm/setup.h>
 #include <asm/system_misc.h>
 #define GP1_IO_BASE            0x338
 #define GP2_IO_BASE            0x33a
 
-
-#ifdef CONFIG_LEDS
-#define DEFAULT_LEDS   0
-#else
-#define DEFAULT_LEDS   GPIO_GREEN_LED
-#endif
-
 /*
  * Winbond WB83977F accessibility stuff
  */
@@ -611,15 +605,9 @@ static void __init rwa010_init(void)
 static int __init nw_hw_init(void)
 {
        if (machine_is_netwinder()) {
-               unsigned long flags;
-
                wb977_init();
                cpld_init();
                rwa010_init();
-
-               raw_spin_lock_irqsave(&nw_gpio_lock, flags);
-               nw_gpio_modify_op(GPIO_RED_LED|GPIO_GREEN_LED, DEFAULT_LEDS);
-               raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
        }
        return 0;
 }
@@ -672,6 +660,102 @@ static void netwinder_restart(char mode, const char *cmd)
        }
 }
 
+/* LEDs */
+#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
+struct netwinder_led {
+       struct led_classdev     cdev;
+       u8                      mask;
+};
+
+/*
+ * The triggers lines up below will only be used if the
+ * LED triggers are compiled in.
+ */
+static const struct {
+       const char *name;
+       const char *trigger;
+} netwinder_leds[] = {
+       { "netwinder:green", "heartbeat", },
+       { "netwinder:red", "cpu0", },
+};
+
+/*
+ * The LED control in Netwinder is reversed:
+ *  - setting bit means turn off LED
+ *  - clearing bit means turn on LED
+ */
+static void netwinder_led_set(struct led_classdev *cdev,
+               enum led_brightness b)
+{
+       struct netwinder_led *led = container_of(cdev,
+                       struct netwinder_led, cdev);
+       unsigned long flags;
+       u32 reg;
+
+       spin_lock_irqsave(&nw_gpio_lock, flags);
+       reg = nw_gpio_read();
+       if (b != LED_OFF)
+               reg &= ~led->mask;
+       else
+               reg |= led->mask;
+       nw_gpio_modify_op(led->mask, reg);
+       spin_unlock_irqrestore(&nw_gpio_lock, flags);
+}
+
+static enum led_brightness netwinder_led_get(struct led_classdev *cdev)
+{
+       struct netwinder_led *led = container_of(cdev,
+                       struct netwinder_led, cdev);
+       unsigned long flags;
+       u32 reg;
+
+       spin_lock_irqsave(&nw_gpio_lock, flags);
+       reg = nw_gpio_read();
+       spin_unlock_irqrestore(&nw_gpio_lock, flags);
+
+       return (reg & led->mask) ? LED_OFF : LED_FULL;
+}
+
+static int __init netwinder_leds_init(void)
+{
+       int i;
+
+       if (!machine_is_netwinder())
+               return -ENODEV;
+
+       for (i = 0; i < ARRAY_SIZE(netwinder_leds); i++) {
+               struct netwinder_led *led;
+
+               led = kzalloc(sizeof(*led), GFP_KERNEL);
+               if (!led)
+                       break;
+
+               led->cdev.name = netwinder_leds[i].name;
+               led->cdev.brightness_set = netwinder_led_set;
+               led->cdev.brightness_get = netwinder_led_get;
+               led->cdev.default_trigger = netwinder_leds[i].trigger;
+
+               if (i == 0)
+                       led->mask = GPIO_GREEN_LED;
+               else
+                       led->mask = GPIO_RED_LED;
+
+               if (led_classdev_register(NULL, &led->cdev) < 0) {
+                       kfree(led);
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Since we may have triggers on any subsystem, defer registration
+ * until after subsystem_init.
+ */
+fs_initcall(netwinder_leds_init);
+#endif
+
 MACHINE_START(NETWINDER, "Rebel-NetWinder")
        /* Maintainer: Russell King/Rebel.com */
        .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 (file)
index 5a2bd89..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- *  linux/arch/arm/mach-footbridge/netwinder-leds.c
- *
- *  Copyright (C) 1998-1999 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * NetWinder LED control routines.
- *
- * The Netwinder uses the leds as follows:
- *  - Green - toggles state every 50 timer interrupts
- *  - Red   - On if the system is not idle
- *
- * Changelog:
- *   02-05-1999        RMK     Various cleanups
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-
-#include <mach/hardware.h>
-#include <asm/leds.h>
-#include <asm/mach-types.h>
-
-#define LED_STATE_ENABLED      1
-#define LED_STATE_CLAIMED      2
-static char led_state;
-static char hw_led_state;
-
-static DEFINE_RAW_SPINLOCK(leds_lock);
-
-static void netwinder_leds_event(led_event_t evt)
-{
-       unsigned long flags;
-
-       raw_spin_lock_irqsave(&leds_lock, flags);
-
-       switch (evt) {
-       case led_start:
-               led_state |= LED_STATE_ENABLED;
-               hw_led_state = GPIO_GREEN_LED;
-               break;
-
-       case led_stop:
-               led_state &= ~LED_STATE_ENABLED;
-               break;
-
-       case led_claim:
-               led_state |= LED_STATE_CLAIMED;
-               hw_led_state = 0;
-               break;
-
-       case led_release:
-               led_state &= ~LED_STATE_CLAIMED;
-               hw_led_state = 0;
-               break;
-
-#ifdef CONFIG_LEDS_TIMER
-       case led_timer:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state ^= GPIO_GREEN_LED;
-               break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-       case led_idle_start:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state &= ~GPIO_RED_LED;
-               break;
-
-       case led_idle_end:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state |= GPIO_RED_LED;
-               break;
-#endif
-
-       case led_halted:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state |= GPIO_RED_LED;
-               break;
-
-       case led_green_on:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state |= GPIO_GREEN_LED;
-               break;
-
-       case led_green_off:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state &= ~GPIO_GREEN_LED;
-               break;
-
-       case led_amber_on:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state |= GPIO_GREEN_LED | GPIO_RED_LED;
-               break;
-
-       case led_amber_off:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state &= ~(GPIO_GREEN_LED | GPIO_RED_LED);
-               break;
-
-       case led_red_on:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state |= GPIO_RED_LED;
-               break;
-
-       case led_red_off:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state &= ~GPIO_RED_LED;
-               break;
-
-       default:
-               break;
-       }
-
-       raw_spin_unlock_irqrestore(&leds_lock, flags);
-
-       if  (led_state & LED_STATE_ENABLED) {
-               raw_spin_lock_irqsave(&nw_gpio_lock, flags);
-               nw_gpio_modify_op(GPIO_RED_LED | GPIO_GREEN_LED, hw_led_state);
-               raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
-       }
-}
-
-static int __init leds_init(void)
-{
-       if (machine_is_netwinder())
-               leds_event = netwinder_leds_event;
-
-       leds_event(led_start);
-
-       return 0;
-}
-
-__initcall(leds_init);
index ebeef96..5521d18 100644 (file)
@@ -4,11 +4,10 @@
 
 # Object file lists.
 
-obj-y                                  := core.o lm.o
+obj-y                                  := core.o lm.o leds.o
 obj-$(CONFIG_ARCH_INTEGRATOR_AP)       += integrator_ap.o
 obj-$(CONFIG_ARCH_INTEGRATOR_CP)       += integrator_cp.o
 
-obj-$(CONFIG_LEDS)                     += leds.o
 obj-$(CONFIG_PCI)                      += pci_v3.o pci.o
 obj-$(CONFIG_CPU_FREQ_INTEGRATOR)      += cpu.o
 obj-$(CONFIG_INTEGRATOR_IMPD1)         += impd1.o
index ebf680b..208c05d 100644 (file)
@@ -27,7 +27,6 @@
 #include <mach/cm.h>
 #include <mach/irqs.h>
 
-#include <asm/leds.h>
 #include <asm/mach-types.h>
 #include <asm/mach/time.h>
 #include <asm/pgtable.h>
@@ -127,8 +126,6 @@ static struct amba_pl010_data integrator_uart_data = {
        .set_mctrl = integrator_uart_set_mctrl,
 };
 
-#define CM_CTRL        IO_ADDRESS(INTEGRATOR_HDR_CTRL)
-
 static DEFINE_RAW_SPINLOCK(cm_lock);
 
 /**
index 445d57a..1a78692 100644 (file)
@@ -3,6 +3,8 @@
  */
 void cm_control(u32, u32);
 
+#define CM_CTRL        IO_ADDRESS(INTEGRATOR_HDR_CTRL)
+
 #define CM_CTRL_LED                    (1 << 0)
 #define CM_CTRL_nMBDET                 (1 << 1)
 #define CM_CTRL_REMAP                  (1 << 2)
index 466defa..7a7f6d3 100644 (file)
 /*
- *  linux/arch/arm/mach-integrator/leds.c
+ * Driver for the 4 user LEDs found on the Integrator AP/CP baseboard
+ * Based on Versatile and RealView machine LED code
  *
- *  Integrator/AP and Integrator/CP LED control routines
- *
- *  Copyright (C) 1999 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * License terms: GNU General Public License (GPL) version 2
+ * Author: Bryan Wu <bryan.wu@canonical.com>
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/spinlock.h>
 #include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
 
+#include <mach/cm.h>
 #include <mach/hardware.h>
 #include <mach/platform.h>
-#include <asm/leds.h>
-#include <asm/mach-types.h>
-#include <mach/cm.h>
 
-static int saved_leds;
+#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
+
+#define ALPHA_REG __io_address(INTEGRATOR_DBG_BASE)
+#define LEDREG (__io_address(INTEGRATOR_DBG_BASE) + INTEGRATOR_DBG_LEDS_OFFSET)
 
-static void integrator_leds_event(led_event_t ledevt)
+struct integrator_led {
+       struct led_classdev     cdev;
+       u8                      mask;
+};
+
+/*
+ * The triggers lines up below will only be used if the
+ * LED triggers are compiled in.
+ */
+static const struct {
+       const char *name;
+       const char *trigger;
+} integrator_leds[] = {
+       { "integrator:green0", "heartbeat", },
+       { "integrator:yellow", },
+       { "integrator:red", },
+       { "integrator:green1", },
+       { "integrator:core_module", "cpu0", },
+};
+
+static void integrator_led_set(struct led_classdev *cdev,
+                             enum led_brightness b)
 {
-       unsigned long flags;
-       const unsigned int dbg_base = IO_ADDRESS(INTEGRATOR_DBG_BASE);
-       unsigned int update_alpha_leds;
+       struct integrator_led *led = container_of(cdev,
+                                                struct integrator_led, cdev);
+       u32 reg = __raw_readl(LEDREG);
 
-       // yup, change the LEDs
-       local_irq_save(flags);
-       update_alpha_leds = 0;
+       if (b != LED_OFF)
+               reg |= led->mask;
+       else
+               reg &= ~led->mask;
 
-       switch(ledevt) {
-       case led_idle_start:
-               cm_control(CM_CTRL_LED, 0);
-               break;
+       while (__raw_readl(ALPHA_REG) & 1)
+               cpu_relax();
 
-       case led_idle_end:
-               cm_control(CM_CTRL_LED, CM_CTRL_LED);
-               break;
+       __raw_writel(reg, LEDREG);
+}
 
-       case led_timer:
-               saved_leds ^= GREEN_LED;
-               update_alpha_leds = 1;
-               break;
+static enum led_brightness integrator_led_get(struct led_classdev *cdev)
+{
+       struct integrator_led *led = container_of(cdev,
+                                                struct integrator_led, cdev);
+       u32 reg = __raw_readl(LEDREG);
 
-       case led_red_on:
-               saved_leds |= RED_LED;
-               update_alpha_leds = 1;
-               break;
+       return (reg & led->mask) ? LED_FULL : LED_OFF;
+}
 
-       case led_red_off:
-               saved_leds &= ~RED_LED;
-               update_alpha_leds = 1;
-               break;
+static void cm_led_set(struct led_classdev *cdev,
+                             enum led_brightness b)
+{
+       if (b != LED_OFF)
+               cm_control(CM_CTRL_LED, CM_CTRL_LED);
+       else
+               cm_control(CM_CTRL_LED, 0);
+}
 
-       default:
-               break;
-       }
+static enum led_brightness cm_led_get(struct led_classdev *cdev)
+{
+       u32 reg = readl(CM_CTRL);
 
-       if (update_alpha_leds) {
-               while (__raw_readl(dbg_base + INTEGRATOR_DBG_ALPHA_OFFSET) & 1);
-               __raw_writel(saved_leds, dbg_base + INTEGRATOR_DBG_LEDS_OFFSET);
-       }
-       local_irq_restore(flags);
+       return (reg & CM_CTRL_LED) ? LED_FULL : LED_OFF;
 }
 
-static int __init leds_init(void)
+static int __init integrator_leds_init(void)
 {
-       if (machine_is_integrator() || machine_is_cintegrator())
-               leds_event = integrator_leds_event;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(integrator_leds); i++) {
+               struct integrator_led *led;
+
+               led = kzalloc(sizeof(*led), GFP_KERNEL);
+               if (!led)
+                       break;
+
+
+               led->cdev.name = integrator_leds[i].name;
+
+               if (i == 4) { /* Setting for LED in core module */
+                       led->cdev.brightness_set = cm_led_set;
+                       led->cdev.brightness_get = cm_led_get;
+               } else {
+                       led->cdev.brightness_set = integrator_led_set;
+                       led->cdev.brightness_get = integrator_led_get;
+               }
+
+               led->cdev.default_trigger = integrator_leds[i].trigger;
+               led->mask = BIT(i);
+
+               if (led_classdev_register(NULL, &led->cdev) < 0) {
+                       kfree(led);
+                       break;
+               }
+       }
 
        return 0;
 }
 
-core_initcall(leds_init);
+/*
+ * Since we may have triggers on any subsystem, defer registration
+ * until after subsystem_init.
+ */
+fs_initcall(integrator_leds_init);
+#endif
index 853efd9..9324ef9 100644 (file)
@@ -11,9 +11,6 @@ obj-                          :=
 # PCI support is optional
 obj-$(CONFIG_PCI)              += pci.o
 
-# LEDs
-obj-$(CONFIG_LEDS)             += leds.o
-
 # Board-specific support
 obj-$(CONFIG_MACH_KS8695)      += board-micrel.o
 obj-$(CONFIG_MACH_DSM320)      += board-dsm320.o
index 73bd638..47399bc 100644 (file)
@@ -182,27 +182,6 @@ static void __init ks8695_add_device_watchdog(void)
 }
 
 
-/* --------------------------------------------------------------------
- *  LEDs
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_LEDS)
-short ks8695_leds_cpu = -1;
-short ks8695_leds_timer = -1;
-
-void __init ks8695_init_leds(u8 cpu_led, u8 timer_led)
-{
-       /* Enable GPIO to access the LEDs */
-       gpio_direction_output(cpu_led, 1);
-       gpio_direction_output(timer_led, 1);
-
-       ks8695_leds_cpu   = cpu_led;
-       ks8695_leds_timer = timer_led;
-}
-#else
-void __init ks8695_init_leds(u8 cpu_led, u8 timer_led) {}
-#endif
-
 /* -------------------------------------------------------------------- */
 
 /*
index 85a3c9a..1e6594a 100644 (file)
@@ -18,11 +18,6 @@ extern void __init ks8695_add_device_wan(void);
 extern void __init ks8695_add_device_lan(void);
 extern void __init ks8695_add_device_hpna(void);
 
- /* LEDs */
-extern short ks8695_leds_cpu;
-extern short ks8695_leds_timer;
-extern void __init ks8695_init_leds(u8 cpu_led, u8 timer_led);
-
  /* PCI */
 #define KS8695_MODE_PCI                0
 #define KS8695_MODE_MINIPCI    1
diff --git a/arch/arm/mach-ks8695/leds.c b/arch/arm/mach-ks8695/leds.c
deleted file mode 100644 (file)
index 4bd7075..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * LED driver for KS8695-based boards.
- *
- * Copyright (C) Andrew Victor
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/gpio.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <asm/leds.h>
-#include <mach/devices.h>
-
-
-static inline void ks8695_led_on(unsigned int led)
-{
-       gpio_set_value(led, 0);
-}
-
-static inline void ks8695_led_off(unsigned int led)
-{
-       gpio_set_value(led, 1);
-}
-
-static inline void ks8695_led_toggle(unsigned int led)
-{
-       unsigned long is_off = gpio_get_value(led);
-       if (is_off)
-               ks8695_led_on(led);
-       else
-               ks8695_led_off(led);
-}
-
-
-/*
- * Handle LED events.
- */
-static void ks8695_leds_event(led_event_t evt)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-
-       switch(evt) {
-       case led_start:         /* System startup */
-               ks8695_led_on(ks8695_leds_cpu);
-               break;
-
-       case led_stop:          /* System stop / suspend */
-               ks8695_led_off(ks8695_leds_cpu);
-               break;
-
-#ifdef CONFIG_LEDS_TIMER
-       case led_timer:         /* Every 50 timer ticks */
-               ks8695_led_toggle(ks8695_leds_timer);
-               break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-       case led_idle_start:    /* Entering idle state */
-               ks8695_led_off(ks8695_leds_cpu);
-               break;
-
-       case led_idle_end:      /* Exit idle state */
-               ks8695_led_on(ks8695_leds_cpu);
-               break;
-#endif
-
-       default:
-               break;
-       }
-
-       local_irq_restore(flags);
-}
-
-
-static int __init leds_init(void)
-{
-       if ((ks8695_leds_timer == -1) || (ks8695_leds_cpu == -1))
-               return -ENODEV;
-
-       leds_event = ks8695_leds_event;
-
-       leds_event(led_start);
-       return 0;
-}
-
-__initcall(leds_init);
index 398e9e5..cd169c3 100644 (file)
@@ -61,14 +61,6 @@ obj-$(CONFIG_ARCH_OMAP850)           += gpio7xx.o
 obj-$(CONFIG_ARCH_OMAP15XX)            += gpio15xx.o
 obj-$(CONFIG_ARCH_OMAP16XX)            += gpio16xx.o
 
-# LEDs support
-led-$(CONFIG_MACH_OMAP_H2)             += leds-h2p2-debug.o
-led-$(CONFIG_MACH_OMAP_H3)             += leds-h2p2-debug.o
-led-$(CONFIG_MACH_OMAP_INNOVATOR)      += leds-innovator.o
-led-$(CONFIG_MACH_OMAP_PERSEUS2)       += leds-h2p2-debug.o
-led-$(CONFIG_MACH_OMAP_OSK)            += leds-osk.o
-obj-$(CONFIG_LEDS)                     += $(led-y)
-
 ifneq ($(CONFIG_FB_OMAP),)
 obj-y += lcd_dma.o
 endif
index 44a4ab1..cd8836f 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/i2c/tps65010.h>
 #include <linux/smc91x.h>
 #include <linux/omapfb.h>
+#include <linux/leds.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -306,12 +307,39 @@ static struct platform_device h2_irda_device = {
        .resource       = h2_irda_resources,
 };
 
+static struct gpio_led h2_gpio_led_pins[] = {
+       {
+               .name           = "h2:red",
+               .default_trigger = "heartbeat",
+               .gpio           = 3,
+       },
+       {
+               .name           = "h2:green",
+               .default_trigger = "cpu0",
+               .gpio           = OMAP_MPUIO(4),
+       },
+};
+
+static struct gpio_led_platform_data h2_gpio_led_data = {
+       .leds           = h2_gpio_led_pins,
+       .num_leds       = ARRAY_SIZE(h2_gpio_led_pins),
+};
+
+static struct platform_device h2_gpio_leds = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+               .platform_data = &h2_gpio_led_data,
+       },
+};
+
 static struct platform_device *h2_devices[] __initdata = {
        &h2_nor_device,
        &h2_nand_device,
        &h2_smc91x_device,
        &h2_irda_device,
        &h2_kp_device,
+       &h2_gpio_leds,
 };
 
 static void __init h2_init_smc91x(void)
@@ -406,6 +434,10 @@ static void __init h2_init(void)
        omap_cfg_reg(E19_1610_KBR4);
        omap_cfg_reg(N19_1610_KBR5);
 
+       /* GPIO based LEDs */
+       omap_cfg_reg(P18_1610_GPIO3);
+       omap_cfg_reg(MPUIO4);
+
        h2_smc91x_resources[1].start = gpio_to_irq(0);
        h2_smc91x_resources[1].end = gpio_to_irq(0);
        platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
index 86cb5a0..1fa9c45 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/i2c/tps65010.h>
 #include <linux/smc91x.h>
 #include <linux/omapfb.h>
+#include <linux/leds.h>
 
 #include <asm/setup.h>
 #include <asm/page.h>
@@ -324,6 +325,32 @@ static struct spi_board_info h3_spi_board_info[] __initdata = {
        },
 };
 
+static struct gpio_led h3_gpio_led_pins[] = {
+       {
+               .name           = "h3:red",
+               .default_trigger = "heartbeat",
+               .gpio           = 3,
+       },
+       {
+               .name           = "h3:green",
+               .default_trigger = "cpu0",
+               .gpio           = OMAP_MPUIO(4),
+       },
+};
+
+static struct gpio_led_platform_data h3_gpio_led_data = {
+       .leds           = h3_gpio_led_pins,
+       .num_leds       = ARRAY_SIZE(h3_gpio_led_pins),
+};
+
+static struct platform_device h3_gpio_leds = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+               .platform_data = &h3_gpio_led_data,
+       },
+};
+
 static struct platform_device *devices[] __initdata = {
        &nor_device,
        &nand_device,
@@ -331,6 +358,7 @@ static struct platform_device *devices[] __initdata = {
        &intlat_device,
        &h3_kp_device,
        &h3_lcd_device,
+       &h3_gpio_leds,
 };
 
 static struct omap_usb_config h3_usb_config __initdata = {
@@ -398,6 +426,10 @@ static void __init h3_init(void)
        omap_cfg_reg(E19_1610_KBR4);
        omap_cfg_reg(N19_1610_KBR5);
 
+       /* GPIO based LEDs */
+       omap_cfg_reg(P18_1610_GPIO3);
+       omap_cfg_reg(MPUIO4);
+
        smc91x_resources[1].start = gpio_to_irq(40);
        smc91x_resources[1].end = gpio_to_irq(40);
        platform_add_devices(devices, ARRAY_SIZE(devices));
index 8784705..7ee1c1e 100644 (file)
@@ -380,10 +380,37 @@ static struct platform_device osk5912_lcd_device = {
        .id             = -1,
 };
 
+static struct gpio_led mistral_gpio_led_pins[] = {
+       {
+               .name           = "mistral:red",
+               .default_trigger = "heartbeat",
+               .gpio           = 3,
+       },
+       {
+               .name           = "mistral:green",
+               .default_trigger = "cpu0",
+               .gpio           = OMAP_MPUIO(4),
+       },
+};
+
+static struct gpio_led_platform_data mistral_gpio_led_data = {
+       .leds           = mistral_gpio_led_pins,
+       .num_leds       = ARRAY_SIZE(mistral_gpio_led_pins),
+};
+
+static struct platform_device mistral_gpio_leds = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+               .platform_data = &mistral_gpio_led_data,
+       },
+};
+
 static struct platform_device *mistral_devices[] __initdata = {
        &osk5912_kp_device,
        &mistral_bl_device,
        &osk5912_lcd_device,
+       &mistral_gpio_leds,
 };
 
 static int mistral_get_pendown_state(void)
@@ -508,6 +535,12 @@ static void __init osk_mistral_init(void)
        if (gpio_request(2, "lcd_pwr") == 0)
                gpio_direction_output(2, 1);
 
+       /*
+        * GPIO based LEDs
+        */
+       omap_cfg_reg(P18_1610_GPIO3);
+       omap_cfg_reg(MPUIO4);
+
        i2c_register_board_info(1, mistral_i2c_board_info,
                        ARRAY_SIZE(mistral_i2c_board_info));
 
diff --git a/arch/arm/mach-omap1/leds-h2p2-debug.c b/arch/arm/mach-omap1/leds-h2p2-debug.c
deleted file mode 100644 (file)
index f6b14a1..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * linux/arch/arm/mach-omap1/leds-h2p2-debug.c
- *
- * Copyright 2003 by Texas Instruments Incorporated
- *
- * There are 16 LEDs on the debug board (all green); four may be used
- * for logical 'green', 'amber', 'red', and 'blue' (after "claiming").
- *
- * The "surfer" expansion board and H2 sample board also have two-color
- * green+red LEDs (in parallel), used here for timer and idle indicators.
- */
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/sched.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/leds.h>
-#include <asm/mach-types.h>
-
-#include <plat/fpga.h>
-
-#include "leds.h"
-
-
-#define GPIO_LED_RED           3
-#define GPIO_LED_GREEN         OMAP_MPUIO(4)
-
-
-#define LED_STATE_ENABLED      0x01
-#define LED_STATE_CLAIMED      0x02
-#define LED_TIMER_ON           0x04
-
-#define GPIO_IDLE              GPIO_LED_GREEN
-#define GPIO_TIMER             GPIO_LED_RED
-
-
-void h2p2_dbg_leds_event(led_event_t evt)
-{
-       unsigned long flags;
-
-       static struct h2p2_dbg_fpga __iomem *fpga;
-       static u16 led_state, hw_led_state;
-
-       local_irq_save(flags);
-
-       if (!(led_state & LED_STATE_ENABLED) && evt != led_start)
-               goto done;
-
-       switch (evt) {
-       case led_start:
-               if (!fpga)
-                       fpga = ioremap(H2P2_DBG_FPGA_START,
-                                               H2P2_DBG_FPGA_SIZE);
-               if (fpga) {
-                       led_state |= LED_STATE_ENABLED;
-                       __raw_writew(~0, &fpga->leds);
-               }
-               break;
-
-       case led_stop:
-       case led_halted:
-               /* all leds off during suspend or shutdown */
-
-               if (! machine_is_omap_perseus2()) {
-                       gpio_set_value(GPIO_TIMER, 0);
-                       gpio_set_value(GPIO_IDLE, 0);
-               }
-
-               __raw_writew(~0, &fpga->leds);
-               led_state &= ~LED_STATE_ENABLED;
-               if (evt == led_halted) {
-                       iounmap(fpga);
-                       fpga = NULL;
-               }
-
-               goto done;
-
-       case led_claim:
-               led_state |= LED_STATE_CLAIMED;
-               hw_led_state = 0;
-               break;
-
-       case led_release:
-               led_state &= ~LED_STATE_CLAIMED;
-               break;
-
-#ifdef CONFIG_LEDS_TIMER
-       case led_timer:
-               led_state ^= LED_TIMER_ON;
-
-               if (machine_is_omap_perseus2())
-                       hw_led_state ^= H2P2_DBG_FPGA_P2_LED_TIMER;
-               else {
-                       gpio_set_value(GPIO_TIMER, led_state & LED_TIMER_ON);
-                       goto done;
-               }
-
-               break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-       case led_idle_start:
-               if (machine_is_omap_perseus2())
-                       hw_led_state |= H2P2_DBG_FPGA_P2_LED_IDLE;
-               else {
-                       gpio_set_value(GPIO_IDLE, 1);
-                       goto done;
-               }
-
-               break;
-
-       case led_idle_end:
-               if (machine_is_omap_perseus2())
-                       hw_led_state &= ~H2P2_DBG_FPGA_P2_LED_IDLE;
-               else {
-                       gpio_set_value(GPIO_IDLE, 0);
-                       goto done;
-               }
-
-               break;
-#endif
-
-       case led_green_on:
-               hw_led_state |= H2P2_DBG_FPGA_LED_GREEN;
-               break;
-       case led_green_off:
-               hw_led_state &= ~H2P2_DBG_FPGA_LED_GREEN;
-               break;
-
-       case led_amber_on:
-               hw_led_state |= H2P2_DBG_FPGA_LED_AMBER;
-               break;
-       case led_amber_off:
-               hw_led_state &= ~H2P2_DBG_FPGA_LED_AMBER;
-               break;
-
-       case led_red_on:
-               hw_led_state |= H2P2_DBG_FPGA_LED_RED;
-               break;
-       case led_red_off:
-               hw_led_state &= ~H2P2_DBG_FPGA_LED_RED;
-               break;
-
-       case led_blue_on:
-               hw_led_state |= H2P2_DBG_FPGA_LED_BLUE;
-               break;
-       case led_blue_off:
-               hw_led_state &= ~H2P2_DBG_FPGA_LED_BLUE;
-               break;
-
-       default:
-               break;
-       }
-
-
-       /*
-        *  Actually burn the LEDs
-        */
-       if (led_state & LED_STATE_ENABLED)
-               __raw_writew(~hw_led_state, &fpga->leds);
-
-done:
-       local_irq_restore(flags);
-}
diff --git a/arch/arm/mach-omap1/leds-innovator.c b/arch/arm/mach-omap1/leds-innovator.c
deleted file mode 100644 (file)
index 3a066ee..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * linux/arch/arm/mach-omap1/leds-innovator.c
- */
-#include <linux/init.h>
-
-#include <mach/hardware.h>
-#include <asm/leds.h>
-
-#include "leds.h"
-
-
-#define LED_STATE_ENABLED      1
-#define LED_STATE_CLAIMED      2
-
-static unsigned int led_state;
-static unsigned int hw_led_state;
-
-void innovator_leds_event(led_event_t evt)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-
-       switch (evt) {
-       case led_start:
-               hw_led_state = 0;
-               led_state = LED_STATE_ENABLED;
-               break;
-
-       case led_stop:
-               led_state &= ~LED_STATE_ENABLED;
-               hw_led_state = 0;
-               break;
-
-       case led_claim:
-               led_state |= LED_STATE_CLAIMED;
-               hw_led_state = 0;
-               break;
-
-       case led_release:
-               led_state &= ~LED_STATE_CLAIMED;
-               hw_led_state = 0;
-               break;
-
-#ifdef CONFIG_LEDS_TIMER
-       case led_timer:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state ^= 0;
-               break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-       case led_idle_start:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state |= 0;
-               break;
-
-       case led_idle_end:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state &= ~0;
-               break;
-#endif
-
-       case led_halted:
-               break;
-
-       case led_green_on:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state &= ~0;
-               break;
-
-       case led_green_off:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state |= 0;
-               break;
-
-       case led_amber_on:
-               break;
-
-       case led_amber_off:
-               break;
-
-       case led_red_on:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state &= ~0;
-               break;
-
-       case led_red_off:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state |= 0;
-               break;
-
-       default:
-               break;
-       }
-
-       local_irq_restore(flags);
-}
diff --git a/arch/arm/mach-omap1/leds-osk.c b/arch/arm/mach-omap1/leds-osk.c
deleted file mode 100644 (file)
index 936ed42..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * linux/arch/arm/mach-omap1/leds-osk.c
- *
- * LED driver for OSK with optional Mistral QVGA board
- */
-#include <linux/gpio.h>
-#include <linux/init.h>
-
-#include <mach/hardware.h>
-#include <asm/leds.h>
-
-#include "leds.h"
-
-
-#define LED_STATE_ENABLED      (1 << 0)
-#define LED_STATE_CLAIMED      (1 << 1)
-static u8 led_state;
-
-#define        TIMER_LED               (1 << 3)        /* Mistral board */
-#define        IDLE_LED                (1 << 4)        /* Mistral board */
-static u8 hw_led_state;
-
-
-#ifdef CONFIG_OMAP_OSK_MISTRAL
-
-/* For now, all system indicators require the Mistral board, since that
- * LED can be manipulated without a task context.  This LED is either red,
- * or green, but not both; it can't give the full "disco led" effect.
- */
-
-#define GPIO_LED_RED           3
-#define GPIO_LED_GREEN         OMAP_MPUIO(4)
-
-static void mistral_setled(void)
-{
-       int     red = 0;
-       int     green = 0;
-
-       if (hw_led_state & TIMER_LED)
-               red = 1;
-       else if (hw_led_state & IDLE_LED)
-               green = 1;
-       /* else both sides are disabled */
-
-       gpio_set_value(GPIO_LED_GREEN, green);
-       gpio_set_value(GPIO_LED_RED, red);
-}
-
-#endif
-
-void osk_leds_event(led_event_t evt)
-{
-       unsigned long   flags;
-       u16             leds;
-
-       local_irq_save(flags);
-
-       if (!(led_state & LED_STATE_ENABLED) && evt != led_start)
-               goto done;
-
-       leds = hw_led_state;
-       switch (evt) {
-       case led_start:
-               led_state |= LED_STATE_ENABLED;
-               hw_led_state = 0;
-               leds = ~0;
-               break;
-
-       case led_halted:
-       case led_stop:
-               led_state &= ~LED_STATE_ENABLED;
-               hw_led_state = 0;
-               break;
-
-       case led_claim:
-               led_state |= LED_STATE_CLAIMED;
-               hw_led_state = 0;
-               leds = ~0;
-               break;
-
-       case led_release:
-               led_state &= ~LED_STATE_CLAIMED;
-               hw_led_state = 0;
-               break;
-
-#ifdef CONFIG_OMAP_OSK_MISTRAL
-
-       case led_timer:
-               hw_led_state ^= TIMER_LED;
-               mistral_setled();
-               break;
-
-       case led_idle_start:    /* idle == off */
-               hw_led_state &= ~IDLE_LED;
-               mistral_setled();
-               break;
-
-       case led_idle_end:
-               hw_led_state |= IDLE_LED;
-               mistral_setled();
-               break;
-
-#endif /* CONFIG_OMAP_OSK_MISTRAL */
-
-       default:
-               break;
-       }
-
-       leds ^= hw_led_state;
-
-done:
-       local_irq_restore(flags);
-}
diff --git a/arch/arm/mach-omap1/leds.c b/arch/arm/mach-omap1/leds.c
deleted file mode 100644 (file)
index ae6dd93..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * linux/arch/arm/mach-omap1/leds.c
- *
- * OMAP LEDs dispatcher
- */
-#include <linux/gpio.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <asm/leds.h>
-#include <asm/mach-types.h>
-
-#include <plat/mux.h>
-
-#include "leds.h"
-
-static int __init
-omap_leds_init(void)
-{
-       if (!cpu_class_is_omap1())
-               return -ENODEV;
-
-       if (machine_is_omap_innovator())
-               leds_event = innovator_leds_event;
-
-       else if (machine_is_omap_h2()
-                       || machine_is_omap_h3()
-                       || machine_is_omap_perseus2())
-               leds_event = h2p2_dbg_leds_event;
-
-       else if (machine_is_omap_osk())
-               leds_event = osk_leds_event;
-
-       else
-               return -1;
-
-       if (machine_is_omap_h2()
-                       || machine_is_omap_h3()
-#ifdef CONFIG_OMAP_OSK_MISTRAL
-                       || machine_is_omap_osk()
-#endif
-                       ) {
-
-               /* LED1/LED2 pins can be used as GPIO (as done here), or by
-                * the LPG (works even in deep sleep!), to drive a bicolor
-                * LED on the H2 sample board, and another on the H2/P2
-                * "surfer" expansion board.
-                *
-                * The same pins drive a LED on the OSK Mistral board, but
-                * that's a different kind of LED (just one color at a time).
-                */
-               omap_cfg_reg(P18_1610_GPIO3);
-               if (gpio_request(3, "LED red") == 0)
-                       gpio_direction_output(3, 1);
-               else
-                       printk(KERN_WARNING "LED: can't get GPIO3/red?\n");
-
-               omap_cfg_reg(MPUIO4);
-               if (gpio_request(OMAP_MPUIO(4), "LED green") == 0)
-                       gpio_direction_output(OMAP_MPUIO(4), 1);
-               else
-                       printk(KERN_WARNING "LED: can't get MPUIO4/green?\n");
-       }
-
-       leds_event(led_start);
-       return 0;
-}
-
-__initcall(omap_leds_init);
diff --git a/arch/arm/mach-omap1/leds.h b/arch/arm/mach-omap1/leds.h
deleted file mode 100644 (file)
index a1e9fed..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-extern void innovator_leds_event(led_event_t evt);
-extern void h2p2_dbg_leds_event(led_event_t evt);
-extern void osk_leds_event(led_event_t evt);
index 4062480..4d4816f 100644 (file)
@@ -44,7 +44,6 @@
 #include <linux/clockchips.h>
 #include <linux/io.h>
 
-#include <asm/leds.h>
 #include <asm/irq.h>
 #include <asm/sched_clock.h>
 
index eae49c3..7452954 100644 (file)
@@ -46,7 +46,6 @@
 #include <linux/clockchips.h>
 #include <linux/io.h>
 
-#include <asm/leds.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
index 78a6a11..9b1c953 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/ethtool.h>
 #include <net/dsa.h>
 #include <asm/mach-types.h>
-#include <asm/leds.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
 #include <mach/orion5x.h>
index 2f5dc54..51ba2b8 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/i2c.h>
 #include <net/dsa.h>
 #include <asm/mach-types.h>
-#include <asm/leds.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
 #include <mach/orion5x.h>
index 399130f..0a56b94 100644 (file)
@@ -19,8 +19,8 @@
 #include <linux/mv643xx_eth.h>
 #include <linux/ata_platform.h>
 #include <linux/i2c.h>
+#include <linux/leds.h>
 #include <asm/mach-types.h>
-#include <asm/leds.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
 #include <mach/orion5x.h>
 #define RD88F5182_PCI_SLOT0_IRQ_A_PIN  7
 #define RD88F5182_PCI_SLOT0_IRQ_B_PIN  6
 
-/*
- * GPIO Debug LED
- */
-
-#define RD88F5182_GPIO_DBG_LED         0
-
 /*****************************************************************************
  * 16M NOR Flash on Device bus CS1
  ****************************************************************************/
@@ -83,55 +77,32 @@ static struct platform_device rd88f5182_nor_flash = {
        .resource               = &rd88f5182_nor_flash_resource,
 };
 
-#ifdef CONFIG_LEDS
-
 /*****************************************************************************
- * Use GPIO debug led as CPU active indication
+ * Use GPIO LED as CPU active indication
  ****************************************************************************/
 
-static void rd88f5182_dbgled_event(led_event_t evt)
-{
-       int val;
-
-       if (evt == led_idle_end)
-               val = 1;
-       else if (evt == led_idle_start)
-               val = 0;
-       else
-               return;
-
-       gpio_set_value(RD88F5182_GPIO_DBG_LED, val);
-}
-
-static int __init rd88f5182_dbgled_init(void)
-{
-       int pin;
-
-       if (machine_is_rd88f5182()) {
-               pin = RD88F5182_GPIO_DBG_LED;
+#define RD88F5182_GPIO_LED             0
 
-               if (gpio_request(pin, "DBGLED") == 0) {
-                       if (gpio_direction_output(pin, 0) != 0) {
-                               printk(KERN_ERR "rd88f5182_dbgled_init failed "
-                                               "to set output pin %d\n", pin);
-                               gpio_free(pin);
-                               return 0;
-                       }
-               } else {
-                       printk(KERN_ERR "rd88f5182_dbgled_init failed "
-                                       "to request gpio %d\n", pin);
-                       return 0;
-               }
-
-               leds_event = rd88f5182_dbgled_event;
-       }
-
-       return 0;
-}
+static struct gpio_led rd88f5182_gpio_led_pins[] = {
+       {
+               .name           = "rd88f5182:cpu",
+               .default_trigger = "cpu0",
+               .gpio           = RD88F5182_GPIO_LED,
+       },
+};
 
-__initcall(rd88f5182_dbgled_init);
+static struct gpio_led_platform_data rd88f5182_gpio_led_data = {
+       .leds           = rd88f5182_gpio_led_pins,
+       .num_leds       = ARRAY_SIZE(rd88f5182_gpio_led_pins),
+};
 
-#endif
+static struct platform_device rd88f5182_gpio_leds = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+               .platform_data = &rd88f5182_gpio_led_data,
+       },
+};
 
 /*****************************************************************************
  * PCI
@@ -298,6 +269,7 @@ static void __init rd88f5182_init(void)
 
        orion5x_setup_dev1_win(RD88F5182_NOR_BASE, RD88F5182_NOR_SIZE);
        platform_device_register(&rd88f5182_nor_flash);
+       platform_device_register(&rd88f5182_gpio_leds);
 
        i2c_register_board_info(0, &rd88f5182_i2c_rtc, 1);
 }
index 92df49c..ed50910 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/ethtool.h>
 #include <net/dsa.h>
 #include <asm/mach-types.h>
-#include <asm/leds.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
 #include <mach/orion5x.h>
index 0cfe8af..47a7ae9 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/leds.h>
 #include <asm/mach/time.h>
 #include <asm/errno.h>
 
index be0f7df..d4337e3 100644 (file)
@@ -95,12 +95,4 @@ obj-$(CONFIG_MACH_RAUMFELD_CONNECTOR)        += raumfeld.o
 obj-$(CONFIG_MACH_RAUMFELD_SPEAKER)    += raumfeld.o
 obj-$(CONFIG_MACH_ZIPIT2)      += z2.o
 
-# Support for blinky lights
-led-y := leds.o
-led-$(CONFIG_ARCH_LUBBOCK)     += leds-lubbock.o
-led-$(CONFIG_MACH_MAINSTONE)   += leds-mainstone.o
-led-$(CONFIG_ARCH_PXA_IDP)     += leds-idp.o
-
-obj-$(CONFIG_LEDS)             += $(led-y)
-
 obj-$(CONFIG_TOSA_BT)          += tosa-bt.o
index 6ff466b..ae1e997 100644 (file)
@@ -191,6 +191,87 @@ static void __init idp_map_io(void)
        iotable_init(idp_io_desc, ARRAY_SIZE(idp_io_desc));
 }
 
+/* LEDs */
+#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
+struct idp_led {
+       struct led_classdev     cdev;
+       u8                      mask;
+};
+
+/*
+ * The triggers lines up below will only be used if the
+ * LED triggers are compiled in.
+ */
+static const struct {
+       const char *name;
+       const char *trigger;
+} idp_leds[] = {
+       { "idp:green", "heartbeat", },
+       { "idp:red", "cpu0", },
+};
+
+static void idp_led_set(struct led_classdev *cdev,
+               enum led_brightness b)
+{
+       struct idp_led *led = container_of(cdev,
+                       struct idp_led, cdev);
+       u32 reg = IDP_CPLD_LED_CONTROL;
+
+       if (b != LED_OFF)
+               reg &= ~led->mask;
+       else
+               reg |= led->mask;
+
+       IDP_CPLD_LED_CONTROL = reg;
+}
+
+static enum led_brightness idp_led_get(struct led_classdev *cdev)
+{
+       struct idp_led *led = container_of(cdev,
+                       struct idp_led, cdev);
+
+       return (IDP_CPLD_LED_CONTROL & led->mask) ? LED_OFF : LED_FULL;
+}
+
+static int __init idp_leds_init(void)
+{
+       int i;
+
+       if (!machine_is_pxa_idp())
+               return -ENODEV;
+
+       for (i = 0; i < ARRAY_SIZE(idp_leds); i++) {
+               struct idp_led *led;
+
+               led = kzalloc(sizeof(*led), GFP_KERNEL);
+               if (!led)
+                       break;
+
+               led->cdev.name = idp_leds[i].name;
+               led->cdev.brightness_set = idp_led_set;
+               led->cdev.brightness_get = idp_led_get;
+               led->cdev.default_trigger = idp_leds[i].trigger;
+
+               if (i == 0)
+                       led->mask = IDP_HB_LED;
+               else
+                       led->mask = IDP_BUSY_LED;
+
+               if (led_classdev_register(NULL, &led->cdev) < 0) {
+                       kfree(led);
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Since we may have triggers on any subsystem, defer registration
+ * until after subsystem_init.
+ */
+fs_initcall(idp_leds_init);
+#endif
 
 MACHINE_START(PXA_IDP, "Vibren PXA255 IDP")
        /* Maintainer: Vibren Technologies */
diff --git a/arch/arm/mach-pxa/leds-idp.c b/arch/arm/mach-pxa/leds-idp.c
deleted file mode 100644 (file)
index 06b0600..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * linux/arch/arm/mach-pxa/leds-idp.c
- *
- * Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu>
- *
- * Copyright (c) 2001 Jeff Sutherland <jeffs@accelent.com>
- *
- * Original (leds-footbridge.c) by Russell King
- *
- * Macros for actual LED manipulation should be in machine specific
- * files in this 'mach' directory.
- */
-
-
-#include <linux/init.h>
-
-#include <mach/hardware.h>
-#include <asm/leds.h>
-
-#include <mach/pxa25x.h>
-#include <mach/idp.h>
-
-#include "leds.h"
-
-#define LED_STATE_ENABLED      1
-#define LED_STATE_CLAIMED      2
-
-static unsigned int led_state;
-static unsigned int hw_led_state;
-
-void idp_leds_event(led_event_t evt)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-
-       switch (evt) {
-       case led_start:
-               hw_led_state = IDP_HB_LED | IDP_BUSY_LED;
-               led_state = LED_STATE_ENABLED;
-               break;
-
-       case led_stop:
-               led_state &= ~LED_STATE_ENABLED;
-               break;
-
-       case led_claim:
-               led_state |= LED_STATE_CLAIMED;
-               hw_led_state = IDP_HB_LED | IDP_BUSY_LED;
-               break;
-
-       case led_release:
-               led_state &= ~LED_STATE_CLAIMED;
-               hw_led_state = IDP_HB_LED | IDP_BUSY_LED;
-               break;
-
-#ifdef CONFIG_LEDS_TIMER
-       case led_timer:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state ^= IDP_HB_LED;
-               break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-       case led_idle_start:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state &= ~IDP_BUSY_LED;
-               break;
-
-       case led_idle_end:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state |= IDP_BUSY_LED;
-               break;
-#endif
-
-       case led_halted:
-               break;
-
-       case led_green_on:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state |= IDP_HB_LED;
-               break;
-
-       case led_green_off:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state &= ~IDP_HB_LED;
-               break;
-
-       case led_amber_on:
-               break;
-
-       case led_amber_off:
-               break;
-
-       case led_red_on:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state |= IDP_BUSY_LED;
-               break;
-
-       case led_red_off:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state &= ~IDP_BUSY_LED;
-               break;
-
-       default:
-               break;
-       }
-
-       if  (led_state & LED_STATE_ENABLED)
-               IDP_CPLD_LED_CONTROL = ( (IDP_CPLD_LED_CONTROL | IDP_LEDS_MASK) & ~hw_led_state);
-       else
-               IDP_CPLD_LED_CONTROL |= IDP_LEDS_MASK;
-
-       local_irq_restore(flags);
-}
diff --git a/arch/arm/mach-pxa/leds-lubbock.c b/arch/arm/mach-pxa/leds-lubbock.c
deleted file mode 100644 (file)
index 0bd85c8..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * linux/arch/arm/mach-pxa/leds-lubbock.c
- *
- * Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu>
- *
- * Copyright (c) 2001 Jeff Sutherland <jeffs@accelent.com>
- *
- * Original (leds-footbridge.c) by Russell King
- *
- * Major surgery on April 2004 by Nicolas Pitre for less global
- * namespace collision.  Mostly adapted the Mainstone version.
- */
-
-#include <linux/init.h>
-
-#include <mach/hardware.h>
-#include <asm/leds.h>
-#include <mach/pxa25x.h>
-#include <mach/lubbock.h>
-
-#include "leds.h"
-
-/*
- * 8 discrete leds available for general use:
- *
- * Note: bits [15-8] are used to enable/blank the 8 7 segment hex displays
- * so be sure to not monkey with them here.
- */
-
-#define D28                    (1 << 0)
-#define D27                    (1 << 1)
-#define D26                    (1 << 2)
-#define D25                    (1 << 3)
-#define D24                    (1 << 4)
-#define D23                    (1 << 5)
-#define D22                    (1 << 6)
-#define D21                    (1 << 7)
-
-#define LED_STATE_ENABLED      1
-#define LED_STATE_CLAIMED      2
-
-static unsigned int led_state;
-static unsigned int hw_led_state;
-
-void lubbock_leds_event(led_event_t evt)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-
-       switch (evt) {
-       case led_start:
-               hw_led_state = 0;
-               led_state = LED_STATE_ENABLED;
-               break;
-
-       case led_stop:
-               led_state &= ~LED_STATE_ENABLED;
-               break;
-
-       case led_claim:
-               led_state |= LED_STATE_CLAIMED;
-               hw_led_state = 0;
-               break;
-
-       case led_release:
-               led_state &= ~LED_STATE_CLAIMED;
-               hw_led_state = 0;
-               break;
-
-#ifdef CONFIG_LEDS_TIMER
-       case led_timer:
-               hw_led_state ^= D26;
-               break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-       case led_idle_start:
-               hw_led_state &= ~D27;
-               break;
-
-       case led_idle_end:
-               hw_led_state |= D27;
-               break;
-#endif
-
-       case led_halted:
-               break;
-
-       case led_green_on:
-               hw_led_state |= D21;
-               break;
-
-       case led_green_off:
-               hw_led_state &= ~D21;
-               break;
-
-       case led_amber_on:
-               hw_led_state |= D22;
-               break;
-
-       case led_amber_off:
-               hw_led_state &= ~D22;
-               break;
-
-       case led_red_on:
-               hw_led_state |= D23;
-               break;
-
-       case led_red_off:
-               hw_led_state &= ~D23;
-               break;
-
-       default:
-               break;
-       }
-
-       if  (led_state & LED_STATE_ENABLED)
-               LUB_DISC_BLNK_LED = (LUB_DISC_BLNK_LED | 0xff) & ~hw_led_state;
-       else
-               LUB_DISC_BLNK_LED |= 0xff;
-
-       local_irq_restore(flags);
-}
diff --git a/arch/arm/mach-pxa/leds-mainstone.c b/arch/arm/mach-pxa/leds-mainstone.c
deleted file mode 100644 (file)
index 4058ab3..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * linux/arch/arm/mach-pxa/leds-mainstone.c
- *
- * Author:     Nicolas Pitre
- * Created:    Nov 05, 2002
- * Copyright:  MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-
-#include <mach/hardware.h>
-#include <asm/leds.h>
-
-#include <mach/pxa27x.h>
-#include <mach/mainstone.h>
-
-#include "leds.h"
-
-
-/* 8 discrete leds available for general use: */
-#define D28                    (1 << 0)
-#define D27                    (1 << 1)
-#define D26                    (1 << 2)
-#define D25                    (1 << 3)
-#define D24                    (1 << 4)
-#define D23                    (1 << 5)
-#define D22                    (1 << 6)
-#define D21                    (1 << 7)
-
-#define LED_STATE_ENABLED      1
-#define LED_STATE_CLAIMED      2
-
-static unsigned int led_state;
-static unsigned int hw_led_state;
-
-void mainstone_leds_event(led_event_t evt)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-
-       switch (evt) {
-       case led_start:
-               hw_led_state = 0;
-               led_state = LED_STATE_ENABLED;
-               break;
-
-       case led_stop:
-               led_state &= ~LED_STATE_ENABLED;
-               break;
-
-       case led_claim:
-               led_state |= LED_STATE_CLAIMED;
-               hw_led_state = 0;
-               break;
-
-       case led_release:
-               led_state &= ~LED_STATE_CLAIMED;
-               hw_led_state = 0;
-               break;
-
-#ifdef CONFIG_LEDS_TIMER
-       case led_timer:
-               hw_led_state ^= D26;
-               break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-       case led_idle_start:
-               hw_led_state &= ~D27;
-               break;
-
-       case led_idle_end:
-               hw_led_state |= D27;
-               break;
-#endif
-
-       case led_halted:
-               break;
-
-       case led_green_on:
-               hw_led_state |= D21;
-               break;
-
-       case led_green_off:
-               hw_led_state &= ~D21;
-               break;
-
-       case led_amber_on:
-               hw_led_state |= D22;
-               break;
-
-       case led_amber_off:
-               hw_led_state &= ~D22;
-               break;
-
-       case led_red_on:
-               hw_led_state |= D23;
-               break;
-
-       case led_red_off:
-               hw_led_state &= ~D23;
-               break;
-
-       default:
-               break;
-       }
-
-       if  (led_state & LED_STATE_ENABLED)
-               MST_LEDCTRL = (MST_LEDCTRL | 0xff) & ~hw_led_state;
-       else
-               MST_LEDCTRL |= 0xff;
-
-       local_irq_restore(flags);
-}
diff --git a/arch/arm/mach-pxa/leds.c b/arch/arm/mach-pxa/leds.c
deleted file mode 100644 (file)
index bbe4d5f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * linux/arch/arm/mach-pxa/leds.c
- *
- * xscale LEDs dispatcher
- *
- * Copyright (C) 2001 Nicolas Pitre
- *
- * Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc.
- */
-#include <linux/compiler.h>
-#include <linux/init.h>
-
-#include <asm/leds.h>
-#include <asm/mach-types.h>
-
-#include "leds.h"
-
-static int __init
-pxa_leds_init(void)
-{
-       if (machine_is_lubbock())
-               leds_event = lubbock_leds_event;
-       if (machine_is_mainstone())
-               leds_event = mainstone_leds_event;
-       if (machine_is_pxa_idp())
-               leds_event = idp_leds_event;
-
-       leds_event(led_start);
-       return 0;
-}
-
-core_initcall(pxa_leds_init);
diff --git a/arch/arm/mach-pxa/leds.h b/arch/arm/mach-pxa/leds.h
deleted file mode 100644 (file)
index 7f0dfe0..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * arch/arm/mach-pxa/leds.h
- *
- * Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc.
- *
- * blinky lights for various PXA-based systems:
- *
- */
-
-extern void idp_leds_event(led_event_t evt);
-extern void lubbock_leds_event(led_event_t evt);
-extern void mainstone_leds_event(led_event_t evt);
-extern void trizeps4_leds_event(led_event_t evt);
index 0ca0db7..3c48035 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/syscore_ops.h>
 #include <linux/major.h>
@@ -23,6 +24,8 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/smc91x.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
@@ -549,6 +552,98 @@ static void __init lubbock_map_io(void)
        PCFR |= PCFR_OPDE;
 }
 
+/*
+ * Driver for the 8 discrete LEDs available for general use:
+ * Note: bits [15-8] are used to enable/blank the 8 7 segment hex displays
+ * so be sure to not monkey with them here.
+ */
+
+#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
+struct lubbock_led {
+       struct led_classdev     cdev;
+       u8                      mask;
+};
+
+/*
+ * The triggers lines up below will only be used if the
+ * LED triggers are compiled in.
+ */
+static const struct {
+       const char *name;
+       const char *trigger;
+} lubbock_leds[] = {
+       { "lubbock:D28", "default-on", },
+       { "lubbock:D27", "cpu0", },
+       { "lubbock:D26", "heartbeat" },
+       { "lubbock:D25", },
+       { "lubbock:D24", },
+       { "lubbock:D23", },
+       { "lubbock:D22", },
+       { "lubbock:D21", },
+};
+
+static void lubbock_led_set(struct led_classdev *cdev,
+                             enum led_brightness b)
+{
+       struct lubbock_led *led = container_of(cdev,
+                                        struct lubbock_led, cdev);
+       u32 reg = LUB_DISC_BLNK_LED;
+
+       if (b != LED_OFF)
+               reg |= led->mask;
+       else
+               reg &= ~led->mask;
+
+       LUB_DISC_BLNK_LED = reg;
+}
+
+static enum led_brightness lubbock_led_get(struct led_classdev *cdev)
+{
+       struct lubbock_led *led = container_of(cdev,
+                                        struct lubbock_led, cdev);
+       u32 reg = LUB_DISC_BLNK_LED;
+
+       return (reg & led->mask) ? LED_FULL : LED_OFF;
+}
+
+static int __init lubbock_leds_init(void)
+{
+       int i;
+
+       if (!machine_is_lubbock())
+               return -ENODEV;
+
+       /* All ON */
+       LUB_DISC_BLNK_LED |= 0xff;
+       for (i = 0; i < ARRAY_SIZE(lubbock_leds); i++) {
+               struct lubbock_led *led;
+
+               led = kzalloc(sizeof(*led), GFP_KERNEL);
+               if (!led)
+                       break;
+
+               led->cdev.name = lubbock_leds[i].name;
+               led->cdev.brightness_set = lubbock_led_set;
+               led->cdev.brightness_get = lubbock_led_get;
+               led->cdev.default_trigger = lubbock_leds[i].trigger;
+               led->mask = BIT(i);
+
+               if (led_classdev_register(NULL, &led->cdev) < 0) {
+                       kfree(led);
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Since we may have triggers on any subsystem, defer registration
+ * until after subsystem_init.
+ */
+fs_initcall(lubbock_leds_init);
+#endif
+
 MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)")
        /* Maintainer: MontaVista Software Inc. */
        .map_io         = lubbock_map_io,
index 1aebaf7..bdc6c33 100644 (file)
@@ -28,6 +28,8 @@
 #include <linux/pwm_backlight.h>
 #include <linux/smc91x.h>
 #include <linux/i2c/pxa-i2c.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
@@ -613,6 +615,98 @@ static void __init mainstone_map_io(void)
        PCFR = 0x66;
 }
 
+/*
+ * Driver for the 8 discrete LEDs available for general use:
+ * Note: bits [15-8] are used to enable/blank the 8 7 segment hex displays
+ * so be sure to not monkey with them here.
+ */
+
+#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
+struct mainstone_led {
+       struct led_classdev     cdev;
+       u8                      mask;
+};
+
+/*
+ * The triggers lines up below will only be used if the
+ * LED triggers are compiled in.
+ */
+static const struct {
+       const char *name;
+       const char *trigger;
+} mainstone_leds[] = {
+       { "mainstone:D28", "default-on", },
+       { "mainstone:D27", "cpu0", },
+       { "mainstone:D26", "heartbeat" },
+       { "mainstone:D25", },
+       { "mainstone:D24", },
+       { "mainstone:D23", },
+       { "mainstone:D22", },
+       { "mainstone:D21", },
+};
+
+static void mainstone_led_set(struct led_classdev *cdev,
+                             enum led_brightness b)
+{
+       struct mainstone_led *led = container_of(cdev,
+                                        struct mainstone_led, cdev);
+       u32 reg = MST_LEDCTRL;
+
+       if (b != LED_OFF)
+               reg |= led->mask;
+       else
+               reg &= ~led->mask;
+
+       MST_LEDCTRL = reg;
+}
+
+static enum led_brightness mainstone_led_get(struct led_classdev *cdev)
+{
+       struct mainstone_led *led = container_of(cdev,
+                                        struct mainstone_led, cdev);
+       u32 reg = MST_LEDCTRL;
+
+       return (reg & led->mask) ? LED_FULL : LED_OFF;
+}
+
+static int __init mainstone_leds_init(void)
+{
+       int i;
+
+       if (!machine_is_mainstone())
+               return -ENODEV;
+
+       /* All ON */
+       MST_LEDCTRL |= 0xff;
+       for (i = 0; i < ARRAY_SIZE(mainstone_leds); i++) {
+               struct mainstone_led *led;
+
+               led = kzalloc(sizeof(*led), GFP_KERNEL);
+               if (!led)
+                       break;
+
+               led->cdev.name = mainstone_leds[i].name;
+               led->cdev.brightness_set = mainstone_led_set;
+               led->cdev.brightness_get = mainstone_led_get;
+               led->cdev.default_trigger = mainstone_leds[i].trigger;
+               led->mask = BIT(i);
+
+               if (led_classdev_register(NULL, &led->cdev) < 0) {
+                       kfree(led);
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Since we may have triggers on any subsystem, defer registration
+ * until after subsystem_init.
+ */
+fs_initcall(mainstone_leds_init);
+#endif
+
 MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
        /* Maintainer: MontaVista Software Inc. */
        .atag_offset    = 0x100,        /* BLOB boot parameter setting */
index 45868bb..d22dee9 100644 (file)
@@ -35,7 +35,6 @@
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/leds.h>
 #include <asm/mach-types.h>
 #include <asm/hardware/arm_timer.h>
 #include <asm/hardware/icst.h>
@@ -436,44 +435,6 @@ struct clcd_board clcd_plat_data = {
        .remove         = versatile_clcd_remove_dma,
 };
 
-#ifdef CONFIG_LEDS
-#define VA_LEDS_BASE (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LED_OFFSET)
-
-void realview_leds_event(led_event_t ledevt)
-{
-       unsigned long flags;
-       u32 val;
-       u32 led = 1 << smp_processor_id();
-
-       local_irq_save(flags);
-       val = readl(VA_LEDS_BASE);
-
-       switch (ledevt) {
-       case led_idle_start:
-               val = val & ~led;
-               break;
-
-       case led_idle_end:
-               val = val | led;
-               break;
-
-       case led_timer:
-               val = val ^ REALVIEW_SYS_LED7;
-               break;
-
-       case led_halted:
-               val = 0;
-               break;
-
-       default:
-               break;
-       }
-
-       writel(val, VA_LEDS_BASE);
-       local_irq_restore(flags);
-}
-#endif /* CONFIG_LEDS */
-
 /*
  * Where is the timer (VA)?
  */
index f8f2c0a..f2141ae 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/io.h>
 
 #include <asm/setup.h>
-#include <asm/leds.h>
 
 #define APB_DEVICE(name, busid, base, plat)                    \
 static AMBA_APB_DEVICE(name, busid, 0, REALVIEW_##base##_BASE, base##_IRQ, plat)
@@ -47,7 +46,6 @@ extern void __iomem *timer1_va_base;
 extern void __iomem *timer2_va_base;
 extern void __iomem *timer3_va_base;
 
-extern void realview_leds_event(led_event_t ledevt);
 extern void realview_timer_init(unsigned int timer_irq);
 extern int realview_flash_register(struct resource *res, u32 num);
 extern int realview_eth_register(const char *name, struct resource *res);
index baf382c..21661ad 100644 (file)
@@ -30,7 +30,6 @@
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/leds.h>
 #include <asm/mach-types.h>
 #include <asm/pmu.h>
 #include <asm/pgtable.h>
@@ -462,10 +461,6 @@ static void __init realview_eb_init(void)
                struct amba_device *d = amba_devs[i];
                amba_device_register(d, &iomem_resource);
        }
-
-#ifdef CONFIG_LEDS
-       leds_event = realview_leds_event;
-#endif
 }
 
 MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
index b1d7caf..c0ff882 100644 (file)
@@ -32,7 +32,6 @@
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/leds.h>
 #include <asm/mach-types.h>
 #include <asm/pmu.h>
 #include <asm/pgtable.h>
@@ -375,10 +374,6 @@ static void __init realview_pb1176_init(void)
                struct amba_device *d = amba_devs[i];
                amba_device_register(d, &iomem_resource);
        }
-
-#ifdef CONFIG_LEDS
-       leds_event = realview_leds_event;
-#endif
 }
 
 MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")
index a98c536..30779ae 100644 (file)
@@ -30,7 +30,6 @@
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/leds.h>
 #include <asm/mach-types.h>
 #include <asm/pmu.h>
 #include <asm/pgtable.h>
@@ -357,10 +356,6 @@ static void __init realview_pb11mp_init(void)
                struct amba_device *d = amba_devs[i];
                amba_device_register(d, &iomem_resource);
        }
-
-#ifdef CONFIG_LEDS
-       leds_event = realview_leds_event;
-#endif
 }
 
 MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
index 5965017..081cd72 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/io.h>
 
 #include <asm/irq.h>
-#include <asm/leds.h>
 #include <asm/mach-types.h>
 #include <asm/pmu.h>
 #include <asm/pgtable.h>
@@ -299,10 +298,6 @@ static void __init realview_pba8_init(void)
                struct amba_device *d = amba_devs[i];
                amba_device_register(d, &iomem_resource);
        }
-
-#ifdef CONFIG_LEDS
-       leds_event = realview_leds_event;
-#endif
 }
 
 MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8")
index 3f2f605..1ce62b9 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/io.h>
 
 #include <asm/irq.h>
-#include <asm/leds.h>
 #include <asm/mach-types.h>
 #include <asm/pmu.h>
 #include <asm/smp_twd.h>
@@ -394,10 +393,6 @@ static void __init realview_pbx_init(void)
                struct amba_device *d = amba_devs[i];
                amba_device_register(d, &iomem_resource);
        }
-
-#ifdef CONFIG_LEDS
-       leds_event = realview_leds_event;
-#endif
 }
 
 MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")
index 60b97ec..1aed9e7 100644 (file)
@@ -7,21 +7,17 @@ obj-y := clock.o generic.o irq.o time.o #nmi-oopser.o
 obj-m :=
 obj-n :=
 obj-  :=
-led-y := leds.o
 
 obj-$(CONFIG_CPU_FREQ_SA1100)          += cpu-sa1100.o
 obj-$(CONFIG_CPU_FREQ_SA1110)          += cpu-sa1110.o
 
 # Specific board support
 obj-$(CONFIG_SA1100_ASSABET)           += assabet.o
-led-$(CONFIG_SA1100_ASSABET)           += leds-assabet.o
 obj-$(CONFIG_ASSABET_NEPONSET)         += neponset.o
 
 obj-$(CONFIG_SA1100_BADGE4)            += badge4.o
-led-$(CONFIG_SA1100_BADGE4)            += leds-badge4.o
 
 obj-$(CONFIG_SA1100_CERF)              += cerf.o
-led-$(CONFIG_SA1100_CERF)              += leds-cerf.o
 
 obj-$(CONFIG_SA1100_COLLIE)            += collie.o
 
@@ -29,13 +25,11 @@ obj-$(CONFIG_SA1100_H3100)          += h3100.o h3xxx.o
 obj-$(CONFIG_SA1100_H3600)             += h3600.o h3xxx.o
 
 obj-$(CONFIG_SA1100_HACKKIT)           += hackkit.o
-led-$(CONFIG_SA1100_HACKKIT)           += leds-hackkit.o
 
 obj-$(CONFIG_SA1100_JORNADA720)                += jornada720.o
 obj-$(CONFIG_SA1100_JORNADA720_SSP)    += jornada720_ssp.o
 
 obj-$(CONFIG_SA1100_LART)              += lart.o
-led-$(CONFIG_SA1100_LART)              += leds-lart.o
 
 obj-$(CONFIG_SA1100_NANOENGINE)                += nanoengine.o
 obj-$(CONFIG_PCI_NANOENGINE)           += pci-nanoengine.o
@@ -46,9 +40,6 @@ obj-$(CONFIG_SA1100_SHANNON)          += shannon.o
 
 obj-$(CONFIG_SA1100_SIMPAD)            += simpad.o
 
-# LEDs support
-obj-$(CONFIG_LEDS) += $(led-y)
-
 # Miscellaneous functions
 obj-$(CONFIG_PM)                       += pm.o sleep.o
 obj-$(CONFIG_SA1100_SSP)               += ssp.o
index d673211..1710ed1 100644 (file)
@@ -20,6 +20,8 @@
 #include <linux/mtd/partitions.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
 
 #include <video/sa1100fb.h>
 
@@ -529,6 +531,89 @@ static void __init assabet_map_io(void)
        sa1100_register_uart(2, 3);
 }
 
+/* LEDs */
+#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
+struct assabet_led {
+       struct led_classdev cdev;
+       u32 mask;
+};
+
+/*
+ * The triggers lines up below will only be used if the
+ * LED triggers are compiled in.
+ */
+static const struct {
+       const char *name;
+       const char *trigger;
+} assabet_leds[] = {
+       { "assabet:red", "cpu0",},
+       { "assabet:green", "heartbeat", },
+};
+
+/*
+ * The LED control in Assabet is reversed:
+ *  - setting bit means turn off LED
+ *  - clearing bit means turn on LED
+ */
+static void assabet_led_set(struct led_classdev *cdev,
+               enum led_brightness b)
+{
+       struct assabet_led *led = container_of(cdev,
+                       struct assabet_led, cdev);
+
+       if (b != LED_OFF)
+               ASSABET_BCR_clear(led->mask);
+       else
+               ASSABET_BCR_set(led->mask);
+}
+
+static enum led_brightness assabet_led_get(struct led_classdev *cdev)
+{
+       struct assabet_led *led = container_of(cdev,
+                       struct assabet_led, cdev);
+
+       return (ASSABET_BCR & led->mask) ? LED_OFF : LED_FULL;
+}
+
+static int __init assabet_leds_init(void)
+{
+       int i;
+
+       if (!machine_is_assabet())
+               return -ENODEV;
+
+       for (i = 0; i < ARRAY_SIZE(assabet_leds); i++) {
+               struct assabet_led *led;
+
+               led = kzalloc(sizeof(*led), GFP_KERNEL);
+               if (!led)
+                       break;
+
+               led->cdev.name = assabet_leds[i].name;
+               led->cdev.brightness_set = assabet_led_set;
+               led->cdev.brightness_get = assabet_led_get;
+               led->cdev.default_trigger = assabet_leds[i].trigger;
+
+               if (!i)
+                       led->mask = ASSABET_BCR_LED_RED;
+               else
+                       led->mask = ASSABET_BCR_LED_GREEN;
+
+               if (led_classdev_register(NULL, &led->cdev) < 0) {
+                       kfree(led);
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Since we may have triggers on any subsystem, defer registration
+ * until after subsystem_init.
+ */
+fs_initcall(assabet_leds_init);
+#endif
 
 MACHINE_START(ASSABET, "Intel-Assabet")
        .atag_offset    = 0x100,
index b30fb99..038df48 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/errno.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -76,8 +78,36 @@ static struct platform_device sa1111_device = {
        .resource       = sa1111_resources,
 };
 
+/* LEDs */
+struct gpio_led badge4_gpio_leds[] = {
+       {
+               .name                   = "badge4:red",
+               .default_trigger        = "heartbeat",
+               .gpio                   = 7,
+       },
+       {
+               .name                   = "badge4:green",
+               .default_trigger        = "cpu0",
+               .gpio                   = 9,
+       },
+};
+
+static struct gpio_led_platform_data badge4_gpio_led_info = {
+       .leds           = badge4_gpio_leds,
+       .num_leds       = ARRAY_SIZE(badge4_gpio_leds),
+};
+
+static struct platform_device badge4_leds = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &badge4_gpio_led_info,
+       }
+};
+
 static struct platform_device *devices[] __initdata = {
        &sa1111_device,
+       &badge4_leds,
 };
 
 static int __init badge4_sa1111_init(void)
index 09d7f4b..5240f10 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/irq.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
 
 #include <mach/hardware.h>
 #include <asm/setup.h>
@@ -43,8 +45,48 @@ static struct platform_device cerfuart2_device = {
        .resource       = cerfuart2_resources,
 };
 
+/* LEDs */
+struct gpio_led cerf_gpio_leds[] = {
+       {
+               .name                   = "cerf:d0",
+               .default_trigger        = "heartbeat",
+               .gpio                   = 0,
+       },
+       {
+               .name                   = "cerf:d1",
+               .default_trigger        = "cpu0",
+               .gpio                   = 1,
+       },
+       {
+               .name                   = "cerf:d2",
+               .default_trigger        = "default-on",
+               .gpio                   = 2,
+       },
+       {
+               .name                   = "cerf:d3",
+               .default_trigger        = "default-on",
+               .gpio                   = 3,
+       },
+
+};
+
+static struct gpio_led_platform_data cerf_gpio_led_info = {
+       .leds           = cerf_gpio_leds,
+       .num_leds       = ARRAY_SIZE(cerf_gpio_leds),
+};
+
+static struct platform_device cerf_leds = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &cerf_gpio_led_info,
+       }
+};
+
+
 static struct platform_device *cerf_devices[] __initdata = {
        &cerfuart2_device,
+       &cerf_leds,
 };
 
 #ifdef CONFIG_SA1100_CERF_FLASH_32MB
index 7f86bd9..fc106aa 100644 (file)
 #include <linux/serial_core.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/tty.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
 
 #include <asm/mach-types.h>
 #include <asm/setup.h>
@@ -183,9 +187,37 @@ static struct flash_platform_data hackkit_flash_data = {
 static struct resource hackkit_flash_resource =
        DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
 
+/* LEDs */
+struct gpio_led hackkit_gpio_leds[] = {
+       {
+               .name                   = "hackkit:red",
+               .default_trigger        = "cpu0",
+               .gpio                   = 22,
+       },
+       {
+               .name                   = "hackkit:green",
+               .default_trigger        = "heartbeat",
+               .gpio                   = 23,
+       },
+};
+
+static struct gpio_led_platform_data hackkit_gpio_led_info = {
+       .leds           = hackkit_gpio_leds,
+       .num_leds       = ARRAY_SIZE(hackkit_gpio_leds),
+};
+
+static struct platform_device hackkit_leds = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &hackkit_gpio_led_info,
+       }
+};
+
 static void __init hackkit_init(void)
 {
        sa11x0_register_mtd(&hackkit_flash_data, &hackkit_flash_resource, 1);
+       platform_device_register(&hackkit_leds);
 }
 
 /**********************************************************************
index b775a0a..b2ce04b 100644 (file)
@@ -5,6 +5,9 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/tty.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
 
 #include <video/sa1100fb.h>
 
@@ -126,6 +129,27 @@ static struct map_desc lart_io_desc[] __initdata = {
        }
 };
 
+/* LEDs */
+struct gpio_led lart_gpio_leds[] = {
+       {
+               .name                   = "lart:red",
+               .default_trigger        = "cpu0",
+               .gpio                   = 23,
+       },
+};
+
+static struct gpio_led_platform_data lart_gpio_led_info = {
+       .leds           = lart_gpio_leds,
+       .num_leds       = ARRAY_SIZE(lart_gpio_leds),
+};
+
+static struct platform_device lart_leds = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &lart_gpio_led_info,
+       }
+};
 static void __init lart_map_io(void)
 {
        sa1100_map_io();
@@ -139,6 +163,8 @@ static void __init lart_map_io(void)
        GPDR |= GPIO_UART_TXD;
        GPDR &= ~GPIO_UART_RXD;
        PPAR |= PPAR_UPR;
+
+       platform_device_register(&lart_leds);
 }
 
 MACHINE_START(LART, "LART")
diff --git a/arch/arm/mach-sa1100/leds-assabet.c b/arch/arm/mach-sa1100/leds-assabet.c
deleted file mode 100644 (file)
index 3699176..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * linux/arch/arm/mach-sa1100/leds-assabet.c
- *
- * Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu>
- *
- * Original (leds-footbridge.c) by Russell King
- *
- * Assabet uses the LEDs as follows:
- *   - Green - toggles state every 50 timer interrupts
- *   - Red   - on if system is not idle
- */
-#include <linux/init.h>
-
-#include <mach/hardware.h>
-#include <asm/leds.h>
-#include <mach/assabet.h>
-
-#include "leds.h"
-
-
-#define LED_STATE_ENABLED      1
-#define LED_STATE_CLAIMED      2
-
-static unsigned int led_state;
-static unsigned int hw_led_state;
-
-#define ASSABET_BCR_LED_MASK   (ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED)
-
-void assabet_leds_event(led_event_t evt)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-
-       switch (evt) {
-       case led_start:
-               hw_led_state = ASSABET_BCR_LED_RED | ASSABET_BCR_LED_GREEN;
-               led_state = LED_STATE_ENABLED;
-               break;
-
-       case led_stop:
-               led_state &= ~LED_STATE_ENABLED;
-               hw_led_state = ASSABET_BCR_LED_RED | ASSABET_BCR_LED_GREEN;
-               ASSABET_BCR_frob(ASSABET_BCR_LED_MASK, hw_led_state);
-               break;
-
-       case led_claim:
-               led_state |= LED_STATE_CLAIMED;
-               hw_led_state = ASSABET_BCR_LED_RED | ASSABET_BCR_LED_GREEN;
-               break;
-
-       case led_release:
-               led_state &= ~LED_STATE_CLAIMED;
-               hw_led_state = ASSABET_BCR_LED_RED | ASSABET_BCR_LED_GREEN;
-               break;
-
-#ifdef CONFIG_LEDS_TIMER
-       case led_timer:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state ^= ASSABET_BCR_LED_GREEN;
-               break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-       case led_idle_start:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state |= ASSABET_BCR_LED_RED;
-               break;
-
-       case led_idle_end:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state &= ~ASSABET_BCR_LED_RED;
-               break;
-#endif
-
-       case led_halted:
-               break;
-
-       case led_green_on:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state &= ~ASSABET_BCR_LED_GREEN;
-               break;
-
-       case led_green_off:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state |= ASSABET_BCR_LED_GREEN;
-               break;
-
-       case led_amber_on:
-               break;
-
-       case led_amber_off:
-               break;
-
-       case led_red_on:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state &= ~ASSABET_BCR_LED_RED;
-               break;
-
-       case led_red_off:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state |= ASSABET_BCR_LED_RED;
-               break;
-
-       default:
-               break;
-       }
-
-       if  (led_state & LED_STATE_ENABLED)
-               ASSABET_BCR_frob(ASSABET_BCR_LED_MASK, hw_led_state);
-
-       local_irq_restore(flags);
-}
diff --git a/arch/arm/mach-sa1100/leds-badge4.c b/arch/arm/mach-sa1100/leds-badge4.c
deleted file mode 100644 (file)
index f99fac3..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * linux/arch/arm/mach-sa1100/leds-badge4.c
- *
- * Author: Christopher Hoover <ch@hpl.hp.com>
- * Copyright (C) 2002 Hewlett-Packard Company
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/init.h>
-
-#include <mach/hardware.h>
-#include <asm/leds.h>
-
-#include "leds.h"
-
-#define LED_STATE_ENABLED      1
-#define LED_STATE_CLAIMED      2
-
-static unsigned int led_state;
-static unsigned int hw_led_state;
-
-#define LED_RED                GPIO_GPIO(7)
-#define LED_GREEN       GPIO_GPIO(9)
-#define LED_MASK       (LED_RED|LED_GREEN)
-
-#define LED_IDLE       LED_GREEN
-#define LED_TIMER      LED_RED
-
-void badge4_leds_event(led_event_t evt)
-{
-        unsigned long flags;
-
-       local_irq_save(flags);
-
-        switch (evt) {
-        case led_start:
-               GPDR |= LED_MASK;
-                hw_led_state = LED_MASK;
-                led_state = LED_STATE_ENABLED;
-                break;
-
-        case led_stop:
-                led_state &= ~LED_STATE_ENABLED;
-                break;
-
-        case led_claim:
-                led_state |= LED_STATE_CLAIMED;
-                hw_led_state = LED_MASK;
-                break;
-
-        case led_release:
-                led_state &= ~LED_STATE_CLAIMED;
-                hw_led_state = LED_MASK;
-                break;
-
-#ifdef CONFIG_LEDS_TIMER
-        case led_timer:
-                if (!(led_state & LED_STATE_CLAIMED))
-                        hw_led_state ^= LED_TIMER;
-                break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-        case led_idle_start:
-               /* LED off when system is idle */
-                if (!(led_state & LED_STATE_CLAIMED))
-                        hw_led_state &= ~LED_IDLE;
-                break;
-
-        case led_idle_end:
-                if (!(led_state & LED_STATE_CLAIMED))
-                        hw_led_state |= LED_IDLE;
-                break;
-#endif
-
-        case led_red_on:
-                if (!(led_state & LED_STATE_CLAIMED))
-                        hw_led_state &= ~LED_RED;
-                break;
-
-        case led_red_off:
-                if (!(led_state & LED_STATE_CLAIMED))
-                        hw_led_state |= LED_RED;
-                break;
-
-        case led_green_on:
-                if (!(led_state & LED_STATE_CLAIMED))
-                        hw_led_state &= ~LED_GREEN;
-                break;
-
-        case led_green_off:
-                if (!(led_state & LED_STATE_CLAIMED))
-                        hw_led_state |= LED_GREEN;
-                break;
-
-       default:
-               break;
-        }
-
-        if  (led_state & LED_STATE_ENABLED) {
-                GPSR = hw_led_state;
-                GPCR = hw_led_state ^ LED_MASK;
-        }
-
-       local_irq_restore(flags);
-}
diff --git a/arch/arm/mach-sa1100/leds-cerf.c b/arch/arm/mach-sa1100/leds-cerf.c
deleted file mode 100644 (file)
index 30fc3b2..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * linux/arch/arm/mach-sa1100/leds-cerf.c
- *
- * Author: ???
- */
-#include <linux/init.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/leds.h>
-
-#include "leds.h"
-
-
-#define LED_STATE_ENABLED      1
-#define LED_STATE_CLAIMED      2
-
-static unsigned int led_state;
-static unsigned int hw_led_state;
-
-#define LED_D0          GPIO_GPIO(0)
-#define LED_D1          GPIO_GPIO(1)
-#define LED_D2          GPIO_GPIO(2)
-#define LED_D3          GPIO_GPIO(3)
-#define LED_MASK        (LED_D0|LED_D1|LED_D2|LED_D3)
-
-void cerf_leds_event(led_event_t evt)
-{
-        unsigned long flags;
-
-       local_irq_save(flags);
-
-        switch (evt) {
-        case led_start:
-                hw_led_state = LED_MASK;
-                led_state = LED_STATE_ENABLED;
-                break;
-
-        case led_stop:
-                led_state &= ~LED_STATE_ENABLED;
-                break;
-
-        case led_claim:
-                led_state |= LED_STATE_CLAIMED;
-                hw_led_state = LED_MASK;
-                break;
-        case led_release:
-                led_state &= ~LED_STATE_CLAIMED;
-                hw_led_state = LED_MASK;
-                break;
-
-#ifdef CONFIG_LEDS_TIMER
-        case led_timer:
-                if (!(led_state & LED_STATE_CLAIMED))
-                        hw_led_state ^= LED_D0;
-                break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-        case led_idle_start:
-                if (!(led_state & LED_STATE_CLAIMED))
-                        hw_led_state &= ~LED_D1;
-                break;
-
-        case led_idle_end:
-                if (!(led_state & LED_STATE_CLAIMED))
-                        hw_led_state |= LED_D1;
-                break;
-#endif
-        case led_green_on:
-                if (!(led_state & LED_STATE_CLAIMED))
-                        hw_led_state &= ~LED_D2;
-                break;
-
-        case led_green_off:
-                if (!(led_state & LED_STATE_CLAIMED))
-                        hw_led_state |= LED_D2;
-                break;
-
-        case led_amber_on:
-                if (!(led_state & LED_STATE_CLAIMED))
-                        hw_led_state &= ~LED_D3;
-                break;
-
-        case led_amber_off:
-                if (!(led_state & LED_STATE_CLAIMED))
-                        hw_led_state |= LED_D3;
-                break;
-
-        case led_red_on:
-                if (!(led_state & LED_STATE_CLAIMED))
-                        hw_led_state &= ~LED_D1;
-                break;
-
-        case led_red_off:
-                if (!(led_state & LED_STATE_CLAIMED))
-                        hw_led_state |= LED_D1;
-                break;
-
-        default:
-                break;
-        }
-
-        if  (led_state & LED_STATE_ENABLED) {
-                GPSR = hw_led_state;
-                GPCR = hw_led_state ^ LED_MASK;
-        }
-
-       local_irq_restore(flags);
-}
diff --git a/arch/arm/mach-sa1100/leds-hackkit.c b/arch/arm/mach-sa1100/leds-hackkit.c
deleted file mode 100644 (file)
index 6a23524..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * linux/arch/arm/mach-sa1100/leds-hackkit.c
- *
- * based on leds-lart.c
- *
- * (C) Erik Mouw (J.A.K.Mouw@its.tudelft.nl), April 21, 2000
- * (C) Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de>, 2002
- *
- * The HackKit has two leds (GPIO 22/23). The red led (gpio 22) is used
- * as cpu led, the green one is used as timer led.
- */
-#include <linux/init.h>
-
-#include <mach/hardware.h>
-#include <asm/leds.h>
-
-#include "leds.h"
-
-
-#define LED_STATE_ENABLED      1
-#define LED_STATE_CLAIMED      2
-
-static unsigned int led_state;
-static unsigned int hw_led_state;
-
-#define LED_GREEN    GPIO_GPIO23
-#define LED_RED    GPIO_GPIO22
-#define LED_MASK  (LED_RED | LED_GREEN)
-
-void hackkit_leds_event(led_event_t evt)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-
-       switch(evt) {
-               case led_start:
-                       /* pin 22/23 are outputs */
-                       GPDR |= LED_MASK;
-                       hw_led_state = LED_MASK;
-                       led_state = LED_STATE_ENABLED;
-                       break;
-
-               case led_stop:
-                       led_state &= ~LED_STATE_ENABLED;
-                       break;
-
-               case led_claim:
-                       led_state |= LED_STATE_CLAIMED;
-                       hw_led_state = LED_MASK;
-                       break;
-
-               case led_release:
-                       led_state &= ~LED_STATE_CLAIMED;
-                       hw_led_state = LED_MASK;
-                       break;
-
-#ifdef CONFIG_LEDS_TIMER
-               case led_timer:
-                       if (!(led_state & LED_STATE_CLAIMED))
-                               hw_led_state ^= LED_GREEN;
-                       break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-               case led_idle_start:
-                       /* The LART people like the LED to be off when the
-                          system is idle... */
-                       if (!(led_state & LED_STATE_CLAIMED))
-                               hw_led_state &= ~LED_RED;
-                       break;
-
-               case led_idle_end:
-                       /* ... and on if the system is not idle */
-                       if (!(led_state & LED_STATE_CLAIMED))
-                               hw_led_state |= LED_RED;
-                       break;
-#endif
-
-               case led_red_on:
-                       if (led_state & LED_STATE_CLAIMED)
-                               hw_led_state &= ~LED_RED;
-                       break;
-
-               case led_red_off:
-                       if (led_state & LED_STATE_CLAIMED)
-                               hw_led_state |= LED_RED;
-                       break;
-
-               case led_green_on:
-                       if (led_state & LED_STATE_CLAIMED)
-                               hw_led_state &= ~LED_GREEN;
-                       break;
-
-               case led_green_off:
-                       if (led_state & LED_STATE_CLAIMED)
-                               hw_led_state |= LED_GREEN;
-                       break;
-
-               default:
-                       break;
-       }
-
-       /* Now set the GPIO state, or nothing will happen at all */
-       if (led_state & LED_STATE_ENABLED) {
-               GPSR = hw_led_state;
-               GPCR = hw_led_state ^ LED_MASK;
-       }
-
-       local_irq_restore(flags);
-}
diff --git a/arch/arm/mach-sa1100/leds-lart.c b/arch/arm/mach-sa1100/leds-lart.c
deleted file mode 100644 (file)
index 50a5b14..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * linux/arch/arm/mach-sa1100/leds-lart.c
- *
- * (C) Erik Mouw (J.A.K.Mouw@its.tudelft.nl), April 21, 2000
- *
- * LART uses the LED as follows:
- *   - GPIO23 is the LED, on if system is not idle
- *  You can use both CONFIG_LEDS_CPU and CONFIG_LEDS_TIMER at the same
- *  time, but in that case the timer events will still dictate the
- *  pace of the LED.
- */
-#include <linux/init.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/leds.h>
-
-#include "leds.h"
-
-
-#define LED_STATE_ENABLED      1
-#define LED_STATE_CLAIMED      2
-
-static unsigned int led_state;
-static unsigned int hw_led_state;
-
-#define LED_23    GPIO_GPIO23
-#define LED_MASK  (LED_23)
-
-void lart_leds_event(led_event_t evt)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-
-       switch(evt) {
-       case led_start:
-               /* pin 23 is output pin */
-               GPDR |= LED_23;
-               hw_led_state = LED_MASK;
-               led_state = LED_STATE_ENABLED;
-               break;
-
-       case led_stop:
-               led_state &= ~LED_STATE_ENABLED;
-               break;
-
-       case led_claim:
-               led_state |= LED_STATE_CLAIMED;
-               hw_led_state = LED_MASK;
-               break;
-
-       case led_release:
-               led_state &= ~LED_STATE_CLAIMED;
-               hw_led_state = LED_MASK;
-               break;
-
-#ifdef CONFIG_LEDS_TIMER
-       case led_timer:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state ^= LED_23;
-               break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-       case led_idle_start:
-               /* The LART people like the LED to be off when the
-                   system is idle... */
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state &= ~LED_23;
-               break;
-
-       case led_idle_end:
-               /* ... and on if the system is not idle */
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state |= LED_23;
-               break;
-#endif
-
-       case led_red_on:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state &= ~LED_23;
-               break;
-
-       case led_red_off:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state |= LED_23;
-               break;
-
-       default:
-               break;
-       }
-
-       /* Now set the GPIO state, or nothing will happen at all */
-       if (led_state & LED_STATE_ENABLED) {
-               GPSR = hw_led_state;
-               GPCR = hw_led_state ^ LED_MASK;
-       }
-
-       local_irq_restore(flags);
-}
diff --git a/arch/arm/mach-sa1100/leds.c b/arch/arm/mach-sa1100/leds.c
deleted file mode 100644 (file)
index 5fe71a0..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * linux/arch/arm/mach-sa1100/leds.c
- *
- * SA1100 LEDs dispatcher
- *
- * Copyright (C) 2001 Nicolas Pitre
- */
-#include <linux/compiler.h>
-#include <linux/init.h>
-
-#include <asm/leds.h>
-#include <asm/mach-types.h>
-
-#include "leds.h"
-
-static int __init
-sa1100_leds_init(void)
-{
-       if (machine_is_assabet())
-               leds_event = assabet_leds_event;
-       if (machine_is_consus())
-               leds_event = consus_leds_event;
-       if (machine_is_badge4())
-               leds_event = badge4_leds_event;
-       if (machine_is_brutus())
-               leds_event = brutus_leds_event;
-       if (machine_is_cerf())
-               leds_event = cerf_leds_event;
-       if (machine_is_flexanet())
-               leds_event = flexanet_leds_event;
-       if (machine_is_graphicsclient())
-               leds_event = graphicsclient_leds_event;
-       if (machine_is_hackkit())
-               leds_event = hackkit_leds_event;
-       if (machine_is_lart())
-               leds_event = lart_leds_event;
-       if (machine_is_pfs168())
-               leds_event = pfs168_leds_event;
-       if (machine_is_graphicsmaster())
-               leds_event = graphicsmaster_leds_event;
-       if (machine_is_adsbitsy())
-               leds_event = adsbitsy_leds_event;
-       if (machine_is_pt_system3())
-               leds_event = system3_leds_event;
-
-       leds_event(led_start);
-       return 0;
-}
-
-core_initcall(sa1100_leds_init);
diff --git a/arch/arm/mach-sa1100/leds.h b/arch/arm/mach-sa1100/leds.h
deleted file mode 100644 (file)
index 776b602..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-extern void assabet_leds_event(led_event_t evt);
-extern void badge4_leds_event(led_event_t evt);
-extern void consus_leds_event(led_event_t evt);
-extern void brutus_leds_event(led_event_t evt);
-extern void cerf_leds_event(led_event_t evt);
-extern void flexanet_leds_event(led_event_t evt);
-extern void graphicsclient_leds_event(led_event_t evt);
-extern void hackkit_leds_event(led_event_t evt);
-extern void lart_leds_event(led_event_t evt);
-extern void pfs168_leds_event(led_event_t evt);
-extern void graphicsmaster_leds_event(led_event_t evt);
-extern void adsbitsy_leds_event(led_event_t evt);
-extern void system3_leds_event(led_event_t evt);
index 45be9b0..2965718 100644 (file)
@@ -4,9 +4,7 @@
 
 # Object file lists.
 
-obj-y                  := core.o dma.o irq.o pci.o
+obj-y                  := core.o dma.o irq.o pci.o leds.o
 obj-m                  :=
 obj-n                  :=
 obj-                   :=
-
-obj-$(CONFIG_LEDS)     += leds.o
index 2704bcd..c709979 100644 (file)
@@ -13,7 +13,6 @@
 
 #include <asm/setup.h>
 #include <asm/mach-types.h>
-#include <asm/leds.h>
 #include <asm/param.h>
 #include <asm/system_misc.h>
 
index 2560907..081c778 100644 (file)
 /*
- * arch/arm/mach-shark/leds.c
- * by Alexander Schulz
- *
- * derived from:
- * arch/arm/kernel/leds-footbridge.c
- * Copyright (C) 1998-1999 Russell King
- *
  * DIGITAL Shark LED control routines.
  *
- * The leds use is as follows:
- *  - Green front - toggles state every 50 timer interrupts
- *  - Amber front - Unused, this is a dual color led (Amber/Green)
- *  - Amber back  - On if system is not idle
+ * Driver for the 3 user LEDs found on the Shark
+ * Based on Versatile and RealView machine LED code
  *
- * Changelog:
+ * License terms: GNU General Public License (GPL) version 2
+ * Author: Bryan Wu <bryan.wu@canonical.com>
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/ioport.h>
 #include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
 
-#include <asm/leds.h>
+#include <asm/mach-types.h>
 
-#define LED_STATE_ENABLED      1
-#define LED_STATE_CLAIMED      2
+#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
+struct shark_led {
+       struct led_classdev cdev;
+       u8 mask;
+};
 
-#define SEQUOIA_LED_GREEN       (1<<6)
-#define SEQUOIA_LED_AMBER       (1<<5)
-#define SEQUOIA_LED_BACK        (1<<7)
+/*
+ * The triggers lines up below will only be used if the
+ * LED triggers are compiled in.
+ */
+static const struct {
+       const char *name;
+       const char *trigger;
+} shark_leds[] = {
+       { "shark:amber0", "default-on", },      /* Bit 5 */
+       { "shark:green", "heartbeat", },        /* Bit 6 */
+       { "shark:amber1", "cpu0" },             /* Bit 7 */
+};
+
+static u16 led_reg_read(void)
+{
+       outw(0x09, 0x24);
+       return inw(0x26);
+}
 
-static char led_state;
-static short hw_led_state;
-static short saved_state;
+static void led_reg_write(u16 value)
+{
+       outw(0x09, 0x24);
+       outw(value, 0x26);
+}
 
-static DEFINE_RAW_SPINLOCK(leds_lock);
+static void shark_led_set(struct led_classdev *cdev,
+                             enum led_brightness b)
+{
+       struct shark_led *led = container_of(cdev,
+                                                struct shark_led, cdev);
+       u16 reg = led_reg_read();
 
-short sequoia_read(int addr) {
-  outw(addr,0x24);
-  return inw(0x26);
-}
+       if (b != LED_OFF)
+               reg |= led->mask;
+       else
+               reg &= ~led->mask;
 
-void sequoia_write(short value,short addr) {
-  outw(addr,0x24);
-  outw(value,0x26);
+       led_reg_write(reg);
 }
 
-static void sequoia_leds_event(led_event_t evt)
+static enum led_brightness shark_led_get(struct led_classdev *cdev)
 {
-       unsigned long flags;
-
-       raw_spin_lock_irqsave(&leds_lock, flags);
+       struct shark_led *led = container_of(cdev,
+                                                struct shark_led, cdev);
+       u16 reg = led_reg_read();
 
-       hw_led_state = sequoia_read(0x09);
+       return (reg & led->mask) ? LED_FULL : LED_OFF;
+}
 
-       switch (evt) {
-       case led_start:
-               hw_led_state |= SEQUOIA_LED_GREEN;
-               hw_led_state |= SEQUOIA_LED_AMBER;
-#ifdef CONFIG_LEDS_CPU
-               hw_led_state |= SEQUOIA_LED_BACK;
-#else
-               hw_led_state &= ~SEQUOIA_LED_BACK;
-#endif
-               led_state |= LED_STATE_ENABLED;
-               break;
-
-       case led_stop:
-               hw_led_state &= ~SEQUOIA_LED_BACK;
-               hw_led_state |= SEQUOIA_LED_GREEN;
-               hw_led_state |= SEQUOIA_LED_AMBER;
-               led_state &= ~LED_STATE_ENABLED;
-               break;
-
-       case led_claim:
-               led_state |= LED_STATE_CLAIMED;
-               saved_state = hw_led_state;
-               hw_led_state &= ~SEQUOIA_LED_BACK;
-               hw_led_state |= SEQUOIA_LED_GREEN;
-               hw_led_state |= SEQUOIA_LED_AMBER;
-               break;
-
-       case led_release:
-               led_state &= ~LED_STATE_CLAIMED;
-               hw_led_state = saved_state;
-               break;
-
-#ifdef CONFIG_LEDS_TIMER
-       case led_timer:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state ^= SEQUOIA_LED_GREEN;
-               break;
-#endif
+static int __init shark_leds_init(void)
+{
+       int i;
+       u16 reg;
 
-#ifdef CONFIG_LEDS_CPU
-       case led_idle_start:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state &= ~SEQUOIA_LED_BACK;
-               break;
+       if (!machine_is_shark())
+               return -ENODEV;
 
-       case led_idle_end:
-               if (!(led_state & LED_STATE_CLAIMED))
-                       hw_led_state |= SEQUOIA_LED_BACK;
-               break;
-#endif
+       for (i = 0; i < ARRAY_SIZE(shark_leds); i++) {
+               struct shark_led *led;
 
-       case led_green_on:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state &= ~SEQUOIA_LED_GREEN;
-               break;
-
-       case led_green_off:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state |= SEQUOIA_LED_GREEN;
-               break;
-
-       case led_amber_on:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state &= ~SEQUOIA_LED_AMBER;
-               break;
-
-       case led_amber_off:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state |= SEQUOIA_LED_AMBER;
-               break;
-
-       case led_red_on:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state |= SEQUOIA_LED_BACK;
-               break;
-
-       case led_red_off:
-               if (led_state & LED_STATE_CLAIMED)
-                       hw_led_state &= ~SEQUOIA_LED_BACK;
-               break;
-
-       default:
-               break;
-       }
+               led = kzalloc(sizeof(*led), GFP_KERNEL);
+               if (!led)
+                       break;
 
-       if  (led_state & LED_STATE_ENABLED)
-               sequoia_write(hw_led_state,0x09);
+               led->cdev.name = shark_leds[i].name;
+               led->cdev.brightness_set = shark_led_set;
+               led->cdev.brightness_get = shark_led_get;
+               led->cdev.default_trigger = shark_leds[i].trigger;
 
-       raw_spin_unlock_irqrestore(&leds_lock, flags);
-}
+               /* Count in 5 bits offset */
+               led->mask = BIT(i + 5);
 
-static int __init leds_init(void)
-{
-       extern void (*leds_event)(led_event_t);
-       short temp;
-       
-       leds_event = sequoia_leds_event;
+               if (led_classdev_register(NULL, &led->cdev) < 0) {
+                       kfree(led);
+                       break;
+               }
+       }
 
        /* Make LEDs independent of power-state */
-       request_region(0x24,4,"sequoia");
-       temp = sequoia_read(0x09);
-       temp |= 1<<10;
-       sequoia_write(temp,0x09);
-       leds_event(led_start);
+       request_region(0x24, 4, "led_reg");
+       reg = led_reg_read();
+       reg |= 1 << 10;
+       led_reg_write(reg);
+
        return 0;
 }
 
-__initcall(leds_init);
+/*
+ * Since we may have triggers on any subsystem, defer registration
+ * until after subsystem_init.
+ */
+fs_initcall(shark_leds_init);
+#endif
index cd8ea35..855ca02 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/mtd/physmap.h>
 
 #include <asm/irq.h>
-#include <asm/leds.h>
 #include <asm/hardware/arm_timer.h>
 #include <asm/hardware/icst.h>
 #include <asm/hardware/vic.h>
@@ -763,10 +762,6 @@ void __init versatile_init(void)
                struct amba_device *d = amba_devs[i];
                amba_device_register(d, &iomem_resource);
        }
-
-#ifdef CONFIG_LEDS
-       leds_event = versatile_leds_event;
-#endif
 }
 
 /*
index dd36eba..13910ba 100644 (file)
@@ -41,9 +41,8 @@ config OMAP_DEBUG_DEVICES
          For debug cards on TI reference boards.
 
 config OMAP_DEBUG_LEDS
-       bool
+       def_bool y if NEW_LEDS
        depends on OMAP_DEBUG_DEVICES
-       default y if LEDS_CLASS
 
 config POWER_AVS_OMAP
        bool "AVS(Adaptive Voltage Scaling) support for OMAP IP versions 1&2"
index 39407cb..24e23f3 100644 (file)
 /*
  * linux/arch/arm/plat-omap/debug-leds.c
  *
+ * Copyright 2011 by Bryan Wu <bryan.wu@canonical.com>
  * Copyright 2003 by Texas Instruments Incorporated
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/gpio.h>
+
+#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/leds.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <mach/hardware.h>
-#include <asm/leds.h>
 #include <asm/mach-types.h>
 
 #include <plat/fpga.h>
 
-
 /* Many OMAP development platforms reuse the same "debug board"; these
  * platforms include H2, H3, H4, and Perseus2.  There are 16 LEDs on the
  * debug board (all green), accessed through FPGA registers.
- *
- * The "surfer" expansion board and H2 sample board also have two-color
- * green+red LEDs (in parallel), used here for timer and idle indicators
- * in preference to the ones on the debug board, for a "Disco LED" effect.
- *
- * This driver exports either the original ARM LED API, the new generic
- * one, or both.
- */
-
-static spinlock_t                      lock;
-static struct h2p2_dbg_fpga __iomem    *fpga;
-static u16                             led_state, hw_led_state;
-
-
-#ifdef CONFIG_OMAP_DEBUG_LEDS
-#define new_led_api()  1
-#else
-#define new_led_api()  0
-#endif
-
-
-/*-------------------------------------------------------------------------*/
-
-/* original ARM debug LED API:
- *  - timer and idle leds (some boards use non-FPGA leds here);
- *  - up to 4 generic leds, easily accessed in-kernel (any context)
  */
 
-#define GPIO_LED_RED           3
-#define GPIO_LED_GREEN         OMAP_MPUIO(4)
-
-#define LED_STATE_ENABLED      0x01
-#define LED_STATE_CLAIMED      0x02
-#define LED_TIMER_ON           0x04
-
-#define GPIO_IDLE              GPIO_LED_GREEN
-#define GPIO_TIMER             GPIO_LED_RED
-
-static void h2p2_dbg_leds_event(led_event_t evt)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&lock, flags);
-
-       if (!(led_state & LED_STATE_ENABLED) && evt != led_start)
-               goto done;
-
-       switch (evt) {
-       case led_start:
-               if (fpga)
-                       led_state |= LED_STATE_ENABLED;
-               break;
-
-       case led_stop:
-       case led_halted:
-               /* all leds off during suspend or shutdown */
-
-               if (!(machine_is_omap_perseus2() || machine_is_omap_h4())) {
-                       gpio_set_value(GPIO_TIMER, 0);
-                       gpio_set_value(GPIO_IDLE, 0);
-               }
-
-               __raw_writew(~0, &fpga->leds);
-               led_state &= ~LED_STATE_ENABLED;
-               goto done;
-
-       case led_claim:
-               led_state |= LED_STATE_CLAIMED;
-               hw_led_state = 0;
-               break;
-
-       case led_release:
-               led_state &= ~LED_STATE_CLAIMED;
-               break;
-
-#ifdef CONFIG_LEDS_TIMER
-       case led_timer:
-               led_state ^= LED_TIMER_ON;
-
-               if (machine_is_omap_perseus2() || machine_is_omap_h4())
-                       hw_led_state ^= H2P2_DBG_FPGA_P2_LED_TIMER;
-               else {
-                       gpio_set_value(GPIO_TIMER,
-                                       led_state & LED_TIMER_ON);
-                       goto done;
-               }
-
-               break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-       /* LED lit iff busy */
-       case led_idle_start:
-               if (machine_is_omap_perseus2() || machine_is_omap_h4())
-                       hw_led_state &= ~H2P2_DBG_FPGA_P2_LED_IDLE;
-               else {
-                       gpio_set_value(GPIO_IDLE, 1);
-                       goto done;
-               }
-
-               break;
+static struct h2p2_dbg_fpga __iomem *fpga;
 
-       case led_idle_end:
-               if (machine_is_omap_perseus2() || machine_is_omap_h4())
-                       hw_led_state |= H2P2_DBG_FPGA_P2_LED_IDLE;
-               else {
-                       gpio_set_value(GPIO_IDLE, 0);
-                       goto done;
-               }
-
-               break;
-#endif
-
-       case led_green_on:
-               hw_led_state |= H2P2_DBG_FPGA_LED_GREEN;
-               break;
-       case led_green_off:
-               hw_led_state &= ~H2P2_DBG_FPGA_LED_GREEN;
-               break;
-
-       case led_amber_on:
-               hw_led_state |= H2P2_DBG_FPGA_LED_AMBER;
-               break;
-       case led_amber_off:
-               hw_led_state &= ~H2P2_DBG_FPGA_LED_AMBER;
-               break;
-
-       case led_red_on:
-               hw_led_state |= H2P2_DBG_FPGA_LED_RED;
-               break;
-       case led_red_off:
-               hw_led_state &= ~H2P2_DBG_FPGA_LED_RED;
-               break;
-
-       case led_blue_on:
-               hw_led_state |= H2P2_DBG_FPGA_LED_BLUE;
-               break;
-       case led_blue_off:
-               hw_led_state &= ~H2P2_DBG_FPGA_LED_BLUE;
-               break;
-
-       default:
-               break;
-       }
-
-
-       /*
-        *  Actually burn the LEDs
-        */
-       if (led_state & LED_STATE_ENABLED)
-               __raw_writew(~hw_led_state, &fpga->leds);
-
-done:
-       spin_unlock_irqrestore(&lock, flags);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* "new" LED API
- *  - with syfs access and generic triggering
- *  - not readily accessible to in-kernel drivers
- */
+static u16 fpga_led_state;
 
 struct dbg_led {
        struct led_classdev     cdev;
        u16                     mask;
 };
 
-static struct dbg_led dbg_leds[] = {
-       /* REVISIT at least H2 uses different timer & cpu leds... */
-#ifndef CONFIG_LEDS_TIMER
-       { .mask = 1 << 0,  .cdev.name =  "d4:green",
-               .cdev.default_trigger = "heartbeat", },
-#endif
-#ifndef CONFIG_LEDS_CPU
-       { .mask = 1 << 1,  .cdev.name =  "d5:green", },         /* !idle */
-#endif
-       { .mask = 1 << 2,  .cdev.name =  "d6:green", },
-       { .mask = 1 << 3,  .cdev.name =  "d7:green", },
-
-       { .mask = 1 << 4,  .cdev.name =  "d8:green", },
-       { .mask = 1 << 5,  .cdev.name =  "d9:green", },
-       { .mask = 1 << 6,  .cdev.name = "d10:green", },
-       { .mask = 1 << 7,  .cdev.name = "d11:green", },
-
-       { .mask = 1 << 8,  .cdev.name = "d12:green", },
-       { .mask = 1 << 9,  .cdev.name = "d13:green", },
-       { .mask = 1 << 10, .cdev.name = "d14:green", },
-       { .mask = 1 << 11, .cdev.name = "d15:green", },
-
-#ifndef        CONFIG_LEDS
-       { .mask = 1 << 12, .cdev.name = "d16:green", },
-       { .mask = 1 << 13, .cdev.name = "d17:green", },
-       { .mask = 1 << 14, .cdev.name = "d18:green", },
-       { .mask = 1 << 15, .cdev.name = "d19:green", },
-#endif
+static const struct {
+       const char *name;
+       const char *trigger;
+} dbg_leds[] = {
+       { "dbg:d4", "heartbeat", },
+       { "dbg:d5", "cpu0", },
+       { "dbg:d6", "default-on", },
+       { "dbg:d7", },
+       { "dbg:d8", },
+       { "dbg:d9", },
+       { "dbg:d10", },
+       { "dbg:d11", },
+       { "dbg:d12", },
+       { "dbg:d13", },
+       { "dbg:d14", },
+       { "dbg:d15", },
+       { "dbg:d16", },
+       { "dbg:d17", },
+       { "dbg:d18", },
+       { "dbg:d19", },
 };
 
-static void
-fpga_led_set(struct led_classdev *cdev, enum led_brightness value)
+/*
+ * The triggers lines up below will only be used if the
+ * LED triggers are compiled in.
+ */
+static void dbg_led_set(struct led_classdev *cdev,
+                             enum led_brightness b)
 {
-       struct dbg_led  *led = container_of(cdev, struct dbg_led, cdev);
-       unsigned long   flags;
+       struct dbg_led *led = container_of(cdev, struct dbg_led, cdev);
+       u16 reg;
 
-       spin_lock_irqsave(&lock, flags);
-       if (value == LED_OFF)
-               hw_led_state &= ~led->mask;
+       reg = __raw_readw(&fpga->leds);
+       if (b != LED_OFF)
+               reg |= led->mask;
        else
-               hw_led_state |= led->mask;
-       __raw_writew(~hw_led_state, &fpga->leds);
-       spin_unlock_irqrestore(&lock, flags);
+               reg &= ~led->mask;
+       __raw_writew(reg, &fpga->leds);
 }
 
-static void __init newled_init(struct device *dev)
+static enum led_brightness dbg_led_get(struct led_classdev *cdev)
 {
-       unsigned        i;
-       struct dbg_led  *led;
-       int             status;
+       struct dbg_led *led = container_of(cdev, struct dbg_led, cdev);
+       u16 reg;
 
-       for (i = 0, led = dbg_leds; i < ARRAY_SIZE(dbg_leds); i++, led++) {
-               led->cdev.brightness_set = fpga_led_set;
-               status = led_classdev_register(dev, &led->cdev);
-               if (status < 0)
-                       break;
-       }
-       return;
+       reg = __raw_readw(&fpga->leds);
+       return (reg & led->mask) ? LED_FULL : LED_OFF;
 }
 
-
-/*-------------------------------------------------------------------------*/
-
-static int /* __init */ fpga_probe(struct platform_device *pdev)
+static int fpga_probe(struct platform_device *pdev)
 {
        struct resource *iomem;
-
-       spin_lock_init(&lock);
+       int i;
 
        iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!iomem)
                return -ENODEV;
 
        fpga = ioremap(iomem->start, H2P2_DBG_FPGA_SIZE);
-       __raw_writew(~0, &fpga->leds);
+       __raw_writew(0xff, &fpga->leds);
+
+       for (i = 0; i < ARRAY_SIZE(dbg_leds); i++) {
+               struct dbg_led *led;
+
+               led = kzalloc(sizeof(*led), GFP_KERNEL);
+               if (!led)
+                       break;
 
-#ifdef CONFIG_LEDS
-       leds_event = h2p2_dbg_leds_event;
-       leds_event(led_start);
-#endif
+               led->cdev.name = dbg_leds[i].name;
+               led->cdev.brightness_set = dbg_led_set;
+               led->cdev.brightness_get = dbg_led_get;
+               led->cdev.default_trigger = dbg_leds[i].trigger;
+               led->mask = BIT(i);
 
-       if (new_led_api()) {
-               newled_init(&pdev->dev);
+               if (led_classdev_register(NULL, &led->cdev) < 0) {
+                       kfree(led);
+                       break;
+               }
        }
 
        return 0;
@@ -281,13 +120,15 @@ static int /* __init */ fpga_probe(struct platform_device *pdev)
 
 static int fpga_suspend_noirq(struct device *dev)
 {
-       __raw_writew(~0, &fpga->leds);
+       fpga_led_state = __raw_readw(&fpga->leds);
+       __raw_writew(0xff, &fpga->leds);
+
        return 0;
 }
 
 static int fpga_resume_noirq(struct device *dev)
 {
-       __raw_writew(~hw_led_state, &fpga->leds);
+       __raw_writew(~fpga_led_state, &fpga->leds);
        return 0;
 }
 
index 4dcb11c..60552e2 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/io.h>
 #include <linux/platform_device.h>
 
-#include <asm/leds.h>
 #include <asm/mach-types.h>
 
 #include <asm/irq.h>
index 8d5c10a..2a4ae8a 100644 (file)
@@ -16,8 +16,10 @@ config PLAT_VERSATILE_FPGA_IRQ_NR
        depends on PLAT_VERSATILE_FPGA_IRQ
 
 config PLAT_VERSATILE_LEDS
-       def_bool y if LEDS_CLASS
+       def_bool y if NEW_LEDS
        depends on ARCH_REALVIEW || ARCH_VERSATILE
+       select LEDS_CLASS
+       select LEDS_TRIGGER
 
 config PLAT_VERSATILE_SCHED_CLOCK
        def_bool y
index 3169fa5..d2490d0 100644 (file)
@@ -37,10 +37,10 @@ static const struct {
 } versatile_leds[] = {
        { "versatile:0", "heartbeat", },
        { "versatile:1", "mmc0", },
-       { "versatile:2", },
-       { "versatile:3", },
-       { "versatile:4", },
-       { "versatile:5", },
+       { "versatile:2", "cpu0" },
+       { "versatile:3", "cpu1" },
+       { "versatile:4", "cpu2" },
+       { "versatile:5", "cpu3" },
        { "versatile:6", },
        { "versatile:7", },
 };
index d45c334..a0e2f7d 100644 (file)
@@ -30,7 +30,6 @@
 
 #include <asm/hardware/dec21285.h>
 #include <asm/io.h>
-#include <asm/leds.h>
 #include <asm/mach-types.h>
 #include <asm/uaccess.h>
 
@@ -179,9 +178,6 @@ static ssize_t flash_write(struct file *file, const char __user *buf,
 
        written = 0;
 
-       leds_event(led_claim);
-       leds_event(led_green_on);
-
        nBlock = (int) p >> 16; //block # of 64K bytes
 
        /*
@@ -258,11 +254,6 @@ static ssize_t flash_write(struct file *file, const char __user *buf,
                        printk(KERN_DEBUG "flash_write: written 0x%X bytes OK.\n", written);
        }
 
-       /*
-        * restore reg on exit
-        */
-       leds_event(led_release);
-
        mutex_unlock(&nwflash_mutex);
 
        return written;
@@ -333,11 +324,6 @@ static int erase_block(int nBlock)
        unsigned long timeout;
        int temp, temp1;
 
-       /*
-        * orange LED == erase
-        */
-       leds_event(led_amber_on);
-
        /*
         * reset footbridge to the correct offset 0 (...0..3)
         */
@@ -446,12 +432,6 @@ static int write_block(unsigned long p, const char __user *buf, int count)
        unsigned long timeout;
        unsigned long timeout1;
 
-       /*
-        * red LED == write
-        */
-       leds_event(led_amber_off);
-       leds_event(led_red_on);
-
        pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + p));
 
        /*
@@ -557,18 +537,10 @@ static int write_block(unsigned long p, const char __user *buf, int count)
                                        printk(KERN_DEBUG "write_block: Retrying write at 0x%X)n",
                                               pWritePtr - FLASH_BASE);
 
-                               /*
-                                * no LED == waiting
-                                */
-                               leds_event(led_amber_off);
                                /*
                                 * wait couple ms
                                 */
                                msleep(10);
-                               /*
-                                * red LED == write
-                                */
-                               leds_event(led_red_on);
 
                                goto WriteRetry;
                        } else {
@@ -583,12 +555,6 @@ static int write_block(unsigned long p, const char __user *buf, int count)
                }
        }
 
-       /*
-        * green LED == read/verify
-        */
-       leds_event(led_amber_off);
-       leds_event(led_green_on);
-
        msleep(10);
 
        pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + p));
index c96bbaa..16578d3 100644 (file)
@@ -506,6 +506,16 @@ config LEDS_TRIGGER_BACKLIGHT
 
          If unsure, say N.
 
+config LEDS_TRIGGER_CPU
+       bool "LED CPU Trigger"
+       depends on LEDS_TRIGGERS
+       help
+         This allows LEDs to be controlled by active CPUs. This shows
+         the active CPUs across an array of LEDs so you can see which
+         CPUs are active on the system at any given moment.
+
+         If unsure, say N.
+
 config LEDS_TRIGGER_GPIO
        tristate "LED GPIO Trigger"
        depends on LEDS_TRIGGERS
index a4429a9..a9b627c 100644 (file)
@@ -61,5 +61,6 @@ obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK)   += ledtrig-ide-disk.o
 obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT)   += ledtrig-heartbeat.o
 obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)   += ledtrig-backlight.o
 obj-$(CONFIG_LEDS_TRIGGER_GPIO)                += ledtrig-gpio.o
+obj-$(CONFIG_LEDS_TRIGGER_CPU)         += ledtrig-cpu.o
 obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON)  += ledtrig-default-on.o
 obj-$(CONFIG_LEDS_TRIGGER_TRANSIENT)   += ledtrig-transient.o
diff --git a/drivers/leds/ledtrig-cpu.c b/drivers/leds/ledtrig-cpu.c
new file mode 100644 (file)
index 0000000..b312056
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * ledtrig-cpu.c - LED trigger based on CPU activity
+ *
+ * This LED trigger will be registered for each possible CPU and named as
+ * cpu0, cpu1, cpu2, cpu3, etc.
+ *
+ * It can be bound to any LED just like other triggers using either a
+ * board file or via sysfs interface.
+ *
+ * An API named ledtrig_cpu is exported for any user, who want to add CPU
+ * activity indication in their code
+ *
+ * Copyright 2011 Linus Walleij <linus.walleij@linaro.org>
+ * Copyright 2011 - 2012 Bryan Wu <bryan.wu@canonical.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/percpu.h>
+#include <linux/syscore_ops.h>
+#include <linux/rwsem.h>
+#include "leds.h"
+
+#define MAX_NAME_LEN   8
+
+struct led_trigger_cpu {
+       char name[MAX_NAME_LEN];
+       struct led_trigger *_trig;
+       struct mutex lock;
+       int lock_is_inited;
+};
+
+static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig);
+
+/**
+ * ledtrig_cpu - emit a CPU event as a trigger
+ * @evt: CPU event to be emitted
+ *
+ * Emit a CPU event on a CPU core, which will trigger a
+ * binded LED to turn on or turn off.
+ */
+void ledtrig_cpu(enum cpu_led_event ledevt)
+{
+       struct led_trigger_cpu *trig = &__get_cpu_var(cpu_trig);
+
+       /* mutex lock should be initialized before calling mutex_call() */
+       if (!trig->lock_is_inited)
+               return;
+
+       mutex_lock(&trig->lock);
+
+       /* Locate the correct CPU LED */
+       switch (ledevt) {
+       case CPU_LED_IDLE_END:
+       case CPU_LED_START:
+               /* Will turn the LED on, max brightness */
+               led_trigger_event(trig->_trig, LED_FULL);
+               break;
+
+       case CPU_LED_IDLE_START:
+       case CPU_LED_STOP:
+       case CPU_LED_HALTED:
+               /* Will turn the LED off */
+               led_trigger_event(trig->_trig, LED_OFF);
+               break;
+
+       default:
+               /* Will leave the LED as it is */
+               break;
+       }
+
+       mutex_unlock(&trig->lock);
+}
+EXPORT_SYMBOL(ledtrig_cpu);
+
+static int ledtrig_cpu_syscore_suspend(void)
+{
+       ledtrig_cpu(CPU_LED_STOP);
+       return 0;
+}
+
+static void ledtrig_cpu_syscore_resume(void)
+{
+       ledtrig_cpu(CPU_LED_START);
+}
+
+static void ledtrig_cpu_syscore_shutdown(void)
+{
+       ledtrig_cpu(CPU_LED_HALTED);
+}
+
+static struct syscore_ops ledtrig_cpu_syscore_ops = {
+       .shutdown       = ledtrig_cpu_syscore_shutdown,
+       .suspend        = ledtrig_cpu_syscore_suspend,
+       .resume         = ledtrig_cpu_syscore_resume,
+};
+
+static int __init ledtrig_cpu_init(void)
+{
+       int cpu;
+
+       /* Supports up to 9999 cpu cores */
+       BUILD_BUG_ON(CONFIG_NR_CPUS > 9999);
+
+       /*
+        * Registering CPU led trigger for each CPU core here
+        * ignores CPU hotplug, but after this CPU hotplug works
+        * fine with this trigger.
+        */
+       for_each_possible_cpu(cpu) {
+               struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu);
+
+               mutex_init(&trig->lock);
+
+               snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu);
+
+               mutex_lock(&trig->lock);
+               led_trigger_register_simple(trig->name, &trig->_trig);
+               trig->lock_is_inited = 1;
+               mutex_unlock(&trig->lock);
+       }
+
+       register_syscore_ops(&ledtrig_cpu_syscore_ops);
+
+       pr_info("ledtrig-cpu: registered to indicate activity on CPUs\n");
+
+       return 0;
+}
+module_init(ledtrig_cpu_init);
+
+static void __exit ledtrig_cpu_exit(void)
+{
+       int cpu;
+
+       for_each_possible_cpu(cpu) {
+               struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu);
+
+               mutex_lock(&trig->lock);
+
+               led_trigger_unregister_simple(trig->_trig);
+               trig->_trig = NULL;
+               memset(trig->name, 0, MAX_NAME_LEN);
+               trig->lock_is_inited = 0;
+
+               mutex_unlock(&trig->lock);
+               mutex_destroy(&trig->lock);
+       }
+
+       unregister_syscore_ops(&ledtrig_cpu_syscore_ops);
+}
+module_exit(ledtrig_cpu_exit);
+
+MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
+MODULE_AUTHOR("Bryan Wu <bryan.wu@canonical.com>");
+MODULE_DESCRIPTION("CPU LED trigger");
+MODULE_LICENSE("GPL");
index 3aade1d..c6f8dad 100644 (file)
@@ -237,4 +237,20 @@ struct gpio_led_platform_data {
 struct platform_device *gpio_led_register_device(
                int id, const struct gpio_led_platform_data *pdata);
 
+enum cpu_led_event {
+       CPU_LED_IDLE_START,     /* CPU enters idle */
+       CPU_LED_IDLE_END,       /* CPU idle ends */
+       CPU_LED_START,          /* Machine starts, especially resume */
+       CPU_LED_STOP,           /* Machine stops, especially suspend */
+       CPU_LED_HALTED,         /* Machine shutdown */
+};
+#ifdef CONFIG_LEDS_TRIGGER_CPU
+extern void ledtrig_cpu(enum cpu_led_event evt);
+#else
+static inline void ledtrig_cpu(enum cpu_led_event evt)
+{
+       return;
+}
+#endif
+
 #endif         /* __LINUX_LEDS_H_INCLUDED */