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