summaryrefslogtreecommitdiff
path: root/packages/linux/ixp4xx-kernel
diff options
context:
space:
mode:
authorJohn Bowler <jbowler@nslu2-linux.org>2006-01-22 09:14:24 +0000
committerOpenEmbedded Project <openembedded-devel@lists.openembedded.org>2006-01-22 09:14:24 +0000
commit65fd7a75e0f5786a0582b33f7ba01e814692f992 (patch)
treee7092ced8612d13498fcb4eb1190e55e63ab3bf9 /packages/linux/ixp4xx-kernel
parentb23d1cb9a50613922861d94f8ff24005656877c3 (diff)
ixp4xx-kernel: new LED driver in 2.6.15.1
slugos-init: update for new LED support in 0.10 - the kernel now uses the RP LED driver code, the new patches add a generic ixp4xx driver and board level definitions for nslu2, loft and nas100d
Diffstat (limited to 'packages/linux/ixp4xx-kernel')
-rw-r--r--packages/linux/ixp4xx-kernel/2.6.15/95-ixp4xx-leds.patch260
-rw-r--r--packages/linux/ixp4xx-kernel/2.6.15/96-loft-leds.patch86
-rw-r--r--packages/linux/ixp4xx-kernel/2.6.15/96-nas100d-leds.patch78
-rw-r--r--packages/linux/ixp4xx-kernel/2.6.15/96-nslu2-leds.patch90
-rw-r--r--packages/linux/ixp4xx-kernel/2.6.15/defconfig9
5 files changed, 523 insertions, 0 deletions
diff --git a/packages/linux/ixp4xx-kernel/2.6.15/95-ixp4xx-leds.patch b/packages/linux/ixp4xx-kernel/2.6.15/95-ixp4xx-leds.patch
new file mode 100644
index 0000000000..b081519893
--- /dev/null
+++ b/packages/linux/ixp4xx-kernel/2.6.15/95-ixp4xx-leds.patch
@@ -0,0 +1,260 @@
+NEW_LEDS support for ixp4xx boards where LEDs are connected
+to the GPIO lines.
+
+This includes a new generic ixp4xx driver (leds-ixp4xx-gpio.c
+name "IXP4XX-GPIO-LED") and a patch to the original leds.h to
+make the 'name' field of led_device (const char)
+
+Signed-off-by: John Bowler <jbowler@acm.org>
+
+--- linux-2.6.15/drivers/leds/Kconfig 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.15/drivers/leds/Kconfig 1970-01-01 00:00:00.000000000 +0000
+@@ -43,6 +43,15 @@ config LEDS_SPITZ
+ This option enables support for the LEDs on Sharp Zaurus
+ SL-Cxx00 series (C1000, C3000, C3100).
+
++config LEDS_IXP4XX
++ tristate "LED Support for GPIO connected LEDs on IXP4XX processors"
++ depends LEDS_CLASS && ARCH_IXP4XX
++ help
++ This option enables support for the LEDs connected to GPIO
++ outputs of the Intel IXP4XX processors. To be useful the
++ particular board must have LEDs and they must be connected
++ to the GPIO lines. If unsure, say Y.
++
+ config LEDS_TRIGGER_TIMER
+ tristate "LED Timer Trigger"
+ depends LEDS_TRIGGERS
+--- linux-2.6.15/drivers/leds/Makefile 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.15/drivers/leds/Makefile 1970-01-01 00:00:00.000000000 +0000
+@@ -8,6 +8,7 @@ obj-$(CONFIG_LEDS_TRIGGERS) += led-trig
+ obj-$(CONFIG_LEDS_CORGI) += leds-corgi.o
+ obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o
+ obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o
++obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o
+
+ # LED Triggers
+ obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
+--- linux-2.6.15/drivers/leds/leds-ixp4xx-gpio.c 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.15/drivers/leds/leds-ixp4xx-gpio.c 1970-01-01 00:00:00.000000000 +0000
+@@ -0,0 +1,209 @@
++/*
++ * IXP4XX GPIO driver LED driver
++ *
++ * Author: John Bowler <jbowler@acm.org>
++ *
++ * Copyright (c) 2006 John Bowler
++ *
++ * Permission is hereby granted, free of charge, to any
++ * person obtaining a copy of this software and associated
++ * documentation files (the "Software"), to deal in the
++ * Software without restriction, including without
++ * limitation the rights to use, copy, modify, merge,
++ * publish, distribute, sublicense, and/or sell copies of
++ * the Software, and to permit persons to whom the
++ * Software is furnished to do so, subject to the
++ * following conditions:
++ *
++ * The above copyright notice and this permission notice
++ * shall be included in all copies or substantial portions
++ * of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
++ * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
++ * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
++ * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
++ * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
++ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
++ * OTHER DEALINGS IN THE SOFTWARE.
++ *
++ */
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/spinlock.h>
++#include <linux/leds.h>
++#include <asm/arch/hardware.h>
++
++extern spinlock_t gpio_lock;
++
++/* Up to 16 gpio lines are possible. */
++#define GPIO_MAX 16
++static struct ixp4xxgpioled_device {
++ struct led_device ancestor;
++ int flags;
++} ixp4xxgpioled_devices[GPIO_MAX];
++
++void ixp4xxgpioled_brightness_set(struct led_device *pled, int value)
++{
++ const struct ixp4xxgpioled_device *const ixp4xx_dev =
++ container_of(pled, struct ixp4xxgpioled_device, ancestor);
++ const u32 gpio_pin = ixp4xx_dev - ixp4xxgpioled_devices;
++
++ if (gpio_pin < GPIO_MAX && ixp4xx_dev->ancestor.name != 0) {
++ /* Set or clear the 'gpio_pin' bit according to the style
++ * and the required setting (value > 0 == on)
++ */
++ const int gpio_value =
++ (value > 0) == (ixp4xx_dev->flags != IXP4XX_GPIO_LOW) ?
++ IXP4XX_GPIO_HIGH : IXP4XX_GPIO_LOW;
++
++ {
++ unsigned long flags;
++ spin_lock_irqsave(&gpio_lock, flags);
++ gpio_line_set(gpio_pin, gpio_value);
++ spin_unlock_irqrestore(&gpio_lock, flags);
++ }
++ }
++}
++
++/* LEDs are described in resources, the following iterates over the valid
++ * LED resources.
++ */
++#define for_all_leds(i, pdev) \
++ for (i=0; i<pdev->num_resources; ++i) \
++ if (pdev->resource[i].start < GPIO_MAX && \
++ pdev->resource[i].name != 0)
++
++/* The following applies 'operation' to each LED from the given platform,
++ * the function always returns 0 to allow tail call elimination.
++ */
++static int apply_to_all_leds(struct platform_device *pdev,
++ void (*operation)(struct led_device *pled)) {
++ int i;
++ for_all_leds(i, pdev)
++ operation(&ixp4xxgpioled_devices[pdev->resource[i].start].ancestor);
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int ixp4xxgpioled_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ return apply_to_all_leds(pdev, leds_device_suspend);
++}
++
++static int ixp4xxgpioled_resume(struct platform_device *pdev)
++{
++ return apply_to_all_leds(pdev, leds_device_resume);
++}
++#endif
++
++static void ixp4xxgpioled_remove_one_led(struct led_device *pled) {
++ leds_device_unregister(pled);
++ pled->name = 0;
++}
++
++static int ixp4xxgpioled_remove(struct platform_device *pdev)
++{
++ return apply_to_all_leds(pdev, ixp4xxgpioled_remove_one_led);
++}
++
++static int ixp4xxgpioled_probe(struct platform_device *pdev)
++{
++ /* The board level has to tell the driver where the
++ * LEDs are connected - there is no way to find out
++ * electrically. It must also say whether the GPIO
++ * lines are active high or active low.
++ *
++ * To do this read the num_resources (the number of
++ * LEDs) and the struct resource (the data for each
++ * LED). The name comes from the resource, and it
++ * isn't copied.
++ */
++ int i;
++ for_all_leds(i, pdev) {
++ const u8 gpio_pin = pdev->resource[i].start;
++ int rc;
++
++ if (ixp4xxgpioled_devices[gpio_pin].ancestor.name == 0) {
++ unsigned long flags;
++
++ spin_lock_irqsave(&gpio_lock, flags);
++ gpio_line_config(gpio_pin, IXP4XX_GPIO_OUT);
++ /* The config can, apparently, reset the state,
++ * I suspect the gpio line may be an input and
++ * the config may cause the line to be latched,
++ * so the setting depends on how the LED is
++ * connected to the line (which affects how it
++ * floats if not driven).
++ */
++ gpio_line_set(gpio_pin, IXP4XX_GPIO_HIGH);
++ spin_unlock_irqrestore(&gpio_lock, flags);
++
++ ixp4xxgpioled_devices[gpio_pin].flags =
++ pdev->resource[i].flags & IORESOURCE_BITS;
++
++ ixp4xxgpioled_devices[gpio_pin].ancestor.name =
++ pdev->resource[i].name;
++
++ /* This is how a board manufacturer makes the LED
++ * come on on reset - the GPIO line will be high, so
++ * make the LED light when the line is low...
++ */
++ if (ixp4xxgpioled_devices[gpio_pin].flags != IXP4XX_GPIO_LOW)
++ ixp4xxgpioled_devices[gpio_pin].ancestor.brightness = 100;
++ else
++ ixp4xxgpioled_devices[gpio_pin].ancestor.brightness = 0;
++
++ ixp4xxgpioled_devices[gpio_pin].ancestor.flags = 0;
++
++ ixp4xxgpioled_devices[gpio_pin].ancestor.brightness_set =
++ ixp4xxgpioled_brightness_set;
++
++ ixp4xxgpioled_devices[gpio_pin].ancestor.default_trigger = 0;
++ }
++
++ rc = leds_device_register(&pdev->dev,
++ &ixp4xxgpioled_devices[gpio_pin].ancestor);
++ if (rc < 0) {
++ ixp4xxgpioled_devices[gpio_pin].ancestor.name = 0;
++ ixp4xxgpioled_remove(pdev);
++ return rc;
++ }
++ }
++
++ return 0;
++}
++
++static struct platform_driver ixp4xxgpioled_driver = {
++ .probe = ixp4xxgpioled_probe,
++ .remove = ixp4xxgpioled_remove,
++#ifdef CONFIG_PM
++ .suspend = ixp4xxgpioled_suspend,
++ .resume = ixp4xxgpioled_resume,
++#endif
++ .driver = {
++ .name = "IXP4XX-GPIO-LED",
++ },
++};
++
++static int __devinit ixp4xxgpioled_init(void)
++{
++ return platform_driver_register(&ixp4xxgpioled_driver);
++}
++
++static void ixp4xxgpioled_exit(void)
++{
++ platform_driver_unregister(&ixp4xxgpioled_driver);
++}
++
++module_init(ixp4xxgpioled_init);
++module_exit(ixp4xxgpioled_exit);
++
++MODULE_AUTHOR("John Bowler <jbowler@acm.org>");
++MODULE_DESCRIPTION("IXP4XX GPIO LED driver");
++MODULE_LICENSE("MIT");
+--- linux-2.6.15/include/linux/leds.h 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.15/include/linux/leds.h 1970-01-01 00:00:00.000000000 +0000
+@@ -16,7 +16,7 @@ struct class_device;
+ * LED Core
+ */
+ struct led_device {
+- char *name;
++ const char *name;
+ int brightness;
+ int flags;
+ #define LED_SUSPENDED (1 << 0)
diff --git a/packages/linux/ixp4xx-kernel/2.6.15/96-loft-leds.patch b/packages/linux/ixp4xx-kernel/2.6.15/96-loft-leds.patch
new file mode 100644
index 0000000000..6098afcf8f
--- /dev/null
+++ b/packages/linux/ixp4xx-kernel/2.6.15/96-loft-leds.patch
@@ -0,0 +1,86 @@
+NEW_LEDS support for the loft board
+
+Signed-off-by: John Bowler <jbowler@acm.org>
+
+--- linux-2.6.15/arch/arm/mach-ixp4xx/ixdp425-setup.c 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.15/arch/arm/mach-ixp4xx/ixdp425-setup.c 1970-01-01 00:00:00.000000000 +0000
+@@ -15,6 +15,7 @@
+ #include <linux/tty.h>
+ #include <linux/serial_8250.h>
+ #include <linux/eeprom.h>
++#include <linux/leds.h>
+
+ #include <asm/types.h>
+ #include <asm/setup.h>
+@@ -200,6 +201,53 @@ MACHINE_END
+ * maybe the ixdp425 too.
+ */
+ #ifdef CONFIG_MACH_LOFT
++#ifdef CONFIG_LEDS_CLASS
++static struct resource loft_led_resources[] = {
++ {
++ .name = "J8:1", /* header */
++ .start = 0,
++ .end = 0,
++ .flags = IXP4XX_GPIO_LOW,
++ },
++ {
++ .name = "J8:3", /* header */
++ .start = 1,
++ .end = 1,
++ .flags = IXP4XX_GPIO_LOW,
++ },
++ {
++ .name = "J8:5", /* header */
++ .start = 2,
++ .end = 2,
++ .flags = IXP4XX_GPIO_LOW,
++ },
++ {
++ .name = "ready", /* green led, also J8 pin 7 */
++ .start = 3,
++ .end = 3,
++ .flags = IXP4XX_GPIO_LOW,
++ },
++ {
++ .name = "J8:9", /* header */
++ .start = 4,
++ .end = 4,
++ .flags = IXP4XX_GPIO_LOW,
++ },
++};
++
++static struct platform_device loft_leds = {
++ .name = "IXP4XX-GPIO-LED",
++ .id = -1,
++ .num_resources = ARRAY_SIZE(loft_led_resources),
++ .resource = loft_led_resources,
++};
++#endif
++
++static struct platform_device *loft_devices[] __initdata = {
++ &ixdp425_i2c_controller,
++ &ixdp425_flash,
++};
++
+ /*
+ * When the EEPROM is added the MAC address are read from it.
+ */
+@@ -244,7 +292,16 @@ static void __init loft_init(void)
+
+ ixp4xx_sys_init();
+
+- platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices));
++ /* Put the UART in first for debugging, don't care if it fails. */
++ (void)platform_device_register(&ixdp425_uart);
++
++ /* These should work... */
++ platform_add_devices(loft_devices, ARRAY_SIZE(loft_devices));
++
++#ifdef CONFIG_LEDS_CLASS
++ /* We don't care if this fails. */
++ (void)platform_device_register(&loft_leds);
++#endif
+ }
+
+ MACHINE_START(LOFT, "Giant Shoulder Inc Loft board")
diff --git a/packages/linux/ixp4xx-kernel/2.6.15/96-nas100d-leds.patch b/packages/linux/ixp4xx-kernel/2.6.15/96-nas100d-leds.patch
new file mode 100644
index 0000000000..7025b1ac20
--- /dev/null
+++ b/packages/linux/ixp4xx-kernel/2.6.15/96-nas100d-leds.patch
@@ -0,0 +1,78 @@
+NEW_LEDS support for the IOMega NAS100D
+
+Signed-off-by: John Bowler <jbowler@acm.org>
+
+--- linux-2.6.15/arch/arm/mach-ixp4xx/nas100d-setup.c 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.15/arch/arm/mach-ixp4xx/nas100d-setup.c 1970-01-01 00:00:00.000000000 +0000
+@@ -16,6 +16,7 @@
+ #include <linux/serial.h>
+ #include <linux/serial_8250.h>
+ #include <linux/mtd/mtd.h>
++#include <linux/leds.h>
+
+ #include <asm/setup.h>
+ #include <asm/memory.h>
+@@ -44,6 +45,36 @@ static struct platform_device nas100d_fl
+ .resource = &nas100d_flash_resource,
+ };
+
++#ifdef CONFIG_LEDS_CLASS
++static struct resource nas100d_led_resources[] = {
++ {
++ .name = "wlan", /* green led */
++ .start = 0,
++ .end = 0,
++ .flags = IXP4XX_GPIO_LOW,
++ },
++ {
++ .name = "ready", /* blue power led (off is flashing!) */
++ .start = 15,
++ .end = 15,
++ .flags = IXP4XX_GPIO_LOW,
++ },
++ {
++ .name = "disk-1", /* yellow led */
++ .start = 3,
++ .end = 3,
++ .flags = IXP4XX_GPIO_LOW,
++ },
++};
++
++static struct platform_device nas100d_leds = {
++ .name = "IXP4XX-GPIO-LED",
++ .id = -1,
++ .num_resources = ARRAY_SIZE(nas100d_led_resources),
++ .resource = nas100d_led_resources,
++};
++#endif
++
+ static struct ixp4xx_i2c_pins nas100d_i2c_gpio_pins = {
+ .sda_pin = NAS100D_SDA_PIN,
+ .scl_pin = NAS100D_SCL_PIN,
+@@ -106,7 +137,6 @@ static struct platform_device nas100d_rt
+ static struct platform_device *nas100d_devices[] __initdata = {
+ &nas100d_i2c_controller,
+ &nas100d_flash,
+- &nas100d_uart,
+ &nas100d_rtc,
+ };
+
+@@ -163,7 +193,18 @@ static void __init nas100d_init(void)
+
+ pm_power_off = nas100d_power_off;
+
++ /* This is only useful on a modified machine, but it is valuable
++ * to have it first in order to see debug messages, and so that
++ * it does *not* get removed if platform_add_devices fails!
++ */
++ (void)platform_device_register(&nas100d_uart);
++
+ platform_add_devices(nas100d_devices, ARRAY_SIZE(nas100d_devices));
++
++#ifdef CONFIG_LEDS_CLASS
++ /* We don't care whether or not this works. */
++ (void)platform_device_register(&nas100d_leds);
++#endif
+ }
+
+ /*
diff --git a/packages/linux/ixp4xx-kernel/2.6.15/96-nslu2-leds.patch b/packages/linux/ixp4xx-kernel/2.6.15/96-nslu2-leds.patch
new file mode 100644
index 0000000000..2898e83fdb
--- /dev/null
+++ b/packages/linux/ixp4xx-kernel/2.6.15/96-nslu2-leds.patch
@@ -0,0 +1,90 @@
+NEW_LEDS support for the LinkSys NSLU2
+
+Signed-off-by: John Bowler <jbowler@acm.org>
+
+--- linux-2.6.15/arch/arm/mach-ixp4xx/nslu2-setup.c 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.15/arch/arm/mach-ixp4xx/nslu2-setup.c 1970-01-01 00:00:00.000000000 +0000
+@@ -17,6 +17,7 @@
+ #include <linux/serial.h>
+ #include <linux/serial_8250.h>
+ #include <linux/mtd/mtd.h>
++#include <linux/leds.h>
+
+ #include <asm/setup.h>
+ #include <asm/memory.h>
+@@ -50,6 +51,48 @@ static struct ixp4xx_i2c_pins nslu2_i2c_
+ .scl_pin = NSLU2_SCL_PIN,
+ };
+
++#ifdef CONFIG_LEDS_CLASS
++static struct resource nslu2_led_resources[] = {
++ {
++ .name = "ready", /* green led */
++ .start = NSLU2_LED_GRN,
++ .end = NSLU2_LED_GRN,
++ .flags = IXP4XX_GPIO_HIGH,
++ },
++ {
++ .name = "status", /* red led */
++ .start = NSLU2_LED_RED,
++ .end = NSLU2_LED_RED,
++ .flags = IXP4XX_GPIO_HIGH,
++ },
++ {
++ .name = "disk-1",
++ .start = NSLU2_LED_DISK1,
++ .end = NSLU2_LED_DISK1,
++ .flags = IXP4XX_GPIO_LOW,
++ },
++ {
++ .name = "disk-2",
++ .start = NSLU2_LED_DISK2,
++ .end = NSLU2_LED_DISK2,
++ .flags = IXP4XX_GPIO_LOW,
++ },
++ {
++ .name = "buzzer",
++ .start = NSLU2_GPIO_BUZZ,
++ .end = NSLU2_GPIO_BUZZ,
++ .flags = IXP4XX_GPIO_LOW,
++ },
++};
++
++static struct platform_device nslu2_leds = {
++ .name = "IXP4XX-GPIO-LED",
++ .id = -1,
++ .num_resources = ARRAY_SIZE(nslu2_led_resources),
++ .resource = nslu2_led_resources,
++};
++#endif
++
+ static struct platform_device nslu2_i2c_controller = {
+ .name = "IXP4XX-I2C",
+ .id = 0,
+@@ -103,7 +146,6 @@ static struct platform_device nslu2_uart
+ static struct platform_device *nslu2_devices[] __initdata = {
+ &nslu2_i2c_controller,
+ &nslu2_flash,
+- &nslu2_uart,
+ };
+
+ static void nslu2_power_off(void)
+@@ -164,7 +206,18 @@ static void __init nslu2_init(void)
+
+ pm_power_off = nslu2_power_off;
+
++ /* This is only useful on a modified machine, but it is valuable
++ * to have it first in order to see debug messages, and so that
++ * it does *not* get removed if platform_add_devices fails!
++ */
++ (void)platform_device_register(&nslu2_uart);
++
+ platform_add_devices(nslu2_devices, ARRAY_SIZE(nslu2_devices));
++
++#ifdef CONFIG_LEDS_CLASS
++ /* We don't care whether or not this works. */
++ (void)platform_device_register(&nslu2_leds);
++#endif
+ }
+
+ /*
diff --git a/packages/linux/ixp4xx-kernel/2.6.15/defconfig b/packages/linux/ixp4xx-kernel/2.6.15/defconfig
index 719c10e526..54fe2c613f 100644
--- a/packages/linux/ixp4xx-kernel/2.6.15/defconfig
+++ b/packages/linux/ixp4xx-kernel/2.6.15/defconfig
@@ -1065,6 +1065,15 @@ CONFIG_HWMON=y
#
#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_IXP4XX=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+
+#
# Multimedia devices
#
CONFIG_VIDEO_DEV=m