diff -Nur linux-2.6.29.1.orig/arch/mips/Kconfig linux-2.6.29.1/arch/mips/Kconfig
--- linux-2.6.29.1.orig/arch/mips/Kconfig	2009-04-02 22:55:27.000000000 +0200
+++ linux-2.6.29.1/arch/mips/Kconfig	2009-04-13 14:27:23.734393467 +0200
@@ -22,6 +22,23 @@
 config MACH_ALCHEMY
 	bool "Alchemy processor based machines"
 
+config ATHEROS_AR71XX
+	bool "Atheros AR71xx based boards"
+	select CEVT_R4K
+	select CSRC_R4K
+	select DMA_NONCOHERENT
+	select HW_HAS_PCI
+	select IRQ_CPU
+	select ARCH_REQUIRE_GPIOLIB
+	select SYS_HAS_CPU_MIPS32_R1
+	select SYS_HAS_CPU_MIPS32_R2
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_HAS_EARLY_PRINTK
+	select MIPS_MACHINE
+	help
+	  Support for Atheros AR71xx based boards.
+
 config BASLER_EXCITE
 	bool "Basler eXcite smart camera"
 	select CEVT_R4K
@@ -640,6 +657,7 @@
 endchoice
 
 source "arch/mips/alchemy/Kconfig"
+source "arch/mips/ar71xx/Kconfig"
 source "arch/mips/basler/excite/Kconfig"
 source "arch/mips/jazz/Kconfig"
 source "arch/mips/lasat/Kconfig"
@@ -810,6 +828,9 @@
 config SYNC_R4K
 	bool
 
+config MIPS_MACHINE
+	def_bool n
+
 config NO_IOPORT
 	def_bool n
 
diff -Nur linux-2.6.29.1.orig/arch/mips/Makefile linux-2.6.29.1/arch/mips/Makefile
--- linux-2.6.29.1.orig/arch/mips/Makefile	2009-04-02 22:55:27.000000000 +0200
+++ linux-2.6.29.1/arch/mips/Makefile	2009-04-13 14:27:34.483063970 +0200
@@ -602,6 +602,14 @@
 load-$(CONFIG_CPU_CAVIUM_OCTEON) 	+= 0xffffffff81100000
 endif
 
+#
+# Atheros AR71xx
+#
+core-$(CONFIG_ATHEROS_AR71XX) += arch/mips/ar71xx/
+cflags-$(CONFIG_ATHEROS_AR71XX)       += -I$(srctree)/arch/mips/include/asm/mach-ar71xx
+load-$(CONFIG_ATHEROS_AR71XX) += 0xffffffff80060000
+
+
 cflags-y			+= -I$(srctree)/arch/mips/include/asm/mach-generic
 drivers-$(CONFIG_PCI)		+= arch/mips/pci/
 
diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/Kconfig linux-2.6.29.1/arch/mips/ar71xx/Kconfig
--- linux-2.6.29.1.orig/arch/mips/ar71xx/Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.29.1/arch/mips/ar71xx/Kconfig	2009-04-13 14:27:34.483063970 +0200
@@ -0,0 +1,64 @@
+if ATHEROS_AR71XX
+
+config AR71XX_EARLY_SERIAL
+	bool "Use early serial console"
+	default n
+
+menu "Atheros AR71xx machine selection"
+
+config AR71XX_MACH_AP81
+	bool "Atheros AP81 board support"
+	default y
+
+config AR71XX_MACH_AP83
+	bool "Atheros AP83 board support"
+	default y
+
+config AR71XX_MACH_PB42
+	bool "Atheros PB42 board support"
+	default y
+
+config AR71XX_MACH_AW_NR580
+	bool "AzureWave AW-NR580 board support"
+	default y
+
+config AR71XX_MACH_GENERIC
+	bool "Generic AR71xx based machine support"
+	default y
+
+config AR71XX_MACH_WP543
+	bool "Compex WP543 board support"
+	select MYLOADER
+	default y
+
+config AR71XX_MACH_RB_4XX
+	bool "MikroTik RouterBOARD 4xx series support"
+	default y
+
+config AR71XX_MACH_WNR2000
+	bool "NETGEAR WNR2000 board support"
+	default y
+
+config AR71XX_MACH_MZK_W04NU
+	bool "Planex MZK-W04NU board support"
+	default y
+
+config AR71XX_MACH_MZK_W300NH
+	bool "Planex MZK-W300NH board support"
+	default y
+
+config AR71XX_MACH_TL_WR941ND
+	bool "TP-LINK TL-WR941ND support"
+	default y
+
+config AR71XX_MACH_TEW_632BRP
+	bool "TRENDnet TEW-632BRP support"
+	default y
+
+config AR71XX_MACH_UBNT
+	bool "Ubiquiti AR71xx based boards support"
+	default y
+
+endmenu
+
+endif
diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/Makefile linux-2.6.29.1/arch/mips/ar71xx/Makefile
--- linux-2.6.29.1.orig/arch/mips/ar71xx/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.29.1/arch/mips/ar71xx/Makefile	2009-04-13 14:27:34.487064480 +0200
@@ -0,0 +1,25 @@
+#
+# Makefile for the Atheros AR71xx SoC specific parts of the kernel
+#
+# Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+# Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+#
+# 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.
+
+obj-y	:= prom.o irq.o setup.o devices.o gpio.o ar71xx.o
+
+obj-$(CONFIG_AR71XX_MACH_AP81)		+= mach-ap81.o
+obj-$(CONFIG_AR71XX_MACH_AP83)		+= mach-ap83.o
+obj-$(CONFIG_AR71XX_MACH_AW_NR580)	+= mach-aw-nr580.o
+obj-$(CONFIG_AR71XX_MACH_GENERIC)	+= mach-generic.o
+obj-$(CONFIG_AR71XX_MACH_MZK_W04NU)	+= mach-mzk-w04nu.o
+obj-$(CONFIG_AR71XX_MACH_MZK_W300NH)	+= mach-mzk-w300nh.o
+obj-$(CONFIG_AR71XX_MACH_PB42)		+= mach-pb42.o
+obj-$(CONFIG_AR71XX_MACH_RB_4XX)	+= mach-rb-4xx.o
+obj-$(CONFIG_AR71XX_MACH_TEW_632BRP)	+= mach-tew-632brp.o
+obj-$(CONFIG_AR71XX_MACH_TL_WR941ND)	+= mach-tl-wr941nd.o
+obj-$(CONFIG_AR71XX_MACH_UBNT)		+= mach-ubnt.o
+obj-$(CONFIG_AR71XX_MACH_WNR2000)	+= mach-wnr2000.o
+obj-$(CONFIG_AR71XX_MACH_WP543)		+= mach-wp543.o
diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/ar71xx.c linux-2.6.29.1/arch/mips/ar71xx/ar71xx.c
--- linux-2.6.29.1.orig/arch/mips/ar71xx/ar71xx.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.29.1/arch/mips/ar71xx/ar71xx.c	2009-04-13 14:27:34.487064480 +0200
@@ -0,0 +1,100 @@
+/*
+ *  AR71xx SoC routines
+ *
+ *  Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  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 <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+
+#include <asm/mach-ar71xx/ar71xx.h>
+
+void __iomem *ar71xx_ddr_base;
+EXPORT_SYMBOL_GPL(ar71xx_ddr_base);
+
+void __iomem *ar71xx_pll_base;
+EXPORT_SYMBOL_GPL(ar71xx_pll_base);
+
+void __iomem *ar71xx_reset_base;
+EXPORT_SYMBOL_GPL(ar71xx_reset_base);
+
+void __iomem *ar71xx_gpio_base;
+EXPORT_SYMBOL_GPL(ar71xx_gpio_base);
+
+void __iomem *ar71xx_usb_ctrl_base;
+EXPORT_SYMBOL_GPL(ar71xx_usb_ctrl_base);
+
+void ar71xx_device_stop(u32 mask)
+{
+	unsigned long flags;
+	u32 t;
+
+	switch (ar71xx_soc) {
+	case AR71XX_SOC_AR7130:
+	case AR71XX_SOC_AR7141:
+	case AR71XX_SOC_AR7161:
+		local_irq_save(flags);
+		t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE);
+		ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t | mask);
+		local_irq_restore(flags);
+		break;
+
+	case AR71XX_SOC_AR9130:
+	case AR71XX_SOC_AR9132:
+		local_irq_save(flags);
+		t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
+		ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t | mask);
+		local_irq_restore(flags);
+		break;
+
+	default:
+		BUG();
+	}
+}
+EXPORT_SYMBOL_GPL(ar71xx_device_stop);
+
+void ar71xx_device_start(u32 mask)
+{
+	unsigned long flags;
+	u32 t;
+
+	switch (ar71xx_soc) {
+	case AR71XX_SOC_AR7130:
+	case AR71XX_SOC_AR7141:
+	case AR71XX_SOC_AR7161:
+		local_irq_save(flags);
+		t = ar71xx_reset_rr(AR71XX_RESET_REG_RESET_MODULE);
+		ar71xx_reset_wr(AR71XX_RESET_REG_RESET_MODULE, t & ~mask);
+		local_irq_restore(flags);
+		break;
+
+	case AR71XX_SOC_AR9130:
+	case AR71XX_SOC_AR9132:
+		local_irq_save(flags);
+		t = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
+		ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, t & ~mask);
+		local_irq_restore(flags);
+		break;
+
+	default:
+		BUG();
+	}
+}
+EXPORT_SYMBOL_GPL(ar71xx_device_start);
+
+void ar71xx_ddr_flush(u32 reg)
+{
+	ar71xx_ddr_wr(reg, 1);
+	while ((ar71xx_ddr_rr(reg) & 0x1));
+
+	ar71xx_ddr_wr(reg, 1);
+	while ((ar71xx_ddr_rr(reg) & 0x1));
+}
+EXPORT_SYMBOL_GPL(ar71xx_ddr_flush);
+
diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/devices.c linux-2.6.29.1/arch/mips/ar71xx/devices.c
--- linux-2.6.29.1.orig/arch/mips/ar71xx/devices.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.29.1/arch/mips/ar71xx/devices.c	2009-04-13 14:27:34.491064431 +0200
@@ -0,0 +1,675 @@
+/*
+ *  Atheros AR71xx SoC platform devices
+ *
+ *  Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ *  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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/ath9k_platform.h>
+
+#include <asm/mach-ar71xx/ar71xx.h>
+
+#include "devices.h"
+
+static u8 ar71xx_mac_base[ETH_ALEN] __initdata;
+
+/*
+ * OHCI (USB full speed host controller)
+ */
+static struct resource ar71xx_ohci_resources[] = {
+	[0] = {
+		.start	= AR71XX_OHCI_BASE,
+		.end	= AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AR71XX_MISC_IRQ_OHCI,
+		.end	= AR71XX_MISC_IRQ_OHCI,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 ar71xx_ohci_dmamask = DMA_BIT_MASK(32);
+static struct platform_device ar71xx_ohci_device = {
+	.name		= "ar71xx-ohci",
+	.id		= -1,
+	.resource	= ar71xx_ohci_resources,
+	.num_resources	= ARRAY_SIZE(ar71xx_ohci_resources),
+	.dev = {
+		.dma_mask		= &ar71xx_ohci_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
+/*
+ * EHCI (USB full speed host controller)
+ */
+static struct resource ar71xx_ehci_resources[] = {
+	[0] = {
+		.start	= AR71XX_EHCI_BASE,
+		.end	= AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AR71XX_CPU_IRQ_USB,
+		.end	= AR71XX_CPU_IRQ_USB,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+
+static u64 ar71xx_ehci_dmamask = DMA_BIT_MASK(32);
+static struct ar71xx_ehci_platform_data ar71xx_ehci_data;
+
+static struct platform_device ar71xx_ehci_device = {
+	.name		= "ar71xx-ehci",
+	.id		= -1,
+	.resource	= ar71xx_ehci_resources,
+	.num_resources	= ARRAY_SIZE(ar71xx_ehci_resources),
+	.dev = {
+		.dma_mask		= &ar71xx_ehci_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data		= &ar71xx_ehci_data,
+	},
+};
+
+#define AR71XX_USB_RESET_MASK \
+	(RESET_MODULE_USB_HOST | RESET_MODULE_USB_PHY \
+	| RESET_MODULE_USB_OHCI_DLL)
+
+static void ar71xx_usb_setup(void)
+{
+	ar71xx_device_stop(AR71XX_USB_RESET_MASK);
+	mdelay(1000);
+	ar71xx_device_start(AR71XX_USB_RESET_MASK);
+
+	/* Turning on the Buff and Desc swap bits */
+	ar71xx_usb_ctrl_wr(USB_CTRL_REG_CONFIG, 0xf0000);
+
+	/* WAR for HW bug. Here it adjusts the duration between two SOFS */
+	ar71xx_usb_ctrl_wr(USB_CTRL_REG_FLADJ, 0x20c00);
+
+	mdelay(900);
+}
+
+static void ar91xx_usb_setup(void)
+{
+	ar71xx_device_stop(RESET_MODULE_USBSUS_OVERRIDE);
+	mdelay(10);
+
+	ar71xx_device_start(RESET_MODULE_USB_HOST);
+	mdelay(10);
+
+	ar71xx_device_start(RESET_MODULE_USB_PHY);
+	mdelay(10);
+}
+
+void __init ar71xx_add_device_usb(void)
+{
+	switch (ar71xx_soc) {
+	case AR71XX_SOC_AR7130:
+	case AR71XX_SOC_AR7141:
+	case AR71XX_SOC_AR7161:
+		ar71xx_usb_setup();
+		platform_device_register(&ar71xx_ohci_device);
+		platform_device_register(&ar71xx_ehci_device);
+		break;
+
+	case AR71XX_SOC_AR9130:
+	case AR71XX_SOC_AR9132:
+		ar91xx_usb_setup();
+		ar71xx_ehci_data.is_ar91xx = 1;
+		platform_device_register(&ar71xx_ehci_device);
+		break;
+
+	default:
+		BUG();
+	}
+}
+
+#ifndef CONFIG_AR71XX_EARLY_SERIAL
+static struct resource ar71xx_uart_resources[] = {
+	{
+		.start	= AR71XX_UART_BASE,
+		.end	= AR71XX_UART_BASE + AR71XX_UART_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
+static struct plat_serial8250_port ar71xx_uart_data[] = {
+	{
+		.mapbase	= AR71XX_UART_BASE,
+		.irq		= AR71XX_MISC_IRQ_UART,
+		.flags		= AR71XX_UART_FLAGS,
+		.iotype		= UPIO_MEM32,
+		.regshift	= 2,
+	}, {
+		/* terminating entry */
+	}
+};
+
+static struct platform_device ar71xx_uart_device = {
+	.name		= "serial8250",
+	.id		= PLAT8250_DEV_PLATFORM,
+	.resource	= ar71xx_uart_resources,
+	.num_resources	= ARRAY_SIZE(ar71xx_uart_resources),
+	.dev = {
+		.platform_data	= ar71xx_uart_data
+	},
+};
+
+void __init ar71xx_add_device_uart(void)
+{
+	ar71xx_uart_data[0].uartclk = ar71xx_ahb_freq;
+	platform_device_register(&ar71xx_uart_device);
+}
+#endif /* CONFIG_AR71XX_EARLY_SERIAL */
+
+static struct resource ar71xx_mdio_resources[] = {
+	{
+		.name	= "mdio_base",
+		.flags	= IORESOURCE_MEM,
+		.start	= AR71XX_GE0_BASE + 0x20,
+		.end	= AR71XX_GE0_BASE + 0x38 - 1,
+	}
+};
+
+static struct ag71xx_mdio_platform_data ar71xx_mdio_data = {
+	.phy_mask	= 0xffffffff,
+};
+
+static struct platform_device ar71xx_mdio_device = {
+	.name		= "ag71xx-mdio",
+	.id		= -1,
+	.resource	= ar71xx_mdio_resources,
+	.num_resources	= ARRAY_SIZE(ar71xx_mdio_resources),
+	.dev = {
+		.platform_data = &ar71xx_mdio_data,
+	},
+};
+
+void __init ar71xx_add_device_mdio(u32 phy_mask)
+{
+	ar71xx_mdio_data.phy_mask = phy_mask;
+	platform_device_register(&ar71xx_mdio_device);
+}
+
+static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift)
+{
+	void __iomem *base;
+	u32 t;
+
+	base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE);
+
+	t = __raw_readl(base + cfg_reg);
+	t &= ~(3 << shift);
+	t |=  (2 << shift);
+	__raw_writel(t, base + cfg_reg);
+	udelay(100);
+
+	__raw_writel(pll_val, base + pll_reg);
+
+	t |= (3 << shift);
+	__raw_writel(t, base + cfg_reg);
+	udelay(100);
+
+	t &= ~(3 << shift);
+	__raw_writel(t, base + cfg_reg);
+	udelay(100);
+
+	printk(KERN_DEBUG "ar71xx: pll_reg %#x: %#x\n",
+		(unsigned int)(base + pll_reg), __raw_readl(base + pll_reg));
+
+	iounmap(base);
+}
+
+static void ar71xx_set_pll_ge0(u32 val)
+{
+	ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH0_INT_CLOCK,
+			val, AR71XX_ETH0_PLL_SHIFT);
+}
+
+static void ar71xx_set_pll_ge1(u32 val)
+{
+	ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH1_INT_CLOCK,
+			 val, AR71XX_ETH1_PLL_SHIFT);
+}
+
+static void ar91xx_set_pll_ge0(u32 val)
+{
+	ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK,
+			 val, AR91XX_ETH0_PLL_SHIFT);
+}
+
+static void ar91xx_set_pll_ge1(u32 val)
+{
+	ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK,
+			 val, AR91XX_ETH1_PLL_SHIFT);
+}
+
+static void ar71xx_ddr_flush_ge0(void)
+{
+	ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE0);
+}
+
+static void ar71xx_ddr_flush_ge1(void)
+{
+	ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE1);
+}
+
+static void ar91xx_ddr_flush_ge0(void)
+{
+	ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE0);
+}
+
+static void ar91xx_ddr_flush_ge1(void)
+{
+	ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE1);
+}
+
+static struct resource ar71xx_eth0_resources[] = {
+	{
+		.name	= "mac_base",
+		.flags	= IORESOURCE_MEM,
+		.start	= AR71XX_GE0_BASE,
+		.end	= AR71XX_GE0_BASE + 0x20 - 1,
+	}, {
+		.name	= "mac_base2",
+		.flags	= IORESOURCE_MEM,
+		.start	= AR71XX_GE0_BASE + 0x38,
+		.end	= AR71XX_GE0_BASE + 0x200 - 1,
+	}, {
+		.name	= "mii_ctrl",
+		.flags	= IORESOURCE_MEM,
+		.start	= AR71XX_MII_BASE + MII_REG_MII0_CTRL,
+		.end	= AR71XX_MII_BASE + MII_REG_MII0_CTRL + 3,
+	}, {
+		.name	= "mac_irq",
+		.flags	= IORESOURCE_IRQ,
+		.start	= AR71XX_CPU_IRQ_GE0,
+		.end	= AR71XX_CPU_IRQ_GE0,
+	},
+};
+
+struct ag71xx_platform_data ar71xx_eth0_data = {
+	.reset_bit	= RESET_MODULE_GE0_MAC,
+};
+
+static struct platform_device ar71xx_eth0_device = {
+	.name		= "ag71xx",
+	.id		= 0,
+	.resource	= ar71xx_eth0_resources,
+	.num_resources	= ARRAY_SIZE(ar71xx_eth0_resources),
+	.dev = {
+		.platform_data = &ar71xx_eth0_data,
+	},
+};
+
+static struct resource ar71xx_eth1_resources[] = {
+	{
+		.name	= "mac_base",
+		.flags	= IORESOURCE_MEM,
+		.start	= AR71XX_GE1_BASE,
+		.end	= AR71XX_GE1_BASE + 0x20 - 1,
+	}, {
+		.name	= "mac_base2",
+		.flags	= IORESOURCE_MEM,
+		.start	= AR71XX_GE1_BASE + 0x38,
+		.end	= AR71XX_GE1_BASE + 0x200 - 1,
+	}, {
+		.name	= "mii_ctrl",
+		.flags	= IORESOURCE_MEM,
+		.start	= AR71XX_MII_BASE + MII_REG_MII1_CTRL,
+		.end	= AR71XX_MII_BASE + MII_REG_MII1_CTRL + 3,
+	}, {
+		.name	= "mac_irq",
+		.flags	= IORESOURCE_IRQ,
+		.start	= AR71XX_CPU_IRQ_GE1,
+		.end	= AR71XX_CPU_IRQ_GE1,
+	},
+};
+
+struct ag71xx_platform_data ar71xx_eth1_data = {
+	.reset_bit	= RESET_MODULE_GE1_MAC,
+};
+
+static struct platform_device ar71xx_eth1_device = {
+	.name		= "ag71xx",
+	.id		= 1,
+	.resource	= ar71xx_eth1_resources,
+	.num_resources	= ARRAY_SIZE(ar71xx_eth1_resources),
+	.dev = {
+		.platform_data = &ar71xx_eth1_data,
+	},
+};
+
+static int ar71xx_eth_instance __initdata;
+void __init ar71xx_add_device_eth(unsigned int id)
+{
+	struct platform_device *pdev;
+	struct ag71xx_platform_data *pdata;
+
+	switch (id) {
+	case 0:
+		switch (ar71xx_eth0_data.phy_if_mode) {
+		case PHY_INTERFACE_MODE_MII:
+			ar71xx_eth0_data.mii_if = MII0_CTRL_IF_MII;
+			break;
+		case PHY_INTERFACE_MODE_GMII:
+			ar71xx_eth0_data.mii_if = MII0_CTRL_IF_GMII;
+			break;
+		case PHY_INTERFACE_MODE_RGMII:
+			ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RGMII;
+			break;
+		case PHY_INTERFACE_MODE_RMII:
+			ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RMII;
+			break;
+		default:
+			printk(KERN_ERR "ar71xx: invalid PHY interface mode "
+					"for eth0\n");
+			return;
+		}
+		pdev = &ar71xx_eth0_device;
+		break;
+	case 1:
+		switch (ar71xx_eth1_data.phy_if_mode) {
+		case PHY_INTERFACE_MODE_RMII:
+			ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RMII;
+			break;
+		case PHY_INTERFACE_MODE_RGMII:
+			ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RGMII;
+			break;
+		default:
+			printk(KERN_ERR "ar71xx: invalid PHY interface mode "
+					"for eth1\n");
+			return;
+		}
+		pdev = &ar71xx_eth1_device;
+		break;
+	default:
+		printk(KERN_ERR "ar71xx: invalid ethernet id %d\n", id);
+		return;
+	}
+
+	pdata = pdev->dev.platform_data;
+
+	switch (ar71xx_soc) {
+	case AR71XX_SOC_AR7130:
+		pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
+				      : ar71xx_ddr_flush_ge0;
+		pdata->set_pll =  id ? ar71xx_set_pll_ge1
+				     : ar71xx_set_pll_ge0;
+		break;
+
+	case AR71XX_SOC_AR7141:
+	case AR71XX_SOC_AR7161:
+		pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
+				      : ar71xx_ddr_flush_ge0;
+		pdata->set_pll =  id ? ar71xx_set_pll_ge1
+				     : ar71xx_set_pll_ge0;
+		pdata->has_gbit = 1;
+		break;
+
+	case AR71XX_SOC_AR9130:
+		pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
+				      : ar91xx_ddr_flush_ge0;
+		pdata->set_pll =  id ? ar91xx_set_pll_ge1
+				     : ar91xx_set_pll_ge0;
+		pdata->is_ar91xx = 1;
+		break;
+
+	case AR71XX_SOC_AR9132:
+		pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
+				      : ar91xx_ddr_flush_ge0;
+		pdata->set_pll =  id ? ar91xx_set_pll_ge1
+				      : ar91xx_set_pll_ge0;
+		pdata->is_ar91xx = 1;
+		pdata->has_gbit = 1;
+		break;
+
+	default:
+		BUG();
+	}
+
+	switch (pdata->phy_if_mode) {
+	case PHY_INTERFACE_MODE_GMII:
+	case PHY_INTERFACE_MODE_RGMII:
+		if (!pdata->has_gbit) {
+			printk(KERN_ERR "ar71xx: no gbit available on eth%d\n",
+					id);
+			return;
+		}
+		/* fallthrough */
+	default:
+		break;
+	}
+
+	if (is_valid_ether_addr(ar71xx_mac_base)) {
+		memcpy(pdata->mac_addr, ar71xx_mac_base, ETH_ALEN);
+		pdata->mac_addr[5] += ar71xx_eth_instance;
+	} else {
+		random_ether_addr(pdata->mac_addr);
+		printk(KERN_DEBUG
+			"ar71xx: using random MAC address for eth%d\n",
+			ar71xx_eth_instance);
+	}
+
+	platform_device_register(pdev);
+	ar71xx_eth_instance++;
+}
+
+static struct resource ar71xx_spi_resources[] = {
+	[0] = {
+		.start	= AR71XX_SPI_BASE,
+		.end	= AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ar71xx_spi_device = {
+	.name		= "ar71xx-spi",
+	.id		= -1,
+	.resource	= ar71xx_spi_resources,
+	.num_resources	= ARRAY_SIZE(ar71xx_spi_resources),
+};
+
+void __init ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata,
+				struct spi_board_info const *info,
+				unsigned n)
+{
+	spi_register_board_info(info, n);
+	ar71xx_spi_device.dev.platform_data = pdata;
+	platform_device_register(&ar71xx_spi_device);
+}
+
+void __init ar71xx_add_device_leds_gpio(int id, unsigned num_leds,
+				struct gpio_led *leds)
+{
+	struct platform_device *pdev;
+	struct gpio_led_platform_data pdata;
+	struct gpio_led *p;
+	int err;
+
+	p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return;
+
+	memcpy(p, leds, num_leds * sizeof(*p));
+
+	pdev = platform_device_alloc("leds-gpio", id);
+	if (!pdev)
+		goto err_free_leds;
+
+	memset(&pdata, 0, sizeof(pdata));
+	pdata.num_leds = num_leds;
+	pdata.leds = p;
+
+	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+	if (err)
+		goto err_put_pdev;
+
+	err = platform_device_add(pdev);
+	if (err)
+		goto err_put_pdev;
+
+	return;
+
+err_put_pdev:
+	platform_device_put(pdev);
+
+err_free_leds:
+	kfree(p);
+}
+
+void __init ar71xx_add_device_gpio_buttons(int id,
+					   unsigned poll_interval,
+					   unsigned nbuttons,
+					   struct gpio_button *buttons)
+{
+	struct platform_device *pdev;
+	struct gpio_buttons_platform_data pdata;
+	struct gpio_button *p;
+	int err;
+
+	p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return;
+
+	memcpy(p, buttons, nbuttons * sizeof(*p));
+
+	pdev = platform_device_alloc("gpio-buttons", id);
+	if (!pdev)
+		goto err_free_buttons;
+
+	memset(&pdata, 0, sizeof(pdata));
+	pdata.poll_interval = poll_interval;
+	pdata.nbuttons = nbuttons;
+	pdata.buttons = p;
+
+	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+	if (err)
+		goto err_put_pdev;
+
+
+	err = platform_device_add(pdev);
+	if (err)
+		goto err_put_pdev;
+
+	return;
+
+err_put_pdev:
+	platform_device_put(pdev);
+
+err_free_buttons:
+	kfree(p);
+}
+
+void __init ar71xx_add_device_wdt(void)
+{
+	platform_device_register_simple("ar71xx-wdt", -1, NULL, 0);
+}
+
+void __init ar71xx_set_mac_base(unsigned char *mac)
+{
+	memcpy(ar71xx_mac_base, mac, ETH_ALEN);
+}
+
+void __init ar71xx_parse_mac_addr(char *mac_str)
+{
+	u8 tmp[ETH_ALEN];
+	int t;
+
+	t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
+			&tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
+
+	if (t != ETH_ALEN)
+		t = sscanf(mac_str, "%02hhx.%02hhx.%02hhx.%02hhx.%02hhx.%02hhx",
+			&tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
+
+	if (t == ETH_ALEN)
+		ar71xx_set_mac_base(tmp);
+	else
+		printk(KERN_DEBUG "ar71xx: failed to parse mac address "
+				"\"%s\"\n", mac_str);
+}
+
+static struct resource ar91xx_wmac_resources[] = {
+	{
+		.start	= AR91XX_WMAC_BASE,
+		.end	= AR91XX_WMAC_BASE + AR91XX_WMAC_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= AR71XX_CPU_IRQ_WMAC,
+		.end	= AR71XX_CPU_IRQ_WMAC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct ath9k_platform_data ar91xx_wmac_data;
+
+static struct platform_device ar91xx_wmac_device = {
+	.name		= "ath9k",
+	.id		= -1,
+	.resource	= ar91xx_wmac_resources,
+	.num_resources	= ARRAY_SIZE(ar91xx_wmac_resources),
+	.dev = {
+		.platform_data = &ar91xx_wmac_data,
+	},
+};
+
+void __init ar91xx_add_device_wmac(void)
+{
+	u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
+
+	memcpy(ar91xx_wmac_data.eeprom_data, ee,
+	       sizeof(ar91xx_wmac_data.eeprom_data));
+
+	ar71xx_device_stop(RESET_MODULE_AMBA2WMAC);
+	mdelay(10);
+
+	ar71xx_device_start(RESET_MODULE_AMBA2WMAC);
+	mdelay(10);
+
+	platform_device_register(&ar91xx_wmac_device);
+}
+
+static struct platform_device ar71xx_dsa_switch_device = {
+	.name		= "dsa",
+	.id		= 0,
+};
+
+void __init ar71xx_add_device_dsa(unsigned int id,
+				  struct dsa_platform_data *d)
+{
+	switch (id) {
+	case 0:
+		d->netdev = &ar71xx_eth0_device.dev;
+		break;
+	case 1:
+		d->netdev = &ar71xx_eth1_device.dev;
+		break;
+	default:
+		printk(KERN_ERR
+			"ar71xx: invalid ethernet id %d for DSA switch\n",
+			id);
+		return;
+	}
+	d->mii_bus = &ar71xx_mdio_device.dev;
+	ar71xx_dsa_switch_device.dev.platform_data = d;
+
+	platform_device_register(&ar71xx_dsa_switch_device);
+}
diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/devices.h linux-2.6.29.1/arch/mips/ar71xx/devices.h
--- linux-2.6.29.1.orig/arch/mips/ar71xx/devices.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.29.1/arch/mips/ar71xx/devices.h	2009-04-13 14:27:34.491064431 +0200
@@ -0,0 +1,58 @@
+/*
+ *  Atheros AR71xx SoC device definitions
+ *
+ *  Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  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.
+ */
+
+#ifndef __AR71XX_DEVICES_H
+#define __AR71XX_DEVICES_H
+
+#include <asm/mach-ar71xx/platform.h>
+
+#include <linux/leds.h>
+#include <linux/gpio_buttons.h>
+#include <net/dsa.h>
+
+void ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata,
+			   struct spi_board_info const *info,
+			   unsigned n) __init;
+
+void ar71xx_set_mac_base(unsigned char *mac) __init;
+void ar71xx_parse_mac_addr(char *mac_str) __init;
+
+extern struct ag71xx_platform_data ar71xx_eth0_data;
+extern struct ag71xx_platform_data ar71xx_eth1_data;
+void ar71xx_add_device_eth(unsigned int id) __init;
+
+void ar71xx_add_device_mdio(u32 phy_mask) __init;
+
+void ar71xx_add_device_leds_gpio(int id,
+				 unsigned num_leds,
+				 struct gpio_led *leds) __init;
+
+void ar71xx_add_device_gpio_buttons(int id,
+				    unsigned poll_interval,
+				    unsigned nbuttons,
+				    struct gpio_button *buttons) __init;
+
+void ar71xx_add_device_usb(void) __init;
+
+#ifdef CONFIG_AR71XX_EARLY_SERIAL
+static inline void ar71xx_add_device_uart(void) {}
+#else
+void ar71xx_add_device_uart(void) __init;
+#endif
+
+void ar71xx_add_device_wdt(void) __init;
+
+void ar91xx_add_device_wmac(void) __init;
+
+void ar71xx_add_device_dsa(unsigned int id,
+			   struct dsa_platform_data *d) __init;
+
+#endif /* __AR71XX_DEVICES_H */
diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/gpio.c linux-2.6.29.1/arch/mips/ar71xx/gpio.c
--- linux-2.6.29.1.orig/arch/mips/ar71xx/gpio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.29.1/arch/mips/ar71xx/gpio.c	2009-04-13 14:27:34.495064103 +0200
@@ -0,0 +1,154 @@
+/*
+ *  Atheros AR71xx SoC GPIO API support
+ *
+ *  Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-ar71xx/ar71xx.h>
+
+static DEFINE_SPINLOCK(ar71xx_gpio_lock);
+
+unsigned long ar71xx_gpio_count;
+EXPORT_SYMBOL(ar71xx_gpio_count);
+
+void __ar71xx_gpio_set_value(unsigned gpio, int value)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ar71xx_gpio_lock, flags);
+
+	if (value)
+		ar71xx_gpio_wr(GPIO_REG_SET, (1 << gpio));
+	else
+		ar71xx_gpio_wr(GPIO_REG_CLEAR, (1 << gpio));
+
+	spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
+}
+EXPORT_SYMBOL(__ar71xx_gpio_set_value);
+
+int __ar71xx_gpio_get_value(unsigned gpio)
+{
+	return (ar71xx_gpio_rr(GPIO_REG_IN) & (1 << gpio)) ? 1 : 0;
+}
+EXPORT_SYMBOL(__ar71xx_gpio_get_value);
+
+static int ar71xx_gpio_get_value(struct gpio_chip *chip, unsigned offset)
+{
+	return __ar71xx_gpio_get_value(offset);
+}
+
+static void ar71xx_gpio_set_value(struct gpio_chip *chip,
+				  unsigned offset, int value)
+{
+	__ar71xx_gpio_set_value(offset, value);
+}
+
+static int ar71xx_gpio_direction_input(struct gpio_chip *chip,
+				       unsigned offset)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ar71xx_gpio_lock, flags);
+
+	ar71xx_gpio_wr(GPIO_REG_OE,
+			ar71xx_gpio_rr(GPIO_REG_OE) & ~(1 << offset));
+
+	spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
+
+	return 0;
+}
+
+static int ar71xx_gpio_direction_output(struct gpio_chip *chip,
+					unsigned offset, int value)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ar71xx_gpio_lock, flags);
+
+	if (value)
+		ar71xx_gpio_wr(GPIO_REG_SET, (1 << offset));
+	else
+		ar71xx_gpio_wr(GPIO_REG_CLEAR, (1 << offset));
+
+	ar71xx_gpio_wr(GPIO_REG_OE,
+			ar71xx_gpio_rr(GPIO_REG_OE) | (1 << offset));
+
+	spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
+
+	return 0;
+}
+
+static struct gpio_chip ar71xx_gpio_chip = {
+	.label			= "ar71xx",
+	.get			= ar71xx_gpio_get_value,
+	.set			= ar71xx_gpio_set_value,
+	.direction_input	= ar71xx_gpio_direction_input,
+	.direction_output	= ar71xx_gpio_direction_output,
+	.base			= 0,
+	.ngpio			= AR71XX_GPIO_COUNT,
+};
+
+void ar71xx_gpio_function_enable(u32 mask)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ar71xx_gpio_lock, flags);
+
+	ar71xx_gpio_wr(GPIO_REG_FUNC, ar71xx_gpio_rr(GPIO_REG_FUNC) | mask);
+
+	spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
+}
+
+void ar71xx_gpio_function_disable(u32 mask)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ar71xx_gpio_lock, flags);
+
+	ar71xx_gpio_wr(GPIO_REG_FUNC, ar71xx_gpio_rr(GPIO_REG_FUNC) & ~mask);
+
+	spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
+}
+
+void __init ar71xx_gpio_init(void)
+{
+	int err;
+
+	if (!request_mem_region(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
+				"AR71xx GPIO controller"))
+		panic("cannot allocate AR71xx GPIO registers page");
+
+	switch (ar71xx_soc) {
+	case AR71XX_SOC_AR7130:
+	case AR71XX_SOC_AR7141:
+	case AR71XX_SOC_AR7161:
+		ar71xx_gpio_chip.ngpio = AR71XX_GPIO_COUNT;
+		break;
+
+	case AR71XX_SOC_AR9130:
+	case AR71XX_SOC_AR9132:
+		ar71xx_gpio_chip.ngpio = AR91XX_GPIO_COUNT;
+		break;
+
+	default:
+		BUG();
+	}
+
+	err = gpiochip_add(&ar71xx_gpio_chip);
+	if (err)
+		panic("cannot add AR71xx GPIO chip, error=%d", err);
+}
diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/irq.c linux-2.6.29.1/arch/mips/ar71xx/irq.c
--- linux-2.6.29.1.orig/arch/mips/ar71xx/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.29.1/arch/mips/ar71xx/irq.c	2009-04-13 14:27:34.543070220 +0200
@@ -0,0 +1,302 @@
+/*
+ *  Atheros AR71xx SoC specific interrupt handling
+ *
+ *  Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ *  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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+
+#include <asm/mach-ar71xx/ar71xx.h>
+
+#ifdef CONFIG_PCI
+static void ar71xx_pci_irq_dispatch(void)
+{
+	u32 pending;
+
+	pending = ar71xx_reset_rr(AR71XX_RESET_REG_PCI_INT_STATUS) &
+	    ar71xx_reset_rr(AR71XX_RESET_REG_PCI_INT_ENABLE);
+
+	if (pending & PCI_INT_DEV0)
+		do_IRQ(AR71XX_PCI_IRQ_DEV0);
+
+	else if (pending & PCI_INT_DEV1)
+		do_IRQ(AR71XX_PCI_IRQ_DEV1);
+
+	else if (pending & PCI_INT_DEV2)
+		do_IRQ(AR71XX_PCI_IRQ_DEV2);
+
+	else
+		spurious_interrupt();
+}
+
+static void ar71xx_pci_irq_unmask(unsigned int irq)
+{
+	irq -= AR71XX_PCI_IRQ_BASE;
+	ar71xx_reset_wr(AR71XX_RESET_REG_PCI_INT_ENABLE,
+		ar71xx_reset_rr(AR71XX_RESET_REG_PCI_INT_ENABLE) | (1 << irq));
+}
+
+static void ar71xx_pci_irq_mask(unsigned int irq)
+{
+	irq -= AR71XX_PCI_IRQ_BASE;
+	ar71xx_reset_wr(AR71XX_RESET_REG_PCI_INT_ENABLE,
+		ar71xx_reset_rr(AR71XX_RESET_REG_PCI_INT_ENABLE) & ~(1 << irq));
+}
+
+static struct irq_chip ar71xx_pci_irq_chip = {
+	.name		= "AR71XX PCI ",
+	.mask		= ar71xx_pci_irq_mask,
+	.unmask		= ar71xx_pci_irq_unmask,
+	.mask_ack	= ar71xx_pci_irq_mask,
+};
+
+static struct irqaction ar71xx_pci_irqaction = {
+	.handler	= no_action,
+	.name		= "cascade [AR71XX PCI]",
+};
+
+static void __init ar71xx_pci_irq_init(void)
+{
+	int i;
+
+	ar71xx_reset_wr(AR71XX_RESET_REG_PCI_INT_ENABLE, 0);
+	ar71xx_reset_wr(AR71XX_RESET_REG_PCI_INT_STATUS, 0);
+
+	for (i = AR71XX_PCI_IRQ_BASE;
+	     i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		set_irq_chip_and_handler(i, &ar71xx_pci_irq_chip,
+					 handle_level_irq);
+	}
+
+	setup_irq(AR71XX_CPU_IRQ_PCI, &ar71xx_pci_irqaction);
+}
+#endif /* CONFIG_PCI */
+
+static void ar71xx_gpio_irq_dispatch(void)
+{
+	u32 pending;
+
+	pending = ar71xx_gpio_rr(GPIO_REG_INT_PENDING)
+		& ar71xx_gpio_rr(GPIO_REG_INT_ENABLE);
+
+	if (pending)
+		do_IRQ(AR71XX_GPIO_IRQ_BASE + fls(pending) - 1);
+	else
+		spurious_interrupt();
+}
+
+static void ar71xx_gpio_irq_unmask(unsigned int irq)
+{
+	irq -= AR71XX_GPIO_IRQ_BASE;
+	ar71xx_gpio_wr(GPIO_REG_INT_ENABLE,
+			ar71xx_gpio_rr(GPIO_REG_INT_ENABLE) | (1 << irq));
+}
+
+static void ar71xx_gpio_irq_mask(unsigned int irq)
+{
+	irq -= AR71XX_GPIO_IRQ_BASE;
+	ar71xx_gpio_wr(GPIO_REG_INT_ENABLE,
+			ar71xx_gpio_rr(GPIO_REG_INT_ENABLE) & ~(1 << irq));
+}
+
+#if 0
+static int ar71xx_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
+{
+	/* TODO: implement */
+	return 0;
+}
+#else
+#define ar71xx_gpio_irq_set_type	NULL
+#endif
+
+struct irq_chip ar71xx_gpio_irq_chip = {
+	.name		= "AR71XX GPIO",
+	.unmask		= ar71xx_gpio_irq_unmask,
+	.mask		= ar71xx_gpio_irq_mask,
+	.mask_ack	= ar71xx_gpio_irq_mask,
+	.set_type	= ar71xx_gpio_irq_set_type,
+};
+
+static struct irqaction ar71xx_gpio_irqaction = {
+	.handler	= no_action,
+	.name		= "cascade [AR71XX GPIO]",
+};
+
+#define GPIO_IRQ_INIT_STATUS (IRQ_LEVEL | IRQ_TYPE_LEVEL_HIGH | IRQ_DISABLED)
+#define GPIO_INT_ALL	0xffff
+
+static void __init ar71xx_gpio_irq_init(void)
+{
+	int i;
+
+	ar71xx_gpio_wr(GPIO_REG_INT_ENABLE, 0);
+	ar71xx_gpio_wr(GPIO_REG_INT_PENDING, 0);
+
+	/* setup type of all GPIO interrupts to level sensitive */
+	ar71xx_gpio_wr(GPIO_REG_INT_TYPE, GPIO_INT_ALL);
+
+	/* setup polarity of all GPIO interrupts to active high */
+	ar71xx_gpio_wr(GPIO_REG_INT_POLARITY, GPIO_INT_ALL);
+
+	for (i = AR71XX_GPIO_IRQ_BASE;
+	     i < AR71XX_GPIO_IRQ_BASE + AR71XX_GPIO_IRQ_COUNT; i++) {
+		irq_desc[i].status = GPIO_IRQ_INIT_STATUS;
+		set_irq_chip_and_handler(i, &ar71xx_gpio_irq_chip,
+					 handle_level_irq);
+	}
+
+	setup_irq(AR71XX_MISC_IRQ_GPIO, &ar71xx_gpio_irqaction);
+}
+
+static void ar71xx_misc_irq_dispatch(void)
+{
+	u32 pending;
+
+	pending = ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_STATUS)
+	    & ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+	if (pending & MISC_INT_UART)
+		do_IRQ(AR71XX_MISC_IRQ_UART);
+
+	else if (pending & MISC_INT_DMA)
+		do_IRQ(AR71XX_MISC_IRQ_DMA);
+
+	else if (pending & MISC_INT_PERFC)
+		do_IRQ(AR71XX_MISC_IRQ_PERFC);
+
+	else if (pending & MISC_INT_TIMER)
+		do_IRQ(AR71XX_MISC_IRQ_TIMER);
+
+	else if (pending & MISC_INT_OHCI)
+		do_IRQ(AR71XX_MISC_IRQ_OHCI);
+
+	else if (pending & MISC_INT_ERROR)
+		do_IRQ(AR71XX_MISC_IRQ_ERROR);
+
+	else if (pending & MISC_INT_GPIO)
+		ar71xx_gpio_irq_dispatch();
+
+	else if (pending & MISC_INT_WDOG)
+		do_IRQ(AR71XX_MISC_IRQ_WDOG);
+
+	else
+		spurious_interrupt();
+}
+
+static void ar71xx_misc_irq_unmask(unsigned int irq)
+{
+	irq -= AR71XX_MISC_IRQ_BASE;
+	ar71xx_reset_wr(AR71XX_RESET_REG_MISC_INT_ENABLE,
+		ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE) | (1 << irq));
+}
+
+static void ar71xx_misc_irq_mask(unsigned int irq)
+{
+	irq -= AR71XX_MISC_IRQ_BASE;
+	ar71xx_reset_wr(AR71XX_RESET_REG_MISC_INT_ENABLE,
+		ar71xx_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE) & ~(1 << irq));
+}
+
+struct irq_chip ar71xx_misc_irq_chip = {
+	.name		= "AR71XX MISC",
+	.unmask		= ar71xx_misc_irq_unmask,
+	.mask		= ar71xx_misc_irq_mask,
+	.mask_ack	= ar71xx_misc_irq_mask,
+};
+
+static struct irqaction ar71xx_misc_irqaction = {
+	.handler	= no_action,
+	.name		= "cascade [AR71XX MISC]",
+};
+
+static void __init ar71xx_misc_irq_init(void)
+{
+	int i;
+
+	ar71xx_reset_wr(AR71XX_RESET_REG_MISC_INT_ENABLE, 0);
+	ar71xx_reset_wr(AR71XX_RESET_REG_MISC_INT_STATUS, 0);
+
+	for (i = AR71XX_MISC_IRQ_BASE;
+	     i < AR71XX_MISC_IRQ_BASE + AR71XX_MISC_IRQ_COUNT; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		set_irq_chip_and_handler(i, &ar71xx_misc_irq_chip,
+					 handle_level_irq);
+	}
+
+	setup_irq(AR71XX_CPU_IRQ_MISC, &ar71xx_misc_irqaction);
+}
+
+static void ar913x_wmac_irq_dispatch(void)
+{
+	do_IRQ(AR71XX_CPU_IRQ_WMAC);
+}
+
+static void (* ar71xx_ip2_irq_handler)(void) = spurious_interrupt;
+
+asmlinkage void plat_irq_dispatch(void)
+{
+	unsigned long pending;
+
+	pending = read_c0_status() & read_c0_cause() & ST0_IM;
+
+	if (pending & STATUSF_IP7)
+		do_IRQ(AR71XX_CPU_IRQ_TIMER);
+
+	else if (pending & STATUSF_IP2)
+		ar71xx_ip2_irq_handler();
+
+	else if (pending & STATUSF_IP4)
+		do_IRQ(AR71XX_CPU_IRQ_GE0);
+
+	else if (pending & STATUSF_IP5)
+		do_IRQ(AR71XX_CPU_IRQ_GE1);
+
+	else if (pending & STATUSF_IP3)
+		do_IRQ(AR71XX_CPU_IRQ_USB);
+
+	else if (pending & STATUSF_IP6)
+		ar71xx_misc_irq_dispatch();
+
+	else
+		spurious_interrupt();
+}
+
+void __init arch_init_irq(void)
+{
+	mips_cpu_irq_init();
+
+	ar71xx_misc_irq_init();
+
+	switch (ar71xx_soc) {
+	case AR71XX_SOC_AR7130:
+	case AR71XX_SOC_AR7141:
+	case AR71XX_SOC_AR7161:
+#ifdef CONFIG_PCI
+		ar71xx_pci_irq_init();
+		ar71xx_ip2_irq_handler = ar71xx_pci_irq_dispatch;
+#endif
+		break;
+	case AR71XX_SOC_AR9130:
+	case AR71XX_SOC_AR9132:
+		ar71xx_ip2_irq_handler = ar913x_wmac_irq_dispatch;
+		break;
+	default:
+		BUG();
+	}
+
+	ar71xx_gpio_irq_init();
+}
diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-ap81.c linux-2.6.29.1/arch/mips/ar71xx/mach-ap81.c
--- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-ap81.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.29.1/arch/mips/ar71xx/mach-ap81.c	2009-04-13 14:27:34.543070220 +0200
@@ -0,0 +1,148 @@
+/*
+ *  Atheros AP81 board support
+ *
+ *  Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  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 <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/input.h>
+
+#include <asm/mips_machine.h>
+#include <asm/mach-ar71xx/ar71xx.h>
+
+#include "devices.h"
+
+#define AP81_GPIO_LED_STATUS	1
+#define AP81_GPIO_LED_AOSS	3
+#define AP81_GPIO_LED_WLAN	6
+#define AP81_GPIO_LED_POWER	14
+
+#define AP81_GPIO_BTN_SW4	12
+#define AP81_GPIO_BTN_SW1	21
+
+#define AP81_BUTTONS_POLL_INTERVAL	20
+
+#ifdef CONFIG_MTD_PARTITIONS
+static struct mtd_partition ap81_partitions[] = {
+	{
+		.name		= "u-boot",
+		.offset		= 0,
+		.size		= 0x040000,
+		.mask_flags	= MTD_WRITEABLE,
+	} , {
+		.name		= "u-boot-env",
+		.offset		= 0x040000,
+		.size		= 0x010000,
+	} , {
+		.name		= "rootfs",
+		.offset		= 0x050000,
+		.size		= 0x500000,
+	} , {
+		.name		= "uImage",
+		.offset		= 0x550000,
+		.size		= 0x100000,
+	} , {
+		.name		= "ART",
+		.offset		= 0x650000,
+		.size		= 0x1b0000,
+		.mask_flags	= MTD_WRITEABLE,
+	}
+};
+#endif /* CONFIG_MTD_PARTITIONS */
+
+static struct flash_platform_data ap81_flash_data = {
+#ifdef CONFIG_MTD_PARTITIONS
+        .parts          = ap81_partitions,
+        .nr_parts       = ARRAY_SIZE(ap81_partitions),
+#endif
+};
+
+static struct spi_board_info ap81_spi_info[] = {
+	{
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.max_speed_hz	= 25000000,
+		.modalias	= "m25p80",
+		.platform_data  = &ap81_flash_data,
+	}
+};
+
+static struct gpio_led ap81_leds_gpio[] __initdata = {
+	{
+		.name		= "ap81:green:status",
+		.gpio		= AP81_GPIO_LED_STATUS,
+		.active_low	= 1,
+	}, {
+		.name		= "ap81:amber:aoss",
+		.gpio		= AP81_GPIO_LED_AOSS,
+		.active_low	= 1,
+	}, {
+		.name		= "ap81:green:wlan",
+		.gpio		= AP81_GPIO_LED_WLAN,
+		.active_low	= 1,
+	}, {
+		.name		= "ap81:green:power",
+		.gpio		= AP81_GPIO_LED_POWER,
+		.active_low	= 1,
+	}
+};
+
+static struct gpio_button ap81_gpio_buttons[] __initdata = {
+	{
+		.desc		= "sw1",
+		.type		= EV_KEY,
+		.code		= BTN_0,
+		.threshold	= 5,
+		.gpio		= AP81_GPIO_BTN_SW1,
+		.active_low	= 1,
+	} , {
+		.desc		= "sw4",
+		.type		= EV_KEY,
+		.code		= BTN_1,
+		.threshold	= 5,
+		.gpio		= AP81_GPIO_BTN_SW4,
+		.active_low	= 1,
+	}
+};
+
+static void __init ap81_setup(void)
+{
+	ar71xx_add_device_mdio(0x0);
+
+	ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
+	ar71xx_eth0_data.phy_mask = 0xf;
+	ar71xx_eth0_data.speed = SPEED_100;
+	ar71xx_eth0_data.duplex = DUPLEX_FULL;
+	ar71xx_eth0_data.has_ar8216 = 1;
+
+	ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
+	ar71xx_eth1_data.phy_mask = 0x10;
+
+	ar71xx_add_device_eth(0);
+	ar71xx_add_device_eth(1);
+
+	ar71xx_add_device_usb();
+
+	ar71xx_add_device_spi(NULL, ap81_spi_info,
+			      ARRAY_SIZE(ap81_spi_info));
+
+	ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio),
+					ap81_leds_gpio);
+
+	ar71xx_add_device_gpio_buttons(-1, AP81_BUTTONS_POLL_INTERVAL,
+					ARRAY_SIZE(ap81_gpio_buttons),
+					ap81_gpio_buttons);
+
+	ar91xx_add_device_wmac();
+}
+
+MIPS_MACHINE(AR71XX_MACH_AP81, "Atheros AP81", ap81_setup);
diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-ap83.c linux-2.6.29.1/arch/mips/ar71xx/mach-ap83.c
--- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-ap83.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.29.1/arch/mips/ar71xx/mach-ap83.c	2009-04-13 14:27:34.547067937 +0200
@@ -0,0 +1,87 @@
+/*
+ *  Atheros AP83 board support
+ *
+ *  Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  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 <linux/platform_device.h>
+#include <linux/input.h>
+
+#include <asm/mips_machine.h>
+#include <asm/mach-ar71xx/ar71xx.h>
+
+#include "devices.h"
+
+#define AP83_GPIO_LED_WLAN	6
+#define AP83_GPIO_LED_POWER	14
+#define AP83_GPIO_LED_JUMPSTART	15
+#define AP83_GPIO_BTN_JUMPSTART	12
+#define AP83_GPIO_BTN_RESET	21
+
+static struct gpio_led ap83_leds_gpio[] __initdata = {
+	{
+		.name		= "ap83:green:jumpstart",
+		.gpio		= AP83_GPIO_LED_JUMPSTART,
+		.active_low	= 0,
+	}, {
+		.name		= "ap83:green:power",
+		.gpio		= AP83_GPIO_LED_POWER,
+		.active_low	= 0,
+	}, {
+		.name		= "ap83:green:wlan",
+		.gpio		= AP83_GPIO_LED_WLAN,
+		.active_low	= 0,
+	},
+};
+
+static struct gpio_button ap83_gpio_buttons[] __initdata = {
+	{
+		.desc		= "soft_reset",
+		.type		= EV_KEY,
+		.code		= BTN_0,
+		.threshold	= 5,
+		.gpio		= AP83_GPIO_BTN_RESET,
+		.active_low	= 1,
+	} , {
+		.desc		= "jumpstart",
+		.type		= EV_KEY,
+		.code		= BTN_1,
+		.threshold	= 5,
+		.gpio		= AP83_GPIO_BTN_JUMPSTART,
+		.active_low	= 1,
+	}
+};
+
+static void __init ap83_setup(void)
+{
+	ar71xx_add_device_mdio(0xfffffffe);
+
+	ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
+	ar71xx_eth0_data.phy_mask = 0x1;
+
+	ar71xx_add_device_eth(0);
+
+	ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
+	ar71xx_eth1_data.phy_mask = 0x0;
+	ar71xx_eth1_data.speed = SPEED_1000;
+	ar71xx_eth1_data.duplex = DUPLEX_FULL;
+
+	ar71xx_add_device_eth(1);
+
+	ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ap83_leds_gpio),
+					ap83_leds_gpio);
+
+	ar71xx_add_device_gpio_buttons(-1, 20, ARRAY_SIZE(ap83_gpio_buttons),
+					ap83_gpio_buttons);
+
+	ar71xx_add_device_usb();
+
+	ar91xx_add_device_wmac();
+}
+
+MIPS_MACHINE(AR71XX_MACH_AP83, "Atheros AP83", ap83_setup);
diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-aw-nr580.c linux-2.6.29.1/arch/mips/ar71xx/mach-aw-nr580.c
--- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-aw-nr580.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.29.1/arch/mips/ar71xx/mach-aw-nr580.c	2009-04-13 14:27:34.547067937 +0200
@@ -0,0 +1,119 @@
+/*
+ *  AzureWave AW-NR580 board support
+ *
+ *  Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  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 <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/input.h>
+
+#include <asm/mips_machine.h>
+#include <asm/mach-ar71xx/ar71xx.h>
+#include <asm/mach-ar71xx/pci.h>
+
+#include "devices.h"
+
+#define AW_NR580_GPIO_LED_READY_RED	0
+#define AW_NR580_GPIO_LED_WLAN		1
+#define AW_NR580_GPIO_LED_READY_GREEN	2
+#define AW_NR580_GPIO_LED_WPS_GREEN	4
+#define AW_NR580_GPIO_LED_WPS_AMBER	5
+
+#define AW_NR580_GPIO_BTN_WPS		3
+#define AW_NR580_GPIO_BTN_RESET		11
+
+#define AW_NR580_BUTTONS_POLL_INTERVAL	20
+
+static struct spi_board_info aw_nr580_spi_info[] = {
+	{
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.max_speed_hz	= 25000000,
+		.modalias	= "m25p80",
+	}
+};
+
+static struct gpio_led aw_nr580_leds_gpio[] __initdata = {
+	{
+		.name		= "aw-nr580:red:ready",
+		.gpio		= AW_NR580_GPIO_LED_READY_RED,
+		.active_low	= 0,
+	}, {
+		.name		= "aw-nr580:green:ready",
+		.gpio		= AW_NR580_GPIO_LED_READY_GREEN,
+		.active_low	= 0,
+	}, {
+		.name		= "aw-nr580:green:wps",
+		.gpio		= AW_NR580_GPIO_LED_WPS_GREEN,
+		.active_low	= 0,
+	}, {
+		.name		= "aw-nr580:amber:wps",
+		.gpio		= AW_NR580_GPIO_LED_WPS_AMBER,
+		.active_low	= 0,
+	}, {
+		.name		= "aw-nr580:green:wlan",
+		.gpio		= AW_NR580_GPIO_LED_WLAN,
+		.active_low	= 0,
+	}
+};
+
+static struct gpio_button aw_nr580_gpio_buttons[] __initdata = {
+	{
+		.desc		= "reset",
+		.type		= EV_KEY,
+		.code		= BTN_0,
+		.threshold	= 5,
+		.gpio		= AW_NR580_GPIO_BTN_RESET,
+		.active_low	= 1,
+	}, {
+		.desc		= "wps",
+		.type		= EV_KEY,
+		.code		= BTN_1,
+		.threshold	= 5,
+		.gpio		= AW_NR580_GPIO_BTN_WPS,
+		.active_low	= 1,
+	}
+};
+
+static struct ar71xx_pci_irq aw_nr580_pci_irqs[] __initdata = {
+	{
+		.slot	= 1,
+		.pin	= 1,
+		.irq	= AR71XX_PCI_IRQ_DEV1,
+	}
+};
+
+static void __init aw_nr580_setup(void)
+{
+	ar71xx_add_device_mdio(0x0);
+
+	ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
+	ar71xx_eth0_data.phy_mask = 0xf;
+	ar71xx_eth0_data.speed = SPEED_100;
+	ar71xx_eth0_data.duplex = DUPLEX_FULL;
+
+	ar71xx_add_device_eth(0);
+
+	ar71xx_pci_init(ARRAY_SIZE(aw_nr580_pci_irqs), aw_nr580_pci_irqs);
+
+	ar71xx_add_device_spi(NULL, aw_nr580_spi_info,
+					ARRAY_SIZE(aw_nr580_spi_info));
+
+	ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(aw_nr580_leds_gpio),
+					aw_nr580_leds_gpio);
+
+	ar71xx_add_device_gpio_buttons(-1, AW_NR580_BUTTONS_POLL_INTERVAL,
+					ARRAY_SIZE(aw_nr580_gpio_buttons),
+					aw_nr580_gpio_buttons);
+}
+
+MIPS_MACHINE(AR71XX_MACH_AW_NR580, "AzureWave AW-NR580", aw_nr580_setup);
diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-generic.c linux-2.6.29.1/arch/mips/ar71xx/mach-generic.c
--- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-generic.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.29.1/arch/mips/ar71xx/mach-generic.c	2009-04-13 14:27:34.547067937 +0200
@@ -0,0 +1,22 @@
+/*
+ *  Generic AR71xx machine support
+ *
+ *  Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  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 <linux/init.h>
+
+#include <asm/mips_machine.h>
+#include <asm/mach-ar71xx/ar71xx.h>
+
+static void __init ar71xx_generic_init(void)
+{
+	/* Nothing to do */
+}
+
+MIPS_MACHINE(AR71XX_MACH_GENERIC, "Generic AR71xx board", ar71xx_generic_init);
diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-mzk-w04nu.c linux-2.6.29.1/arch/mips/ar71xx/mach-mzk-w04nu.c
--- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-mzk-w04nu.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.29.1/arch/mips/ar71xx/mach-mzk-w04nu.c	2009-04-13 14:27:34.551067888 +0200
@@ -0,0 +1,173 @@
+/*
+ *  Planex MZK-W04NU board support
+ *
+ *  Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
+ *
+ *  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 <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/input.h>
+
+#include <asm/mips_machine.h>
+
+#include <asm/mach-ar71xx/ar71xx.h>
+
+#include "devices.h"
+
+#define MZK_W04NU_GPIO_LED_USB		0
+#define MZK_W04NU_GPIO_LED_STATUS	1
+#define MZK_W04NU_GPIO_LED_WPS		3
+#define MZK_W04NU_GPIO_LED_WLAN		6
+#define MZK_W04NU_GPIO_LED_AP		15
+#define MZK_W04NU_GPIO_LED_ROUTER	16
+
+#define MZK_W04NU_GPIO_BTN_APROUTER	5
+#define MZK_W04NU_GPIO_BTN_WPS		12
+#define MZK_W04NU_GPIO_BTN_RESET	21
+
+#define MZK_W04NU_BUTTONS_POLL_INTERVAL	20
+
+#ifdef CONFIG_MTD_PARTITIONS
+static struct mtd_partition mzk_w04nu_partitions[] = {
+	{
+		.name		= "u-boot",
+		.offset		= 0,
+		.size		= 0x040000,
+		.mask_flags	= MTD_WRITEABLE,
+	} , {
+		.name		= "u-boot-env",
+		.offset		= 0x040000,
+		.size		= 0x010000,
+	} , {
+		.name		= "kernel",
+		.offset		= 0x050000,
+		.size		= 0x160000,
+	} , {
+		.name		= "rootfs",
+		.offset		= 0x1b0000,
+		.size		= 0x630000,
+	} , {
+		.name		= "art",
+		.offset		= 0x7e0000,
+		.size		= 0x020000,
+		.mask_flags	= MTD_WRITEABLE,
+	} , {
+		.name		= "firmware",
+		.offset		= 0x050000,
+		.size		= 0x770000,
+	}
+};
+#endif /* CONFIG_MTD_PARTITIONS */
+
+static struct flash_platform_data mzk_w04nu_flash_data = {
+#ifdef CONFIG_MTD_PARTITIONS
+        .parts          = mzk_w04nu_partitions,
+        .nr_parts       = ARRAY_SIZE(mzk_w04nu_partitions),
+#endif
+};
+
+static struct spi_board_info mzk_w04nu_spi_info[] = {
+	{
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.max_speed_hz	= 25000000,
+		.modalias	= "m25p80",
+		.platform_data  = &mzk_w04nu_flash_data,
+	}
+};
+
+static struct gpio_led mzk_w04nu_leds_gpio[] __initdata = {
+	{
+		.name		= "mzk-w04nu:green:status",
+		.gpio		= MZK_W04NU_GPIO_LED_STATUS,
+		.active_low	= 1,
+	}, {
+		.name		= "mzk-w04nu:blue:wps",
+		.gpio		= MZK_W04NU_GPIO_LED_WPS,
+		.active_low	= 1,
+	}, {
+		.name		= "mzk-w04nu:green:wlan",
+		.gpio		= MZK_W04NU_GPIO_LED_WLAN,
+		.active_low	= 1,
+	}, {
+		.name		= "mzk-w04nu:green:usb",
+		.gpio		= MZK_W04NU_GPIO_LED_USB,
+		.active_low	= 1,
+	}, {
+		.name		= "mzk-w04nu:green:ap",
+		.gpio		= MZK_W04NU_GPIO_LED_AP,
+		.active_low	= 1,
+	}, {
+		.name		= "mzk-w04nu:green:router",
+		.gpio		= MZK_W04NU_GPIO_LED_ROUTER,
+		.active_low	= 1,
+	}
+};
+
+static struct gpio_button mzk_w04nu_gpio_buttons[] __initdata = {
+	{
+		.desc		= "reset",
+		.type		= EV_KEY,
+		.code		= BTN_0,
+		.threshold	= 5,
+		.gpio		= MZK_W04NU_GPIO_BTN_RESET,
+		.active_low	= 1,
+	}, {
+		.desc		= "wps",
+		.type		= EV_KEY,
+		.code		= BTN_1,
+		.threshold	= 5,
+		.gpio		= MZK_W04NU_GPIO_BTN_WPS,
+		.active_low	= 1,
+	}, {
+		.desc		= "aprouter",
+		.type		= EV_KEY,
+		.code		= BTN_2,
+		.threshold	= 5,
+		.gpio		= MZK_W04NU_GPIO_BTN_APROUTER,
+		.active_low	= 0,
+	}
+};
+
+static void __init mzk_w04nu_setup(void)
+{
+	u8 *mac = (u8 *) KSEG1ADDR(0x1fff1000);
+
+	ar71xx_set_mac_base(mac);
+
+	ar71xx_add_device_mdio(0x0);
+
+	ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
+	ar71xx_eth0_data.phy_mask = 0xf;
+	ar71xx_eth0_data.speed = SPEED_100;
+	ar71xx_eth0_data.duplex = DUPLEX_FULL;
+	ar71xx_eth0_data.has_ar8216 = 1;
+
+	ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
+	ar71xx_eth1_data.phy_mask = 0x10;
+
+	ar71xx_add_device_eth(0);
+	ar71xx_add_device_eth(1);
+
+	ar71xx_add_device_spi(NULL, mzk_w04nu_spi_info,
+					ARRAY_SIZE(mzk_w04nu_spi_info));
+
+	ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(mzk_w04nu_leds_gpio),
+					mzk_w04nu_leds_gpio);
+
+	ar71xx_add_device_gpio_buttons(-1, MZK_W04NU_BUTTONS_POLL_INTERVAL,
+					ARRAY_SIZE(mzk_w04nu_gpio_buttons),
+					mzk_w04nu_gpio_buttons);
+	ar71xx_add_device_usb();
+
+	ar91xx_add_device_wmac();
+}
+
+MIPS_MACHINE(AR71XX_MACH_MZK_W04NU, "Planex MZK-W04NU", mzk_w04nu_setup);
diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-mzk-w300nh.c linux-2.6.29.1/arch/mips/ar71xx/mach-mzk-w300nh.c
--- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-mzk-w300nh.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.29.1/arch/mips/ar71xx/mach-mzk-w300nh.c	2009-04-13 14:27:34.551067888 +0200
@@ -0,0 +1,81 @@
+/*
+ *  Planex MZK-W300NH board support
+ *
+ *  Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  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 <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <asm/mips_machine.h>
+
+#include <asm/mach-ar71xx/ar71xx.h>
+
+#include "devices.h"
+
+#ifdef CONFIG_MTD_PARTITIONS
+static struct mtd_partition mzk_w300nh_partitions[] = {
+	{
+		.name		= "u-boot",
+		.offset		= 0,
+		.size		= 0x040000,
+		.mask_flags	= MTD_WRITEABLE,
+	} , {
+		.name		= "u-boot-env",
+		.offset		= 0x040000,
+		.size		= 0x010000,
+	} , {
+		.name		= "uImage",
+		.offset		= 0x050000,
+		.size		= 0x160000,
+	} , {
+		.name		= "rootfs",
+		.offset		= 0x1b0000,
+		.size		= 0x610000,
+	} , {
+		.name		= "config",
+		.offset		= 0x7c0000,
+		.size		= 0x020000,
+	} , {
+		.name		= "art",
+		.offset		= 0x7e0000,
+		.size		= 0x020000,
+		.mask_flags	= MTD_WRITEABLE,
+	}
+};
+#endif /* CONFIG_MTD_PARTITIONS */
+
+static struct flash_platform_data mzk_w300nh_flash_data = {
+#ifdef CONFIG_MTD_PARTITIONS
+        .parts          = mzk_w300nh_partitions,
+        .nr_parts       = ARRAY_SIZE(mzk_w300nh_partitions),
+#endif
+};
+
+static struct spi_board_info mzk_w300nh_spi_info[] = {
+	{
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.max_speed_hz	= 25000000,
+		.modalias	= "m25p80",
+		.platform_data  = &mzk_w300nh_flash_data,
+	}
+};
+
+static void __init mzk_w300nh_setup(void)
+{
+	ar71xx_add_device_spi(NULL, mzk_w300nh_spi_info,
+					ARRAY_SIZE(mzk_w300nh_spi_info));
+
+	ar91xx_add_device_wmac();
+}
+
+MIPS_MACHINE(AR71XX_MACH_MZK_W300NH, "Planex MZK-W300NH", mzk_w300nh_setup);
diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-pb42.c linux-2.6.29.1/arch/mips/ar71xx/mach-pb42.c
--- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-pb42.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.29.1/arch/mips/ar71xx/mach-pb42.c	2009-04-13 14:27:34.555068677 +0200
@@ -0,0 +1,102 @@
+/*
+ *  Atheros PB42 board support
+ *
+ *  Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  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 <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <asm/mips_machine.h>
+#include <asm/mach-ar71xx/ar71xx.h>
+#include <asm/mach-ar71xx/pci.h>
+
+#include "devices.h"
+
+#define PB42_BUTTONS_POLL_INTERVAL	20
+
+#define PB42_GPIO_BTN_SW4	8
+#define PB42_GPIO_BTN_SW5	3
+
+static struct spi_board_info pb42_spi_info[] = {
+	{
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.max_speed_hz	= 25000000,
+		.modalias	= "m25p80",
+	}
+};
+
+static struct ar71xx_pci_irq pb42_pci_irqs[] __initdata = {
+	{
+		.slot	= 0,
+		.pin	= 1,
+		.irq	= AR71XX_PCI_IRQ_DEV0,
+	}, {
+		.slot	= 1,
+		.pin	= 1,
+		.irq	= AR71XX_PCI_IRQ_DEV1,
+	}, {
+		.slot	= 2,
+		.pin	= 1,
+		.irq	= AR71XX_PCI_IRQ_DEV2,
+	}
+};
+
+static struct gpio_button pb42_gpio_buttons[] __initdata = {
+	{
+		.desc		= "sw4",
+		.type		= EV_KEY,
+		.code		= BTN_0,
+		.threshold	= 5,
+		.gpio		= PB42_GPIO_BTN_SW4,
+		.active_low	= 1,
+	} , {
+		.desc		= "sw5",
+		.type		= EV_KEY,
+		.code		= BTN_1,
+		.threshold	= 5,
+		.gpio		= PB42_GPIO_BTN_SW5,
+		.active_low	= 1,
+	}
+};
+
+#define PB42_WAN_PHYMASK	BIT(20)
+#define PB42_LAN_PHYMASK	(BIT(16) | BIT(17) | BIT(18) | BIT(19))
+#define PB42_MDIO_PHYMASK	(PB42_LAN_PHYMASK | PB42_WAN_PHYMASK)
+
+static void __init pb42_init(void)
+{
+	ar71xx_add_device_spi(NULL, pb42_spi_info,
+				ARRAY_SIZE(pb42_spi_info));
+
+	ar71xx_add_device_mdio(~PB42_MDIO_PHYMASK);
+
+	ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
+	ar71xx_eth0_data.phy_mask = PB42_WAN_PHYMASK;
+
+	ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
+	ar71xx_eth1_data.phy_mask = PB42_LAN_PHYMASK;
+	ar71xx_eth1_data.speed = SPEED_100;
+	ar71xx_eth1_data.duplex = DUPLEX_FULL;
+
+	ar71xx_add_device_eth(0);
+	ar71xx_add_device_eth(1);
+
+	ar71xx_add_device_gpio_buttons(-1, PB42_BUTTONS_POLL_INTERVAL,
+				       ARRAY_SIZE(pb42_gpio_buttons),
+				       pb42_gpio_buttons);
+
+	ar71xx_pci_init(ARRAY_SIZE(pb42_pci_irqs), pb42_pci_irqs);
+}
+
+MIPS_MACHINE(AR71XX_MACH_PB42, "Atheros PB42", pb42_init);
diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-rb-4xx.c linux-2.6.29.1/arch/mips/ar71xx/mach-rb-4xx.c
--- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-rb-4xx.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.29.1/arch/mips/ar71xx/mach-rb-4xx.c	2009-04-13 14:27:34.555068677 +0200
@@ -0,0 +1,251 @@
+/*
+ *  MikroTik RouterBOARD 4xx series support
+ *
+ *  Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  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 <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/mmc/host.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/mmc_spi.h>
+#include <linux/input.h>
+
+#include <asm/mips_machine.h>
+#include <asm/mach-ar71xx/ar71xx.h>
+#include <asm/mach-ar71xx/pci.h>
+
+#include "devices.h"
+
+#define RB4XX_GPIO_USER_LED	4
+#define RB4XX_GPIO_RESET_SWITCH	7
+
+#define RB4XX_BUTTONS_POLL_INTERVAL	20
+
+static struct gpio_led rb4xx_leds_gpio[] __initdata = {
+	{
+		.name		= "rb4xx:yellow:user",
+		.gpio		= RB4XX_GPIO_USER_LED,
+		.active_low	= 0,
+	},
+};
+
+static struct gpio_button rb4xx_gpio_buttons[] __initdata = {
+	{
+		.desc		= "reset_switch",
+		.type		= EV_KEY,
+		.code		= BTN_0,
+		.threshold	= 5,
+		.gpio		= RB4XX_GPIO_RESET_SWITCH,
+		.active_low	= 1,
+	}
+};
+
+static struct platform_device rb4xx_nand_device = {
+	.name	= "rb4xx-nand",
+	.id	= -1,
+};
+
+static struct ar71xx_pci_irq rb4xx_pci_irqs[] __initdata = {
+	{
+		.slot	= 1,
+		.pin	= 1,
+		.irq	= AR71XX_PCI_IRQ_DEV0,
+	}, {
+		.slot	= 1,
+		.pin	= 2,
+		.irq	= AR71XX_PCI_IRQ_DEV1,
+	}, {
+		.slot	= 2,
+		.pin	= 1,
+		.irq	= AR71XX_PCI_IRQ_DEV1,
+	}, {
+		.slot	= 3,
+		.pin	= 1,
+		.irq	= AR71XX_PCI_IRQ_DEV2,
+	}
+};
+
+#if 0
+/*
+ * SPI device support is experimental
+ */
+static struct flash_platform_data rb4xx_flash_data = {
+	.type	= "pm25lv512",
+};
+
+static struct spi_board_info rb4xx_spi_info[] = {
+	{
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.max_speed_hz	= 25000000,
+		.modalias	= "m25p80",
+		.platform_data	= &rb4xx_flash_data,
+	}
+};
+
+static struct mmc_spi_platform_data rb433_mmc_data = {
+	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
+};
+
+static struct spi_board_info rb433_spi_info[] = {
+	{
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.max_speed_hz	= 25000000,
+		.modalias	= "m25p80",
+		.platform_data	= &rb433_flash_data,
+	}, {
+		.bus_num	= 0,
+		.chip_select	= 2,
+		.max_speed_hz	= 25000000,
+		.modalias	= "mmc_spi",
+		.platform_data	= &rb433_mmc_data,
+	}
+};
+
+static u32 rb433_spi_get_ioc_base(u8 chip_select, int cs_high, int is_on)
+{
+	u32 ret;
+
+	if (is_on == AR71XX_SPI_CS_INACTIVE) {
+		ret = SPI_IOC_CS0 | SPI_IOC_CS1;
+	} else {
+		if (cs_high) {
+			ret = SPI_IOC_CS0 | SPI_IOC_CS1;
+		} else {
+			if ((chip_select ^ 2) == 0)
+				ret = SPI_IOC_CS1 ^ (SPI_IOC_CS0 | SPI_IOC_CS1);
+			else
+				ret = SPI_IOC_CS0 ^ (SPI_IOC_CS0 | SPI_IOC_CS1);
+		}
+	}
+
+	return ret;
+}
+
+struct ar71xx_spi_platform_data rb433_spi_data = {
+	.bus_num		= 0,
+	.num_chipselect		= 3,
+	.get_ioc_base		= rb433_spi_get_ioc_base,
+};
+
+static void rb4xx_add_device_spi(void)
+{
+	ar71xx_add_device_spi(NULL, rb4xx_spi_info, ARRAY_SIZE(rb4xx_spi_info));
+}
+
+static void rb433_add_device_spi(void)
+{
+	ar71xx_add_device_spi(&rb433_spi_data, rb433_spi_info,
+				ARRAY_SIZE(rb433_spi_info));
+}
+#else
+static inline void rb4xx_add_device_spi(void) {}
+static inline void rb433_add_device_spi(void) {}
+#endif
+
+static void __init rb4xx_generic_setup(void)
+{
+	ar71xx_gpio_function_enable(GPIO_FUNC_SPI_CS1_EN |
+				    GPIO_FUNC_SPI_CS2_EN);
+
+	ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(rb4xx_leds_gpio),
+					rb4xx_leds_gpio);
+
+	ar71xx_add_device_gpio_buttons(-1, RB4XX_BUTTONS_POLL_INTERVAL,
+					ARRAY_SIZE(rb4xx_gpio_buttons),
+					rb4xx_gpio_buttons);
+
+	platform_device_register(&rb4xx_nand_device);
+}
+
+static void __init rb411_setup(void)
+{
+	rb4xx_generic_setup();
+	rb4xx_add_device_spi();
+
+	ar71xx_add_device_mdio(0xfffffffe);
+
+	ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
+	ar71xx_eth0_data.phy_mask = 0x00000001;
+
+	ar71xx_add_device_eth(0);
+
+	ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs);
+}
+
+MIPS_MACHINE(AR71XX_MACH_RB_411, "MikroTik RouterBOARD 411/A/AH", rb411_setup);
+
+static void __init rb433_setup(void)
+{
+	rb4xx_generic_setup();
+	rb433_add_device_spi();
+
+	ar71xx_add_device_mdio(0xffffffe9);
+
+	ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
+	ar71xx_eth0_data.phy_mask = 0x00000006;
+	ar71xx_eth0_data.speed = SPEED_100;
+	ar71xx_eth0_data.duplex = DUPLEX_FULL;
+
+	ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
+	ar71xx_eth1_data.phy_mask = 0x00000010;
+
+	ar71xx_add_device_eth(1);
+	ar71xx_add_device_eth(0);
+
+	ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs);
+}
+
+MIPS_MACHINE(AR71XX_MACH_RB_433, "MikroTik RouterBOARD 433/AH", rb433_setup);
+
+static void __init rb450_setup(void)
+{
+	rb4xx_generic_setup();
+	rb4xx_add_device_spi();
+
+	ar71xx_add_device_mdio(0xffffffe0);
+
+	ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
+	ar71xx_eth0_data.phy_mask = 0x0000000f;
+	ar71xx_eth0_data.speed = SPEED_100;
+	ar71xx_eth0_data.duplex = DUPLEX_FULL;
+
+	ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
+	ar71xx_eth1_data.phy_mask = 0x00000010;
+
+	ar71xx_add_device_eth(1);
+	ar71xx_add_device_eth(0);
+}
+
+MIPS_MACHINE(AR71XX_MACH_RB_450, "MikroTik RouterBOARD 450", rb450_setup);
+
+static void __init rb493_setup(void)
+{
+	rb4xx_generic_setup();
+	rb4xx_add_device_spi();
+
+	ar71xx_add_device_mdio(0x3fffff00);
+
+	ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
+	ar71xx_eth0_data.phy_mask = 0;
+	ar71xx_eth0_data.speed = SPEED_100;
+	ar71xx_eth0_data.duplex = DUPLEX_FULL;
+
+	ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
+	ar71xx_eth1_data.phy_mask = 0x00000001;
+
+	ar71xx_add_device_eth(0);
+	ar71xx_add_device_eth(1);
+
+	ar71xx_pci_init(ARRAY_SIZE(rb4xx_pci_irqs), rb4xx_pci_irqs);
+}
+
+MIPS_MACHINE(AR71XX_MACH_RB_493, "MikroTik RouterBOARD 493/AH", rb493_setup);
diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-tew-632brp.c linux-2.6.29.1/arch/mips/ar71xx/mach-tew-632brp.c
--- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-tew-632brp.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.29.1/arch/mips/ar71xx/mach-tew-632brp.c	2009-04-13 14:27:34.559070024 +0200
@@ -0,0 +1,142 @@
+/*
+ *  TrendNET TEW-632BRP board support
+ *
+ *  Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ *  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 <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/input.h>
+
+#include <asm/mips_machine.h>
+
+#include <asm/mach-ar71xx/ar71xx.h>
+
+#include "devices.h"
+
+#define TEW_632BRP_GPIO_LED_STATUS	1
+#define TEW_632BRP_GPIO_LED_WPS		3
+#define TEW_632BRP_GPIO_LED_WLAN	6
+#define TEW_632BRP_GPIO_BTN_WPS		12
+#define TEW_632BRP_GPIO_BTN_RESET	21
+
+#define TEW_632BRP_BUTTONS_POLL_INTERVAL	20
+
+#ifdef CONFIG_MTD_PARTITIONS
+static struct mtd_partition tew_632brp_partitions[] = {
+	{
+		.name		= "u-boot",
+		.offset		= 0,
+		.size		= 0x020000,
+		.mask_flags	= MTD_WRITEABLE,
+	} , {
+		.name		= "config",
+		.offset		= 0x020000,
+		.size		= 0x010000,
+	} , {
+		.name		= "kernel",
+		.offset		= 0x030000,
+		.size		= 0x0c0000,
+	} , {
+		.name		= "rootfs",
+		.offset		= 0x0f0000,
+		.size		= 0x300000,
+	} , {
+		.name		= "art",
+		.offset		= 0x3f0000,
+		.size		= 0x010000,
+		.mask_flags	= MTD_WRITEABLE,
+	} , {
+		.name		= "firmw