Loading arch/arm/mach-shark/Makefile +1 −3 Original line number Diff line number Diff line Loading @@ -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 arch/arm/mach-shark/core.c +0 −1 Original line number Diff line number Diff line Loading @@ -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> Loading arch/arm/mach-shark/leds.c +86 −134 Original line number Diff line number Diff line /* * 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> #define LED_STATE_ENABLED 1 #define LED_STATE_CLAIMED 2 #define SEQUOIA_LED_GREEN (1<<6) #define SEQUOIA_LED_AMBER (1<<5) #define SEQUOIA_LED_BACK (1<<7) static char led_state; static short hw_led_state; static short saved_state; #include <asm/mach-types.h> static DEFINE_RAW_SPINLOCK(leds_lock); #if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS) struct shark_led { struct led_classdev cdev; u8 mask; }; short sequoia_read(int addr) { outw(addr,0x24); /* * 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); } void sequoia_write(short value,short addr) { outw(addr,0x24); static void led_reg_write(u16 value) { outw(0x09, 0x24); outw(value, 0x26); } static void sequoia_leds_event(led_event_t evt) static void shark_led_set(struct led_classdev *cdev, enum led_brightness b) { unsigned long flags; struct shark_led *led = container_of(cdev, struct shark_led, cdev); u16 reg = led_reg_read(); raw_spin_lock_irqsave(&leds_lock, flags); if (b != LED_OFF) reg |= led->mask; else reg &= ~led->mask; hw_led_state = sequoia_read(0x09); 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 led_reg_write(reg); } #ifdef CONFIG_LEDS_CPU case led_idle_start: if (!(led_state & LED_STATE_CLAIMED)) hw_led_state &= ~SEQUOIA_LED_BACK; break; static enum led_brightness shark_led_get(struct led_classdev *cdev) { struct shark_led *led = container_of(cdev, struct shark_led, cdev); u16 reg = led_reg_read(); case led_idle_end: if (!(led_state & LED_STATE_CLAIMED)) hw_led_state |= SEQUOIA_LED_BACK; break; #endif return (reg & led->mask) ? LED_FULL : LED_OFF; } case led_green_on: if (led_state & LED_STATE_CLAIMED) hw_led_state &= ~SEQUOIA_LED_GREEN; break; static int __init shark_leds_init(void) { int i; u16 reg; case led_green_off: if (led_state & LED_STATE_CLAIMED) hw_led_state |= SEQUOIA_LED_GREEN; break; if (!machine_is_shark()) return -ENODEV; case led_amber_on: if (led_state & LED_STATE_CLAIMED) hw_led_state &= ~SEQUOIA_LED_AMBER; break; for (i = 0; i < ARRAY_SIZE(shark_leds); i++) { struct shark_led *led; case led_amber_off: if (led_state & LED_STATE_CLAIMED) hw_led_state |= SEQUOIA_LED_AMBER; led = kzalloc(sizeof(*led), GFP_KERNEL); if (!led) break; case led_red_on: if (led_state & LED_STATE_CLAIMED) hw_led_state |= SEQUOIA_LED_BACK; break; 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; case led_red_off: if (led_state & LED_STATE_CLAIMED) hw_led_state &= ~SEQUOIA_LED_BACK; break; /* Count in 5 bits offset */ led->mask = BIT(i + 5); default: if (led_classdev_register(NULL, &led->cdev) < 0) { kfree(led); break; } if (led_state & LED_STATE_ENABLED) sequoia_write(hw_led_state,0x09); raw_spin_unlock_irqrestore(&leds_lock, flags); } static int __init leds_init(void) { extern void (*leds_event)(led_event_t); short temp; leds_event = sequoia_leds_event; /* 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 Loading
arch/arm/mach-shark/Makefile +1 −3 Original line number Diff line number Diff line Loading @@ -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
arch/arm/mach-shark/core.c +0 −1 Original line number Diff line number Diff line Loading @@ -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> Loading
arch/arm/mach-shark/leds.c +86 −134 Original line number Diff line number Diff line /* * 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> #define LED_STATE_ENABLED 1 #define LED_STATE_CLAIMED 2 #define SEQUOIA_LED_GREEN (1<<6) #define SEQUOIA_LED_AMBER (1<<5) #define SEQUOIA_LED_BACK (1<<7) static char led_state; static short hw_led_state; static short saved_state; #include <asm/mach-types.h> static DEFINE_RAW_SPINLOCK(leds_lock); #if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS) struct shark_led { struct led_classdev cdev; u8 mask; }; short sequoia_read(int addr) { outw(addr,0x24); /* * 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); } void sequoia_write(short value,short addr) { outw(addr,0x24); static void led_reg_write(u16 value) { outw(0x09, 0x24); outw(value, 0x26); } static void sequoia_leds_event(led_event_t evt) static void shark_led_set(struct led_classdev *cdev, enum led_brightness b) { unsigned long flags; struct shark_led *led = container_of(cdev, struct shark_led, cdev); u16 reg = led_reg_read(); raw_spin_lock_irqsave(&leds_lock, flags); if (b != LED_OFF) reg |= led->mask; else reg &= ~led->mask; hw_led_state = sequoia_read(0x09); 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 led_reg_write(reg); } #ifdef CONFIG_LEDS_CPU case led_idle_start: if (!(led_state & LED_STATE_CLAIMED)) hw_led_state &= ~SEQUOIA_LED_BACK; break; static enum led_brightness shark_led_get(struct led_classdev *cdev) { struct shark_led *led = container_of(cdev, struct shark_led, cdev); u16 reg = led_reg_read(); case led_idle_end: if (!(led_state & LED_STATE_CLAIMED)) hw_led_state |= SEQUOIA_LED_BACK; break; #endif return (reg & led->mask) ? LED_FULL : LED_OFF; } case led_green_on: if (led_state & LED_STATE_CLAIMED) hw_led_state &= ~SEQUOIA_LED_GREEN; break; static int __init shark_leds_init(void) { int i; u16 reg; case led_green_off: if (led_state & LED_STATE_CLAIMED) hw_led_state |= SEQUOIA_LED_GREEN; break; if (!machine_is_shark()) return -ENODEV; case led_amber_on: if (led_state & LED_STATE_CLAIMED) hw_led_state &= ~SEQUOIA_LED_AMBER; break; for (i = 0; i < ARRAY_SIZE(shark_leds); i++) { struct shark_led *led; case led_amber_off: if (led_state & LED_STATE_CLAIMED) hw_led_state |= SEQUOIA_LED_AMBER; led = kzalloc(sizeof(*led), GFP_KERNEL); if (!led) break; case led_red_on: if (led_state & LED_STATE_CLAIMED) hw_led_state |= SEQUOIA_LED_BACK; break; 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; case led_red_off: if (led_state & LED_STATE_CLAIMED) hw_led_state &= ~SEQUOIA_LED_BACK; break; /* Count in 5 bits offset */ led->mask = BIT(i + 5); default: if (led_classdev_register(NULL, &led->cdev) < 0) { kfree(led); break; } if (led_state & LED_STATE_ENABLED) sequoia_write(hw_led_state,0x09); raw_spin_unlock_irqrestore(&leds_lock, flags); } static int __init leds_init(void) { extern void (*leds_event)(led_event_t); short temp; leds_event = sequoia_leds_event; /* 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