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 Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/linkage.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/leds.h>
#include <linux/spi/spi.h>

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

/* Initialized by bootloader-specific startup code. */
struct tag *bootloader_tags __initdata;
@@ -100,8 +102,31 @@ void __init setup_board(void)
	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)
{
	unsigned	i;

	/*
	 * ATNGW100 uses 16-bit SDRAM interface, so we don't need to
	 * 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));

	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;
}
postcore_initcall(atngw100_init);
+15 −1
Original line number Diff line number Diff line
@@ -712,7 +712,21 @@ CONFIG_SPI_ATMEL=y
#
# 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
+13 −9
Original line number Diff line number Diff line

menu "LED devices"
	depends on HAS_IOMEM

config NEW_LEDS
menuconfig NEW_LEDS
	bool "LED Support"
	depends on HAS_IOMEM
	help
	  Say Y to enable Linux LED support.  This allows control of supported
	  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
	  via the input system.

if NEW_LEDS

config LEDS_CLASS
	tristate "LED Class Support"
	depends on NEW_LEDS
	help
	  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.
@@ -95,11 +93,18 @@ config LEDS_COBALT
	help
	  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"

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

endmenu
endif # NEW_LEDS
+1 −0
Original line number 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_H1940)		+= leds-h1940.o
obj-$(CONFIG_LEDS_COBALT)		+= leds-cobalt.o
obj-$(CONFIG_LEDS_GPIO)			+= leds-gpio.o

# LED Triggers
obj-$(CONFIG_LEDS_TRIGGER_TIMER)	+= ledtrig-timer.o
+22 −27
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
 * LED Class Core
 *
 * 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
 * it under the terms of the GNU General Public License version 2 as
@@ -24,9 +24,10 @@

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;

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

static ssize_t led_brightness_store(struct class_device *dev,
				const char *buf, size_t size)
static ssize_t led_brightness_store(struct device *dev,
		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;
	char *after;
	unsigned long state = simple_strtoul(buf, &after, 10);
@@ -56,10 +57,9 @@ static ssize_t led_brightness_store(struct class_device *dev,
	return ret;
}

static CLASS_DEVICE_ATTR(brightness, 0644, led_brightness_show,
			led_brightness_store);
static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store);
#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

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

	led_cdev->class_dev = class_device_create(leds_class, NULL, 0,
						parent, "%s", led_cdev->name);
	if (unlikely(IS_ERR(led_cdev->class_dev)))
		return PTR_ERR(led_cdev->class_dev);
	led_cdev->dev = device_create(leds_class, parent, 0, "%s",
					    led_cdev->name);
	if (unlikely(IS_ERR(led_cdev->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 */
	rc = class_device_create_file(led_cdev->class_dev,
				      &class_device_attr_brightness);
	rc = device_create_file(led_cdev->dev, &dev_attr_brightness);
	if (rc)
		goto err_out;

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

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

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

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

	return 0;

#ifdef CONFIG_LEDS_TRIGGERS
err_out_led_list:
	class_device_remove_file(led_cdev->class_dev,
				&class_device_attr_brightness);
	device_remove_file(led_cdev->dev, &dev_attr_brightness);
	list_del(&led_cdev->node);
#endif
err_out:
	class_device_unregister(led_cdev->class_dev);
	device_unregister(led_cdev->dev);
	return rc;
}
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)
{
	class_device_remove_file(led_cdev->class_dev,
				&class_device_attr_brightness);
	device_remove_file(led_cdev->dev, &dev_attr_brightness);
#ifdef CONFIG_LEDS_TRIGGERS
	class_device_remove_file(led_cdev->class_dev,
				&class_device_attr_trigger);
	device_remove_file(led_cdev->dev, &dev_attr_trigger);
	write_lock(&led_cdev->trigger_lock);
	if (led_cdev->trigger)
		led_trigger_set(led_cdev, NULL);
	write_unlock(&led_cdev->trigger_lock);
#endif

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

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