Bläddra i källkod

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: Fix race between LED device uevent and actual attributes creation
  leds-gpio: fix default state handling on OF platforms
  leds: Add Dell Business Class Netbook LED driver
  leds: Kconfig cleanup
  leds: led-class.c - Quiet boot messages
  leds: make PCI device id constant
  leds: ALIX2: Add dependency to !GPIO_CS5335
Linus Torvalds 15 år sedan
förälder
incheckning
5dbc2f543d

+ 45 - 35
drivers/leds/Kconfig

@@ -15,6 +15,8 @@ config LEDS_CLASS
 	  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.
 
 
+if LEDS_CLASS
+
 comment "LED drivers"
 comment "LED drivers"
 
 
 config LEDS_88PM860X
 config LEDS_88PM860X
@@ -26,73 +28,73 @@ config LEDS_88PM860X
 
 
 config LEDS_ATMEL_PWM
 config LEDS_ATMEL_PWM
 	tristate "LED Support using Atmel PWM outputs"
 	tristate "LED Support using Atmel PWM outputs"
-	depends on LEDS_CLASS && ATMEL_PWM
+	depends on ATMEL_PWM
 	help
 	help
 	  This option enables support for LEDs driven using outputs
 	  This option enables support for LEDs driven using outputs
 	  of the dedicated PWM controller found on newer Atmel SOCs.
 	  of the dedicated PWM controller found on newer Atmel SOCs.
 
 
 config LEDS_LOCOMO
 config LEDS_LOCOMO
 	tristate "LED Support for Locomo device"
 	tristate "LED Support for Locomo device"
-	depends on LEDS_CLASS && SHARP_LOCOMO
+	depends on SHARP_LOCOMO
 	help
 	help
 	  This option enables support for the LEDs on Sharp Locomo.
 	  This option enables support for the LEDs on Sharp Locomo.
 	  Zaurus models SL-5500 and SL-5600.
 	  Zaurus models SL-5500 and SL-5600.
 
 
 config LEDS_MIKROTIK_RB532
 config LEDS_MIKROTIK_RB532
 	tristate "LED Support for Mikrotik Routerboard 532"
 	tristate "LED Support for Mikrotik Routerboard 532"
-	depends on LEDS_CLASS && MIKROTIK_RB532
+	depends on MIKROTIK_RB532
 	help
 	help
 	  This option enables support for the so called "User LED" of
 	  This option enables support for the so called "User LED" of
 	  Mikrotik's Routerboard 532.
 	  Mikrotik's Routerboard 532.
 
 
 config LEDS_S3C24XX
 config LEDS_S3C24XX
 	tristate "LED Support for Samsung S3C24XX GPIO LEDs"
 	tristate "LED Support for Samsung S3C24XX GPIO LEDs"
-	depends on LEDS_CLASS && ARCH_S3C2410
+	depends on ARCH_S3C2410
 	help
 	help
 	  This option enables support for LEDs connected to GPIO lines
 	  This option enables support for LEDs connected to GPIO lines
 	  on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440.
 	  on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440.
 
 
 config LEDS_AMS_DELTA
 config LEDS_AMS_DELTA
 	tristate "LED Support for the Amstrad Delta (E3)"
 	tristate "LED Support for the Amstrad Delta (E3)"
-	depends on LEDS_CLASS && MACH_AMS_DELTA
+	depends on MACH_AMS_DELTA
 	help
 	help
 	  This option enables support for the LEDs on Amstrad Delta (E3).
 	  This option enables support for the LEDs on Amstrad Delta (E3).
 
 
 config LEDS_NET48XX
 config LEDS_NET48XX
 	tristate "LED Support for Soekris net48xx series Error LED"
 	tristate "LED Support for Soekris net48xx series Error LED"
-	depends on LEDS_CLASS && SCx200_GPIO
+	depends on SCx200_GPIO
 	help
 	help
 	  This option enables support for the Soekris net4801 and net4826 error
 	  This option enables support for the Soekris net4801 and net4826 error
 	  LED.
 	  LED.
 
 
 config LEDS_FSG
 config LEDS_FSG
 	tristate "LED Support for the Freecom FSG-3"
 	tristate "LED Support for the Freecom FSG-3"
-	depends on LEDS_CLASS && MACH_FSG
+	depends on MACH_FSG
 	help
 	help
 	  This option enables support for the LEDs on the Freecom FSG-3.
 	  This option enables support for the LEDs on the Freecom FSG-3.
 
 
 config LEDS_WRAP
 config LEDS_WRAP
 	tristate "LED Support for the WRAP series LEDs"
 	tristate "LED Support for the WRAP series LEDs"
-	depends on LEDS_CLASS && SCx200_GPIO
+	depends on SCx200_GPIO
 	help
 	help
 	  This option enables support for the PCEngines WRAP programmable LEDs.
 	  This option enables support for the PCEngines WRAP programmable LEDs.
 
 
 config LEDS_ALIX2
 config LEDS_ALIX2
 	tristate "LED Support for ALIX.2 and ALIX.3 series"
 	tristate "LED Support for ALIX.2 and ALIX.3 series"
-	depends on LEDS_CLASS && X86 && EXPERIMENTAL
+	depends on X86 && !GPIO_CS5535 && !CS5535_GPIO
 	help
 	help
 	  This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs.
 	  This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs.
 	  You have to set leds-alix2.force=1 for boards with Award BIOS.
 	  You have to set leds-alix2.force=1 for boards with Award BIOS.
 
 
 config LEDS_H1940
 config LEDS_H1940
 	tristate "LED Support for iPAQ H1940 device"
 	tristate "LED Support for iPAQ H1940 device"
-	depends on LEDS_CLASS && ARCH_H1940
+	depends on ARCH_H1940
 	help
 	help
 	  This option enables support for the LEDs on the h1940.
 	  This option enables support for the LEDs on the h1940.
 
 
 config LEDS_COBALT_QUBE
 config LEDS_COBALT_QUBE
 	tristate "LED Support for the Cobalt Qube series front LED"
 	tristate "LED Support for the Cobalt Qube series front LED"
-	depends on LEDS_CLASS && MIPS_COBALT
+	depends on MIPS_COBALT
 	help
 	help
 	  This option enables support for the front LED on Cobalt Qube series
 	  This option enables support for the front LED on Cobalt Qube series
 
 
@@ -105,7 +107,7 @@ config LEDS_COBALT_RAQ
 
 
 config LEDS_SUNFIRE
 config LEDS_SUNFIRE
 	tristate "LED support for SunFire servers."
 	tristate "LED support for SunFire servers."
-	depends on LEDS_CLASS && SPARC64
+	depends on SPARC64
 	select LEDS_TRIGGERS
 	select LEDS_TRIGGERS
 	help
 	help
 	  This option enables support for the Left, Middle, and Right
 	  This option enables support for the Left, Middle, and Right
@@ -113,14 +115,14 @@ config LEDS_SUNFIRE
 
 
 config LEDS_HP6XX
 config LEDS_HP6XX
 	tristate "LED Support for the HP Jornada 6xx"
 	tristate "LED Support for the HP Jornada 6xx"
-	depends on LEDS_CLASS && SH_HP6XX
+	depends on SH_HP6XX
 	help
 	help
 	  This option enables LED support for the handheld
 	  This option enables LED support for the handheld
 	  HP Jornada 620/660/680/690.
 	  HP Jornada 620/660/680/690.
 
 
 config LEDS_PCA9532
 config LEDS_PCA9532
 	tristate "LED driver for PCA9532 dimmer"
 	tristate "LED driver for PCA9532 dimmer"
-	depends on LEDS_CLASS && I2C && INPUT && EXPERIMENTAL
+	depends on I2C && INPUT && EXPERIMENTAL
 	help
 	help
 	  This option enables support for NXP pca9532
 	  This option enables support for NXP pca9532
 	  LED controller. It is generally only useful
 	  LED controller. It is generally only useful
@@ -128,7 +130,7 @@ config LEDS_PCA9532
 
 
 config LEDS_GPIO
 config LEDS_GPIO
 	tristate "LED Support for GPIO connected LEDs"
 	tristate "LED Support for GPIO connected LEDs"
-	depends on LEDS_CLASS && GENERIC_GPIO
+	depends on GENERIC_GPIO
 	help
 	help
 	  This option enables support for the LEDs connected to GPIO
 	  This option enables support for the LEDs connected to GPIO
 	  outputs. To be useful the particular board must have LEDs
 	  outputs. To be useful the particular board must have LEDs
@@ -155,7 +157,7 @@ config LEDS_GPIO_OF
 
 
 config LEDS_LP3944
 config LEDS_LP3944
 	tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip"
 	tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip"
-	depends on LEDS_CLASS && I2C
+	depends on I2C
 	help
 	help
 	  This option enables support for LEDs connected to the National
 	  This option enables support for LEDs connected to the National
 	  Semiconductor LP3944 Lighting Management Unit (LMU) also known as
 	  Semiconductor LP3944 Lighting Management Unit (LMU) also known as
@@ -166,7 +168,7 @@ config LEDS_LP3944
 
 
 config LEDS_CLEVO_MAIL
 config LEDS_CLEVO_MAIL
 	tristate "Mail LED on Clevo notebook"
 	tristate "Mail LED on Clevo notebook"
-	depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI
+	depends on X86 && SERIO_I8042 && DMI
 	help
 	help
 	  This driver makes the mail LED accessible from userspace
 	  This driver makes the mail LED accessible from userspace
 	  programs through the leds subsystem. This LED have three
 	  programs through the leds subsystem. This LED have three
@@ -196,7 +198,7 @@ config LEDS_CLEVO_MAIL
 
 
 config LEDS_PCA955X
 config LEDS_PCA955X
 	tristate "LED Support for PCA955x I2C chips"
 	tristate "LED Support for PCA955x I2C chips"
-	depends on LEDS_CLASS && I2C
+	depends on I2C
 	help
 	help
 	  This option enables support for LEDs connected to PCA955x
 	  This option enables support for LEDs connected to PCA955x
 	  LED driver chips accessed via the I2C bus.  Supported
 	  LED driver chips accessed via the I2C bus.  Supported
@@ -204,54 +206,54 @@ config LEDS_PCA955X
 
 
 config LEDS_WM831X_STATUS
 config LEDS_WM831X_STATUS
 	tristate "LED support for status LEDs on WM831x PMICs"
 	tristate "LED support for status LEDs on WM831x PMICs"
-	depends on LEDS_CLASS && MFD_WM831X
+	depends on MFD_WM831X
 	help
 	help
 	  This option enables support for the status LEDs of the WM831x
 	  This option enables support for the status LEDs of the WM831x
           series of PMICs.
           series of PMICs.
 
 
 config LEDS_WM8350
 config LEDS_WM8350
 	tristate "LED Support for WM8350 AudioPlus PMIC"
 	tristate "LED Support for WM8350 AudioPlus PMIC"
-	depends on LEDS_CLASS && MFD_WM8350
+	depends on MFD_WM8350
 	help
 	help
 	  This option enables support for LEDs driven by the Wolfson
 	  This option enables support for LEDs driven by the Wolfson
 	  Microelectronics WM8350 AudioPlus PMIC.
 	  Microelectronics WM8350 AudioPlus PMIC.
 
 
 config LEDS_DA903X
 config LEDS_DA903X
 	tristate "LED Support for DA9030/DA9034 PMIC"
 	tristate "LED Support for DA9030/DA9034 PMIC"
-	depends on LEDS_CLASS && PMIC_DA903X
+	depends on PMIC_DA903X
 	help
 	help
 	  This option enables support for on-chip LED drivers found
 	  This option enables support for on-chip LED drivers found
 	  on Dialog Semiconductor DA9030/DA9034 PMICs.
 	  on Dialog Semiconductor DA9030/DA9034 PMICs.
 
 
 config LEDS_DAC124S085
 config LEDS_DAC124S085
 	tristate "LED Support for DAC124S085 SPI DAC"
 	tristate "LED Support for DAC124S085 SPI DAC"
-	depends on LEDS_CLASS && SPI
+	depends on SPI
 	help
 	help
 	  This option enables support for DAC124S085 SPI DAC from NatSemi,
 	  This option enables support for DAC124S085 SPI DAC from NatSemi,
 	  which can be used to control up to four LEDs.
 	  which can be used to control up to four LEDs.
 
 
 config LEDS_PWM
 config LEDS_PWM
 	tristate "PWM driven LED Support"
 	tristate "PWM driven LED Support"
-	depends on LEDS_CLASS && HAVE_PWM
+	depends on HAVE_PWM
 	help
 	help
 	  This option enables support for pwm driven LEDs
 	  This option enables support for pwm driven LEDs
 
 
 config LEDS_REGULATOR
 config LEDS_REGULATOR
 	tristate "REGULATOR driven LED support"
 	tristate "REGULATOR driven LED support"
-	depends on LEDS_CLASS && REGULATOR
+	depends on REGULATOR
 	help
 	help
 	  This option enables support for regulator driven LEDs.
 	  This option enables support for regulator driven LEDs.
 
 
 config LEDS_BD2802
 config LEDS_BD2802
 	tristate "LED driver for BD2802 RGB LED"
 	tristate "LED driver for BD2802 RGB LED"
-	depends on LEDS_CLASS && I2C
+	depends on I2C
 	help
 	help
 	  This option enables support for BD2802GU RGB LED driver chips
 	  This option enables support for BD2802GU RGB LED driver chips
 	  accessed via the I2C bus.
 	  accessed via the I2C bus.
 
 
 config LEDS_INTEL_SS4200
 config LEDS_INTEL_SS4200
 	tristate "LED driver for Intel NAS SS4200 series"
 	tristate "LED driver for Intel NAS SS4200 series"
-	depends on LEDS_CLASS && PCI && DMI
+	depends on PCI && DMI
 	help
 	help
 	  This option enables support for the Intel SS4200 series of
 	  This option enables support for the Intel SS4200 series of
 	  Network Attached Storage servers.  You may control the hard
 	  Network Attached Storage servers.  You may control the hard
@@ -260,7 +262,7 @@ config LEDS_INTEL_SS4200
 
 
 config LEDS_LT3593
 config LEDS_LT3593
 	tristate "LED driver for LT3593 controllers"
 	tristate "LED driver for LT3593 controllers"
-	depends on LEDS_CLASS && GENERIC_GPIO
+	depends on GENERIC_GPIO
 	help
 	help
 	  This option enables support for LEDs driven by a Linear Technology
 	  This option enables support for LEDs driven by a Linear Technology
 	  LT3593 controller. This controller uses a special one-wire pulse
 	  LT3593 controller. This controller uses a special one-wire pulse
@@ -268,7 +270,7 @@ config LEDS_LT3593
 
 
 config LEDS_ADP5520
 config LEDS_ADP5520
 	tristate "LED Support for ADP5520/ADP5501 PMIC"
 	tristate "LED Support for ADP5520/ADP5501 PMIC"
-	depends on LEDS_CLASS && PMIC_ADP5520
+	depends on PMIC_ADP5520
 	help
 	help
 	  This option enables support for on-chip LED drivers found
 	  This option enables support for on-chip LED drivers found
 	  on Analog Devices ADP5520/ADP5501 PMICs.
 	  on Analog Devices ADP5520/ADP5501 PMICs.
@@ -276,7 +278,12 @@ config LEDS_ADP5520
 	  To compile this driver as a module, choose M here: the module will
 	  To compile this driver as a module, choose M here: the module will
 	  be called leds-adp5520.
 	  be called leds-adp5520.
 
 
-comment "LED Triggers"
+config LEDS_DELL_NETBOOKS
+	tristate "External LED on Dell Business Netbooks"
+	depends on X86 && ACPI_WMI
+	help
+	  This adds support for the Latitude 2100 and similar
+	  notebooks that have an external LED.
 
 
 config LEDS_TRIGGERS
 config LEDS_TRIGGERS
 	bool "LED Trigger support"
 	bool "LED Trigger support"
@@ -285,9 +292,12 @@ config LEDS_TRIGGERS
 	  These triggers allow kernel events to drive the LEDs and can
 	  These triggers allow kernel events to drive the LEDs and can
 	  be configured via sysfs. If unsure, say Y.
 	  be configured via sysfs. If unsure, say Y.
 
 
+if LEDS_TRIGGERS
+
+comment "LED Triggers"
+
 config LEDS_TRIGGER_TIMER
 config LEDS_TRIGGER_TIMER
 	tristate "LED Timer Trigger"
 	tristate "LED Timer Trigger"
-	depends on LEDS_TRIGGERS
 	help
 	help
 	  This allows LEDs to be controlled by a programmable timer
 	  This allows LEDs to be controlled by a programmable timer
 	  via sysfs. Some LED hardware can be programmed to start
 	  via sysfs. Some LED hardware can be programmed to start
@@ -298,14 +308,13 @@ config LEDS_TRIGGER_TIMER
 
 
 config LEDS_TRIGGER_IDE_DISK
 config LEDS_TRIGGER_IDE_DISK
 	bool "LED IDE Disk Trigger"
 	bool "LED IDE Disk Trigger"
-	depends on LEDS_TRIGGERS && IDE_GD_ATA
+	depends on IDE_GD_ATA
 	help
 	help
 	  This allows LEDs to be controlled by IDE disk activity.
 	  This allows LEDs to be controlled by IDE disk activity.
 	  If unsure, say Y.
 	  If unsure, say Y.
 
 
 config LEDS_TRIGGER_HEARTBEAT
 config LEDS_TRIGGER_HEARTBEAT
 	tristate "LED Heartbeat Trigger"
 	tristate "LED Heartbeat Trigger"
-	depends on LEDS_TRIGGERS
 	help
 	help
 	  This allows LEDs to be controlled by a CPU load average.
 	  This allows LEDs to be controlled by a CPU load average.
 	  The flash frequency is a hyperbolic function of the 1-minute
 	  The flash frequency is a hyperbolic function of the 1-minute
@@ -314,7 +323,6 @@ config LEDS_TRIGGER_HEARTBEAT
 
 
 config LEDS_TRIGGER_BACKLIGHT
 config LEDS_TRIGGER_BACKLIGHT
 	tristate "LED backlight Trigger"
 	tristate "LED backlight Trigger"
-	depends on LEDS_TRIGGERS
 	help
 	help
 	  This allows LEDs to be controlled as a backlight device: they
 	  This allows LEDs to be controlled as a backlight device: they
 	  turn off and on when the display is blanked and unblanked.
 	  turn off and on when the display is blanked and unblanked.
@@ -323,7 +331,6 @@ config LEDS_TRIGGER_BACKLIGHT
 
 
 config LEDS_TRIGGER_GPIO
 config LEDS_TRIGGER_GPIO
 	tristate "LED GPIO Trigger"
 	tristate "LED GPIO Trigger"
-	depends on LEDS_TRIGGERS
 	depends on GPIOLIB
 	depends on GPIOLIB
 	help
 	help
 	  This allows LEDs to be controlled by gpio events. It's good
 	  This allows LEDs to be controlled by gpio events. It's good
@@ -336,7 +343,6 @@ config LEDS_TRIGGER_GPIO
 
 
 config LEDS_TRIGGER_DEFAULT_ON
 config LEDS_TRIGGER_DEFAULT_ON
 	tristate "LED Default ON Trigger"
 	tristate "LED Default ON Trigger"
-	depends on LEDS_TRIGGERS
 	help
 	help
 	  This allows LEDs to be initialised in the ON state.
 	  This allows LEDs to be initialised in the ON state.
 	  If unsure, say Y.
 	  If unsure, say Y.
@@ -344,4 +350,8 @@ config LEDS_TRIGGER_DEFAULT_ON
 comment "iptables trigger is under Netfilter config (LED target)"
 comment "iptables trigger is under Netfilter config (LED target)"
 	depends on LEDS_TRIGGERS
 	depends on LEDS_TRIGGERS
 
 
+endif # LEDS_TRIGGERS
+
+endif # LEDS_CLASS
+
 endif # NEW_LEDS
 endif # NEW_LEDS

+ 1 - 0
drivers/leds/Makefile

@@ -34,6 +34,7 @@ obj-$(CONFIG_LEDS_REGULATOR)		+= leds-regulator.o
 obj-$(CONFIG_LEDS_INTEL_SS4200)		+= leds-ss4200.o
 obj-$(CONFIG_LEDS_INTEL_SS4200)		+= leds-ss4200.o
 obj-$(CONFIG_LEDS_LT3593)		+= leds-lt3593.o
 obj-$(CONFIG_LEDS_LT3593)		+= leds-lt3593.o
 obj-$(CONFIG_LEDS_ADP5520)		+= leds-adp5520.o
 obj-$(CONFIG_LEDS_ADP5520)		+= leds-adp5520.o
+obj-$(CONFIG_LEDS_DELL_NETBOOKS)	+= dell-led.o
 
 
 # LED SPI Drivers
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)		+= leds-dac124s085.o
 obj-$(CONFIG_LEDS_DAC124S085)		+= leds-dac124s085.o

+ 200 - 0
drivers/leds/dell-led.c

@@ -0,0 +1,200 @@
+/*
+ * dell_led.c - Dell LED Driver
+ *
+ * Copyright (C) 2010 Dell Inc.
+ * Louis Davis <louis_davis@dell.com>
+ * Jim Dailey <jim_dailey@dell.com>
+ *
+ * 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.
+ *
+ */
+
+#include <linux/acpi.h>
+#include <linux/leds.h>
+
+MODULE_AUTHOR("Louis Davis/Jim Dailey");
+MODULE_DESCRIPTION("Dell LED Control Driver");
+MODULE_LICENSE("GPL");
+
+#define DELL_LED_BIOS_GUID "F6E4FE6E-909D-47cb-8BAB-C9F6F2F8D396"
+MODULE_ALIAS("wmi:" DELL_LED_BIOS_GUID);
+
+/* Error Result Codes: */
+#define INVALID_DEVICE_ID	250
+#define INVALID_PARAMETER	251
+#define INVALID_BUFFER		252
+#define INTERFACE_ERROR		253
+#define UNSUPPORTED_COMMAND	254
+#define UNSPECIFIED_ERROR	255
+
+/* Device ID */
+#define DEVICE_ID_PANEL_BACK	1
+
+/* LED Commands */
+#define CMD_LED_ON	16
+#define CMD_LED_OFF	17
+#define CMD_LED_BLINK	18
+
+struct bios_args {
+	unsigned char length;
+	unsigned char result_code;
+	unsigned char device_id;
+	unsigned char command;
+	unsigned char on_time;
+	unsigned char off_time;
+};
+
+static int dell_led_perform_fn(u8 length,
+		u8 result_code,
+		u8 device_id,
+		u8 command,
+		u8 on_time,
+		u8 off_time)
+{
+	struct bios_args *bios_return;
+	u8 return_code;
+	union acpi_object *obj;
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct acpi_buffer input;
+	acpi_status status;
+
+	struct bios_args args;
+	args.length = length;
+	args.result_code = result_code;
+	args.device_id = device_id;
+	args.command = command;
+	args.on_time = on_time;
+	args.off_time = off_time;
+
+	input.length = sizeof(struct bios_args);
+	input.pointer = &args;
+
+	status = wmi_evaluate_method(DELL_LED_BIOS_GUID,
+		1,
+		1,
+		&input,
+		&output);
+
+	if (ACPI_FAILURE(status))
+		return status;
+
+	obj = output.pointer;
+
+	if (!obj)
+		return -EINVAL;
+	else if (obj->type != ACPI_TYPE_BUFFER) {
+		kfree(obj);
+		return -EINVAL;
+	}
+
+	bios_return = ((struct bios_args *)obj->buffer.pointer);
+	return_code = bios_return->result_code;
+
+	kfree(obj);
+
+	return return_code;
+}
+
+static int led_on(void)
+{
+	return dell_led_perform_fn(3,	/* Length of command */
+		INTERFACE_ERROR,	/* Init to  INTERFACE_ERROR */
+		DEVICE_ID_PANEL_BACK,	/* Device ID */
+		CMD_LED_ON,		/* Command */
+		0,			/* not used */
+		0);			/* not used */
+}
+
+static int led_off(void)
+{
+	return dell_led_perform_fn(3,	/* Length of command */
+		INTERFACE_ERROR,	/* Init to  INTERFACE_ERROR */
+		DEVICE_ID_PANEL_BACK,	/* Device ID */
+		CMD_LED_OFF,		/* Command */
+		0,			/* not used */
+		0);			/* not used */
+}
+
+static int led_blink(unsigned char on_eighths,
+		unsigned char off_eighths)
+{
+	return dell_led_perform_fn(5,	/* Length of command */
+		INTERFACE_ERROR,	/* Init to  INTERFACE_ERROR */
+		DEVICE_ID_PANEL_BACK,	/* Device ID */
+		CMD_LED_BLINK,		/* Command */
+		on_eighths,		/* blink on in eigths of a second */
+		off_eighths);		/* blink off in eights of a second */
+}
+
+static void dell_led_set(struct led_classdev *led_cdev,
+		enum led_brightness value)
+{
+	if (value == LED_OFF)
+		led_off();
+	else
+		led_on();
+}
+
+static int dell_led_blink(struct led_classdev *led_cdev,
+		unsigned long *delay_on,
+		unsigned long *delay_off)
+{
+	unsigned long on_eighths;
+	unsigned long off_eighths;
+
+	/* The Dell LED delay is based on 125ms intervals.
+	   Need to round up to next interval. */
+
+	on_eighths = (*delay_on + 124) / 125;
+	if (0 == on_eighths)
+		on_eighths = 1;
+	if (on_eighths > 255)
+		on_eighths = 255;
+	*delay_on = on_eighths * 125;
+
+	off_eighths = (*delay_off + 124) / 125;
+	if (0 == off_eighths)
+		off_eighths = 1;
+	if (off_eighths > 255)
+		off_eighths = 255;
+	*delay_off = off_eighths * 125;
+
+	led_blink(on_eighths, off_eighths);
+
+	return 0;
+}
+
+static struct led_classdev dell_led = {
+	.name		= "dell::lid",
+	.brightness	= LED_OFF,
+	.max_brightness = 1,
+	.brightness_set = dell_led_set,
+	.blink_set	= dell_led_blink,
+	.flags		= LED_CORE_SUSPENDRESUME,
+};
+
+static int __init dell_led_init(void)
+{
+	int error = 0;
+
+	if (!wmi_has_guid(DELL_LED_BIOS_GUID))
+		return -ENODEV;
+
+	error = led_off();
+	if (error != 0)
+		return -ENODEV;
+
+	return led_classdev_register(NULL, &dell_led);
+}
+
+static void __exit dell_led_exit(void)
+{
+	led_classdev_unregister(&dell_led);
+
+	led_off();
+}
+
+module_init(dell_led_init);
+module_exit(dell_led_exit);

+ 9 - 33
drivers/leds/led-class.c

@@ -72,11 +72,14 @@ static ssize_t led_max_brightness_show(struct device *dev,
 	return sprintf(buf, "%u\n", led_cdev->max_brightness);
 	return sprintf(buf, "%u\n", led_cdev->max_brightness);
 }
 }
 
 
-static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store);
-static DEVICE_ATTR(max_brightness, 0444, led_max_brightness_show, NULL);
+static struct device_attribute led_class_attrs[] = {
+	__ATTR(brightness, 0644, led_brightness_show, led_brightness_store),
+	__ATTR(max_brightness, 0644, led_max_brightness_show, NULL),
 #ifdef CONFIG_LEDS_TRIGGERS
 #ifdef CONFIG_LEDS_TRIGGERS
-static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
+	__ATTR(trigger, 0644, led_trigger_show, led_trigger_store),
 #endif
 #endif
+	__ATTR_NULL,
+};
 
 
 /**
 /**
  * led_classdev_suspend - suspend an led_classdev.
  * led_classdev_suspend - suspend an led_classdev.
@@ -127,18 +130,11 @@ static int led_resume(struct device *dev)
  */
  */
 int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
 int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
 {
 {
-	int rc;
-
 	led_cdev->dev = device_create(leds_class, parent, 0, led_cdev,
 	led_cdev->dev = device_create(leds_class, parent, 0, led_cdev,
 				      "%s", led_cdev->name);
 				      "%s", led_cdev->name);
 	if (IS_ERR(led_cdev->dev))
 	if (IS_ERR(led_cdev->dev))
 		return PTR_ERR(led_cdev->dev);
 		return PTR_ERR(led_cdev->dev);
 
 
-	/* register the attributes */
-	rc = device_create_file(led_cdev->dev, &dev_attr_brightness);
-	if (rc)
-		goto err_out;
-
 #ifdef CONFIG_LEDS_TRIGGERS
 #ifdef CONFIG_LEDS_TRIGGERS
 	init_rwsem(&led_cdev->trigger_lock);
 	init_rwsem(&led_cdev->trigger_lock);
 #endif
 #endif
@@ -150,36 +146,18 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
 	if (!led_cdev->max_brightness)
 	if (!led_cdev->max_brightness)
 		led_cdev->max_brightness = LED_FULL;
 		led_cdev->max_brightness = LED_FULL;
 
 
-	rc = device_create_file(led_cdev->dev, &dev_attr_max_brightness);
-	if (rc)
-		goto err_out_attr_max;
-
 	led_update_brightness(led_cdev);
 	led_update_brightness(led_cdev);
 
 
 #ifdef CONFIG_LEDS_TRIGGERS
 #ifdef CONFIG_LEDS_TRIGGERS
-	rc = device_create_file(led_cdev->dev, &dev_attr_trigger);
-	if (rc)
-		goto err_out_led_list;
-
 	led_trigger_set_default(led_cdev);
 	led_trigger_set_default(led_cdev);
 #endif
 #endif
 
 
-	printk(KERN_INFO "Registered led device: %s\n",
+	printk(KERN_DEBUG "Registered led device: %s\n",
 			led_cdev->name);
 			led_cdev->name);
 
 
 	return 0;
 	return 0;
-
-#ifdef CONFIG_LEDS_TRIGGERS
-err_out_led_list:
-	device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
-#endif
-err_out_attr_max:
-	device_remove_file(led_cdev->dev, &dev_attr_brightness);
-	list_del(&led_cdev->node);
-err_out:
-	device_unregister(led_cdev->dev);
-	return rc;
 }
 }
+
 EXPORT_SYMBOL_GPL(led_classdev_register);
 EXPORT_SYMBOL_GPL(led_classdev_register);
 
 
 /**
 /**
@@ -190,10 +168,7 @@ EXPORT_SYMBOL_GPL(led_classdev_register);
  */
  */
 void led_classdev_unregister(struct led_classdev *led_cdev)
 void led_classdev_unregister(struct led_classdev *led_cdev)
 {
 {
-	device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
-	device_remove_file(led_cdev->dev, &dev_attr_brightness);
 #ifdef CONFIG_LEDS_TRIGGERS
 #ifdef CONFIG_LEDS_TRIGGERS
-	device_remove_file(led_cdev->dev, &dev_attr_trigger);
 	down_write(&led_cdev->trigger_lock);
 	down_write(&led_cdev->trigger_lock);
 	if (led_cdev->trigger)
 	if (led_cdev->trigger)
 		led_trigger_set(led_cdev, NULL);
 		led_trigger_set(led_cdev, NULL);
@@ -215,6 +190,7 @@ static int __init leds_init(void)
 		return PTR_ERR(leds_class);
 		return PTR_ERR(leds_class);
 	leds_class->suspend = led_suspend;
 	leds_class->suspend = led_suspend;
 	leds_class->resume = led_resume;
 	leds_class->resume = led_resume;
+	leds_class->dev_attrs = led_class_attrs;
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 2
drivers/leds/leds-gpio.c

@@ -211,7 +211,6 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev,
 					const struct of_device_id *match)
 					const struct of_device_id *match)
 {
 {
 	struct device_node *np = ofdev->node, *child;
 	struct device_node *np = ofdev->node, *child;
-	struct gpio_led led;
 	struct gpio_led_of_platform_data *pdata;
 	struct gpio_led_of_platform_data *pdata;
 	int count = 0, ret;
 	int count = 0, ret;
 
 
@@ -226,8 +225,8 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev,
 	if (!pdata)
 	if (!pdata)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	memset(&led, 0, sizeof(led));
 	for_each_child_of_node(np, child) {
 	for_each_child_of_node(np, child) {
+		struct gpio_led led = {};
 		enum of_gpio_flags flags;
 		enum of_gpio_flags flags;
 		const char *state;
 		const char *state;
 
 

+ 1 - 1
drivers/leds/leds-ss4200.c

@@ -63,7 +63,7 @@ MODULE_LICENSE("GPL");
 /*
 /*
  * PCI ID of the Intel ICH7 LPC Device within which the GPIO block lives.
  * PCI ID of the Intel ICH7 LPC Device within which the GPIO block lives.
  */
  */
-static struct pci_device_id ich7_lpc_pci_id[] =
+static const struct pci_device_id ich7_lpc_pci_id[] =
 {
 {
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1) },