11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * linux/arch/arm/mach-footbridge/ebsa285.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * EBSA285 machine fixup 51da177e4SLinus Torvalds */ 61da177e4SLinus Torvalds #include <linux/init.h> 7*43024ed6SRussell King #include <linux/io.h> 870d13e08SRussell King #include <linux/spinlock.h> 9cf6856d6SBryan Wu #include <linux/slab.h> 10cf6856d6SBryan Wu #include <linux/leds.h> 111da177e4SLinus Torvalds 121da177e4SLinus Torvalds #include <asm/hardware/dec21285.h> 131da177e4SLinus Torvalds #include <asm/mach-types.h> 141da177e4SLinus Torvalds 151da177e4SLinus Torvalds #include <asm/mach/arch.h> 161da177e4SLinus Torvalds 171da177e4SLinus Torvalds #include "common.h" 181da177e4SLinus Torvalds 19cf6856d6SBryan Wu /* LEDs */ 20cf6856d6SBryan Wu #if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS) 21*43024ed6SRussell King #define XBUS_AMBER_L BIT(0) 22*43024ed6SRussell King #define XBUS_GREEN_L BIT(1) 23*43024ed6SRussell King #define XBUS_RED_L BIT(2) 24*43024ed6SRussell King #define XBUS_TOGGLE BIT(7) 25*43024ed6SRussell King 26cf6856d6SBryan Wu struct ebsa285_led { 27cf6856d6SBryan Wu struct led_classdev cdev; 28cf6856d6SBryan Wu u8 mask; 29cf6856d6SBryan Wu }; 30cf6856d6SBryan Wu 31cf6856d6SBryan Wu /* 32cf6856d6SBryan Wu * The triggers lines up below will only be used if the 33cf6856d6SBryan Wu * LED triggers are compiled in. 34cf6856d6SBryan Wu */ 35cf6856d6SBryan Wu static const struct { 36cf6856d6SBryan Wu const char *name; 37cf6856d6SBryan Wu const char *trigger; 38cf6856d6SBryan Wu } ebsa285_leds[] = { 3967130c54SRussell King { "ebsa285:amber", "cpu0", }, 4067130c54SRussell King { "ebsa285:green", "heartbeat", }, 41cf6856d6SBryan Wu { "ebsa285:red",}, 42cf6856d6SBryan Wu }; 43cf6856d6SBryan Wu 4467130c54SRussell King static unsigned char hw_led_state; 45*43024ed6SRussell King static void __iomem *xbus; 4667130c54SRussell King 47cf6856d6SBryan Wu static void ebsa285_led_set(struct led_classdev *cdev, 48cf6856d6SBryan Wu enum led_brightness b) 49cf6856d6SBryan Wu { 50cf6856d6SBryan Wu struct ebsa285_led *led = container_of(cdev, 51cf6856d6SBryan Wu struct ebsa285_led, cdev); 52cf6856d6SBryan Wu 5367130c54SRussell King if (b == LED_OFF) 5467130c54SRussell King hw_led_state |= led->mask; 55cf6856d6SBryan Wu else 5667130c54SRussell King hw_led_state &= ~led->mask; 57*43024ed6SRussell King writeb(hw_led_state, xbus); 58cf6856d6SBryan Wu } 59cf6856d6SBryan Wu 60cf6856d6SBryan Wu static enum led_brightness ebsa285_led_get(struct led_classdev *cdev) 61cf6856d6SBryan Wu { 62cf6856d6SBryan Wu struct ebsa285_led *led = container_of(cdev, 63cf6856d6SBryan Wu struct ebsa285_led, cdev); 64cf6856d6SBryan Wu 6567130c54SRussell King return hw_led_state & led->mask ? LED_OFF : LED_FULL; 66cf6856d6SBryan Wu } 67cf6856d6SBryan Wu 68cf6856d6SBryan Wu static int __init ebsa285_leds_init(void) 69cf6856d6SBryan Wu { 70cf6856d6SBryan Wu int i; 71cf6856d6SBryan Wu 7267130c54SRussell King if (!machine_is_ebsa285()) 73cf6856d6SBryan Wu return -ENODEV; 74cf6856d6SBryan Wu 75*43024ed6SRussell King xbus = ioremap(XBUS_CS2, SZ_4K); 76*43024ed6SRussell King if (!xbus) 77*43024ed6SRussell King return -ENOMEM; 78*43024ed6SRussell King 7967130c54SRussell King /* 3 LEDS all off */ 80*43024ed6SRussell King hw_led_state = XBUS_AMBER_L | XBUS_GREEN_L | XBUS_RED_L; 81*43024ed6SRussell King writeb(hw_led_state, xbus); 82cf6856d6SBryan Wu 83cf6856d6SBryan Wu for (i = 0; i < ARRAY_SIZE(ebsa285_leds); i++) { 84cf6856d6SBryan Wu struct ebsa285_led *led; 85cf6856d6SBryan Wu 86cf6856d6SBryan Wu led = kzalloc(sizeof(*led), GFP_KERNEL); 87cf6856d6SBryan Wu if (!led) 88cf6856d6SBryan Wu break; 89cf6856d6SBryan Wu 90cf6856d6SBryan Wu led->cdev.name = ebsa285_leds[i].name; 91cf6856d6SBryan Wu led->cdev.brightness_set = ebsa285_led_set; 92cf6856d6SBryan Wu led->cdev.brightness_get = ebsa285_led_get; 93cf6856d6SBryan Wu led->cdev.default_trigger = ebsa285_leds[i].trigger; 94cf6856d6SBryan Wu led->mask = BIT(i); 95cf6856d6SBryan Wu 96cf6856d6SBryan Wu if (led_classdev_register(NULL, &led->cdev) < 0) { 97cf6856d6SBryan Wu kfree(led); 98cf6856d6SBryan Wu break; 99cf6856d6SBryan Wu } 100cf6856d6SBryan Wu } 101cf6856d6SBryan Wu 102cf6856d6SBryan Wu return 0; 103cf6856d6SBryan Wu } 104cf6856d6SBryan Wu 105cf6856d6SBryan Wu /* 106cf6856d6SBryan Wu * Since we may have triggers on any subsystem, defer registration 107cf6856d6SBryan Wu * until after subsystem_init. 108cf6856d6SBryan Wu */ 109cf6856d6SBryan Wu fs_initcall(ebsa285_leds_init); 110cf6856d6SBryan Wu #endif 111cf6856d6SBryan Wu 1121da177e4SLinus Torvalds MACHINE_START(EBSA285, "EBSA285") 113e9dea0c6SRussell King /* Maintainer: Russell King */ 11493ef8883SNicolas Pitre .atag_offset = 0x100, 115e9dea0c6SRussell King .video_start = 0x000a0000, 116e9dea0c6SRussell King .video_end = 0x000bffff, 117e9dea0c6SRussell King .map_io = footbridge_map_io, 1186cefe92fSRussell King .init_early = footbridge_sched_clock, 119e9dea0c6SRussell King .init_irq = footbridge_init_irq, 1206bb27d73SStephen Warren .init_time = footbridge_timer_init, 1216fca1e17SRussell King .restart = footbridge_restart, 1221da177e4SLinus Torvalds MACHINE_END 1231da177e4SLinus Torvalds 124