linux/arch/arm/mach-footbridge/ebsa285.c
<<
>>
Prefs
   1/*
   2 * linux/arch/arm/mach-footbridge/ebsa285.c
   3 *
   4 * EBSA285 machine fixup
   5 */
   6#include <linux/init.h>
   7#include <linux/io.h>
   8#include <linux/spinlock.h>
   9#include <linux/slab.h>
  10#include <linux/leds.h>
  11
  12#include <asm/hardware/dec21285.h>
  13#include <asm/mach-types.h>
  14
  15#include <asm/mach/arch.h>
  16
  17#include "common.h"
  18
  19/* LEDs */
  20#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
  21#define XBUS_AMBER_L    BIT(0)
  22#define XBUS_GREEN_L    BIT(1)
  23#define XBUS_RED_L      BIT(2)
  24#define XBUS_TOGGLE     BIT(7)
  25
  26struct ebsa285_led {
  27        struct led_classdev     cdev;
  28        u8                      mask;
  29};
  30
  31/*
  32 * The triggers lines up below will only be used if the
  33 * LED triggers are compiled in.
  34 */
  35static const struct {
  36        const char *name;
  37        const char *trigger;
  38} ebsa285_leds[] = {
  39        { "ebsa285:amber", "cpu0", },
  40        { "ebsa285:green", "heartbeat", },
  41        { "ebsa285:red",},
  42};
  43
  44static unsigned char hw_led_state;
  45static void __iomem *xbus;
  46
  47static void ebsa285_led_set(struct led_classdev *cdev,
  48                enum led_brightness b)
  49{
  50        struct ebsa285_led *led = container_of(cdev,
  51                        struct ebsa285_led, cdev);
  52
  53        if (b == LED_OFF)
  54                hw_led_state |= led->mask;
  55        else
  56                hw_led_state &= ~led->mask;
  57        writeb(hw_led_state, xbus);
  58}
  59
  60static enum led_brightness ebsa285_led_get(struct led_classdev *cdev)
  61{
  62        struct ebsa285_led *led = container_of(cdev,
  63                        struct ebsa285_led, cdev);
  64
  65        return hw_led_state & led->mask ? LED_OFF : LED_FULL;
  66}
  67
  68static int __init ebsa285_leds_init(void)
  69{
  70        int i;
  71
  72        if (!machine_is_ebsa285())
  73                return -ENODEV;
  74
  75        xbus = ioremap(XBUS_CS2, SZ_4K);
  76        if (!xbus)
  77                return -ENOMEM;
  78
  79        /* 3 LEDS all off */
  80        hw_led_state = XBUS_AMBER_L | XBUS_GREEN_L | XBUS_RED_L;
  81        writeb(hw_led_state, xbus);
  82
  83        for (i = 0; i < ARRAY_SIZE(ebsa285_leds); i++) {
  84                struct ebsa285_led *led;
  85
  86                led = kzalloc(sizeof(*led), GFP_KERNEL);
  87                if (!led)
  88                        break;
  89
  90                led->cdev.name = ebsa285_leds[i].name;
  91                led->cdev.brightness_set = ebsa285_led_set;
  92                led->cdev.brightness_get = ebsa285_led_get;
  93                led->cdev.default_trigger = ebsa285_leds[i].trigger;
  94                led->mask = BIT(i);
  95
  96                if (led_classdev_register(NULL, &led->cdev) < 0) {
  97                        kfree(led);
  98                        break;
  99                }
 100        }
 101
 102        return 0;
 103}
 104
 105/*
 106 * Since we may have triggers on any subsystem, defer registration
 107 * until after subsystem_init.
 108 */
 109fs_initcall(ebsa285_leds_init);
 110#endif
 111
 112MACHINE_START(EBSA285, "EBSA285")
 113        /* Maintainer: Russell King */
 114        .atag_offset    = 0x100,
 115        .video_start    = 0x000a0000,
 116        .video_end      = 0x000bffff,
 117        .map_io         = footbridge_map_io,
 118        .init_early     = footbridge_sched_clock,
 119        .init_irq       = footbridge_init_irq,
 120        .init_time      = footbridge_timer_init,
 121        .restart        = footbridge_restart,
 122MACHINE_END
 123
 124