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