Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d7f5e3df authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://git.o-hand.com/linux-rpurdie-leds

* 'for-linus' of git://git.o-hand.com/linux-rpurdie-leds:
  leds: Convert from struct class_device to struct device
  leds: leds-gpio for ngw100
  leds: Add warning printks in error paths
  leds: Fix trigger unregister_simple if register_simple fails
  leds: Use menuconfig objects II - LED
  leds: Teach leds-gpio to handle timer-unsafe GPIOs
  leds: Add generic GPIO LED driver
parents 2fe83b3a f8a7c6fe
Loading
Loading
Loading
Loading
+31 −0
Original line number Original line Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/linkage.h>
#include <linux/linkage.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/types.h>
#include <linux/leds.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi.h>


#include <asm/io.h>
#include <asm/io.h>
@@ -21,6 +22,7 @@
#include <asm/arch/at32ap7000.h>
#include <asm/arch/at32ap7000.h>
#include <asm/arch/board.h>
#include <asm/arch/board.h>
#include <asm/arch/init.h>
#include <asm/arch/init.h>
#include <asm/arch/portmux.h>


/* Initialized by bootloader-specific startup code. */
/* Initialized by bootloader-specific startup code. */
struct tag *bootloader_tags __initdata;
struct tag *bootloader_tags __initdata;
@@ -100,8 +102,31 @@ void __init setup_board(void)
	at32_setup_serial_console(0);
	at32_setup_serial_console(0);
}
}


static const struct gpio_led ngw_leds[] = {
	{ .name = "sys", .gpio = GPIO_PIN_PA(16), .active_low = 1,
		.default_trigger = "heartbeat",
	},
	{ .name = "a", .gpio = GPIO_PIN_PA(19), .active_low = 1, },
	{ .name = "b", .gpio = GPIO_PIN_PE(19), .active_low = 1, },
};

static const struct gpio_led_platform_data ngw_led_data = {
	.num_leds =	ARRAY_SIZE(ngw_leds),
	.leds =		(void *) ngw_leds,
};

static struct platform_device ngw_gpio_leds = {
	.name =		"leds-gpio",
	.id =		-1,
	.dev = {
		.platform_data = (void *) &ngw_led_data,
	}
};

static int __init atngw100_init(void)
static int __init atngw100_init(void)
{
{
	unsigned	i;

	/*
	/*
	 * ATNGW100 uses 16-bit SDRAM interface, so we don't need to
	 * ATNGW100 uses 16-bit SDRAM interface, so we don't need to
	 * reserve any pins for it.
	 * reserve any pins for it.
@@ -116,6 +141,12 @@ static int __init atngw100_init(void)


	at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
	at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));


	for (i = 0; i < ARRAY_SIZE(ngw_leds); i++) {
		at32_select_gpio(ngw_leds[i].gpio,
				AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
	}
	platform_device_register(&ngw_gpio_leds);

	return 0;
	return 0;
}
}
postcore_initcall(atngw100_init);
postcore_initcall(atngw100_init);
+15 −1
Original line number Original line Diff line number Diff line
@@ -712,7 +712,21 @@ CONFIG_SPI_ATMEL=y
#
#
# LED devices
# LED devices
#
#
# CONFIG_NEW_LEDS is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y

#
# LED drivers
#
CONFIG_LEDS_GPIO=y

#
# LED Triggers
#
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y



#
#
# LED drivers
# LED drivers
+13 −9
Original line number Original line Diff line number Diff line

menuconfig NEW_LEDS
menu "LED devices"
	depends on HAS_IOMEM

config NEW_LEDS
	bool "LED Support"
	bool "LED Support"
	depends on HAS_IOMEM
	help
	help
	  Say Y to enable Linux LED support.  This allows control of supported
	  Say Y to enable Linux LED support.  This allows control of supported
	  LEDs from both userspace and optionally, by kernel events (triggers).
	  LEDs from both userspace and optionally, by kernel events (triggers).
@@ -11,9 +8,10 @@ config NEW_LEDS
	  This is not related to standard keyboard LEDs which are controlled
	  This is not related to standard keyboard LEDs which are controlled
	  via the input system.
	  via the input system.


if NEW_LEDS

config LEDS_CLASS
config LEDS_CLASS
	tristate "LED Class Support"
	tristate "LED Class Support"
	depends on NEW_LEDS
	help
	help
	  This option enables the led sysfs class in /sys/class/leds.  You'll
	  This option enables the led sysfs class in /sys/class/leds.  You'll
	  need this to do anything useful with LEDs.  If unsure, say N.
	  need this to do anything useful with LEDs.  If unsure, say N.
@@ -95,11 +93,18 @@ config LEDS_COBALT
	help
	help
	  This option enables support for the front LED on Cobalt Server
	  This option enables support for the front LED on Cobalt Server


config LEDS_GPIO
	tristate "LED Support for GPIO connected LEDs"
	depends on LEDS_CLASS && GENERIC_GPIO
	help
	  This option enables support for the LEDs connected to GPIO
	  outputs. To be useful the particular board must have LEDs
	  and they must be connected to the GPIO lines.

comment "LED Triggers"
comment "LED Triggers"


config LEDS_TRIGGERS
config LEDS_TRIGGERS
	bool "LED Trigger support"
	bool "LED Trigger support"
	depends on NEW_LEDS
	help
	help
	  This option enables trigger support for the leds class.
	  This option enables trigger support for the leds class.
	  These triggers allow kernel events to drive the LEDs and can
	  These triggers allow kernel events to drive the LEDs and can
@@ -128,5 +133,4 @@ config LEDS_TRIGGER_HEARTBEAT
	  load average.
	  load average.
	  If unsure, say Y.
	  If unsure, say Y.


endmenu
endif # NEW_LEDS
+1 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@ obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o
obj-$(CONFIG_LEDS_WRAP)			+= leds-wrap.o
obj-$(CONFIG_LEDS_WRAP)			+= leds-wrap.o
obj-$(CONFIG_LEDS_H1940)		+= leds-h1940.o
obj-$(CONFIG_LEDS_H1940)		+= leds-h1940.o
obj-$(CONFIG_LEDS_COBALT)		+= leds-cobalt.o
obj-$(CONFIG_LEDS_COBALT)		+= leds-cobalt.o
obj-$(CONFIG_LEDS_GPIO)			+= leds-gpio.o


# LED Triggers
# LED Triggers
obj-$(CONFIG_LEDS_TRIGGER_TIMER)	+= ledtrig-timer.o
obj-$(CONFIG_LEDS_TRIGGER_TIMER)	+= ledtrig-timer.o
+22 −27
Original line number Original line Diff line number Diff line
@@ -2,7 +2,7 @@
 * LED Class Core
 * LED Class Core
 *
 *
 * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu>
 * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu>
 * Copyright (C) 2005-2006 Richard Purdie <rpurdie@openedhand.com>
 * Copyright (C) 2005-2007 Richard Purdie <rpurdie@openedhand.com>
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * 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
 * it under the terms of the GNU General Public License version 2 as
@@ -24,9 +24,10 @@


static struct class *leds_class;
static struct class *leds_class;


static ssize_t led_brightness_show(struct class_device *dev, char *buf)
static ssize_t led_brightness_show(struct device *dev, 
		struct device_attribute *attr, char *buf)
{
{
	struct led_classdev *led_cdev = class_get_devdata(dev);
	struct led_classdev *led_cdev = dev_get_drvdata(dev);
	ssize_t ret = 0;
	ssize_t ret = 0;


	/* no lock needed for this */
	/* no lock needed for this */
@@ -36,10 +37,10 @@ static ssize_t led_brightness_show(struct class_device *dev, char *buf)
	return ret;
	return ret;
}
}


static ssize_t led_brightness_store(struct class_device *dev,
static ssize_t led_brightness_store(struct device *dev,
				const char *buf, size_t size)
		struct device_attribute *attr, const char *buf, size_t size)
{
{
	struct led_classdev *led_cdev = class_get_devdata(dev);
	struct led_classdev *led_cdev = dev_get_drvdata(dev);
	ssize_t ret = -EINVAL;
	ssize_t ret = -EINVAL;
	char *after;
	char *after;
	unsigned long state = simple_strtoul(buf, &after, 10);
	unsigned long state = simple_strtoul(buf, &after, 10);
@@ -56,10 +57,9 @@ static ssize_t led_brightness_store(struct class_device *dev,
	return ret;
	return ret;
}
}


static CLASS_DEVICE_ATTR(brightness, 0644, led_brightness_show,
static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store);
			led_brightness_store);
#ifdef CONFIG_LEDS_TRIGGERS
#ifdef CONFIG_LEDS_TRIGGERS
static CLASS_DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
#endif
#endif


/**
/**
@@ -93,16 +93,15 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
{
{
	int rc;
	int rc;


	led_cdev->class_dev = class_device_create(leds_class, NULL, 0,
	led_cdev->dev = device_create(leds_class, parent, 0, "%s",
						parent, "%s", led_cdev->name);
					    led_cdev->name);
	if (unlikely(IS_ERR(led_cdev->class_dev)))
	if (unlikely(IS_ERR(led_cdev->dev)))
		return PTR_ERR(led_cdev->class_dev);
		return PTR_ERR(led_cdev->dev);


	class_set_devdata(led_cdev->class_dev, led_cdev);
	dev_set_drvdata(led_cdev->dev, led_cdev);


	/* register the attributes */
	/* register the attributes */
	rc = class_device_create_file(led_cdev->class_dev,
	rc = device_create_file(led_cdev->dev, &dev_attr_brightness);
				      &class_device_attr_brightness);
	if (rc)
	if (rc)
		goto err_out;
		goto err_out;


@@ -114,8 +113,7 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
#ifdef CONFIG_LEDS_TRIGGERS
#ifdef CONFIG_LEDS_TRIGGERS
	rwlock_init(&led_cdev->trigger_lock);
	rwlock_init(&led_cdev->trigger_lock);


	rc = class_device_create_file(led_cdev->class_dev,
	rc = device_create_file(led_cdev->dev, &dev_attr_trigger);
				      &class_device_attr_trigger);
	if (rc)
	if (rc)
		goto err_out_led_list;
		goto err_out_led_list;


@@ -123,18 +121,17 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
#endif
#endif


	printk(KERN_INFO "Registered led device: %s\n",
	printk(KERN_INFO "Registered led device: %s\n",
			led_cdev->class_dev->class_id);
			led_cdev->name);


	return 0;
	return 0;


#ifdef CONFIG_LEDS_TRIGGERS
#ifdef CONFIG_LEDS_TRIGGERS
err_out_led_list:
err_out_led_list:
	class_device_remove_file(led_cdev->class_dev,
	device_remove_file(led_cdev->dev, &dev_attr_brightness);
				&class_device_attr_brightness);
	list_del(&led_cdev->node);
	list_del(&led_cdev->node);
#endif
#endif
err_out:
err_out:
	class_device_unregister(led_cdev->class_dev);
	device_unregister(led_cdev->dev);
	return rc;
	return rc;
}
}
EXPORT_SYMBOL_GPL(led_classdev_register);
EXPORT_SYMBOL_GPL(led_classdev_register);
@@ -147,18 +144,16 @@ EXPORT_SYMBOL_GPL(led_classdev_register);
 */
 */
void led_classdev_unregister(struct led_classdev *led_cdev)
void led_classdev_unregister(struct led_classdev *led_cdev)
{
{
	class_device_remove_file(led_cdev->class_dev,
	device_remove_file(led_cdev->dev, &dev_attr_brightness);
				&class_device_attr_brightness);
#ifdef CONFIG_LEDS_TRIGGERS
#ifdef CONFIG_LEDS_TRIGGERS
	class_device_remove_file(led_cdev->class_dev,
	device_remove_file(led_cdev->dev, &dev_attr_trigger);
				&class_device_attr_trigger);
	write_lock(&led_cdev->trigger_lock);
	write_lock(&led_cdev->trigger_lock);
	if (led_cdev->trigger)
	if (led_cdev->trigger)
		led_trigger_set(led_cdev, NULL);
		led_trigger_set(led_cdev, NULL);
	write_unlock(&led_cdev->trigger_lock);
	write_unlock(&led_cdev->trigger_lock);
#endif
#endif


	class_device_unregister(led_cdev->class_dev);
	device_unregister(led_cdev->dev);


	write_lock(&leds_list_lock);
	write_lock(&leds_list_lock);
	list_del(&led_cdev->node);
	list_del(&led_cdev->node);
Loading