ARM: mach-ebsa110: retire custom LED code
Bryan Wu [Thu, 30 Jun 2011 14:56:17 +0000 (22:56 +0800)]
Signed-off-by: Bryan Wu <bryan.wu@canonical.com>

arch/arm/mach-ebsa110/Makefile
arch/arm/mach-ebsa110/leds.c

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