dect
/
linux-2.6
Archived
13
0
Fork 0

Merge branch 'for-arm-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds into next/drivers

From Bryan Wu <bryan.wu@canonical.com>:

Based on Linus Walleij's ARM LED consolidation work, this patchset introduce a
new generic led trigger for CPU not only for ARM but also for others.

For enabling CPU idle event, CPU arch code should call ledtrig_cpu() stub to
trigger idle start or idle end event.

These patches convert old style LED driver in arch/arm to gpio_led or new led
driver interface. Against 3.5 release and build successfully for all the machines.

Test ledtrig-cpu driver on OMAP4 Panda board.

v9 --> v10
 * fix compiling issue on versatile_defconfig reported by Russell King
 * rebase to 3.5 kernel and move patches to new git tree

v8 --> v9:
 * use mutex to replace rw_sema pointed out by Tim Gardner
 * add a new struct led_trigger_cpu
 * add lock_is_inited to record mutex lock initialization

v6 --> v7:
 * add a patch to unify the led-trigger name
 * fix some typo pointed
 * use BUG_ON to detect CPU numbers during building stage

v5 --> v6:
 * replace  __get_cpu_var() to per_cpu()
 * remove smp_processor_id() which is wrong with for_each_possible_cpu()
 * test on real OMAP4 Panda board
 * add comments about CPU hotplug in the CPU LED trigger driver

v4 --> v5:
 * rebase all the patches on top of latest linux-next
 * replace on_each_cpu() with for_each_possible_cpu()
 * add some description of ledtrig_cpu() API
 * remove old leds code from driver nwflash.c, which should use a new led trigger then
 * this trigger driver can be built as module now

v3 --> v4:
 * fix a typo pointed by Jochen Friedrich
 * fix some building errors
 * add Reviewed-by and Tested-by into patch log

v2 --> v3:
 * almost rewrote the whole ledtrig-cpu driver, which is more simple
 * every CPU will have a per-CPU trigger
 * cpu trigger can be assigned to any leds
 * fix a lockdep issue in led-trigger common code
 * other fix according to review

v1 --> v2:
 * remove select operations in Kconfig of every machines
 * add back supporting of led in core module of mach-integrator
 * solidate name scheme in ledtrig-cpu.c
 * add comments of CPU_LED_* cpu led events
 * fold patches of RealView and Versatile together
 * add machine_is_ check during assabet led driver init
 * add some Acked-by in patch logs
 * remove code for simpad machine in machine-sa11000, since Jochen Friedrich
   introduced gpiolib and gpio-led driver for simpad
 * on Assabet and Netwinder machine, LED operations is reversed like:
   setting bit means turn off leds
   clearing bit means turn on leds
 * add a new function to read CM_CTRL register for led driver

* 'for-arm-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds:
  ARM: use new LEDS CPU trigger stub to replace old one
  ARM: mach-sa1100: retire custom LED code
  ARM: mach-omap1: retire custom LED code
  ARM: mach-pnx4008: remove including old leds event API header file
  ARM: plat-samsung: remove including old leds event API header file
  ARM: mach-pxa: retire custom LED code
  char: nwflash: remove old led event code
  ARM: mach-footbridge: retire custom LED code
  ARM: mach-ebsa110: retire custom LED code
  ARM: mach-clps711x: retire custom LED code of P720T machine
  ARM: mach-integrator: retire custom LED code
  ARM: mach-integrator: move CM_CTRL to header file for accessing by other functions
  ARM: mach-orion5x: convert custom LED code to gpio_led and LED CPU trigger
  ARM: mach-shark: retire custom LED code
  ARM: mach-ks8695: remove leds driver, since nobody use it
  ARM: mach-realview and mach-versatile: retire custom LED code
  ARM: at91: convert old leds drivers to gpio_led and led_trigger drivers
  led-triggers: create a trigger for CPU activity

Conflicts:
	arch/arm/mach-clps711x/p720t.c
	arch/arm/mach-sa1100/leds-cerf.c
	arch/arm/mach-sa1100/leds-lart.c

Let's hope this is the last time we pull this and it doesn't cause
more trouble. I have verified that version 10 causes no build
warnings or errors any more, and the patches still look good.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2012-08-13 16:45:48 +02:00
commit 19e4ab54e7
97 changed files with 1447 additions and 2989 deletions

View File

@ -1787,59 +1787,6 @@ config FORCE_MAX_ZONEORDER
This config option is actually maximum order plus one. For example,
a value of 11 means that the largest free memory block is 2^10 pages.
config LEDS
bool "Timer and CPU usage LEDs"
depends on ARCH_CDB89712 || ARCH_EBSA110 || \
ARCH_EBSA285 || ARCH_INTEGRATOR || \
ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
ARCH_AT91 || ARCH_DAVINCI || \
ARCH_KS8695 || MACH_RD88F5182 || ARCH_REALVIEW
help
If you say Y here, the LEDs on your machine will be used
to provide useful information about your current system status.
If you are compiling a kernel for a NetWinder or EBSA-285, you will
be able to select which LEDs are active using the options below. If
you are compiling a kernel for the EBSA-110 or the LART however, the
red LED will simply flash regularly to indicate that the system is
still functional. It is safe to say Y here if you have a CATS
system, but the driver will do nothing.
config LEDS_TIMER
bool "Timer LED" if (!ARCH_CDB89712 && !ARCH_OMAP) || \
OMAP_OSK_MISTRAL || MACH_OMAP_H2 \
|| MACH_OMAP_PERSEUS2
depends on LEDS
depends on !GENERIC_CLOCKEVENTS
default y if ARCH_EBSA110
help
If you say Y here, one of the system LEDs (the green one on the
NetWinder, the amber one on the EBSA285, or the red one on the LART)
will flash regularly to indicate that the system is still
operational. This is mainly useful to kernel hackers who are
debugging unstable kernels.
The LART uses the same LED for both Timer LED and CPU usage LED
functions. You may choose to use both, but the Timer LED function
will overrule the CPU usage LED.
config LEDS_CPU
bool "CPU usage LED" if (!ARCH_CDB89712 && !ARCH_EBSA110 && \
!ARCH_OMAP) \
|| OMAP_OSK_MISTRAL || MACH_OMAP_H2 \
|| MACH_OMAP_PERSEUS2
depends on LEDS
help
If you say Y here, the red LED will be used to give a good real
time indication of CPU usage, by lighting whenever the idle task
is not currently executing.
The LART uses the same LED for both Timer LED and CPU usage LED
functions. You may choose to use both, but the Timer LED function
will overrule the CPU usage LED.
config ALIGNMENT_TRAP
bool
depends on CPU_CP15_MMU

View File

@ -1,50 +0,0 @@
/*
* arch/arm/include/asm/leds.h
*
* 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.
*
* Event-driven interface for LEDs on machines
* Added led_start and led_stop- Alex Holden, 28th Dec 1998.
*/
#ifndef ASM_ARM_LEDS_H
#define ASM_ARM_LEDS_H
typedef enum {
led_idle_start,
led_idle_end,
led_timer,
led_start,
led_stop,
led_claim, /* override idle & timer leds */
led_release, /* restore idle & timer leds */
led_start_timer_mode,
led_stop_timer_mode,
led_green_on,
led_green_off,
led_amber_on,
led_amber_off,
led_red_on,
led_red_off,
led_blue_on,
led_blue_off,
/*
* I want this between led_timer and led_start, but
* someone has decided to export this to user space
*/
led_halted
} led_event_t;
/* Use this routine to handle LEDs */
#ifdef CONFIG_LEDS
extern void (*leds_event)(led_event_t);
#else
#define leds_event(e)
#endif
#endif

View File

@ -21,7 +21,6 @@ obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \
obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o
obj-$(CONFIG_LEDS) += leds.o
obj-$(CONFIG_OC_ETM) += etm.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
obj-$(CONFIG_ISA_DMA_API) += dma.o

View File

@ -1,121 +0,0 @@
/*
* LED support code, ripped out of arch/arm/kernel/time.c
*
* Copyright (C) 1994-2001 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.
*/
#include <linux/export.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/syscore_ops.h>
#include <linux/string.h>
#include <asm/leds.h>
static void dummy_leds_event(led_event_t evt)
{
}
void (*leds_event)(led_event_t) = dummy_leds_event;
struct leds_evt_name {
const char name[8];
int on;
int off;
};
static const struct leds_evt_name evt_names[] = {
{ "amber", led_amber_on, led_amber_off },
{ "blue", led_blue_on, led_blue_off },
{ "green", led_green_on, led_green_off },
{ "red", led_red_on, led_red_off },
};
static ssize_t leds_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
int ret = -EINVAL, len = strcspn(buf, " ");
if (len > 0 && buf[len] == '\0')
len--;
if (strncmp(buf, "claim", len) == 0) {
leds_event(led_claim);
ret = size;
} else if (strncmp(buf, "release", len) == 0) {
leds_event(led_release);
ret = size;
} else {
int i;
for (i = 0; i < ARRAY_SIZE(evt_names); i++) {
if (strlen(evt_names[i].name) != len ||
strncmp(buf, evt_names[i].name, len) != 0)
continue;
if (strncmp(buf+len, " on", 3) == 0) {
leds_event(evt_names[i].on);
ret = size;
} else if (strncmp(buf+len, " off", 4) == 0) {
leds_event(evt_names[i].off);
ret = size;
}
break;
}
}
return ret;
}
static DEVICE_ATTR(event, 0200, NULL, leds_store);
static struct bus_type leds_subsys = {
.name = "leds",
.dev_name = "leds",
};
static struct device leds_device = {
.id = 0,
.bus = &leds_subsys,
};
static int leds_suspend(void)
{
leds_event(led_stop);
return 0;
}
static void leds_resume(void)
{
leds_event(led_start);
}
static void leds_shutdown(void)
{
leds_event(led_halted);
}
static struct syscore_ops leds_syscore_ops = {
.shutdown = leds_shutdown,
.suspend = leds_suspend,
.resume = leds_resume,
};
static int __init leds_init(void)
{
int ret;
ret = subsys_system_register(&leds_subsys, NULL);
if (ret == 0)
ret = device_register(&leds_device);
if (ret == 0)
ret = device_create_file(&leds_device, &dev_attr_event);
if (ret == 0)
register_syscore_ops(&leds_syscore_ops);
return ret;
}
device_initcall(leds_init);
EXPORT_SYMBOL(leds_event);

View File

@ -31,9 +31,9 @@
#include <linux/random.h>
#include <linux/hw_breakpoint.h>
#include <linux/cpuidle.h>
#include <linux/leds.h>
#include <asm/cacheflush.h>
#include <asm/leds.h>
#include <asm/processor.h>
#include <asm/thread_notify.h>
#include <asm/stacktrace.h>
@ -189,7 +189,7 @@ void cpu_idle(void)
while (1) {
tick_nohz_idle_enter();
rcu_idle_enter();
leds_event(led_idle_start);
ledtrig_cpu(CPU_LED_IDLE_START);
while (!need_resched()) {
#ifdef CONFIG_HOTPLUG_CPU
if (cpu_is_offline(smp_processor_id()))
@ -220,7 +220,7 @@ void cpu_idle(void)
} else
local_irq_enable();
}
leds_event(led_idle_end);
ledtrig_cpu(CPU_LED_IDLE_END);
rcu_idle_exit();
tick_nohz_idle_exit();
schedule_preempt_disabled();

View File

@ -25,7 +25,6 @@
#include <linux/timer.h>
#include <linux/irq.h>
#include <asm/leds.h>
#include <asm/thread_info.h>
#include <asm/sched_clock.h>
#include <asm/stacktrace.h>
@ -80,21 +79,6 @@ u32 arch_gettimeoffset(void)
}
#endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */
#ifdef CONFIG_LEDS_TIMER
static inline void do_leds(void)
{
static unsigned int count = HZ/2;
if (--count == 0) {
count = HZ/2;
leds_event(led_timer);
}
}
#else
#define do_leds()
#endif
#ifndef CONFIG_GENERIC_CLOCKEVENTS
/*
* Kernel system timer support.
@ -102,7 +86,6 @@ static inline void do_leds(void)
void timer_tick(void)
{
profile_tick(CPU_PROFILING);
do_leds();
xtime_update(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(get_irq_regs()));

View File

@ -220,8 +220,6 @@ static struct gpio_led csb_leds[] = {
static void __init csb337_board_init(void)
{
/* Setup the LEDs */
at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1);
/* Serial */
/* DBGU on ttyS0 */
at91_register_uart(0, 0, 0);

View File

@ -138,11 +138,20 @@ static struct spi_board_info __initdata ecb_at91spi_devices[] = {
},
};
/*
* LEDs
*/
static struct gpio_led ecb_leds[] = {
{ /* D1 */
.name = "led1",
.gpio = AT91_PIN_PC7,
.active_low = 1,
.default_trigger = "heartbeat",
}
};
static void __init ecb_at91board_init(void)
{
/* Setup the LEDs */
at91_init_leds(AT91_PIN_PC7, AT91_PIN_PC7);
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);
@ -165,6 +174,9 @@ static void __init ecb_at91board_init(void)
/* SPI */
at91_add_device_spi(ecb_at91spi_devices, ARRAY_SIZE(ecb_at91spi_devices));
/* LEDs */
at91_gpio_leds(ecb_leds, ARRAY_SIZE(ecb_leds));
}
MACHINE_START(ECBAT91, "emQbit's ECB_AT91")

View File

@ -93,10 +93,26 @@ static struct spi_board_info eco920_spi_devices[] = {
},
};
/*
* LEDs
*/
static struct gpio_led eco920_leds[] = {
{ /* D1 */
.name = "led1",
.gpio = AT91_PIN_PB0,
.active_low = 1,
.default_trigger = "heartbeat",
},
{ /* D2 */
.name = "led2",
.gpio = AT91_PIN_PB1,
.active_low = 1,
.default_trigger = "timer",
}
};
static void __init eco920_board_init(void)
{
/* Setup the LEDs */
at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1);
/* DBGU on ttyS0. (Rx & Tx only */
at91_register_uart(0, 0, 0);
at91_add_device_serial();
@ -127,6 +143,8 @@ static void __init eco920_board_init(void)
);
at91_add_device_spi(eco920_spi_devices, ARRAY_SIZE(eco920_spi_devices));
/* LEDs */
at91_gpio_leds(eco920_leds, ARRAY_SIZE(eco920_leds));
}
MACHINE_START(ECO920, "eco920")

View File

@ -66,11 +66,20 @@ static struct at91_udc_data __initdata kafa_udc_data = {
.pullup_pin = AT91_PIN_PB7,
};
/*
* LEDs
*/
static struct gpio_led kafa_leds[] = {
{ /* D1 */
.name = "led1",
.gpio = AT91_PIN_PB4,
.active_low = 1,
.default_trigger = "heartbeat",
},
};
static void __init kafa_board_init(void)
{
/* Set up the LEDs */
at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4);
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);
@ -88,6 +97,8 @@ static void __init kafa_board_init(void)
at91_add_device_i2c(NULL, 0);
/* SPI */
at91_add_device_spi(NULL, 0);
/* LEDs */
at91_gpio_leds(kafa_leds, ARRAY_SIZE(kafa_leds));
}
MACHINE_START(KAFA, "Sperry-Sun KAFA")

View File

@ -96,11 +96,26 @@ static struct atmel_nand_data __initdata kb9202_nand_data = {
.num_parts = ARRAY_SIZE(kb9202_nand_partition),
};
/*
* LEDs
*/
static struct gpio_led kb9202_leds[] = {
{ /* D1 */
.name = "led1",
.gpio = AT91_PIN_PC19,
.active_low = 1,
.default_trigger = "heartbeat",
},
{ /* D2 */
.name = "led2",
.gpio = AT91_PIN_PC18,
.active_low = 1,
.default_trigger = "timer",
}
};
static void __init kb9202_board_init(void)
{
/* Set up the LEDs */
at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18);
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);
@ -128,6 +143,8 @@ static void __init kb9202_board_init(void)
at91_add_device_spi(NULL, 0);
/* NAND */
at91_add_device_nand(&kb9202_nand_data);
/* LEDs */
at91_gpio_leds(kb9202_leds, ARRAY_SIZE(kb9202_leds));
}
MACHINE_START(KB9200, "KB920x")

View File

@ -177,9 +177,6 @@ static struct gpio_led dk_leds[] = {
static void __init dk_board_init(void)
{
/* Setup the LEDs */
at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);

View File

@ -148,9 +148,6 @@ static struct gpio_led ek_leds[] = {
static void __init ek_board_init(void)
{
/* Setup the LEDs */
at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2);
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);

View File

@ -185,9 +185,6 @@ static struct platform_device rsiews_nor_flash = {
*/
static void __init rsi_ews_board_init(void)
{
/* Setup the LEDs */
at91_init_leds(AT91_PIN_PB6, AT91_PIN_PB9);
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
/* This one is for debugging */

View File

@ -166,11 +166,26 @@ static struct at91_mmc_data __initdata ek_mmc_data = {
.vcc_pin = -EINVAL,
};
/*
* LEDs
*/
static struct gpio_led ek_leds[] = {
{ /* D1 */
.name = "led1",
.gpio = AT91_PIN_PA9,
.active_low = 1,
.default_trigger = "heartbeat",
},
{ /* D2 */
.name = "led2",
.gpio = AT91_PIN_PA6,
.active_low = 1,
.default_trigger = "timer",
}
};
static void __init ek_board_init(void)
{
/* Setup the LEDs */
at91_init_leds(AT91_PIN_PA9, AT91_PIN_PA6);
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);
@ -197,6 +212,8 @@ static void __init ek_board_init(void)
at91_add_device_mmc(0, &ek_mmc_data);
/* I2C */
at91_add_device_i2c(NULL, 0);
/* LEDs */
at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
}
MACHINE_START(SAM9_L9260, "Olimex SAM9-L9260")

View File

@ -569,9 +569,6 @@ static struct gpio_led ek_leds[] = {
static void __init ek_board_init(void)
{
/* Setup the LEDs */
at91_init_leds(AT91_PIN_PA13, AT91_PIN_PA14);
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);

View File

@ -541,9 +541,6 @@ void __init yl9200_add_device_video(void) {}
static void __init yl9200_board_init(void)
{
/* Setup the LEDs D2=PB17 (timer), D3=PB16 (cpu) */
at91_init_leds(AT91_PIN_PB16, AT91_PIN_PB17);
/* Serial */
/* DBGU on ttyS0. (Rx & Tx only) */
at91_register_uart(0, 0, 0);

View File

@ -187,7 +187,6 @@ struct at91_can_data {
extern void __init at91_add_device_can(struct at91_can_data *data);
/* LEDs */
extern void __init at91_init_leds(u8 cpu_led, u8 timer_led);
extern void __init at91_gpio_leds(struct gpio_led *leds, int nr);
extern void __init at91_pwm_leds(struct gpio_led *leds, int nr);

View File

@ -90,108 +90,3 @@ void __init at91_pwm_leds(struct gpio_led *leds, int nr)
#else
void __init at91_pwm_leds(struct gpio_led *leds, int nr){}
#endif
/* ------------------------------------------------------------------------- */
#if defined(CONFIG_LEDS)
#include <asm/leds.h>
/*
* Old ARM-specific LED framework; not fully functional when generic time is
* in use.
*/
static u8 at91_leds_cpu;
static u8 at91_leds_timer;
static inline void at91_led_on(unsigned int led)
{
at91_set_gpio_value(led, 0);
}
static inline void at91_led_off(unsigned int led)
{
at91_set_gpio_value(led, 1);
}
static inline void at91_led_toggle(unsigned int led)
{
unsigned long is_off = at91_get_gpio_value(led);
if (is_off)
at91_led_on(led);
else
at91_led_off(led);
}
/*
* Handle LED events.
*/
static void at91_leds_event(led_event_t evt)
{
unsigned long flags;
local_irq_save(flags);
switch(evt) {
case led_start: /* System startup */
at91_led_on(at91_leds_cpu);
break;
case led_stop: /* System stop / suspend */
at91_led_off(at91_leds_cpu);
break;
#ifdef CONFIG_LEDS_TIMER
case led_timer: /* Every 50 timer ticks */
at91_led_toggle(at91_leds_timer);
break;
#endif
#ifdef CONFIG_LEDS_CPU
case led_idle_start: /* Entering idle state */
at91_led_off(at91_leds_cpu);
break;
case led_idle_end: /* Exit idle state */
at91_led_on(at91_leds_cpu);
break;
#endif
default:
break;
}
local_irq_restore(flags);
}
static int __init leds_init(void)
{
if (!at91_leds_timer || !at91_leds_cpu)
return -ENODEV;
leds_event = at91_leds_event;
leds_event(led_start);
return 0;
}
__initcall(leds_init);
void __init at91_init_leds(u8 cpu_led, u8 timer_led)
{
/* Enable GPIO to access the LEDs */
at91_set_gpio_output(cpu_led, 1);
at91_set_gpio_output(timer_led, 1);
at91_leds_cpu = cpu_led;
at91_leds_timer = timer_led;
}
#else
void __init at91_init_leds(u8 cpu_led, u8 timer_led) {}
#endif

View File

@ -16,5 +16,3 @@ obj-$(CONFIG_ARCH_CLEP7312) += clep7312.o
obj-$(CONFIG_ARCH_EDB7211) += edb7211-arch.o edb7211-mm.o
obj-$(CONFIG_ARCH_FORTUNET) += fortunet.o
obj-$(CONFIG_ARCH_P720T) += p720t.o
leds-$(CONFIG_ARCH_P720T) += p720t-leds.o
obj-$(CONFIG_LEDS) += $(leds-y)

View File

@ -30,7 +30,6 @@
#include <asm/sizes.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/mach/map.h>

View File

@ -1,63 +0,0 @@
/*
* linux/arch/arm/mach-clps711x/leds.c
*
* Integrator LED control routines
*
* Copyright (C) 2000 Deep Blue Solutions Ltd
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
static void p720t_leds_event(led_event_t ledevt)
{
unsigned long flags;
u32 pddr;
local_irq_save(flags);
switch(ledevt) {
case led_idle_start:
break;
case led_idle_end:
break;
case led_timer:
pddr = clps_readb(PDDR);
clps_writeb(pddr ^ 1, PDDR);
break;
default:
break;
}
local_irq_restore(flags);
}
static int __init leds_init(void)
{
if (machine_is_p720t())
leds_event = p720t_leds_event;
return 0;
}
arch_initcall(leds_init);

View File

@ -23,6 +23,8 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/leds.h>
#include <mach/hardware.h>
#include <asm/pgtable.h>
@ -34,6 +36,8 @@
#include <asm/mach/map.h>
#include <mach/syspld.h>
#include <asm/hardware/clps7111.h>
#include "common.h"
/*
@ -107,6 +111,64 @@ static void __init p720t_init_early(void)
}
}
/*
* LED controled by CPLD
*/
#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
static void p720t_led_set(struct led_classdev *cdev,
enum led_brightness b)
{
u8 reg = clps_readb(PDDR);
if (b != LED_OFF)
reg |= 0x1;
else
reg &= ~0x1;
clps_writeb(reg, PDDR);
}
static enum led_brightness p720t_led_get(struct led_classdev *cdev)
{
u8 reg = clps_readb(PDDR);
return (reg & 0x1) ? LED_FULL : LED_OFF;
}
static int __init p720t_leds_init(void)
{
struct led_classdev *cdev;
int ret;
if (!machine_is_p720t())
return -ENODEV;
cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
if (!cdev)
return -ENOMEM;
cdev->name = "p720t:0";
cdev->brightness_set = p720t_led_set;
cdev->brightness_get = p720t_led_get;
cdev->default_trigger = "heartbeat";
ret = led_classdev_register(NULL, cdev);
if (ret < 0) {
kfree(cdev);
return ret;
}
return 0;
}
/*
* Since we may have triggers on any subsystem, defer registration
* until after subsystem_init.
*/
fs_initcall(p720t_leds_init);
#endif
MACHINE_START(P720T, "ARM-Prospector720T")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
.atag_offset = 0x100,

View 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

View 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;
default:
break;
}
spin_unlock_irqrestore(&leds_lock, flags);
__raw_writeb(reg, SOFT_BASE);
}
static int __init leds_init(void)
static enum led_brightness ebsa110_led_get(struct led_classdev *cdev)
{
if (machine_is_ebsa110())
leds_event = ebsa110_leds_event;
u8 reg = __raw_readb(SOFT_BASE);
return (reg & 0x80) ? LED_FULL : LED_OFF;
}
static int __init ebsa110_leds_init(void)
{
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

View File

@ -14,15 +14,11 @@ pci-$(CONFIG_ARCH_EBSA285_HOST) += ebsa285-pci.o
pci-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o
pci-$(CONFIG_ARCH_PERSONAL_SERVER) += personal-pci.o
leds-$(CONFIG_ARCH_EBSA285) += ebsa285-leds.o
leds-$(CONFIG_ARCH_NETWINDER) += netwinder-leds.o
obj-$(CONFIG_ARCH_CATS) += cats-hw.o isa-timer.o
obj-$(CONFIG_ARCH_EBSA285) += ebsa285.o dc21285-timer.o
obj-$(CONFIG_ARCH_NETWINDER) += netwinder-hw.o isa-timer.o
obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal.o dc21285-timer.o
obj-$(CONFIG_PCI) +=$(pci-y)
obj-$(CONFIG_LEDS) +=$(leds-y)
obj-$(CONFIG_ISA) += isa.o isa-rtc.o

View File

@ -1,138 +0,0 @@
/*
* linux/arch/arm/mach-footbridge/ebsa285-leds.c
*
* Copyright (C) 1998-1999 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-285 control routines.
*
* The EBSA-285 uses the leds as follows:
* - Green - toggles state every 50 timer interrupts
* - Amber - On if system is not idle
* - Red - currently unused
*
* Changelog:
* 02-05-1999 RMK Various cleanups
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <mach/hardware.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#define LED_STATE_ENABLED 1
#define LED_STATE_CLAIMED 2
static char led_state;
static char hw_led_state;
static DEFINE_SPINLOCK(leds_lock);
static void ebsa285_leds_event(led_event_t evt)
{
unsigned long flags;
spin_lock_irqsave(&leds_lock, flags);
switch (evt) {
case led_start:
hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN;
#ifndef CONFIG_LEDS_CPU
hw_led_state |= XBUS_LED_AMBER;
#endif
led_state |= LED_STATE_ENABLED;
break;
case led_stop:
led_state &= ~LED_STATE_ENABLED;
break;
case led_claim:
led_state |= LED_STATE_CLAIMED;
hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN | XBUS_LED_AMBER;
break;
case led_release:
led_state &= ~LED_STATE_CLAIMED;
hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN | XBUS_LED_AMBER;
break;
#ifdef CONFIG_LEDS_TIMER
case led_timer:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state ^= XBUS_LED_GREEN;
break;
#endif
#ifdef CONFIG_LEDS_CPU
case led_idle_start:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state |= XBUS_LED_AMBER;
break;
case led_idle_end:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state &= ~XBUS_LED_AMBER;
break;
#endif
case led_halted:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state &= ~XBUS_LED_RED;
break;
case led_green_on:
if (led_state & LED_STATE_CLAIMED)
hw_led_state &= ~XBUS_LED_GREEN;
break;
case led_green_off:
if (led_state & LED_STATE_CLAIMED)
hw_led_state |= XBUS_LED_GREEN;
break;
case led_amber_on:
if (led_state & LED_STATE_CLAIMED)
hw_led_state &= ~XBUS_LED_AMBER;
break;
case led_amber_off:
if (led_state & LED_STATE_CLAIMED)
hw_led_state |= XBUS_LED_AMBER;
break;
case led_red_on:
if (led_state & LED_STATE_CLAIMED)
hw_led_state &= ~XBUS_LED_RED;
break;
case led_red_off:
if (led_state & LED_STATE_CLAIMED)
hw_led_state |= XBUS_LED_RED;
break;
default:
break;
}
if (led_state & LED_STATE_ENABLED)
*XBUS_LEDS = hw_led_state;
spin_unlock_irqrestore(&leds_lock, flags);
}
static int __init leds_init(void)
{
if (machine_is_ebsa285())
leds_event = ebsa285_leds_event;
leds_event(led_start);
return 0;
}
__initcall(leds_init);

View File

@ -5,6 +5,8 @@
*/
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/leds.h>
#include <asm/hardware/dec21285.h>
#include <asm/mach-types.h>
@ -13,6 +15,85 @@
#include "common.h"
/* LEDs */
#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
struct ebsa285_led {
struct led_classdev cdev;
u8 mask;
};
/*
* 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;
} ebsa285_leds[] = {
{ "ebsa285:amber", "heartbeat", },
{ "ebsa285:green", "cpu0", },
{ "ebsa285:red",},
};
static void ebsa285_led_set(struct led_classdev *cdev,
enum led_brightness b)
{
struct ebsa285_led *led = container_of(cdev,
struct ebsa285_led, cdev);
if (b != LED_OFF)
*XBUS_LEDS |= led->mask;
else
*XBUS_LEDS &= ~led->mask;
}
static enum led_brightness ebsa285_led_get(struct led_classdev *cdev)
{
struct ebsa285_led *led = container_of(cdev,
struct ebsa285_led, cdev);
return (*XBUS_LEDS & led->mask) ? LED_FULL : LED_OFF;
}
static int __init ebsa285_leds_init(void)
{
int i;
if (machine_is_ebsa285())
return -ENODEV;
/* 3 LEDS All ON */
*XBUS_LEDS |= XBUS_LED_AMBER | XBUS_LED_GREEN | XBUS_LED_RED;
for (i = 0; i < ARRAY_SIZE(ebsa285_leds); i++) {
struct ebsa285_led *led;
led = kzalloc(sizeof(*led), GFP_KERNEL);
if (!led)
break;
led->cdev.name = ebsa285_leds[i].name;
led->cdev.brightness_set = ebsa285_led_set;
led->cdev.brightness_get = ebsa285_led_get;
led->cdev.default_trigger = ebsa285_leds[i].trigger;
led->mask = BIT(i);
if (led_classdev_register(NULL, &led->cdev) < 0) {
kfree(led);
break;
}
}
return 0;
}
/*
* Since we may have triggers on any subsystem, defer registration
* until after subsystem_init.
*/
fs_initcall(ebsa285_leds_init);
#endif
MACHINE_START(EBSA285, "EBSA285")
/* Maintainer: Russell King */
.atag_offset = 0x100,

View File

@ -12,9 +12,10 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/leds.h>
#include <asm/hardware/dec21285.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/setup.h>
#include <asm/system_misc.h>
@ -27,13 +28,6 @@
#define GP1_IO_BASE 0x338
#define GP2_IO_BASE 0x33a
#ifdef CONFIG_LEDS
#define DEFAULT_LEDS 0
#else
#define DEFAULT_LEDS GPIO_GREEN_LED
#endif
/*
* Winbond WB83977F accessibility stuff
*/
@ -611,15 +605,9 @@ static void __init rwa010_init(void)
static int __init nw_hw_init(void)
{
if (machine_is_netwinder()) {
unsigned long flags;
wb977_init();
cpld_init();
rwa010_init();
raw_spin_lock_irqsave(&nw_gpio_lock, flags);
nw_gpio_modify_op(GPIO_RED_LED|GPIO_GREEN_LED, DEFAULT_LEDS);
raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
}
return 0;
}
@ -672,6 +660,102 @@ static void netwinder_restart(char mode, const char *cmd)
}
}
/* LEDs */
#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
struct netwinder_led {
struct led_classdev cdev;
u8 mask;
};
/*
* 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;
} netwinder_leds[] = {
{ "netwinder:green", "heartbeat", },
{ "netwinder:red", "cpu0", },
};
/*
* The LED control in Netwinder is reversed:
* - setting bit means turn off LED
* - clearing bit means turn on LED
*/
static void netwinder_led_set(struct led_classdev *cdev,
enum led_brightness b)
{
struct netwinder_led *led = container_of(cdev,
struct netwinder_led, cdev);
unsigned long flags;
u32 reg;
spin_lock_irqsave(&nw_gpio_lock, flags);
reg = nw_gpio_read();
if (b != LED_OFF)
reg &= ~led->mask;
else
reg |= led->mask;
nw_gpio_modify_op(led->mask, reg);
spin_unlock_irqrestore(&nw_gpio_lock, flags);
}
static enum led_brightness netwinder_led_get(struct led_classdev *cdev)
{
struct netwinder_led *led = container_of(cdev,
struct netwinder_led, cdev);
unsigned long flags;
u32 reg;
spin_lock_irqsave(&nw_gpio_lock, flags);
reg = nw_gpio_read();
spin_unlock_irqrestore(&nw_gpio_lock, flags);
return (reg & led->mask) ? LED_OFF : LED_FULL;
}
static int __init netwinder_leds_init(void)
{
int i;
if (!machine_is_netwinder())
return -ENODEV;
for (i = 0; i < ARRAY_SIZE(netwinder_leds); i++) {
struct netwinder_led *led;
led = kzalloc(sizeof(*led), GFP_KERNEL);
if (!led)
break;
led->cdev.name = netwinder_leds[i].name;
led->cdev.brightness_set = netwinder_led_set;
led->cdev.brightness_get = netwinder_led_get;
led->cdev.default_trigger = netwinder_leds[i].trigger;
if (i == 0)
led->mask = GPIO_GREEN_LED;
else
led->mask = GPIO_RED_LED;
if (led_classdev_register(NULL, &led->cdev) < 0) {
kfree(led);
break;
}
}
return 0;
}
/*
* Since we may have triggers on any subsystem, defer registration
* until after subsystem_init.
*/
fs_initcall(netwinder_leds_init);
#endif
MACHINE_START(NETWINDER, "Rebel-NetWinder")
/* Maintainer: Russell King/Rebel.com */
.atag_offset = 0x100,

View File

@ -1,138 +0,0 @@
/*
* linux/arch/arm/mach-footbridge/netwinder-leds.c
*
* Copyright (C) 1998-1999 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.
*
* NetWinder LED control routines.
*
* The Netwinder uses the leds as follows:
* - Green - toggles state every 50 timer interrupts
* - Red - On if the system is not idle
*
* Changelog:
* 02-05-1999 RMK Various cleanups
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <mach/hardware.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#define LED_STATE_ENABLED 1
#define LED_STATE_CLAIMED 2
static char led_state;
static char hw_led_state;
static DEFINE_RAW_SPINLOCK(leds_lock);
static void netwinder_leds_event(led_event_t evt)
{
unsigned long flags;
raw_spin_lock_irqsave(&leds_lock, flags);
switch (evt) {
case led_start:
led_state |= LED_STATE_ENABLED;
hw_led_state = GPIO_GREEN_LED;
break;
case led_stop:
led_state &= ~LED_STATE_ENABLED;
break;
case led_claim:
led_state |= LED_STATE_CLAIMED;
hw_led_state = 0;
break;
case led_release:
led_state &= ~LED_STATE_CLAIMED;
hw_led_state = 0;
break;
#ifdef CONFIG_LEDS_TIMER
case led_timer:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state ^= GPIO_GREEN_LED;
break;
#endif
#ifdef CONFIG_LEDS_CPU
case led_idle_start:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state &= ~GPIO_RED_LED;
break;
case led_idle_end:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state |= GPIO_RED_LED;
break;
#endif
case led_halted:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state |= GPIO_RED_LED;
break;
case led_green_on:
if (led_state & LED_STATE_CLAIMED)
hw_led_state |= GPIO_GREEN_LED;
break;
case led_green_off:
if (led_state & LED_STATE_CLAIMED)
hw_led_state &= ~GPIO_GREEN_LED;
break;
case led_amber_on:
if (led_state & LED_STATE_CLAIMED)
hw_led_state |= GPIO_GREEN_LED | GPIO_RED_LED;
break;
case led_amber_off:
if (led_state & LED_STATE_CLAIMED)
hw_led_state &= ~(GPIO_GREEN_LED | GPIO_RED_LED);
break;
case led_red_on:
if (led_state & LED_STATE_CLAIMED)
hw_led_state |= GPIO_RED_LED;
break;
case led_red_off:
if (led_state & LED_STATE_CLAIMED)
hw_led_state &= ~GPIO_RED_LED;
break;
default:
break;
}
raw_spin_unlock_irqrestore(&leds_lock, flags);
if (led_state & LED_STATE_ENABLED) {
raw_spin_lock_irqsave(&nw_gpio_lock, flags);
nw_gpio_modify_op(GPIO_RED_LED | GPIO_GREEN_LED, hw_led_state);
raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
}
}
static int __init leds_init(void)
{
if (machine_is_netwinder())
leds_event = netwinder_leds_event;
leds_event(led_start);
return 0;
}
__initcall(leds_init);

View File

@ -4,11 +4,10 @@
# Object file lists.
obj-y := core.o lm.o
obj-y := core.o lm.o leds.o
obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o
obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o
obj-$(CONFIG_LEDS) += leds.o
obj-$(CONFIG_PCI) += pci_v3.o pci.o
obj-$(CONFIG_CPU_FREQ_INTEGRATOR) += cpu.o
obj-$(CONFIG_INTEGRATOR_IMPD1) += impd1.o

View File

@ -27,7 +27,6 @@
#include <mach/cm.h>
#include <mach/irqs.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/mach/time.h>
#include <asm/pgtable.h>
@ -127,8 +126,6 @@ static struct amba_pl010_data integrator_uart_data = {
.set_mctrl = integrator_uart_set_mctrl,
};
#define CM_CTRL IO_ADDRESS(INTEGRATOR_HDR_CTRL)
static DEFINE_RAW_SPINLOCK(cm_lock);
/**

View File

@ -3,6 +3,8 @@
*/
void cm_control(u32, u32);
#define CM_CTRL IO_ADDRESS(INTEGRATOR_HDR_CTRL)
#define CM_CTRL_LED (1 << 0)
#define CM_CTRL_nMBDET (1 << 1)
#define CM_CTRL_REMAP (1 << 2)

View File

@ -1,90 +1,125 @@
/*
* linux/arch/arm/mach-integrator/leds.c
* Driver for the 4 user LEDs found on the Integrator AP/CP baseboard
* Based on Versatile and RealView machine LED code
*
* Integrator/AP and Integrator/CP LED control routines
*
* Copyright (C) 1999 ARM Limited
* Copyright (C) 2000 Deep Blue Solutions Ltd
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* License terms: GNU General Public License (GPL) version 2
* Author: Bryan Wu <bryan.wu@canonical.com>
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/leds.h>
#include <mach/cm.h>
#include <mach/hardware.h>
#include <mach/platform.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <mach/cm.h>
static int saved_leds;
#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
static void integrator_leds_event(led_event_t ledevt)
#define ALPHA_REG __io_address(INTEGRATOR_DBG_BASE)
#define LEDREG (__io_address(INTEGRATOR_DBG_BASE) + INTEGRATOR_DBG_LEDS_OFFSET)
struct integrator_led {
struct led_classdev cdev;
u8 mask;
};
/*
* 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;
} integrator_leds[] = {
{ "integrator:green0", "heartbeat", },
{ "integrator:yellow", },
{ "integrator:red", },
{ "integrator:green1", },
{ "integrator:core_module", "cpu0", },
};
static void integrator_led_set(struct led_classdev *cdev,
enum led_brightness b)
{
unsigned long flags;
const unsigned int dbg_base = IO_ADDRESS(INTEGRATOR_DBG_BASE);
unsigned int update_alpha_leds;
struct integrator_led *led = container_of(cdev,
struct integrator_led, cdev);
u32 reg = __raw_readl(LEDREG);
// yup, change the LEDs
local_irq_save(flags);
update_alpha_leds = 0;
if (b != LED_OFF)
reg |= led->mask;
else
reg &= ~led->mask;
switch(ledevt) {
case led_idle_start:
cm_control(CM_CTRL_LED, 0);
break;
while (__raw_readl(ALPHA_REG) & 1)
cpu_relax();
case led_idle_end:
cm_control(CM_CTRL_LED, CM_CTRL_LED);
break;
case led_timer:
saved_leds ^= GREEN_LED;
update_alpha_leds = 1;
break;
case led_red_on:
saved_leds |= RED_LED;
update_alpha_leds = 1;
break;
case led_red_off:
saved_leds &= ~RED_LED;
update_alpha_leds = 1;
break;
default:
break;
}
if (update_alpha_leds) {
while (__raw_readl(dbg_base + INTEGRATOR_DBG_ALPHA_OFFSET) & 1);
__raw_writel(saved_leds, dbg_base + INTEGRATOR_DBG_LEDS_OFFSET);
}
local_irq_restore(flags);
__raw_writel(reg, LEDREG);
}
static int __init leds_init(void)
static enum led_brightness integrator_led_get(struct led_classdev *cdev)
{
if (machine_is_integrator() || machine_is_cintegrator())
leds_event = integrator_leds_event;
struct integrator_led *led = container_of(cdev,
struct integrator_led, cdev);
u32 reg = __raw_readl(LEDREG);
return (reg & led->mask) ? LED_FULL : LED_OFF;
}
static void cm_led_set(struct led_classdev *cdev,
enum led_brightness b)
{
if (b != LED_OFF)
cm_control(CM_CTRL_LED, CM_CTRL_LED);
else
cm_control(CM_CTRL_LED, 0);
}
static enum led_brightness cm_led_get(struct led_classdev *cdev)
{
u32 reg = readl(CM_CTRL);
return (reg & CM_CTRL_LED) ? LED_FULL : LED_OFF;
}
static int __init integrator_leds_init(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(integrator_leds); i++) {
struct integrator_led *led;
led = kzalloc(sizeof(*led), GFP_KERNEL);
if (!led)
break;
led->cdev.name = integrator_leds[i].name;
if (i == 4) { /* Setting for LED in core module */
led->cdev.brightness_set = cm_led_set;
led->cdev.brightness_get = cm_led_get;
} else {
led->cdev.brightness_set = integrator_led_set;
led->cdev.brightness_get = integrator_led_get;
}
led->cdev.default_trigger = integrator_leds[i].trigger;
led->mask = BIT(i);
if (led_classdev_register(NULL, &led->cdev) < 0) {
kfree(led);
break;
}
}
return 0;
}
core_initcall(leds_init);
/*
* Since we may have triggers on any subsystem, defer registration
* until after subsystem_init.
*/
fs_initcall(integrator_leds_init);
#endif

View File

@ -11,9 +11,6 @@ obj- :=
# PCI support is optional
obj-$(CONFIG_PCI) += pci.o
# LEDs
obj-$(CONFIG_LEDS) += leds.o
# Board-specific support
obj-$(CONFIG_MACH_KS8695) += board-micrel.o
obj-$(CONFIG_MACH_DSM320) += board-dsm320.o

View File

@ -182,27 +182,6 @@ static void __init ks8695_add_device_watchdog(void)
}
/* --------------------------------------------------------------------
* LEDs
* -------------------------------------------------------------------- */
#if defined(CONFIG_LEDS)
short ks8695_leds_cpu = -1;
short ks8695_leds_timer = -1;
void __init ks8695_init_leds(u8 cpu_led, u8 timer_led)
{
/* Enable GPIO to access the LEDs */
gpio_direction_output(cpu_led, 1);
gpio_direction_output(timer_led, 1);
ks8695_leds_cpu = cpu_led;
ks8695_leds_timer = timer_led;
}
#else
void __init ks8695_init_leds(u8 cpu_led, u8 timer_led) {}
#endif
/* -------------------------------------------------------------------- */
/*

View File

@ -18,11 +18,6 @@ extern void __init ks8695_add_device_wan(void);
extern void __init ks8695_add_device_lan(void);
extern void __init ks8695_add_device_hpna(void);
/* LEDs */
extern short ks8695_leds_cpu;
extern short ks8695_leds_timer;
extern void __init ks8695_init_leds(u8 cpu_led, u8 timer_led);
/* PCI */
#define KS8695_MODE_PCI 0
#define KS8695_MODE_MINIPCI 1

View File

@ -1,92 +0,0 @@
/*
* LED driver for KS8695-based boards.
*
* Copyright (C) Andrew Victor
*
* 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.
*/
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <asm/leds.h>
#include <mach/devices.h>
static inline void ks8695_led_on(unsigned int led)
{
gpio_set_value(led, 0);
}
static inline void ks8695_led_off(unsigned int led)
{
gpio_set_value(led, 1);
}
static inline void ks8695_led_toggle(unsigned int led)
{
unsigned long is_off = gpio_get_value(led);
if (is_off)
ks8695_led_on(led);
else
ks8695_led_off(led);
}
/*
* Handle LED events.
*/
static void ks8695_leds_event(led_event_t evt)
{
unsigned long flags;
local_irq_save(flags);
switch(evt) {
case led_start: /* System startup */
ks8695_led_on(ks8695_leds_cpu);
break;
case led_stop: /* System stop / suspend */
ks8695_led_off(ks8695_leds_cpu);
break;
#ifdef CONFIG_LEDS_TIMER
case led_timer: /* Every 50 timer ticks */
ks8695_led_toggle(ks8695_leds_timer);
break;
#endif
#ifdef CONFIG_LEDS_CPU
case led_idle_start: /* Entering idle state */
ks8695_led_off(ks8695_leds_cpu);
break;
case led_idle_end: /* Exit idle state */
ks8695_led_on(ks8695_leds_cpu);
break;
#endif
default:
break;
}
local_irq_restore(flags);
}
static int __init leds_init(void)
{
if ((ks8695_leds_timer == -1) || (ks8695_leds_cpu == -1))
return -ENODEV;
leds_event = ks8695_leds_event;
leds_event(led_start);
return 0;
}
__initcall(leds_init);

View File

@ -61,14 +61,6 @@ obj-$(CONFIG_ARCH_OMAP850) += gpio7xx.o
obj-$(CONFIG_ARCH_OMAP15XX) += gpio15xx.o
obj-$(CONFIG_ARCH_OMAP16XX) += gpio16xx.o
# LEDs support
led-$(CONFIG_MACH_OMAP_H2) += leds-h2p2-debug.o
led-$(CONFIG_MACH_OMAP_H3) += leds-h2p2-debug.o
led-$(CONFIG_MACH_OMAP_INNOVATOR) += leds-innovator.o
led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o
led-$(CONFIG_MACH_OMAP_OSK) += leds-osk.o
obj-$(CONFIG_LEDS) += $(led-y)
ifneq ($(CONFIG_FB_OMAP),)
obj-y += lcd_dma.o
endif

View File

@ -31,6 +31,7 @@
#include <linux/i2c/tps65010.h>
#include <linux/smc91x.h>
#include <linux/omapfb.h>
#include <linux/leds.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@ -306,12 +307,39 @@ static struct platform_device h2_irda_device = {
.resource = h2_irda_resources,
};
static struct gpio_led h2_gpio_led_pins[] = {
{
.name = "h2:red",
.default_trigger = "heartbeat",
.gpio = 3,
},
{
.name = "h2:green",
.default_trigger = "cpu0",
.gpio = OMAP_MPUIO(4),
},
};
static struct gpio_led_platform_data h2_gpio_led_data = {
.leds = h2_gpio_led_pins,
.num_leds = ARRAY_SIZE(h2_gpio_led_pins),
};
static struct platform_device h2_gpio_leds = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &h2_gpio_led_data,
},
};
static struct platform_device *h2_devices[] __initdata = {
&h2_nor_device,
&h2_nand_device,
&h2_smc91x_device,
&h2_irda_device,
&h2_kp_device,
&h2_gpio_leds,
};
static void __init h2_init_smc91x(void)
@ -406,6 +434,10 @@ static void __init h2_init(void)
omap_cfg_reg(E19_1610_KBR4);
omap_cfg_reg(N19_1610_KBR5);
/* GPIO based LEDs */
omap_cfg_reg(P18_1610_GPIO3);
omap_cfg_reg(MPUIO4);
h2_smc91x_resources[1].start = gpio_to_irq(0);
h2_smc91x_resources[1].end = gpio_to_irq(0);
platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));

View File

@ -31,6 +31,7 @@
#include <linux/i2c/tps65010.h>
#include <linux/smc91x.h>
#include <linux/omapfb.h>
#include <linux/leds.h>
#include <asm/setup.h>
#include <asm/page.h>
@ -324,6 +325,32 @@ static struct spi_board_info h3_spi_board_info[] __initdata = {
},
};
static struct gpio_led h3_gpio_led_pins[] = {
{
.name = "h3:red",
.default_trigger = "heartbeat",
.gpio = 3,
},
{
.name = "h3:green",
.default_trigger = "cpu0",
.gpio = OMAP_MPUIO(4),
},
};
static struct gpio_led_platform_data h3_gpio_led_data = {
.leds = h3_gpio_led_pins,
.num_leds = ARRAY_SIZE(h3_gpio_led_pins),
};
static struct platform_device h3_gpio_leds = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &h3_gpio_led_data,
},
};
static struct platform_device *devices[] __initdata = {
&nor_device,
&nand_device,
@ -331,6 +358,7 @@ static struct platform_device *devices[] __initdata = {
&intlat_device,
&h3_kp_device,
&h3_lcd_device,
&h3_gpio_leds,
};
static struct omap_usb_config h3_usb_config __initdata = {
@ -398,6 +426,10 @@ static void __init h3_init(void)
omap_cfg_reg(E19_1610_KBR4);
omap_cfg_reg(N19_1610_KBR5);
/* GPIO based LEDs */
omap_cfg_reg(P18_1610_GPIO3);
omap_cfg_reg(MPUIO4);
smc91x_resources[1].start = gpio_to_irq(40);
smc91x_resources[1].end = gpio_to_irq(40);
platform_add_devices(devices, ARRAY_SIZE(devices));

View File

@ -380,10 +380,37 @@ static struct platform_device osk5912_lcd_device = {
.id = -1,
};
static struct gpio_led mistral_gpio_led_pins[] = {
{
.name = "mistral:red",
.default_trigger = "heartbeat",
.gpio = 3,
},
{
.name = "mistral:green",
.default_trigger = "cpu0",
.gpio = OMAP_MPUIO(4),
},
};
static struct gpio_led_platform_data mistral_gpio_led_data = {
.leds = mistral_gpio_led_pins,
.num_leds = ARRAY_SIZE(mistral_gpio_led_pins),
};
static struct platform_device mistral_gpio_leds = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &mistral_gpio_led_data,
},
};
static struct platform_device *mistral_devices[] __initdata = {
&osk5912_kp_device,
&mistral_bl_device,
&osk5912_lcd_device,
&mistral_gpio_leds,
};
static int mistral_get_pendown_state(void)
@ -508,6 +535,12 @@ static void __init osk_mistral_init(void)
if (gpio_request(2, "lcd_pwr") == 0)
gpio_direction_output(2, 1);
/*
* GPIO based LEDs
*/
omap_cfg_reg(P18_1610_GPIO3);
omap_cfg_reg(MPUIO4);
i2c_register_board_info(1, mistral_i2c_board_info,
ARRAY_SIZE(mistral_i2c_board_info));

View File

@ -1,166 +0,0 @@
/*
* linux/arch/arm/mach-omap1/leds-h2p2-debug.c
*
* Copyright 2003 by Texas Instruments Incorporated
*
* There are 16 LEDs on the debug board (all green); four may be used
* for logical 'green', 'amber', 'red', and 'blue' (after "claiming").
*
* The "surfer" expansion board and H2 sample board also have two-color
* green+red LEDs (in parallel), used here for timer and idle indicators.
*/
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/sched.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <plat/fpga.h>
#include "leds.h"
#define GPIO_LED_RED 3
#define GPIO_LED_GREEN OMAP_MPUIO(4)
#define LED_STATE_ENABLED 0x01
#define LED_STATE_CLAIMED 0x02
#define LED_TIMER_ON 0x04
#define GPIO_IDLE GPIO_LED_GREEN
#define GPIO_TIMER GPIO_LED_RED
void h2p2_dbg_leds_event(led_event_t evt)
{
unsigned long flags;
static struct h2p2_dbg_fpga __iomem *fpga;
static u16 led_state, hw_led_state;
local_irq_save(flags);
if (!(led_state & LED_STATE_ENABLED) && evt != led_start)
goto done;
switch (evt) {
case led_start:
if (!fpga)
fpga = ioremap(H2P2_DBG_FPGA_START,
H2P2_DBG_FPGA_SIZE);
if (fpga) {
led_state |= LED_STATE_ENABLED;
__raw_writew(~0, &fpga->leds);
}
break;
case led_stop:
case led_halted:
/* all leds off during suspend or shutdown */
if (! machine_is_omap_perseus2()) {
gpio_set_value(GPIO_TIMER, 0);
gpio_set_value(GPIO_IDLE, 0);
}
__raw_writew(~0, &fpga->leds);
led_state &= ~LED_STATE_ENABLED;
if (evt == led_halted) {
iounmap(fpga);
fpga = NULL;
}
goto done;
case led_claim:
led_state |= LED_STATE_CLAIMED;
hw_led_state = 0;
break;
case led_release:
led_state &= ~LED_STATE_CLAIMED;
break;
#ifdef CONFIG_LEDS_TIMER
case led_timer:
led_state ^= LED_TIMER_ON;
if (machine_is_omap_perseus2())
hw_led_state ^= H2P2_DBG_FPGA_P2_LED_TIMER;
else {
gpio_set_value(GPIO_TIMER, led_state & LED_TIMER_ON);
goto done;
}
break;
#endif
#ifdef CONFIG_LEDS_CPU
case led_idle_start:
if (machine_is_omap_perseus2())
hw_led_state |= H2P2_DBG_FPGA_P2_LED_IDLE;
else {
gpio_set_value(GPIO_IDLE, 1);
goto done;
}
break;
case led_idle_end:
if (machine_is_omap_perseus2())
hw_led_state &= ~H2P2_DBG_FPGA_P2_LED_IDLE;
else {
gpio_set_value(GPIO_IDLE, 0);
goto done;
}
break;
#endif
case led_green_on:
hw_led_state |= H2P2_DBG_FPGA_LED_GREEN;
break;
case led_green_off:
hw_led_state &= ~H2P2_DBG_FPGA_LED_GREEN;
break;
case led_amber_on:
hw_led_state |= H2P2_DBG_FPGA_LED_AMBER;
break;
case led_amber_off:
hw_led_state &= ~H2P2_DBG_FPGA_LED_AMBER;
break;
case led_red_on:
hw_led_state |= H2P2_DBG_FPGA_LED_RED;
break;
case led_red_off:
hw_led_state &= ~H2P2_DBG_FPGA_LED_RED;
break;
case led_blue_on:
hw_led_state |= H2P2_DBG_FPGA_LED_BLUE;
break;
case led_blue_off:
hw_led_state &= ~H2P2_DBG_FPGA_LED_BLUE;
break;
default:
break;
}
/*
* Actually burn the LEDs
*/
if (led_state & LED_STATE_ENABLED)
__raw_writew(~hw_led_state, &fpga->leds);
done:
local_irq_restore(flags);
}

View File

@ -1,98 +0,0 @@
/*
* linux/arch/arm/mach-omap1/leds-innovator.c
*/
#include <linux/init.h>
#include <mach/hardware.h>
#include <asm/leds.h>
#include "leds.h"
#define LED_STATE_ENABLED 1
#define LED_STATE_CLAIMED 2
static unsigned int led_state;
static unsigned int hw_led_state;
void innovator_leds_event(led_event_t evt)
{
unsigned long flags;
local_irq_save(flags);
switch (evt) {
case led_start:
hw_led_state = 0;
led_state = LED_STATE_ENABLED;
break;
case led_stop:
led_state &= ~LED_STATE_ENABLED;
hw_led_state = 0;
break;
case led_claim:
led_state |= LED_STATE_CLAIMED;
hw_led_state = 0;
break;
case led_release:
led_state &= ~LED_STATE_CLAIMED;
hw_led_state = 0;
break;
#ifdef CONFIG_LEDS_TIMER
case led_timer:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state ^= 0;
break;
#endif
#ifdef CONFIG_LEDS_CPU
case led_idle_start:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state |= 0;
break;
case led_idle_end:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state &= ~0;
break;
#endif
case led_halted:
break;
case led_green_on:
if (led_state & LED_STATE_CLAIMED)
hw_led_state &= ~0;
break;
case led_green_off:
if (led_state & LED_STATE_CLAIMED)
hw_led_state |= 0;
break;
case led_amber_on:
break;
case led_amber_off:
break;
case led_red_on:
if (led_state & LED_STATE_CLAIMED)
hw_led_state &= ~0;
break;
case led_red_off:
if (led_state & LED_STATE_CLAIMED)
hw_led_state |= 0;
break;
default:
break;
}
local_irq_restore(flags);
}

View File

@ -1,113 +0,0 @@
/*
* linux/arch/arm/mach-omap1/leds-osk.c
*
* LED driver for OSK with optional Mistral QVGA board
*/
#include <linux/gpio.h>
#include <linux/init.h>
#include <mach/hardware.h>
#include <asm/leds.h>
#include "leds.h"
#define LED_STATE_ENABLED (1 << 0)
#define LED_STATE_CLAIMED (1 << 1)
static u8 led_state;
#define TIMER_LED (1 << 3) /* Mistral board */
#define IDLE_LED (1 << 4) /* Mistral board */
static u8 hw_led_state;
#ifdef CONFIG_OMAP_OSK_MISTRAL
/* For now, all system indicators require the Mistral board, since that
* LED can be manipulated without a task context. This LED is either red,
* or green, but not both; it can't give the full "disco led" effect.
*/
#define GPIO_LED_RED 3
#define GPIO_LED_GREEN OMAP_MPUIO(4)
static void mistral_setled(void)
{
int red = 0;
int green = 0;
if (hw_led_state & TIMER_LED)
red = 1;
else if (hw_led_state & IDLE_LED)
green = 1;
/* else both sides are disabled */
gpio_set_value(GPIO_LED_GREEN, green);
gpio_set_value(GPIO_LED_RED, red);
}
#endif
void osk_leds_event(led_event_t evt)
{
unsigned long flags;
u16 leds;
local_irq_save(flags);
if (!(led_state & LED_STATE_ENABLED) && evt != led_start)
goto done;
leds = hw_led_state;
switch (evt) {
case led_start:
led_state |= LED_STATE_ENABLED;
hw_led_state = 0;
leds = ~0;
break;
case led_halted:
case led_stop:
led_state &= ~LED_STATE_ENABLED;
hw_led_state = 0;
break;
case led_claim:
led_state |= LED_STATE_CLAIMED;
hw_led_state = 0;
leds = ~0;
break;
case led_release:
led_state &= ~LED_STATE_CLAIMED;
hw_led_state = 0;
break;
#ifdef CONFIG_OMAP_OSK_MISTRAL
case led_timer:
hw_led_state ^= TIMER_LED;
mistral_setled();
break;
case led_idle_start: /* idle == off */
hw_led_state &= ~IDLE_LED;
mistral_setled();
break;
case led_idle_end:
hw_led_state |= IDLE_LED;
mistral_setled();
break;
#endif /* CONFIG_OMAP_OSK_MISTRAL */
default:
break;
}
leds ^= hw_led_state;
done:
local_irq_restore(flags);
}

View File

@ -1,69 +0,0 @@
/*
* linux/arch/arm/mach-omap1/leds.c
*
* OMAP LEDs dispatcher
*/
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <plat/mux.h>
#include "leds.h"
static int __init
omap_leds_init(void)
{
if (!cpu_class_is_omap1())
return -ENODEV;
if (machine_is_omap_innovator())
leds_event = innovator_leds_event;
else if (machine_is_omap_h2()
|| machine_is_omap_h3()
|| machine_is_omap_perseus2())
leds_event = h2p2_dbg_leds_event;
else if (machine_is_omap_osk())
leds_event = osk_leds_event;
else
return -1;
if (machine_is_omap_h2()
|| machine_is_omap_h3()
#ifdef CONFIG_OMAP_OSK_MISTRAL
|| machine_is_omap_osk()
#endif
) {
/* LED1/LED2 pins can be used as GPIO (as done here), or by
* the LPG (works even in deep sleep!), to drive a bicolor
* LED on the H2 sample board, and another on the H2/P2
* "surfer" expansion board.
*
* The same pins drive a LED on the OSK Mistral board, but
* that's a different kind of LED (just one color at a time).
*/
omap_cfg_reg(P18_1610_GPIO3);
if (gpio_request(3, "LED red") == 0)
gpio_direction_output(3, 1);
else
printk(KERN_WARNING "LED: can't get GPIO3/red?\n");
omap_cfg_reg(MPUIO4);
if (gpio_request(OMAP_MPUIO(4), "LED green") == 0)
gpio_direction_output(OMAP_MPUIO(4), 1);
else
printk(KERN_WARNING "LED: can't get MPUIO4/green?\n");
}
leds_event(led_start);
return 0;
}
__initcall(omap_leds_init);

View File

@ -1,3 +0,0 @@
extern void innovator_leds_event(led_event_t evt);
extern void h2p2_dbg_leds_event(led_event_t evt);
extern void osk_leds_event(led_event_t evt);

View File

@ -44,7 +44,6 @@
#include <linux/clockchips.h>
#include <linux/io.h>
#include <asm/leds.h>
#include <asm/irq.h>
#include <asm/sched_clock.h>

View File

@ -46,7 +46,6 @@
#include <linux/clockchips.h>
#include <linux/io.h>
#include <asm/leds.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>

View File

@ -18,7 +18,6 @@
#include <linux/ethtool.h>
#include <net/dsa.h>
#include <asm/mach-types.h>
#include <asm/leds.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
#include <mach/orion5x.h>

View File

@ -19,7 +19,6 @@
#include <linux/i2c.h>
#include <net/dsa.h>
#include <asm/mach-types.h>
#include <asm/leds.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
#include <mach/orion5x.h>

View File

@ -19,8 +19,8 @@
#include <linux/mv643xx_eth.h>
#include <linux/ata_platform.h>
#include <linux/i2c.h>
#include <linux/leds.h>
#include <asm/mach-types.h>
#include <asm/leds.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
#include <mach/orion5x.h>
@ -53,12 +53,6 @@
#define RD88F5182_PCI_SLOT0_IRQ_A_PIN 7
#define RD88F5182_PCI_SLOT0_IRQ_B_PIN 6
/*
* GPIO Debug LED
*/
#define RD88F5182_GPIO_DBG_LED 0
/*****************************************************************************
* 16M NOR Flash on Device bus CS1
****************************************************************************/
@ -83,55 +77,32 @@ static struct platform_device rd88f5182_nor_flash = {
.resource = &rd88f5182_nor_flash_resource,
};
#ifdef CONFIG_LEDS
/*****************************************************************************
* Use GPIO debug led as CPU active indication
* Use GPIO LED as CPU active indication
****************************************************************************/
static void rd88f5182_dbgled_event(led_event_t evt)
{
int val;
#define RD88F5182_GPIO_LED 0
if (evt == led_idle_end)
val = 1;
else if (evt == led_idle_start)
val = 0;
else
return;
static struct gpio_led rd88f5182_gpio_led_pins[] = {
{
.name = "rd88f5182:cpu",
.default_trigger = "cpu0",
.gpio = RD88F5182_GPIO_LED,
},
};
gpio_set_value(RD88F5182_GPIO_DBG_LED, val);
}
static struct gpio_led_platform_data rd88f5182_gpio_led_data = {
.leds = rd88f5182_gpio_led_pins,
.num_leds = ARRAY_SIZE(rd88f5182_gpio_led_pins),
};
static int __init rd88f5182_dbgled_init(void)
{
int pin;
if (machine_is_rd88f5182()) {
pin = RD88F5182_GPIO_DBG_LED;
if (gpio_request(pin, "DBGLED") == 0) {
if (gpio_direction_output(pin, 0) != 0) {
printk(KERN_ERR "rd88f5182_dbgled_init failed "
"to set output pin %d\n", pin);
gpio_free(pin);
return 0;
}
} else {
printk(KERN_ERR "rd88f5182_dbgled_init failed "
"to request gpio %d\n", pin);
return 0;
}
leds_event = rd88f5182_dbgled_event;
}
return 0;
}
__initcall(rd88f5182_dbgled_init);
#endif
static struct platform_device rd88f5182_gpio_leds = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &rd88f5182_gpio_led_data,
},
};
/*****************************************************************************
* PCI
@ -298,6 +269,7 @@ static void __init rd88f5182_init(void)
orion5x_setup_dev1_win(RD88F5182_NOR_BASE, RD88F5182_NOR_SIZE);
platform_device_register(&rd88f5182_nor_flash);
platform_device_register(&rd88f5182_gpio_leds);
i2c_register_board_info(0, &rd88f5182_i2c_rtc, 1);
}

View File

@ -20,7 +20,6 @@
#include <linux/ethtool.h>
#include <net/dsa.h>
#include <asm/mach-types.h>
#include <asm/leds.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
#include <mach/orion5x.h>

View File

@ -25,7 +25,6 @@
#include <linux/io.h>
#include <mach/hardware.h>
#include <asm/leds.h>
#include <asm/mach/time.h>
#include <asm/errno.h>

View File

@ -95,12 +95,4 @@ obj-$(CONFIG_MACH_RAUMFELD_CONNECTOR) += raumfeld.o
obj-$(CONFIG_MACH_RAUMFELD_SPEAKER) += raumfeld.o
obj-$(CONFIG_MACH_ZIPIT2) += z2.o
# Support for blinky lights
led-y := leds.o
led-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o
led-$(CONFIG_MACH_MAINSTONE) += leds-mainstone.o
led-$(CONFIG_ARCH_PXA_IDP) += leds-idp.o
obj-$(CONFIG_LEDS) += $(led-y)
obj-$(CONFIG_TOSA_BT) += tosa-bt.o

View File

@ -191,6 +191,87 @@ static void __init idp_map_io(void)
iotable_init(idp_io_desc, ARRAY_SIZE(idp_io_desc));
}
/* LEDs */
#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
struct idp_led {
struct led_classdev cdev;
u8 mask;
};
/*
* 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;
} idp_leds[] = {
{ "idp:green", "heartbeat", },
{ "idp:red", "cpu0", },
};
static void idp_led_set(struct led_classdev *cdev,
enum led_brightness b)
{
struct idp_led *led = container_of(cdev,
struct idp_led, cdev);
u32 reg = IDP_CPLD_LED_CONTROL;
if (b != LED_OFF)
reg &= ~led->mask;
else
reg |= led->mask;
IDP_CPLD_LED_CONTROL = reg;
}
static enum led_brightness idp_led_get(struct led_classdev *cdev)
{
struct idp_led *led = container_of(cdev,
struct idp_led, cdev);
return (IDP_CPLD_LED_CONTROL & led->mask) ? LED_OFF : LED_FULL;
}
static int __init idp_leds_init(void)
{
int i;
if (!machine_is_pxa_idp())
return -ENODEV;
for (i = 0; i < ARRAY_SIZE(idp_leds); i++) {
struct idp_led *led;
led = kzalloc(sizeof(*led), GFP_KERNEL);
if (!led)
break;
led->cdev.name = idp_leds[i].name;
led->cdev.brightness_set = idp_led_set;
led->cdev.brightness_get = idp_led_get;
led->cdev.default_trigger = idp_leds[i].trigger;
if (i == 0)
led->mask = IDP_HB_LED;
else
led->mask = IDP_BUSY_LED;
if (led_classdev_register(NULL, &led->cdev) < 0) {
kfree(led);
break;
}
}
return 0;
}
/*
* Since we may have triggers on any subsystem, defer registration
* until after subsystem_init.
*/
fs_initcall(idp_leds_init);
#endif
MACHINE_START(PXA_IDP, "Vibren PXA255 IDP")
/* Maintainer: Vibren Technologies */

View File

@ -1,115 +0,0 @@
/*
* linux/arch/arm/mach-pxa/leds-idp.c
*
* Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu>
*
* Copyright (c) 2001 Jeff Sutherland <jeffs@accelent.com>
*
* Original (leds-footbridge.c) by Russell King
*
* Macros for actual LED manipulation should be in machine specific
* files in this 'mach' directory.
*/
#include <linux/init.h>
#include <mach/hardware.h>
#include <asm/leds.h>
#include <mach/pxa25x.h>
#include <mach/idp.h>
#include "leds.h"
#define LED_STATE_ENABLED 1
#define LED_STATE_CLAIMED 2
static unsigned int led_state;
static unsigned int hw_led_state;
void idp_leds_event(led_event_t evt)
{
unsigned long flags;
local_irq_save(flags);
switch (evt) {
case led_start:
hw_led_state = IDP_HB_LED | IDP_BUSY_LED;
led_state = LED_STATE_ENABLED;
break;
case led_stop:
led_state &= ~LED_STATE_ENABLED;
break;
case led_claim:
led_state |= LED_STATE_CLAIMED;
hw_led_state = IDP_HB_LED | IDP_BUSY_LED;
break;
case led_release:
led_state &= ~LED_STATE_CLAIMED;
hw_led_state = IDP_HB_LED | IDP_BUSY_LED;
break;
#ifdef CONFIG_LEDS_TIMER
case led_timer:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state ^= IDP_HB_LED;
break;
#endif
#ifdef CONFIG_LEDS_CPU
case led_idle_start:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state &= ~IDP_BUSY_LED;
break;
case led_idle_end:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state |= IDP_BUSY_LED;
break;
#endif
case led_halted:
break;
case led_green_on:
if (led_state & LED_STATE_CLAIMED)
hw_led_state |= IDP_HB_LED;
break;
case led_green_off:
if (led_state & LED_STATE_CLAIMED)
hw_led_state &= ~IDP_HB_LED;
break;
case led_amber_on:
break;
case led_amber_off:
break;
case led_red_on:
if (led_state & LED_STATE_CLAIMED)
hw_led_state |= IDP_BUSY_LED;
break;
case led_red_off:
if (led_state & LED_STATE_CLAIMED)
hw_led_state &= ~IDP_BUSY_LED;
break;
default:
break;
}
if (led_state & LED_STATE_ENABLED)
IDP_CPLD_LED_CONTROL = ( (IDP_CPLD_LED_CONTROL | IDP_LEDS_MASK) & ~hw_led_state);
else
IDP_CPLD_LED_CONTROL |= IDP_LEDS_MASK;
local_irq_restore(flags);
}

View File

@ -1,124 +0,0 @@
/*
* linux/arch/arm/mach-pxa/leds-lubbock.c
*
* Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu>
*
* Copyright (c) 2001 Jeff Sutherland <jeffs@accelent.com>
*
* Original (leds-footbridge.c) by Russell King
*
* Major surgery on April 2004 by Nicolas Pitre for less global
* namespace collision. Mostly adapted the Mainstone version.
*/
#include <linux/init.h>
#include <mach/hardware.h>
#include <asm/leds.h>
#include <mach/pxa25x.h>
#include <mach/lubbock.h>
#include "leds.h"
/*
* 8 discrete leds available for general use:
*
* Note: bits [15-8] are used to enable/blank the 8 7 segment hex displays
* so be sure to not monkey with them here.
*/
#define D28 (1 << 0)
#define D27 (1 << 1)
#define D26 (1 << 2)
#define D25 (1 << 3)
#define D24 (1 << 4)
#define D23 (1 << 5)
#define D22 (1 << 6)
#define D21 (1 << 7)
#define LED_STATE_ENABLED 1
#define LED_STATE_CLAIMED 2
static unsigned int led_state;
static unsigned int hw_led_state;
void lubbock_leds_event(led_event_t evt)
{
unsigned long flags;
local_irq_save(flags);
switch (evt) {
case led_start:
hw_led_state = 0;
led_state = LED_STATE_ENABLED;
break;
case led_stop:
led_state &= ~LED_STATE_ENABLED;
break;
case led_claim:
led_state |= LED_STATE_CLAIMED;
hw_led_state = 0;
break;
case led_release:
led_state &= ~LED_STATE_CLAIMED;
hw_led_state = 0;
break;
#ifdef CONFIG_LEDS_TIMER
case led_timer:
hw_led_state ^= D26;
break;
#endif
#ifdef CONFIG_LEDS_CPU
case led_idle_start:
hw_led_state &= ~D27;
break;
case led_idle_end:
hw_led_state |= D27;
break;
#endif
case led_halted:
break;
case led_green_on:
hw_led_state |= D21;
break;
case led_green_off:
hw_led_state &= ~D21;
break;
case led_amber_on:
hw_led_state |= D22;
break;
case led_amber_off:
hw_led_state &= ~D22;
break;
case led_red_on:
hw_led_state |= D23;
break;
case led_red_off:
hw_led_state &= ~D23;
break;
default:
break;
}
if (led_state & LED_STATE_ENABLED)
LUB_DISC_BLNK_LED = (LUB_DISC_BLNK_LED | 0xff) & ~hw_led_state;
else
LUB_DISC_BLNK_LED |= 0xff;
local_irq_restore(flags);
}

View File

@ -1,119 +0,0 @@
/*
* linux/arch/arm/mach-pxa/leds-mainstone.c
*
* Author: Nicolas Pitre
* Created: Nov 05, 2002
* Copyright: MontaVista Software Inc.
*
* 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.
*/
#include <linux/init.h>
#include <mach/hardware.h>
#include <asm/leds.h>
#include <mach/pxa27x.h>
#include <mach/mainstone.h>
#include "leds.h"
/* 8 discrete leds available for general use: */
#define D28 (1 << 0)
#define D27 (1 << 1)
#define D26 (1 << 2)
#define D25 (1 << 3)
#define D24 (1 << 4)
#define D23 (1 << 5)
#define D22 (1 << 6)
#define D21 (1 << 7)
#define LED_STATE_ENABLED 1
#define LED_STATE_CLAIMED 2
static unsigned int led_state;
static unsigned int hw_led_state;
void mainstone_leds_event(led_event_t evt)
{
unsigned long flags;
local_irq_save(flags);
switch (evt) {
case led_start:
hw_led_state = 0;
led_state = LED_STATE_ENABLED;
break;
case led_stop:
led_state &= ~LED_STATE_ENABLED;
break;
case led_claim:
led_state |= LED_STATE_CLAIMED;
hw_led_state = 0;
break;
case led_release:
led_state &= ~LED_STATE_CLAIMED;
hw_led_state = 0;
break;
#ifdef CONFIG_LEDS_TIMER
case led_timer:
hw_led_state ^= D26;
break;
#endif
#ifdef CONFIG_LEDS_CPU
case led_idle_start:
hw_led_state &= ~D27;
break;
case led_idle_end:
hw_led_state |= D27;
break;
#endif
case led_halted:
break;
case led_green_on:
hw_led_state |= D21;
break;
case led_green_off:
hw_led_state &= ~D21;
break;
case led_amber_on:
hw_led_state |= D22;
break;
case led_amber_off:
hw_led_state &= ~D22;
break;
case led_red_on:
hw_led_state |= D23;
break;
case led_red_off:
hw_led_state &= ~D23;
break;
default:
break;
}
if (led_state & LED_STATE_ENABLED)
MST_LEDCTRL = (MST_LEDCTRL | 0xff) & ~hw_led_state;
else
MST_LEDCTRL |= 0xff;
local_irq_restore(flags);
}

View File

@ -1,32 +0,0 @@
/*
* linux/arch/arm/mach-pxa/leds.c
*
* xscale LEDs dispatcher
*
* Copyright (C) 2001 Nicolas Pitre
*
* Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc.
*/
#include <linux/compiler.h>
#include <linux/init.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include "leds.h"
static int __init
pxa_leds_init(void)
{
if (machine_is_lubbock())
leds_event = lubbock_leds_event;
if (machine_is_mainstone())
leds_event = mainstone_leds_event;
if (machine_is_pxa_idp())
leds_event = idp_leds_event;
leds_event(led_start);
return 0;
}
core_initcall(pxa_leds_init);

View File

@ -1,13 +0,0 @@
/*
* arch/arm/mach-pxa/leds.h
*
* Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc.
*
* blinky lights for various PXA-based systems:
*
*/
extern void idp_leds_event(led_event_t evt);
extern void lubbock_leds_event(led_event_t evt);
extern void mainstone_leds_event(led_event_t evt);
extern void trizeps4_leds_event(led_event_t evt);

View File

@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/syscore_ops.h>
#include <linux/major.h>
@ -23,6 +24,8 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/smc91x.h>
#include <linux/slab.h>
#include <linux/leds.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
@ -549,6 +552,98 @@ static void __init lubbock_map_io(void)
PCFR |= PCFR_OPDE;
}
/*
* Driver for the 8 discrete LEDs available for general use:
* Note: bits [15-8] are used to enable/blank the 8 7 segment hex displays
* so be sure to not monkey with them here.
*/
#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
struct lubbock_led {
struct led_classdev cdev;
u8 mask;
};
/*
* 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;
} lubbock_leds[] = {
{ "lubbock:D28", "default-on", },
{ "lubbock:D27", "cpu0", },
{ "lubbock:D26", "heartbeat" },
{ "lubbock:D25", },
{ "lubbock:D24", },
{ "lubbock:D23", },
{ "lubbock:D22", },
{ "lubbock:D21", },
};
static void lubbock_led_set(struct led_classdev *cdev,
enum led_brightness b)
{
struct lubbock_led *led = container_of(cdev,
struct lubbock_led, cdev);
u32 reg = LUB_DISC_BLNK_LED;
if (b != LED_OFF)
reg |= led->mask;
else
reg &= ~led->mask;
LUB_DISC_BLNK_LED = reg;
}
static enum led_brightness lubbock_led_get(struct led_classdev *cdev)
{
struct lubbock_led *led = container_of(cdev,
struct lubbock_led, cdev);
u32 reg = LUB_DISC_BLNK_LED;
return (reg & led->mask) ? LED_FULL : LED_OFF;
}
static int __init lubbock_leds_init(void)
{
int i;
if (!machine_is_lubbock())
return -ENODEV;
/* All ON */
LUB_DISC_BLNK_LED |= 0xff;
for (i = 0; i < ARRAY_SIZE(lubbock_leds); i++) {
struct lubbock_led *led;
led = kzalloc(sizeof(*led), GFP_KERNEL);
if (!led)
break;
led->cdev.name = lubbock_leds[i].name;
led->cdev.brightness_set = lubbock_led_set;
led->cdev.brightness_get = lubbock_led_get;
led->cdev.default_trigger = lubbock_leds[i].trigger;
led->mask = BIT(i);
if (led_classdev_register(NULL, &led->cdev) < 0) {
kfree(led);
break;
}
}
return 0;
}
/*
* Since we may have triggers on any subsystem, defer registration
* until after subsystem_init.
*/
fs_initcall(lubbock_leds_init);
#endif
MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)")
/* Maintainer: MontaVista Software Inc. */
.map_io = lubbock_map_io,

View File

@ -28,6 +28,8 @@
#include <linux/pwm_backlight.h>
#include <linux/smc91x.h>
#include <linux/i2c/pxa-i2c.h>
#include <linux/slab.h>
#include <linux/leds.h>
#include <asm/types.h>
#include <asm/setup.h>
@ -613,6 +615,98 @@ static void __init mainstone_map_io(void)
PCFR = 0x66;
}
/*
* Driver for the 8 discrete LEDs available for general use:
* Note: bits [15-8] are used to enable/blank the 8 7 segment hex displays
* so be sure to not monkey with them here.
*/
#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
struct mainstone_led {
struct led_classdev cdev;
u8 mask;
};
/*
* 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;
} mainstone_leds[] = {
{ "mainstone:D28", "default-on", },
{ "mainstone:D27", "cpu0", },
{ "mainstone:D26", "heartbeat" },
{ "mainstone:D25", },
{ "mainstone:D24", },
{ "mainstone:D23", },
{ "mainstone:D22", },
{ "mainstone:D21", },
};
static void mainstone_led_set(struct led_classdev *cdev,
enum led_brightness b)
{
struct mainstone_led *led = container_of(cdev,
struct mainstone_led, cdev);
u32 reg = MST_LEDCTRL;
if (b != LED_OFF)
reg |= led->mask;
else
reg &= ~led->mask;
MST_LEDCTRL = reg;
}
static enum led_brightness mainstone_led_get(struct led_classdev *cdev)
{
struct mainstone_led *led = container_of(cdev,
struct mainstone_led, cdev);
u32 reg = MST_LEDCTRL;
return (reg & led->mask) ? LED_FULL : LED_OFF;
}
static int __init mainstone_leds_init(void)
{
int i;
if (!machine_is_mainstone())
return -ENODEV;
/* All ON */
MST_LEDCTRL |= 0xff;
for (i = 0; i < ARRAY_SIZE(mainstone_leds); i++) {
struct mainstone_led *led;
led = kzalloc(sizeof(*led), GFP_KERNEL);
if (!led)
break;
led->cdev.name = mainstone_leds[i].name;
led->cdev.brightness_set = mainstone_led_set;
led->cdev.brightness_get = mainstone_led_get;
led->cdev.default_trigger = mainstone_leds[i].trigger;
led->mask = BIT(i);
if (led_classdev_register(NULL, &led->cdev) < 0) {
kfree(led);
break;
}
}
return 0;
}
/*
* Since we may have triggers on any subsystem, defer registration
* until after subsystem_init.
*/
fs_initcall(mainstone_leds_init);
#endif
MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
/* Maintainer: MontaVista Software Inc. */
.atag_offset = 0x100, /* BLOB boot parameter setting */

View File

@ -35,7 +35,6 @@
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/hardware/arm_timer.h>
#include <asm/hardware/icst.h>
@ -436,44 +435,6 @@ struct clcd_board clcd_plat_data = {
.remove = versatile_clcd_remove_dma,
};
#ifdef CONFIG_LEDS
#define VA_LEDS_BASE (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LED_OFFSET)
void realview_leds_event(led_event_t ledevt)
{
unsigned long flags;
u32 val;
u32 led = 1 << smp_processor_id();
local_irq_save(flags);
val = readl(VA_LEDS_BASE);
switch (ledevt) {
case led_idle_start:
val = val & ~led;
break;
case led_idle_end:
val = val | led;
break;
case led_timer:
val = val ^ REALVIEW_SYS_LED7;
break;
case led_halted:
val = 0;
break;
default:
break;
}
writel(val, VA_LEDS_BASE);
local_irq_restore(flags);
}
#endif /* CONFIG_LEDS */
/*
* Where is the timer (VA)?
*/

View File

@ -26,7 +26,6 @@
#include <linux/io.h>
#include <asm/setup.h>
#include <asm/leds.h>
#define APB_DEVICE(name, busid, base, plat) \
static AMBA_APB_DEVICE(name, busid, 0, REALVIEW_##base##_BASE, base##_IRQ, plat)
@ -47,7 +46,6 @@ extern void __iomem *timer1_va_base;
extern void __iomem *timer2_va_base;
extern void __iomem *timer3_va_base;
extern void realview_leds_event(led_event_t ledevt);
extern void realview_timer_init(unsigned int timer_irq);
extern int realview_flash_register(struct resource *res, u32 num);
extern int realview_eth_register(const char *name, struct resource *res);

View File

@ -30,7 +30,6 @@
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/pmu.h>
#include <asm/pgtable.h>
@ -462,10 +461,6 @@ static void __init realview_eb_init(void)
struct amba_device *d = amba_devs[i];
amba_device_register(d, &iomem_resource);
}
#ifdef CONFIG_LEDS
leds_event = realview_leds_event;
#endif
}
MACHINE_START(REALVIEW_EB, "ARM-RealView EB")

View File

@ -32,7 +32,6 @@
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/pmu.h>
#include <asm/pgtable.h>
@ -375,10 +374,6 @@ static void __init realview_pb1176_init(void)
struct amba_device *d = amba_devs[i];
amba_device_register(d, &iomem_resource);
}
#ifdef CONFIG_LEDS
leds_event = realview_leds_event;
#endif
}
MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")

View File

@ -30,7 +30,6 @@
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/pmu.h>
#include <asm/pgtable.h>
@ -357,10 +356,6 @@ static void __init realview_pb11mp_init(void)
struct amba_device *d = amba_devs[i];
amba_device_register(d, &iomem_resource);
}
#ifdef CONFIG_LEDS
leds_event = realview_leds_event;
#endif
}
MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")

View File

@ -29,7 +29,6 @@
#include <linux/io.h>
#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/pmu.h>
#include <asm/pgtable.h>
@ -299,10 +298,6 @@ static void __init realview_pba8_init(void)
struct amba_device *d = amba_devs[i];
amba_device_register(d, &iomem_resource);
}
#ifdef CONFIG_LEDS
leds_event = realview_leds_event;
#endif
}
MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8")

View File

@ -28,7 +28,6 @@
#include <linux/io.h>
#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/pmu.h>
#include <asm/smp_twd.h>
@ -394,10 +393,6 @@ static void __init realview_pbx_init(void)
struct amba_device *d = amba_devs[i];
amba_device_register(d, &iomem_resource);
}
#ifdef CONFIG_LEDS
leds_event = realview_leds_event;
#endif
}
MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")

View File

@ -7,21 +7,17 @@ obj-y := clock.o generic.o irq.o time.o #nmi-oopser.o
obj-m :=
obj-n :=
obj- :=
led-y := leds.o
obj-$(CONFIG_CPU_FREQ_SA1100) += cpu-sa1100.o
obj-$(CONFIG_CPU_FREQ_SA1110) += cpu-sa1110.o
# Specific board support
obj-$(CONFIG_SA1100_ASSABET) += assabet.o
led-$(CONFIG_SA1100_ASSABET) += leds-assabet.o
obj-$(CONFIG_ASSABET_NEPONSET) += neponset.o
obj-$(CONFIG_SA1100_BADGE4) += badge4.o
led-$(CONFIG_SA1100_BADGE4) += leds-badge4.o
obj-$(CONFIG_SA1100_CERF) += cerf.o
led-$(CONFIG_SA1100_CERF) += leds-cerf.o
obj-$(CONFIG_SA1100_COLLIE) += collie.o
@ -29,13 +25,11 @@ obj-$(CONFIG_SA1100_H3100) += h3100.o h3xxx.o
obj-$(CONFIG_SA1100_H3600) += h3600.o h3xxx.o
obj-$(CONFIG_SA1100_HACKKIT) += hackkit.o
led-$(CONFIG_SA1100_HACKKIT) += leds-hackkit.o
obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o
obj-$(CONFIG_SA1100_JORNADA720_SSP) += jornada720_ssp.o
obj-$(CONFIG_SA1100_LART) += lart.o
led-$(CONFIG_SA1100_LART) += leds-lart.o
obj-$(CONFIG_SA1100_NANOENGINE) += nanoengine.o
obj-$(CONFIG_PCI_NANOENGINE) += pci-nanoengine.o
@ -46,9 +40,6 @@ obj-$(CONFIG_SA1100_SHANNON) += shannon.o
obj-$(CONFIG_SA1100_SIMPAD) += simpad.o
# LEDs support
obj-$(CONFIG_LEDS) += $(led-y)
# Miscellaneous functions
obj-$(CONFIG_PM) += pm.o sleep.o
obj-$(CONFIG_SA1100_SSP) += ssp.o

View File

@ -20,6 +20,8 @@
#include <linux/mtd/partitions.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/leds.h>
#include <linux/slab.h>
#include <video/sa1100fb.h>
@ -529,6 +531,89 @@ static void __init assabet_map_io(void)
sa1100_register_uart(2, 3);
}
/* LEDs */
#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
struct assabet_led {
struct led_classdev cdev;
u32 mask;
};
/*
* 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;
} assabet_leds[] = {
{ "assabet:red", "cpu0",},
{ "assabet:green", "heartbeat", },
};
/*
* The LED control in Assabet is reversed:
* - setting bit means turn off LED
* - clearing bit means turn on LED
*/
static void assabet_led_set(struct led_classdev *cdev,
enum led_brightness b)
{
struct assabet_led *led = container_of(cdev,
struct assabet_led, cdev);
if (b != LED_OFF)
ASSABET_BCR_clear(led->mask);
else
ASSABET_BCR_set(led->mask);
}
static enum led_brightness assabet_led_get(struct led_classdev *cdev)
{
struct assabet_led *led = container_of(cdev,
struct assabet_led, cdev);
return (ASSABET_BCR & led->mask) ? LED_OFF : LED_FULL;
}
static int __init assabet_leds_init(void)
{
int i;
if (!machine_is_assabet())
return -ENODEV;
for (i = 0; i < ARRAY_SIZE(assabet_leds); i++) {
struct assabet_led *led;
led = kzalloc(sizeof(*led), GFP_KERNEL);
if (!led)
break;
led->cdev.name = assabet_leds[i].name;
led->cdev.brightness_set = assabet_led_set;
led->cdev.brightness_get = assabet_led_get;
led->cdev.default_trigger = assabet_leds[i].trigger;
if (!i)
led->mask = ASSABET_BCR_LED_RED;
else
led->mask = ASSABET_BCR_LED_GREEN;
if (led_classdev_register(NULL, &led->cdev) < 0) {
kfree(led);
break;
}
}
return 0;
}
/*
* Since we may have triggers on any subsystem, defer registration
* until after subsystem_init.
*/
fs_initcall(assabet_leds_init);
#endif
MACHINE_START(ASSABET, "Intel-Assabet")
.atag_offset = 0x100,

View File

@ -22,6 +22,8 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@ -76,8 +78,36 @@ static struct platform_device sa1111_device = {
.resource = sa1111_resources,
};
/* LEDs */
struct gpio_led badge4_gpio_leds[] = {
{
.name = "badge4:red",
.default_trigger = "heartbeat",
.gpio = 7,
},
{
.name = "badge4:green",
.default_trigger = "cpu0",
.gpio = 9,
},
};
static struct gpio_led_platform_data badge4_gpio_led_info = {
.leds = badge4_gpio_leds,
.num_leds = ARRAY_SIZE(badge4_gpio_leds),
};
static struct platform_device badge4_leds = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &badge4_gpio_led_info,
}
};
static struct platform_device *devices[] __initdata = {
&sa1111_device,
&badge4_leds,
};
static int __init badge4_sa1111_init(void)

View File

@ -17,6 +17,8 @@
#include <linux/irq.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <mach/hardware.h>
#include <asm/setup.h>
@ -43,8 +45,48 @@ static struct platform_device cerfuart2_device = {
.resource = cerfuart2_resources,
};
/* LEDs */
struct gpio_led cerf_gpio_leds[] = {
{
.name = "cerf:d0",
.default_trigger = "heartbeat",
.gpio = 0,
},
{
.name = "cerf:d1",
.default_trigger = "cpu0",
.gpio = 1,
},
{
.name = "cerf:d2",
.default_trigger = "default-on",
.gpio = 2,
},
{
.name = "cerf:d3",
.default_trigger = "default-on",
.gpio = 3,
},
};
static struct gpio_led_platform_data cerf_gpio_led_info = {
.leds = cerf_gpio_leds,
.num_leds = ARRAY_SIZE(cerf_gpio_leds),
};
static struct platform_device cerf_leds = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &cerf_gpio_led_info,
}
};
static struct platform_device *cerf_devices[] __initdata = {
&cerfuart2_device,
&cerf_leds,
};
#ifdef CONFIG_SA1100_CERF_FLASH_32MB

View File

@ -21,6 +21,10 @@
#include <linux/serial_core.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/tty.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/platform_device.h>
#include <asm/mach-types.h>
#include <asm/setup.h>
@ -183,9 +187,37 @@ static struct flash_platform_data hackkit_flash_data = {
static struct resource hackkit_flash_resource =
DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
/* LEDs */
struct gpio_led hackkit_gpio_leds[] = {
{
.name = "hackkit:red",
.default_trigger = "cpu0",
.gpio = 22,
},
{
.name = "hackkit:green",
.default_trigger = "heartbeat",
.gpio = 23,
},
};
static struct gpio_led_platform_data hackkit_gpio_led_info = {
.leds = hackkit_gpio_leds,
.num_leds = ARRAY_SIZE(hackkit_gpio_leds),
};
static struct platform_device hackkit_leds = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &hackkit_gpio_led_info,
}
};
static void __init hackkit_init(void)
{
sa11x0_register_mtd(&hackkit_flash_data, &hackkit_flash_resource, 1);
platform_device_register(&hackkit_leds);
}
/**********************************************************************

View File

@ -5,6 +5,9 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/platform_device.h>
#include <video/sa1100fb.h>
@ -126,6 +129,27 @@ static struct map_desc lart_io_desc[] __initdata = {
}
};
/* LEDs */
struct gpio_led lart_gpio_leds[] = {
{
.name = "lart:red",
.default_trigger = "cpu0",
.gpio = 23,
},
};
static struct gpio_led_platform_data lart_gpio_led_info = {
.leds = lart_gpio_leds,
.num_leds = ARRAY_SIZE(lart_gpio_leds),
};
static struct platform_device lart_leds = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &lart_gpio_led_info,
}
};
static void __init lart_map_io(void)
{
sa1100_map_io();
@ -139,6 +163,8 @@ static void __init lart_map_io(void)
GPDR |= GPIO_UART_TXD;
GPDR &= ~GPIO_UART_RXD;
PPAR |= PPAR_UPR;
platform_device_register(&lart_leds);
}
MACHINE_START(LART, "LART")

View File

@ -1,113 +0,0 @@
/*
* linux/arch/arm/mach-sa1100/leds-assabet.c
*
* Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu>
*
* Original (leds-footbridge.c) by Russell King
*
* Assabet uses the LEDs as follows:
* - Green - toggles state every 50 timer interrupts
* - Red - on if system is not idle
*/
#include <linux/init.h>
#include <mach/hardware.h>
#include <asm/leds.h>
#include <mach/assabet.h>
#include "leds.h"
#define LED_STATE_ENABLED 1
#define LED_STATE_CLAIMED 2
static unsigned int led_state;
static unsigned int hw_led_state;
#define ASSABET_BCR_LED_MASK (ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED)
void assabet_leds_event(led_event_t evt)
{
unsigned long flags;
local_irq_save(flags);
switch (evt) {
case led_start:
hw_led_state = ASSABET_BCR_LED_RED | ASSABET_BCR_LED_GREEN;
led_state = LED_STATE_ENABLED;
break;
case led_stop:
led_state &= ~LED_STATE_ENABLED;
hw_led_state = ASSABET_BCR_LED_RED | ASSABET_BCR_LED_GREEN;
ASSABET_BCR_frob(ASSABET_BCR_LED_MASK, hw_led_state);
break;
case led_claim:
led_state |= LED_STATE_CLAIMED;
hw_led_state = ASSABET_BCR_LED_RED | ASSABET_BCR_LED_GREEN;
break;
case led_release:
led_state &= ~LED_STATE_CLAIMED;
hw_led_state = ASSABET_BCR_LED_RED | ASSABET_BCR_LED_GREEN;
break;
#ifdef CONFIG_LEDS_TIMER
case led_timer:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state ^= ASSABET_BCR_LED_GREEN;
break;
#endif
#ifdef CONFIG_LEDS_CPU
case led_idle_start:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state |= ASSABET_BCR_LED_RED;
break;
case led_idle_end:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state &= ~ASSABET_BCR_LED_RED;
break;
#endif
case led_halted:
break;
case led_green_on:
if (led_state & LED_STATE_CLAIMED)
hw_led_state &= ~ASSABET_BCR_LED_GREEN;
break;
case led_green_off:
if (led_state & LED_STATE_CLAIMED)
hw_led_state |= ASSABET_BCR_LED_GREEN;
break;
case led_amber_on:
break;
case led_amber_off:
break;
case led_red_on:
if (led_state & LED_STATE_CLAIMED)
hw_led_state &= ~ASSABET_BCR_LED_RED;
break;
case led_red_off:
if (led_state & LED_STATE_CLAIMED)
hw_led_state |= ASSABET_BCR_LED_RED;
break;
default:
break;
}
if (led_state & LED_STATE_ENABLED)
ASSABET_BCR_frob(ASSABET_BCR_LED_MASK, hw_led_state);
local_irq_restore(flags);
}

View File

@ -1,110 +0,0 @@
/*
* linux/arch/arm/mach-sa1100/leds-badge4.c
*
* Author: Christopher Hoover <ch@hpl.hp.com>
* Copyright (C) 2002 Hewlett-Packard Company
*
* 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.
*
*/
#include <linux/init.h>
#include <mach/hardware.h>
#include <asm/leds.h>
#include "leds.h"
#define LED_STATE_ENABLED 1
#define LED_STATE_CLAIMED 2
static unsigned int led_state;
static unsigned int hw_led_state;
#define LED_RED GPIO_GPIO(7)
#define LED_GREEN GPIO_GPIO(9)
#define LED_MASK (LED_RED|LED_GREEN)
#define LED_IDLE LED_GREEN
#define LED_TIMER LED_RED
void badge4_leds_event(led_event_t evt)
{
unsigned long flags;
local_irq_save(flags);
switch (evt) {
case led_start:
GPDR |= LED_MASK;
hw_led_state = LED_MASK;
led_state = LED_STATE_ENABLED;
break;
case led_stop:
led_state &= ~LED_STATE_ENABLED;
break;
case led_claim:
led_state |= LED_STATE_CLAIMED;
hw_led_state = LED_MASK;
break;
case led_release:
led_state &= ~LED_STATE_CLAIMED;
hw_led_state = LED_MASK;
break;
#ifdef CONFIG_LEDS_TIMER
case led_timer:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state ^= LED_TIMER;
break;
#endif
#ifdef CONFIG_LEDS_CPU
case led_idle_start:
/* LED off when system is idle */
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state &= ~LED_IDLE;
break;
case led_idle_end:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state |= LED_IDLE;
break;
#endif
case led_red_on:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state &= ~LED_RED;
break;
case led_red_off:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state |= LED_RED;
break;
case led_green_on:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state &= ~LED_GREEN;
break;
case led_green_off:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state |= LED_GREEN;
break;
default:
break;
}
if (led_state & LED_STATE_ENABLED) {
GPSR = hw_led_state;
GPCR = hw_led_state ^ LED_MASK;
}
local_irq_restore(flags);
}

View File

@ -1,110 +0,0 @@
/*
* linux/arch/arm/mach-sa1100/leds-cerf.c
*
* Author: ???
*/
#include <linux/init.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <asm/leds.h>
#include "leds.h"
#define LED_STATE_ENABLED 1
#define LED_STATE_CLAIMED 2
static unsigned int led_state;
static unsigned int hw_led_state;
#define LED_D0 GPIO_GPIO(0)
#define LED_D1 GPIO_GPIO(1)
#define LED_D2 GPIO_GPIO(2)
#define LED_D3 GPIO_GPIO(3)
#define LED_MASK (LED_D0|LED_D1|LED_D2|LED_D3)
void cerf_leds_event(led_event_t evt)
{
unsigned long flags;
local_irq_save(flags);
switch (evt) {
case led_start:
hw_led_state = LED_MASK;
led_state = LED_STATE_ENABLED;
break;
case led_stop:
led_state &= ~LED_STATE_ENABLED;
break;
case led_claim:
led_state |= LED_STATE_CLAIMED;
hw_led_state = LED_MASK;
break;
case led_release:
led_state &= ~LED_STATE_CLAIMED;
hw_led_state = LED_MASK;
break;
#ifdef CONFIG_LEDS_TIMER
case led_timer:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state ^= LED_D0;
break;
#endif
#ifdef CONFIG_LEDS_CPU
case led_idle_start:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state &= ~LED_D1;
break;
case led_idle_end:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state |= LED_D1;
break;
#endif
case led_green_on:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state &= ~LED_D2;
break;
case led_green_off:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state |= LED_D2;
break;
case led_amber_on:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state &= ~LED_D3;
break;
case led_amber_off:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state |= LED_D3;
break;
case led_red_on:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state &= ~LED_D1;
break;
case led_red_off:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state |= LED_D1;
break;
default:
break;
}
if (led_state & LED_STATE_ENABLED) {
GPSR = hw_led_state;
GPCR = hw_led_state ^ LED_MASK;
}
local_irq_restore(flags);
}

View File

@ -1,111 +0,0 @@
/*
* linux/arch/arm/mach-sa1100/leds-hackkit.c
*
* based on leds-lart.c
*
* (C) Erik Mouw (J.A.K.Mouw@its.tudelft.nl), April 21, 2000
* (C) Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de>, 2002
*
* The HackKit has two leds (GPIO 22/23). The red led (gpio 22) is used
* as cpu led, the green one is used as timer led.
*/
#include <linux/init.h>
#include <mach/hardware.h>
#include <asm/leds.h>
#include "leds.h"
#define LED_STATE_ENABLED 1
#define LED_STATE_CLAIMED 2
static unsigned int led_state;
static unsigned int hw_led_state;
#define LED_GREEN GPIO_GPIO23
#define LED_RED GPIO_GPIO22
#define LED_MASK (LED_RED | LED_GREEN)
void hackkit_leds_event(led_event_t evt)
{
unsigned long flags;
local_irq_save(flags);
switch(evt) {
case led_start:
/* pin 22/23 are outputs */
GPDR |= LED_MASK;
hw_led_state = LED_MASK;
led_state = LED_STATE_ENABLED;
break;
case led_stop:
led_state &= ~LED_STATE_ENABLED;
break;
case led_claim:
led_state |= LED_STATE_CLAIMED;
hw_led_state = LED_MASK;
break;
case led_release:
led_state &= ~LED_STATE_CLAIMED;
hw_led_state = LED_MASK;
break;
#ifdef CONFIG_LEDS_TIMER
case led_timer:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state ^= LED_GREEN;
break;
#endif
#ifdef CONFIG_LEDS_CPU
case led_idle_start:
/* The LART people like the LED to be off when the
system is idle... */
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state &= ~LED_RED;
break;
case led_idle_end:
/* ... and on if the system is not idle */
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state |= LED_RED;
break;
#endif
case led_red_on:
if (led_state & LED_STATE_CLAIMED)
hw_led_state &= ~LED_RED;
break;
case led_red_off:
if (led_state & LED_STATE_CLAIMED)
hw_led_state |= LED_RED;
break;
case led_green_on:
if (led_state & LED_STATE_CLAIMED)
hw_led_state &= ~LED_GREEN;
break;
case led_green_off:
if (led_state & LED_STATE_CLAIMED)
hw_led_state |= LED_GREEN;
break;
default:
break;
}
/* Now set the GPIO state, or nothing will happen at all */
if (led_state & LED_STATE_ENABLED) {
GPSR = hw_led_state;
GPCR = hw_led_state ^ LED_MASK;
}
local_irq_restore(flags);
}

View File

@ -1,101 +0,0 @@
/*
* linux/arch/arm/mach-sa1100/leds-lart.c
*
* (C) Erik Mouw (J.A.K.Mouw@its.tudelft.nl), April 21, 2000
*
* LART uses the LED as follows:
* - GPIO23 is the LED, on if system is not idle
* You can use both CONFIG_LEDS_CPU and CONFIG_LEDS_TIMER at the same
* time, but in that case the timer events will still dictate the
* pace of the LED.
*/
#include <linux/init.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <asm/leds.h>
#include "leds.h"
#define LED_STATE_ENABLED 1
#define LED_STATE_CLAIMED 2
static unsigned int led_state;
static unsigned int hw_led_state;
#define LED_23 GPIO_GPIO23
#define LED_MASK (LED_23)
void lart_leds_event(led_event_t evt)
{
unsigned long flags;
local_irq_save(flags);
switch(evt) {
case led_start:
/* pin 23 is output pin */
GPDR |= LED_23;
hw_led_state = LED_MASK;
led_state = LED_STATE_ENABLED;
break;
case led_stop:
led_state &= ~LED_STATE_ENABLED;
break;
case led_claim:
led_state |= LED_STATE_CLAIMED;
hw_led_state = LED_MASK;
break;
case led_release:
led_state &= ~LED_STATE_CLAIMED;
hw_led_state = LED_MASK;
break;
#ifdef CONFIG_LEDS_TIMER
case led_timer:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state ^= LED_23;
break;
#endif
#ifdef CONFIG_LEDS_CPU
case led_idle_start:
/* The LART people like the LED to be off when the
system is idle... */
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state &= ~LED_23;
break;
case led_idle_end:
/* ... and on if the system is not idle */
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state |= LED_23;
break;
#endif
case led_red_on:
if (led_state & LED_STATE_CLAIMED)
hw_led_state &= ~LED_23;
break;
case led_red_off:
if (led_state & LED_STATE_CLAIMED)
hw_led_state |= LED_23;
break;
default:
break;
}
/* Now set the GPIO state, or nothing will happen at all */
if (led_state & LED_STATE_ENABLED) {
GPSR = hw_led_state;
GPCR = hw_led_state ^ LED_MASK;
}
local_irq_restore(flags);
}

View File

@ -1,50 +0,0 @@
/*
* linux/arch/arm/mach-sa1100/leds.c
*
* SA1100 LEDs dispatcher
*
* Copyright (C) 2001 Nicolas Pitre
*/
#include <linux/compiler.h>
#include <linux/init.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include "leds.h"
static int __init
sa1100_leds_init(void)
{
if (machine_is_assabet())
leds_event = assabet_leds_event;
if (machine_is_consus())
leds_event = consus_leds_event;
if (machine_is_badge4())
leds_event = badge4_leds_event;
if (machine_is_brutus())
leds_event = brutus_leds_event;
if (machine_is_cerf())
leds_event = cerf_leds_event;
if (machine_is_flexanet())
leds_event = flexanet_leds_event;
if (machine_is_graphicsclient())
leds_event = graphicsclient_leds_event;
if (machine_is_hackkit())
leds_event = hackkit_leds_event;
if (machine_is_lart())
leds_event = lart_leds_event;
if (machine_is_pfs168())
leds_event = pfs168_leds_event;
if (machine_is_graphicsmaster())
leds_event = graphicsmaster_leds_event;
if (machine_is_adsbitsy())
leds_event = adsbitsy_leds_event;
if (machine_is_pt_system3())
leds_event = system3_leds_event;
leds_event(led_start);
return 0;
}
core_initcall(sa1100_leds_init);

View File

@ -1,13 +0,0 @@
extern void assabet_leds_event(led_event_t evt);
extern void badge4_leds_event(led_event_t evt);
extern void consus_leds_event(led_event_t evt);
extern void brutus_leds_event(led_event_t evt);
extern void cerf_leds_event(led_event_t evt);
extern void flexanet_leds_event(led_event_t evt);
extern void graphicsclient_leds_event(led_event_t evt);
extern void hackkit_leds_event(led_event_t evt);
extern void lart_leds_event(led_event_t evt);
extern void pfs168_leds_event(led_event_t evt);
extern void graphicsmaster_leds_event(led_event_t evt);
extern void adsbitsy_leds_event(led_event_t evt);
extern void system3_leds_event(led_event_t evt);

View File

@ -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

View File

@ -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>

View File

@ -1,165 +1,117 @@
/*
* 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>
#include <asm/mach-types.h>
#define LED_STATE_ENABLED 1
#define LED_STATE_CLAIMED 2
#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
struct shark_led {
struct led_classdev cdev;
u8 mask;
};
#define SEQUOIA_LED_GREEN (1<<6)
#define SEQUOIA_LED_AMBER (1<<5)
#define SEQUOIA_LED_BACK (1<<7)
/*
* 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 char led_state;
static short hw_led_state;
static short saved_state;
static DEFINE_RAW_SPINLOCK(leds_lock);
short sequoia_read(int addr) {
outw(addr,0x24);
return inw(0x26);
}
void sequoia_write(short value,short addr) {
outw(addr,0x24);
outw(value,0x26);
}
static void sequoia_leds_event(led_event_t evt)
static u16 led_reg_read(void)
{
unsigned long flags;
outw(0x09, 0x24);
return inw(0x26);
}
raw_spin_lock_irqsave(&leds_lock, flags);
static void led_reg_write(u16 value)
{
outw(0x09, 0x24);
outw(value, 0x26);
}
hw_led_state = sequoia_read(0x09);
static void shark_led_set(struct led_classdev *cdev,
enum led_brightness b)
{
struct shark_led *led = container_of(cdev,
struct shark_led, cdev);
u16 reg = led_reg_read();
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;
if (b != LED_OFF)
reg |= led->mask;
else
reg &= ~led->mask;
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;
led_reg_write(reg);
}
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;
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_release:
led_state &= ~LED_STATE_CLAIMED;
hw_led_state = saved_state;
break;
return (reg & led->mask) ? LED_FULL : LED_OFF;
}
#ifdef CONFIG_LEDS_TIMER
case led_timer:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state ^= SEQUOIA_LED_GREEN;
break;
#endif
static int __init shark_leds_init(void)
{
int i;
u16 reg;
#ifdef CONFIG_LEDS_CPU
case led_idle_start:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state &= ~SEQUOIA_LED_BACK;
break;
if (!machine_is_shark())
return -ENODEV;
case led_idle_end:
if (!(led_state & LED_STATE_CLAIMED))
hw_led_state |= SEQUOIA_LED_BACK;
break;
#endif
for (i = 0; i < ARRAY_SIZE(shark_leds); i++) {
struct shark_led *led;
case led_green_on:
if (led_state & LED_STATE_CLAIMED)
hw_led_state &= ~SEQUOIA_LED_GREEN;
break;
led = kzalloc(sizeof(*led), GFP_KERNEL);
if (!led)
break;
case led_green_off:
if (led_state & LED_STATE_CLAIMED)
hw_led_state |= SEQUOIA_LED_GREEN;
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_amber_on:
if (led_state & LED_STATE_CLAIMED)
hw_led_state &= ~SEQUOIA_LED_AMBER;
break;
/* Count in 5 bits offset */
led->mask = BIT(i + 5);
case led_amber_off:
if (led_state & LED_STATE_CLAIMED)
hw_led_state |= SEQUOIA_LED_AMBER;
break;
case led_red_on:
if (led_state & LED_STATE_CLAIMED)
hw_led_state |= SEQUOIA_LED_BACK;
break;
case led_red_off:
if (led_state & LED_STATE_CLAIMED)
hw_led_state &= ~SEQUOIA_LED_BACK;
break;
default:
break;
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

View File

@ -37,7 +37,6 @@
#include <linux/mtd/physmap.h>
#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/hardware/arm_timer.h>
#include <asm/hardware/icst.h>
#include <asm/hardware/vic.h>
@ -763,10 +762,6 @@ void __init versatile_init(void)
struct amba_device *d = amba_devs[i];
amba_device_register(d, &iomem_resource);
}
#ifdef CONFIG_LEDS
leds_event = versatile_leds_event;
#endif
}
/*

View File

@ -41,9 +41,8 @@ config OMAP_DEBUG_DEVICES
For debug cards on TI reference boards.
config OMAP_DEBUG_LEDS
bool
def_bool y if NEW_LEDS
depends on OMAP_DEBUG_DEVICES
default y if LEDS_CLASS
config POWER_AVS_OMAP
bool "AVS(Adaptive Voltage Scaling) support for OMAP IP versions 1&2"

View File

@ -1,279 +1,118 @@
/*
* linux/arch/arm/plat-omap/debug-leds.c
*
* Copyright 2011 by Bryan Wu <bryan.wu@canonical.com>
* Copyright 2003 by Texas Instruments Incorporated
*
* 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.
*/
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <mach/hardware.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <plat/fpga.h>
/* Many OMAP development platforms reuse the same "debug board"; these
* platforms include H2, H3, H4, and Perseus2. There are 16 LEDs on the
* debug board (all green), accessed through FPGA registers.
*
* The "surfer" expansion board and H2 sample board also have two-color
* green+red LEDs (in parallel), used here for timer and idle indicators
* in preference to the ones on the debug board, for a "Disco LED" effect.
*
* This driver exports either the original ARM LED API, the new generic
* one, or both.
*/
static spinlock_t lock;
static struct h2p2_dbg_fpga __iomem *fpga;
static u16 led_state, hw_led_state;
static struct h2p2_dbg_fpga __iomem *fpga;
#ifdef CONFIG_OMAP_DEBUG_LEDS
#define new_led_api() 1
#else
#define new_led_api() 0
#endif
/*-------------------------------------------------------------------------*/
/* original ARM debug LED API:
* - timer and idle leds (some boards use non-FPGA leds here);
* - up to 4 generic leds, easily accessed in-kernel (any context)
*/
#define GPIO_LED_RED 3
#define GPIO_LED_GREEN OMAP_MPUIO(4)
#define LED_STATE_ENABLED 0x01
#define LED_STATE_CLAIMED 0x02
#define LED_TIMER_ON 0x04
#define GPIO_IDLE GPIO_LED_GREEN
#define GPIO_TIMER GPIO_LED_RED
static void h2p2_dbg_leds_event(led_event_t evt)
{
unsigned long flags;
spin_lock_irqsave(&lock, flags);
if (!(led_state & LED_STATE_ENABLED) && evt != led_start)
goto done;
switch (evt) {
case led_start:
if (fpga)
led_state |= LED_STATE_ENABLED;
break;
case led_stop:
case led_halted:
/* all leds off during suspend or shutdown */
if (!(machine_is_omap_perseus2() || machine_is_omap_h4())) {
gpio_set_value(GPIO_TIMER, 0);
gpio_set_value(GPIO_IDLE, 0);
}
__raw_writew(~0, &fpga->leds);
led_state &= ~LED_STATE_ENABLED;
goto done;
case led_claim:
led_state |= LED_STATE_CLAIMED;
hw_led_state = 0;
break;
case led_release:
led_state &= ~LED_STATE_CLAIMED;
break;
#ifdef CONFIG_LEDS_TIMER
case led_timer:
led_state ^= LED_TIMER_ON;
if (machine_is_omap_perseus2() || machine_is_omap_h4())
hw_led_state ^= H2P2_DBG_FPGA_P2_LED_TIMER;
else {
gpio_set_value(GPIO_TIMER,
led_state & LED_TIMER_ON);
goto done;
}
break;
#endif
#ifdef CONFIG_LEDS_CPU
/* LED lit iff busy */
case led_idle_start:
if (machine_is_omap_perseus2() || machine_is_omap_h4())
hw_led_state &= ~H2P2_DBG_FPGA_P2_LED_IDLE;
else {
gpio_set_value(GPIO_IDLE, 1);
goto done;
}
break;
case led_idle_end:
if (machine_is_omap_perseus2() || machine_is_omap_h4())
hw_led_state |= H2P2_DBG_FPGA_P2_LED_IDLE;
else {
gpio_set_value(GPIO_IDLE, 0);
goto done;
}
break;
#endif
case led_green_on:
hw_led_state |= H2P2_DBG_FPGA_LED_GREEN;
break;
case led_green_off:
hw_led_state &= ~H2P2_DBG_FPGA_LED_GREEN;
break;
case led_amber_on:
hw_led_state |= H2P2_DBG_FPGA_LED_AMBER;
break;
case led_amber_off:
hw_led_state &= ~H2P2_DBG_FPGA_LED_AMBER;
break;
case led_red_on:
hw_led_state |= H2P2_DBG_FPGA_LED_RED;
break;
case led_red_off:
hw_led_state &= ~H2P2_DBG_FPGA_LED_RED;
break;
case led_blue_on:
hw_led_state |= H2P2_DBG_FPGA_LED_BLUE;
break;
case led_blue_off:
hw_led_state &= ~H2P2_DBG_FPGA_LED_BLUE;
break;
default:
break;
}
/*
* Actually burn the LEDs
*/
if (led_state & LED_STATE_ENABLED)
__raw_writew(~hw_led_state, &fpga->leds);
done:
spin_unlock_irqrestore(&lock, flags);
}
/*-------------------------------------------------------------------------*/
/* "new" LED API
* - with syfs access and generic triggering
* - not readily accessible to in-kernel drivers
*/
static u16 fpga_led_state;
struct dbg_led {
struct led_classdev cdev;
u16 mask;
};
static struct dbg_led dbg_leds[] = {
/* REVISIT at least H2 uses different timer & cpu leds... */
#ifndef CONFIG_LEDS_TIMER
{ .mask = 1 << 0, .cdev.name = "d4:green",
.cdev.default_trigger = "heartbeat", },
#endif
#ifndef CONFIG_LEDS_CPU
{ .mask = 1 << 1, .cdev.name = "d5:green", }, /* !idle */
#endif
{ .mask = 1 << 2, .cdev.name = "d6:green", },
{ .mask = 1 << 3, .cdev.name = "d7:green", },
{ .mask = 1 << 4, .cdev.name = "d8:green", },
{ .mask = 1 << 5, .cdev.name = "d9:green", },
{ .mask = 1 << 6, .cdev.name = "d10:green", },
{ .mask = 1 << 7, .cdev.name = "d11:green", },
{ .mask = 1 << 8, .cdev.name = "d12:green", },
{ .mask = 1 << 9, .cdev.name = "d13:green", },
{ .mask = 1 << 10, .cdev.name = "d14:green", },
{ .mask = 1 << 11, .cdev.name = "d15:green", },
#ifndef CONFIG_LEDS
{ .mask = 1 << 12, .cdev.name = "d16:green", },
{ .mask = 1 << 13, .cdev.name = "d17:green", },
{ .mask = 1 << 14, .cdev.name = "d18:green", },
{ .mask = 1 << 15, .cdev.name = "d19:green", },
#endif
static const struct {
const char *name;
const char *trigger;
} dbg_leds[] = {
{ "dbg:d4", "heartbeat", },
{ "dbg:d5", "cpu0", },
{ "dbg:d6", "default-on", },
{ "dbg:d7", },
{ "dbg:d8", },
{ "dbg:d9", },
{ "dbg:d10", },
{ "dbg:d11", },
{ "dbg:d12", },
{ "dbg:d13", },
{ "dbg:d14", },
{ "dbg:d15", },
{ "dbg:d16", },
{ "dbg:d17", },
{ "dbg:d18", },
{ "dbg:d19", },
};
static void
fpga_led_set(struct led_classdev *cdev, enum led_brightness value)
/*
* The triggers lines up below will only be used if the
* LED triggers are compiled in.
*/
static void dbg_led_set(struct led_classdev *cdev,
enum led_brightness b)
{
struct dbg_led *led = container_of(cdev, struct dbg_led, cdev);
unsigned long flags;
struct dbg_led *led = container_of(cdev, struct dbg_led, cdev);
u16 reg;
spin_lock_irqsave(&lock, flags);
if (value == LED_OFF)
hw_led_state &= ~led->mask;
reg = __raw_readw(&fpga->leds);
if (b != LED_OFF)
reg |= led->mask;
else
hw_led_state |= led->mask;
__raw_writew(~hw_led_state, &fpga->leds);
spin_unlock_irqrestore(&lock, flags);
reg &= ~led->mask;
__raw_writew(reg, &fpga->leds);
}
static void __init newled_init(struct device *dev)
static enum led_brightness dbg_led_get(struct led_classdev *cdev)
{
unsigned i;
struct dbg_led *led;
int status;
struct dbg_led *led = container_of(cdev, struct dbg_led, cdev);
u16 reg;
for (i = 0, led = dbg_leds; i < ARRAY_SIZE(dbg_leds); i++, led++) {
led->cdev.brightness_set = fpga_led_set;
status = led_classdev_register(dev, &led->cdev);
if (status < 0)
break;
}
return;
reg = __raw_readw(&fpga->leds);
return (reg & led->mask) ? LED_FULL : LED_OFF;
}
/*-------------------------------------------------------------------------*/
static int /* __init */ fpga_probe(struct platform_device *pdev)
static int fpga_probe(struct platform_device *pdev)
{
struct resource *iomem;
spin_lock_init(&lock);
int i;
iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!iomem)
return -ENODEV;
fpga = ioremap(iomem->start, H2P2_DBG_FPGA_SIZE);
__raw_writew(~0, &fpga->leds);
__raw_writew(0xff, &fpga->leds);
#ifdef CONFIG_LEDS
leds_event = h2p2_dbg_leds_event;
leds_event(led_start);
#endif
for (i = 0; i < ARRAY_SIZE(dbg_leds); i++) {
struct dbg_led *led;
if (new_led_api()) {
newled_init(&pdev->dev);
led = kzalloc(sizeof(*led), GFP_KERNEL);
if (!led)
break;
led->cdev.name = dbg_leds[i].name;
led->cdev.brightness_set = dbg_led_set;
led->cdev.brightness_get = dbg_led_get;
led->cdev.default_trigger = dbg_leds[i].trigger;
led->mask = BIT(i);
if (led_classdev_register(NULL, &led->cdev) < 0) {
kfree(led);
break;
}
}
return 0;
@ -281,13 +120,15 @@ static int /* __init */ fpga_probe(struct platform_device *pdev)
static int fpga_suspend_noirq(struct device *dev)
{
__raw_writew(~0, &fpga->leds);
fpga_led_state = __raw_readw(&fpga->leds);
__raw_writew(0xff, &fpga->leds);
return 0;
}
static int fpga_resume_noirq(struct device *dev)
{
__raw_writew(~hw_led_state, &fpga->leds);
__raw_writew(~fpga_led_state, &fpga->leds);
return 0;
}

View File

@ -28,7 +28,6 @@
#include <linux/io.h>
#include <linux/platform_device.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/irq.h>

View File

@ -16,8 +16,10 @@ config PLAT_VERSATILE_FPGA_IRQ_NR
depends on PLAT_VERSATILE_FPGA_IRQ
config PLAT_VERSATILE_LEDS
def_bool y if LEDS_CLASS
def_bool y if NEW_LEDS
depends on ARCH_REALVIEW || ARCH_VERSATILE
select LEDS_CLASS
select LEDS_TRIGGER
config PLAT_VERSATILE_SCHED_CLOCK
def_bool y

View File

@ -37,10 +37,10 @@ static const struct {
} versatile_leds[] = {
{ "versatile:0", "heartbeat", },
{ "versatile:1", "mmc0", },
{ "versatile:2", },
{ "versatile:3", },
{ "versatile:4", },
{ "versatile:5", },
{ "versatile:2", "cpu0" },
{ "versatile:3", "cpu1" },
{ "versatile:4", "cpu2" },
{ "versatile:5", "cpu3" },
{ "versatile:6", },
{ "versatile:7", },
};

View File

@ -30,7 +30,6 @@
#include <asm/hardware/dec21285.h>
#include <asm/io.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/uaccess.h>
@ -179,9 +178,6 @@ static ssize_t flash_write(struct file *file, const char __user *buf,
written = 0;
leds_event(led_claim);
leds_event(led_green_on);
nBlock = (int) p >> 16; //block # of 64K bytes
/*
@ -258,11 +254,6 @@ static ssize_t flash_write(struct file *file, const char __user *buf,
printk(KERN_DEBUG "flash_write: written 0x%X bytes OK.\n", written);
}
/*
* restore reg on exit
*/
leds_event(led_release);
mutex_unlock(&nwflash_mutex);
return written;
@ -333,11 +324,6 @@ static int erase_block(int nBlock)
unsigned long timeout;
int temp, temp1;
/*
* orange LED == erase
*/
leds_event(led_amber_on);
/*
* reset footbridge to the correct offset 0 (...0..3)
*/
@ -446,12 +432,6 @@ static int write_block(unsigned long p, const char __user *buf, int count)
unsigned long timeout;
unsigned long timeout1;
/*
* red LED == write
*/
leds_event(led_amber_off);
leds_event(led_red_on);
pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + p));
/*
@ -557,18 +537,10 @@ static int write_block(unsigned long p, const char __user *buf, int count)
printk(KERN_DEBUG "write_block: Retrying write at 0x%X)n",
pWritePtr - FLASH_BASE);
/*
* no LED == waiting
*/
leds_event(led_amber_off);
/*
* wait couple ms
*/
msleep(10);
/*
* red LED == write
*/
leds_event(led_red_on);
goto WriteRetry;
} else {
@ -583,12 +555,6 @@ static int write_block(unsigned long p, const char __user *buf, int count)
}
}
/*
* green LED == read/verify
*/
leds_event(led_amber_off);
leds_event(led_green_on);
msleep(10);
pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + p));

View File

@ -506,6 +506,16 @@ config LEDS_TRIGGER_BACKLIGHT
If unsure, say N.
config LEDS_TRIGGER_CPU
bool "LED CPU Trigger"
depends on LEDS_TRIGGERS
help
This allows LEDs to be controlled by active CPUs. This shows
the active CPUs across an array of LEDs so you can see which
CPUs are active on the system at any given moment.
If unsure, say N.
config LEDS_TRIGGER_GPIO
tristate "LED GPIO Trigger"
depends on LEDS_TRIGGERS

View File

@ -61,5 +61,6 @@ obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o
obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o
obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o
obj-$(CONFIG_LEDS_TRIGGER_GPIO) += ledtrig-gpio.o
obj-$(CONFIG_LEDS_TRIGGER_CPU) += ledtrig-cpu.o
obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
obj-$(CONFIG_LEDS_TRIGGER_TRANSIENT) += ledtrig-transient.o

163
drivers/leds/ledtrig-cpu.c Normal file
View File

@ -0,0 +1,163 @@
/*
* ledtrig-cpu.c - LED trigger based on CPU activity
*
* This LED trigger will be registered for each possible CPU and named as
* cpu0, cpu1, cpu2, cpu3, etc.
*
* It can be bound to any LED just like other triggers using either a
* board file or via sysfs interface.
*
* An API named ledtrig_cpu is exported for any user, who want to add CPU
* activity indication in their code
*
* Copyright 2011 Linus Walleij <linus.walleij@linaro.org>
* Copyright 2011 - 2012 Bryan Wu <bryan.wu@canonical.com>
*
* 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.
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/percpu.h>
#include <linux/syscore_ops.h>
#include <linux/rwsem.h>
#include "leds.h"
#define MAX_NAME_LEN 8
struct led_trigger_cpu {
char name[MAX_NAME_LEN];
struct led_trigger *_trig;
struct mutex lock;
int lock_is_inited;
};
static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig);
/**
* ledtrig_cpu - emit a CPU event as a trigger
* @evt: CPU event to be emitted
*
* Emit a CPU event on a CPU core, which will trigger a
* binded LED to turn on or turn off.
*/
void ledtrig_cpu(enum cpu_led_event ledevt)
{
struct led_trigger_cpu *trig = &__get_cpu_var(cpu_trig);
/* mutex lock should be initialized before calling mutex_call() */
if (!trig->lock_is_inited)
return;
mutex_lock(&trig->lock);
/* Locate the correct CPU LED */
switch (ledevt) {
case CPU_LED_IDLE_END:
case CPU_LED_START:
/* Will turn the LED on, max brightness */
led_trigger_event(trig->_trig, LED_FULL);
break;
case CPU_LED_IDLE_START:
case CPU_LED_STOP:
case CPU_LED_HALTED:
/* Will turn the LED off */
led_trigger_event(trig->_trig, LED_OFF);
break;
default:
/* Will leave the LED as it is */
break;
}
mutex_unlock(&trig->lock);
}
EXPORT_SYMBOL(ledtrig_cpu);
static int ledtrig_cpu_syscore_suspend(void)
{
ledtrig_cpu(CPU_LED_STOP);
return 0;
}
static void ledtrig_cpu_syscore_resume(void)
{
ledtrig_cpu(CPU_LED_START);
}
static void ledtrig_cpu_syscore_shutdown(void)
{
ledtrig_cpu(CPU_LED_HALTED);
}
static struct syscore_ops ledtrig_cpu_syscore_ops = {
.shutdown = ledtrig_cpu_syscore_shutdown,
.suspend = ledtrig_cpu_syscore_suspend,
.resume = ledtrig_cpu_syscore_resume,
};
static int __init ledtrig_cpu_init(void)
{
int cpu;
/* Supports up to 9999 cpu cores */
BUILD_BUG_ON(CONFIG_NR_CPUS > 9999);
/*
* Registering CPU led trigger for each CPU core here
* ignores CPU hotplug, but after this CPU hotplug works
* fine with this trigger.
*/
for_each_possible_cpu(cpu) {
struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu);
mutex_init(&trig->lock);
snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu);
mutex_lock(&trig->lock);
led_trigger_register_simple(trig->name, &trig->_trig);
trig->lock_is_inited = 1;
mutex_unlock(&trig->lock);
}
register_syscore_ops(&ledtrig_cpu_syscore_ops);
pr_info("ledtrig-cpu: registered to indicate activity on CPUs\n");
return 0;
}
module_init(ledtrig_cpu_init);
static void __exit ledtrig_cpu_exit(void)
{
int cpu;
for_each_possible_cpu(cpu) {
struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu);
mutex_lock(&trig->lock);
led_trigger_unregister_simple(trig->_trig);
trig->_trig = NULL;
memset(trig->name, 0, MAX_NAME_LEN);
trig->lock_is_inited = 0;
mutex_unlock(&trig->lock);
mutex_destroy(&trig->lock);
}
unregister_syscore_ops(&ledtrig_cpu_syscore_ops);
}
module_exit(ledtrig_cpu_exit);
MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
MODULE_AUTHOR("Bryan Wu <bryan.wu@canonical.com>");
MODULE_DESCRIPTION("CPU LED trigger");
MODULE_LICENSE("GPL");

View File

@ -237,4 +237,20 @@ struct gpio_led_platform_data {
struct platform_device *gpio_led_register_device(
int id, const struct gpio_led_platform_data *pdata);
enum cpu_led_event {
CPU_LED_IDLE_START, /* CPU enters idle */
CPU_LED_IDLE_END, /* CPU idle ends */
CPU_LED_START, /* Machine starts, especially resume */
CPU_LED_STOP, /* Machine stops, especially suspend */
CPU_LED_HALTED, /* Machine shutdown */
};
#ifdef CONFIG_LEDS_TRIGGER_CPU
extern void ledtrig_cpu(enum cpu_led_event evt);
#else
static inline void ledtrig_cpu(enum cpu_led_event evt)
{
return;
}
#endif
#endif /* __LINUX_LEDS_H_INCLUDED */