-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ARM: mach-integrator: retire custom LED code
Use the LED in core module for CPU activity and also enable 4 debugging LEDs in baseboard. The CPU activity LED is now handled by the trigger in the leds subsystem, retire this old CONFIG_LEDS-based code. Signed-off-by: Bryan Wu <bryan.wu@canonical.com>
- Loading branch information
Bryan Wu
committed
Aug 1, 2012
1 parent
b7ea032
commit 95f4965
Showing
3 changed files
with
99 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
|
||
#define ALPHA_REG __io_address(INTEGRATOR_DBG_BASE) | ||
#define LEDREG (__io_address(INTEGRATOR_DBG_BASE) + INTEGRATOR_DBG_LEDS_OFFSET) | ||
|
||
static void integrator_leds_event(led_event_t ledevt) | ||
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; | ||
__raw_writel(reg, LEDREG); | ||
} | ||
|
||
case led_timer: | ||
saved_leds ^= GREEN_LED; | ||
update_alpha_leds = 1; | ||
break; | ||
static enum led_brightness integrator_led_get(struct led_classdev *cdev) | ||
{ | ||
struct integrator_led *led = container_of(cdev, | ||
struct integrator_led, cdev); | ||
u32 reg = __raw_readl(LEDREG); | ||
|
||
case led_red_on: | ||
saved_leds |= RED_LED; | ||
update_alpha_leds = 1; | ||
break; | ||
return (reg & led->mask) ? LED_FULL : LED_OFF; | ||
} | ||
|
||
case led_red_off: | ||
saved_leds &= ~RED_LED; | ||
update_alpha_leds = 1; | ||
break; | ||
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); | ||
} | ||
|
||
default: | ||
break; | ||
} | ||
static enum led_brightness cm_led_get(struct led_classdev *cdev) | ||
{ | ||
u32 reg = readl(CM_CTRL); | ||
|
||
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); | ||
return (reg & CM_CTRL_LED) ? LED_FULL : LED_OFF; | ||
} | ||
|
||
static int __init leds_init(void) | ||
static int __init integrator_leds_init(void) | ||
{ | ||
if (machine_is_integrator() || machine_is_cintegrator()) | ||
leds_event = integrator_leds_event; | ||
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 |