From: Imre Kaloz Date: Fri, 23 May 2008 15:25:56 +0000 (+0000) Subject: add USB fixup & board detection for the Cambria, plus merge the LED latch driver... X-Git-Tag: reboot~26453 X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=8f5f48527e1457e0c8c95f578038da13765d131a;p=openwrt%2Fopenwrt.git add USB fixup & board detection for the Cambria, plus merge the LED latch driver into the Avila LED patch -- again, thanks Chris :) SVN-Revision: 11250 --- diff --git a/target/linux/ixp4xx/patches-2.6.25/190-cambria_support.patch b/target/linux/ixp4xx/patches-2.6.25/190-cambria_support.patch index ee207d1014..82368abd93 100644 --- a/target/linux/ixp4xx/patches-2.6.25/190-cambria_support.patch +++ b/target/linux/ixp4xx/patches-2.6.25/190-cambria_support.patch @@ -125,11 +125,10 @@ Index: linux-2.6.25.4/arch/arm/mach-ixp4xx/cambria-pci.c +} + +subsys_initcall(cambria_pci_init); -Index: linux-2.6.25.4/arch/arm/mach-ixp4xx/cambria-setup.c -=================================================================== ---- /dev/null -+++ linux-2.6.25.4/arch/arm/mach-ixp4xx/cambria-setup.c -@@ -0,0 +1,250 @@ +diff -ruN /usr/src/openwrt/clean/linux-2.6.25.4/arch/arm/mach-ixp4xx/cambria-setup.c linux-2.6.25.4/arch/arm/mach-ixp4xx/cambria-setup.c +--- /usr/src/openwrt/clean/linux-2.6.25.4/arch/arm/mach-ixp4xx/cambria-setup.c 1969-12-31 16:00:00.000000000 -0800 ++++ linux-2.6.25.4/arch/arm/mach-ixp4xx/cambria-setup.c 2008-05-20 16:02:43.000000000 -0700 +@@ -0,0 +1,445 @@ +/* + * arch/arm/mach-ixp4xx/cambria-setup.c + * @@ -157,7 +156,8 @@ Index: linux-2.6.25.4/arch/arm/mach-ixp4xx/cambria-setup.c +# include +# include +#endif -+ ++ ++#include +#include +#include +#include @@ -168,6 +168,13 @@ Index: linux-2.6.25.4/arch/arm/mach-ixp4xx/cambria-setup.c +#include +#include + ++struct cambria_board_info { ++ unsigned char *model; ++ void (* setup)(void); ++}; ++ ++static struct cambria_board_info *cambria_info __initdata; ++ +static struct flash_platform_data cambria_flash_data = { + .map_name = "cfi_probe", + .width = 2, @@ -257,97 +264,264 @@ Index: linux-2.6.25.4/arch/arm/mach-ixp4xx/cambria-setup.c + .resource = cambria_pata_resources, +}; + -+static struct eth_plat_info cambria_plat_eth[] = { -+ { -+ .phy = 2, -+ .rxq = 4, -+ .txreadyq = 21, -+ }, { -+ .phy = 1, -+ .rxq = 2, -+ .txreadyq = 19, -+ } ++static struct eth_plat_info cambria_npec_data = { ++ .phy = 2, ++ .rxq = 4, ++ .txreadyq = 21, ++}; ++ ++static struct eth_plat_info cambria_npea_data = { ++ .phy = 1, ++ .rxq = 2, ++ .txreadyq = 19, ++}; ++ ++static struct platform_device cambria_npec_device = { ++ .name = "ixp4xx_eth", ++ .id = IXP4XX_ETH_NPEC, ++ .dev.platform_data = &cambria_npec_data, ++}; ++ ++static struct platform_device cambria_npea_device = { ++ .name = "ixp4xx_eth", ++ .id = IXP4XX_ETH_NPEA, ++ .dev.platform_data = &cambria_npea_data, +}; + -+static struct platform_device cambria_eth[] = { -+ { -+ .name = "ixp4xx_eth", -+ .id = IXP4XX_ETH_NPEC, -+ .dev.platform_data = cambria_plat_eth, -+ }, { -+ .name = "ixp4xx_eth", -+ .id = IXP4XX_ETH_NPEA, -+ .dev.platform_data = cambria_plat_eth + 1, ++static struct gpio_led cambria_gpio_leds[] = { ++ { ++ .name = "user", /* green led */ ++ .gpio = 5, ++ .active_low = 1, ++ } ++}; ++ ++static struct gpio_led_platform_data cambria_gpio_leds_data = { ++ .num_leds = 1, ++ .leds = cambria_gpio_leds, ++}; ++ ++static struct platform_device cambria_gpio_leds_device = { ++ .name = "leds-gpio", ++ .id = -1, ++ .dev.platform_data = &cambria_gpio_leds_data, ++}; ++ ++ ++static struct latch_led cambria_latch_leds[] = { ++ { ++ .name = "ledA", /* green led */ ++ .bit = 0, ++ }, ++ { ++ .name = "ledB", /* green led */ ++ .bit = 1, ++ }, ++ { ++ .name = "ledC", /* green led */ ++ .bit = 2, ++ }, ++ { ++ .name = "ledD", /* green led */ ++ .bit = 3, ++ }, ++ { ++ .name = "ledE", /* green led */ ++ .bit = 4, ++ }, ++ { ++ .name = "ledF", /* green led */ ++ .bit = 5, ++ }, ++ { ++ .name = "ledG", /* green led */ ++ .bit = 6, ++ }, ++ { ++ .name = "ledH", /* green led */ ++ .bit = 7, + } +}; + -+#ifdef CONFIG_LEDS_IXP4XX -+static struct platform_device cambria_leds_pld = { -+ .name = "IXP4XX-PLD-LED", -+ .id = -1, -+ .num_resources = 0, ++static struct latch_led_platform_data cambria_latch_leds_data = { ++ .num_leds = 8, ++ .leds = cambria_latch_leds, ++ .mem = 0x53F40000, +}; + -+static struct platform_device cambria_leds_mem = { -+ .name = "IXP4XX-MEM-LED", -+ .id = -1, -+ .num_resources = 0, ++static struct platform_device cambria_latch_leds_device = { ++ .name = "leds-latch", ++ .id = -1, ++ .dev.platform_data = &cambria_latch_leds_data, +}; -+#endif ++ ++static struct resource cambria_usb0_resources[] = { ++ { ++ .start = 0xCD000000, ++ .end = 0xCD000300, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = 32, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct resource cambria_usb1_resources[] = { ++ { ++ .start = 0xCE000000, ++ .end = 0xCE000300, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = 33, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static u64 ehci_dma_mask = ~(u32)0; ++ ++static struct platform_device cambria_usb0_device = { ++ .name = "ixp4xx-ehci", ++ .id = 0, ++ .dev = { ++ .dma_mask = &ehci_dma_mask, ++ .coherent_dma_mask = 0xffffffff, ++ }, ++ .resource = cambria_usb0_resources, ++ .num_resources = 2, ++}; ++ ++static struct platform_device cambria_usb1_device = { ++ .name = "ixp4xx-ehci", ++ .id = 1, ++ .dev = { ++ .dma_mask = &ehci_dma_mask, ++ .coherent_dma_mask = 0xffffffff, ++ }, ++ .resource = cambria_usb1_resources, ++ .num_resources = 2, ++}; ++ + +static struct platform_device *cambria_devices[] __initdata = { + &cambria_i2c_gpio, + &cambria_flash, + &cambria_uart, -+#ifdef CONFIG_LEDS_IXP4XX -+ &cambria_leds_pld, -+ &cambria_leds_mem, -+#endif -+ &cambria_eth[0], -+ &cambria_eth[1], +}; + ++static void __init cambria_gw23xx_setup(void) ++{ ++ platform_device_register(&cambria_npec_device); ++ platform_device_register(&cambria_npea_device); ++} ++ +#ifdef CONFIG_SENSORS_EEPROM -+static int cambria_eeprom_do(struct notifier_block *self, unsigned long event, void *t) ++static void __init cambria_gw2350_setup(void) +{ -+ struct eeprom_data *data = t; -+ struct sockaddr address; -+ struct net_device * netdev; -+ -+ char macs[12]; -+ -+ /* The MACs are the first 12 bytes in the eeprom at address 0x51 */ -+ if (event == EEPROM_REGISTER && data->client.addr == 0x51) { -+ data->attr->read(&data->client.dev.kobj, data->attr, macs, 0, 12); -+ /* eth0 */ -+ memcpy(address.sa_data, macs, ETH_ALEN); -+ memcpy(&cambria_plat_eth[0].hwaddr, macs, ETH_ALEN); -+ if ( (netdev = dev_get_by_name(&init_net, "eth0")) ) -+ netdev->set_mac_address(netdev, &address); -+ -+ /* eth1 */ -+ memcpy(address.sa_data, macs + ETH_ALEN, ETH_ALEN); -+ memcpy(&cambria_plat_eth[1].hwaddr, macs + ETH_ALEN, ETH_ALEN); -+ if ( (netdev = dev_get_by_name(&init_net, "eth1")) ) -+ netdev->set_mac_address(netdev, &address); -+ } ++ platform_device_register(&cambria_npec_device); ++ platform_device_register(&cambria_npea_device); + -+ return NOTIFY_DONE; ++ platform_device_register(&cambria_usb0_device); ++ platform_device_register(&cambria_usb1_device); ++ ++ platform_device_register(&cambria_gpio_leds_device); +} + -+static struct notifier_block cambria_eeprom_notifier = { -+ .notifier_call = cambria_eeprom_do ++static void __init cambria_gw2358_setup(void) ++{ ++ platform_device_register(&cambria_npec_device); ++ platform_device_register(&cambria_npea_device); ++ ++ platform_device_register(&cambria_usb0_device); ++ platform_device_register(&cambria_usb1_device); ++ ++ platform_device_register(&cambria_pata); ++ ++ platform_device_register(&cambria_latch_leds_device); ++} ++ ++static struct cambria_board_info cambria_boards[] __initdata = { ++ { ++ .model = "GW2350", ++ .setup = cambria_gw2350_setup, ++ }, { ++ .model = "GW2358", ++ .setup = cambria_gw2358_setup, ++ } ++}; ++ ++static struct cambria_board_info * __init cambria_find_board_info(char *model) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(cambria_boards); i++) { ++ struct cambria_board_info *info = &cambria_boards[i]; ++ if (strncmp(info->model, model, strlen(info->model)) == 0) ++ return info; ++ } ++ ++ return NULL; ++} ++ ++struct cambria_eeprom_header { ++ unsigned char mac0[ETH_ALEN]; ++ unsigned char mac1[ETH_ALEN]; ++ unsigned char res0[4]; ++ unsigned char magic[2]; ++ unsigned char config[14]; ++ unsigned char model[16]; +}; -+#endif ++ ++static int __init cambria_eeprom_notify(struct notifier_block *self, ++ unsigned long event, void *t) ++{ ++ struct eeprom_data *ee = t; ++ struct cambria_eeprom_header hdr; ++ ++ if (cambria_info) ++ return NOTIFY_DONE; ++ ++ /* The eeprom is at address 0x51 */ ++ if (event != EEPROM_REGISTER || ee->client.addr != 0x51) ++ return NOTIFY_DONE; ++ ++ ee->attr->read(&ee->client.dev.kobj, ee->attr, (char *)&hdr, ++ 0, sizeof(hdr)); ++ ++ if (hdr.magic[0] != 'G' || hdr.magic[1] != 'W') ++ return NOTIFY_DONE; ++ ++ memcpy(&cambria_npec_data.hwaddr, hdr.mac0, ETH_ALEN); ++ memcpy(&cambria_npea_data.hwaddr, hdr.mac1, ETH_ALEN); ++ ++ cambria_info = cambria_find_board_info(hdr.model); ++ ++ return NOTIFY_OK; ++} ++ ++static struct notifier_block cambria_eeprom_notifier __initdata = { ++ .notifier_call = cambria_eeprom_notify ++}; ++ ++static void __init cambria_register_eeprom_notifier(void) ++{ ++ register_eeprom_notifier(&cambria_eeprom_notifier); ++} ++ ++static void __init cambria_unregister_eeprom_notifier(void) ++{ ++ unregister_eeprom_notifier(&cambria_eeprom_notifier); ++} ++#else /* CONFIG_SENSORS_EEPROM */ ++static inline void cambria_register_eeprom_notifier(void) {}; ++static inline void cambria_unregister_eeprom_notifier(void) {}; ++#endif /* CONFIG_SENSORS_EEPROM */ + +static void __init cambria_init(void) +{ + ixp4xx_sys_init(); + -+#ifdef CONFIG_SENSORS_EEPROM -+ register_eeprom_notifier(&cambria_eeprom_notifier); -+#endif -+ + cambria_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); + cambria_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1; + @@ -365,8 +539,28 @@ Index: linux-2.6.25.4/arch/arm/mach-ixp4xx/cambria-setup.c + cambria_pata_data.cs0_cfg = IXP4XX_EXP_CS3; + cambria_pata_data.cs1_cfg = IXP4XX_EXP_CS3; + -+ platform_device_register(&cambria_pata); ++ cambria_register_eeprom_notifier(); ++} ++ ++static int __init cambria_model_setup(void) ++{ ++ if (!machine_is_cambria()) ++ return 0; ++ ++ if (cambria_info) { ++ printk(KERN_DEBUG "Running on Gateworks Cambria %s\n", ++ cambria_info->model); ++ cambria_info->setup(); ++ } else { ++ printk(KERN_INFO "Unknown/missing Cambria model number" ++ " -- defaults will be used\n"); ++ cambria_gw23xx_setup(); ++ } ++ ++ cambria_unregister_eeprom_notifier(); ++ return 0; +} ++late_initcall(cambria_model_setup); + +#ifdef CONFIG_MACH_CAMBRIA +MACHINE_START(CAMBRIA, "Gateworks Cambria series") diff --git a/target/linux/ixp4xx/patches-2.6.25/301-avila_led.patch b/target/linux/ixp4xx/patches-2.6.25/301-avila_led.patch index b7e4940163..aba62841f5 100644 --- a/target/linux/ixp4xx/patches-2.6.25/301-avila_led.patch +++ b/target/linux/ixp4xx/patches-2.6.25/301-avila_led.patch @@ -1,19 +1,6 @@ -Index: linux-2.6.25.4/include/asm-arm/arch-ixp4xx/avila.h -=================================================================== ---- linux-2.6.25.4.orig/include/asm-arm/arch-ixp4xx/avila.h -+++ linux-2.6.25.4/include/asm-arm/arch-ixp4xx/avila.h -@@ -36,4 +36,6 @@ - #define AVILA_PCI_INTC_PIN 9 - #define AVILA_PCI_INTD_PIN 8 - -- -+/* User LEDs */ -+#define AVILA_GW23XX_LED_USER_GPIO 3 -+#define AVILA_GW23X7_LED_USER_GPIO 4 -Index: linux-2.6.25.4/arch/arm/mach-ixp4xx/avila-setup.c -=================================================================== ---- linux-2.6.25.4.orig/arch/arm/mach-ixp4xx/avila-setup.c -+++ linux-2.6.25.4/arch/arm/mach-ixp4xx/avila-setup.c +diff -ruN clean/linux-2.6.25.4/arch/arm/mach-ixp4xx/avila-setup.c linux-2.6.25.4/arch/arm/mach-ixp4xx/avila-setup.c +--- clean/linux-2.6.25.4/arch/arm/mach-ixp4xx/avila-setup.c 2008-05-20 09:18:21.000000000 -0700 ++++ linux-2.6.25.4/arch/arm/mach-ixp4xx/avila-setup.c 2008-05-20 09:31:55.000000000 -0700 @@ -26,6 +26,7 @@ # include #endif @@ -22,11 +9,11 @@ Index: linux-2.6.25.4/arch/arm/mach-ixp4xx/avila-setup.c #include #include -@@ -172,6 +173,25 @@ static struct platform_device avila_npec +@@ -172,6 +173,72 @@ .dev.platform_data = &avila_npec_data, }; -+static struct gpio_led avila_leds[] = { ++static struct gpio_led avila_gpio_leds[] = { + { + .name = "user", /* green led */ + .gpio = AVILA_GW23XX_LED_USER_GPIO, @@ -34,52 +21,99 @@ Index: linux-2.6.25.4/arch/arm/mach-ixp4xx/avila-setup.c + } +}; + -+static struct gpio_led_platform_data avila_leds_data = { ++static struct gpio_led_platform_data avila_gpio_leds_data = { + .num_leds = 1, -+ .leds = avila_leds, ++ .leds = avila_gpio_leds, +}; + -+static struct platform_device avila_leds_device = { ++static struct platform_device avila_gpio_leds_device = { + .name = "leds-gpio", + .id = -1, -+ .dev.platform_data = &avila_leds_data, ++ .dev.platform_data = &avila_gpio_leds_data, ++}; ++ ++static struct latch_led avila_latch_leds[] = { ++ { ++ .name = "led0", /* green led */ ++ .bit = 0, ++ }, ++ { ++ .name = "led1", /* green led */ ++ .bit = 1, ++ }, ++ { ++ .name = "led2", /* green led */ ++ .bit = 2, ++ }, ++ { ++ .name = "led3", /* green led */ ++ .bit = 3, ++ }, ++ { ++ .name = "led4", /* green led */ ++ .bit = 4, ++ }, ++ { ++ .name = "led5", /* green led */ ++ .bit = 5, ++ }, ++ { ++ .name = "led6", /* green led */ ++ .bit = 6, ++ }, ++ { ++ .name = "led7", /* green led */ ++ .bit = 7, ++ } ++}; ++ ++static struct latch_led_platform_data avila_latch_leds_data = { ++ .num_leds = 8, ++ .leds = avila_latch_leds, ++ .mem = 0x51000000, ++}; ++ ++static struct platform_device avila_latch_leds_device = { ++ .name = "leds-latch", ++ .id = -1, ++ .dev.platform_data = &avila_latch_leds_data, +}; + static struct platform_device *avila_devices[] __initdata = { &avila_i2c_gpio, &avila_flash, -@@ -182,6 +202,8 @@ static void __init avila_gw23xx_setup(vo +@@ -182,6 +249,8 @@ { platform_device_register(&avila_npeb_device); platform_device_register(&avila_npec_device); + -+ platform_device_register(&avila_leds_device); ++ platform_device_register(&avila_gpio_leds_device); } #ifdef CONFIG_SENSORS_EEPROM -@@ -189,6 +211,8 @@ static void __init avila_gw2342_setup(vo +@@ -189,6 +258,8 @@ { platform_device_register(&avila_npeb_device); platform_device_register(&avila_npec_device); + -+ platform_device_register(&avila_leds_device); ++ platform_device_register(&avila_gpio_leds_device); } static void __init avila_gw2345_setup(void) -@@ -199,22 +223,30 @@ static void __init avila_gw2345_setup(vo +@@ -199,22 +270,30 @@ avila_npec_data.phy = 5; /* port 5 of the KS8995 switch */ platform_device_register(&avila_npec_device); + -+ platform_device_register(&avila_leds_device); ++ platform_device_register(&avila_gpio_leds_device); } static void __init avila_gw2347_setup(void) { platform_device_register(&avila_npeb_device); + -+ avila_leds[0].gpio = AVILA_GW23X7_LED_USER_GPIO; -+ platform_device_register(&avila_leds_device); ++ avila_gpio_leds[0].gpio = AVILA_GW23X7_LED_USER_GPIO; ++ platform_device_register(&avila_gpio_leds_device); } static void __init avila_gw2348_setup(void) @@ -87,30 +121,248 @@ Index: linux-2.6.25.4/arch/arm/mach-ixp4xx/avila-setup.c platform_device_register(&avila_npeb_device); platform_device_register(&avila_npec_device); + -+ platform_device_register(&avila_leds_device); ++ platform_device_register(&avila_gpio_leds_device); } static void __init avila_gw2353_setup(void) { platform_device_register(&avila_npeb_device); -+ platform_device_register(&avila_leds_device); ++ platform_device_register(&avila_gpio_leds_device); } static void __init avila_gw2355_setup(void) -@@ -225,11 +257,16 @@ static void __init avila_gw2355_setup(vo +@@ -225,11 +304,29 @@ avila_npec_data.phy = 16; platform_device_register(&avila_npec_device); + -+ platform_device_register(&avila_leds_device); ++ platform_device_register(&avila_gpio_leds_device); ++ ++ *IXP4XX_EXP_CS4 |= 0xbfff3c03; ++ avila_latch_leds[0].name = "RXD"; ++ avila_latch_leds[1].name = "TXD"; ++ avila_latch_leds[2].name = "POL"; ++ avila_latch_leds[3].name = "LNK"; ++ avila_latch_leds[4].name = "ERR"; ++ avila_latch_leds_data.num_leds = 5; ++ avila_latch_leds_data.mem = 0x54000000; ++ platform_device_register(&avila_latch_leds_device); } static void __init avila_gw2357_setup(void) { platform_device_register(&avila_npeb_device); + -+ avila_leds[0].gpio = AVILA_GW23X7_LED_USER_GPIO; -+ platform_device_register(&avila_leds_device); ++ avila_gpio_leds[0].gpio = AVILA_GW23X7_LED_USER_GPIO; ++ platform_device_register(&avila_gpio_leds_device); ++ ++ *IXP4XX_EXP_CS1 |= 0xbfff3c03; ++ platform_device_register(&avila_latch_leds_device); } static struct avila_board_info avila_boards[] __initdata = { +diff -ruN clean/linux-2.6.25.4/drivers/leds/Kconfig linux-2.6.25.4/drivers/leds/Kconfig +--- clean/linux-2.6.25.4/drivers/leds/Kconfig 2008-05-15 08:00:12.000000000 -0700 ++++ linux-2.6.25.4/drivers/leds/Kconfig 2008-05-20 09:25:15.000000000 -0700 +@@ -113,6 +113,12 @@ + outputs. To be useful the particular board must have LEDs + and they must be connected to the GPIO lines. + ++config LEDS_LATCH ++ tristate "LED Support for Memory Latched LEDs" ++ depends on LEDS_CLASS ++ help ++ -- To Do -- ++ + config LEDS_CM_X270 + tristate "LED Support for the CM-X270 LEDs" + depends on LEDS_CLASS && MACH_ARMCORE +diff -ruN clean/linux-2.6.25.4/drivers/leds/leds-latch.c linux-2.6.25.4/drivers/leds/leds-latch.c +--- clean/linux-2.6.25.4/drivers/leds/leds-latch.c 1969-12-31 16:00:00.000000000 -0800 ++++ linux-2.6.25.4/drivers/leds/leds-latch.c 2008-04-30 14:03:21.000000000 -0700 +@@ -0,0 +1,141 @@ ++/* ++ * LEDs driver for Memory Latched Devices ++ * ++ * Copyright (C) 2008 Gateworks Corp. ++ * Chris Lang ++ * ++ * 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 ++ * published by the Free Software Foundation. ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static unsigned int mem_keep = 0xFF; ++static spinlock_t mem_lock; ++static unsigned char *iobase; ++ ++struct latch_led_data { ++ struct led_classdev cdev; ++ struct work_struct work; ++ u8 new_level; ++ u8 bit; ++}; ++ ++static void latch_led_set(struct led_classdev *led_cdev, ++ enum led_brightness value) ++{ ++ struct latch_led_data *led_dat = ++ container_of(led_cdev, struct latch_led_data, cdev); ++ ++ spin_lock(mem_lock); ++ ++ if (value == LED_OFF) ++ mem_keep |= (0x1 << led_dat->bit); ++ else ++ mem_keep &= ~(0x1 << led_dat->bit); ++ ++ writeb(mem_keep, iobase); ++ ++ spin_unlock(mem_lock); ++} ++ ++static int latch_led_probe(struct platform_device *pdev) ++{ ++ struct latch_led_platform_data *pdata = pdev->dev.platform_data; ++ struct latch_led *cur_led; ++ struct latch_led_data *leds_data, *led_dat; ++ int i, ret = 0; ++ ++ if (!pdata) ++ return -EBUSY; ++ ++ leds_data = kzalloc(sizeof(struct latch_led_data) * pdata->num_leds, ++ GFP_KERNEL); ++ if (!leds_data) ++ return -ENOMEM; ++ ++ iobase = ioremap_nocache(pdata->mem, 0x1000); ++ writeb(0xFF, iobase); ++ ++ for (i = 0; i < pdata->num_leds; i++) { ++ cur_led = &pdata->leds[i]; ++ led_dat = &leds_data[i]; ++ ++ led_dat->cdev.name = cur_led->name; ++ led_dat->cdev.default_trigger = cur_led->default_trigger; ++ led_dat->cdev.brightness_set = latch_led_set; ++ led_dat->cdev.brightness = LED_OFF; ++ led_dat->bit = cur_led->bit; ++ ++ ret = led_classdev_register(&pdev->dev, &led_dat->cdev); ++ if (ret < 0) { ++ goto err; ++ } ++ } ++ ++ platform_set_drvdata(pdev, leds_data); ++ ++ return 0; ++ ++err: ++ if (i > 0) { ++ for (i = i - 1; i >= 0; i--) { ++ led_classdev_unregister(&leds_data[i].cdev); ++ } ++ } ++ ++ kfree(leds_data); ++ ++ return ret; ++} ++ ++static int __devexit latch_led_remove(struct platform_device *pdev) ++{ ++ int i; ++ struct latch_led_platform_data *pdata = pdev->dev.platform_data; ++ struct latch_led_data *leds_data; ++ ++ leds_data = platform_get_drvdata(pdev); ++ ++ for (i = 0; i < pdata->num_leds; i++) { ++ led_classdev_unregister(&leds_data[i].cdev); ++ cancel_work_sync(&leds_data[i].work); ++ } ++ ++ kfree(leds_data); ++ ++ return 0; ++} ++ ++static struct platform_driver latch_led_driver = { ++ .probe = latch_led_probe, ++ .remove = __devexit_p(latch_led_remove), ++ .driver = { ++ .name = "leds-latch", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init latch_led_init(void) ++{ ++ return platform_driver_register(&latch_led_driver); ++} ++ ++static void __exit latch_led_exit(void) ++{ ++ platform_driver_unregister(&latch_led_driver); ++} ++ ++module_init(latch_led_init); ++module_exit(latch_led_exit); ++ ++MODULE_AUTHOR("Chris Lang "); ++MODULE_DESCRIPTION("Latch LED driver"); ++MODULE_LICENSE("GPL"); +diff -ruN clean/linux-2.6.25.4/drivers/leds/Makefile linux-2.6.25.4/drivers/leds/Makefile +--- clean/linux-2.6.25.4/drivers/leds/Makefile 2008-05-15 08:00:12.000000000 -0700 ++++ linux-2.6.25.4/drivers/leds/Makefile 2008-05-20 09:26:14.000000000 -0700 +@@ -18,6 +18,7 @@ + obj-$(CONFIG_LEDS_COBALT_QUBE) += leds-cobalt-qube.o + obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o + obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o ++obj-$(CONFIG_LEDS_LATCH) += leds-latch.o + obj-$(CONFIG_LEDS_CM_X270) += leds-cm-x270.o + obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o + obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o +diff -ruN clean/linux-2.6.25.4/include/asm-arm/arch-ixp4xx/avila.h linux-2.6.25.4/include/asm-arm/arch-ixp4xx/avila.h +--- clean/linux-2.6.25.4/include/asm-arm/arch-ixp4xx/avila.h 2008-05-15 08:00:12.000000000 -0700 ++++ linux-2.6.25.4/include/asm-arm/arch-ixp4xx/avila.h 2008-05-20 09:22:28.000000000 -0700 +@@ -36,4 +36,6 @@ + #define AVILA_PCI_INTC_PIN 9 + #define AVILA_PCI_INTD_PIN 8 + +- ++/* User LEDs */ ++#define AVILA_GW23XX_LED_USER_GPIO 3 ++#define AVILA_GW23X7_LED_USER_GPIO 4 +diff -ruN clean/linux-2.6.25.4/include/linux/leds.h linux-2.6.25.4/include/linux/leds.h +--- clean/linux-2.6.25.4/include/linux/leds.h 2008-05-15 08:00:12.000000000 -0700 ++++ linux-2.6.25.4/include/linux/leds.h 2008-05-20 09:32:35.000000000 -0700 +@@ -136,5 +136,18 @@ + struct gpio_led *leds; + }; + ++/* For the leds-latch driver */ ++struct latch_led { ++ const char *name; ++ char *default_trigger; ++ unsigned bit; ++}; ++ ++struct latch_led_platform_data { ++ int num_leds; ++ u32 mem; ++ struct latch_led *leds; ++}; ++ + + #endif /* __LINUX_LEDS_H_INCLUDED */ diff --git a/target/linux/ixp4xx/patches-2.6.25/304-gateworks_led_latch.patch b/target/linux/ixp4xx/patches-2.6.25/304-gateworks_led_latch.patch deleted file mode 100644 index 485ea8e70c..0000000000 --- a/target/linux/ixp4xx/patches-2.6.25/304-gateworks_led_latch.patch +++ /dev/null @@ -1,449 +0,0 @@ -diff -ruN trunk/build_dir/linux-ixp4xx_generic/linux-2.6.24.5/drivers/leds/Kconfig linux-2.6.24.5/drivers/leds/Kconfig ---- trunk/build_dir/linux-ixp4xx_generic/linux-2.6.24.5/drivers/leds/Kconfig 2008-04-29 11:29:49.000000000 -0700 -+++ linux-2.6.24.5/drivers/leds/Kconfig 2008-04-29 17:18:47.000000000 -0700 -@@ -120,6 +120,12 @@ - outputs. To be useful the particular board must have LEDs - and they must be connected to the GPIO lines. - -+config LEDS_LATCH -+ tristate "LED Support for Memory Latched LEDs" -+ depends on LEDS_CLASS -+ help -+ -- To Do -- -+ - config LEDS_CM_X270 - tristate "LED Support for the CM-X270 LEDs" - depends on LEDS_CLASS && MACH_ARMCORE -diff -ruN trunk/build_dir/linux-ixp4xx_generic/linux-2.6.24.5/drivers/leds/leds-latch.c linux-2.6.24.5/drivers/leds/leds-latch.c ---- trunk/build_dir/linux-ixp4xx_generic/linux-2.6.24.5/drivers/leds/leds-latch.c 1969-12-31 16:00:00.000000000 -0800 -+++ linux-2.6.24.5/drivers/leds/leds-latch.c 2008-04-30 14:03:21.000000000 -0700 -@@ -0,0 +1,141 @@ -+/* -+ * LEDs driver for Memory Latched Devices -+ * -+ * Copyright (C) 2008 Gateworks Corp. -+ * Chris Lang -+ * -+ * 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 -+ * published by the Free Software Foundation. -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static unsigned int mem_keep = 0xFF; -+static spinlock_t mem_lock; -+static unsigned char *iobase; -+ -+struct latch_led_data { -+ struct led_classdev cdev; -+ struct work_struct work; -+ u8 new_level; -+ u8 bit; -+}; -+ -+static void latch_led_set(struct led_classdev *led_cdev, -+ enum led_brightness value) -+{ -+ struct latch_led_data *led_dat = -+ container_of(led_cdev, struct latch_led_data, cdev); -+ -+ spin_lock(mem_lock); -+ -+ if (value == LED_OFF) -+ mem_keep |= (0x1 << led_dat->bit); -+ else -+ mem_keep &= ~(0x1 << led_dat->bit); -+ -+ writeb(mem_keep, iobase); -+ -+ spin_unlock(mem_lock); -+} -+ -+static int latch_led_probe(struct platform_device *pdev) -+{ -+ struct latch_led_platform_data *pdata = pdev->dev.platform_data; -+ struct latch_led *cur_led; -+ struct latch_led_data *leds_data, *led_dat; -+ int i, ret = 0; -+ -+ if (!pdata) -+ return -EBUSY; -+ -+ leds_data = kzalloc(sizeof(struct latch_led_data) * pdata->num_leds, -+ GFP_KERNEL); -+ if (!leds_data) -+ return -ENOMEM; -+ -+ iobase = ioremap_nocache(pdata->mem, 0x1000); -+ writeb(0xFF, iobase); -+ -+ for (i = 0; i < pdata->num_leds; i++) { -+ cur_led = &pdata->leds[i]; -+ led_dat = &leds_data[i]; -+ -+ led_dat->cdev.name = cur_led->name; -+ led_dat->cdev.default_trigger = cur_led->default_trigger; -+ led_dat->cdev.brightness_set = latch_led_set; -+ led_dat->cdev.brightness = LED_OFF; -+ led_dat->bit = cur_led->bit; -+ -+ ret = led_classdev_register(&pdev->dev, &led_dat->cdev); -+ if (ret < 0) { -+ goto err; -+ } -+ } -+ -+ platform_set_drvdata(pdev, leds_data); -+ -+ return 0; -+ -+err: -+ if (i > 0) { -+ for (i = i - 1; i >= 0; i--) { -+ led_classdev_unregister(&leds_data[i].cdev); -+ } -+ } -+ -+ kfree(leds_data); -+ -+ return ret; -+} -+ -+static int __devexit latch_led_remove(struct platform_device *pdev) -+{ -+ int i; -+ struct latch_led_platform_data *pdata = pdev->dev.platform_data; -+ struct latch_led_data *leds_data; -+ -+ leds_data = platform_get_drvdata(pdev); -+ -+ for (i = 0; i < pdata->num_leds; i++) { -+ led_classdev_unregister(&leds_data[i].cdev); -+ cancel_work_sync(&leds_data[i].work); -+ } -+ -+ kfree(leds_data); -+ -+ return 0; -+} -+ -+static struct platform_driver latch_led_driver = { -+ .probe = latch_led_probe, -+ .remove = __devexit_p(latch_led_remove), -+ .driver = { -+ .name = "leds-latch", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init latch_led_init(void) -+{ -+ return platform_driver_register(&latch_led_driver); -+} -+ -+static void __exit latch_led_exit(void) -+{ -+ platform_driver_unregister(&latch_led_driver); -+} -+ -+module_init(latch_led_init); -+module_exit(latch_led_exit); -+ -+MODULE_AUTHOR("Chris Lang "); -+MODULE_DESCRIPTION("Latch LED driver"); -+MODULE_LICENSE("GPL"); -diff -ruN trunk/build_dir/linux-ixp4xx_generic/linux-2.6.24.5/drivers/leds/Makefile linux-2.6.24.5/drivers/leds/Makefile ---- trunk/build_dir/linux-ixp4xx_generic/linux-2.6.24.5/drivers/leds/Makefile 2008-04-29 11:29:49.000000000 -0700 -+++ linux-2.6.24.5/drivers/leds/Makefile 2008-04-29 17:19:02.000000000 -0700 -@@ -21,6 +21,7 @@ - obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o - obj-$(CONFIG_LEDS_CM_X270) += leds-cm-x270.o - obj-$(CONFIG_LEDS_FSG) += leds-fsg.o -+obj-$(CONFIG_LEDS_LATCH) += leds-latch.o - - # LED Triggers - obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o -diff -ruN trunk/build_dir/linux-ixp4xx_generic/linux-2.6.24.5/arch/arm/mach-ixp4xx/avila-setup.c linux-2.6.24.5/arch/arm/mach-ixp4xx/avila-setup.c ---- trunk/build_dir/linux-ixp4xx_generic/linux-2.6.24.5/arch/arm/mach-ixp4xx/avila-setup.c 2008-04-29 11:29:50.000000000 -0700 -+++ linux-2.6.24.5/arch/arm/mach-ixp4xx/avila-setup.c 2008-04-30 15:43:40.000000000 -0700 -@@ -173,7 +173,7 @@ - .dev.platform_data = &avila_npec_data, - }; - --static struct gpio_led avila_leds[] = { -+static struct gpio_led avila_gpio_leds[] = { - { - .name = "user", /* green led */ - .gpio = AVILA_GW23XX_LED_USER_GPIO, -@@ -181,17 +181,65 @@ - } - }; - --static struct gpio_led_platform_data avila_leds_data = { -+static struct gpio_led_platform_data avila_gpio_leds_data = { - .num_leds = 1, -- .leds = avila_leds, -+ .leds = avila_gpio_leds, - }; - --static struct platform_device avila_leds_device = { -+static struct platform_device avila_gpio_leds_device = { - .name = "leds-gpio", - .id = -1, -- .dev.platform_data = &avila_leds_data, -+ .dev.platform_data = &avila_gpio_leds_data, - }; - -+static struct latch_led avila_latch_leds[] = { -+ { -+ .name = "led0", /* green led */ -+ .bit = 0, -+ }, -+ { -+ .name = "led1", /* green led */ -+ .bit = 1, -+ }, -+ { -+ .name = "led2", /* green led */ -+ .bit = 2, -+ }, -+ { -+ .name = "led3", /* green led */ -+ .bit = 3, -+ }, -+ { -+ .name = "led4", /* green led */ -+ .bit = 4, -+ }, -+ { -+ .name = "led5", /* green led */ -+ .bit = 5, -+ }, -+ { -+ .name = "led6", /* green led */ -+ .bit = 6, -+ }, -+ { -+ .name = "led7", /* green led */ -+ .bit = 7, -+ } -+}; -+ -+static struct latch_led_platform_data avila_latch_leds_data = { -+ .num_leds = 8, -+ .leds = avila_latch_leds, -+ .mem = 0x51000000, -+}; -+ -+static struct platform_device avila_latch_leds_device = { -+ .name = "leds-latch", -+ .id = -1, -+ .dev.platform_data = &avila_latch_leds_data, -+}; -+ -+ - static struct resource avila_gpio_resources[] = { - { - .name = "gpio", -@@ -221,7 +269,7 @@ - platform_device_register(&avila_npeb_device); - platform_device_register(&avila_npec_device); - -- platform_device_register(&avila_leds_device); -+ platform_device_register(&avila_gpio_leds_device); - } - - #ifdef CONFIG_SENSORS_EEPROM -@@ -230,7 +278,7 @@ - platform_device_register(&avila_npeb_device); - platform_device_register(&avila_npec_device); - -- platform_device_register(&avila_leds_device); -+ platform_device_register(&avila_gpio_leds_device); - } - - static void __init avila_gw2345_setup(void) -@@ -242,7 +290,7 @@ - avila_npec_data.phy = 5; /* port 5 of the KS8995 switch */ - platform_device_register(&avila_npec_device); - -- platform_device_register(&avila_leds_device); -+ platform_device_register(&avila_gpio_leds_device); - } - - static void __init avila_gw2347_setup(void) -@@ -250,8 +298,8 @@ - avila_npeb_data.quirks |= IXP4XX_ETH_QUIRK_GW23X7; - platform_device_register(&avila_npeb_device); - -- avila_leds[0].gpio = AVILA_GW23X7_LED_USER_GPIO; -- platform_device_register(&avila_leds_device); -+ avila_gpio_leds[0].gpio = AVILA_GW23X7_LED_USER_GPIO; -+ platform_device_register(&avila_gpio_leds_device); - } - - static void __init avila_gw2348_setup(void) -@@ -259,13 +307,13 @@ - platform_device_register(&avila_npeb_device); - platform_device_register(&avila_npec_device); - -- platform_device_register(&avila_leds_device); -+ platform_device_register(&avila_gpio_leds_device); - } - - static void __init avila_gw2353_setup(void) - { - platform_device_register(&avila_npeb_device); -- platform_device_register(&avila_leds_device); -+ platform_device_register(&avila_gpio_leds_device); - } - - static void __init avila_gw2355_setup(void) -@@ -277,7 +325,17 @@ - avila_npec_data.phy = 16; - platform_device_register(&avila_npec_device); - -- platform_device_register(&avila_leds_device); -+ platform_device_register(&avila_gpio_leds_device); -+ -+ *IXP4XX_EXP_CS4 |= 0xbfff3c03; -+ avila_latch_leds[0].name = "RXD"; -+ avila_latch_leds[1].name = "TXD"; -+ avila_latch_leds[2].name = "POL"; -+ avila_latch_leds[3].name = "LNK"; -+ avila_latch_leds[4].name = "ERR"; -+ avila_latch_leds_data.num_leds = 5; -+ avila_latch_leds_data.mem = 0x54000000; -+ platform_device_register(&avila_latch_leds_device); - } - - static void __init avila_gw2357_setup(void) -@@ -285,8 +343,11 @@ - avila_npeb_data.quirks |= IXP4XX_ETH_QUIRK_GW23X7; - platform_device_register(&avila_npeb_device); - -- avila_leds[0].gpio = AVILA_GW23X7_LED_USER_GPIO; -- platform_device_register(&avila_leds_device); -+ avila_gpio_leds[0].gpio = AVILA_GW23X7_LED_USER_GPIO; -+ platform_device_register(&avila_gpio_leds_device); -+ -+ *IXP4XX_EXP_CS1 |= 0xbfff3c03; -+ platform_device_register(&avila_latch_leds_device); - } - - static struct avila_board_info avila_boards[] __initdata = { -diff -ruN trunk/build_dir/linux-ixp4xx_generic/linux-2.6.24.5/arch/arm/mach-ixp4xx/cambria-setup.c linux-2.6.24.5/arch/arm/mach-ixp4xx/cambria-setup.c ---- trunk/build_dir/linux-ixp4xx_generic/linux-2.6.24.5/arch/arm/mach-ixp4xx/cambria-setup.c 2008-04-29 11:29:49.000000000 -0700 -+++ linux-2.6.24.5/arch/arm/mach-ixp4xx/cambria-setup.c 2008-04-30 14:43:57.000000000 -0700 -@@ -25,6 +25,8 @@ - # include - # include - #endif -+ -+#include - - #include - #include -@@ -149,19 +151,52 @@ - } - }; - --#ifdef CONFIG_LEDS_IXP4XX --static struct platform_device cambria_leds_pld = { -- .name = "IXP4XX-PLD-LED", -- .id = -1, -- .num_resources = 0, --}; -- --static struct platform_device cambria_leds_mem = { -- .name = "IXP4XX-MEM-LED", -- .id = -1, -- .num_resources = 0, -+static struct latch_led cambria_leds[] = { -+ { -+ .name = "ledA", /* green led */ -+ .bit = 0, -+ }, -+ { -+ .name = "ledB", /* green led */ -+ .bit = 1, -+ }, -+ { -+ .name = "ledC", /* green led */ -+ .bit = 2, -+ }, -+ { -+ .name = "ledD", /* green led */ -+ .bit = 3, -+ }, -+ { -+ .name = "ledE", /* green led */ -+ .bit = 4, -+ }, -+ { -+ .name = "ledF", /* green led */ -+ .bit = 5, -+ }, -+ { -+ .name = "ledG", /* green led */ -+ .bit = 6, -+ }, -+ { -+ .name = "ledH", /* green led */ -+ .bit = 7, -+ } -+}; -+ -+static struct latch_led_platform_data cambria_leds_data = { -+ .num_leds = 8, -+ .leds = cambria_leds, -+ .mem = 0x53F40000, -+}; -+ -+static struct platform_device cambria_leds_device = { -+ .name = "leds-latch", -+ .id = -1, -+ .dev.platform_data = &cambria_leds_data, - }; --#endif - - static struct platform_device *cambria_devices[] __initdata = { - &cambria_i2c_gpio, -@@ -234,6 +269,9 @@ - cambria_pata_data.cs1_cfg = IXP4XX_EXP_CS3; - - platform_device_register(&cambria_pata); -+ -+ *IXP4XX_EXP_CS3 |= 0xbfff3c03; -+ platform_device_register(&cambria_leds_device); - } - - #ifdef CONFIG_MACH_CAMBRIA ---- trunk/build_dir/linux-ixp4xx_generic/linux-2.6.24.5/include/linux/leds.h 2008-04-18 18:53:39.000000000 -0700 -+++ linux-2.6.24.5/include/linux/leds.h 2008-04-29 17:48:56.000000000 -0700 -@@ -123,5 +123,18 @@ - struct gpio_led *leds; - }; - -+/* For the leds-latch driver */ -+struct latch_led { -+ const char *name; -+ char *default_trigger; -+ unsigned bit; -+}; -+ -+struct latch_led_platform_data { -+ int num_leds; -+ u32 mem; -+ struct latch_led *leds; -+}; -+ - - #endif /* __LINUX_LEDS_H_INCLUDED */