diff -Nur linux-2.6.36.orig/arch/mips/Kconfig linux-2.6.36/arch/mips/Kconfig
--- linux-2.6.36.orig/arch/mips/Kconfig	2010-10-20 22:30:22.000000000 +0200
+++ linux-2.6.36/arch/mips/Kconfig	2010-11-18 21:16:05.000000000 +0100
@@ -60,6 +60,23 @@
 	  Support for the Texas Instruments AR7 System-on-a-Chip
 	  family: TNETD7100, 7200 and 7300.
 
+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 BCM47XX
 	bool "Broadcom BCM47XX based boards"
 	select CEVT_R4K
@@ -709,6 +726,7 @@
 endchoice
 
 source "arch/mips/alchemy/Kconfig"
+source "arch/mips/ar71xx/Kconfig"
 source "arch/mips/bcm63xx/Kconfig"
 source "arch/mips/jazz/Kconfig"
 source "arch/mips/jz4740/Kconfig"
@@ -872,9 +890,15 @@
 config MIPS_DISABLE_OBSOLETE_IDE
 	bool
 
+config MYLOADER
+	bool
+
 config SYNC_R4K
 	bool
 
+config MIPS_MACHINE
+	def_bool n
+
 config NO_IOPORT
 	def_bool n
 
diff -Nur linux-2.6.36.orig/arch/mips/Makefile linux-2.6.36/arch/mips/Makefile
--- linux-2.6.36.orig/arch/mips/Makefile	2010-10-20 22:30:22.000000000 +0200
+++ linux-2.6.36/arch/mips/Makefile	2010-11-18 21:16:07.000000000 +0100
@@ -160,6 +160,13 @@
 cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -Wa,-march=octeon
 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-$(CONFIG_CPU_R4000_WORKAROUNDS)	+= $(call cc-option,-mfix-r4000,)
 cflags-$(CONFIG_CPU_R4400_WORKAROUNDS)	+= $(call cc-option,-mfix-r4400,)
 cflags-$(CONFIG_CPU_DADDI_WORKAROUNDS)	+= $(call cc-option,-mno-daddi,)
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/Kconfig linux-2.6.36/arch/mips/ar71xx/Kconfig
--- linux-2.6.36.orig/arch/mips/ar71xx/Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/Kconfig	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,264 @@
+if ATHEROS_AR71XX
+
+menu "Atheros AR71xx machine selection"
+
+config AR71XX_MACH_AP81
+	bool "Atheros AP81 board support"
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_AR913X_WMAC
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	select AR71XX_DEV_USB
+	default n
+
+config AR71XX_MACH_AP83
+	bool "Atheros AP83 board support"
+	select AR71XX_DEV_AR913X_WMAC
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	select AR71XX_DEV_USB
+	default n
+
+config AR71XX_MACH_DIR_600_A1
+	bool "D-Link DIR-600 rev. A1 support"
+	select AR71XX_DEV_AP91_ETH
+	select AR71XX_DEV_AP91_PCI if PCI
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	select AR71XX_NVRAM
+	default n
+
+config AR71XX_MACH_DIR_615_C1
+	bool "D-Link DIR-615 rev. C1 support"
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_AR913X_WMAC
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	select AR71XX_NVRAM
+	default n
+
+config AR71XX_MACH_DIR_825_B1
+	bool "D-Link DIR-825 rev. B1 board support"
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_AP94_PCI if PCI
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	select AR71XX_DEV_USB
+	default n
+
+config AR71XX_MACH_PB42
+	bool "Atheros PB42 board support"
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_PB42_PCI if PCI
+	default n
+
+config AR71XX_MACH_PB44
+	bool "Atheros PB44 board support"
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_PB42_PCI if PCI
+	select AR71XX_DEV_LEDS_GPIO
+	select AR71XX_DEV_USB
+	default n
+
+config AR71XX_MACH_PB92
+	bool "Atheros PB92 board support"
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_PB9X_PCI if PCI
+	select AR71XX_DEV_LEDS_GPIO
+	select AR71XX_DEV_USB
+	default n
+
+config AR71XX_MACH_AW_NR580
+	bool "AzureWave AW-NR580 board support"
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_PB42_PCI if PCI
+	select AR71XX_DEV_LEDS_GPIO
+	default n
+
+config AR71XX_MACH_WZR_HP_G300NH
+	bool "Buffalo WZR-HP-G300NH board support"
+	select AR71XX_DEV_AR913X_WMAC
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	select AR71XX_DEV_USB
+	default y
+
+config AR71XX_MACH_WP543
+	bool "Compex WP543/WPJ543 board support"
+	select MYLOADER
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_PB42_PCI if PCI
+	select AR71XX_DEV_LEDS_GPIO
+	select AR71XX_DEV_USB
+	default n
+
+config AR71XX_MACH_WRT160NL
+	bool "Linksys WRT160NL board support"
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_AR913X_WMAC
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	select AR71XX_DEV_USB
+	select AR71XX_NVRAM
+	default n
+
+config AR71XX_MACH_WRT400N
+	bool "Linksys WRT400N board support"
+	select AR71XX_DEV_AP94_PCI if PCI
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	default n
+
+config AR71XX_MACH_RB4XX
+	bool "MikroTik RouterBOARD 4xx series support"
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	select AR71XX_DEV_USB
+	default n
+
+config AR71XX_MACH_RB750
+	bool "MikroTik RouterBOARD 750 support"
+	select AR71XX_DEV_AP91_ETH
+	default n
+
+config AR71XX_MACH_WNDR3700
+	bool "NETGEAR WNDR3700 board support"
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_AP94_PCI if PCI
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	select AR71XX_DEV_USB
+	default n
+
+config AR71XX_MACH_WNR2000
+	bool "NETGEAR WNR2000 board support"
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_AR913X_WMAC
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	default n
+
+config AR71XX_MACH_MZK_W04NU
+	bool "Planex MZK-W04NU board support"
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_AR913X_WMAC
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	select AR71XX_DEV_USB
+	default n
+
+config AR71XX_MACH_MZK_W300NH
+	bool "Planex MZK-W300NH board support"
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_AR913X_WMAC
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	default n
+
+config AR71XX_MACH_NBG460N
+	bool "Zyxel NBG460N/550N/550NH board support"
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_AR913X_WMAC
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	default n
+	
+config AR71XX_MACH_TL_WR741ND
+	bool "TP-LINK TL-WR741ND support"
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_AP91_ETH
+	select AR71XX_DEV_AP91_PCI if PCI
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	default n
+
+config AR71XX_MACH_TL_WR841N_V1
+	bool "TP-LINK TL-WR841N v1 support"
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_PB42_PCI if PCI
+	select AR71XX_DEV_DSA
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	default n
+
+config AR71XX_MACH_TL_WR941ND
+	bool "TP-LINK TL-WR941ND support"
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_AR913X_WMAC
+	select AR71XX_DEV_DSA
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	default n
+
+config AR71XX_MACH_TL_WR1043ND
+	bool "TP-LINK TL-WR1043ND support"
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_AR913X_WMAC
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	select AR71XX_DEV_USB
+	default n
+
+config AR71XX_MACH_TEW_632BRP
+	bool "TRENDnet TEW-632BRP support"
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_AR913X_WMAC
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	select AR71XX_NVRAM
+	default n
+
+config AR71XX_MACH_UBNT
+	bool "Ubiquiti AR71xx based boards support"
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_AP91_PCI if PCI
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	select AR71XX_DEV_PB42_PCI if PCI
+	select AR71XX_DEV_USB
+	default n
+
+endmenu
+
+config AR71XX_DEV_M25P80
+	def_bool n
+
+config AR71XX_DEV_AP91_PCI
+	def_bool n
+
+config AR71XX_DEV_AP91_ETH
+	def_bool n
+
+config AR71XX_DEV_AP94_PCI
+	def_bool n
+
+config AR71XX_DEV_AR913X_WMAC
+	def_bool n
+
+config AR71XX_DEV_DSA
+	def_bool n
+
+config AR71XX_DEV_GPIO_BUTTONS
+	def_bool n
+
+config AR71XX_DEV_LEDS_GPIO
+	def_bool n
+
+config AR71XX_DEV_PB42_PCI
+	def_bool n
+
+config AR71XX_DEV_PB9X_PCI
+	def_bool n
+
+config AR71XX_DEV_USB
+	def_bool n
+
+config AR71XX_NVRAM
+	def_bool n
+
+endif
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/Makefile linux-2.6.36/arch/mips/ar71xx/Makefile
--- linux-2.6.36.orig/arch/mips/ar71xx/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/Makefile	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,54 @@
+#
+# 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_EARLY_PRINTK)		+= early_printk.o
+obj-$(CONFIG_PCI)			+= pci.o
+
+obj-$(CONFIG_AR71XX_DEV_AP91_ETH)	+= dev-ap91-eth.o
+obj-$(CONFIG_AR71XX_DEV_AP91_PCI)	+= dev-ap91-pci.o
+obj-$(CONFIG_AR71XX_DEV_AP94_PCI)	+= dev-ap94-pci.o
+obj-$(CONFIG_AR71XX_DEV_AR913X_WMAC)	+= dev-ar913x-wmac.o
+obj-$(CONFIG_AR71XX_DEV_DSA)		+= dev-dsa.o
+obj-$(CONFIG_AR71XX_DEV_GPIO_BUTTONS)	+= dev-gpio-buttons.o
+obj-$(CONFIG_AR71XX_DEV_LEDS_GPIO)	+= dev-leds-gpio.o
+obj-$(CONFIG_AR71XX_DEV_M25P80)		+= dev-m25p80.o
+obj-$(CONFIG_AR71XX_DEV_PB42_PCI)	+= dev-pb42-pci.o
+obj-$(CONFIG_AR71XX_DEV_PB9X_PCI)	+= dev-pb9x-pci.o
+obj-$(CONFIG_AR71XX_DEV_USB)		+= dev-usb.o
+
+obj-$(CONFIG_AR71XX_NVRAM)		+= nvram.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_DIR_600_A1)	+= mach-dir-600-a1.o
+obj-$(CONFIG_AR71XX_MACH_DIR_615_C1)	+= mach-dir-615-c1.o
+obj-$(CONFIG_AR71XX_MACH_DIR_825_B1)	+= mach-dir-825-b1.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_NBG460N)	+= mach-nbg460n.o
+obj-$(CONFIG_AR71XX_MACH_PB42)		+= mach-pb42.o
+obj-$(CONFIG_AR71XX_MACH_PB44)		+= mach-pb44.o
+obj-$(CONFIG_AR71XX_MACH_PB92)		+= mach-pb92.o
+obj-$(CONFIG_AR71XX_MACH_RB4XX)		+= mach-rb4xx.o
+obj-$(CONFIG_AR71XX_MACH_RB750)		+= mach-rb750.o
+obj-$(CONFIG_AR71XX_MACH_TEW_632BRP)	+= mach-tew-632brp.o
+obj-$(CONFIG_AR71XX_MACH_TL_WR741ND)	+= mach-tl-wr741nd.o
+obj-$(CONFIG_AR71XX_MACH_TL_WR841N_V1)	+= mach-tl-wr841n.o
+obj-$(CONFIG_AR71XX_MACH_TL_WR941ND)	+= mach-tl-wr941nd.o
+obj-$(CONFIG_AR71XX_MACH_TL_WR1043ND)	+= mach-tl-wr1043nd.o
+obj-$(CONFIG_AR71XX_MACH_UBNT)		+= mach-ubnt.o
+obj-$(CONFIG_AR71XX_MACH_WNDR3700)	+= mach-wndr3700.o
+obj-$(CONFIG_AR71XX_MACH_WNR2000)	+= mach-wnr2000.o
+obj-$(CONFIG_AR71XX_MACH_WP543)		+= mach-wp543.o
+obj-$(CONFIG_AR71XX_MACH_WRT160NL)	+= mach-wrt160nl.o
+obj-$(CONFIG_AR71XX_MACH_WRT400N)	+= mach-wrt400n.o
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/ar71xx.c linux-2.6.36/arch/mips/ar71xx/ar71xx.c
--- linux-2.6.36.orig/arch/mips/ar71xx/ar71xx.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/ar71xx.c	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,177 @@
+/*
+ *  AR71xx SoC routines
+ *
+ *  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/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/mutex.h>
+
+#include <asm/mach-ar71xx/ar71xx.h>
+
+static DEFINE_MUTEX(ar71xx_flash_mutex);
+
+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 mask_inv;
+	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_AR7240:
+	case AR71XX_SOC_AR7241:
+	case AR71XX_SOC_AR7242:
+		mask_inv = mask & RESET_MODULE_USB_OHCI_DLL_7240;
+		local_irq_save(flags);
+		t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
+		t |= mask;
+		t &= ~mask_inv;
+		ar71xx_reset_wr(AR724X_RESET_REG_RESET_MODULE, t);
+		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 mask_inv;
+	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_AR7240:
+	case AR71XX_SOC_AR7241:
+	case AR71XX_SOC_AR7242:
+		mask_inv = mask & RESET_MODULE_USB_OHCI_DLL_7240;
+		local_irq_save(flags);
+		t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
+		t &= ~mask;
+		t |= mask_inv;
+		ar71xx_reset_wr(AR724X_RESET_REG_RESET_MODULE, t);
+		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);
+
+int ar71xx_device_stopped(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);
+		local_irq_restore(flags);
+		break;
+
+	case AR71XX_SOC_AR7240:
+	case AR71XX_SOC_AR7241:
+	case AR71XX_SOC_AR7242:
+		local_irq_save(flags);
+		t = ar71xx_reset_rr(AR724X_RESET_REG_RESET_MODULE);
+		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);
+		local_irq_restore(flags);
+		break;
+
+	default:
+		BUG();
+	}
+
+	return ((t & mask) == mask);
+}
+EXPORT_SYMBOL_GPL(ar71xx_device_stopped);
+
+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);
+
+void ar71xx_flash_acquire(void)
+{
+	mutex_lock(&ar71xx_flash_mutex);
+}
+EXPORT_SYMBOL_GPL(ar71xx_flash_acquire);
+
+void ar71xx_flash_release(void)
+{
+	mutex_unlock(&ar71xx_flash_mutex);
+}
+EXPORT_SYMBOL_GPL(ar71xx_flash_release);
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-ap91-eth.c linux-2.6.36/arch/mips/ar71xx/dev-ap91-eth.c
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-ap91-eth.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-ap91-eth.c	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,70 @@
+/*
+ *  Atheros AP91 reference board ethernet initialization
+ *
+ *  Copyright (C) 2010 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 "devices.h"
+#include "dev-dsa.h"
+#include "dev-ap91-eth.h"
+
+static struct dsa_chip_data ap91_dsa_chip = {
+	.port_names[0]  = "cpu",
+	.port_names[1]  = "lan1",
+	.port_names[2]  = "lan2",
+	.port_names[3]  = "lan3",
+	.port_names[4]  = "lan4",
+};
+
+static struct dsa_platform_data ap91_dsa_data = {
+	.nr_chips	= 1,
+	.chip		= &ap91_dsa_chip,
+};
+
+static void ap91_eth_set_port_name(unsigned port, const char *name)
+{
+	if (port < 1 || port > 5)
+		return;
+
+	if (name)
+		ap91_dsa_chip.port_names[port] = (char *) name;
+}
+
+void __init ap91_eth_init(u8 *mac_addr, const char *port_names[])
+{
+	if (mac_addr)
+		ar71xx_set_mac_base(mac_addr);
+
+	if (port_names) {
+		int i;
+
+		for (i = 0; i < AP91_ETH_NUM_PORT_NAMES; i++)
+			ap91_eth_set_port_name(i + 1, port_names[i]);
+	}
+
+	/* WAN port */
+	ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
+	ar71xx_eth0_data.speed = SPEED_100;
+	ar71xx_eth0_data.duplex = DUPLEX_FULL;
+	ar71xx_eth0_data.fifo_cfg1 = 0x0fff0000;
+	ar71xx_eth0_data.fifo_cfg2 = 0x00001fff;
+	ar71xx_eth0_data.fifo_cfg3 = 0x008001ff;
+
+	/* LAN ports */
+	ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
+	ar71xx_eth1_data.speed = SPEED_1000;
+	ar71xx_eth1_data.duplex = DUPLEX_FULL;
+	ar71xx_eth1_data.fifo_cfg1 = 0x0fff0000;
+	ar71xx_eth1_data.fifo_cfg2 = 0x00001fff;
+	ar71xx_eth1_data.fifo_cfg3 = 0x008001ff;
+
+	ar71xx_add_device_mdio(0x0);
+	ar71xx_add_device_eth(1);
+	ar71xx_add_device_eth(0);
+
+	ar71xx_add_device_dsa(1, &ap91_dsa_data);
+}
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-ap91-eth.h linux-2.6.36/arch/mips/ar71xx/dev-ap91-eth.h
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-ap91-eth.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-ap91-eth.h	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,23 @@
+/*
+ *  Atheros AP91 reference board ethernet initialization
+ *
+ *  Copyright (C) 2010 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.
+ */
+
+#ifndef _AR71XX_DEV_AP91_ETH_H
+#define _AR71XX_DEV_AP91_ETH_H
+
+#define AP91_ETH_NUM_PORT_NAMES	4
+
+#if defined(CONFIG_AR71XX_DEV_AP91_ETH)
+void ap91_eth_init(u8 *mac_addr, const char *port_names[]) __init;
+#else
+static inline void ap91_eth_init(u8 *mac_addr) { }
+#endif
+
+#endif /* _AR71XX_DEV_AP91_ETH_H */
+
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-ap91-pci.c linux-2.6.36/arch/mips/ar71xx/dev-ap91-pci.c
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-ap91-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-ap91-pci.c	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,114 @@
+/*
+ *  Atheros AP91 reference board PCI initialization
+ *
+ *  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/pci.h>
+#include <linux/ath9k_platform.h>
+#include <linux/delay.h>
+
+#include <asm/mach-ar71xx/ar71xx.h>
+#include <asm/mach-ar71xx/pci.h>
+
+#include "dev-ap91-pci.h"
+
+static struct ath9k_platform_data ap91_wmac_data;
+static char ap91_wmac_mac[6];
+static int ap91_pci_fixup_enabled;
+
+static struct ar71xx_pci_irq ap91_pci_irqs[] __initdata = {
+	{
+		.slot	= 0,
+		.pin	= 1,
+		.irq	= AR71XX_PCI_IRQ_DEV0,
+	}
+};
+
+static int ap91_pci_plat_dev_init(struct pci_dev *dev)
+{
+	switch(PCI_SLOT(dev->devfn)) {
+	case 0:
+		dev->dev.platform_data = &ap91_wmac_data;
+		break;
+	}
+
+	return 0;
+}
+
+static void ap91_pci_fixup(struct pci_dev *dev)
+{
+	void __iomem *mem;
+	u16 *cal_data;
+	u16 cmd;
+	u32 val;
+
+	if (!ap91_pci_fixup_enabled)
+		return;
+
+	printk(KERN_INFO "PCI: fixup device %s\n", pci_name(dev));
+
+	cal_data = ap91_wmac_data.eeprom_data;
+	if (*cal_data != 0xa55a) {
+		printk(KERN_ERR "PCI: no calibration data found for %s\n",
+		       pci_name(dev));
+		return;
+	}
+
+	mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000);
+	if (!mem) {
+		printk(KERN_ERR "PCI: ioremap error for device %s\n",
+		       pci_name(dev));
+		return;
+	}
+
+	/* Setup the PCI device to allow access to the internal registers */
+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0xffff);
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+	pci_write_config_word(dev, PCI_COMMAND, cmd);
+
+        /* set pointer to first reg address */
+	cal_data += 3;
+	while (*cal_data != 0xffff) {
+		u32 reg;
+		reg = *cal_data++;
+		val = *cal_data++;
+		val |= (*cal_data++) << 16;
+
+		__raw_writel(val, mem + reg);
+		udelay(100);
+	}
+
+	pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
+	dev->vendor = val & 0xffff;
+	dev->device = (val >> 16) & 0xffff;
+
+	pci_read_config_dword(dev, PCI_CLASS_REVISION, &val);
+	dev->revision = val & 0xff;
+	dev->class = val >> 8; /* upper 3 bytes */
+
+	iounmap(mem);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ap91_pci_fixup);
+
+void __init ap91_pci_init(u8 *cal_data, u8 *mac_addr)
+{
+	if (cal_data)
+		memcpy(ap91_wmac_data.eeprom_data, cal_data,
+		       sizeof(ap91_wmac_data.eeprom_data));
+
+	if (mac_addr) {
+		memcpy(ap91_wmac_mac, mac_addr, sizeof(ap91_wmac_mac));
+		ap91_wmac_data.macaddr = ap91_wmac_mac;
+	}
+
+	ar71xx_pci_plat_dev_init = ap91_pci_plat_dev_init;
+	ar71xx_pci_init(ARRAY_SIZE(ap91_pci_irqs), ap91_pci_irqs);
+
+	ap91_pci_fixup_enabled = 1;
+}
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-ap91-pci.h linux-2.6.36/arch/mips/ar71xx/dev-ap91-pci.h
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-ap91-pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-ap91-pci.h	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,21 @@
+/*
+ *  Atheros AP91 reference board PCI initialization
+ *
+ *  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.
+ */
+
+#ifndef _AR71XX_DEV_AP91_PCI_H
+#define _AR71XX_DEV_AP91_PCI_H
+
+#if defined(CONFIG_AR71XX_DEV_AP91_PCI)
+void ap91_pci_init(u8 *cal_data, u8 *mac_addr) __init;
+#else
+static inline void ap91_pci_init(u8 *cal_data, u8 *mac_addr) { }
+#endif
+
+#endif /* _AR71XX_DEV_AP91_PCI_H */
+
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-ap94-pci.c linux-2.6.36/arch/mips/ar71xx/dev-ap94-pci.c
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-ap94-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-ap94-pci.c	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,159 @@
+/*
+ *  Atheros AP94 reference board PCI initialization
+ *
+ *  Copyright (C) 2009-2010 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/pci.h>
+#include <linux/ath9k_platform.h>
+#include <linux/delay.h>
+
+#include <asm/mach-ar71xx/ar71xx.h>
+#include <asm/mach-ar71xx/pci.h>
+
+#include "dev-ap94-pci.h"
+
+static struct ath9k_platform_data ap94_wmac0_data;
+static struct ath9k_platform_data ap94_wmac1_data;
+static char ap94_wmac0_mac[6];
+static char ap94_wmac1_mac[6];
+static int ap94_pci_fixup_enabled;
+
+static struct ar71xx_pci_irq ap94_pci_irqs[] __initdata = {
+        {
+                .slot   = 0,
+                .pin    = 1,
+                .irq    = AR71XX_PCI_IRQ_DEV0,
+        }, {
+                .slot   = 1,
+                .pin    = 1,
+                .irq    = AR71XX_PCI_IRQ_DEV1,
+        }
+};
+
+static int ap94_pci_plat_dev_init(struct pci_dev *dev)
+{
+	switch(PCI_SLOT(dev->devfn)) {
+	case 17:
+		dev->dev.platform_data = &ap94_wmac0_data;
+		break;
+
+	case 18:
+		dev->dev.platform_data = &ap94_wmac1_data;
+		break;
+	}
+
+	return 0;
+}
+
+static void ap94_pci_fixup(struct pci_dev *dev)
+{
+	void __iomem *mem;
+	u16 *cal_data;
+	u16 cmd;
+	u32 bar0;
+	u32 val;
+
+	if (!ap94_pci_fixup_enabled)
+		return;
+
+	switch (PCI_SLOT(dev->devfn)) {
+	case 17:
+		cal_data = ap94_wmac0_data.eeprom_data;
+		break;
+	case 18:
+		cal_data = ap94_wmac1_data.eeprom_data;
+		break;
+	default:
+		return;
+	}
+
+	if (*cal_data != 0xa55a) {
+		printk(KERN_ERR "PCI: no calibration data found for %s\n",
+		       pci_name(dev));
+		return;
+	}
+
+	mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000);
+	if (!mem) {
+		printk(KERN_ERR "PCI: ioremap error for device %s\n",
+		       pci_name(dev));
+		return;
+	}
+
+	printk(KERN_INFO "PCI: fixup device %s\n", pci_name(dev));
+
+	pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0);
+
+	/* Setup the PCI device to allow access to the internal registers */
+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, AR71XX_PCI_MEM_BASE);
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+	pci_write_config_word(dev, PCI_COMMAND, cmd);
+
+	/* set pointer to first reg address */
+	cal_data += 3;
+	while (*cal_data != 0xffff) {
+		u32 reg;
+		reg = *cal_data++;
+		val = *cal_data++;
+		val |= (*cal_data++) << 16;
+
+		__raw_writel(val, mem + reg);
+		udelay(100);
+	}
+
+	pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
+	dev->vendor = val & 0xffff;
+	dev->device = (val >> 16) & 0xffff;
+
+	pci_read_config_dword(dev, PCI_CLASS_REVISION, &val);
+	dev->revision = val & 0xff;
+	dev->class = val >> 8; /* upper 3 bytes */
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+	pci_write_config_word(dev, PCI_COMMAND, cmd);
+
+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0);
+
+	iounmap(mem);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ap94_pci_fixup);
+
+void __init ap94_pci_enable_quirk_wndr3700(void)
+{
+	ap94_wmac0_data.quirk_wndr3700 = 1;
+	ap94_wmac1_data.quirk_wndr3700 = 1;
+}
+
+void __init ap94_pci_init(u8 *cal_data0, u8 *mac_addr0,
+			  u8 *cal_data1, u8 *mac_addr1)
+{
+	if (cal_data0)
+		memcpy(ap94_wmac0_data.eeprom_data, cal_data0,
+		       sizeof(ap94_wmac0_data.eeprom_data));
+
+	if (cal_data1)
+		memcpy(ap94_wmac1_data.eeprom_data, cal_data1,
+		       sizeof(ap94_wmac1_data.eeprom_data));
+
+	if (mac_addr0) {
+		memcpy(ap94_wmac0_mac, mac_addr0, sizeof(ap94_wmac0_mac));
+		ap94_wmac0_data.macaddr = ap94_wmac0_mac;
+	}
+
+	if (mac_addr1) {
+		memcpy(ap94_wmac1_mac, mac_addr1, sizeof(ap94_wmac1_mac));
+		ap94_wmac1_data.macaddr = ap94_wmac1_mac;
+	}
+
+	ar71xx_pci_plat_dev_init = ap94_pci_plat_dev_init;
+	ar71xx_pci_init(ARRAY_SIZE(ap94_pci_irqs), ap94_pci_irqs);
+
+	ap94_pci_fixup_enabled = 1;
+}
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-ap94-pci.h linux-2.6.36/arch/mips/ar71xx/dev-ap94-pci.h
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-ap94-pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-ap94-pci.h	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,28 @@
+/*
+ *  Atheros AP94 reference board PCI initialization
+ *
+ *  Copyright (C) 2009-2010 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.
+ */
+
+#ifndef _AR71XX_DEV_AP94_PCI_H
+#define _AR71XX_DEV_AP94_PCI_H
+
+#if defined(CONFIG_AR71XX_DEV_AP94_PCI)
+void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0,
+		   u8 *cal_data1, u8 *mac_addr1) __init;
+
+void ap94_pci_enable_quirk_wndr3700(void) __init;
+
+#else
+static inline void ap94_pci_init(u8 *cal_data0, u8 *mac_addr0,
+				 u8 *cal_data1, u8 *mac_addr1) {}
+
+static inline void ap94_pci_enable_quirk_wndr3700(void) {}
+#endif
+
+#endif /* _AR71XX_DEV_AP94_PCI_H */
+
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-ar913x-wmac.c linux-2.6.36/arch/mips/ar71xx/dev-ar913x-wmac.c
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-ar913x-wmac.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-ar913x-wmac.c	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,68 @@
+/*
+ *  Atheros AR913x SoC built-in WMAC device support
+ *
+ *  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/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/ath9k_platform.h>
+
+#include <asm/mach-ar71xx/ar71xx.h>
+
+#include "dev-ar913x-wmac.h"
+
+static struct ath9k_platform_data ar913x_wmac_data;
+static char ar913x_wmac_mac[6];
+
+static struct resource ar913x_wmac_resources[] = {
+	{
+		.start	= AR91XX_WMAC_BASE,
+		.end	= AR91XX_WMAC_BASE + AR91XX_WMAC_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= AR71XX_CPU_IRQ_IP2,
+		.end	= AR71XX_CPU_IRQ_IP2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ar913x_wmac_device = {
+	.name		= "ath9k",
+	.id		= -1,
+	.resource	= ar913x_wmac_resources,
+	.num_resources	= ARRAY_SIZE(ar913x_wmac_resources),
+	.dev = {
+		.platform_data = &ar913x_wmac_data,
+	},
+};
+
+void __init ar913x_add_device_wmac(u8 *cal_data, u8 *mac_addr)
+{
+	if (cal_data)
+		memcpy(ar913x_wmac_data.eeprom_data, cal_data,
+		       sizeof(ar913x_wmac_data.eeprom_data));
+
+	if (mac_addr) {
+		memcpy(ar913x_wmac_mac, mac_addr, sizeof(ar913x_wmac_mac));
+		ar913x_wmac_data.macaddr = ar913x_wmac_mac;
+	}
+
+	ar71xx_device_stop(RESET_MODULE_AMBA2WMAC);
+	mdelay(10);
+
+	ar71xx_device_start(RESET_MODULE_AMBA2WMAC);
+	mdelay(10);
+
+	platform_device_register(&ar913x_wmac_device);
+}
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-ar913x-wmac.h linux-2.6.36/arch/mips/ar71xx/dev-ar913x-wmac.h
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-ar913x-wmac.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-ar913x-wmac.h	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,19 @@
+/*
+ *  Atheros AR913x SoC built-in WMAC device support
+ *
+ *  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.
+ */
+
+#ifndef _AR71XX_DEV_AR913X_WMAC_H
+#define _AR71XX_DEV_AR913X_WMAC_H
+
+void ar913x_add_device_wmac(u8 *cal_data, u8 *mac_addr) __init;
+
+#endif /* _AR71XX_DEV_AR913X_WMAC_H */
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-dsa.c linux-2.6.36/arch/mips/ar71xx/dev-dsa.c
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-dsa.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-dsa.c	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,50 @@
+/*
+ *  Atheros AR71xx DSA switch device 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/platform_device.h>
+
+#include <asm/mach-ar71xx/ar71xx.h>
+
+#include "devices.h"
+#include "dev-dsa.h"
+
+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)
+{
+	int i;
+
+	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;
+	}
+
+	for (i = 0; i < d->nr_chips; i++)
+		d->chip[i].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.36.orig/arch/mips/ar71xx/dev-dsa.h linux-2.6.36/arch/mips/ar71xx/dev-dsa.h
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-dsa.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-dsa.h	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,20 @@
+/*
+ *  Atheros AR71xx DSA switch device 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.
+ */
+
+#ifndef _AR71XX_DEV_DSA_H
+#define _AR71XX_DEV_DSA_H
+
+#include <net/dsa.h>
+
+void ar71xx_add_device_dsa(unsigned int id,
+			   struct dsa_platform_data *d) __init;
+
+#endif /* _AR71XX_DEV_DSA_H */
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-gpio-buttons.c linux-2.6.36/arch/mips/ar71xx/dev-gpio-buttons.c
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-gpio-buttons.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-gpio-buttons.c	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,58 @@
+/*
+ *  Atheros AR71xx GPIO button 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/platform_device.h>
+
+#include "dev-gpio-buttons.h"
+
+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);
+}
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-gpio-buttons.h linux-2.6.36/arch/mips/ar71xx/dev-gpio-buttons.h
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-gpio-buttons.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-gpio-buttons.h	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,25 @@
+/*
+ *  Atheros AR71xx GPIO button 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.
+ */
+
+#ifndef _AR71XX_DEV_GPIO_BUTTONS_H
+#define _AR71XX_DEV_GPIO_BUTTONS_H
+
+#include <linux/input.h>
+#include <linux/gpio_buttons.h>
+
+#include <asm/mach-ar71xx/platform.h>
+
+void ar71xx_add_device_gpio_buttons(int id,
+				    unsigned poll_interval,
+				    unsigned nbuttons,
+				    struct gpio_button *buttons) __init;
+
+#endif /* _AR71XX_DEV_GPIO_BUTTONS_H */
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-leds-gpio.c linux-2.6.36/arch/mips/ar71xx/dev-leds-gpio.c
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-leds-gpio.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-leds-gpio.c	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,57 @@
+/*
+ *  Atheros AR71xx GPIO LED device support
+ *
+ *  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/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "dev-leds-gpio.h"
+
+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);
+}
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-leds-gpio.h linux-2.6.36/arch/mips/ar71xx/dev-leds-gpio.h
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-leds-gpio.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-leds-gpio.h	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,21 @@
+/*
+ *  Atheros AR71xx GPIO LED device 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.
+ */
+
+#ifndef _AR71XX_DEV_LEDS_GPIO_H
+#define _AR71XX_DEV_LEDS_GPIO_H
+
+#include <linux/leds.h>
+
+void ar71xx_add_device_leds_gpio(int id,
+				 unsigned num_leds,
+				 struct gpio_led *leds) __init;
+
+#endif /* _AR71XX_DEV_LEDS_GPIO_H */
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-m25p80.c linux-2.6.36/arch/mips/ar71xx/dev-m25p80.c
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-m25p80.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-m25p80.c	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,30 @@
+/*
+ *  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/init.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include "devices.h"
+#include "dev-m25p80.h"
+
+static struct spi_board_info ar71xx_spi_info[] = {
+	{
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.max_speed_hz	= 25000000,
+		.modalias	= "m25p80",
+	}
+};
+
+void __init ar71xx_add_device_m25p80(struct flash_platform_data *pdata)
+{
+	ar71xx_spi_info[0].platform_data = pdata;
+	ar71xx_add_device_spi(NULL, ar71xx_spi_info,
+			      ARRAY_SIZE(ar71xx_spi_info));
+}
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-m25p80.h linux-2.6.36/arch/mips/ar71xx/dev-m25p80.h
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-m25p80.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-m25p80.h	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,16 @@
+/*
+ *  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.
+ */
+
+#ifndef _AR71XX_DEV_M25P80_H
+#define _AR71XX_DEV_M25P80_H
+
+#include <linux/spi/flash.h>
+
+void ar71xx_add_device_m25p80(struct flash_platform_data *pdata) __init;
+
+#endif /* _AR71XX_DEV_M25P80_H */
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-pb42-pci.c linux-2.6.36/arch/mips/ar71xx/dev-pb42-pci.c
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-pb42-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-pb42-pci.c	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,40 @@
+/*
+ *  Atheros PB42 reference board PCI initialization
+ *
+ *  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/pci.h>
+
+#include <asm/mach-ar71xx/ar71xx.h>
+#include <asm/mach-ar71xx/pci.h>
+
+#include "dev-pb42-pci.h"
+
+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,
+	}
+};
+
+void __init pb42_pci_init(void)
+{
+	ar71xx_pci_init(ARRAY_SIZE(pb42_pci_irqs), pb42_pci_irqs);
+}
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-pb42-pci.h linux-2.6.36/arch/mips/ar71xx/dev-pb42-pci.h
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-pb42-pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-pb42-pci.h	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,21 @@
+/*
+ *  Atheros PB42 reference board PCI initialization
+ *
+ *  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_DEV_PB42_PCI_H
+#define _AR71XX_DEV_PB42_PCI_H
+
+#if defined(CONFIG_AR71XX_DEV_PB42_PCI)
+void pb42_pci_init(void) __init;
+#else
+static inline void pb42_pci_init(void) { }
+#endif
+
+#endif /* _AR71XX_DEV_PB42_PCI_H */
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-pb9x-pci.c linux-2.6.36/arch/mips/ar71xx/dev-pb9x-pci.c
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-pb9x-pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-pb9x-pci.c	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,33 @@
+/*
+ *  Atheros PB9x reference board PCI initialization
+ *
+ *  Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org>
+ *  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/pci.h>
+
+#include <asm/mach-ar71xx/ar71xx.h>
+#include <asm/mach-ar71xx/pci.h>
+
+#include "dev-pb9x-pci.h"
+
+static struct ar71xx_pci_irq pb9x_pci_irqs[] __initdata = {
+	{
+		.slot	= 0,
+		.pin	= 1,
+		.irq	= AR71XX_PCI_IRQ_DEV0,
+	}
+};
+
+void __init pb9x_pci_init(void)
+{
+	ar71xx_pci_init(ARRAY_SIZE(pb9x_pci_irqs), pb9x_pci_irqs);
+}
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-pb9x-pci.h linux-2.6.36/arch/mips/ar71xx/dev-pb9x-pci.h
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-pb9x-pci.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-pb9x-pci.h	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,22 @@
+/*
+ *  Atheros PB9x reference board PCI initialization
+ *
+ *  Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org>
+ *  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_DEV_PB9X_PCI_H
+#define _AR71XX_DEV_PB9X_PCI_H
+
+#if defined(CONFIG_AR71XX_DEV_PB9X_PCI)
+void pb9x_pci_init(void) __init;
+#else
+static inline void pb9x_pci_init(void) { }
+#endif
+
+#endif /* _AR71XX_DEV_PB9X_PCI_H */
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-usb.c linux-2.6.36/arch/mips/ar71xx/dev-usb.c
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-usb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-usb.c	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,181 @@
+/*
+ *  Atheros AR71xx USB host device support
+ *
+ *  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/platform_device.h>
+
+#include <asm/mach-ar71xx/ar71xx.h>
+#include <asm/mach-ar71xx/platform.h>
+
+#include "dev-usb.h"
+
+/*
+ * 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 struct resource ar7240_ohci_resources[] = {
+	[0] = {
+		.start	= AR7240_OHCI_BASE,
+		.end	= AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AR71XX_CPU_IRQ_USB,
+		.end	= AR71XX_CPU_IRQ_USB,
+		.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)
+
+#define AR7240_USB_RESET_MASK \
+	(RESET_MODULE_USB_HOST | RESET_MODULE_USB_OHCI_DLL_7240)
+
+static void __init 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);
+
+	platform_device_register(&ar71xx_ohci_device);
+	platform_device_register(&ar71xx_ehci_device);
+}
+
+static void __init ar7240_usb_setup(void)
+{
+	ar71xx_device_stop(AR7240_USB_RESET_MASK);
+	mdelay(1000);
+	ar71xx_device_start(AR7240_USB_RESET_MASK);
+
+	/* WAR for HW bug. Here it adjusts the duration between two SOFS */
+	ar71xx_usb_ctrl_wr(USB_CTRL_REG_FLADJ, 0x3);
+
+	if (ar71xx_soc == AR71XX_SOC_AR7241 || ar71xx_soc == AR71XX_SOC_AR7242) {
+		ar71xx_ehci_data.is_ar91xx = 1;
+		ar71xx_ehci_device.resource = ar7240_ohci_resources;
+		ar71xx_ehci_device.num_resources = ARRAY_SIZE(ar7240_ohci_resources);
+		platform_device_register(&ar71xx_ehci_device);
+	} else {
+		ar71xx_ohci_device.resource = ar7240_ohci_resources;
+		ar71xx_ohci_device.num_resources = ARRAY_SIZE(ar7240_ohci_resources);
+		platform_device_register(&ar71xx_ohci_device);
+	}
+}
+
+static void __init 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);
+
+	ar71xx_ehci_data.is_ar91xx = 1;
+	platform_device_register(&ar71xx_ehci_device);
+}
+
+void __init ar71xx_add_device_usb(void)
+{
+	switch (ar71xx_soc) {
+	case AR71XX_SOC_AR7240:
+	case AR71XX_SOC_AR7241:
+	case AR71XX_SOC_AR7242:
+		ar7240_usb_setup();
+		break;
+
+	case AR71XX_SOC_AR7130:
+	case AR71XX_SOC_AR7141:
+	case AR71XX_SOC_AR7161:
+		ar71xx_usb_setup();
+		break;
+
+	case AR71XX_SOC_AR9130:
+	case AR71XX_SOC_AR9132:
+		ar91xx_usb_setup();
+		break;
+
+	default:
+		BUG();
+	}
+}
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/dev-usb.h linux-2.6.36/arch/mips/ar71xx/dev-usb.h
--- linux-2.6.36.orig/arch/mips/ar71xx/dev-usb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/dev-usb.h	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,17 @@
+/*
+ *  Atheros AR71xx USB host device 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.
+ */
+
+#ifndef _AR71XX_DEV_USB_H
+#define _AR71XX_DEV_USB_H
+
+void ar71xx_add_device_usb(void) __init;
+
+#endif /* _AR71XX_DEV_USB_H */
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/devices.c linux-2.6.36/arch/mips/ar71xx/devices.c
--- linux-2.6.36.orig/arch/mips/ar71xx/devices.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/devices.c	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,575 @@
+/*
+ *  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/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+
+#include <asm/mach-ar71xx/ar71xx.h>
+
+#include "devices.h"
+
+static u8 ar71xx_mac_base[ETH_ALEN] __initdata;
+
+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);
+}
+
+static struct resource ar71xx_mdio_resources[] = {
+	{
+		.name	= "mdio_base",
+		.flags	= IORESOURCE_MEM,
+		.start	= AR71XX_GE0_BASE,
+		.end	= AR71XX_GE0_BASE + 0x200 - 1,
+	}
+};
+
+static struct ag71xx_mdio_platform_data ar71xx_mdio_data;
+
+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)
+{
+	switch (ar71xx_soc) {
+	case AR71XX_SOC_AR7240:
+	case AR71XX_SOC_AR7241:
+	case AR71XX_SOC_AR7242:
+		ar71xx_mdio_data.is_ar7240 = 1;
+		break;
+	default:
+		break;
+	}
+
+	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);
+}
+
+struct ar71xx_eth_pll_data ar71xx_eth0_pll_data;
+struct ar71xx_eth_pll_data ar71xx_eth1_pll_data;
+
+static u32 ar71xx_get_eth_pll(unsigned int mac, int speed)
+{
+	struct ar71xx_eth_pll_data *pll_data;
+	u32 pll_val;
+
+	switch (mac) {
+	case 0:
+		pll_data = &ar71xx_eth0_pll_data;
+		break;
+	case 1:
+		pll_data = &ar71xx_eth1_pll_data;
+		break;
+	default:
+		BUG();
+	}
+
+	switch (speed) {
+	case SPEED_10:
+		pll_val = pll_data->pll_10;
+		break;
+	case SPEED_100:
+		pll_val = pll_data->pll_100;
+		break;
+	case SPEED_1000:
+		pll_val = pll_data->pll_1000;
+		break;
+	default:
+		BUG();
+	}
+
+	return pll_val;
+}
+
+static void ar71xx_set_pll_ge0(int speed)
+{
+	u32 val = ar71xx_get_eth_pll(0, speed);
+
+	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(int speed)
+{
+	u32 val = ar71xx_get_eth_pll(1, speed);
+
+	ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH1_INT_CLOCK,
+			 val, AR71XX_ETH1_PLL_SHIFT);
+}
+
+static void ar724x_set_pll_ge0(int speed)
+{
+	/* TODO */
+}
+
+static void ar724x_set_pll_ge1(int speed)
+{
+	/* TODO */
+}
+
+static void ar91xx_set_pll_ge0(int speed)
+{
+	u32 val = ar71xx_get_eth_pll(0, speed);
+
+	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(int speed)
+{
+	u32 val = ar71xx_get_eth_pll(1, speed);
+
+	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 ar724x_ddr_flush_ge0(void)
+{
+	ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE0);
+}
+
+static void ar724x_ddr_flush_ge1(void)
+{
+	ar71xx_ddr_flush(AR724X_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 + 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,
+};
+
+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 + 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,
+};
+
+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,
+	},
+};
+
+#define AR71XX_PLL_VAL_1000	0x00110000
+#define AR71XX_PLL_VAL_100	0x00001099
+#define AR71XX_PLL_VAL_10	0x00991099
+
+#define AR724X_PLL_VAL_1000	0x00110000
+#define AR724X_PLL_VAL_100	0x00001099
+#define AR724X_PLL_VAL_10	0x00991099
+
+#define AR91XX_PLL_VAL_1000	0x1a000000
+#define AR91XX_PLL_VAL_100	0x13000a44
+#define AR91XX_PLL_VAL_10	0x00441099
+
+static void __init ar71xx_init_eth_pll_data(unsigned int id)
+{
+	struct ar71xx_eth_pll_data *pll_data;
+	u32 pll_10, pll_100, pll_1000;
+
+	switch (id) {
+	case 0:
+		pll_data = &ar71xx_eth0_pll_data;
+		break;
+	case 1:
+		pll_data = &ar71xx_eth1_pll_data;
+		break;
+	default:
+		BUG();
+	}
+
+	switch (ar71xx_soc) {
+	case AR71XX_SOC_AR7130:
+	case AR71XX_SOC_AR7141:
+	case AR71XX_SOC_AR7161:
+		pll_10 = AR71XX_PLL_VAL_10;
+		pll_100 = AR71XX_PLL_VAL_100;
+		pll_1000 = AR71XX_PLL_VAL_1000;
+		break;
+
+	case AR71XX_SOC_AR7240:
+	case AR71XX_SOC_AR7241:
+	case AR71XX_SOC_AR7242:
+		pll_10 = AR724X_PLL_VAL_10;
+		pll_100 = AR724X_PLL_VAL_100;
+		pll_1000 = AR724X_PLL_VAL_1000;
+		break;
+
+	case AR71XX_SOC_AR9130:
+	case AR71XX_SOC_AR9132:
+		pll_10 = AR91XX_PLL_VAL_10;
+		pll_100 = AR91XX_PLL_VAL_100;
+		pll_1000 = AR91XX_PLL_VAL_1000;
+		break;
+	default:
+		BUG();
+	}
+
+	if (!pll_data->pll_10)
+		pll_data->pll_10 = pll_10;
+
+	if (!pll_data->pll_100)
+		pll_data->pll_100 = pll_100;
+
+	if (!pll_data->pll_1000)
+		pll_data->pll_1000 = pll_1000;
+}
+
+static int ar71xx_eth_instance __initdata;
+void __init ar71xx_add_device_eth(unsigned int id)
+{
+	struct platform_device *pdev;
+	struct ag71xx_platform_data *pdata;
+
+	ar71xx_init_eth_pll_data(id);
+
+	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_AR7241:
+	case AR71XX_SOC_AR7242:
+		ar71xx_eth0_data.reset_bit |= AR724X_RESET_GE0_MDIO;
+		ar71xx_eth1_data.reset_bit |= AR724X_RESET_GE1_MDIO;
+		/* fall through */
+	case AR71XX_SOC_AR7240:
+		pdata->ddr_flush = id ? ar724x_ddr_flush_ge1
+				      : ar724x_ddr_flush_ge0;
+		pdata->set_pll =  id ? ar724x_set_pll_ge1
+				     : ar724x_set_pll_ge0;
+		pdata->is_ar724x = 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);
+	}
+
+	if (pdata->mii_bus_dev == NULL)
+		pdata->mii_bus_dev = &ar71xx_mdio_device.dev;
+
+	/* Reset the device */
+	ar71xx_device_stop(pdata->reset_bit);
+	mdelay(100);
+
+	ar71xx_device_start(pdata->reset_bit);
+	mdelay(100);
+
+	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_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 int __init ar71xx_ethaddr_setup(char *str)
+{
+	ar71xx_parse_mac_addr(str);
+	return 1;
+}
+__setup("ethaddr=", ar71xx_ethaddr_setup);
+
+static int __init ar71xx_kmac_setup(char *str)
+{
+	ar71xx_parse_mac_addr(str);
+	return 1;
+}
+__setup("kmac=", ar71xx_kmac_setup);
diff -Nur linux-2.6.36.orig/arch/mips/ar71xx/devices.h linux-2.6.36/arch/mips/ar71xx/devices.h
--- linux-2.6.36.orig/arch/mips/ar71xx/devices.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.36/arch/mips/ar71xx/devices.h	2010-11-18 21:16:05.000000000 +0100
@@ -0,0 +1,48 @@
+/*
+ *  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>
+
+struct platform_device;
+
+void ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata,
+			   struct spi_board_info c