diff options
author | Felix Fietkau <nbd@openwrt.org> | 2015-03-13 03:01:42 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2015-03-13 03:01:42 +0000 |
commit | 1b5b20e51e290e58cc28a9a7cfb72178c0c10614 (patch) | |
tree | c1d2f7bb8aef9a275057b2a77d5a8aa2351e9314 /target | |
parent | 6d29a8bc64830d3f0c26eafe47880f84aeb425e8 (diff) | |
download | mtk-20170518-1b5b20e51e290e58cc28a9a7cfb72178c0c10614.zip mtk-20170518-1b5b20e51e290e58cc28a9a7cfb72178c0c10614.tar.gz mtk-20170518-1b5b20e51e290e58cc28a9a7cfb72178c0c10614.tar.bz2 |
atheros: v3.18: rearrange code between patches
Cleanup board patch by moving code to specific patches, and factor out
leds to separate patch. No functional changes.
Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
SVN-Revision: 44729
Diffstat (limited to 'target')
9 files changed, 587 insertions, 344 deletions
diff --git a/target/linux/atheros/patches-3.18/100-board.patch b/target/linux/atheros/patches-3.18/100-board.patch index 7dd0b7a..643014f 100644 --- a/target/linux/atheros/patches-3.18/100-board.patch +++ b/target/linux/atheros/patches-3.18/100-board.patch @@ -1,6 +1,6 @@ --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig -@@ -96,6 +96,20 @@ config AR7 +@@ -96,6 +96,19 @@ config AR7 Support for the Texas Instruments AR7 System-on-a-Chip family: TNETD7100, 7200 and 7300. @@ -14,14 +14,13 @@ + select SYS_HAS_CPU_MIPS32_R1 + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_32BIT_KERNEL -+ select ARCH_REQUIRE_GPIOLIB + help + Support for AR231x and AR531x based boards + config ATH79 bool "Atheros AR71XX/AR724X/AR913X based boards" select ARCH_REQUIRE_GPIOLIB -@@ -834,6 +848,7 @@ config MIPS_PARAVIRT +@@ -834,6 +847,7 @@ config MIPS_PARAVIRT endchoice @@ -354,7 +353,7 @@ +} --- /dev/null +++ b/arch/mips/include/asm/mach-ath25/ath25_platform.h -@@ -0,0 +1,84 @@ +@@ -0,0 +1,73 @@ +#ifndef __ASM_MACH_ATH25_PLATFORM_H +#define __ASM_MACH_ATH25_PLATFORM_H + @@ -427,17 +426,6 @@ + const char *radio; +}; + -+/* -+ * Platform device information for the Ethernet MAC -+ */ -+struct ar231x_eth { -+ void (*reset_set)(u32); -+ void (*reset_clear)(u32); -+ u32 reset_mac; -+ u32 reset_phy; -+ char *macaddr; -+}; -+ +#endif /* __ASM_MACH_ATH25_PLATFORM_H */ --- /dev/null +++ b/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h @@ -640,7 +628,7 @@ +#endif /* __ASM_MACH_ATH25_WAR_H */ --- /dev/null +++ b/arch/mips/ath25/ar2315_regs.h -@@ -0,0 +1,479 @@ +@@ -0,0 +1,471 @@ +/* + * Register definitions for AR2315+ + * @@ -700,9 +688,6 @@ +#define AR2315_PCI_EXT_BASE 0x80000000 /* PCI external */ +#define AR2315_PCI_EXT_SIZE 0x40000000 + -+/* MII registers offset inside Ethernet MMR region */ -+#define AR2315_ENET0_MII_BASE (AR2315_ENET0_BASE + 0x14) -+ +/* + * Cold reset register + */ @@ -968,11 +953,6 @@ +#define AR2315_AMBACLK_CLK_DIV_M 0x0000000c +#define AR2315_AMBACLK_CLK_DIV_S 2 + -+/* GPIO MMR base address */ -+#define AR2315_GPIO 0x0088 -+ -+#define AR2315_RESET_GPIO 5 -+ +/* + * PCI Clock Control + */ @@ -1122,7 +1102,7 @@ +#endif /* __ASM_MACH_ATH25_AR2315_REGS_H */ --- /dev/null +++ b/arch/mips/ath25/ar5312_regs.h -@@ -0,0 +1,229 @@ +@@ -0,0 +1,225 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive @@ -1191,10 +1171,6 @@ +#define AR5312_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */ +#define AR5312_AR2313_REV8 0x0058 /* AR2313 WMAC (AP43-030) */ + -+/* MII registers offset inside Ethernet MMR region */ -+#define AR5312_ENET0_MII_BASE (AR5312_ENET0_BASE + 0x14) -+#define AR5312_ENET1_MII_BASE (AR5312_ENET1_BASE + 0x14) -+ +/* Reset/Timer Block Address Map */ +#define AR5312_TIMER 0x0000 /* countdown timer */ +#define AR5312_RELOAD 0x0004 /* timer reload value */ @@ -1354,7 +1330,7 @@ +#endif /* __ASM_MACH_ATH25_AR5312_REGS_H */ --- /dev/null +++ b/arch/mips/ath25/ar5312.c -@@ -0,0 +1,492 @@ +@@ -0,0 +1,401 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive @@ -1382,8 +1358,6 @@ +#include <linux/bitops.h> +#include <linux/irqdomain.h> +#include <linux/reboot.h> -+#include <linux/leds.h> -+#include <linux/gpio.h> +#include <asm/bootinfo.h> +#include <asm/reboot.h> +#include <asm/time.h> @@ -1495,10 +1469,6 @@ + + if (pending & CAUSEF_IP2) + do_IRQ(AR5312_IRQ_WLAN0); -+ else if (pending & CAUSEF_IP3) -+ do_IRQ(AR5312_IRQ_ENET0); -+ else if (pending & CAUSEF_IP4) -+ do_IRQ(AR5312_IRQ_ENET1); + else if (pending & CAUSEF_IP5) + do_IRQ(AR5312_IRQ_WLAN1); + else if (pending & CAUSEF_IP6) @@ -1530,22 +1500,6 @@ + ar5312_misc_irq_domain = domain; +} + -+static void ar5312_device_reset_set(u32 mask) -+{ -+ u32 val; -+ -+ val = ar5312_rst_reg_read(AR5312_RESET); -+ ar5312_rst_reg_write(AR5312_RESET, val | mask); -+} -+ -+static void ar5312_device_reset_clear(u32 mask) -+{ -+ u32 val; -+ -+ val = ar5312_rst_reg_read(AR5312_RESET); -+ ar5312_rst_reg_write(AR5312_RESET, val & ~mask); -+} -+ +static struct physmap_flash_data ar5312_flash_data = { + .width = 2, +}; @@ -1556,20 +1510,6 @@ + .flags = IORESOURCE_MEM, +}; + -+static struct ar231x_eth ar5312_eth0_data = { -+ .reset_set = ar5312_device_reset_set, -+ .reset_clear = ar5312_device_reset_clear, -+ .reset_mac = AR5312_RESET_ENET0, -+ .reset_phy = AR5312_RESET_EPHY0, -+}; -+ -+static struct ar231x_eth ar5312_eth1_data = { -+ .reset_set = ar5312_device_reset_set, -+ .reset_clear = ar5312_device_reset_clear, -+ .reset_mac = AR5312_RESET_ENET1, -+ .reset_phy = AR5312_RESET_EPHY1, -+}; -+ +static struct platform_device ar5312_physmap_flash = { + .name = "physmap-flash", + .id = 0, @@ -1578,23 +1518,6 @@ + .num_resources = 1, +}; + -+#ifdef CONFIG_LEDS_GPIO -+static struct gpio_led ar5312_leds[] = { -+ { .name = "wlan", .gpio = 0, .active_low = 1, }, -+}; -+ -+static const struct gpio_led_platform_data ar5312_led_data = { -+ .num_leds = ARRAY_SIZE(ar5312_leds), -+ .leds = (void *)ar5312_leds, -+}; -+ -+static struct platform_device ar5312_gpio_leds = { -+ .name = "leds-gpio", -+ .id = -1, -+ .dev.platform_data = (void *)&ar5312_led_data, -+}; -+#endif -+ +static void __init ar5312_flash_init(void) +{ + void __iomem *flashctl_base; @@ -1641,7 +1564,6 @@ +void __init ar5312_init_devices(void) +{ + struct ath25_boarddata *config; -+ u8 *c; + + ar5312_flash_init(); + @@ -1663,35 +1585,8 @@ + + platform_device_register(&ar5312_physmap_flash); + -+#ifdef CONFIG_LEDS_GPIO -+ ar5312_leds[0].gpio = config->sys_led_gpio; -+ platform_device_register(&ar5312_gpio_leds); -+#endif -+ -+ /* Fix up MAC addresses if necessary */ -+ if (is_broadcast_ether_addr(config->enet0_mac)) -+ ether_addr_copy(config->enet0_mac, config->enet1_mac); -+ -+ /* If ENET0 and ENET1 have the same mac address, -+ * increment the one from ENET1 */ -+ if (ether_addr_equal(config->enet0_mac, config->enet1_mac)) { -+ c = config->enet1_mac + 5; -+ while ((c >= config->enet1_mac) && !(++(*c))) -+ c--; -+ } -+ + switch (ath25_soc) { + case ATH25_SOC_AR5312: -+ ar5312_eth0_data.macaddr = config->enet0_mac; -+ ath25_add_ethernet(0, AR5312_ENET0_BASE, "eth0_mii", -+ AR5312_ENET0_MII_BASE, AR5312_IRQ_ENET0, -+ &ar5312_eth0_data); -+ -+ ar5312_eth1_data.macaddr = config->enet1_mac; -+ ath25_add_ethernet(1, AR5312_ENET1_BASE, "eth1_mii", -+ AR5312_ENET1_MII_BASE, AR5312_IRQ_ENET1, -+ &ar5312_eth1_data); -+ + if (!ath25_board.radio) + return; + @@ -1700,18 +1595,8 @@ + + ath25_add_wmac(0, AR5312_WLAN0_BASE, AR5312_IRQ_WLAN0); + break; -+ /* -+ * AR2312/3 ethernet uses the PHY of ENET0, but the MAC -+ * of ENET1. Atheros calls it 'twisted' for a reason :) -+ */ + case ATH25_SOC_AR2312: + case ATH25_SOC_AR2313: -+ ar5312_eth1_data.reset_phy = ar5312_eth0_data.reset_phy; -+ ar5312_eth1_data.macaddr = config->enet0_mac; -+ ath25_add_ethernet(1, AR5312_ENET1_BASE, "eth0_mii", -+ AR5312_ENET0_MII_BASE, AR5312_IRQ_ENET1, -+ &ar5312_eth1_data); -+ + if (!ath25_board.radio) + return; + break; @@ -1849,7 +1734,7 @@ +} --- /dev/null +++ b/arch/mips/ath25/ar2315.c -@@ -0,0 +1,438 @@ +@@ -0,0 +1,312 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive @@ -1876,9 +1761,6 @@ +#include <linux/bitops.h> +#include <linux/irqdomain.h> +#include <linux/reboot.h> -+#include <linux/delay.h> -+#include <linux/leds.h> -+#include <linux/gpio.h> +#include <asm/bootinfo.h> +#include <asm/reboot.h> +#include <asm/time.h> @@ -1994,8 +1876,6 @@ + + if (pending & CAUSEF_IP3) + do_IRQ(AR2315_IRQ_WLAN0); -+ else if (pending & CAUSEF_IP4) -+ do_IRQ(AR2315_IRQ_ENET0); + else if (pending & CAUSEF_IP2) + do_IRQ(AR2315_IRQ_MISC); + else if (pending & CAUSEF_IP7) @@ -2025,131 +1905,10 @@ + ar2315_misc_irq_domain = domain; +} + -+static void ar2315_device_reset_set(u32 mask) -+{ -+ u32 val; -+ -+ val = ar2315_rst_reg_read(AR2315_RESET); -+ ar2315_rst_reg_write(AR2315_RESET, val | mask); -+} -+ -+static void ar2315_device_reset_clear(u32 mask) -+{ -+ u32 val; -+ -+ val = ar2315_rst_reg_read(AR2315_RESET); -+ ar2315_rst_reg_write(AR2315_RESET, val & ~mask); -+} -+ -+static struct ar231x_eth ar2315_eth_data = { -+ .reset_set = ar2315_device_reset_set, -+ .reset_clear = ar2315_device_reset_clear, -+ .reset_mac = AR2315_RESET_ENET0, -+ .reset_phy = AR2315_RESET_EPHY0, -+}; -+ -+static struct resource ar2315_spiflash_res[] = { -+ { -+ .name = "spiflash_read", -+ .flags = IORESOURCE_MEM, -+ .start = AR2315_SPI_READ_BASE, -+ .end = AR2315_SPI_READ_BASE + AR2315_SPI_READ_SIZE - 1, -+ }, -+ { -+ .name = "spiflash_mmr", -+ .flags = IORESOURCE_MEM, -+ .start = AR2315_SPI_MMR_BASE, -+ .end = AR2315_SPI_MMR_BASE + AR2315_SPI_MMR_SIZE - 1, -+ }, -+}; -+ -+static struct platform_device ar2315_spiflash = { -+ .id = 0, -+ .name = "ar2315-spiflash", -+ .resource = ar2315_spiflash_res, -+ .num_resources = ARRAY_SIZE(ar2315_spiflash_res) -+}; -+ -+static struct resource ar2315_wdt_res[] = { -+ { -+ .flags = IORESOURCE_MEM, -+ .start = AR2315_RST_BASE + AR2315_WDT_TIMER, -+ .end = AR2315_RST_BASE + AR2315_WDT_TIMER + 8 - 1, -+ }, -+ { -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ -+static struct platform_device ar2315_wdt = { -+ .id = 0, -+ .name = "ar2315-wdt", -+ .resource = ar2315_wdt_res, -+ .num_resources = ARRAY_SIZE(ar2315_wdt_res) -+}; -+ -+#ifdef CONFIG_LEDS_GPIO -+static struct gpio_led ar2315_leds[6]; -+static struct gpio_led_platform_data ar2315_led_data = { -+ .leds = (void *)ar2315_leds, -+}; -+ -+static struct platform_device ar2315_gpio_leds = { -+ .name = "leds-gpio", -+ .id = -1, -+ .dev = { -+ .platform_data = (void *)&ar2315_led_data, -+ } -+}; -+ -+static void __init ar2315_init_gpio_leds(void) -+{ -+ static char led_names[6][6]; -+ int i, led = 0; -+ -+ ar2315_led_data.num_leds = 0; -+ for (i = 1; i < 8; i++) { -+ if ((i == AR2315_RESET_GPIO) || -+ (i == ath25_board.config->reset_config_gpio)) -+ continue; -+ -+ if (i == ath25_board.config->sys_led_gpio) -+ strcpy(led_names[led], "wlan"); -+ else -+ sprintf(led_names[led], "gpio%d", i); -+ -+ ar2315_leds[led].name = led_names[led]; -+ ar2315_leds[led].gpio = i; -+ ar2315_leds[led].active_low = 0; -+ led++; -+ } -+ ar2315_led_data.num_leds = led; -+ platform_device_register(&ar2315_gpio_leds); -+} -+#else -+static inline void ar2315_init_gpio_leds(void) -+{ -+} -+#endif -+ +void __init ar2315_init_devices(void) +{ + /* Find board configuration */ + ath25_find_config(AR2315_SPI_READ_BASE, AR2315_SPI_READ_SIZE); -+ ar2315_eth_data.macaddr = ath25_board.config->enet0_mac; -+ -+ ar2315_init_gpio_leds(); -+ -+ ar2315_wdt_res[1].start = irq_create_mapping(ar2315_misc_irq_domain, -+ AR2315_MISC_IRQ_WATCHDOG); -+ ar2315_wdt_res[1].end = ar2315_wdt_res[1].start; -+ platform_device_register(&ar2315_wdt); -+ -+ platform_device_register(&ar2315_spiflash); -+ -+ ath25_add_ethernet(0, AR2315_ENET0_BASE, "eth0_mii", -+ AR2315_ENET0_MII_BASE, AR2315_IRQ_ENET0, -+ &ar2315_eth_data); + + ath25_add_wmac(0, AR2315_WLAN0_BASE, AR2315_IRQ_WLAN0); +} @@ -2166,8 +1925,8 @@ + /* Cold reset does not work on the AR2315/6, use the GPIO reset bits + * a workaround. Give it some time to attempt a gpio based hardware + * reset (atheros reference design workaround) */ -+ gpio_request_one(AR2315_RESET_GPIO, GPIOF_OUT_INIT_LOW, "Reset"); -+ mdelay(100); ++ ++ /* TODO: implement the GPIO reset workaround */ + + /* Some boards (e.g. Senao EOC-2610) don't implement the reset logic + * workaround. Attempt to jump to the mips reset location - @@ -2368,12 +2127,10 @@ +#endif --- /dev/null +++ b/arch/mips/ath25/devices.h -@@ -0,0 +1,45 @@ +@@ -0,0 +1,41 @@ +#ifndef __ATH25_DEVICES_H +#define __ATH25_DEVICES_H + -+#define AR231X_GPIO_IRQ_BASE 0x30 -+ +#define ATH25_REG_MS(_val, _field) (((_val) & _field##_M) >> _field##_S) + +#define ATH25_IRQ_CPU_CLOCK (MIPS_CPU_IRQ_BASE + 7) /* C0_CAUSE: 0x8000 */ @@ -2398,8 +2155,6 @@ +extern void (*ath25_irq_dispatch)(void); + +int ath25_find_config(phys_addr_t offset, unsigned long size); -+int ath25_add_ethernet(int nr, u32 base, const char *mii_name, u32 mii_base, -+ int irq, void *pdata); +void ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk); +int ath25_add_wmac(int nr, u32 base, int irq); + @@ -2416,7 +2171,7 @@ +#endif --- /dev/null +++ b/arch/mips/ath25/devices.c -@@ -0,0 +1,191 @@ +@@ -0,0 +1,127 @@ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/serial.h> @@ -2433,51 +2188,6 @@ +struct ar231x_board_config ath25_board; +enum ath25_soc_type ath25_soc = ATH25_SOC_UNKNOWN; + -+static struct resource ath25_eth0_res[] = { -+ { -+ .name = "eth0_membase", -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = "eth0_mii", -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = "eth0_irq", -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ -+static struct resource ath25_eth1_res[] = { -+ { -+ .name = "eth1_membase", -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = "eth1_mii", -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = "eth1_irq", -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ -+static struct platform_device ath25_eth[] = { -+ { -+ .id = 0, -+ .name = "ar231x-eth", -+ .resource = ath25_eth0_res, -+ .num_resources = ARRAY_SIZE(ath25_eth0_res) -+ }, -+ { -+ .id = 1, -+ .name = "ar231x-eth", -+ .resource = ath25_eth1_res, -+ .num_resources = ARRAY_SIZE(ath25_eth1_res) -+ } -+}; -+ +static struct resource ath25_wmac0_res[] = { + { + .name = "wmac0_membase", @@ -2536,25 +2246,6 @@ + return soc_type_strings[ath25_soc]; +} + -+int __init ath25_add_ethernet(int nr, u32 base, const char *mii_name, -+ u32 mii_base, int irq, void *pdata) -+{ -+ struct resource *res; -+ -+ ath25_eth[nr].dev.platform_data = pdata; -+ res = &ath25_eth[nr].resource[0]; -+ res->start = base; -+ res->end = base + 0x2000 - 1; -+ res++; -+ res->name = mii_name; -+ res->start = mii_base; -+ res->end = mii_base + 8 - 1; -+ res++; -+ res->start = irq; -+ res->end = irq; -+ return platform_device_register(&ath25_eth[nr]); -+} -+ +void __init ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk) +{ + struct uart_port s; diff --git a/target/linux/atheros/patches-3.18/101-early-printk-support.patch b/target/linux/atheros/patches-3.18/101-early-printk-support.patch index 713dda5..6ad1455 100644 --- a/target/linux/atheros/patches-3.18/101-early-printk-support.patch +++ b/target/linux/atheros/patches-3.18/101-early-printk-support.patch @@ -60,10 +60,10 @@ obj-$(CONFIG_SOC_AR2315) += ar2315.o --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig -@@ -107,6 +107,7 @@ config ATH25 +@@ -106,6 +106,7 @@ config ATH25 + select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_32BIT_KERNEL - select ARCH_REQUIRE_GPIOLIB + select SYS_HAS_EARLY_PRINTK help Support for AR231x and AR531x based boards diff --git a/target/linux/atheros/patches-3.18/105-ar2315_pci.patch b/target/linux/atheros/patches-3.18/105-ar2315_pci.patch index 8e3dfa1..80256d4 100644 --- a/target/linux/atheros/patches-3.18/105-ar2315_pci.patch +++ b/target/linux/atheros/patches-3.18/105-ar2315_pci.patch @@ -537,10 +537,10 @@ + default y --- a/arch/mips/ath25/ar2315.c +++ b/arch/mips/ath25/ar2315.c -@@ -144,6 +144,10 @@ static void ar2315_irq_dispatch(void) +@@ -139,6 +139,10 @@ static void ar2315_irq_dispatch(void) + + if (pending & CAUSEF_IP3) do_IRQ(AR2315_IRQ_WLAN0); - else if (pending & CAUSEF_IP4) - do_IRQ(AR2315_IRQ_ENET0); +#ifdef CONFIG_PCI_AR2315 + else if (pending & CAUSEF_IP5) + do_IRQ(AR2315_IRQ_LCBUS_PCI); @@ -548,7 +548,7 @@ else if (pending & CAUSEF_IP2) do_IRQ(AR2315_IRQ_MISC); else if (pending & CAUSEF_IP7) -@@ -429,10 +433,62 @@ void __init ar2315_plat_mem_setup(void) +@@ -303,10 +307,62 @@ void __init ar2315_plat_mem_setup(void) _machine_restart = ar2315_restart; } diff --git a/target/linux/atheros/patches-3.18/107-ar5312_gpio.patch b/target/linux/atheros/patches-3.18/107-ar5312_gpio.patch index 56ac81e..ec336b4 100644 --- a/target/linux/atheros/patches-3.18/107-ar5312_gpio.patch +++ b/target/linux/atheros/patches-3.18/107-ar5312_gpio.patch @@ -10,7 +10,15 @@ config SOC_AR2315 --- a/arch/mips/ath25/ar5312.c +++ b/arch/mips/ath25/ar5312.c -@@ -221,6 +221,22 @@ static struct platform_device ar5312_phy +@@ -25,6 +25,7 @@ + #include <linux/bitops.h> + #include <linux/irqdomain.h> + #include <linux/reboot.h> ++#include <linux/gpio.h> + #include <asm/bootinfo.h> + #include <asm/reboot.h> + #include <asm/time.h> +@@ -185,6 +186,22 @@ static struct platform_device ar5312_phy .num_resources = 1, }; @@ -30,18 +38,18 @@ + .num_resources = ARRAY_SIZE(ar5312_gpio_res), +}; + - #ifdef CONFIG_LEDS_GPIO - static struct gpio_led ar5312_leds[] = { - { .name = "wlan", .gpio = 0, .active_low = 1, }, -@@ -306,6 +322,8 @@ void __init ar5312_init_devices(void) + static void __init ar5312_flash_init(void) + { + void __iomem *flashctl_base; +@@ -252,6 +269,8 @@ void __init ar5312_init_devices(void) platform_device_register(&ar5312_physmap_flash); + platform_device_register(&ar5312_gpio); + - #ifdef CONFIG_LEDS_GPIO - ar5312_leds[0].gpio = config->sys_led_gpio; - platform_device_register(&ar5312_gpio_leds); + switch (ath25_soc) { + case ATH25_SOC_AR5312: + if (!ath25_board.radio) --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -112,6 +112,13 @@ config GPIO_MAX730X @@ -192,3 +200,13 @@ + return platform_driver_register(&ar5312_gpio_driver); +} +subsys_initcall(ar5312_gpio_init); +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -107,6 +107,7 @@ config ATH25 + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_HAS_EARLY_PRINTK ++ select ARCH_REQUIRE_GPIOLIB + help + Support for AR231x and AR531x based boards + diff --git a/target/linux/atheros/patches-3.18/108-ar2315_gpio.patch b/target/linux/atheros/patches-3.18/108-ar2315_gpio.patch index d85fc15..187e5a6 100644 --- a/target/linux/atheros/patches-3.18/108-ar2315_gpio.patch +++ b/target/linux/atheros/patches-3.18/108-ar2315_gpio.patch @@ -10,9 +10,18 @@ config PCI_AR2315 --- a/arch/mips/ath25/ar2315.c +++ b/arch/mips/ath25/ar2315.c -@@ -240,6 +240,32 @@ static struct platform_device ar2315_wdt - .num_resources = ARRAY_SIZE(ar2315_wdt_res) - }; +@@ -24,6 +24,8 @@ + #include <linux/bitops.h> + #include <linux/irqdomain.h> + #include <linux/reboot.h> ++#include <linux/delay.h> ++#include <linux/gpio.h> + #include <asm/bootinfo.h> + #include <asm/reboot.h> + #include <asm/time.h> +@@ -172,11 +174,42 @@ void __init ar2315_arch_init_irq(void) + ar2315_misc_irq_domain = domain; + } +static struct resource ar2315_gpio_res[] = { + { @@ -40,21 +49,30 @@ + .num_resources = ARRAY_SIZE(ar2315_gpio_res) +}; + - #ifdef CONFIG_LEDS_GPIO - static struct gpio_led ar2315_leds[6]; - static struct gpio_led_platform_data ar2315_led_data = { -@@ -290,6 +316,11 @@ void __init ar2315_init_devices(void) + void __init ar2315_init_devices(void) + { + /* Find board configuration */ ath25_find_config(AR2315_SPI_READ_BASE, AR2315_SPI_READ_SIZE); - ar2315_eth_data.macaddr = ath25_board.config->enet0_mac; + ar2315_gpio_res[1].start = irq_create_mapping(ar2315_misc_irq_domain, + AR2315_MISC_IRQ_GPIO); + ar2315_gpio_res[1].end = ar2315_gpio_res[1].start; + platform_device_register(&ar2315_gpio); + - ar2315_init_gpio_leds(); + ath25_add_wmac(0, AR2315_WLAN0_BASE, AR2315_IRQ_WLAN0); + } + +@@ -192,8 +225,8 @@ static void ar2315_restart(char *command + /* Cold reset does not work on the AR2315/6, use the GPIO reset bits + * a workaround. Give it some time to attempt a gpio based hardware + * reset (atheros reference design workaround) */ +- +- /* TODO: implement the GPIO reset workaround */ ++ gpio_request_one(AR2315_RESET_GPIO, GPIOF_OUT_INIT_LOW, "Reset"); ++ mdelay(100); - ar2315_wdt_res[1].start = irq_create_mapping(ar2315_misc_irq_domain, + /* Some boards (e.g. Senao EOC-2610) don't implement the reset logic + * workaround. Attempt to jump to the mips reset location - --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -112,6 +112,13 @@ config GPIO_MAX730X @@ -317,3 +335,29 @@ + return platform_driver_register(&ar2315_gpio_driver); +} +subsys_initcall(ar2315_gpio_init); +--- a/arch/mips/ath25/devices.h ++++ b/arch/mips/ath25/devices.h +@@ -1,6 +1,11 @@ + #ifndef __ATH25_DEVICES_H + #define __ATH25_DEVICES_H + ++#define AR231X_GPIO_IRQ_BASE 0x30 ++ ++/* GPIO number for AR2315/16 reset issue workaround */ ++#define AR2315_RESET_GPIO 5 ++ + #define ATH25_REG_MS(_val, _field) (((_val) & _field##_M) >> _field##_S) + + #define ATH25_IRQ_CPU_CLOCK (MIPS_CPU_IRQ_BASE + 7) /* C0_CAUSE: 0x8000 */ +--- a/arch/mips/ath25/ar2315_regs.h ++++ b/arch/mips/ath25/ar2315_regs.h +@@ -322,6 +322,9 @@ + #define AR2315_AMBACLK_CLK_DIV_M 0x0000000c + #define AR2315_AMBACLK_CLK_DIV_S 2 + ++/* GPIO MMR base address */ ++#define AR2315_GPIO 0x0088 ++ + /* + * PCI Clock Control + */ diff --git a/target/linux/atheros/patches-3.18/110-ar2313_ethernet.patch b/target/linux/atheros/patches-3.18/110-ar2313_ethernet.patch index d1b2df4..7d90aec 100644 --- a/target/linux/atheros/patches-3.18/110-ar2313_ethernet.patch +++ b/target/linux/atheros/patches-3.18/110-ar2313_ethernet.patch @@ -1531,3 +1531,298 @@ +static void ar231x_check_link(struct net_device *dev); + +#endif /* _AR2313_H_ */ +--- a/arch/mips/ath25/ar2315_regs.h ++++ b/arch/mips/ath25/ar2315_regs.h +@@ -57,6 +57,9 @@ + #define AR2315_PCI_EXT_BASE 0x80000000 /* PCI external */ + #define AR2315_PCI_EXT_SIZE 0x40000000 + ++/* MII registers offset inside Ethernet MMR region */ ++#define AR2315_ENET0_MII_BASE (AR2315_ENET0_BASE + 0x14) ++ + /* + * Cold reset register + */ +--- a/arch/mips/ath25/ar5312_regs.h ++++ b/arch/mips/ath25/ar5312_regs.h +@@ -66,6 +66,10 @@ + #define AR5312_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */ + #define AR5312_AR2313_REV8 0x0058 /* AR2313 WMAC (AP43-030) */ + ++/* MII registers offset inside Ethernet MMR region */ ++#define AR5312_ENET0_MII_BASE (AR5312_ENET0_BASE + 0x14) ++#define AR5312_ENET1_MII_BASE (AR5312_ENET1_BASE + 0x14) ++ + /* Reset/Timer Block Address Map */ + #define AR5312_TIMER 0x0000 /* countdown timer */ + #define AR5312_RELOAD 0x0004 /* timer reload value */ +--- a/arch/mips/ath25/ar2315.c ++++ b/arch/mips/ath25/ar2315.c +@@ -141,6 +141,8 @@ static void ar2315_irq_dispatch(void) + + if (pending & CAUSEF_IP3) + do_IRQ(AR2315_IRQ_WLAN0); ++ else if (pending & CAUSEF_IP4) ++ do_IRQ(AR2315_IRQ_ENET0); + #ifdef CONFIG_PCI_AR2315 + else if (pending & CAUSEF_IP5) + do_IRQ(AR2315_IRQ_LCBUS_PCI); +@@ -174,6 +176,29 @@ void __init ar2315_arch_init_irq(void) + ar2315_misc_irq_domain = domain; + } + ++static void ar2315_device_reset_set(u32 mask) ++{ ++ u32 val; ++ ++ val = ar2315_rst_reg_read(AR2315_RESET); ++ ar2315_rst_reg_write(AR2315_RESET, val | mask); ++} ++ ++static void ar2315_device_reset_clear(u32 mask) ++{ ++ u32 val; ++ ++ val = ar2315_rst_reg_read(AR2315_RESET); ++ ar2315_rst_reg_write(AR2315_RESET, val & ~mask); ++} ++ ++static struct ar231x_eth ar2315_eth_data = { ++ .reset_set = ar2315_device_reset_set, ++ .reset_clear = ar2315_device_reset_clear, ++ .reset_mac = AR2315_RESET_ENET0, ++ .reset_phy = AR2315_RESET_EPHY0, ++}; ++ + static struct resource ar2315_gpio_res[] = { + { + .name = "ar2315-gpio", +@@ -210,6 +235,11 @@ void __init ar2315_init_devices(void) + ar2315_gpio_res[1].end = ar2315_gpio_res[1].start; + platform_device_register(&ar2315_gpio); + ++ ar2315_eth_data.macaddr = ath25_board.config->enet0_mac; ++ ath25_add_ethernet(0, AR2315_ENET0_BASE, "eth0_mii", ++ AR2315_ENET0_MII_BASE, AR2315_IRQ_ENET0, ++ &ar2315_eth_data); ++ + ath25_add_wmac(0, AR2315_WLAN0_BASE, AR2315_IRQ_WLAN0); + } + +--- a/arch/mips/ath25/ar5312.c ++++ b/arch/mips/ath25/ar5312.c +@@ -137,6 +137,10 @@ static void ar5312_irq_dispatch(void) + + if (pending & CAUSEF_IP2) + do_IRQ(AR5312_IRQ_WLAN0); ++ else if (pending & CAUSEF_IP3) ++ do_IRQ(AR5312_IRQ_ENET0); ++ else if (pending & CAUSEF_IP4) ++ do_IRQ(AR5312_IRQ_ENET1); + else if (pending & CAUSEF_IP5) + do_IRQ(AR5312_IRQ_WLAN1); + else if (pending & CAUSEF_IP6) +@@ -168,6 +172,36 @@ void __init ar5312_arch_init_irq(void) + ar5312_misc_irq_domain = domain; + } + ++static void ar5312_device_reset_set(u32 mask) ++{ ++ u32 val; ++ ++ val = ar5312_rst_reg_read(AR5312_RESET); ++ ar5312_rst_reg_write(AR5312_RESET, val | mask); ++} ++ ++static void ar5312_device_reset_clear(u32 mask) ++{ ++ u32 val; ++ ++ val = ar5312_rst_reg_read(AR5312_RESET); ++ ar5312_rst_reg_write(AR5312_RESET, val & ~mask); ++} ++ ++static struct ar231x_eth ar5312_eth0_data = { ++ .reset_set = ar5312_device_reset_set, ++ .reset_clear = ar5312_device_reset_clear, ++ .reset_mac = AR5312_RESET_ENET0, ++ .reset_phy = AR5312_RESET_EPHY0, ++}; ++ ++static struct ar231x_eth ar5312_eth1_data = { ++ .reset_set = ar5312_device_reset_set, ++ .reset_clear = ar5312_device_reset_clear, ++ .reset_mac = AR5312_RESET_ENET1, ++ .reset_phy = AR5312_RESET_EPHY1, ++}; ++ + static struct physmap_flash_data ar5312_flash_data = { + .width = 2, + }; +@@ -248,6 +282,7 @@ static void __init ar5312_flash_init(voi + void __init ar5312_init_devices(void) + { + struct ath25_boarddata *config; ++ u8 *c; + + ar5312_flash_init(); + +@@ -271,8 +306,30 @@ void __init ar5312_init_devices(void) + + platform_device_register(&ar5312_gpio); + ++ /* Fix up MAC addresses if necessary */ ++ if (is_broadcast_ether_addr(config->enet0_mac)) ++ ether_addr_copy(config->enet0_mac, config->enet1_mac); ++ ++ /* If ENET0 and ENET1 have the same mac address, ++ * increment the one from ENET1 */ ++ if (ether_addr_equal(config->enet0_mac, config->enet1_mac)) { ++ c = config->enet1_mac + 5; ++ while ((c >= config->enet1_mac) && !(++(*c))) ++ c--; ++ } ++ + switch (ath25_soc) { + case ATH25_SOC_AR5312: ++ ar5312_eth0_data.macaddr = config->enet0_mac; ++ ath25_add_ethernet(0, AR5312_ENET0_BASE, "eth0_mii", ++ AR5312_ENET0_MII_BASE, AR5312_IRQ_ENET0, ++ &ar5312_eth0_data); ++ ++ ar5312_eth1_data.macaddr = config->enet1_mac; ++ ath25_add_ethernet(1, AR5312_ENET1_BASE, "eth1_mii", ++ AR5312_ENET1_MII_BASE, AR5312_IRQ_ENET1, ++ &ar5312_eth1_data); ++ + if (!ath25_board.radio) + return; + +@@ -281,8 +338,18 @@ void __init ar5312_init_devices(void) + + ath25_add_wmac(0, AR5312_WLAN0_BASE, AR5312_IRQ_WLAN0); + break; ++ /* ++ * AR2312/3 ethernet uses the PHY of ENET0, but the MAC ++ * of ENET1. Atheros calls it 'twisted' for a reason :) ++ */ + case ATH25_SOC_AR2312: + case ATH25_SOC_AR2313: ++ ar5312_eth1_data.reset_phy = ar5312_eth0_data.reset_phy; ++ ar5312_eth1_data.macaddr = config->enet0_mac; ++ ath25_add_ethernet(1, AR5312_ENET1_BASE, "eth0_mii", ++ AR5312_ENET0_MII_BASE, AR5312_IRQ_ENET1, ++ &ar5312_eth1_data); ++ + if (!ath25_board.radio) + return; + break; +--- a/arch/mips/ath25/devices.h ++++ b/arch/mips/ath25/devices.h +@@ -30,6 +30,8 @@ extern struct ar231x_board_config ath25_ + extern void (*ath25_irq_dispatch)(void); + + int ath25_find_config(phys_addr_t offset, unsigned long size); ++int ath25_add_ethernet(int nr, u32 base, const char *mii_name, u32 mii_base, ++ int irq, void *pdata); + void ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk); + int ath25_add_wmac(int nr, u32 base, int irq); + +--- a/arch/mips/ath25/devices.c ++++ b/arch/mips/ath25/devices.c +@@ -14,6 +14,51 @@ + struct ar231x_board_config ath25_board; + enum ath25_soc_type ath25_soc = ATH25_SOC_UNKNOWN; + ++static struct resource ath25_eth0_res[] = { ++ { ++ .name = "eth0_membase", ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .name = "eth0_mii", ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .name = "eth0_irq", ++ .flags = IORESOURCE_IRQ, ++ } ++}; ++ ++static struct resource ath25_eth1_res[] = { ++ { ++ .name = "eth1_membase", ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .name = "eth1_mii", ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .name = "eth1_irq", ++ .flags = IORESOURCE_IRQ, ++ } ++}; ++ ++static struct platform_device ath25_eth[] = { ++ { ++ .id = 0, ++ .name = "ar231x-eth", ++ .resource = ath25_eth0_res, ++ .num_resources = ARRAY_SIZE(ath25_eth0_res) ++ }, ++ { ++ .id = 1, ++ .name = "ar231x-eth", ++ .resource = ath25_eth1_res, ++ .num_resources = ARRAY_SIZE(ath25_eth1_res) ++ } ++}; ++ + static struct resource ath25_wmac0_res[] = { + { + .name = "wmac0_membase", +@@ -72,6 +117,25 @@ const char *get_system_type(void) + return soc_type_strings[ath25_soc]; + } + ++int __init ath25_add_ethernet(int nr, u32 base, const char *mii_name, ++ u32 mii_base, int irq, void *pdata) ++{ ++ struct resource *res; ++ ++ ath25_eth[nr].dev.platform_data = pdata; ++ res = &ath25_eth[nr].resource[0]; ++ res->start = base; ++ res->end = base + 0x2000 - 1; ++ res++; ++ res->name = mii_name; ++ res->start = mii_base; ++ res->end = mii_base + 8 - 1; ++ res++; ++ res->start = irq; ++ res->end = irq; ++ return platform_device_register(&ath25_eth[nr]); ++} ++ + void __init ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk) + { + struct uart_port s; +--- a/arch/mips/include/asm/mach-ath25/ath25_platform.h ++++ b/arch/mips/include/asm/mach-ath25/ath25_platform.h +@@ -70,4 +70,15 @@ struct ar231x_board_config { + const char *radio; + }; + ++/* ++ * Platform device information for the Ethernet MAC ++ */ ++struct ar231x_eth { ++ void (*reset_set)(u32); ++ void (*reset_clear)(u32); ++ u32 reset_mac; ++ u32 reset_phy; ++ char *macaddr; ++}; ++ + #endif /* __ASM_MACH_ATH25_PLATFORM_H */ diff --git a/target/linux/atheros/patches-3.18/120-spiflash.patch b/target/linux/atheros/patches-3.18/120-spiflash.patch index 35e659c..06fe09c 100644 --- a/target/linux/atheros/patches-3.18/120-spiflash.patch +++ b/target/linux/atheros/patches-3.18/120-spiflash.patch @@ -592,3 +592,43 @@ +#define SPI_STATUS_WIP STM_STATUS_WIP + +#endif +--- a/arch/mips/ath25/ar2315.c ++++ b/arch/mips/ath25/ar2315.c +@@ -225,6 +225,28 @@ static struct platform_device ar2315_gpi + .num_resources = ARRAY_SIZE(ar2315_gpio_res) + }; + ++static struct resource ar2315_spiflash_res[] = { ++ { ++ .name = "spiflash_read", ++ .flags = IORESOURCE_MEM, ++ .start = AR2315_SPI_READ_BASE, ++ .end = AR2315_SPI_READ_BASE + AR2315_SPI_READ_SIZE - 1, ++ }, ++ { ++ .name = "spiflash_mmr", ++ .flags = IORESOURCE_MEM, ++ .start = AR2315_SPI_MMR_BASE, ++ .end = AR2315_SPI_MMR_BASE + AR2315_SPI_MMR_SIZE - 1, ++ }, ++}; ++ ++static struct platform_device ar2315_spiflash = { ++ .id = 0, ++ .name = "ar2315-spiflash", ++ .resource = ar2315_spiflash_res, ++ .num_resources = ARRAY_SIZE(ar2315_spiflash_res) ++}; ++ + void __init ar2315_init_devices(void) + { + /* Find board configuration */ +@@ -235,6 +257,8 @@ void __init ar2315_init_devices(void) + ar2315_gpio_res[1].end = ar2315_gpio_res[1].start; + platform_device_register(&ar2315_gpio); + ++ platform_device_register(&ar2315_spiflash); ++ + ar2315_eth_data.macaddr = ath25_board.config->enet0_mac; + ath25_add_ethernet(0, AR2315_ENET0_BASE, "eth0_mii", + AR2315_ENET0_MII_BASE, AR2315_IRQ_ENET0, diff --git a/target/linux/atheros/patches-3.18/130-watchdog.patch b/target/linux/atheros/patches-3.18/130-watchdog.patch index 05e965d..cec9e42 100644 --- a/target/linux/atheros/patches-3.18/130-watchdog.patch +++ b/target/linux/atheros/patches-3.18/130-watchdog.patch @@ -236,3 +236,42 @@ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o +--- a/arch/mips/ath25/ar2315.c ++++ b/arch/mips/ath25/ar2315.c +@@ -225,6 +225,24 @@ static struct platform_device ar2315_gpi + .num_resources = ARRAY_SIZE(ar2315_gpio_res) + }; + ++static struct resource ar2315_wdt_res[] = { ++ { ++ .flags = IORESOURCE_MEM, ++ .start = AR2315_RST_BASE + AR2315_WDT_TIMER, ++ .end = AR2315_RST_BASE + AR2315_WDT_TIMER + 8 - 1, ++ }, ++ { ++ .flags = IORESOURCE_IRQ, ++ } ++}; ++ ++static struct platform_device ar2315_wdt = { ++ .id = 0, ++ .name = "ar2315-wdt", ++ .resource = ar2315_wdt_res, ++ .num_resources = ARRAY_SIZE(ar2315_wdt_res) ++}; ++ + static struct resource ar2315_spiflash_res[] = { + { + .name = "spiflash_read", +@@ -257,6 +275,11 @@ void __init ar2315_init_devices(void) + ar2315_gpio_res[1].end = ar2315_gpio_res[1].start; + platform_device_register(&ar2315_gpio); + ++ ar2315_wdt_res[1].start = irq_create_mapping(ar2315_misc_irq_domain, ++ AR2315_MISC_IRQ_WATCHDOG); ++ ar2315_wdt_res[1].end = ar2315_wdt_res[1].start; ++ platform_device_register(&ar2315_wdt); ++ + platform_device_register(&ar2315_spiflash); + + ar2315_eth_data.macaddr = ath25_board.config->enet0_mac; diff --git a/target/linux/atheros/patches-3.18/330-board_leds.patch b/target/linux/atheros/patches-3.18/330-board_leds.patch new file mode 100644 index 0000000..d069595 --- /dev/null +++ b/target/linux/atheros/patches-3.18/330-board_leds.patch @@ -0,0 +1,116 @@ +--- a/arch/mips/ath25/ar2315.c ++++ b/arch/mips/ath25/ar2315.c +@@ -26,6 +26,7 @@ + #include <linux/reboot.h> + #include <linux/delay.h> + #include <linux/gpio.h> ++#include <linux/leds.h> + #include <asm/bootinfo.h> + #include <asm/reboot.h> + #include <asm/time.h> +@@ -265,6 +266,50 @@ static struct platform_device ar2315_spi + .num_resources = ARRAY_SIZE(ar2315_spiflash_res) + }; + ++#ifdef CONFIG_LEDS_GPIO ++static struct gpio_led ar2315_leds[6]; ++static struct gpio_led_platform_data ar2315_led_data = { ++ .leds = (void *)ar2315_leds, ++}; ++ ++static struct platform_device ar2315_gpio_leds = { ++ .name = "leds-gpio", ++ .id = -1, ++ .dev = { ++ .platform_data = (void *)&ar2315_led_data, ++ } ++}; ++ ++static void __init ar2315_init_gpio_leds(void) ++{ ++ static char led_names[6][6]; ++ int i, led = 0; ++ ++ ar2315_led_data.num_leds = 0; ++ for (i = 1; i < 8; i++) { ++ if ((i == AR2315_RESET_GPIO) || ++ (i == ath25_board.config->reset_config_gpio)) ++ continue; ++ ++ if (i == ath25_board.config->sys_led_gpio) ++ strcpy(led_names[led], "wlan"); ++ else ++ sprintf(led_names[led], "gpio%d", i); ++ ++ ar2315_leds[led].name = led_names[led]; ++ ar2315_leds[led].gpio = i; ++ ar2315_leds[led].active_low = 0; ++ led++; ++ } ++ ar2315_led_data.num_leds = led; ++ platform_device_register(&ar2315_gpio_leds); ++} ++#else ++static inline void ar2315_init_gpio_leds(void) ++{ ++} ++#endif ++ + void __init ar2315_init_devices(void) + { + /* Find board configuration */ +@@ -275,6 +320,8 @@ void __init ar2315_init_devices(void) + ar2315_gpio_res[1].end = ar2315_gpio_res[1].start; + platform_device_register(&ar2315_gpio); + ++ ar2315_init_gpio_leds(); ++ + ar2315_wdt_res[1].start = irq_create_mapping(ar2315_misc_irq_domain, + AR2315_MISC_IRQ_WATCHDOG); + ar2315_wdt_res[1].end = ar2315_wdt_res[1].start; +--- a/arch/mips/ath25/ar5312.c ++++ b/arch/mips/ath25/ar5312.c +@@ -26,6 +26,7 @@ + #include <linux/irqdomain.h> + #include <linux/reboot.h> + #include <linux/gpio.h> ++#include <linux/leds.h> + #include <asm/bootinfo.h> + #include <asm/reboot.h> + #include <asm/time.h> +@@ -236,6 +237,23 @@ static struct platform_device ar5312_gpi + .num_resources = ARRAY_SIZE(ar5312_gpio_res), + }; + ++#ifdef CONFIG_LEDS_GPIO ++static struct gpio_led ar5312_leds[] = { ++ { .name = "wlan", .gpio = 0, .active_low = 1, }, ++}; ++ ++static const struct gpio_led_platform_data ar5312_led_data = { ++ .num_leds = ARRAY_SIZE(ar5312_leds), ++ .leds = (void *)ar5312_leds, ++}; ++ ++static struct platform_device ar5312_gpio_leds = { ++ .name = "leds-gpio", ++ .id = -1, ++ .dev.platform_data = (void *)&ar5312_led_data, ++}; ++#endif ++ + static void __init ar5312_flash_init(void) + { + void __iomem *flashctl_base; +@@ -306,6 +324,11 @@ void __init ar5312_init_devices(void) + + platform_device_register(&ar5312_gpio); + ++#ifdef CONFIG_LEDS_GPIO ++ ar5312_leds[0].gpio = config->sys_led_gpio; ++ platform_device_register(&ar5312_gpio_leds); ++#endif ++ + /* Fix up MAC addresses if necessary */ + if (is_broadcast_ether_addr(config->enet0_mac)) + ether_addr_copy(config->enet0_mac, config->enet1_mac); |