diff options
Diffstat (limited to 'target/rb433/patches/ar71xx.patch')
-rw-r--r-- | target/rb433/patches/ar71xx.patch | 9913 |
1 files changed, 0 insertions, 9913 deletions
diff --git a/target/rb433/patches/ar71xx.patch b/target/rb433/patches/ar71xx.patch deleted file mode 100644 index 3646174f4..000000000 --- a/target/rb433/patches/ar71xx.patch +++ /dev/null @@ -1,9913 +0,0 @@ -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 = "firmware", -+ .offset = 0x030000, -+ .size = 0x3c0000, -+ } -+}; -+#endif /* CONFIG_MTD_PARTITIONS */ -+ -+static struct flash_platform_data tew_632brp_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = tew_632brp_partitions, -+ .nr_parts = ARRAY_SIZE(tew_632brp_partitions), -+#endif -+}; -+ -+static struct spi_board_info tew_632brp_spi_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ .platform_data = &tew_632brp_flash_data, -+ } -+}; -+ -+static struct gpio_led tew_632brp_leds_gpio[] __initdata = { -+ { -+ .name = "tew-632brp:green:status", -+ .gpio = TEW_632BRP_GPIO_LED_STATUS, -+ .active_low = 1, -+ }, { -+ .name = "tew-632brp:blue:wps", -+ .gpio = TEW_632BRP_GPIO_LED_WPS, -+ .active_low = 1, -+ }, { -+ .name = "tew-632brp:green:wlan", -+ .gpio = TEW_632BRP_GPIO_LED_WLAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_button tew_632brp_gpio_buttons[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .threshold = 5, -+ .gpio = TEW_632BRP_GPIO_BTN_RESET, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = BTN_1, -+ .threshold = 5, -+ .gpio = TEW_632BRP_GPIO_BTN_WPS, -+ } -+}; -+ -+static void __init tew_632brp_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_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, tew_632brp_spi_info, -+ ARRAY_SIZE(tew_632brp_spi_info)); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tew_632brp_leds_gpio), -+ tew_632brp_leds_gpio); -+ -+ ar71xx_add_device_gpio_buttons(-1, TEW_632BRP_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(tew_632brp_gpio_buttons), -+ tew_632brp_gpio_buttons); -+ -+ ar91xx_add_device_wmac(); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_TEW_632BRP, "TRENDnet TEW-632BRP", tew_632brp_setup); -diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-tl-wr941nd.c linux-2.6.29.1/arch/mips/ar71xx/mach-tl-wr941nd.c ---- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-tl-wr941nd.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/ar71xx/mach-tl-wr941nd.c 2009-04-13 14:27:34.591071588 +0200 -@@ -0,0 +1,144 @@ -+/* -+ * TP-LINK TL-WR941ND 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 TL_WR941ND_GPIO_LED_SYSTEM 2 -+#define TL_WR941ND_GPIO_LED_QSS 5 -+ -+#define TL_WR941ND_GPIO_BTN_RESET 3 -+#define TL_WR941ND_GPIO_BTN_QSS 7 -+ -+#define TL_WR941ND_BUTTONS_POLL_INTERVAL 20 -+ -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition tl_wr941nd_partitions[] = { -+ { -+ .name = "u-boot", -+ .offset = 0, -+ .size = 0x020000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "kernel", -+ .offset = 0x020000, -+ .size = 0x120000, -+ } , { -+ .name = "rootfs", -+ .offset = 0x140000, -+ .size = 0x2b0000, -+ } , { -+ .name = "art", -+ .offset = 0x3f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ } , { -+ .name = "firmware", -+ .offset = 0x020000, -+ .size = 0x3d0000, -+ } -+}; -+#endif /* CONFIG_MTD_PARTITIONS */ -+ -+static struct flash_platform_data tl_wr941nd_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = tl_wr941nd_partitions, -+ .nr_parts = ARRAY_SIZE(tl_wr941nd_partitions), -+#endif -+}; -+ -+static struct spi_board_info tl_wr941nd_spi_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ .platform_data = &tl_wr941nd_flash_data, -+ } -+}; -+ -+static struct gpio_led tl_wr941nd_leds_gpio[] __initdata = { -+ { -+ .name = "tl-wr941nd:green:system", -+ .gpio = TL_WR941ND_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tl-wr941nd:red:qss", -+ .gpio = TL_WR941ND_GPIO_LED_QSS, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_button tl_wr941nd_gpio_buttons[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .threshold = 5, -+ .gpio = TL_WR941ND_GPIO_BTN_RESET, -+ .active_low = 1, -+ }, { -+ .desc = "qss", -+ .type = EV_KEY, -+ .code = BTN_1, -+ .threshold = 5, -+ .gpio = TL_WR941ND_GPIO_BTN_QSS, -+ .active_low = 1, -+ } -+}; -+ -+static struct dsa_platform_data tl_wr941nd_dsa_data = { -+ .port_names[0] = "wan", -+ .port_names[1] = "lan1", -+ .port_names[2] = "lan2", -+ .port_names[3] = "lan3", -+ .port_names[4] = "lan4", -+ .port_names[5] = "cpu", -+}; -+ -+static void __init tl_wr941nd_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -+ -+ 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 = 0x0; -+ ar71xx_eth0_data.speed = SPEED_100; -+ ar71xx_eth0_data.duplex = DUPLEX_FULL; -+ -+ ar71xx_add_device_eth(0); -+ ar71xx_add_device_dsa(0, &tl_wr941nd_dsa_data); -+ -+ ar71xx_add_device_spi(NULL, tl_wr941nd_spi_info, -+ ARRAY_SIZE(tl_wr941nd_spi_info)); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(tl_wr941nd_leds_gpio), -+ tl_wr941nd_leds_gpio); -+ -+ ar71xx_add_device_gpio_buttons(-1, TL_WR941ND_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr941nd_gpio_buttons), -+ tl_wr941nd_gpio_buttons); -+ ar91xx_add_device_wmac(); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_TL_WR941ND, "TP-LINK TL-WR941ND", tl_wr941nd_setup); -diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-ubnt.c linux-2.6.29.1/arch/mips/ar71xx/mach-ubnt.c ---- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-ubnt.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/ar71xx/mach-ubnt.c 2009-04-13 14:27:34.591071588 +0200 -@@ -0,0 +1,188 @@ -+/* -+ * Ubiquiti RouterStation support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org> -+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> -+ * Copyright (C) 2008 Ubiquiti <support@ubnt.com> -+ * -+ * 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/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 UBNT_RS_GPIO_LED_RF 2 -+#define UBNT_RS_GPIO_SW4 8 -+ -+#define UBNT_LS_SR71_GPIO_LED_D25 0 -+#define UBNT_LS_SR71_GPIO_LED_D26 1 -+#define UBNT_LS_SR71_GPIO_LED_D24 2 -+#define UBNT_LS_SR71_GPIO_LED_D23 4 -+#define UBNT_LS_SR71_GPIO_LED_D22 5 -+#define UBNT_LS_SR71_GPIO_LED_D27 6 -+#define UBNT_LS_SR71_GPIO_LED_D28 7 -+ -+#define UBNT_BUTTONS_POLL_INTERVAL 20 -+ -+static struct spi_board_info ubnt_spi_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ } -+}; -+ -+static struct ar71xx_pci_irq ubnt_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_led ubnt_rs_leds_gpio[] __initdata = { -+ { -+ .name = "ubnt:green:rf", -+ .gpio = UBNT_RS_GPIO_LED_RF, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_led ubnt_ls_sr71_leds_gpio[] __initdata = { -+ { -+ .name = "ubnt:green:d22", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D22, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:d23", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D23, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:d24", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D24, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:red:d25", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D25, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:red:d26", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D26, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:d27", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D27, -+ .active_low = 0, -+ }, { -+ .name = "ubnt:green:d28", -+ .gpio = UBNT_LS_SR71_GPIO_LED_D28, -+ .active_low = 0, -+ } -+}; -+ -+static struct gpio_button ubnt_gpio_buttons[] __initdata = { -+ { -+ .desc = "sw4", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .threshold = 5, -+ .gpio = UBNT_RS_GPIO_SW4, -+ .active_low = 1, -+ } -+}; -+ -+static void __init ubnt_generic_setup(void) -+{ -+ ar71xx_add_device_spi(NULL, ubnt_spi_info, -+ ARRAY_SIZE(ubnt_spi_info)); -+ -+ ar71xx_add_device_gpio_buttons(-1, UBNT_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(ubnt_gpio_buttons), -+ ubnt_gpio_buttons); -+ -+ ar71xx_pci_init(ARRAY_SIZE(ubnt_pci_irqs), ubnt_pci_irqs); -+} -+ -+#define UBNT_RS_WAN_PHYMASK (1 << 20) -+#define UBNT_RS_LAN_PHYMASK ((1 << 16) | (1 << 17) | (1 << 18) | (1 << 19)) -+ -+static void __init ubnt_rs_setup(void) -+{ -+ ubnt_generic_setup(); -+ -+ ar71xx_add_device_mdio(~(UBNT_RS_WAN_PHYMASK | UBNT_RS_LAN_PHYMASK)); -+ -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.phy_mask = UBNT_RS_WAN_PHYMASK; -+ -+ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; -+ ar71xx_eth1_data.phy_mask = UBNT_RS_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_usb(); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_rs_leds_gpio), -+ ubnt_rs_leds_gpio); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_UBNT_RS, "Ubiquiti RouterStation", ubnt_rs_setup); -+ -+static void __init ubnt_rspro_setup(void) -+{ -+ ubnt_generic_setup(); -+ -+ ar71xx_add_device_usb(); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_UBNT_RSPRO, "Ubiquiti RouterStation Pro", -+ ubnt_rspro_setup); -+ -+static void __init ubnt_lsx_setup(void) -+{ -+ ubnt_generic_setup(); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_UBNT_LSX, "Ubiquiti LSX", ubnt_lsx_setup); -+ -+#define UBNT_LSSR71_PHY_MASK (1 << 1) -+ -+static void __init ubnt_lssr71_setup(void) -+{ -+ ubnt_generic_setup(); -+ -+ ar71xx_add_device_mdio(~UBNT_LSSR71_PHY_MASK); -+ -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.phy_mask = UBNT_LSSR71_PHY_MASK; -+ -+ ar71xx_add_device_eth(0); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(ubnt_ls_sr71_leds_gpio), -+ ubnt_ls_sr71_leds_gpio); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_UBNT_LSSR71, "Ubiquiti LS-SR71", ubnt_lssr71_setup); -diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-wnr2000.c linux-2.6.29.1/arch/mips/ar71xx/mach-wnr2000.c ---- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-wnr2000.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/ar71xx/mach-wnr2000.c 2009-04-13 14:27:34.595070701 +0200 -@@ -0,0 +1,158 @@ -+/* -+ * NETGEAR WNR2000 board support -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org> -+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> -+ * Copyright (C) 2008-2009 Andy Boyett <agb@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 WNR2000_GPIO_LED_PWR_GREEN 14 -+#define WNR2000_GPIO_LED_PWR_AMBER 7 -+#define WNR2000_GPIO_LED_WPS 4 -+#define WNR2000_GPIO_LED_WLAN 6 -+#define WNR2000_GPIO_BTN_RESET 21 -+#define WNR2000_GPIO_BTN_WPS 8 -+ -+#define WNR2000_BUTTONS_POLL_INTERVAL 20 -+ -+#ifdef CONFIG_MTD_PARTITIONS -+static struct mtd_partition wnr2000_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 = 0x240000, -+ } , { -+ .name = "user-config", -+ .offset = 0x290000, -+ .size = 0x010000, -+ } , { -+ .name = "uImage", -+ .offset = 0x2a0000, -+ .size = 0x120000, -+ } , { -+ .name = "language_table", -+ .offset = 0x3c0000, -+ .size = 0x020000, -+ } , { -+ .name = "rootfs_checksum", -+ .offset = 0x3e0000, -+ .size = 0x010000, -+ } , { -+ .name = "art", -+ .offset = 0x3f0000, -+ .size = 0x010000, -+ .mask_flags = MTD_WRITEABLE, -+ } -+}; -+#endif /* CONFIG_MTD_PARTITIONS */ -+ -+static struct flash_platform_data wnr2000_flash_data = { -+#ifdef CONFIG_MTD_PARTITIONS -+ .parts = wnr2000_partitions, -+ .nr_parts = ARRAY_SIZE(wnr2000_partitions), -+#endif -+}; -+ -+static struct spi_board_info wnr2000_spi_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ .platform_data = &wnr2000_flash_data, -+ } -+}; -+ -+static struct gpio_led wnr2000_leds_gpio[] __initdata = { -+ { -+ .name = "wnr2000:green:power", -+ .gpio = WNR2000_GPIO_LED_PWR_GREEN, -+ .active_low = 1, -+ }, { -+ .name = "wnr2000:amber:power", -+ .gpio = WNR2000_GPIO_LED_PWR_AMBER, -+ .active_low = 1, -+ }, { -+ .name = "wnr2000:green:wps", -+ .gpio = WNR2000_GPIO_LED_WPS, -+ .active_low = 1, -+ }, { -+ .name = "wnr2000:blue:wlan", -+ .gpio = WNR2000_GPIO_LED_WLAN, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_button wnr2000_gpio_buttons[] __initdata = { -+ { -+ .desc = "reset", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .threshold = 5, -+ .gpio = WNR2000_GPIO_BTN_RESET, -+ }, { -+ .desc = "wps", -+ .type = EV_KEY, -+ .code = BTN_1, -+ .threshold = 5, -+ .gpio = WNR2000_GPIO_BTN_WPS, -+ } -+}; -+ -+static void __init wnr2000_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_spi(NULL, wnr2000_spi_info, -+ ARRAY_SIZE(wnr2000_spi_info)); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wnr2000_leds_gpio), -+ wnr2000_leds_gpio); -+ -+ ar71xx_add_device_gpio_buttons(-1, WNR2000_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(wnr2000_gpio_buttons), -+ wnr2000_gpio_buttons); -+ -+ -+ ar91xx_add_device_wmac(); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_WNR2000, "NETGEAR WNR2000", wnr2000_setup); -diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/mach-wp543.c linux-2.6.29.1/arch/mips/ar71xx/mach-wp543.c ---- linux-2.6.29.1.orig/arch/mips/ar71xx/mach-wp543.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/ar71xx/mach-wp543.c 2009-04-13 14:27:34.595070701 +0200 -@@ -0,0 +1,118 @@ -+/* -+ * Compex WP543 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 WP543_GPIO_SW6 2 -+#define WP543_GPIO_LED_1 3 -+#define WP543_GPIO_LED_2 4 -+#define WP543_GPIO_LED_WLAN 5 -+#define WP543_GPIO_LED_CONN 6 -+#define WP543_GPIO_LED_DIAG 7 -+#define WP543_GPIO_SW4 8 -+ -+#define WP543_BUTTONS_POLL_INTERVAL 20 -+ -+static struct spi_board_info wp543_spi_info[] = { -+ { -+ .bus_num = 0, -+ .chip_select = 0, -+ .max_speed_hz = 25000000, -+ .modalias = "m25p80", -+ } -+}; -+ -+static struct ar71xx_pci_irq wp543_pci_irqs[] __initdata = { -+ { -+ .slot = 1, -+ .pin = 1, -+ .irq = AR71XX_PCI_IRQ_DEV0, -+ }, { -+ .slot = 1, -+ .pin = 2, -+ .irq = AR71XX_PCI_IRQ_DEV1, -+ } -+}; -+ -+static struct gpio_led wp543_leds_gpio[] __initdata = { -+ { -+ .name = "wp543:green:led1", -+ .gpio = WP543_GPIO_LED_1, -+ .active_low = 1, -+ }, { -+ .name = "wp543:green:led2", -+ .gpio = WP543_GPIO_LED_2, -+ .active_low = 1, -+ }, { -+ .name = "wp543:green:wlan", -+ .gpio = WP543_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, { -+ .name = "wp543:green:conn", -+ .gpio = WP543_GPIO_LED_CONN, -+ .active_low = 1, -+ }, { -+ .name = "wp543:green:diag", -+ .gpio = WP543_GPIO_LED_DIAG, -+ .active_low = 1, -+ } -+}; -+ -+static struct gpio_button wp543_gpio_buttons[] __initdata = { -+ { -+ .desc = "sw6", -+ .type = EV_KEY, -+ .code = BTN_0, -+ .threshold = 5, -+ .gpio = WP543_GPIO_SW6, -+ }, { -+ .desc = "sw4", -+ .type = EV_KEY, -+ .code = BTN_1, -+ .threshold = 5, -+ .gpio = WP543_GPIO_SW4, -+ } -+}; -+ -+static void __init wp543_setup(void) -+{ -+ ar71xx_add_device_spi(NULL, wp543_spi_info, ARRAY_SIZE(wp543_spi_info)); -+ -+ ar71xx_add_device_mdio(0xfffffff7); -+ -+ ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -+ ar71xx_eth0_data.phy_mask = 0x00000008; -+ ar71xx_add_device_eth(0); -+ -+ ar71xx_add_device_usb(); -+ -+ ar71xx_pci_init(ARRAY_SIZE(wp543_pci_irqs), wp543_pci_irqs); -+ -+ ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(wp543_leds_gpio), -+ wp543_leds_gpio); -+ -+ ar71xx_add_device_gpio_buttons(-1, WP543_BUTTONS_POLL_INTERVAL, -+ ARRAY_SIZE(wp543_gpio_buttons), -+ wp543_gpio_buttons); -+} -+ -+MIPS_MACHINE(AR71XX_MACH_WP543, "Compex WP543", wp543_setup); -diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/prom.c linux-2.6.29.1/arch/mips/ar71xx/prom.c ---- linux-2.6.29.1.orig/arch/mips/ar71xx/prom.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/ar71xx/prom.c 2009-04-13 14:27:34.595070701 +0200 -@@ -0,0 +1,207 @@ -+/* -+ * Atheros AR71xx SoC specific prom 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/init.h> -+#include <linux/io.h> -+#include <linux/serial_reg.h> -+ -+#include <asm/bootinfo.h> -+#include <asm/addrspace.h> -+ -+#include <asm/mach-ar71xx/ar71xx.h> -+ -+#include "devices.h" -+ -+struct board_rec { -+ char *name; -+ unsigned long mach_type; -+}; -+ -+static int ar71xx_prom_argc __initdata; -+static char **ar71xx_prom_argv __initdata; -+static char **ar71xx_prom_envp __initdata; -+ -+static struct board_rec boards[] __initdata = { -+ { -+ .name = "411", -+ .mach_type = AR71XX_MACH_RB_411, -+ }, { -+ .name = "433", -+ .mach_type = AR71XX_MACH_RB_433, -+ }, { -+ .name = "450", -+ .mach_type = AR71XX_MACH_RB_450, -+ }, { -+ .name = "493", -+ .mach_type = AR71XX_MACH_RB_493, -+ }, { -+ .name = "AP81", -+ .mach_type = AR71XX_MACH_AP81, -+ }, { -+ .name = "AP83", -+ .mach_type = AR71XX_MACH_AP83, -+ }, { -+ .name = "AW-NR580", -+ .mach_type = AR71XX_MACH_AW_NR580, -+ }, { -+ .name = "TEW-632BRP", -+ .mach_type = AR71XX_MACH_TEW_632BRP, -+ }, { -+ .name = "TL-WR941ND", -+ .mach_type = AR71XX_MACH_TL_WR941ND, -+ }, { -+ .name = "UBNT-RS", -+ .mach_type = AR71XX_MACH_UBNT_RS, -+ }, { -+ .name = "UBNT-RSPRO", -+ .mach_type = AR71XX_MACH_UBNT_RSPRO, -+ }, { -+ .name = "Ubiquiti AR71xx-based board", -+ .mach_type = AR71XX_MACH_UBNT_RS, -+ }, { -+ .name = "UBNT-LS-SR71", -+ .mach_type = AR71XX_MACH_UBNT_LSSR71, -+ }, { -+ .name = "UBNT-LSX", -+ .mach_type = AR71XX_MACH_UBNT_LSX, -+ }, { -+ .name = "WNR2000", -+ .mach_type = AR71XX_MACH_WNR2000, -+ }, { -+ .name = "PB42", -+ .mach_type = AR71XX_MACH_PB42, -+ }, { -+ .name = "MZK-W300NH", -+ .mach_type = AR71XX_MACH_MZK_W300NH, -+ }, { -+ .name = "MZK-W04NU", -+ .mach_type = AR71XX_MACH_MZK_W04NU, -+ } -+}; -+ -+static inline int is_valid_ram_addr(void *addr) -+{ -+ if (((u32) addr > KSEG0) && -+ ((u32) addr < (KSEG0 + AR71XX_MEM_SIZE_MAX))) -+ return 1; -+ -+ if (((u32) addr > KSEG1) && -+ ((u32) addr < (KSEG1 + AR71XX_MEM_SIZE_MAX))) -+ return 1; -+ -+ return 0; -+} -+ -+static __init char *ar71xx_prom_getargv(const char *name) -+{ -+ int len = strlen(name); -+ int i; -+ -+ if (!is_valid_ram_addr(ar71xx_prom_argv)) -+ return NULL; -+ -+ for (i = 0; i < ar71xx_prom_argc; i++) { -+ char *argv = ar71xx_prom_argv[i]; -+ -+ if (!is_valid_ram_addr(argv)) -+ continue; -+ -+ if (strncmp(name, argv, len) == 0 && (argv)[len] == '=') -+ return argv + len + 1; -+ } -+ -+ return NULL; -+} -+ -+static __init char *ar71xx_prom_getenv(const char *envname) -+{ -+ int len = strlen(envname); -+ char **env; -+ -+ if (!is_valid_ram_addr(ar71xx_prom_envp)) -+ return NULL; -+ -+ for (env = ar71xx_prom_envp; is_valid_ram_addr(*env); env++) { -+ if (strncmp(envname, *env, len) == 0 && (*env)[len] == '=') -+ return *env + len + 1; -+ -+ /* RedBoot env comes in pointer pairs - key, value */ -+ if (strncmp(envname, *env, len) == 0 && (*env)[len] == 0) -+ if (is_valid_ram_addr(*(++env))) -+ return *env; -+ } -+ -+ return NULL; -+} -+ -+static __init unsigned long find_board_byname(char *name) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(boards); i++) -+ if (strcmp(name, boards[i].name) == 0) -+ return boards[i].mach_type; -+ -+ return AR71XX_MACH_GENERIC; -+} -+ -+ -+static void ar71xx_prom_init_generic(void) -+{ -+ char *p; -+ -+ ar71xx_prom_argc = fw_arg0; -+ ar71xx_prom_argv = (char **)fw_arg1; -+ ar71xx_prom_envp = (char **)fw_arg2; -+ -+ p = ar71xx_prom_getargv("board"); -+ if (!p) -+ p = ar71xx_prom_getenv("board"); -+ if (p) -+ ar71xx_mach_type = find_board_byname(p); -+ -+ p = ar71xx_prom_getenv("ethaddr"); -+ if (!p) -+ p = ar71xx_prom_getargv("kmac"); -+ if (p) -+ ar71xx_parse_mac_addr(p); -+} -+ -+void __init prom_init(void) -+{ -+ printk(KERN_DEBUG "prom: fw_arg0=%08x, fw_arg1=%08x, " -+ "fw_arg2=%08x, fw_arg3=%08x\n", -+ (unsigned int)fw_arg0, (unsigned int)fw_arg1, -+ (unsigned int)fw_arg2, (unsigned int)fw_arg3); -+ -+ ar71xx_mach_type = AR71XX_MACH_GENERIC; -+ -+ ar71xx_prom_init_generic(); -+} -+ -+void __init prom_free_prom_memory(void) -+{ -+ /* We do not have to prom memory to free */ -+} -+ -+#define UART_READ(r) \ -+ __raw_readl((void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE) + 4 * (r))) -+ -+#define UART_WRITE(r, v) \ -+ __raw_writel((v), (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE) + 4*(r))) -+ -+void prom_putchar(unsigned char ch) -+{ -+ while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0); -+ UART_WRITE(UART_TX, ch); -+ while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0); -+} -diff -Nur linux-2.6.29.1.orig/arch/mips/ar71xx/setup.c linux-2.6.29.1/arch/mips/ar71xx/setup.c ---- linux-2.6.29.1.orig/arch/mips/ar71xx/setup.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/ar71xx/setup.c 2009-04-13 14:27:34.599071210 +0200 -@@ -0,0 +1,291 @@ -+/* -+ * Atheros AR71xx SoC specific setup -+ * -+ * 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/module.h> -+#include <linux/init.h> -+#include <linux/types.h> -+#include <linux/pci.h> -+#include <linux/serial_8250.h> -+#include <linux/bootmem.h> -+ -+#include <asm/bootinfo.h> -+#include <asm/traps.h> -+#include <asm/time.h> /* for mips_hpt_frequency */ -+#include <asm/reboot.h> /* for _machine_{restart,halt} */ -+#include <asm/mips_machine.h> -+ -+#include <asm/mach-ar71xx/ar71xx.h> -+#include <asm/mach-ar71xx/pci.h> -+ -+#include "devices.h" -+ -+#define AR71XX_SYS_TYPE_LEN 64 -+#define AR71XX_BASE_FREQ 40000000 -+#define AR91XX_BASE_FREQ 5000000 -+ -+unsigned long ar71xx_mach_type; -+ -+u32 ar71xx_cpu_freq; -+EXPORT_SYMBOL_GPL(ar71xx_cpu_freq); -+ -+u32 ar71xx_ahb_freq; -+EXPORT_SYMBOL_GPL(ar71xx_ahb_freq); -+ -+u32 ar71xx_ddr_freq; -+EXPORT_SYMBOL_GPL(ar71xx_ddr_freq); -+ -+enum ar71xx_soc_type ar71xx_soc; -+EXPORT_SYMBOL_GPL(ar71xx_soc); -+ -+int (*ar71xx_pci_bios_init)(unsigned nr_irqs, -+ struct ar71xx_pci_irq *map) __initdata; -+ -+int (*ar71xx_pci_be_handler)(int is_fixup); -+ -+static char ar71xx_sys_type[AR71XX_SYS_TYPE_LEN]; -+ -+static void ar71xx_restart(char *command) -+{ -+ ar71xx_device_stop(RESET_MODULE_FULL_CHIP); -+ for (;;) -+ if (cpu_wait) -+ cpu_wait(); -+} -+ -+static void ar71xx_halt(void) -+{ -+ while (1) -+ cpu_wait(); -+} -+ -+static int ar71xx_be_handler(struct pt_regs *regs, int is_fixup) -+{ -+ int err = 0; -+ -+ if (ar71xx_pci_be_handler) -+ err = ar71xx_pci_be_handler(is_fixup); -+ -+ return (is_fixup && !err) ? MIPS_BE_FIXUP : MIPS_BE_FATAL; -+} -+ -+int __init ar71xx_pci_init(unsigned nr_irqs, struct ar71xx_pci_irq *map) -+{ -+ if (!ar71xx_pci_bios_init) -+ return 0; -+ -+ return ar71xx_pci_bios_init(nr_irqs, map); -+} -+ -+static void __init ar71xx_detect_mem_size(void) -+{ -+ unsigned long size; -+ -+ for (size = AR71XX_MEM_SIZE_MIN; size < AR71XX_MEM_SIZE_MAX; -+ size <<= 1 ) { -+ if (!memcmp(ar71xx_detect_mem_size, -+ ar71xx_detect_mem_size + size, 1024)) -+ break; -+ } -+ -+ add_memory_region(0, size, BOOT_MEM_RAM); -+} -+ -+static void __init ar71xx_detect_sys_type(void) -+{ -+ char *chip; -+ u32 id; -+ u32 rev; -+ -+ id = ar71xx_reset_rr(AR71XX_RESET_REG_REV_ID) & REV_ID_MASK; -+ rev = (id >> REV_ID_REVISION_SHIFT) & REV_ID_REVISION_MASK; -+ -+ switch (id & REV_ID_CHIP_MASK) { -+ case REV_ID_CHIP_AR7130: -+ ar71xx_soc = AR71XX_SOC_AR7130; -+ chip = "7130"; -+ break; -+ -+ case REV_ID_CHIP_AR7141: -+ ar71xx_soc = AR71XX_SOC_AR7141; -+ chip = "7141"; -+ break; -+ -+ case REV_ID_CHIP_AR7161: -+ ar71xx_soc = AR71XX_SOC_AR7161; -+ chip = "7161"; -+ break; -+ -+ case REV_ID_CHIP_AR9130: -+ ar71xx_soc = AR71XX_SOC_AR9130; -+ chip = "9130"; -+ break; -+ -+ case REV_ID_CHIP_AR9132: -+ ar71xx_soc = AR71XX_SOC_AR9132; -+ chip = "9132"; -+ break; -+ -+ default: -+ panic("ar71xx: unknown chip id:0x%02x\n", id); -+ } -+ -+ sprintf(ar71xx_sys_type, "Atheros AR%s rev %u (id:0x%02x)", -+ chip, rev, id); -+} -+ -+static void __init ar91xx_detect_sys_frequency(void) -+{ -+ u32 pll; -+ u32 freq; -+ u32 div; -+ -+ pll = ar71xx_pll_rr(AR91XX_PLL_REG_CPU_CONFIG); -+ -+ div = ((pll >> AR91XX_PLL_DIV_SHIFT) & AR91XX_PLL_DIV_MASK); -+ freq = div * AR91XX_BASE_FREQ; -+ -+ ar71xx_cpu_freq = freq; -+ -+ div = ((pll >> AR91XX_DDR_DIV_SHIFT) & AR91XX_DDR_DIV_MASK) + 1; -+ ar71xx_ddr_freq = freq / div; -+ -+ div = (((pll >> AR91XX_AHB_DIV_SHIFT) & AR91XX_AHB_DIV_MASK) + 1) * 2; -+ ar71xx_ahb_freq = ar71xx_cpu_freq / div; -+} -+ -+static void __init ar71xx_detect_sys_frequency(void) -+{ -+ u32 pll; -+ u32 freq; -+ u32 div; -+ -+ pll = ar71xx_pll_rr(AR71XX_PLL_REG_CPU_CONFIG); -+ -+ div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1; -+ freq = div * AR71XX_BASE_FREQ; -+ -+ div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1; -+ ar71xx_cpu_freq = freq / div; -+ -+ div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1; -+ ar71xx_ddr_freq = freq / div; -+ -+ div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; -+ ar71xx_ahb_freq = ar71xx_cpu_freq / div; -+} -+ -+static void __init detect_sys_frequency(void) -+{ -+ switch (ar71xx_soc) { -+ case AR71XX_SOC_AR7130: -+ case AR71XX_SOC_AR7141: -+ case AR71XX_SOC_AR7161: -+ ar71xx_detect_sys_frequency(); -+ break; -+ -+ case AR71XX_SOC_AR9130: -+ case AR71XX_SOC_AR9132: -+ ar91xx_detect_sys_frequency(); -+ break; -+ -+ default: -+ BUG(); -+ } -+} -+ -+#ifdef CONFIG_AR71XX_EARLY_SERIAL -+static void __init ar71xx_early_serial_setup(void) -+{ -+ struct uart_port p; -+ -+ memset(&p, 0, sizeof(p)); -+ -+ p.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP; -+ p.iotype = UPIO_MEM32; -+ p.uartclk = ar71xx_ahb_freq; -+ p.irq = AR71XX_MISC_IRQ_UART; -+ p.regshift = 2; -+ p.mapbase = AR71XX_UART_BASE; -+ -+ early_serial_setup(&p); -+} -+#else -+static inline void ar71xx_early_serial_setup(void) {}; -+#endif /* CONFIG_AR71XX_EARLY_SERIAL */ -+ -+const char *get_system_type(void) -+{ -+ return ar71xx_sys_type; -+} -+ -+unsigned int __cpuinit get_c0_compare_irq(void) -+{ -+ return CP0_LEGACY_COMPARE_IRQ; -+} -+ -+void __init plat_mem_setup(void) -+{ -+ set_io_port_base(KSEG1); -+ -+ ar71xx_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE, -+ AR71XX_DDR_CTRL_SIZE); -+ -+ ar71xx_pll_base = ioremap_nocache(AR71XX_PLL_BASE, -+ AR71XX_PLL_SIZE); -+ -+ ar71xx_reset_base = ioremap_nocache(AR71XX_RESET_BASE, -+ AR71XX_RESET_SIZE); -+ -+ ar71xx_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); -+ -+ ar71xx_usb_ctrl_base = ioremap_nocache(AR71XX_USB_CTRL_BASE, -+ AR71XX_USB_CTRL_SIZE); -+ -+ ar71xx_detect_mem_size(); -+ ar71xx_detect_sys_type(); -+ detect_sys_frequency(); -+ -+ printk(KERN_INFO -+ "%s, CPU:%u.%03u MHz, AHB:%u.%03u MHz, DDR:%u.%03u MHz\n", -+ ar71xx_sys_type, -+ ar71xx_cpu_freq / 1000000, (ar71xx_cpu_freq / 1000) % 1000, -+ ar71xx_ahb_freq / 1000000, (ar71xx_ahb_freq / 1000) % 1000, -+ ar71xx_ddr_freq / 1000000, (ar71xx_ddr_freq / 1000) % 1000); -+ -+ _machine_restart = ar71xx_restart; -+ _machine_halt = ar71xx_halt; -+ pm_power_off = ar71xx_halt; -+ -+ board_be_handler = ar71xx_be_handler; -+ -+ ar71xx_early_serial_setup(); -+} -+ -+void __init plat_time_init(void) -+{ -+ mips_hpt_frequency = ar71xx_cpu_freq / 2; -+} -+ -+static int __init ar71xx_machine_setup(void) -+{ -+ ar71xx_gpio_init(); -+ -+ ar71xx_add_device_uart(); -+ ar71xx_add_device_wdt(); -+ -+ mips_machine_setup(ar71xx_mach_type); -+ return 0; -+} -+ -+arch_initcall(ar71xx_machine_setup); -diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/fw/myloader/myloader.h linux-2.6.29.1/arch/mips/include/asm/fw/myloader/myloader.h ---- linux-2.6.29.1.orig/arch/mips/include/asm/fw/myloader/myloader.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/include/asm/fw/myloader/myloader.h 2009-04-13 14:27:34.599071210 +0200 -@@ -0,0 +1,34 @@ -+/* -+ * Compex's MyLoader specific definitions -+ * -+ * Copyright (C) 2006-2008 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 _ASM_MIPS_FW_MYLOADER_H -+#define _ASM_MIPS_FW_MYLOADER_H -+ -+#include <linux/myloader.h> -+ -+struct myloader_info { -+ uint32_t vid; -+ uint32_t did; -+ uint32_t svid; -+ uint32_t sdid; -+ uint8_t macs[MYLO_ETHADDR_COUNT][6]; -+}; -+ -+#ifdef CONFIG_MYLOADER -+extern struct myloader_info *myloader_get_info(void) __init; -+#else -+static inline struct myloader_info *myloader_get_info(void) -+{ -+ return NULL; -+} -+#endif /* CONFIG_MYLOADER */ -+ -+#endif /* _ASM_MIPS_FW_MYLOADER_H */ -diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/ar71xx.h ---- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/ar71xx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/ar71xx.h 2009-04-13 14:27:34.623072313 +0200 -@@ -0,0 +1,438 @@ -+/* -+ * Atheros AR71xx SoC specific definitions -+ * -+ * 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 __ASM_MACH_AR71XX_H -+#define __ASM_MACH_AR71XX_H -+ -+#include <linux/types.h> -+#include <linux/init.h> -+#include <linux/io.h> -+#include <linux/bitops.h> -+ -+#ifndef __ASSEMBLER__ -+ -+#define AR71XX_PCI_MEM_BASE 0x10000000 -+#define AR71XX_PCI_MEM_SIZE 0x08000000 -+#define AR71XX_APB_BASE 0x18000000 -+#define AR71XX_GE0_BASE 0x19000000 -+#define AR71XX_GE0_SIZE 0x01000000 -+#define AR71XX_GE1_BASE 0x1a000000 -+#define AR71XX_GE1_SIZE 0x01000000 -+#define AR71XX_EHCI_BASE 0x1b000000 -+#define AR71XX_EHCI_SIZE 0x01000000 -+#define AR71XX_OHCI_BASE 0x1c000000 -+#define AR71XX_OHCI_SIZE 0x01000000 -+#define AR71XX_SPI_BASE 0x1f000000 -+#define AR71XX_SPI_SIZE 0x01000000 -+ -+#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000) -+#define AR71XX_DDR_CTRL_SIZE 0x10000 -+#define AR71XX_CPU_BASE (AR71XX_APB_BASE + 0x00010000) -+#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000) -+#define AR71XX_UART_SIZE 0x10000 -+#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000) -+#define AR71XX_USB_CTRL_SIZE 0x10000 -+#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000) -+#define AR71XX_GPIO_SIZE 0x10000 -+#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000) -+#define AR71XX_PLL_SIZE 0x10000 -+#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000) -+#define AR71XX_RESET_SIZE 0x10000 -+#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000) -+#define AR71XX_MII_SIZE 0x10000 -+#define AR71XX_SLIC_BASE (AR71XX_APB_BASE + 0x00090000) -+#define AR71XX_SLIC_SIZE 0x10000 -+#define AR71XX_DMA_BASE (AR71XX_APB_BASE + 0x000A0000) -+#define AR71XX_DMA_SIZE 0x10000 -+#define AR71XX_STEREO_BASE (AR71XX_APB_BASE + 0x000B0000) -+#define AR71XX_STEREO_SIZE 0x10000 -+#define AR91XX_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000) -+#define AR91XX_WMAC_SIZE 0x30000 -+ -+#define AR71XX_MEM_SIZE_MIN 0x0200000 -+#define AR71XX_MEM_SIZE_MAX 0x8000000 -+ -+#define AR71XX_CPU_IRQ_BASE 0 -+#define AR71XX_MISC_IRQ_BASE 8 -+#define AR71XX_MISC_IRQ_COUNT 8 -+#define AR71XX_GPIO_IRQ_BASE 16 -+#define AR71XX_GPIO_IRQ_COUNT 16 -+#define AR71XX_PCI_IRQ_BASE 32 -+#define AR71XX_PCI_IRQ_COUNT 4 -+ -+#define AR71XX_CPU_IRQ_PCI (AR71XX_CPU_IRQ_BASE + 2) -+#define AR71XX_CPU_IRQ_WMAC (AR71XX_CPU_IRQ_BASE + 2) -+#define AR71XX_CPU_IRQ_USB (AR71XX_CPU_IRQ_BASE + 3) -+#define AR71XX_CPU_IRQ_GE0 (AR71XX_CPU_IRQ_BASE + 4) -+#define AR71XX_CPU_IRQ_GE1 (AR71XX_CPU_IRQ_BASE + 5) -+#define AR71XX_CPU_IRQ_MISC (AR71XX_CPU_IRQ_BASE + 6) -+#define AR71XX_CPU_IRQ_TIMER (AR71XX_CPU_IRQ_BASE + 7) -+ -+#define AR71XX_MISC_IRQ_TIMER (AR71XX_MISC_IRQ_BASE + 0) -+#define AR71XX_MISC_IRQ_ERROR (AR71XX_MISC_IRQ_BASE + 1) -+#define AR71XX_MISC_IRQ_GPIO (AR71XX_MISC_IRQ_BASE + 2) -+#define AR71XX_MISC_IRQ_UART (AR71XX_MISC_IRQ_BASE + 3) -+#define AR71XX_MISC_IRQ_WDOG (AR71XX_MISC_IRQ_BASE + 4) -+#define AR71XX_MISC_IRQ_PERFC (AR71XX_MISC_IRQ_BASE + 5) -+#define AR71XX_MISC_IRQ_OHCI (AR71XX_MISC_IRQ_BASE + 6) -+#define AR71XX_MISC_IRQ_DMA (AR71XX_MISC_IRQ_BASE + 7) -+ -+#define AR71XX_GPIO_IRQ(_x) (AR71XX_GPIO_IRQ_BASE + (_x)) -+ -+#define AR71XX_PCI_IRQ_DEV0 (AR71XX_PCI_IRQ_BASE + 0) -+#define AR71XX_PCI_IRQ_DEV1 (AR71XX_PCI_IRQ_BASE + 1) -+#define AR71XX_PCI_IRQ_DEV2 (AR71XX_PCI_IRQ_BASE + 2) -+#define AR71XX_PCI_IRQ_CORE (AR71XX_PCI_IRQ_BASE + 3) -+ -+extern u32 ar71xx_ahb_freq; -+extern u32 ar71xx_cpu_freq; -+extern u32 ar71xx_ddr_freq; -+ -+enum ar71xx_soc_type { -+ AR71XX_SOC_UNKNOWN, -+ AR71XX_SOC_AR7130, -+ AR71XX_SOC_AR7141, -+ AR71XX_SOC_AR7161, -+ AR71XX_SOC_AR9130, -+ AR71XX_SOC_AR9132 -+}; -+ -+extern enum ar71xx_soc_type ar71xx_soc; -+ -+extern unsigned long ar71xx_mach_type; -+ -+#define AR71XX_MACH_GENERIC 0 -+#define AR71XX_MACH_WP543 1 /* Compex WP543 */ -+#define AR71XX_MACH_RB_411 2 /* MikroTik RouterBOARD 411/411A/411AH */ -+#define AR71XX_MACH_RB_433 3 /* MikroTik RouterBOARD 433/433AH */ -+#define AR71XX_MACH_RB_450 4 /* MikroTik RouterBOARD 450 */ -+#define AR71XX_MACH_RB_493 5 /* Mikrotik RouterBOARD 493/493AH */ -+#define AR71XX_MACH_AW_NR580 6 /* AzureWave AW-NR580 */ -+#define AR71XX_MACH_AP83 7 /* Atheros AP83 */ -+#define AR71XX_MACH_TEW_632BRP 8 /* TRENDnet TEW-632BRP */ -+#define AR71XX_MACH_UBNT_RS 9 /* Ubiquiti RouterStation */ -+#define AR71XX_MACH_UBNT_LSX 10 /* Ubiquiti LSX */ -+#define AR71XX_MACH_WNR2000 11 /* NETGEAR WNR2000 */ -+#define AR71XX_MACH_PB42 12 /* Atheros PB42 */ -+#define AR71XX_MACH_MZK_W300NH 13 /* Planex MZK-W300NH */ -+#define AR71XX_MACH_MZK_W04NU 14 /* Planex MZK-W04NU */ -+#define AR71XX_MACH_UBNT_LSSR71 15 /* Ubiquiti LS-SR71 */ -+#define AR71XX_MACH_TL_WR941ND 16 /* TP-LINK TL-WR941ND */ -+#define AR71XX_MACH_UBNT_RSPRO 17 /* Ubiquiti RouterStation Pro */ -+#define AR71XX_MACH_AP81 18 /* Atheros AP81 */ -+ -+/* -+ * PLL block -+ */ -+#define AR71XX_PLL_REG_CPU_CONFIG 0x00 -+#define AR71XX_PLL_REG_SEC_CONFIG 0x04 -+#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10 -+#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14 -+ -+#define AR71XX_PLL_DIV_SHIFT 3 -+#define AR71XX_PLL_DIV_MASK 0x1f -+#define AR71XX_CPU_DIV_SHIFT 16 -+#define AR71XX_CPU_DIV_MASK 0x3 -+#define AR71XX_DDR_DIV_SHIFT 18 -+#define AR71XX_DDR_DIV_MASK 0x3 -+#define AR71XX_AHB_DIV_SHIFT 20 -+#define AR71XX_AHB_DIV_MASK 0x7 -+ -+#define AR71XX_ETH0_PLL_SHIFT 17 -+#define AR71XX_ETH1_PLL_SHIFT 19 -+ -+#define AR91XX_PLL_REG_CPU_CONFIG 0x00 -+#define AR91XX_PLL_REG_ETH_CONFIG 0x04 -+#define AR91XX_PLL_REG_ETH0_INT_CLOCK 0x14 -+#define AR91XX_PLL_REG_ETH1_INT_CLOCK 0x18 -+ -+#define AR91XX_PLL_DIV_SHIFT 0 -+#define AR91XX_PLL_DIV_MASK 0x3ff -+#define AR91XX_DDR_DIV_SHIFT 22 -+#define AR91XX_DDR_DIV_MASK 0x3 -+#define AR91XX_AHB_DIV_SHIFT 19 -+#define AR91XX_AHB_DIV_MASK 0x1 -+ -+#define AR91XX_ETH0_PLL_SHIFT 20 -+#define AR91XX_ETH1_PLL_SHIFT 22 -+ -+extern void __iomem *ar71xx_pll_base; -+ -+static inline void ar71xx_pll_wr(unsigned reg, u32 val) -+{ -+ __raw_writel(val, ar71xx_pll_base + reg); -+} -+ -+static inline u32 ar71xx_pll_rr(unsigned reg) -+{ -+ return __raw_readl(ar71xx_pll_base + reg); -+} -+ -+/* -+ * USB_CONFIG block -+ */ -+#define USB_CTRL_REG_FLADJ 0x00 -+#define USB_CTRL_REG_CONFIG 0x04 -+ -+extern void __iomem *ar71xx_usb_ctrl_base; -+ -+static inline void ar71xx_usb_ctrl_wr(unsigned reg, u32 val) -+{ -+ __raw_writel(val, ar71xx_usb_ctrl_base + reg); -+} -+ -+static inline u32 ar71xx_usb_ctrl_rr(unsigned reg) -+{ -+ return __raw_readl(ar71xx_usb_ctrl_base + reg); -+} -+ -+/* -+ * GPIO block -+ */ -+#define GPIO_REG_OE 0x00 -+#define GPIO_REG_IN 0x04 -+#define GPIO_REG_OUT 0x08 -+#define GPIO_REG_SET 0x0c -+#define GPIO_REG_CLEAR 0x10 -+#define GPIO_REG_INT_MODE 0x14 -+#define GPIO_REG_INT_TYPE 0x18 -+#define GPIO_REG_INT_POLARITY 0x1c -+#define GPIO_REG_INT_PENDING 0x20 -+#define GPIO_REG_INT_ENABLE 0x24 -+#define GPIO_REG_FUNC 0x28 -+ -+#define GPIO_FUNC_STEREO_EN BIT(17) -+#define GPIO_FUNC_SLIC_EN BIT(16) -+#define GPIO_FUNC_SPI_CS2_EN BIT(13) -+#define GPIO_FUNC_SPI_CS1_EN BIT(12) -+#define GPIO_FUNC_UART_EN BIT(8) -+#define GPIO_FUNC_USB_OC_EN BIT(4) -+#define GPIO_FUNC_USB_CLK_EN BIT(0) -+ -+#define AR71XX_GPIO_COUNT 16 -+#define AR91XX_GPIO_COUNT 22 -+ -+extern void __iomem *ar71xx_gpio_base; -+ -+static inline void ar71xx_gpio_wr(unsigned reg, u32 value) -+{ -+ __raw_writel(value, ar71xx_gpio_base + reg); -+} -+ -+static inline u32 ar71xx_gpio_rr(unsigned reg) -+{ -+ return __raw_readl(ar71xx_gpio_base + reg); -+} -+ -+extern void ar71xx_gpio_init(void) __init; -+extern void ar71xx_gpio_function_enable(u32 mask); -+extern void ar71xx_gpio_function_disable(u32 mask); -+ -+/* -+ * DDR_CTRL block -+ */ -+#define AR71XX_DDR_REG_PCI_WIN0 0x7c -+#define AR71XX_DDR_REG_PCI_WIN1 0x80 -+#define AR71XX_DDR_REG_PCI_WIN2 0x84 -+#define AR71XX_DDR_REG_PCI_WIN3 0x88 -+#define AR71XX_DDR_REG_PCI_WIN4 0x8c -+#define AR71XX_DDR_REG_PCI_WIN5 0x90 -+#define AR71XX_DDR_REG_PCI_WIN6 0x94 -+#define AR71XX_DDR_REG_PCI_WIN7 0x98 -+#define AR71XX_DDR_REG_FLUSH_GE0 0x9c -+#define AR71XX_DDR_REG_FLUSH_GE1 0xa0 -+#define AR71XX_DDR_REG_FLUSH_USB 0xa4 -+#define AR71XX_DDR_REG_FLUSH_PCI 0xa8 -+ -+#define AR91XX_DDR_REG_FLUSH_GE0 0x7c -+#define AR91XX_DDR_REG_FLUSH_GE1 0x80 -+#define AR91XX_DDR_REG_FLUSH_USB 0x84 -+#define AR91XX_DDR_REG_FLUSH_WMAC 0x88 -+ -+#define PCI_WIN0_OFFS 0x10000000 -+#define PCI_WIN1_OFFS 0x11000000 -+#define PCI_WIN2_OFFS 0x12000000 -+#define PCI_WIN3_OFFS 0x13000000 -+#define PCI_WIN4_OFFS 0x14000000 -+#define PCI_WIN5_OFFS 0x15000000 -+#define PCI_WIN6_OFFS 0x16000000 -+#define PCI_WIN7_OFFS 0x07000000 -+ -+extern void __iomem *ar71xx_ddr_base; -+ -+static inline void ar71xx_ddr_wr(unsigned reg, u32 val) -+{ -+ __raw_writel(val, ar71xx_ddr_base + reg); -+} -+ -+static inline u32 ar71xx_ddr_rr(unsigned reg) -+{ -+ return __raw_readl(ar71xx_ddr_base + reg); -+} -+ -+extern void ar71xx_ddr_flush(u32 reg); -+ -+/* -+ * PCI block -+ */ -+#define AR71XX_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + PCI_WIN7_OFFS + 0x10000) -+#define AR71XX_PCI_CFG_SIZE 0x100 -+ -+#define PCI_REG_CRP_AD_CBE 0x00 -+#define PCI_REG_CRP_WRDATA 0x04 -+#define PCI_REG_CRP_RDDATA 0x08 -+#define PCI_REG_CFG_AD 0x0c -+#define PCI_REG_CFG_CBE 0x10 -+#define PCI_REG_CFG_WRDATA 0x14 -+#define PCI_REG_CFG_RDDATA 0x18 -+#define PCI_REG_PCI_ERR 0x1c -+#define PCI_REG_PCI_ERR_ADDR 0x20 -+#define PCI_REG_AHB_ERR 0x24 -+#define PCI_REG_AHB_ERR_ADDR 0x28 -+ -+#define PCI_CRP_CMD_WRITE 0x00010000 -+#define PCI_CRP_CMD_READ 0x00000000 -+#define PCI_CFG_CMD_READ 0x0000000a -+#define PCI_CFG_CMD_WRITE 0x0000000b -+ -+#define PCI_IDSEL_ADL_START 17 -+ -+/* -+ * RESET block -+ */ -+#define AR71XX_RESET_REG_TIMER 0x00 -+#define AR71XX_RESET_REG_TIMER_RELOAD 0x04 -+#define AR71XX_RESET_REG_WDOG_CTRL 0x08 -+#define AR71XX_RESET_REG_WDOG 0x0c -+#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10 -+#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14 -+#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18 -+#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c -+#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20 -+#define AR71XX_RESET_REG_RESET_MODULE 0x24 -+#define AR71XX_RESET_REG_PERFC_CTRL 0x2c -+#define AR71XX_RESET_REG_PERFC0 0x30 -+#define AR71XX_RESET_REG_PERFC1 0x34 -+#define AR71XX_RESET_REG_REV_ID 0x90 -+ -+#define AR91XX_RESET_REG_GLOBAL_INT_STATUS 0x18 -+#define AR91XX_RESET_REG_RESET_MODULE 0x1c -+#define AR91XX_RESET_REG_PERF_CTRL 0x20 -+#define AR91XX_RESET_REG_PERFC0 0x24 -+#define AR91XX_RESET_REG_PERFC1 0x28 -+ -+#define WDOG_CTRL_LAST_RESET BIT(31) -+#define WDOG_CTRL_ACTION_MASK 3 -+#define WDOG_CTRL_ACTION_NONE 0 /* no action */ -+#define WDOG_CTRL_ACTION_GPI 1 /* general purpose interrupt */ -+#define WDOG_CTRL_ACTION_NMI 2 /* NMI */ -+#define WDOG_CTRL_ACTION_FCR 3 /* full chip reset */ -+ -+#define MISC_INT_DMA BIT(7) -+#define MISC_INT_OHCI BIT(6) -+#define MISC_INT_PERFC BIT(5) -+#define MISC_INT_WDOG BIT(4) -+#define MISC_INT_UART BIT(3) -+#define MISC_INT_GPIO BIT(2) -+#define MISC_INT_ERROR BIT(1) -+#define MISC_INT_TIMER BIT(0) -+ -+#define PCI_INT_CORE BIT(4) -+#define PCI_INT_DEV2 BIT(2) -+#define PCI_INT_DEV1 BIT(1) -+#define PCI_INT_DEV0 BIT(0) -+ -+#define RESET_MODULE_EXTERNAL BIT(28) -+#define RESET_MODULE_FULL_CHIP BIT(24) -+#define RESET_MODULE_AMBA2WMAC BIT(22) -+#define RESET_MODULE_CPU_NMI BIT(21) -+#define RESET_MODULE_CPU_COLD BIT(20) -+#define RESET_MODULE_DMA BIT(19) -+#define RESET_MODULE_SLIC BIT(18) -+#define RESET_MODULE_STEREO BIT(17) -+#define RESET_MODULE_DDR BIT(16) -+#define RESET_MODULE_GE1_MAC BIT(13) -+#define RESET_MODULE_GE1_PHY BIT(12) -+#define RESET_MODULE_USBSUS_OVERRIDE BIT(10) -+#define RESET_MODULE_GE0_MAC BIT(9) -+#define RESET_MODULE_GE0_PHY BIT(8) -+#define RESET_MODULE_USB_OHCI_DLL BIT(6) -+#define RESET_MODULE_USB_HOST BIT(5) -+#define RESET_MODULE_USB_PHY BIT(4) -+#define RESET_MODULE_PCI_BUS BIT(1) -+#define RESET_MODULE_PCI_CORE BIT(0) -+ -+#define REV_ID_MASK 0xff -+#define REV_ID_CHIP_MASK 0xf3 -+#define REV_ID_CHIP_AR7130 0xa0 -+#define REV_ID_CHIP_AR7141 0xa1 -+#define REV_ID_CHIP_AR7161 0xa2 -+#define REV_ID_CHIP_AR9130 0xb0 -+#define REV_ID_CHIP_AR9132 0xb1 -+ -+#define REV_ID_REVISION_MASK 0x3 -+#define REV_ID_REVISION_SHIFT 2 -+ -+extern void __iomem *ar71xx_reset_base; -+ -+static inline void ar71xx_reset_wr(unsigned reg, u32 val) -+{ -+ __raw_writel(val, ar71xx_reset_base + reg); -+} -+ -+static inline u32 ar71xx_reset_rr(unsigned reg) -+{ -+ return __raw_readl(ar71xx_reset_base + reg); -+} -+ -+extern void ar71xx_device_stop(u32 mask); -+extern void ar71xx_device_start(u32 mask); -+ -+/* -+ * SPI block -+ */ -+#define SPI_REG_FS 0x00 /* Function Select */ -+#define SPI_REG_CTRL 0x04 /* SPI Control */ -+#define SPI_REG_IOC 0x08 /* SPI I/O Control */ -+#define SPI_REG_RDS 0x0c /* Read Data Shift */ -+ -+#define SPI_FS_GPIO BIT(0) /* Enable GPIO mode */ -+ -+#define SPI_CTRL_RD BIT(6) /* Remap Disable */ -+#define SPI_CTRL_DIV_MASK 0x3f -+ -+#define SPI_IOC_DO BIT(0) /* Data Out pin */ -+#define SPI_IOC_CLK BIT(8) /* CLK pin */ -+#define SPI_IOC_CS(n) BIT(16 + (n)) -+#define SPI_IOC_CS0 SPI_IOC_CS(0) -+#define SPI_IOC_CS1 SPI_IOC_CS(1) -+#define SPI_IOC_CS2 SPI_IOC_CS(2) -+#define SPI_IOC_CS_ALL (SPI_IOC_CS0 | SPI_IOC_CS1 | SPI_IOC_CS2) -+ -+/* -+ * MII_CTRL block -+ */ -+#define MII_REG_MII0_CTRL 0x00 -+#define MII_REG_MII1_CTRL 0x04 -+ -+#define MII0_CTRL_IF_GMII 0 -+#define MII0_CTRL_IF_MII 1 -+#define MII0_CTRL_IF_RGMII 2 -+#define MII0_CTRL_IF_RMII 3 -+ -+#define MII1_CTRL_IF_RGMII 0 -+#define MII1_CTRL_IF_RMII 1 -+ -+#endif /* __ASSEMBLER__ */ -+ -+#endif /* __ASM_MACH_AR71XX_H */ -diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h ---- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/cpu-feature-overrides.h 2009-04-13 14:27:34.627073939 +0200 -@@ -0,0 +1,56 @@ -+/* -+ * Atheros AR71xx specific CPU feature overrides -+ * -+ * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org> -+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> -+ * -+ * This file was derived from: include/asm-mips/cpu-features.h -+ * Copyright (C) 2003, 2004 Ralf Baechle -+ * Copyright (C) 2004 Maciej W. Rozycki -+ * -+ * 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 __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H -+#define __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H -+ -+#define cpu_has_tlb 1 -+#define cpu_has_4kex 1 -+#define cpu_has_3k_cache 0 -+#define cpu_has_4k_cache 1 -+#define cpu_has_tx39_cache 0 -+#define cpu_has_sb1_cache 0 -+#define cpu_has_fpu 0 -+#define cpu_has_32fpr 0 -+#define cpu_has_counter 1 -+#define cpu_has_watch 1 -+#define cpu_has_divec 1 -+ -+#define cpu_has_prefetch 1 -+#define cpu_has_ejtag 1 -+#define cpu_has_llsc 1 -+ -+#define cpu_has_mips16 1 -+#define cpu_has_mdmx 0 -+#define cpu_has_mips3d 0 -+#define cpu_has_smartmips 0 -+ -+#define cpu_has_mips32r1 1 -+#define cpu_has_mips32r2 1 -+#define cpu_has_mips64r1 0 -+#define cpu_has_mips64r2 0 -+ -+#define cpu_has_dsp 0 -+#define cpu_has_mipsmt 0 -+ -+#define cpu_has_64bits 0 -+#define cpu_has_64bit_zero_reg 0 -+#define cpu_has_64bit_gp_regs 0 -+#define cpu_has_64bit_addresses 0 -+ -+#define cpu_dcache_line_size() 32 -+#define cpu_icache_line_size() 32 -+ -+#endif /* __ASM_MACH_AR71XX_CPU_FEATURE_OVERRIDES_H */ -diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/gpio.h linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/gpio.h ---- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/gpio.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/gpio.h 2009-04-13 14:27:34.627073939 +0200 -@@ -0,0 +1,53 @@ -+/* -+ * Atheros AR71xx GPIO API definitions -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef __ASM_MACH_AR71XX_GPIO_H -+#define __ASM_MACH_AR71XX_GPIO_H -+ -+#define ARCH_NR_GPIOS 64 -+#include <asm-generic/gpio.h> -+ -+#include <asm/mach-ar71xx/ar71xx.h> -+ -+extern unsigned long ar71xx_gpio_count; -+extern void __ar71xx_gpio_set_value(unsigned gpio, int value); -+extern int __ar71xx_gpio_get_value(unsigned gpio); -+ -+static inline int gpio_to_irq(unsigned gpio) -+{ -+ return AR71XX_GPIO_IRQ(gpio); -+} -+ -+static inline int irq_to_gpio(unsigned irq) -+{ -+ return irq - AR71XX_GPIO_IRQ_BASE; -+} -+ -+static inline int gpio_get_value(unsigned gpio) -+{ -+ if (gpio < ar71xx_gpio_count) -+ return __ar71xx_gpio_get_value(gpio); -+ -+ return __gpio_get_value(gpio); -+} -+ -+static inline void gpio_set_value(unsigned gpio, int value) -+{ -+ if (gpio < ar71xx_gpio_count) -+ __ar71xx_gpio_set_value(gpio, value); -+ else -+ __gpio_set_value(gpio, value); -+} -+ -+#define gpio_cansleep __gpio_cansleep -+ -+#endif /* __ASM_MACH_AR71XX_GPIO_H */ -diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/irq.h linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/irq.h ---- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/irq.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/irq.h 2009-04-13 14:27:34.643075140 +0200 -@@ -0,0 +1,17 @@ -+/* -+ * 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. -+ */ -+#ifndef __ASM_MACH_AR71XX_IRQ_H -+#define __ASM_MACH_AR71XX_IRQ_H -+ -+#define MIPS_CPU_IRQ_BASE 0 -+#define NR_IRQS 36 -+ -+#include_next <irq.h> -+ -+#endif /* __ASM_MACH_AR71XX_IRQ_H */ -diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h ---- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/kernel-entry-init.h 2009-04-13 14:27:34.643075140 +0200 -@@ -0,0 +1,32 @@ -+/* -+ * Atheros AR71xx specific kernel entry setup -+ * -+ * 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 __ASM_MACH_AR71XX_KERNEL_ENTRY_H -+#define __ASM_MACH_AR71XX_KERNEL_ENTRY_H -+ -+ /* -+ * Some bootloaders set the 'Kseg0 coherency algorithm' to -+ * 'Cacheable, noncoherent, write-through, no write allocate' -+ * and this cause performance issues. Let's go and change it to -+ * 'Cacheable, noncoherent, write-back, write allocate' -+ */ -+ .macro kernel_entry_setup -+ mfc0 t0, CP0_CONFIG -+ li t1, ~CONF_CM_CMASK -+ and t0, t1 -+ ori t0, CONF_CM_CACHABLE_NONCOHERENT -+ mtc0 t0, CP0_CONFIG -+ nop -+ .endm -+ -+ .macro smp_slave_setup -+ .endm -+ -+#endif /* __ASM_MACH_AR71XX_KERNEL_ENTRY_H */ -diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/mangle-port.h ---- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/mangle-port.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/mangle-port.h 2009-04-13 14:27:34.643075140 +0200 -@@ -0,0 +1,45 @@ -+/* -+ * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org> -+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> -+ * -+ * This file was derived from: inlude/asm-mips/mach-generic/mangle-port.h -+ * Copyright (C) 2003, 2004 Ralf Baechle -+ * -+ * 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 __ASM_MACH_AR71XX_MANGLE_PORT_H -+#define __ASM_MACH_AR71XX_MANGLE_PORT_H -+ -+#define __swizzle_addr_b(port) ((port) ^ 3) -+#define __swizzle_addr_w(port) ((port) ^ 2) -+#define __swizzle_addr_l(port) (port) -+#define __swizzle_addr_q(port) (port) -+ -+#if defined(CONFIG_SWAP_IO_SPACE) -+ -+# define ioswabb(a, x) (x) -+# define __mem_ioswabb(a, x) (x) -+# define ioswabw(a, x) le16_to_cpu(x) -+# define __mem_ioswabw(a, x) (x) -+# define ioswabl(a, x) le32_to_cpu(x) -+# define __mem_ioswabl(a, x) (x) -+# define ioswabq(a, x) le64_to_cpu(x) -+# define __mem_ioswabq(a, x) (x) -+ -+#else -+ -+# define ioswabb(a, x) (x) -+# define __mem_ioswabb(a, x) (x) -+# define ioswabw(a, x) (x) -+# define __mem_ioswabw(a, x) cpu_to_le16(x) -+# define ioswabl(a, x) (x) -+# define __mem_ioswabl(a, x) cpu_to_le32(x) -+# define ioswabq(a, x) (x) -+# define __mem_ioswabq(a, x) cpu_to_le64(x) -+ -+#endif -+ -+#endif /* __ASM_MACH_AR71XX_MANGLE_PORT_H */ -diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/pci.h linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/pci.h ---- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/pci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/pci.h 2009-04-13 14:27:34.647074532 +0200 -@@ -0,0 +1,28 @@ -+/* -+ * Atheros AR71xx SoC specific PCI definitions -+ * -+ * 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. -+ */ -+ -+#ifndef __ASM_MACH_AR71XX_PCI_H -+#define __ASM_MACH_AR71XX_PCI_H -+ -+struct ar71xx_pci_irq { -+ int irq; -+ u8 slot; -+ u8 pin; -+}; -+ -+extern int (*ar71xx_pci_be_handler)(int is_fixup); -+extern int (*ar71xx_pci_bios_init)(unsigned nr_irqs, -+ struct ar71xx_pci_irq *map) __initdata; -+ -+extern int ar71xx_pci_init(unsigned nr_irqs, -+ struct ar71xx_pci_irq *map) __init; -+ -+#endif /* __ASM_MACH_AR71XX_PCI_H */ -diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/platform.h linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/platform.h ---- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/platform.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/platform.h 2009-04-13 14:27:34.647074532 +0200 -@@ -0,0 +1,54 @@ -+/* -+ * Atheros AR71xx SoC specific platform data 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 __ASM_MACH_AR71XX_PLATFORM_H -+#define __ASM_MACH_AR71XX_PLATFORM_H -+ -+#include <linux/if_ether.h> -+#include <linux/skbuff.h> -+#include <linux/phy.h> -+#include <linux/spi/spi.h> -+ -+struct ag71xx_platform_data { -+ phy_interface_t phy_if_mode; -+ u32 phy_mask; -+ int speed; -+ int duplex; -+ u32 reset_bit; -+ u32 mii_if; -+ u8 mac_addr[ETH_ALEN]; -+ -+ u8 has_gbit:1; -+ u8 is_ar91xx:1; -+ u8 has_ar8216:1; -+ -+ void (* ddr_flush)(void); -+ void (* set_pll)(u32 pll); -+}; -+ -+struct ag71xx_mdio_platform_data { -+ u32 phy_mask; -+}; -+ -+struct ar71xx_ehci_platform_data { -+ u8 is_ar91xx; -+}; -+ -+struct ar71xx_spi_platform_data { -+ unsigned bus_num; -+ unsigned num_chipselect; -+ u32 (*get_ioc_base)(u8 chip_select, int cs_high, int is_on); -+}; -+ -+#define AR71XX_SPI_CS_INACTIVE 0 -+#define AR71XX_SPI_CS_ACTIVE 1 -+ -+#endif /* __ASM_MACH_AR71XX_PLATFORM_H */ -diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/war.h linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/war.h ---- linux-2.6.29.1.orig/arch/mips/include/asm/mach-ar71xx/war.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/include/asm/mach-ar71xx/war.h 2009-04-13 14:27:34.647074532 +0200 -@@ -0,0 +1,25 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> -+ */ -+#ifndef __ASM_MACH_AR71XX_WAR_H -+#define __ASM_MACH_AR71XX_WAR_H -+ -+#define R4600_V1_INDEX_ICACHEOP_WAR 0 -+#define R4600_V1_HIT_CACHEOP_WAR 0 -+#define R4600_V2_HIT_CACHEOP_WAR 0 -+#define R5432_CP0_INTERRUPT_WAR 0 -+#define BCM1250_M3_WAR 0 -+#define SIBYTE_1956_WAR 0 -+#define MIPS4K_ICACHE_REFILL_WAR 0 -+#define MIPS_CACHE_SYNC_WAR 0 -+#define TX49XX_ICACHE_INDEX_INV_WAR 0 -+#define RM9000_CDEX_SMP_WAR 0 -+#define ICACHE_REFILLS_WORKAROUND_WAR 0 -+#define R10000_LLSC_WAR 0 -+#define MIPS34K_MISSED_ITLB_WAR 0 -+ -+#endif /* __ASM_MACH_AR71XX_WAR_H */ -diff -Nur linux-2.6.29.1.orig/arch/mips/include/asm/time.h linux-2.6.29.1/arch/mips/include/asm/time.h ---- linux-2.6.29.1.orig/arch/mips/include/asm/time.h 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/arch/mips/include/asm/time.h 2009-04-13 14:30:23.269613602 +0200 -@@ -52,6 +52,7 @@ - */ - #ifdef CONFIG_CEVT_R4K_LIB - extern unsigned int __weak get_c0_compare_int(void); -+extern unsigned int __weak get_c0_compare_irq(void); - extern int r4k_clockevent_init(void); - #endif - -diff -Nur linux-2.6.29.1.orig/arch/mips/kernel/Makefile linux-2.6.29.1/arch/mips/kernel/Makefile ---- linux-2.6.29.1.orig/arch/mips/kernel/Makefile 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/arch/mips/kernel/Makefile 2009-04-13 14:27:34.655074992 +0200 -@@ -85,6 +85,7 @@ - - obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o - obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -+obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o - - CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi) - -diff -Nur linux-2.6.29.1.orig/arch/mips/kernel/cevt-r4k.c linux-2.6.29.1/arch/mips/kernel/cevt-r4k.c ---- linux-2.6.29.1.orig/arch/mips/kernel/cevt-r4k.c 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/arch/mips/kernel/cevt-r4k.c 2009-04-13 14:27:34.655074992 +0200 -@@ -15,6 +15,22 @@ - #include <asm/cevt-r4k.h> - - /* -+ * Compare interrupt can be routed and latched outside the core, -+ * so a single execution hazard barrier may not be enough to give -+ * it time to clear as seen in the Cause register. 4 time the -+ * pipeline depth seems reasonably conservative, and empirically -+ * works better in configurations with high CPU/bus clock ratios. -+ */ -+ -+#define compare_change_hazard() \ -+ do { \ -+ irq_disable_hazard(); \ -+ irq_disable_hazard(); \ -+ irq_disable_hazard(); \ -+ irq_disable_hazard(); \ -+ } while (0) -+ -+/* - * The SMTC Kernel for the 34K, 1004K, et. al. replaces several - * of these routines with SMTC-specific variants. - */ -@@ -30,6 +46,7 @@ - cnt = read_c0_count(); - cnt += delta; - write_c0_compare(cnt); -+ compare_change_hazard(); - res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0; - return res; - } -@@ -99,22 +116,6 @@ - return (read_c0_cause() >> cp0_compare_irq) & 0x100; - } - --/* -- * Compare interrupt can be routed and latched outside the core, -- * so a single execution hazard barrier may not be enough to give -- * it time to clear as seen in the Cause register. 4 time the -- * pipeline depth seems reasonably conservative, and empirically -- * works better in configurations with high CPU/bus clock ratios. -- */ -- --#define compare_change_hazard() \ -- do { \ -- irq_disable_hazard(); \ -- irq_disable_hazard(); \ -- irq_disable_hazard(); \ -- irq_disable_hazard(); \ -- } while (0) -- - int c0_compare_int_usable(void) - { - unsigned int delta; -diff -Nur linux-2.6.29.1.orig/arch/mips/kernel/mips_machine.c linux-2.6.29.1/arch/mips/kernel/mips_machine.c ---- linux-2.6.29.1.orig/arch/mips/kernel/mips_machine.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/kernel/mips_machine.c 2009-04-13 14:27:34.683076044 +0200 -@@ -0,0 +1,58 @@ -+/* -+ * Copyright (C) 2008 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 <asm/mips_machine.h> -+#include <asm/bootinfo.h> -+ -+static struct list_head mips_machines __initdata = -+ LIST_HEAD_INIT(mips_machines); -+ -+unsigned char mips_machine_name[MIPS_MACHINE_NAME_LEN] = "Unknown"; -+ -+static struct mips_machine * __init mips_machine_find(unsigned long machtype) -+{ -+ struct list_head *this; -+ -+ list_for_each(this, &mips_machines) { -+ struct mips_machine *mach; -+ -+ mach = list_entry(this, struct mips_machine, list); -+ if (mach->mach_type == machtype) -+ return mach; -+ } -+ -+ return NULL; -+} -+ -+void __init mips_machine_register(struct mips_machine *mach) -+{ -+ list_add_tail(&mach->list, &mips_machines); -+} -+ -+void __init mips_machine_setup(unsigned long machtype) -+{ -+ struct mips_machine *mach; -+ -+ mach = mips_machine_find(machtype); -+ if (!mach) { -+ printk(KERN_ALERT "MIPS: no machine registered for " -+ "machtype %lu\n", machtype); -+ return; -+ } -+ -+ if (mach->mach_name[0]) -+ strncpy(mips_machine_name, mach->mach_name, -+ MIPS_MACHINE_NAME_LEN); -+ -+ printk(KERN_INFO "MIPS: machine is %s\n", mips_machine_name); -+ -+ if (mach->mach_setup) -+ mach->mach_setup(); -+} -+ -diff -Nur linux-2.6.29.1.orig/arch/mips/kernel/proc.c linux-2.6.29.1/arch/mips/kernel/proc.c ---- linux-2.6.29.1.orig/arch/mips/kernel/proc.c 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/arch/mips/kernel/proc.c 2009-04-13 14:27:34.683076044 +0200 -@@ -14,6 +14,7 @@ - #include <asm/cpu-features.h> - #include <asm/mipsregs.h> - #include <asm/processor.h> -+#include <asm/mips_machine.h> - - unsigned int vced_count, vcei_count; - -@@ -33,8 +34,12 @@ - /* - * For the first processor also print the system type - */ -- if (n == 0) -+ if (n == 0) { - seq_printf(m, "system type\t\t: %s\n", get_system_type()); -+#ifdef CONFIG_MIPS_MACHINE -+ seq_printf(m, "machine\t\t\t: %s\n", mips_machine_name); -+#endif -+ } - - seq_printf(m, "processor\t\t: %ld\n", n); - sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n", -diff -Nur linux-2.6.29.1.orig/arch/mips/kernel/traps.c linux-2.6.29.1/arch/mips/kernel/traps.c ---- linux-2.6.29.1.orig/arch/mips/kernel/traps.c 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/arch/mips/kernel/traps.c 2009-04-13 14:29:45.479250639 +0200 -@@ -47,6 +47,7 @@ - #include <asm/mmu_context.h> - #include <asm/types.h> - #include <asm/stacktrace.h> -+#include <asm/time.h> - #include <asm/irq.h> - - extern void check_wait(void); -@@ -1541,6 +1542,8 @@ - */ - if (cpu_has_mips_r2) { - cp0_compare_irq = (read_c0_intctl() >> 29) & 7; -+ if (get_c0_compare_irq) -+ cp0_compare_irq = get_c0_compare_irq(); - cp0_perfcount_irq = (read_c0_intctl() >> 26) & 7; - if (cp0_perfcount_irq == cp0_compare_irq) - cp0_perfcount_irq = -1; -diff -Nur linux-2.6.29.1.orig/arch/mips/pci/Makefile linux-2.6.29.1/arch/mips/pci/Makefile ---- linux-2.6.29.1.orig/arch/mips/pci/Makefile 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/arch/mips/pci/Makefile 2009-04-13 14:27:34.691076784 +0200 -@@ -16,6 +16,7 @@ - obj-$(CONFIG_NEC_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o - obj-$(CONFIG_PCI_TX4927) += ops-tx4927.o - obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o -+obj-$(CONFIG_ATHEROS_AR71XX) += pci-ar71xx.o - - # - # These are still pretty much in the old state, watch, go blind. -diff -Nur linux-2.6.29.1.orig/arch/mips/pci/pci-ar71xx.c linux-2.6.29.1/arch/mips/pci/pci-ar71xx.c ---- linux-2.6.29.1.orig/arch/mips/pci/pci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/arch/mips/pci/pci-ar71xx.c 2009-04-13 14:27:34.695077573 +0200 -@@ -0,0 +1,347 @@ -+/* -+ * Atheros AR71xx PCI host controller driver -+ * -+ * 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/resource.h> -+#include <linux/types.h> -+#include <linux/delay.h> -+#include <linux/bitops.h> -+#include <linux/pci.h> -+#include <linux/pci_regs.h> -+ -+#include <asm/mach-ar71xx/ar71xx.h> -+#include <asm/mach-ar71xx/pci.h> -+ -+#undef DEBUG -+#ifdef DEBUG -+#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args) -+#else -+#define DBG(fmt, args...) -+#endif -+ -+#define AR71XX_PCI_DELAY 100 /* msecs */ -+ -+#if 0 -+#define PCI_IDSEL_BASE PCI_IDSEL_ADL_START -+#else -+#define PCI_IDSEL_BASE 0 -+#endif -+ -+static unsigned ar71xx_pci_nr_irqs; -+static struct ar71xx_pci_irq *ar71xx_pci_irq_map __initdata; -+static void __iomem *ar71xx_pcicfg_base; -+ -+static DEFINE_SPINLOCK(ar71xx_pci_lock); -+ -+static inline void ar71xx_pci_delay(void) -+{ -+ mdelay(AR71XX_PCI_DELAY); -+} -+ -+static inline u32 ar71xx_pcicfg_rr(unsigned int reg) -+{ -+ return __raw_readl(ar71xx_pcicfg_base + reg); -+} -+ -+static inline void ar71xx_pcicfg_wr(unsigned int reg, u32 val) -+{ -+ __raw_writel(val, ar71xx_pcicfg_base + reg); -+} -+ -+/* Byte lane enable bits */ -+static u8 ble_table[4][4] = { -+ {0x0, 0xf, 0xf, 0xf}, -+ {0xe, 0xd, 0xb, 0x7}, -+ {0xc, 0xf, 0x3, 0xf}, -+ {0xf, 0xf, 0xf, 0xf}, -+}; -+ -+static inline u32 ar71xx_pci_get_ble(int where, int size, int local) -+{ -+ u32 t; -+ -+ t = ble_table[size & 3][where & 3]; -+ BUG_ON(t == 0xf); -+ t <<= (local) ? 20 : 4; -+ return t; -+} -+ -+static inline u32 ar71xx_pci_bus_addr(struct pci_bus *bus, unsigned int devfn, -+ int where) -+{ -+ u32 ret; -+ -+ if (!bus->number) { -+ /* type 0 */ -+ ret = (1 << (PCI_IDSEL_BASE + PCI_SLOT(devfn))) -+ | (PCI_FUNC(devfn) << 8) | (where & ~3); -+ } else { -+ /* type 1 */ -+ ret = (bus->number << 16) | (PCI_SLOT(devfn) << 11) -+ | (PCI_FUNC(devfn) << 8) | (where & ~3) | 1; -+ } -+ -+ return ret; -+} -+ -+static int __ar71xx_pci_be_handler(int is_fixup) -+{ -+ u32 pci_err; -+ u32 ahb_err; -+ -+ pci_err = ar71xx_pcicfg_rr(PCI_REG_PCI_ERR) & 3; -+ if (pci_err) { -+ if (!is_fixup) -+ printk(KERN_ALERT "PCI error %d at PCI addr 0x%x\n", -+ pci_err, -+ ar71xx_pcicfg_rr(PCI_REG_PCI_ERR_ADDR)); -+ -+ ar71xx_pcicfg_wr(PCI_REG_PCI_ERR, pci_err); -+ } -+ -+ ahb_err = ar71xx_pcicfg_rr(PCI_REG_AHB_ERR) & 1; -+ if (ahb_err) { -+ if (!is_fixup) -+ printk(KERN_ALERT "AHB error at AHB address 0x%x\n", -+ ar71xx_pcicfg_rr(PCI_REG_AHB_ERR_ADDR)); -+ -+ ar71xx_pcicfg_wr(PCI_REG_AHB_ERR, ahb_err); -+ } -+ -+ return ((ahb_err | pci_err) ? 1 : 0); -+} -+ -+static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus, -+ unsigned int devfn, int where, int size, u32 cmd) -+{ -+ u32 addr; -+ -+ addr = ar71xx_pci_bus_addr(bus, devfn, where); -+ -+ DBG("PCI: set cfgaddr: %02x:%02x.%01x/%02x:%01d, addr=%08x\n", -+ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), -+ where, size, addr); -+ -+ ar71xx_pcicfg_wr(PCI_REG_CFG_AD, addr); -+ ar71xx_pcicfg_wr(PCI_REG_CFG_CBE, -+ cmd | ar71xx_pci_get_ble(where, size, 0)); -+ -+ return __ar71xx_pci_be_handler(1); -+} -+ -+static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 *value) -+{ -+ static u32 mask[8] = {0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0}; -+ unsigned long flags; -+ u32 data; -+ int ret; -+ -+ ret = PCIBIOS_SUCCESSFUL; -+ -+ DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d\n", bus->number, -+ PCI_SLOT(devfn), PCI_FUNC(devfn), where, size); -+ -+ spin_lock_irqsave(&ar71xx_pci_lock, flags); -+ -+ if (bus->number == 0 && devfn == 0) { -+ u32 t; -+ -+ t = PCI_CRP_CMD_READ | (where & ~3); -+ -+ ar71xx_pcicfg_wr(PCI_REG_CRP_AD_CBE, t); -+ data = ar71xx_pcicfg_rr(PCI_REG_CRP_RDDATA); -+ -+ DBG("PCI: rd local cfg, ad_cbe:%08x, data:%08x\n", t, data); -+ -+ } else { -+ int err; -+ -+ err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, -+ PCI_CFG_CMD_READ); -+ -+ if (err == 0) { -+ data = ar71xx_pcicfg_rr(PCI_REG_CFG_RDDATA); -+ } else { -+ ret = PCIBIOS_DEVICE_NOT_FOUND; -+ data = ~0; -+ } -+ } -+ -+ spin_unlock_irqrestore(&ar71xx_pci_lock, flags); -+ -+ DBG("PCI: read config: data=%08x raw=%08x\n", -+ (data >> (8 * (where & 3))) & mask[size & 7], data); -+ -+ *value = (data >> (8 * (where & 3))) & mask[size & 7]; -+ -+ return ret; -+} -+ -+static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 value) -+{ -+ unsigned long flags; -+ int ret; -+ -+ DBG("PCI: write config: %02x:%02x.%01x/%02x:%01d value=%08x\n", -+ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), -+ where, size, value); -+ -+ value = value << (8 * (where & 3)); -+ ret = PCIBIOS_SUCCESSFUL; -+ -+ spin_lock_irqsave(&ar71xx_pci_lock, flags); -+ if (bus->number == 0 && devfn == 0) { -+ u32 t; -+ -+ t = PCI_CRP_CMD_WRITE | (where & ~3); -+ t |= ar71xx_pci_get_ble(where, size, 1); -+ -+ DBG("PCI: wr local cfg, ad_cbe:%08x, value:%08x\n", t, value); -+ -+ ar71xx_pcicfg_wr(PCI_REG_CRP_AD_CBE, t); -+ ar71xx_pcicfg_wr(PCI_REG_CRP_WRDATA, value); -+ } else { -+ int err; -+ -+ err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, -+ PCI_CFG_CMD_WRITE); -+ -+ if (err == 0) -+ ar71xx_pcicfg_wr(PCI_REG_CFG_WRDATA, value); -+ else -+ ret = PCIBIOS_DEVICE_NOT_FOUND; -+ } -+ spin_unlock_irqrestore(&ar71xx_pci_lock, flags); -+ -+ return ret; -+} -+ -+static void ar71xx_pci_fixup(struct pci_dev *dev) -+{ -+ u32 t; -+ -+ if (dev->bus->number != 0 || dev->devfn != 0) -+ return; -+ -+ DBG("PCI: fixup host controller %s (%04x:%04x)\n", pci_name(dev), -+ dev->vendor, dev->device); -+ -+ /* setup COMMAND register */ -+ t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE -+ | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK; -+ -+ pci_write_config_word(dev, PCI_COMMAND, t); -+} -+ -+DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ar71xx_pci_fixup); -+ -+int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) -+{ -+ int irq = -1; -+ int i; -+ -+ slot -= PCI_IDSEL_ADL_START - PCI_IDSEL_BASE; -+ -+ for (i = 0; i < ar71xx_pci_nr_irqs; i++) { -+ struct ar71xx_pci_irq *entry; -+ -+ entry = &ar71xx_pci_irq_map[i]; -+ if (entry->slot == slot && entry->pin == pin) { -+ irq = entry->irq; -+ break; -+ } -+ } -+ -+ if (irq < 0) { -+ printk(KERN_ALERT "PCI: no irq found for pin%u@%s\n", -+ pin, pci_name((struct pci_dev *)dev)); -+ } else { -+ printk(KERN_INFO "PCI: mapping irq %d to pin%u@%s\n", -+ irq, pin, pci_name((struct pci_dev *)dev)); -+ } -+ -+ return irq; -+} -+ -+int pcibios_plat_dev_init(struct pci_dev *dev) -+{ -+ return 0; -+} -+ -+static struct pci_ops ar71xx_pci_ops = { -+ .read = ar71xx_pci_read_config, -+ .write = ar71xx_pci_write_config, -+}; -+ -+static struct resource ar71xx_pci_io_resource = { -+ .name = "PCI IO space", -+ .start = 0, -+ .end = 0, -+ .flags = IORESOURCE_IO, -+}; -+ -+static struct resource ar71xx_pci_mem_resource = { -+ .name = "PCI memory space", -+ .start = AR71XX_PCI_MEM_BASE, -+ .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1, -+ .flags = IORESOURCE_MEM -+}; -+ -+static struct pci_controller ar71xx_pci_controller = { -+ .pci_ops = &ar71xx_pci_ops, -+ .mem_resource = &ar71xx_pci_mem_resource, -+ .io_resource = &ar71xx_pci_io_resource, -+}; -+ -+static int __init __ar71xx_pci_bios_init(unsigned nr_irqs, -+ struct ar71xx_pci_irq *map) -+{ -+ ar71xx_device_stop(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE); -+ ar71xx_pci_delay(); -+ -+ ar71xx_device_start(RESET_MODULE_PCI_BUS | RESET_MODULE_PCI_CORE); -+ ar71xx_pci_delay(); -+ -+ ar71xx_pcicfg_base = ioremap_nocache(AR71XX_PCI_CFG_BASE, -+ AR71XX_PCI_CFG_SIZE); -+ -+ ar71xx_ddr_wr(AR71XX_DDR_REG_PCI_WIN0, PCI_WIN0_OFFS); -+ ar71xx_ddr_wr(AR71XX_DDR_REG_PCI_WIN1, PCI_WIN1_OFFS); -+ ar71xx_ddr_wr(AR71XX_DDR_REG_PCI_WIN2, PCI_WIN2_OFFS); -+ ar71xx_ddr_wr(AR71XX_DDR_REG_PCI_WIN3, PCI_WIN3_OFFS); -+ ar71xx_ddr_wr(AR71XX_DDR_REG_PCI_WIN4, PCI_WIN4_OFFS); -+ ar71xx_ddr_wr(AR71XX_DDR_REG_PCI_WIN5, PCI_WIN5_OFFS); -+ ar71xx_ddr_wr(AR71XX_DDR_REG_PCI_WIN6, PCI_WIN6_OFFS); -+ ar71xx_ddr_wr(AR71XX_DDR_REG_PCI_WIN7, PCI_WIN7_OFFS); -+ -+ ar71xx_pci_delay(); -+ -+ /* clear bus errors */ -+ (void)__ar71xx_pci_be_handler(1); -+ -+ ar71xx_pci_nr_irqs = nr_irqs; -+ ar71xx_pci_irq_map = map; -+ ar71xx_pci_be_handler = __ar71xx_pci_be_handler; -+ -+ register_pci_controller(&ar71xx_pci_controller); -+ -+ return 0; -+} -+ -+static int __init __ar71xx_pci_init(void) -+{ -+ ar71xx_pci_bios_init = __ar71xx_pci_bios_init; -+ return 0; -+} -+pure_initcall(__ar71xx_pci_init); -diff -Nur linux-2.6.29.1.orig/drivers/input/misc/Kconfig linux-2.6.29.1/drivers/input/misc/Kconfig ---- linux-2.6.29.1.orig/drivers/input/misc/Kconfig 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/input/misc/Kconfig 2009-04-13 14:27:34.723078345 +0200 -@@ -227,4 +227,20 @@ - Say Y to include support for delivering PMU events via input - layer on NXP PCF50633. - -+config INPUT_GPIO_BUTTONS -+ tristate "Polled GPIO buttons interface" -+ depends on GENERIC_GPIO -+ select INPUT_POLLDEV -+ help -+ This driver implements support for buttons connected -+ to GPIO pins of various CPUs (and some other chips). -+ -+ Say Y here if your device has buttons connected -+ directly to such GPIO pins. Your board-specific -+ setup logic must also provide a platform device, -+ with configuration data saying which GPIOs are used. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called gpio-buttons. -+ - endif -diff -Nur linux-2.6.29.1.orig/drivers/input/misc/Makefile linux-2.6.29.1/drivers/input/misc/Makefile ---- linux-2.6.29.1.orig/drivers/input/misc/Makefile 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/input/misc/Makefile 2009-04-13 14:29:03.564632184 +0200 -@@ -22,3 +22,4 @@ - obj-$(CONFIG_INPUT_APANEL) += apanel.o - obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o - obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o -+obj-$(CONFIG_INPUT_GPIO_BUTTONS) += gpio_buttons.o -diff -Nur linux-2.6.29.1.orig/drivers/input/misc/gpio_buttons.c linux-2.6.29.1/drivers/input/misc/gpio_buttons.c ---- linux-2.6.29.1.orig/drivers/input/misc/gpio_buttons.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/input/misc/gpio_buttons.c 2009-04-13 14:27:34.727079413 +0200 -@@ -0,0 +1,209 @@ -+/* -+ * Driver for buttons on GPIO lines not capable of generating interrupts -+ * -+ * Copyright (C) 2007,2008 Gabor Juhos <juhosg at openwrt.org> -+ * -+ * This file was based on: /drivers/input/misc/cobalt_btns.c -+ * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> -+ * -+ * also was based on: /drivers/input/keyboard/gpio_keys.c -+ * Copyright 2005 Phil Blundell -+ * -+ * 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/init.h> -+ -+#include <linux/input.h> -+#include <linux/input-polldev.h> -+#include <linux/ioport.h> -+#include <linux/platform_device.h> -+ -+#include <linux/gpio_buttons.h> -+ -+#include <asm/gpio.h> -+ -+#define DRV_NAME "gpio-buttons" -+#define DRV_VERSION "0.1.1" -+#define PFX DRV_NAME ": " -+ -+struct gpio_buttons_dev { -+ struct input_polled_dev *poll_dev; -+ struct gpio_buttons_platform_data *pdata; -+}; -+ -+static void gpio_buttons_poll(struct input_polled_dev *dev) -+{ -+ struct gpio_buttons_dev *bdev = dev->private; -+ struct gpio_buttons_platform_data *pdata = bdev->pdata; -+ struct input_dev *input = dev->input; -+ int i; -+ -+ for (i = 0; i < bdev->pdata->nbuttons; i++) { -+ struct gpio_button *button = &pdata->buttons[i]; -+ unsigned int type = button->type ?: EV_KEY; -+ int state; -+ -+ state = gpio_get_value(button->gpio) ? 1 : 0; -+ state ^= button->active_low; -+ -+ if (state) { -+ button->count++; -+ } else { -+ if (button->count >= button->threshold) { -+ input_event(input, type, button->code, 1); -+ input_sync(input); -+ } -+ button->count = 0; -+ } -+ -+ if (button->count == button->threshold) { -+ input_event(input, type, button->code, 0); -+ input_sync(input); -+ } -+ } -+} -+ -+static int __devinit gpio_buttons_probe(struct platform_device *pdev) -+{ -+ struct gpio_buttons_platform_data *pdata = pdev->dev.platform_data; -+ struct gpio_buttons_dev *bdev; -+ struct input_polled_dev *poll_dev; -+ struct input_dev *input; -+ int error, i; -+ -+ -+ if (!pdata) -+ return -ENXIO; -+ -+ bdev = kzalloc(sizeof(*bdev), GFP_KERNEL); -+ if (!bdev) { -+ printk(KERN_ERR DRV_NAME "no memory for device\n"); -+ return -ENOMEM; -+ } -+ -+ poll_dev = input_allocate_polled_device(); -+ if (!poll_dev) { -+ printk(KERN_ERR DRV_NAME "no memory for polled device\n"); -+ error = -ENOMEM; -+ goto err_free_bdev; -+ } -+ -+ poll_dev->private = bdev; -+ poll_dev->poll = gpio_buttons_poll; -+ poll_dev->poll_interval = pdata->poll_interval; -+ -+ input = poll_dev->input; -+ -+ input->evbit[0] = BIT(EV_KEY); -+ input->name = pdev->name; -+ input->phys = "gpio-buttons/input0"; -+ input->dev.parent = &pdev->dev; -+ -+ input->id.bustype = BUS_HOST; -+ input->id.vendor = 0x0001; -+ input->id.product = 0x0001; -+ input->id.version = 0x0100; -+ -+ for (i = 0; i < pdata->nbuttons; i++) { -+ struct gpio_button *button = &pdata->buttons[i]; -+ unsigned int gpio = button->gpio; -+ unsigned int type = button->type ?: EV_KEY; -+ -+ error = gpio_request(gpio, button->desc ? -+ button->desc : DRV_NAME); -+ if (error) { -+ printk(KERN_ERR PFX "unable to claim gpio %u, " -+ "error %d\n", gpio, error); -+ goto err_free_gpio; -+ } -+ -+ error = gpio_direction_input(gpio); -+ if (error) { -+ printk(KERN_ERR PFX "unable to set direction on " -+ "gpio %u, error %d\n", gpio, error); -+ goto err_free_gpio; -+ } -+ -+ input_set_capability(input, type, button->code); -+ button->count = 0; -+ } -+ -+ bdev->poll_dev = poll_dev; -+ bdev->pdata = pdata; -+ platform_set_drvdata(pdev, bdev); -+ -+ error = input_register_polled_device(poll_dev); -+ if (error) { -+ printk(KERN_ERR PFX "unable to register polled device, " -+ "error %d\n", error); -+ goto err_free_gpio; -+ } -+ -+ return 0; -+ -+err_free_gpio: -+ for (i = i - 1; i >= 0; i--) -+ gpio_free(pdata->buttons[i].gpio); -+ -+ input_free_polled_device(poll_dev); -+ -+err_free_bdev: -+ kfree(bdev); -+ -+ platform_set_drvdata(pdev, NULL); -+ return error; -+} -+ -+static int __devexit gpio_buttons_remove(struct platform_device *pdev) -+{ -+ struct gpio_buttons_dev *bdev = platform_get_drvdata(pdev); -+ struct gpio_buttons_platform_data *pdata = bdev->pdata; -+ int i; -+ -+ input_unregister_polled_device(bdev->poll_dev); -+ -+ for (i = 0; i < pdata->nbuttons; i++) -+ gpio_free(pdata->buttons[i].gpio); -+ -+ input_free_polled_device(bdev->poll_dev); -+ -+ kfree(bdev); -+ platform_set_drvdata(pdev, NULL); -+ -+ return 0; -+} -+ -+static struct platform_driver gpio_buttons_driver = { -+ .probe = gpio_buttons_probe, -+ .remove = __devexit_p(gpio_buttons_remove), -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init gpio_buttons_init(void) -+{ -+ printk(KERN_INFO DRV_NAME " driver version " DRV_VERSION "\n"); -+ return platform_driver_register(&gpio_buttons_driver); -+} -+ -+static void __exit gpio_buttons_exit(void) -+{ -+ platform_driver_unregister(&gpio_buttons_driver); -+} -+ -+module_init(gpio_buttons_init); -+module_exit(gpio_buttons_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Gabor Juhos <juhosg at openwrt.org>"); -+MODULE_VERSION(DRV_VERSION); -+MODULE_DESCRIPTION("Polled buttons driver for CPU GPIOs"); -+ -diff -Nur linux-2.6.29.1.orig/drivers/mtd/nand/Kconfig linux-2.6.29.1/drivers/mtd/nand/Kconfig ---- linux-2.6.29.1.orig/drivers/mtd/nand/Kconfig 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/mtd/nand/Kconfig 2009-04-13 14:27:34.731079923 +0200 -@@ -427,4 +427,8 @@ - Several Renesas SuperH CPU has FLCTL. This option enables support - for NAND Flash using FLCTL. This driver support SH7723. - -+config MTD_NAND_RB4XX -+ tristate "NAND flash driver for RouterBoard 4xx series" -+ depends on MTD_NAND && ATHEROS_AR71XX -+ - endif # MTD_NAND -diff -Nur linux-2.6.29.1.orig/drivers/mtd/nand/Makefile linux-2.6.29.1/drivers/mtd/nand/Makefile ---- linux-2.6.29.1.orig/drivers/mtd/nand/Makefile 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/mtd/nand/Makefile 2009-04-13 14:27:34.731079923 +0200 -@@ -29,6 +29,7 @@ - obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o - obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o - obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o -+obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o - obj-$(CONFIG_MTD_ALAUDA) += alauda.o - obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o - obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o -diff -Nur linux-2.6.29.1.orig/drivers/mtd/nand/rb4xx_nand.c linux-2.6.29.1/drivers/mtd/nand/rb4xx_nand.c ---- linux-2.6.29.1.orig/drivers/mtd/nand/rb4xx_nand.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/mtd/nand/rb4xx_nand.c 2009-04-13 14:27:34.735080153 +0200 -@@ -0,0 +1,507 @@ -+/* -+ * NAND flash driver for the MikroTik RouterBoard 4xx series -+ * -+ * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org> -+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> -+ * -+ * This file was based on the driver for Linux 2.6.22 published by -+ * MikroTik for their RouterBoard 4xx series devices. -+ * -+ * 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/mtd/nand.h> -+#include <linux/mtd/mtd.h> -+#include <linux/mtd/partitions.h> -+#include <linux/platform_device.h> -+#include <linux/delay.h> -+#include <linux/io.h> -+#include <linux/gpio.h> -+ -+#include <asm/mach-ar71xx/ar71xx.h> -+ -+#define DRV_NAME "rb4xx-nand" -+#define DRV_VERSION "0.1.10" -+#define DRV_DESC "NAND flash driver for RouterBoard 4xx series" -+ -+#define USE_FAST_READ 1 -+#define USE_FAST_WRITE 1 -+#undef RB4XX_NAND_DEBUG -+ -+#ifdef RB4XX_NAND_DEBUG -+#define DBG(fmt, arg...) printk(KERN_DEBUG DRV_NAME ": " fmt, ## arg) -+#else -+#define DBG(fmt, arg...) do {} while (0) -+#endif -+ -+#define RB4XX_NAND_GPIO_RDY 5 -+#define RB4XX_FLASH_HZ 33333334 -+#define RB4XX_NAND_HZ 33333334 -+ -+#define SPI_CTRL_FASTEST 0x40 -+#define SPI_CTRL_SAFE 0x43 /* 25 MHz for AHB 200 MHz */ -+#define SBIT_IOC_BASE SPI_IOC_CS1 -+#define SBIT_IOC_DO_SHIFT 0 -+#define SBIT_IOC_DO (1u << SBIT_IOC_DO_SHIFT) -+#define SBIT_IOC_DO2_SHIFT 18 -+#define SBIT_IOC_DO2 (1u << SBIT_IOC_DO2_SHIFT) -+ -+#define CPLD_CMD_WRITE_MULT 0x08 /* send cmd, n x send data, read data */ -+#define CPLD_CMD_WRITE_CFG 0x09 /* send cmd, n x send cfg */ -+#define CPLD_CMD_READ_MULT 0x0a /* send cmd, send idle, n x read data */ -+#define CPLD_CMD_READ_FAST 0x0b /* send cmd, 4 x idle, n x read data */ -+ -+#define CFG_BIT_nCE 0x80 -+#define CFG_BIT_CLE 0x40 -+#define CFG_BIT_ALE 0x20 -+#define CFG_BIT_FAN 0x10 -+#define CFG_BIT_nLED4 0x08 -+#define CFG_BIT_nLED3 0x04 -+#define CFG_BIT_nLED2 0x02 -+#define CFG_BIT_nLED1 0x01 -+ -+#define CFG_BIT_nLEDS \ -+ (CFG_BIT_nLED1 | CFG_BIT_nLED2 | CFG_BIT_nLED3 | CFG_BIT_nLED4) -+ -+struct rb4xx_nand_info { -+ struct nand_chip chip; -+ struct mtd_info mtd; -+}; -+ -+/* -+ * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader -+ * will not be able to find the kernel that we load. -+ */ -+static struct nand_ecclayout rb4xx_nand_ecclayout = { -+ .eccbytes = 6, -+ .eccpos = { 8, 9, 10, 13, 14, 15 }, -+ .oobavail = 9, -+ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } -+}; -+ -+static struct mtd_partition rb4xx_nand_partitions[] = { -+ { -+ .name = "booter", -+ .offset = 0, -+ .size = (256 * 1024), -+ .mask_flags = MTD_WRITEABLE, -+ }, -+ { -+ .name = "kernel", -+ .offset = (256 * 1024), -+ .size = (4 * 1024 * 1024) - (256 * 1024), -+ }, -+ { -+ .name = "rootfs", -+ .offset = MTDPART_OFS_NXTBLK, -+ .size = MTDPART_SIZ_FULL, -+ }, -+}; -+ -+#if USE_FAST_READ -+#define SPI_NDATA_BASE 0x00800000 -+static unsigned spi_ctrl_fread = SPI_CTRL_SAFE; -+static unsigned spi_ctrl_flash = SPI_CTRL_SAFE; -+extern unsigned mips_hpt_frequency; -+#endif -+ -+static inline unsigned rb4xx_spi_rreg(unsigned r) -+{ -+ return __raw_readl((void * __iomem)(KSEG1ADDR(AR71XX_SPI_BASE) + r)); -+} -+ -+static inline void rb4xx_spi_wreg(unsigned r, unsigned v) -+{ -+ __raw_writel(v, (void * __iomem)(KSEG1ADDR(AR71XX_SPI_BASE) + r)); -+} -+ -+static inline void do_spi_clk(int bit) -+{ -+ unsigned bval = SBIT_IOC_BASE | (bit & 1); -+ -+ rb4xx_spi_wreg(SPI_REG_IOC, bval); -+ rb4xx_spi_wreg(SPI_REG_IOC, bval | SPI_IOC_CLK); -+} -+ -+static void do_spi_byte(uint8_t byte) -+{ -+ do_spi_clk(byte >> 7); -+ do_spi_clk(byte >> 6); -+ do_spi_clk(byte >> 5); -+ do_spi_clk(byte >> 4); -+ do_spi_clk(byte >> 3); -+ do_spi_clk(byte >> 2); -+ do_spi_clk(byte >> 1); -+ do_spi_clk(byte); -+ -+ DBG("spi_byte sent 0x%02x got 0x%x\n", -+ byte, rb4xx_spi_rreg(SPI_REG_RDS)); -+} -+ -+#if USE_FAST_WRITE -+static inline void do_spi_clk_fast(int bit1, int bit2) -+{ -+ unsigned bval = (SBIT_IOC_BASE | -+ ((bit1 << SBIT_IOC_DO_SHIFT) & SBIT_IOC_DO) | -+ ((bit2 << SBIT_IOC_DO2_SHIFT) & SBIT_IOC_DO2)); -+ -+ rb4xx_spi_wreg(SPI_REG_IOC, bval); -+ rb4xx_spi_wreg(SPI_REG_IOC, bval | SPI_IOC_CLK); -+} -+ -+static inline void do_spi_byte_fast(uint8_t byte) -+{ -+ do_spi_clk_fast(byte >> 7, byte >> 6); -+ do_spi_clk_fast(byte >> 5, byte >> 4); -+ do_spi_clk_fast(byte >> 3, byte >> 2); -+ do_spi_clk_fast(byte >> 1, byte >> 0); -+ -+ DBG("spi_byte_fast sent 0x%02x got 0x%x\n", -+ byte, rb4xx_spi_rreg(SPI_REG_RDS)); -+} -+#else -+static inline void do_spi_byte_fast(uint8_t byte) -+{ -+ do_spi_byte(byte); -+} -+#endif /* USE_FAST_WRITE */ -+ -+static int do_spi_cmd(unsigned cmd, unsigned sendCnt, const uint8_t *sendData, -+ unsigned recvCnt, uint8_t *recvData, -+ const uint8_t *verifyData, int fastWrite) -+{ -+ unsigned i; -+ -+ DBG("SPI cmd 0x%x send %u recv %u\n", cmd, sendCnt, recvCnt); -+ -+ rb4xx_spi_wreg(SPI_REG_FS, SPI_FS_GPIO); -+ rb4xx_spi_wreg(SPI_REG_CTRL, SPI_CTRL_FASTEST); -+ -+ do_spi_byte(cmd); -+#if 0 -+ if (cmd == CPLD_CMD_READ_FAST) { -+ do_spi_byte(0x80); -+ do_spi_byte(0); -+ do_spi_byte(0); -+ } -+#endif -+ for (i = 0; i < sendCnt; ++i) { -+ if (fastWrite) -+ do_spi_byte_fast(sendData[i]); -+ else -+ do_spi_byte(sendData[i]); -+ } -+ -+ for (i = 0; i < recvCnt; ++i) { -+ if (fastWrite) -+ do_spi_byte_fast(0); -+ else -+ do_spi_byte(0); -+ -+ if (recvData) { -+ recvData[i] = rb4xx_spi_rreg(SPI_REG_RDS) & 0xff; -+ } else if (verifyData) { -+ if (verifyData[i] != (rb4xx_spi_rreg(SPI_REG_RDS) -+ & 0xff)) -+ break; -+ } -+ } -+ -+ rb4xx_spi_wreg(SPI_REG_IOC, SBIT_IOC_BASE | SPI_IOC_CS0); -+ rb4xx_spi_wreg(SPI_REG_CTRL, spi_ctrl_flash); -+ rb4xx_spi_wreg(SPI_REG_FS, 0); -+ -+ return i == recvCnt; -+} -+ -+static int got_write = 1; -+ -+static void rb4xx_nand_write_data(const uint8_t *byte, unsigned cnt) -+{ -+ do_spi_cmd(CPLD_CMD_WRITE_MULT, cnt, byte, 1, NULL, NULL, 1); -+ got_write = 1; -+} -+ -+static void rb4xx_nand_write_byte(uint8_t byte) -+{ -+ rb4xx_nand_write_data(&byte, 1); -+} -+ -+#if USE_FAST_READ -+static uint8_t *rb4xx_nand_read_getaddr(unsigned cnt) -+{ -+ static unsigned nboffset = 0x100000; -+ unsigned addr; -+ -+ if (got_write) { -+ nboffset = (nboffset + 31) & ~31; -+ if (nboffset >= 0x100000) /* 1MB */ -+ nboffset = 0; -+ -+ got_write = 0; -+ rb4xx_spi_wreg(SPI_REG_FS, SPI_FS_GPIO); -+ rb4xx_spi_wreg(SPI_REG_CTRL, spi_ctrl_fread); -+ rb4xx_spi_wreg(SPI_REG_FS, 0); -+ } -+ -+ addr = KSEG1ADDR(AR71XX_SPI_BASE + SPI_NDATA_BASE) + nboffset; -+ DBG("rb4xx_nand_read_getaddr 0x%x cnt 0x%x\n", addr, cnt); -+ -+ nboffset += cnt; -+ return (uint8_t *)addr; -+} -+ -+static void rb4xx_nand_read_data(uint8_t *buf, unsigned cnt) -+{ -+ unsigned size32 = cnt & ~31; -+ unsigned remain = cnt & 31; -+ -+ if (size32) { -+ uint8_t *addr = rb4xx_nand_read_getaddr(size32); -+ memcpy(buf, (void *)addr, size32); -+ } -+ -+ if (remain) { -+ do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, remain, -+ buf + size32, NULL, 0); -+ } -+} -+ -+static int rb4xx_nand_verify_data(const uint8_t *buf, unsigned cnt) -+{ -+ unsigned size32 = cnt & ~31; -+ unsigned remain = cnt & 31; -+ -+ if (size32) { -+ uint8_t *addr = rb4xx_nand_read_getaddr(size32); -+ if (memcmp(buf, (void *)addr, size32) != 0) -+ return 0; -+ } -+ -+ if (remain) { -+ return do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, remain, -+ NULL, buf + size32, 0); -+ } -+ return 1; -+} -+#else /* USE_FAST_READ */ -+static void rb4xx_nand_read_data(uint8_t *buf, unsigned cnt) -+{ -+ do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, cnt, buf, NULL, 0); -+} -+ -+static int rb4xx_nand_verify_data(const uint8_t *buf, unsigned cnt) -+{ -+ return do_spi_cmd(CPLD_CMD_READ_MULT, 1, buf, cnt, NULL, buf, 0); -+} -+#endif /* USE_FAST_READ */ -+ -+static void rb4xx_nand_write_cfg(uint8_t byte) -+{ -+ do_spi_cmd(CPLD_CMD_WRITE_CFG, 1, &byte, 0, NULL, NULL, 0); -+ got_write = 1; -+} -+ -+static int rb4xx_nand_dev_ready(struct mtd_info *mtd) -+{ -+ return gpio_get_value(RB4XX_NAND_GPIO_RDY); -+} -+ -+static void rb4xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, -+ unsigned int ctrl) -+{ -+ if (ctrl & NAND_CTRL_CHANGE) { -+ uint8_t cfg = CFG_BIT_nLEDS; -+ -+ cfg |= (ctrl & NAND_CLE) ? CFG_BIT_CLE : 0; -+ cfg |= (ctrl & NAND_ALE) ? CFG_BIT_ALE : 0; -+ cfg |= (ctrl & NAND_NCE) ? 0 : CFG_BIT_nCE; -+ -+ rb4xx_nand_write_cfg(cfg); -+ } -+ -+ if (cmd != NAND_CMD_NONE) -+ rb4xx_nand_write_byte(cmd); -+} -+ -+static uint8_t rb4xx_nand_read_byte(struct mtd_info *mtd) -+{ -+ uint8_t byte = 0; -+ -+ rb4xx_nand_read_data(&byte, 1); -+ return byte; -+} -+ -+static void rb4xx_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, -+ int len) -+{ -+ rb4xx_nand_write_data(buf, len); -+} -+ -+static void rb4xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, -+ int len) -+{ -+ rb4xx_nand_read_data(buf, len); -+} -+ -+static int rb4xx_nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, -+ int len) -+{ -+ if (!rb4xx_nand_verify_data(buf, len)) -+ return -EFAULT; -+ -+ return 0; -+} -+ -+static unsigned get_spi_ctrl(unsigned hz_max, const char *name) -+{ -+ unsigned div; -+ -+ div = (ar71xx_ahb_freq - 1) / (2 * hz_max); -+ /* -+ * CPU has a bug at (div == 0) - first bit read is random -+ */ -+ if (div == 0) -+ ++div; -+ -+ if (name) { -+ unsigned ahb_khz = (ar71xx_ahb_freq + 500) / 1000; -+ unsigned div_real = 2 * (div + 1); -+ printk(KERN_INFO "%s SPI clock %u kHz (AHB %u kHz / %u)\n", -+ name, -+ ahb_khz / div_real, -+ ahb_khz, div_real); -+ } -+ -+ return SPI_CTRL_FASTEST + div; -+} -+ -+static int __init rb4xx_nand_probe(struct platform_device *pdev) -+{ -+ struct rb4xx_nand_info *info; -+ int ret; -+ -+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); -+ -+ ret = gpio_request(RB4XX_NAND_GPIO_RDY, "NAND RDY"); -+ if (ret) { -+ printk(KERN_ERR "rb4xx-nand: gpio request failed\n"); -+ return ret; -+ } -+ -+ ret = gpio_direction_input(RB4XX_NAND_GPIO_RDY); -+ if (ret) { -+ printk(KERN_ERR "rb4xx-nand: unable to set input mode " -+ "on gpio%d\n", RB4XX_NAND_GPIO_RDY); -+ goto err_free_gpio; -+ } -+ -+ info = kzalloc(sizeof(*info), GFP_KERNEL); -+ if (!info) { -+ printk(KERN_ERR "rb4xx-nand: no memory for private data\n"); -+ ret = -ENOMEM; -+ goto err_free_gpio; -+ } -+ -+#if USE_FAST_READ -+ spi_ctrl_fread = get_spi_ctrl(RB4XX_NAND_HZ, "NAND"); -+#endif -+ spi_ctrl_flash = get_spi_ctrl(RB4XX_FLASH_HZ, "FLASH"); -+ -+ rb4xx_nand_write_cfg(CFG_BIT_nLEDS | CFG_BIT_nCE); -+ -+ info->chip.priv = &info; -+ info->mtd.priv = &info->chip; -+ info->mtd.owner = THIS_MODULE; -+ -+ info->chip.cmd_ctrl = rb4xx_nand_cmd_ctrl; -+ info->chip.dev_ready = rb4xx_nand_dev_ready; -+ info->chip.read_byte = rb4xx_nand_read_byte; -+ info->chip.write_buf = rb4xx_nand_write_buf; -+ info->chip.read_buf = rb4xx_nand_read_buf; -+ info->chip.verify_buf = rb4xx_nand_verify_buf; -+ -+ info->chip.chip_delay = 25; -+ info->chip.ecc.mode = NAND_ECC_SOFT; -+ info->chip.options |= NAND_NO_AUTOINCR; -+ -+ platform_set_drvdata(pdev, info); -+ -+ ret = nand_scan_ident(&info->mtd, 1); -+ if (ret) { -+ ret = -ENXIO; -+ goto err_free_info; -+ } -+ -+ if (info->mtd.writesize == 512) -+ info->chip.ecc.layout = &rb4xx_nand_ecclayout; -+ -+ ret = nand_scan_tail(&info->mtd); -+ if (ret) { -+ return -ENXIO; -+ goto err_set_drvdata; -+ } -+ -+#ifdef CONFIG_MTD_PARTITIONS -+ ret = add_mtd_partitions(&info->mtd, rb4xx_nand_partitions, -+ ARRAY_SIZE(rb4xx_nand_partitions)); -+#else -+ ret = add_mtd_device(&info->mtd); -+#endif -+ if (ret) -+ goto err_release_nand; -+ -+ return 0; -+ -+err_release_nand: -+ nand_release(&info->mtd); -+err_set_drvdata: -+ platform_set_drvdata(pdev, NULL); -+err_free_info: -+ kfree(info); -+err_free_gpio: -+ gpio_free(RB4XX_NAND_GPIO_RDY); -+ return ret; -+} -+ -+static int __devexit rb4xx_nand_remove(struct platform_device *pdev) -+{ -+ struct rb4xx_nand_info *info = platform_get_drvdata(pdev); -+ -+ nand_release(&info->mtd); -+ platform_set_drvdata(pdev, NULL); -+ kfree(info); -+ -+ return 0; -+} -+ -+static struct platform_driver rb4xx_nand_driver = { -+ .probe = rb4xx_nand_probe, -+ .remove = __devexit_p(rb4xx_nand_remove), -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init rb4xx_nand_init(void) -+{ -+ return platform_driver_register(&rb4xx_nand_driver); -+} -+ -+static void __exit rb4xx_nand_exit(void) -+{ -+ platform_driver_unregister(&rb4xx_nand_driver); -+} -+ -+module_init(rb4xx_nand_init); -+module_exit(rb4xx_nand_exit); -+ -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); -+MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>"); -+MODULE_LICENSE("GPL v2"); -diff -Nur linux-2.6.29.1.orig/drivers/net/Kconfig linux-2.6.29.1/drivers/net/Kconfig ---- linux-2.6.29.1.orig/drivers/net/Kconfig 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/net/Kconfig 2009-04-13 14:27:34.763080366 +0200 -@@ -1945,6 +1945,8 @@ - - The safe and default value for this is N. - -+source drivers/net/ag71xx/Kconfig -+ - config DL2K - tristate "DL2000/TC902x-based Gigabit Ethernet support" - depends on PCI -diff -Nur linux-2.6.29.1.orig/drivers/net/Makefile linux-2.6.29.1/drivers/net/Makefile ---- linux-2.6.29.1.orig/drivers/net/Makefile 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/net/Makefile 2009-04-13 14:27:34.767081713 +0200 -@@ -2,6 +2,7 @@ - # Makefile for the Linux network (ethercard) device drivers. - # - -+obj-$(CONFIG_AG71XX) += ag71xx/ - obj-$(CONFIG_E1000) += e1000/ - obj-$(CONFIG_E1000E) += e1000e/ - obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/ -diff -Nur linux-2.6.29.1.orig/drivers/net/ag71xx/Kconfig linux-2.6.29.1/drivers/net/ag71xx/Kconfig ---- linux-2.6.29.1.orig/drivers/net/ag71xx/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/net/ag71xx/Kconfig 2009-04-13 14:27:34.767081713 +0200 -@@ -0,0 +1,23 @@ -+config AG71XX -+ tristate "Atheros AR71xx built-in ethernet mac support" -+ depends on ATHEROS_AR71XX -+ select PHYLIB -+ help -+ If you wish to compile a kernel for AR71xx/91xx and enable -+ ethernet support, then you should always answer Y to this. -+ -+config AG71XX_DEBUG -+ bool "Atheros AR71xx built-in ethernet driver debugging" -+ depends on AG71XX -+ default n -+ help -+ Atheros AR71xx built-in ethernet driver debugging messages. -+ -+config AG71XX_AR8216_SUPPORT -+ bool "special support for the Atheros AR8216 switch" -+ depends on AG71XX -+ default n -+ default y if AR71XX_MACH_WNR2000 || AR71XX_MACH_MZK_W04NU -+ help -+ Say 'y' here if you want to enable special support for the -+ Atheros AR8216 switch found on some boards. -diff -Nur linux-2.6.29.1.orig/drivers/net/ag71xx/Makefile linux-2.6.29.1/drivers/net/ag71xx/Makefile ---- linux-2.6.29.1.orig/drivers/net/ag71xx/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/net/ag71xx/Makefile 2009-04-13 14:27:34.771082502 +0200 -@@ -0,0 +1,13 @@ -+# -+# Makefile for the Atheros AR71xx built-in ethernet macs -+# -+ -+ag71xx-y += ag71xx_main.o -+ag71xx-y += ag71xx_ethtool.o -+ag71xx-y += ag71xx_phy.o -+ag71xx-y += ag71xx_mdio.o -+ -+ag71xx-$(CONFIG_AG71XX_AR8216_SUPPORT) += ag71xx_ar8216.o -+ -+obj-$(CONFIG_AG71XX) += ag71xx.o -+ -diff -Nur linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx.h linux-2.6.29.1/drivers/net/ag71xx/ag71xx.h ---- linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/net/ag71xx/ag71xx.h 2009-04-13 14:27:34.799084111 +0200 -@@ -0,0 +1,449 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org> -+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * 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 __AG71XX_H -+#define __AG71XX_H -+ -+#include <linux/kernel.h> -+#include <linux/version.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/types.h> -+#include <linux/random.h> -+#include <linux/spinlock.h> -+#include <linux/interrupt.h> -+#include <linux/platform_device.h> -+#include <linux/ethtool.h> -+#include <linux/etherdevice.h> -+#include <linux/phy.h> -+#include <linux/skbuff.h> -+#include <linux/dma-mapping.h> -+#include <linux/workqueue.h> -+ -+#include <linux/bitops.h> -+ -+#include <asm/mach-ar71xx/ar71xx.h> -+#include <asm/mach-ar71xx/platform.h> -+ -+#define ETH_FCS_LEN 4 -+ -+#define AG71XX_DRV_NAME "ag71xx" -+#define AG71XX_DRV_VERSION "0.5.21" -+ -+#define AG71XX_NAPI_WEIGHT 64 -+#define AG71XX_OOM_REFILL (1 + HZ/10) -+ -+#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE) -+#define AG71XX_INT_TX (AG71XX_INT_TX_PS) -+#define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF) -+ -+#define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX) -+#define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL) -+ -+#define AG71XX_TX_FIFO_LEN 2048 -+#define AG71XX_TX_MTU_LEN 1536 -+#define AG71XX_RX_PKT_RESERVE 64 -+#define AG71XX_RX_PKT_SIZE \ -+ (AG71XX_RX_PKT_RESERVE + ETH_HLEN + ETH_FRAME_LEN + ETH_FCS_LEN) -+ -+#define AG71XX_TX_RING_SIZE 64 -+#define AG71XX_TX_THRES_STOP (AG71XX_TX_RING_SIZE - 4) -+#define AG71XX_TX_THRES_WAKEUP \ -+ (AG71XX_TX_RING_SIZE - (AG71XX_TX_RING_SIZE / 4)) -+ -+#define AG71XX_RX_RING_SIZE 128 -+ -+#ifdef CONFIG_AG71XX_DEBUG -+#define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args) -+#else -+#define DBG(fmt, args...) do {} while (0) -+#endif -+ -+#define ag71xx_assert(_cond) \ -+do { \ -+ if (_cond) \ -+ break; \ -+ printk("%s,%d: assertion failed\n", __FILE__, __LINE__); \ -+ BUG(); \ -+} while (0) -+ -+struct ag71xx_desc { -+ u32 data; -+ u32 ctrl; -+#define DESC_EMPTY BIT(31) -+#define DESC_MORE BIT(24) -+#define DESC_PKTLEN_M 0x1fff -+ u32 next; -+ u32 pad; -+}; -+ -+struct ag71xx_buf { -+ struct sk_buff *skb; -+}; -+ -+struct ag71xx_ring { -+ struct ag71xx_buf *buf; -+ struct ag71xx_desc *descs; -+ dma_addr_t descs_dma; -+ unsigned int curr; -+ unsigned int dirty; -+ unsigned int size; -+}; -+ -+struct ag71xx_mdio { -+ struct mii_bus *mii_bus; -+ int mii_irq[PHY_MAX_ADDR]; -+ void __iomem *mdio_base; -+}; -+ -+struct ag71xx { -+ void __iomem *mac_base; -+ void __iomem *mac_base2; -+ void __iomem *mii_ctrl; -+ -+ spinlock_t lock; -+ struct platform_device *pdev; -+ struct net_device *dev; -+ struct napi_struct napi; -+ u32 msg_enable; -+ -+ struct ag71xx_ring rx_ring; -+ struct ag71xx_ring tx_ring; -+ -+ struct mii_bus *mii_bus; -+ struct phy_device *phy_dev; -+ -+ unsigned int link; -+ unsigned int speed; -+ int duplex; -+ -+ struct work_struct restart_work; -+ struct timer_list oom_timer; -+}; -+ -+extern struct ethtool_ops ag71xx_ethtool_ops; -+ -+extern struct ag71xx_mdio *ag71xx_mdio_bus; -+extern int ag71xx_mdio_driver_init(void) __init; -+extern void ag71xx_mdio_driver_exit(void); -+ -+extern int ag71xx_phy_connect(struct ag71xx *ag); -+extern void ag71xx_phy_disconnect(struct ag71xx *ag); -+extern void ag71xx_phy_start(struct ag71xx *ag); -+extern void ag71xx_phy_stop(struct ag71xx *ag); -+ -+static inline struct ag71xx_platform_data *ag71xx_get_pdata(struct ag71xx *ag) -+{ -+ return ag->pdev->dev.platform_data; -+} -+ -+static inline int ag71xx_desc_empty(struct ag71xx_desc *desc) -+{ -+ return ((desc->ctrl & DESC_EMPTY) != 0); -+} -+ -+static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc) -+{ -+ return (desc->ctrl & DESC_PKTLEN_M); -+} -+ -+/* Register offsets */ -+#define AG71XX_REG_MAC_CFG1 0x0000 -+#define AG71XX_REG_MAC_CFG2 0x0004 -+#define AG71XX_REG_MAC_IPG 0x0008 -+#define AG71XX_REG_MAC_HDX 0x000c -+#define AG71XX_REG_MAC_MFL 0x0010 -+#define AG71XX_REG_MII_CFG 0x0020 -+#define AG71XX_REG_MII_CMD 0x0024 -+#define AG71XX_REG_MII_ADDR 0x0028 -+#define AG71XX_REG_MII_CTRL 0x002c -+#define AG71XX_REG_MII_STATUS 0x0030 -+#define AG71XX_REG_MII_IND 0x0034 -+#define AG71XX_REG_MAC_IFCTL 0x0038 -+#define AG71XX_REG_MAC_ADDR1 0x0040 -+#define AG71XX_REG_MAC_ADDR2 0x0044 -+#define AG71XX_REG_FIFO_CFG0 0x0048 -+#define AG71XX_REG_FIFO_CFG1 0x004c -+#define AG71XX_REG_FIFO_CFG2 0x0050 -+#define AG71XX_REG_FIFO_CFG3 0x0054 -+#define AG71XX_REG_FIFO_CFG4 0x0058 -+#define AG71XX_REG_FIFO_CFG5 0x005c -+#define AG71XX_REG_FIFO_RAM0 0x0060 -+#define AG71XX_REG_FIFO_RAM1 0x0064 -+#define AG71XX_REG_FIFO_RAM2 0x0068 -+#define AG71XX_REG_FIFO_RAM3 0x006c -+#define AG71XX_REG_FIFO_RAM4 0x0070 -+#define AG71XX_REG_FIFO_RAM5 0x0074 -+#define AG71XX_REG_FIFO_RAM6 0x0078 -+#define AG71XX_REG_FIFO_RAM7 0x007c -+ -+#define AG71XX_REG_TX_CTRL 0x0180 -+#define AG71XX_REG_TX_DESC 0x0184 -+#define AG71XX_REG_TX_STATUS 0x0188 -+#define AG71XX_REG_RX_CTRL 0x018c -+#define AG71XX_REG_RX_DESC 0x0190 -+#define AG71XX_REG_RX_STATUS 0x0194 -+#define AG71XX_REG_INT_ENABLE 0x0198 -+#define AG71XX_REG_INT_STATUS 0x019c -+ -+#define MAC_CFG1_TXE BIT(0) /* Tx Enable */ -+#define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */ -+#define MAC_CFG1_RXE BIT(2) /* Rx Enable */ -+#define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */ -+#define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */ -+#define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */ -+#define MAC_CFG1_LB BIT(8) /* Loopback mode */ -+#define MAC_CFG1_SR BIT(31) /* Soft Reset */ -+ -+#define MAC_CFG2_FDX BIT(0) -+#define MAC_CFG2_CRC_EN BIT(1) -+#define MAC_CFG2_PAD_CRC_EN BIT(2) -+#define MAC_CFG2_LEN_CHECK BIT(4) -+#define MAC_CFG2_HUGE_FRAME_EN BIT(5) -+#define MAC_CFG2_IF_1000 BIT(9) -+#define MAC_CFG2_IF_10_100 BIT(8) -+ -+#define FIFO_CFG0_WTM BIT(0) /* Watermark Module */ -+#define FIFO_CFG0_RXS BIT(1) /* Rx System Module */ -+#define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */ -+#define FIFO_CFG0_TXS BIT(3) /* Tx System Module */ -+#define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */ -+#define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \ -+ | FIFO_CFG0_TXS | FIFO_CFG0_TXF) -+ -+#define FIFO_CFG0_ENABLE_SHIFT 8 -+ -+#define FIFO_CFG4_DE BIT(0) /* Drop Event */ -+#define FIFO_CFG4_DV BIT(1) /* RX_DV Event */ -+#define FIFO_CFG4_FC BIT(2) /* False Carrier */ -+#define FIFO_CFG4_CE BIT(3) /* Code Error */ -+#define FIFO_CFG4_CR BIT(4) /* CRC error */ -+#define FIFO_CFG4_LM BIT(5) /* Length Mismatch */ -+#define FIFO_CFG4_LO BIT(6) /* Length out of range */ -+#define FIFO_CFG4_OK BIT(7) /* Packet is OK */ -+#define FIFO_CFG4_MC BIT(8) /* Multicast Packet */ -+#define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */ -+#define FIFO_CFG4_DR BIT(10) /* Dribble */ -+#define FIFO_CFG4_LE BIT(11) /* Long Event */ -+#define FIFO_CFG4_CF BIT(12) /* Control Frame */ -+#define FIFO_CFG4_PF BIT(13) /* Pause Frame */ -+#define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */ -+#define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */ -+#define FIFO_CFG4_FT BIT(16) /* Frame Truncated */ -+#define FIFO_CFG4_UC BIT(17) /* Unicast Packet */ -+ -+#define FIFO_CFG5_DE BIT(0) /* Drop Event */ -+#define FIFO_CFG5_DV BIT(1) /* RX_DV Event */ -+#define FIFO_CFG5_FC BIT(2) /* False Carrier */ -+#define FIFO_CFG5_CE BIT(3) /* Code Error */ -+#define FIFO_CFG5_LM BIT(4) /* Length Mismatch */ -+#define FIFO_CFG5_LO BIT(5) /* Length Out of Range */ -+#define FIFO_CFG5_OK BIT(6) /* Packet is OK */ -+#define FIFO_CFG5_MC BIT(7) /* Multicast Packet */ -+#define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */ -+#define FIFO_CFG5_DR BIT(9) /* Dribble */ -+#define FIFO_CFG5_CF BIT(10) /* Control Frame */ -+#define FIFO_CFG5_PF BIT(11) /* Pause Frame */ -+#define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */ -+#define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */ -+#define FIFO_CFG5_LE BIT(14) /* Long Event */ -+#define FIFO_CFG5_FT BIT(15) /* Frame Truncated */ -+#define FIFO_CFG5_16 BIT(16) /* unknown */ -+#define FIFO_CFG5_17 BIT(17) /* unknown */ -+#define FIFO_CFG5_SF BIT(18) /* Short Frame */ -+#define FIFO_CFG5_BM BIT(19) /* Byte Mode */ -+ -+#define AG71XX_INT_TX_PS BIT(0) -+#define AG71XX_INT_TX_UR BIT(1) -+#define AG71XX_INT_TX_BE BIT(3) -+#define AG71XX_INT_RX_PR BIT(4) -+#define AG71XX_INT_RX_OF BIT(6) -+#define AG71XX_INT_RX_BE BIT(7) -+ -+#define MAC_IFCTL_SPEED BIT(16) -+ -+#define MII_CFG_CLK_DIV_4 0 -+#define MII_CFG_CLK_DIV_6 2 -+#define MII_CFG_CLK_DIV_8 3 -+#define MII_CFG_CLK_DIV_10 4 -+#define MII_CFG_CLK_DIV_14 5 -+#define MII_CFG_CLK_DIV_20 6 -+#define MII_CFG_CLK_DIV_28 7 -+#define MII_CFG_RESET BIT(31) -+ -+#define MII_CMD_WRITE 0x0 -+#define MII_CMD_READ 0x1 -+#define MII_ADDR_SHIFT 8 -+#define MII_IND_BUSY BIT(0) -+#define MII_IND_INVALID BIT(2) -+ -+#define TX_CTRL_TXE BIT(0) /* Tx Enable */ -+ -+#define TX_STATUS_PS BIT(0) /* Packet Sent */ -+#define TX_STATUS_UR BIT(1) /* Tx Underrun */ -+#define TX_STATUS_BE BIT(3) /* Bus Error */ -+ -+#define RX_CTRL_RXE BIT(0) /* Rx Enable */ -+ -+#define RX_STATUS_PR BIT(0) /* Packet Received */ -+#define RX_STATUS_OF BIT(2) /* Rx Overflow */ -+#define RX_STATUS_BE BIT(3) /* Bus Error */ -+ -+#define MII_CTRL_IF_MASK 3 -+#define MII_CTRL_SPEED_SHIFT 4 -+#define MII_CTRL_SPEED_MASK 3 -+#define MII_CTRL_SPEED_10 0 -+#define MII_CTRL_SPEED_100 1 -+#define MII_CTRL_SPEED_1000 2 -+ -+static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value) -+{ -+ void __iomem *r; -+ -+ switch (reg) { -+ case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL: -+ r = ag->mac_base + reg; -+ __raw_writel(value, r); -+ __raw_readl(r); -+ break; -+ case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS: -+ r = ag->mac_base2 + reg - AG71XX_REG_MAC_IFCTL; -+ __raw_writel(value, r); -+ __raw_readl(r); -+ break; -+ default: -+ BUG(); -+ } -+} -+ -+static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg) -+{ -+ void __iomem *r; -+ u32 ret; -+ -+ switch (reg) { -+ case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL: -+ r = ag->mac_base + reg; -+ ret = __raw_readl(r); -+ break; -+ case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS: -+ r = ag->mac_base2 + reg - AG71XX_REG_MAC_IFCTL; -+ ret = __raw_readl(r); -+ break; -+ default: -+ BUG(); -+ } -+ -+ return ret; -+} -+ -+static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask) -+{ -+ void __iomem *r; -+ -+ switch (reg) { -+ case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL: -+ r = ag->mac_base + reg; -+ __raw_writel(__raw_readl(r) | mask, r); -+ __raw_readl(r); -+ break; -+ case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS: -+ r = ag->mac_base2 + reg - AG71XX_REG_MAC_IFCTL; -+ __raw_writel(__raw_readl(r) | mask, r); -+ __raw_readl(r); -+ break; -+ default: -+ BUG(); -+ } -+} -+ -+static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask) -+{ -+ void __iomem *r; -+ -+ switch (reg) { -+ case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL: -+ r = ag->mac_base + reg; -+ __raw_writel(__raw_readl(r) & ~mask, r); -+ __raw_readl(r); -+ break; -+ case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS: -+ r = ag->mac_base2 + reg - AG71XX_REG_MAC_IFCTL; -+ __raw_writel(__raw_readl(r) & ~mask, r); -+ __raw_readl(r); -+ break; -+ default: -+ BUG(); -+ } -+} -+ -+static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints) -+{ -+ ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints); -+} -+ -+static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints) -+{ -+ ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints); -+} -+ -+static inline void ag71xx_mii_ctrl_wr(struct ag71xx *ag, u32 value) -+{ -+ __raw_writel(value, ag->mii_ctrl); -+ __raw_readl(ag->mii_ctrl); -+} -+ -+static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag) -+{ -+ return __raw_readl(ag->mii_ctrl); -+} -+ -+static void inline ag71xx_mii_ctrl_set_if(struct ag71xx *ag, -+ unsigned int mii_if) -+{ -+ u32 t; -+ -+ t = ag71xx_mii_ctrl_rr(ag); -+ t &= ~(MII_CTRL_IF_MASK); -+ t |= (mii_if & MII_CTRL_IF_MASK); -+ ag71xx_mii_ctrl_wr(ag, t); -+} -+ -+static void inline ag71xx_mii_ctrl_set_speed(struct ag71xx *ag, -+ unsigned int speed) -+{ -+ u32 t; -+ -+ t = ag71xx_mii_ctrl_rr(ag); -+ t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT); -+ t |= (speed & MII_CTRL_SPEED_MASK) << MII_CTRL_SPEED_SHIFT; -+ ag71xx_mii_ctrl_wr(ag, t); -+} -+ -+#ifdef CONFIG_AG71XX_AR8216_SUPPORT -+void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb); -+int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb); -+#else -+static inline void ag71xx_add_ar8216_header(struct ag71xx *ag, -+ struct sk_buff *skb) -+{ -+} -+ -+static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag, -+ struct sk_buff *skb) -+{ -+ return 0; -+} -+#endif -+ -+#endif /* _AG71XX_H */ -diff -Nur linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_ar8216.c linux-2.6.29.1/drivers/net/ag71xx/ag71xx_ar8216.c ---- linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_ar8216.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/net/ag71xx/ag71xx_ar8216.c 2009-04-13 14:27:34.803084620 +0200 -@@ -0,0 +1,53 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * Special support for the Atheros ar8216 switch chip -+ * -+ * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * 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 "ag71xx.h" -+ -+#define AR8216_PACKET_TYPE_MASK 0xf -+#define AR8216_PACKET_TYPE_NORMAL 0 -+ -+#define AR8216_HEADER_LEN 2 -+ -+void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ -+ if (!pdata->has_ar8216) -+ return; -+ -+ skb_push(skb, AR8216_HEADER_LEN); -+ skb->data[0] = 0x10; -+ skb->data[1] = 0x80; -+} -+ -+int ag71xx_remove_ar8216_header(struct ag71xx *ag, -+ struct sk_buff *skb) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ u8 type; -+ -+ if (!pdata->has_ar8216) -+ return 0; -+ -+ type = skb->data[1] & AR8216_PACKET_TYPE_MASK; -+ -+ switch (type) { -+ case AR8216_PACKET_TYPE_NORMAL: -+ skb_pull(skb, AR8216_HEADER_LEN); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -diff -Nur linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_ethtool.c linux-2.6.29.1/drivers/net/ag71xx/ag71xx_ethtool.c ---- linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_ethtool.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/net/ag71xx/ag71xx_ethtool.c 2009-04-13 14:27:34.803084620 +0200 -@@ -0,0 +1,71 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org> -+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * 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 "ag71xx.h" -+ -+static int ag71xx_ethtool_get_settings(struct net_device *dev, -+ struct ethtool_cmd *cmd) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ struct phy_device *phydev = ag->phy_dev; -+ -+ if (!phydev) -+ return -ENODEV; -+ -+ return phy_ethtool_gset(phydev, cmd); -+} -+ -+static int ag71xx_ethtool_set_settings(struct net_device *dev, -+ struct ethtool_cmd *cmd) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ struct phy_device *phydev = ag->phy_dev; -+ -+ if (!phydev) -+ return -ENODEV; -+ -+ return phy_ethtool_sset(phydev, cmd); -+} -+ -+static void ag71xx_ethtool_get_drvinfo(struct net_device *dev, -+ struct ethtool_drvinfo *info) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ -+ strcpy(info->driver, ag->pdev->dev.driver->name); -+ strcpy(info->version, AG71XX_DRV_VERSION); -+ strcpy(info->bus_info, ag->pdev->dev.bus_id); -+} -+ -+static u32 ag71xx_ethtool_get_msglevel(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ -+ return ag->msg_enable; -+} -+ -+static void ag71xx_ethtool_set_msglevel(struct net_device *dev, u32 msg_level) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ -+ ag->msg_enable = msg_level; -+} -+ -+struct ethtool_ops ag71xx_ethtool_ops = { -+ .set_settings = ag71xx_ethtool_set_settings, -+ .get_settings = ag71xx_ethtool_get_settings, -+ .get_drvinfo = ag71xx_ethtool_get_drvinfo, -+ .get_msglevel = ag71xx_ethtool_get_msglevel, -+ .set_msglevel = ag71xx_ethtool_set_msglevel, -+ .get_link = ethtool_op_get_link, -+}; -diff -Nur linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_main.c linux-2.6.29.1/drivers/net/ag71xx/ag71xx_main.c ---- linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_main.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/net/ag71xx/ag71xx_main.c 2009-04-13 18:00:36.641934324 +0200 -@@ -0,0 +1,990 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org> -+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * 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 "ag71xx.h" -+ -+#define AG71XX_DEFAULT_MSG_ENABLE \ -+ ( NETIF_MSG_DRV \ -+ | NETIF_MSG_PROBE \ -+ | NETIF_MSG_LINK \ -+ | NETIF_MSG_TIMER \ -+ | NETIF_MSG_IFDOWN \ -+ | NETIF_MSG_IFUP \ -+ | NETIF_MSG_RX_ERR \ -+ | NETIF_MSG_TX_ERR ) -+ -+static int ag71xx_debug = -1; -+ -+module_param(ag71xx_debug, int, 0); -+MODULE_PARM_DESC(ag71xx_debug, "Debug level (-1=defaults,0=none,...,16=all)"); -+ -+static void ag71xx_dump_dma_regs(struct ag71xx *ag) -+{ -+ DBG("%s: dma_tx_ctrl=%08x, dma_tx_desc=%08x, dma_tx_status=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_TX_CTRL), -+ ag71xx_rr(ag, AG71XX_REG_TX_DESC), -+ ag71xx_rr(ag, AG71XX_REG_TX_STATUS)); -+ -+ DBG("%s: dma_rx_ctrl=%08x, dma_rx_desc=%08x, dma_rx_status=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_RX_CTRL), -+ ag71xx_rr(ag, AG71XX_REG_RX_DESC), -+ ag71xx_rr(ag, AG71XX_REG_RX_STATUS)); -+} -+ -+static void ag71xx_dump_regs(struct ag71xx *ag) -+{ -+ DBG("%s: mac_cfg1=%08x, mac_cfg2=%08x, ipg=%08x, hdx=%08x, mfl=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_MAC_CFG1), -+ ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), -+ ag71xx_rr(ag, AG71XX_REG_MAC_IPG), -+ ag71xx_rr(ag, AG71XX_REG_MAC_HDX), -+ ag71xx_rr(ag, AG71XX_REG_MAC_MFL)); -+ DBG("%s: mac_ifctl=%08x, mac_addr1=%08x, mac_addr2=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), -+ ag71xx_rr(ag, AG71XX_REG_MAC_ADDR1), -+ ag71xx_rr(ag, AG71XX_REG_MAC_ADDR2)); -+ DBG("%s: fifo_cfg0=%08x, fifo_cfg1=%08x, fifo_cfg2=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); -+ DBG("%s: fifo_cfg3=%08x, fifo_cfg4=%08x, fifo_cfg5=%08x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); -+} -+ -+static inline void ag71xx_dump_intr(struct ag71xx *ag, char *label, u32 intr) -+{ -+ DBG("%s: %s intr=%08x %s%s%s%s%s%s\n", -+ ag->dev->name, label, intr, -+ (intr & AG71XX_INT_TX_PS) ? "TXPS " : "", -+ (intr & AG71XX_INT_TX_UR) ? "TXUR " : "", -+ (intr & AG71XX_INT_TX_BE) ? "TXBE " : "", -+ (intr & AG71XX_INT_RX_PR) ? "RXPR " : "", -+ (intr & AG71XX_INT_RX_OF) ? "RXOF " : "", -+ (intr & AG71XX_INT_RX_BE) ? "RXBE " : ""); -+} -+ -+static void ag71xx_ring_free(struct ag71xx_ring *ring) -+{ -+ kfree(ring->buf); -+ -+ if (ring->descs) -+ dma_free_coherent(NULL, ring->size * sizeof(*ring->descs), -+ ring->descs, ring->descs_dma); -+} -+ -+static int ag71xx_ring_alloc(struct ag71xx_ring *ring, unsigned int size) -+{ -+ int err; -+ -+ ring->descs = dma_alloc_coherent(NULL, size * sizeof(*ring->descs), -+ &ring->descs_dma, -+ GFP_ATOMIC); -+ if (!ring->descs) { -+ err = -ENOMEM; -+ goto err; -+ } -+ -+ ring->size = size; -+ -+ ring->buf = kzalloc(size * sizeof(*ring->buf), GFP_KERNEL); -+ if (!ring->buf) { -+ err = -ENOMEM; -+ goto err; -+ } -+ -+ return 0; -+ -+ err: -+ return err; -+} -+ -+static void ag71xx_ring_tx_clean(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->tx_ring; -+ struct net_device *dev = ag->dev; -+ -+ while (ring->curr != ring->dirty) { -+ u32 i = ring->dirty % AG71XX_TX_RING_SIZE; -+ -+ if (!ag71xx_desc_empty(&ring->descs[i])) { -+ ring->descs[i].ctrl = 0; -+ dev->stats.tx_errors++; -+ } -+ -+ if (ring->buf[i].skb) -+ dev_kfree_skb_any(ring->buf[i].skb); -+ -+ ring->buf[i].skb = NULL; -+ -+ ring->dirty++; -+ } -+ -+ /* flush descriptors */ -+ wmb(); -+ -+} -+ -+static void ag71xx_ring_tx_init(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->tx_ring; -+ int i; -+ -+ for (i = 0; i < AG71XX_TX_RING_SIZE; i++) { -+ ring->descs[i].next = (u32) (ring->descs_dma + -+ sizeof(*ring->descs) * ((i + 1) % AG71XX_TX_RING_SIZE)); -+ -+ ring->descs[i].ctrl = DESC_EMPTY; -+ ring->buf[i].skb = NULL; -+ } -+ -+ /* flush descriptors */ -+ wmb(); -+ -+ ring->curr = 0; -+ ring->dirty = 0; -+} -+ -+static void ag71xx_ring_rx_clean(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->rx_ring; -+ int i; -+ -+ if (!ring->buf) -+ return; -+ -+ for (i = 0; i < AG71XX_RX_RING_SIZE; i++) -+ if (ring->buf[i].skb) -+ kfree_skb(ring->buf[i].skb); -+ -+} -+ -+static int ag71xx_ring_rx_init(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->rx_ring; -+ unsigned int i; -+ int ret; -+ -+ ret = 0; -+ for (i = 0; i < AG71XX_RX_RING_SIZE; i++) -+ ring->descs[i].next = (u32) (ring->descs_dma + -+ sizeof(*ring->descs) * ((i + 1) % AG71XX_RX_RING_SIZE)); -+ -+ for (i = 0; i < AG71XX_RX_RING_SIZE; i++) { -+ struct sk_buff *skb; -+ -+ skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE); -+ if (!skb) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ dma_map_single(NULL, skb->data, AG71XX_RX_PKT_SIZE, -+ DMA_FROM_DEVICE); -+ -+ skb->dev = ag->dev; -+ skb_reserve(skb, AG71XX_RX_PKT_RESERVE); -+ -+ ring->buf[i].skb = skb; -+ ring->descs[i].data = virt_to_phys(skb->data); -+ ring->descs[i].ctrl = DESC_EMPTY; -+ } -+ -+ /* flush descriptors */ -+ wmb(); -+ -+ ring->curr = 0; -+ ring->dirty = 0; -+ -+ return ret; -+} -+ -+static int ag71xx_ring_rx_refill(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->rx_ring; -+ unsigned int count; -+ -+ count = 0; -+ for (; ring->curr - ring->dirty > 0; ring->dirty++) { -+ unsigned int i; -+ -+ i = ring->dirty % AG71XX_RX_RING_SIZE; -+ -+ if (ring->buf[i].skb == NULL) { -+ struct sk_buff *skb; -+ -+ skb = dev_alloc_skb(AG71XX_RX_PKT_SIZE); -+ if (skb == NULL) -+ break; -+ -+ dma_map_single(NULL, skb->data, AG71XX_RX_PKT_SIZE, -+ DMA_FROM_DEVICE); -+ -+ skb_reserve(skb, AG71XX_RX_PKT_RESERVE); -+ skb->dev = ag->dev; -+ -+ ring->buf[i].skb = skb; -+ ring->descs[i].data = virt_to_phys(skb->data); -+ } -+ -+ ring->descs[i].ctrl = DESC_EMPTY; -+ count++; -+ } -+ -+ /* flush descriptors */ -+ wmb(); -+ -+ DBG("%s: %u rx descriptors refilled\n", ag->dev->name, count); -+ -+ return count; -+} -+ -+static int ag71xx_rings_init(struct ag71xx *ag) -+{ -+ int ret; -+ -+ ret = ag71xx_ring_alloc(&ag->tx_ring, AG71XX_TX_RING_SIZE); -+ if (ret) -+ return ret; -+ -+ ag71xx_ring_tx_init(ag); -+ -+ ret = ag71xx_ring_alloc(&ag->rx_ring, AG71XX_RX_RING_SIZE); -+ if (ret) -+ return ret; -+ -+ ret = ag71xx_ring_rx_init(ag); -+ return ret; -+} -+ -+static void ag71xx_rings_cleanup(struct ag71xx *ag) -+{ -+ ag71xx_ring_rx_clean(ag); -+ ag71xx_ring_free(&ag->rx_ring); -+ -+ ag71xx_ring_tx_clean(ag); -+ ag71xx_ring_free(&ag->tx_ring); -+} -+ -+static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac) -+{ -+ u32 t; -+ -+ t = (((u32) mac[0]) << 24) | (((u32) mac[1]) << 16) -+ | (((u32) mac[2]) << 8) | ((u32) mac[3]); -+ -+ ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t); -+ -+ t = (((u32) mac[4]) << 24) | (((u32) mac[5]) << 16); -+ ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t); -+} -+ -+static void ag71xx_dma_reset(struct ag71xx *ag) -+{ -+ int i; -+ -+ ag71xx_dump_dma_regs(ag); -+ -+ /* stop RX and TX */ -+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0); -+ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0); -+ -+ /* clear descriptor addresses */ -+ ag71xx_wr(ag, AG71XX_REG_TX_DESC, 0); -+ ag71xx_wr(ag, AG71XX_REG_RX_DESC, 0); -+ -+ /* clear pending RX/TX interrupts */ -+ for (i = 0; i < 256; i++) { -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); -+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); -+ } -+ -+ /* clear pending errors */ -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF); -+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR); -+ -+ if (ag71xx_rr(ag, AG71XX_REG_RX_STATUS)) -+ printk(KERN_ALERT "%s: unable to clear DMA Rx status\n", -+ ag->dev->name); -+ -+ if (ag71xx_rr(ag, AG71XX_REG_TX_STATUS)) -+ printk(KERN_ALERT "%s: unable to clear DMA Tx status\n", -+ ag->dev->name); -+ -+ ag71xx_dump_dma_regs(ag); -+} -+ -+#define MAC_CFG1_INIT (MAC_CFG1_RXE | MAC_CFG1_TXE | \ -+ MAC_CFG1_SRX | MAC_CFG1_STX) -+ -+#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT) -+ -+#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \ -+ FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \ -+ FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \ -+ FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \ -+ FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \ -+ FIFO_CFG4_VT) -+ -+#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \ -+ FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \ -+ FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \ -+ FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \ -+ FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \ -+ FIFO_CFG5_17 | FIFO_CFG5_SF) -+ -+static void ag71xx_hw_init(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ -+ ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR); -+ udelay(20); -+ -+ ar71xx_device_stop(pdata->reset_bit); -+ mdelay(100); -+ ar71xx_device_start(pdata->reset_bit); -+ mdelay(100); -+ -+ /* setup MAC configuration registers */ -+ ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_INIT); -+ ag71xx_sb(ag, AG71XX_REG_MAC_CFG2, -+ MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK); -+ -+ /* setup max frame length */ -+ ag71xx_wr(ag, AG71XX_REG_MAC_MFL, AG71XX_TX_MTU_LEN); -+ -+ /* setup MII interface type */ -+ ag71xx_mii_ctrl_set_if(ag, pdata->mii_if); -+ -+ /* setup FIFO configuration registers */ -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT); -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000); -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff); -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT); -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT); -+ -+ ag71xx_dma_reset(ag); -+} -+ -+static void ag71xx_hw_start(struct ag71xx *ag) -+{ -+ /* start RX engine */ -+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); -+ -+ /* enable interrupts */ -+ ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, AG71XX_INT_INIT); -+} -+ -+static void ag71xx_hw_stop(struct ag71xx *ag) -+{ -+ /* disable all interrupts */ -+ ag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0); -+ -+ ag71xx_dma_reset(ag); -+} -+ -+static int ag71xx_open(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ int ret; -+ -+ ret = ag71xx_rings_init(ag); -+ if (ret) -+ goto err; -+ -+ napi_enable(&ag->napi); -+ -+ netif_carrier_off(dev); -+ ag71xx_phy_start(ag); -+ -+ ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->tx_ring.descs_dma); -+ ag71xx_wr(ag, AG71XX_REG_RX_DESC, ag->rx_ring.descs_dma); -+ -+ ag71xx_hw_set_macaddr(ag, dev->dev_addr); -+ -+ ag71xx_hw_start(ag); -+ -+ netif_start_queue(dev); -+ -+ return 0; -+ -+ err: -+ ag71xx_rings_cleanup(ag); -+ return ret; -+} -+ -+static int ag71xx_stop(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&ag->lock, flags); -+ -+ netif_stop_queue(dev); -+ -+ ag71xx_hw_stop(ag); -+ -+ netif_carrier_off(dev); -+ ag71xx_phy_stop(ag); -+ -+ napi_disable(&ag->napi); -+ del_timer_sync(&ag->oom_timer); -+ -+ spin_unlock_irqrestore(&ag->lock, flags); -+ -+ ag71xx_rings_cleanup(ag); -+ -+ return 0; -+} -+ -+static int ag71xx_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ struct ag71xx_ring *ring = &ag->tx_ring; -+ struct ag71xx_desc *desc; -+ unsigned long flags; -+ int i; -+ -+ i = ring->curr % AG71XX_TX_RING_SIZE; -+ desc = &ring->descs[i]; -+ -+ spin_lock_irqsave(&ag->lock, flags); -+ pdata->ddr_flush(); -+ spin_unlock_irqrestore(&ag->lock, flags); -+ -+ if (!ag71xx_desc_empty(desc)) -+ goto err_drop; -+ -+ ag71xx_add_ar8216_header(ag, skb); -+ -+ if (skb->len <= 0) { -+ DBG("%s: packet len is too small\n", ag->dev->name); -+ goto err_drop; -+ } -+ -+ dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE); -+ -+ ring->buf[i].skb = skb; -+ -+ /* setup descriptor fields */ -+ desc->data = virt_to_phys(skb->data); -+ desc->ctrl = (skb->len & DESC_PKTLEN_M); -+ -+ /* flush descriptor */ -+ wmb(); -+ -+ ring->curr++; -+ if (ring->curr == (ring->dirty + AG71XX_TX_THRES_STOP)) { -+ DBG("%s: tx queue full\n", ag->dev->name); -+ netif_stop_queue(dev); -+ } -+ -+ DBG("%s: packet injected into TX queue\n", ag->dev->name); -+ -+ /* enable TX engine */ -+ ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE); -+ -+ dev->trans_start = jiffies; -+ -+ return 0; -+ -+ err_drop: -+ dev->stats.tx_dropped++; -+ -+ dev_kfree_skb(skb); -+ return 0; -+} -+ -+static int ag71xx_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -+{ -+ struct mii_ioctl_data *data = (struct mii_ioctl_data *) &ifr->ifr_data; -+ struct ag71xx *ag = netdev_priv(dev); -+ int ret; -+ -+ switch (cmd) { -+ case SIOCETHTOOL: -+ if (ag->phy_dev == NULL) -+ break; -+ -+ spin_lock_irq(&ag->lock); -+ ret = phy_ethtool_ioctl(ag->phy_dev, (void *) ifr->ifr_data); -+ spin_unlock_irq(&ag->lock); -+ return ret; -+ -+ case SIOCSIFHWADDR: -+ if (copy_from_user -+ (dev->dev_addr, ifr->ifr_data, sizeof(dev->dev_addr))) -+ return -EFAULT; -+ return 0; -+ -+ case SIOCGIFHWADDR: -+ if (copy_to_user -+ (ifr->ifr_data, dev->dev_addr, sizeof(dev->dev_addr))) -+ return -EFAULT; -+ return 0; -+ -+ case SIOCGMIIPHY: -+ case SIOCGMIIREG: -+ case SIOCSMIIREG: -+ if (ag->phy_dev == NULL) -+ break; -+ -+ return phy_mii_ioctl(ag->phy_dev, data, cmd); -+ -+ default: -+ break; -+ } -+ -+ return -EOPNOTSUPP; -+} -+ -+static void ag71xx_oom_timer_handler(unsigned long data) -+{ -+ struct net_device *dev = (struct net_device *) data; -+ struct ag71xx *ag = netdev_priv(dev); -+ -+ netif_rx_schedule(&ag->napi); -+} -+ -+static void ag71xx_tx_timeout(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ -+ if (netif_msg_tx_err(ag)) -+ printk(KERN_DEBUG "%s: tx timeout\n", ag->dev->name); -+ -+ schedule_work(&ag->restart_work); -+} -+ -+static void ag71xx_restart_work_func(struct work_struct *work) -+{ -+ struct ag71xx *ag = container_of(work, struct ag71xx, restart_work); -+ -+ ag71xx_stop(ag->dev); -+ ag71xx_open(ag->dev); -+} -+ -+static void ag71xx_tx_packets(struct ag71xx *ag) -+{ -+ struct ag71xx_ring *ring = &ag->tx_ring; -+ unsigned int sent; -+ -+ DBG("%s: processing TX ring\n", ag->dev->name); -+ -+ sent = 0; -+ while (ring->dirty != ring->curr) { -+ unsigned int i = ring->dirty % AG71XX_TX_RING_SIZE; -+ struct ag71xx_desc *desc = &ring->descs[i]; -+ struct sk_buff *skb = ring->buf[i].skb; -+ -+ if (!ag71xx_desc_empty(desc)) -+ break; -+ -+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS); -+ -+ ag->dev->stats.tx_bytes += skb->len; -+ ag->dev->stats.tx_packets++; -+ -+ dev_kfree_skb_any(skb); -+ ring->buf[i].skb = NULL; -+ -+ ring->dirty++; -+ sent++; -+ } -+ -+ DBG("%s: %d packets sent out\n", ag->dev->name, sent); -+ -+ if ((ring->curr - ring->dirty) < AG71XX_TX_THRES_WAKEUP) -+ netif_wake_queue(ag->dev); -+ -+} -+ -+static int ag71xx_rx_packets(struct ag71xx *ag, int limit) -+{ -+ struct net_device *dev = ag->dev; -+ struct ag71xx_ring *ring = &ag->rx_ring; -+ int done = 0; -+ -+ DBG("%s: rx packets, limit=%d, curr=%u, dirty=%u\n", -+ dev->name, limit, ring->curr, ring->dirty); -+ -+ while (done < limit) { -+ unsigned int i = ring->curr % AG71XX_RX_RING_SIZE; -+ struct ag71xx_desc *desc = &ring->descs[i]; -+ struct sk_buff *skb; -+ int pktlen; -+ -+ if (ag71xx_desc_empty(desc)) -+ break; -+ -+ if ((ring->dirty + AG71XX_RX_RING_SIZE) == ring->curr) { -+ ag71xx_assert(0); -+ break; -+ } -+ -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR); -+ -+ skb = ring->buf[i].skb; -+ pktlen = ag71xx_desc_pktlen(desc); -+ pktlen -= ETH_FCS_LEN; -+ -+ skb_put(skb, pktlen); -+ -+ skb->dev = dev; -+ skb->ip_summed = CHECKSUM_NONE; -+ -+ dev->last_rx = jiffies; -+ dev->stats.rx_packets++; -+ dev->stats.rx_bytes += pktlen; -+ -+ if (ag71xx_remove_ar8216_header(ag, skb) != 0) { -+ dev->stats.rx_dropped++; -+ kfree_skb(skb); -+ } else { -+ skb->protocol = eth_type_trans(skb, dev); -+ netif_receive_skb(skb); -+ } -+ -+ ring->buf[i].skb = NULL; -+ done++; -+ -+ ring->curr++; -+ } -+ -+ ag71xx_ring_rx_refill(ag); -+ -+ DBG("%s: rx finish, curr=%u, dirty=%u, done=%d\n", -+ dev->name, ring->curr, ring->dirty, done); -+ -+ return done; -+} -+ -+static int ag71xx_poll(struct napi_struct *napi, int limit) -+{ -+ struct ag71xx *ag = container_of(napi, struct ag71xx, napi); -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ struct net_device *dev = ag->dev; -+ struct ag71xx_ring *rx_ring; -+ unsigned long flags; -+ u32 status; -+ int done; -+ -+ pdata->ddr_flush(); -+ ag71xx_tx_packets(ag); -+ -+ DBG("%s: processing RX ring\n", dev->name); -+ done = ag71xx_rx_packets(ag, limit); -+ -+ rx_ring = &ag->rx_ring; -+ if (rx_ring->buf[rx_ring->dirty % AG71XX_RX_RING_SIZE].skb == NULL) -+ goto oom; -+ -+ status = ag71xx_rr(ag, AG71XX_REG_RX_STATUS); -+ if (unlikely(status & RX_STATUS_OF)) { -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_OF); -+ dev->stats.rx_fifo_errors++; -+ -+ /* restart RX */ -+ ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE); -+ } -+ -+ if (done < limit) { -+ if (status & RX_STATUS_PR) -+ goto more; -+ -+ status = ag71xx_rr(ag, AG71XX_REG_TX_STATUS); -+ if (status & TX_STATUS_PS) -+ goto more; -+ -+ DBG("%s: disable polling mode, done=%d, limit=%d\n", -+ dev->name, done, limit); -+ -+ netif_rx_complete(napi); -+ -+ /* enable interrupts */ -+ spin_lock_irqsave(&ag->lock, flags); -+ ag71xx_int_enable(ag, AG71XX_INT_POLL); -+ spin_unlock_irqrestore(&ag->lock, flags); -+ return done; -+ } -+ -+ more: -+ DBG("%s: stay in polling mode, done=%d, limit=%d\n", -+ dev->name, done, limit); -+ return done; -+ -+ oom: -+ if (netif_msg_rx_err(ag)) -+ printk(KERN_DEBUG "%s: out of memory\n", dev->name); -+ -+ mod_timer(&ag->oom_timer, jiffies + AG71XX_OOM_REFILL); -+ netif_rx_complete(napi); -+ return 0; -+} -+ -+static irqreturn_t ag71xx_interrupt(int irq, void *dev_id) -+{ -+ struct net_device *dev = dev_id; -+ struct ag71xx *ag = netdev_priv(dev); -+ u32 status; -+ -+ status = ag71xx_rr(ag, AG71XX_REG_INT_STATUS); -+ ag71xx_dump_intr(ag, "raw", status); -+ -+ if (unlikely(!status)) -+ return IRQ_NONE; -+ -+ if (unlikely(status & AG71XX_INT_ERR)) { -+ if (status & AG71XX_INT_TX_BE) { -+ ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE); -+ dev_err(&dev->dev, "TX BUS error\n"); -+ } -+ if (status & AG71XX_INT_RX_BE) { -+ ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE); -+ dev_err(&dev->dev, "RX BUS error\n"); -+ } -+ } -+ -+ if (likely(status & AG71XX_INT_POLL)) { -+ ag71xx_int_disable(ag, AG71XX_INT_POLL); -+ DBG("%s: enable polling mode\n", dev->name); -+ netif_rx_schedule(&ag->napi); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static void ag71xx_set_multicast_list(struct net_device *dev) -+{ -+ /* TODO */ -+} -+ -+static int __init ag71xx_probe(struct platform_device *pdev) -+{ -+ struct net_device *dev; -+ struct resource *res; -+ struct ag71xx *ag; -+ struct ag71xx_platform_data *pdata; -+ int err; -+ -+ pdata = pdev->dev.platform_data; -+ if (!pdata) { -+ dev_err(&pdev->dev, "no platform data specified\n"); -+ err = -ENXIO; -+ goto err_out; -+ } -+ -+ dev = alloc_etherdev(sizeof(*ag)); -+ if (!dev) { -+ dev_err(&pdev->dev, "alloc_etherdev failed\n"); -+ err = -ENOMEM; -+ goto err_out; -+ } -+ -+ SET_NETDEV_DEV(dev, &pdev->dev); -+ -+ ag = netdev_priv(dev); -+ ag->pdev = pdev; -+ ag->dev = dev; -+ ag->mii_bus = ag71xx_mdio_bus->mii_bus; -+ ag->msg_enable = netif_msg_init(ag71xx_debug, -+ AG71XX_DEFAULT_MSG_ENABLE); -+ spin_lock_init(&ag->lock); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mac_base"); -+ if (!res) { -+ dev_err(&pdev->dev, "no mac_base resource found\n"); -+ err = -ENXIO; -+ goto err_out; -+ } -+ -+ ag->mac_base = ioremap_nocache(res->start, res->end - res->start + 1); -+ if (!ag->mac_base) { -+ dev_err(&pdev->dev, "unable to ioremap mac_base\n"); -+ err = -ENOMEM; -+ goto err_free_dev; -+ } -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mac_base2"); -+ if (!res) { -+ dev_err(&pdev->dev, "no mac_base2 resource found\n"); -+ err = -ENXIO; -+ goto err_unmap_base1; -+ } -+ -+ ag->mac_base2 = ioremap_nocache(res->start, res->end - res->start + 1); -+ if (!ag->mac_base) { -+ dev_err(&pdev->dev, "unable to ioremap mac_base2\n"); -+ err = -ENOMEM; -+ goto err_unmap_base1; -+ } -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mii_ctrl"); -+ if (!res) { -+ dev_err(&pdev->dev, "no mii_ctrl resource found\n"); -+ err = -ENXIO; -+ goto err_unmap_base2; -+ } -+ -+ ag->mii_ctrl = ioremap_nocache(res->start, res->end - res->start + 1); -+ if (!ag->mii_ctrl) { -+ dev_err(&pdev->dev, "unable to ioremap mii_ctrl\n"); -+ err = -ENOMEM; -+ goto err_unmap_base2; -+ } -+ -+ dev->irq = platform_get_irq(pdev, 0); -+ err = request_irq(dev->irq, ag71xx_interrupt, -+ IRQF_DISABLED | IRQF_SAMPLE_RANDOM, -+ dev->name, dev); -+ if (err) { -+ dev_err(&pdev->dev, "unable to request IRQ %d\n", dev->irq); -+ goto err_unmap_mii_ctrl; -+ } -+ -+ dev->base_addr = (unsigned long)ag->mac_base; -+ dev->open = ag71xx_open; -+ dev->stop = ag71xx_stop; -+ dev->hard_start_xmit = ag71xx_hard_start_xmit; -+ dev->set_multicast_list = ag71xx_set_multicast_list; -+ dev->do_ioctl = ag71xx_do_ioctl; -+ dev->ethtool_ops = &ag71xx_ethtool_ops; -+ -+ dev->tx_timeout = ag71xx_tx_timeout; -+ INIT_WORK(&ag->restart_work, ag71xx_restart_work_func); -+ -+ init_timer(&ag->oom_timer); -+ ag->oom_timer.data = (unsigned long) dev; -+ ag->oom_timer.function = ag71xx_oom_timer_handler; -+ -+ memcpy(dev->dev_addr, pdata->mac_addr, ETH_ALEN); -+ -+ netif_napi_add(dev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT); -+ -+ err = register_netdev(dev); -+ if (err) { -+ dev_err(&pdev->dev, "unable to register net device\n"); -+ goto err_free_irq; -+ } -+ -+ printk(KERN_INFO "%s: Atheros AG71xx at 0x%08lx, irq %d\n", -+ dev->name, dev->base_addr, dev->irq); -+ -+ ag71xx_dump_regs(ag); -+ -+ ag71xx_hw_init(ag); -+ -+ ag71xx_dump_regs(ag); -+ -+ /* Reset the mdio bus explicitly */ -+ if (ag->mii_bus) { -+ mutex_lock(&ag->mii_bus->mdio_lock); -+ ag->mii_bus->reset(ag->mii_bus); -+ mutex_unlock(&ag->mii_bus->mdio_lock); -+ } -+ -+ err = ag71xx_phy_connect(ag); -+ if (err) -+ goto err_unregister_netdev; -+ -+ platform_set_drvdata(pdev, dev); -+ -+ return 0; -+ -+ err_unregister_netdev: -+ unregister_netdev(dev); -+ err_free_irq: -+ free_irq(dev->irq, dev); -+ err_unmap_mii_ctrl: -+ iounmap(ag->mii_ctrl); -+ err_unmap_base2: -+ iounmap(ag->mac_base2); -+ err_unmap_base1: -+ iounmap(ag->mac_base); -+ err_free_dev: -+ kfree(dev); -+ err_out: -+ platform_set_drvdata(pdev, NULL); -+ return err; -+} -+ -+static int __exit ag71xx_remove(struct platform_device *pdev) -+{ -+ struct net_device *dev = platform_get_drvdata(pdev); -+ -+ if (dev) { -+ struct ag71xx *ag = netdev_priv(dev); -+ -+ ag71xx_phy_disconnect(ag); -+ unregister_netdev(dev); -+ free_irq(dev->irq, dev); -+ iounmap(ag->mii_ctrl); -+ iounmap(ag->mac_base2); -+ iounmap(ag->mac_base); -+ kfree(dev); -+ platform_set_drvdata(pdev, NULL); -+ } -+ -+ return 0; -+} -+ -+static struct platform_driver ag71xx_driver = { -+ .probe = ag71xx_probe, -+ .remove = __exit_p(ag71xx_remove), -+ .driver = { -+ .name = AG71XX_DRV_NAME, -+ } -+}; -+ -+static int __init ag71xx_module_init(void) -+{ -+ int ret; -+ -+ ret = ag71xx_mdio_driver_init(); -+ if (ret) -+ goto err_out; -+ -+ ret = platform_driver_register(&ag71xx_driver); -+ if (ret) -+ goto err_mdio_exit; -+ -+ return 0; -+ -+ err_mdio_exit: -+ ag71xx_mdio_driver_exit(); -+ err_out: -+ return ret; -+} -+ -+static void __exit ag71xx_module_exit(void) -+{ -+ platform_driver_unregister(&ag71xx_driver); -+ ag71xx_mdio_driver_exit(); -+} -+ -+module_init(ag71xx_module_init); -+module_exit(ag71xx_module_exit); -+ -+MODULE_VERSION(AG71XX_DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); -+MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" AG71XX_DRV_NAME); -diff -Nur linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_mdio.c linux-2.6.29.1/drivers/net/ag71xx/ag71xx_mdio.c ---- linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_mdio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/net/ag71xx/ag71xx_mdio.c 2009-04-13 14:27:34.827084882 +0200 -@@ -0,0 +1,233 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org> -+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * 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 "ag71xx.h" -+ -+#define AG71XX_MDIO_RETRY 1000 -+#define AG71XX_MDIO_DELAY 5 -+ -+struct ag71xx_mdio *ag71xx_mdio_bus; -+ -+static inline void ag71xx_mdio_wr(struct ag71xx_mdio *am, unsigned reg, -+ u32 value) -+{ -+ __raw_writel(value, am->mdio_base + reg - AG71XX_REG_MII_CFG); -+} -+ -+static inline u32 ag71xx_mdio_rr(struct ag71xx_mdio *am, unsigned reg) -+{ -+ return __raw_readl(am->mdio_base + reg - AG71XX_REG_MII_CFG); -+} -+ -+static void ag71xx_mdio_dump_regs(struct ag71xx_mdio *am) -+{ -+ DBG("%s: mii_cfg=%08x, mii_cmd=%08x, mii_addr=%08x\n", -+ am->mii_bus->name, -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_CFG), -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_CMD), -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_ADDR)); -+ DBG("%s: mii_ctrl=%08x, mii_status=%08x, mii_ind=%08x\n", -+ am->mii_bus->name, -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_CTRL), -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS), -+ ag71xx_mdio_rr(am, AG71XX_REG_MII_IND)); -+} -+ -+static int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg) -+{ -+ int ret; -+ int i; -+ -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE); -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR, -+ ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_READ); -+ -+ i = AG71XX_MDIO_RETRY; -+ while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) { -+ if (i-- == 0) { -+ printk(KERN_ERR "%s: mii_read timed out\n", -+ am->mii_bus->name); -+ ret = 0xffff; -+ goto out; -+ } -+ udelay(AG71XX_MDIO_DELAY); -+ } -+ -+ ret = ag71xx_mdio_rr(am, AG71XX_REG_MII_STATUS) & 0xffff; -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CMD, MII_CMD_WRITE); -+ -+ DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, ret); -+ -+ out: -+ return ret; -+} -+ -+static void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, -+ int addr, int reg, u16 val) -+{ -+ int i; -+ -+ DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val); -+ -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_ADDR, -+ ((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff)); -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CTRL, val); -+ -+ i = AG71XX_MDIO_RETRY; -+ while (ag71xx_mdio_rr(am, AG71XX_REG_MII_IND) & MII_IND_BUSY) { -+ if (i-- == 0) { -+ printk(KERN_ERR "%s: mii_write timed out\n", -+ am->mii_bus->name); -+ break; -+ } -+ udelay(AG71XX_MDIO_DELAY); -+ } -+} -+ -+static int ag71xx_mdio_reset(struct mii_bus *bus) -+{ -+ struct ag71xx_mdio *am = bus->priv; -+ -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, MII_CFG_RESET); -+ udelay(100); -+ -+ ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, MII_CFG_CLK_DIV_28); -+ udelay(100); -+ -+ return 0; -+} -+ -+static int ag71xx_mdio_read(struct mii_bus *bus, int addr, int reg) -+{ -+ struct ag71xx_mdio *am = bus->priv; -+ -+ return ag71xx_mdio_mii_read(am, addr, reg); -+} -+ -+static int ag71xx_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val) -+{ -+ struct ag71xx_mdio *am = bus->priv; -+ -+ ag71xx_mdio_mii_write(am, addr, reg, val); -+ return 0; -+} -+ -+static int __init ag71xx_mdio_probe(struct platform_device *pdev) -+{ -+ struct ag71xx_mdio_platform_data *pdata; -+ struct ag71xx_mdio *am; -+ struct resource *res; -+ int i; -+ int err; -+ -+ if (ag71xx_mdio_bus) -+ return -EBUSY; -+ -+ am = kzalloc(sizeof(*am), GFP_KERNEL); -+ if (!am) { -+ err = -ENOMEM; -+ goto err_out; -+ } -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(&pdev->dev, "no iomem resource found\n"); -+ err = -ENXIO; -+ goto err_out; -+ } -+ -+ am->mdio_base = ioremap_nocache(res->start, res->end - res->start + 1); -+ if (!am->mdio_base) { -+ dev_err(&pdev->dev, "unable to ioremap registers\n"); -+ err = -ENOMEM; -+ goto err_free_mdio; -+ } -+ -+ am->mii_bus = mdiobus_alloc(); -+ if (am->mii_bus == NULL) { -+ err = -ENOMEM; -+ goto err_iounmap; -+ } -+ -+ am->mii_bus->name = "ag71xx_mdio"; -+ am->mii_bus->read = ag71xx_mdio_read; -+ am->mii_bus->write = ag71xx_mdio_write; -+ am->mii_bus->reset = ag71xx_mdio_reset; -+ am->mii_bus->irq = am->mii_irq; -+ am->mii_bus->priv = am; -+ am->mii_bus->parent = &pdev->dev; -+ snprintf(am->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0); -+ -+ pdata = pdev->dev.platform_data; -+ if (pdata) -+ am->mii_bus->phy_mask = pdata->phy_mask; -+ -+ for (i = 0; i < PHY_MAX_ADDR; i++) -+ am->mii_irq[i] = PHY_POLL; -+ -+ ag71xx_mdio_wr(am, AG71XX_REG_MAC_CFG1, 0); -+ -+ err = mdiobus_register(am->mii_bus); -+ if (err) -+ goto err_free_bus; -+ -+ ag71xx_mdio_dump_regs(am); -+ -+ platform_set_drvdata(pdev, am); -+ ag71xx_mdio_bus = am; -+ return 0; -+ -+ err_free_bus: -+ mdiobus_free(am->mii_bus); -+ err_iounmap: -+ iounmap(am->mdio_base); -+ err_free_mdio: -+ kfree(am); -+ err_out: -+ return err; -+} -+ -+static int __exit ag71xx_mdio_remove(struct platform_device *pdev) -+{ -+ struct ag71xx_mdio *am = platform_get_drvdata(pdev); -+ -+ if (am) { -+ ag71xx_mdio_bus = NULL; -+ mdiobus_unregister(am->mii_bus); -+ mdiobus_free(am->mii_bus); -+ iounmap(am->mdio_base); -+ kfree(am); -+ platform_set_drvdata(pdev, NULL); -+ } -+ -+ return 0; -+} -+ -+static struct platform_driver ag71xx_mdio_driver = { -+ .probe = ag71xx_mdio_probe, -+ .remove = __exit_p(ag71xx_mdio_remove), -+ .driver = { -+ .name = "ag71xx-mdio", -+ } -+}; -+ -+int ag71xx_mdio_driver_init(void) -+{ -+ return platform_driver_register(&ag71xx_mdio_driver); -+} -+ -+void ag71xx_mdio_driver_exit(void) -+{ -+ platform_driver_unregister(&ag71xx_mdio_driver); -+} -diff -Nur linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_phy.c linux-2.6.29.1/drivers/net/ag71xx/ag71xx_phy.c ---- linux-2.6.29.1.orig/drivers/net/ag71xx/ag71xx_phy.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/net/ag71xx/ag71xx_phy.c 2009-04-13 14:27:34.827084882 +0200 -@@ -0,0 +1,287 @@ -+/* -+ * Atheros AR71xx built-in ethernet mac driver -+ * -+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org> -+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> -+ * -+ * Based on Atheros' AG7100 driver -+ * -+ * 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 "ag71xx.h" -+ -+static unsigned char *ag71xx_speed_str(struct ag71xx *ag) -+{ -+ switch (ag->speed) { -+ case SPEED_1000: -+ return "1000"; -+ case SPEED_100: -+ return "100"; -+ case SPEED_10: -+ return "10"; -+ } -+ -+ return "?"; -+} -+ -+#define AR71XX_PLL_VAL_1000 0x00110000 -+#define AR71XX_PLL_VAL_100 0x00001099 -+#define AR71XX_PLL_VAL_10 0x00991099 -+ -+#define AR91XX_PLL_VAL_1000 0x1a000000 -+#define AR91XX_PLL_VAL_100 0x13000a44 -+#define AR91XX_PLL_VAL_10 0x00441099 -+ -+static void ag71xx_phy_link_update(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ u32 cfg2; -+ u32 ifctl; -+ u32 pll; -+ u32 fifo5; -+ u32 mii_speed; -+ -+ if (!ag->link) { -+ netif_carrier_off(ag->dev); -+ if (netif_msg_link(ag)) -+ printk(KERN_INFO "%s: link down\n", ag->dev->name); -+ return; -+ } -+ -+ cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2); -+ cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX); -+ cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0; -+ -+ ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL); -+ ifctl &= ~(MAC_IFCTL_SPEED); -+ -+ fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5); -+ fifo5 &= ~FIFO_CFG5_BM; -+ -+ switch (ag->speed) { -+ case SPEED_1000: -+ mii_speed = MII_CTRL_SPEED_1000; -+ cfg2 |= MAC_CFG2_IF_1000; -+ pll = pdata->is_ar91xx ? AR91XX_PLL_VAL_1000 -+ : AR71XX_PLL_VAL_1000; -+ fifo5 |= FIFO_CFG5_BM; -+ break; -+ case SPEED_100: -+ mii_speed = MII_CTRL_SPEED_100; -+ cfg2 |= MAC_CFG2_IF_10_100; -+ ifctl |= MAC_IFCTL_SPEED; -+ pll = pdata->is_ar91xx ? AR91XX_PLL_VAL_100 -+ : AR71XX_PLL_VAL_100; -+ break; -+ case SPEED_10: -+ mii_speed = MII_CTRL_SPEED_10; -+ cfg2 |= MAC_CFG2_IF_10_100; -+ pll = pdata->is_ar91xx ? AR91XX_PLL_VAL_10 -+ : AR71XX_PLL_VAL_10; -+ break; -+ default: -+ BUG(); -+ return; -+ } -+ -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, -+ pdata->is_ar91xx ? 0x780fff : 0x008001ff); -+ pdata->set_pll(pll); -+ ag71xx_mii_ctrl_set_speed(ag, mii_speed); -+ -+ ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2); -+ ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5); -+ ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl); -+ -+ netif_carrier_on(ag->dev); -+ if (netif_msg_link(ag)) -+ printk(KERN_INFO "%s: link up (%sMbps/%s duplex)\n", -+ ag->dev->name, -+ ag71xx_speed_str(ag), -+ (DUPLEX_FULL == ag->duplex) ? "Full" : "Half"); -+ -+ DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); -+ -+ DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), -+ ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); -+ -+ DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n", -+ ag->dev->name, -+ ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), -+ ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), -+ ag71xx_mii_ctrl_rr(ag)); -+} -+ -+static void ag71xx_phy_link_adjust(struct net_device *dev) -+{ -+ struct ag71xx *ag = netdev_priv(dev); -+ struct phy_device *phydev = ag->phy_dev; -+ unsigned long flags; -+ int status_change = 0; -+ -+ spin_lock_irqsave(&ag->lock, flags); -+ -+ if (phydev->link) { -+ if (ag->duplex != phydev->duplex -+ || ag->speed != phydev->speed) { -+ status_change = 1; -+ } -+ } -+ -+ if (phydev->link != ag->link) -+ status_change = 1; -+ -+ ag->link = phydev->link; -+ ag->duplex = phydev->duplex; -+ ag->speed = phydev->speed; -+ -+ if (status_change) -+ ag71xx_phy_link_update(ag); -+ -+ spin_unlock_irqrestore(&ag->lock, flags); -+} -+ -+void ag71xx_phy_start(struct ag71xx *ag) -+{ -+ if (ag->phy_dev) { -+ phy_start(ag->phy_dev); -+ } else { -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ -+ ag->duplex = pdata->duplex; -+ ag->speed = pdata->speed; -+ ag->link = 1; -+ ag71xx_phy_link_update(ag); -+ } -+} -+ -+void ag71xx_phy_stop(struct ag71xx *ag) -+{ -+ if (ag->phy_dev) { -+ phy_stop(ag->phy_dev); -+ } else { -+ ag->duplex = -1; -+ ag->link = 0; -+ ag->speed = 0; -+ ag71xx_phy_link_update(ag); -+ } -+} -+ -+static int ag71xx_phy_connect_fixed(struct ag71xx *ag) -+{ -+ struct net_device *dev = ag->dev; -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ int ret = 0; -+ -+ /* use fixed settings */ -+ switch (pdata->speed) { -+ case SPEED_10: -+ case SPEED_100: -+ case SPEED_1000: -+ break; -+ default: -+ printk(KERN_ERR "%s: invalid speed specified\n", -+ dev->name); -+ ret = -EINVAL; -+ break; -+ } -+ -+ return ret; -+} -+ -+static int ag71xx_phy_connect_multi(struct ag71xx *ag) -+{ -+ struct net_device *dev = ag->dev; -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ struct phy_device *phydev = NULL; -+ int phy_count = 0; -+ int phy_addr; -+ int ret = 0; -+ -+ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { -+ if (!(pdata->phy_mask & (1 << phy_addr))) -+ continue; -+ -+ if (ag->mii_bus->phy_map[phy_addr] == NULL) -+ continue; -+ -+ DBG("%s: PHY found at %s, uid=%08x\n", -+ dev->name, -+ ag->mii_bus->phy_map[phy_addr]->dev.bus_id, -+ ag->mii_bus->phy_map[phy_addr]->phy_id); -+ -+ if (phydev == NULL) -+ phydev = ag->mii_bus->phy_map[phy_addr]; -+ -+ phy_count++; -+ } -+ -+ switch (phy_count) { -+ case 0: -+ printk(KERN_ERR "%s: no PHY found with phy_mask=%08x\n", -+ dev->name, pdata->phy_mask); -+ ret = -ENODEV; -+ break; -+ case 1: -+ ag->phy_dev = phy_connect(dev, phydev->dev.bus_id, -+ &ag71xx_phy_link_adjust, 0, pdata->phy_if_mode); -+ -+ if (IS_ERR(ag->phy_dev)) { -+ printk(KERN_ERR "%s: could not connect to PHY at %s\n", -+ dev->name, phydev->dev.bus_id); -+ return PTR_ERR(ag->phy_dev); -+ } -+ -+ /* mask with MAC supported features */ -+ if (pdata->has_gbit) -+ phydev->supported &= PHY_GBIT_FEATURES; -+ else -+ phydev->supported &= PHY_BASIC_FEATURES; -+ -+ phydev->advertising = phydev->supported; -+ -+ printk(KERN_DEBUG "%s: connected to PHY at %s " -+ "[uid=%08x, driver=%s]\n", -+ dev->name, phydev->dev.bus_id, -+ phydev->phy_id, phydev->drv->name); -+ -+ ag->link = 0; -+ ag->speed = 0; -+ ag->duplex = -1; -+ break; -+ -+ default: -+ printk(KERN_DEBUG "%s: connected to %d PHYs\n", -+ dev->name, phy_count); -+ ret = ag71xx_phy_connect_fixed(ag); -+ break; -+ } -+ -+ return ret; -+} -+ -+int ag71xx_phy_connect(struct ag71xx *ag) -+{ -+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); -+ -+ if (pdata->phy_mask) -+ return ag71xx_phy_connect_multi(ag); -+ -+ return ag71xx_phy_connect_fixed(ag); -+} -+ -+void ag71xx_phy_disconnect(struct ag71xx *ag) -+{ -+ if (ag->phy_dev) -+ phy_disconnect(ag->phy_dev); -+} -diff -Nur linux-2.6.29.1.orig/drivers/net/phy/micrel.c linux-2.6.29.1/drivers/net/phy/micrel.c ---- linux-2.6.29.1.orig/drivers/net/phy/micrel.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/net/phy/micrel.c 2009-04-13 14:27:34.831085671 +0200 -@@ -0,0 +1,82 @@ -+/* -+ * Driver for Micrel/Kendin PHYs -+ * -+ * 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/delay.h> -+#include <linux/skbuff.h> -+#include <linux/phy.h> -+ -+#define KSZ_REG_INT_CTRL 0x1b -+ -+#define KSZ_INT_LU_EN (1 << 8) /* enable Link Up interrupt */ -+#define KSZ_INT_RF_EN (1 << 9) /* enable Remote Fault interrupt */ -+#define KSZ_INT_LD_EN (1 << 10) /* enable Link Down interrupt */ -+ -+#define KSZ_INT_INIT (KSZ_INT_LU_EN | KSZ_INT_LD_EN) -+ -+static int ksz8041_ack_interrupt(struct phy_device *phydev) -+{ -+ int err; -+ -+ err = phy_read(phydev, KSZ_REG_INT_CTRL); -+ -+ return (err < 0) ? err : 0; -+} -+ -+static int ksz8041_config_intr(struct phy_device *phydev) -+{ -+ int err; -+ -+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) -+ err = phy_write(phydev, KSZ_REG_INT_CTRL, -+ KSZ_INT_INIT); -+ else -+ err = phy_write(phydev, KSZ_REG_INT_CTRL, 0); -+ -+ return err; -+} -+ -+static struct phy_driver ksz8041_phy_driver = { -+ .phy_id = 0x00221512, -+ .name = "Micrel KSZ8041", -+ .phy_id_mask = 0x001fffff, -+ .features = PHY_BASIC_FEATURES, -+ .flags = PHY_HAS_INTERRUPT, -+ .config_aneg = genphy_config_aneg, -+ .read_status = genphy_read_status, -+ .ack_interrupt = ksz8041_ack_interrupt, -+ .config_intr = ksz8041_config_intr, -+ .driver = { -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init micrel_phy_init(void) -+{ -+ return phy_driver_register(&ksz8041_phy_driver); -+} -+ -+static void __exit micrel_phy_exit(void) -+{ -+ phy_driver_unregister(&ksz8041_phy_driver); -+} -+ -+#ifdef MODULE -+module_init(micrel_phy_init); -+module_exit(micrel_phy_exit); -+#else -+subsys_initcall(micrel_phy_init); -+#endif -+ -+MODULE_DESCRIPTION("Micrel/Kendin PHY driver"); -+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); -+MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>"); -+MODULE_LICENSE("GPL v2"); -diff -Nur linux-2.6.29.1.orig/drivers/net/phy/phy.c linux-2.6.29.1/drivers/net/phy/phy.c ---- linux-2.6.29.1.orig/drivers/net/phy/phy.c 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/net/phy/phy.c 2009-04-13 17:29:36.946673592 +0200 -@@ -299,6 +299,50 @@ - } - EXPORT_SYMBOL(phy_ethtool_gset); - -+int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr) -+{ -+ u32 cmd; -+ int tmp; -+ struct ethtool_cmd ecmd = { ETHTOOL_GSET }; -+ struct ethtool_value edata = { ETHTOOL_GLINK }; -+ -+ if (get_user(cmd, (u32 *) useraddr)) -+ return -EFAULT; -+ -+ switch (cmd) { -+ case ETHTOOL_GSET: -+ phy_ethtool_gset(phydev, &ecmd); -+ if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) -+ return -EFAULT; -+ return 0; -+ -+ case ETHTOOL_SSET: -+ if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) -+ return -EFAULT; -+ return phy_ethtool_sset(phydev, &ecmd); -+ -+ case ETHTOOL_NWAY_RST: -+ /* if autoneg is off, it's an error */ -+ tmp = phy_read(phydev, MII_BMCR); -+ if (tmp & BMCR_ANENABLE) { -+ tmp |= (BMCR_ANRESTART); -+ phy_write(phydev, MII_BMCR, tmp); -+ return 0; -+ } -+ return -EINVAL; -+ -+ case ETHTOOL_GLINK: -+ edata.data = (phy_read(phydev, -+ MII_BMSR) & BMSR_LSTATUS) ? 1 : 0; -+ if (copy_to_user(useraddr, &edata, sizeof(edata))) -+ return -EFAULT; -+ return 0; -+ } -+ -+ return -EOPNOTSUPP; -+} -+EXPORT_SYMBOL(phy_ethtool_ioctl); -+ - /** - * phy_mii_ioctl - generic PHY MII ioctl interface - * @phydev: the phy_device struct -@@ -355,8 +399,8 @@ - } - - phy_write(phydev, mii_data->reg_num, val); -- -- if (mii_data->reg_num == MII_BMCR -+ -+ if (mii_data->reg_num == MII_BMCR - && val & BMCR_RESET - && phydev->drv->config_init) { - phy_scan_fixups(phydev); -@@ -476,7 +520,7 @@ - int idx; - - idx = phy_find_setting(phydev->speed, phydev->duplex); -- -+ - idx++; - - idx = phy_find_valid(idx, phydev->supported); -diff -Nur linux-2.6.29.1.orig/drivers/spi/Kconfig linux-2.6.29.1/drivers/spi/Kconfig ---- linux-2.6.29.1.orig/drivers/spi/Kconfig 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/spi/Kconfig 2009-04-13 14:27:34.831085671 +0200 -@@ -53,6 +53,13 @@ - - comment "SPI Master Controller Drivers" - -+config SPI_AR71XX -+ tristate "Atheros AR71xx SPI Controller" -+ depends on SPI_MASTER && ATHEROS_AR71XX -+ select SPI_BITBANG -+ help -+ This is the SPI contoller driver for Atheros AR71xx. -+ - config SPI_ATMEL - tristate "Atmel SPI Controller" - depends on (ARCH_AT91 || AVR32) -diff -Nur linux-2.6.29.1.orig/drivers/spi/Makefile linux-2.6.29.1/drivers/spi/Makefile ---- linux-2.6.29.1.orig/drivers/spi/Makefile 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/spi/Makefile 2009-04-13 14:27:34.835086738 +0200 -@@ -11,6 +11,7 @@ - obj-$(CONFIG_SPI_MASTER) += spi.o - - # SPI master controller drivers (bus) -+obj-$(CONFIG_SPI_AR71XX) += ar71xx_spi.o - obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o - obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o - obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o -diff -Nur linux-2.6.29.1.orig/drivers/spi/ar71xx_spi.c linux-2.6.29.1/drivers/spi/ar71xx_spi.c ---- linux-2.6.29.1.orig/drivers/spi/ar71xx_spi.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/spi/ar71xx_spi.c 2009-04-13 14:27:34.855087329 +0200 -@@ -0,0 +1,240 @@ -+/* -+ * Atheros AR71xx SPI Controller driver -+ * -+ * 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/delay.h> -+#include <linux/spinlock.h> -+#include <linux/workqueue.h> -+#include <linux/platform_device.h> -+#include <linux/io.h> -+#include <linux/spi/spi.h> -+#include <linux/spi/spi_bitbang.h> -+#include <linux/bitops.h> -+ -+#include <asm/mach-ar71xx/ar71xx.h> -+#include <asm/mach-ar71xx/platform.h> -+ -+#define DRV_DESC "Atheros AR71xx SPI Controller driver" -+#define DRV_VERSION "0.2.2" -+#define DRV_NAME "ar71xx-spi" -+ -+#undef PER_BIT_READ -+ -+struct ar71xx_spi { -+ struct spi_bitbang bitbang; -+ u32 ioc_base; -+ u32 reg_ctrl; -+ -+ void __iomem *base; -+ -+ struct platform_device *pdev; -+ u32 (*get_ioc_base)(u8 chip_select, int cs_high, -+ int is_on); -+}; -+ -+static inline u32 ar71xx_spi_rr(struct ar71xx_spi *sp, unsigned reg) -+{ -+ return __raw_readl(sp->base + reg); -+} -+ -+static inline void ar71xx_spi_wr(struct ar71xx_spi *sp, unsigned reg, u32 val) -+{ -+ __raw_writel(val, sp->base + reg); -+} -+ -+static inline struct ar71xx_spi *spidev_to_sp(struct spi_device *spi) -+{ -+ return spi_master_get_devdata(spi->master); -+} -+ -+static u32 ar71xx_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_CS_ALL; -+ else -+ ret = SPI_IOC_CS_ALL & ~SPI_IOC_CS(chip_select); -+ -+ return ret; -+} -+ -+static void ar71xx_spi_chipselect(struct spi_device *spi, int value) -+{ -+ struct ar71xx_spi *sp = spidev_to_sp(spi); -+ void __iomem *base = sp->base; -+ u32 ioc_base; -+ -+ switch (value) { -+ case BITBANG_CS_INACTIVE: -+ ioc_base = sp->get_ioc_base(spi->chip_select, -+ (spi->mode & SPI_CS_HIGH) != 0, -+ AR71XX_SPI_CS_INACTIVE); -+ -+ __raw_writel(ioc_base, base + SPI_REG_IOC); -+ __raw_writel(sp->reg_ctrl, base + SPI_REG_CTRL); -+ __raw_writel(0, base + SPI_REG_FS); -+ break; -+ -+ case BITBANG_CS_ACTIVE: -+ ioc_base = sp->get_ioc_base(spi->chip_select, -+ (spi->mode & SPI_CS_HIGH) != 0, -+ AR71XX_SPI_CS_ACTIVE); -+ -+ __raw_writel(SPI_FS_GPIO, base + SPI_REG_FS); -+ /* TODO: setup speed */ -+ __raw_writel(0x43, base + SPI_REG_CTRL); -+ __raw_writel(ioc_base, base + SPI_REG_IOC); -+ sp->ioc_base = ioc_base; -+ break; -+ } -+} -+ -+static u32 ar71xx_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs, -+ u32 word, u8 bits) -+{ -+ struct ar71xx_spi *sp = spidev_to_sp(spi); -+ void __iomem *base = sp->base; -+ u32 ioc = sp->ioc_base; -+ u32 ret; -+ -+ /* clock starts at inactive polarity */ -+ for (word <<= (32 - bits); likely(bits); bits--) { -+ u32 out; -+ -+ if (word & (1 << 31)) -+ out = ioc | SPI_IOC_DO; -+ else -+ out = ioc & ~SPI_IOC_DO; -+ -+ /* setup MSB (to slave) on trailing edge */ -+ __raw_writel(out, base + SPI_REG_IOC); -+ -+ __raw_writel(out | SPI_IOC_CLK, base + SPI_REG_IOC); -+ -+ word <<= 1; -+ -+#ifdef PER_BIT_READ -+ /* sample MSB (from slave) on leading edge */ -+ ret = __raw_readl(base + SPI_REG_RDS); -+ __raw_writel(out, base + SPI_REG_IOC); -+#endif -+ -+ } -+ -+#ifndef PER_BIT_READ -+ ret = __raw_readl(base + SPI_REG_RDS); -+#endif -+ return ret; -+} -+ -+static int ar71xx_spi_probe(struct platform_device *pdev) -+{ -+ struct spi_master *master; -+ struct ar71xx_spi *sp; -+ struct ar71xx_spi_platform_data *pdata; -+ struct resource *r; -+ int ret; -+ -+ master = spi_alloc_master(&pdev->dev, sizeof(*sp)); -+ if (master == NULL) { -+ dev_err(&pdev->dev, "failed to allocate spi master\n"); -+ return -ENOMEM; -+ } -+ -+ sp = spi_master_get_devdata(master); -+ platform_set_drvdata(pdev, sp); -+ -+ pdata = pdev->dev.platform_data; -+ -+ sp->bitbang.master = spi_master_get(master); -+ sp->bitbang.chipselect = ar71xx_spi_chipselect; -+ sp->bitbang.txrx_word[SPI_MODE_0] = ar71xx_spi_txrx_mode0; -+ -+ sp->get_ioc_base = ar71xx_spi_get_ioc_base; -+ if (pdata) { -+ sp->bitbang.master->bus_num = pdata->bus_num; -+ sp->bitbang.master->num_chipselect = pdata->num_chipselect; -+ if (pdata->get_ioc_base) -+ sp->get_ioc_base = pdata->get_ioc_base; -+ } else { -+ sp->bitbang.master->bus_num = 0; -+ sp->bitbang.master->num_chipselect = 3; -+ } -+ -+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (r == NULL) { -+ ret = -ENOENT; -+ goto err1; -+ } -+ -+ sp->base = ioremap_nocache(r->start, r->end - r->start + 1); -+ if (!sp->base) { -+ ret = -ENXIO; -+ goto err1; -+ } -+ -+ sp->reg_ctrl = ar71xx_spi_rr(sp, SPI_REG_IOC); -+ -+ ret = spi_bitbang_start(&sp->bitbang); -+ if (!ret) -+ return 0; -+ -+ iounmap(sp->base); -+err1: -+ platform_set_drvdata(pdev, NULL); -+ spi_master_put(sp->bitbang.master); -+ -+ return ret; -+} -+ -+static int ar71xx_spi_remove(struct platform_device *pdev) -+{ -+ struct ar71xx_spi *sp = platform_get_drvdata(pdev); -+ -+ spi_bitbang_stop(&sp->bitbang); -+ iounmap(sp->base); -+ platform_set_drvdata(pdev, NULL); -+ spi_master_put(sp->bitbang.master); -+ -+ return 0; -+} -+ -+static struct platform_driver ar71xx_spi_drv = { -+ .probe = ar71xx_spi_probe, -+ .remove = ar71xx_spi_remove, -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init ar71xx_spi_init(void) -+{ -+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); -+ return platform_driver_register(&ar71xx_spi_drv); -+} -+module_init(ar71xx_spi_init); -+ -+static void __exit ar71xx_spi_exit(void) -+{ -+ platform_driver_unregister(&ar71xx_spi_drv); -+} -+module_exit(ar71xx_spi_exit); -+ -+MODULE_ALIAS("platform:" DRV_NAME); -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); -+MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>"); -+MODULE_LICENSE("GPL v2"); -diff -Nur linux-2.6.29.1.orig/drivers/usb/host/Kconfig linux-2.6.29.1/drivers/usb/host/Kconfig ---- linux-2.6.29.1.orig/drivers/usb/host/Kconfig 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/usb/host/Kconfig 2009-04-13 14:27:34.855087329 +0200 -@@ -81,6 +81,12 @@ - depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX) - default y - -+config USB_EHCI_AR71XX -+ bool "USB EHCI support for AR71xx" -+ depends on USB_EHCI_HCD && ATHEROS_AR71XX -+ help -+ Support for Atheros AR71xx built-in EHCI controller -+ - config USB_EHCI_FSL - bool "Support for Freescale on-chip EHCI USB controller" - depends on USB_EHCI_HCD && FSL_SOC -@@ -154,6 +160,12 @@ - To compile this driver as a module, choose M here: the - module will be called ohci-hcd. - -+config USB_OHCI_AR71XX -+ bool "USB OHCI support for Atheros AR71xx" -+ depends on USB_OHCI_HCD && ATHEROS_AR71XX -+ help -+ Support for Atheros AR71xx built-in OHCI controller -+ - config USB_OHCI_HCD_PPC_SOC - bool "OHCI support for on-chip PPC USB controller" - depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx) -diff -Nur linux-2.6.29.1.orig/drivers/usb/host/ehci-ar71xx.c linux-2.6.29.1/drivers/usb/host/ehci-ar71xx.c ---- linux-2.6.29.1.orig/drivers/usb/host/ehci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/usb/host/ehci-ar71xx.c 2009-04-13 14:27:34.859087838 +0200 -@@ -0,0 +1,235 @@ -+/* -+ * Bus Glue for Atheros AR71xx built-in EHCI controller. -+ * -+ * 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 -+ * Copyright (C) 2007 Atheros Communications, Inc. -+ * -+ * 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/delay.h> -+ -+#include <asm/mach-ar71xx/platform.h> -+ -+extern int usb_disabled(void); -+ -+static int ehci_ar71xx_init(struct usb_hcd *hcd) -+{ -+ struct ehci_hcd *ehci = hcd_to_ehci(hcd); -+ int ret; -+ -+ ehci->caps = hcd->regs; -+ ehci->regs = hcd->regs + -+ HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); -+ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); -+ -+ ehci->sbrn = 0x20; -+ -+ ehci_reset(ehci); -+ -+ ret = ehci_init(hcd); -+ if (ret) -+ return ret; -+ -+ ehci_port_power(ehci, 0); -+ -+ return 0; -+} -+ -+static int ehci_ar91xx_init(struct usb_hcd *hcd) -+{ -+ struct ehci_hcd *ehci = hcd_to_ehci(hcd); -+ int ret; -+ -+ ehci->caps = hcd->regs + 0x100; -+ ehci->regs = hcd->regs + 0x100 + -+ HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); -+ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); -+ -+ hcd->has_tt = 1; -+ ehci->sbrn = 0x20; -+ -+ ehci_reset(ehci); -+ -+ ret = ehci_init(hcd); -+ if (ret) -+ return ret; -+ -+ ehci_port_power(ehci, 0); -+ -+ return 0; -+} -+ -+static int ehci_ar71xx_probe(const struct hc_driver *driver, -+ struct usb_hcd **hcd_out, -+ struct platform_device *pdev) -+{ -+ struct usb_hcd *hcd; -+ struct resource *res; -+ int irq; -+ int ret; -+ -+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); -+ if (!res) { -+ dev_dbg(&pdev->dev, "no IRQ specified for %s\n", -+ pdev->dev.bus_id); -+ return -ENODEV; -+ } -+ irq = res->start; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_dbg(&pdev->dev, "no base address specified for %s\n", -+ pdev->dev.bus_id); -+ return -ENODEV; -+ } -+ -+ hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id); -+ if (!hcd) -+ return -ENOMEM; -+ -+ hcd->rsrc_start = res->start; -+ hcd->rsrc_len = res->end - res->start + 1; -+ -+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { -+ dev_dbg(&pdev->dev, "controller already in use\n"); -+ ret = -EBUSY; -+ goto err_put_hcd; -+ } -+ -+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); -+ if (!hcd->regs) { -+ dev_dbg(&pdev->dev, "error mapping memory\n"); -+ ret = -EFAULT; -+ goto err_release_region; -+ } -+ -+ ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); -+ if (ret) -+ goto err_iounmap; -+ -+ return 0; -+ -+ err_iounmap: -+ iounmap(hcd->regs); -+ -+ err_release_region: -+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -+ err_put_hcd: -+ usb_put_hcd(hcd); -+ return ret; -+} -+ -+static void ehci_ar71xx_remove(struct usb_hcd *hcd, -+ struct platform_device *pdev) -+{ -+ usb_remove_hcd(hcd); -+ iounmap(hcd->regs); -+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -+ usb_put_hcd(hcd); -+} -+ -+static const struct hc_driver ehci_ar71xx_hc_driver = { -+ .description = hcd_name, -+ .product_desc = "Atheros AR71xx built-in EHCI controller", -+ .hcd_priv_size = sizeof(struct ehci_hcd), -+ -+ .irq = ehci_irq, -+ .flags = HCD_MEMORY | HCD_USB2, -+ -+ .reset = ehci_ar71xx_init, -+ .start = ehci_run, -+ .stop = ehci_stop, -+ .shutdown = ehci_shutdown, -+ -+ .urb_enqueue = ehci_urb_enqueue, -+ .urb_dequeue = ehci_urb_dequeue, -+ .endpoint_disable = ehci_endpoint_disable, -+ -+ .get_frame_number = ehci_get_frame, -+ -+ .hub_status_data = ehci_hub_status_data, -+ .hub_control = ehci_hub_control, -+#ifdef CONFIG_PM -+ .hub_suspend = ehci_hub_suspend, -+ .hub_resume = ehci_hub_resume, -+#endif -+ .relinquish_port = ehci_relinquish_port, -+ .port_handed_over = ehci_port_handed_over, -+}; -+ -+static const struct hc_driver ehci_ar91xx_hc_driver = { -+ .description = hcd_name, -+ .product_desc = "Atheros AR91xx built-in EHCI controller", -+ .hcd_priv_size = sizeof(struct ehci_hcd), -+ .irq = ehci_irq, -+ .flags = HCD_MEMORY | HCD_USB2, -+ -+ .reset = ehci_ar91xx_init, -+ .start = ehci_run, -+ .stop = ehci_stop, -+ .shutdown = ehci_shutdown, -+ -+ .urb_enqueue = ehci_urb_enqueue, -+ .urb_dequeue = ehci_urb_dequeue, -+ .endpoint_disable = ehci_endpoint_disable, -+ -+ .get_frame_number = ehci_get_frame, -+ -+ .hub_status_data = ehci_hub_status_data, -+ .hub_control = ehci_hub_control, -+#ifdef CONFIG_PM -+ .hub_suspend = ehci_hub_suspend, -+ .hub_resume = ehci_hub_resume, -+#endif -+ .relinquish_port = ehci_relinquish_port, -+ .port_handed_over = ehci_port_handed_over, -+}; -+ -+static int ehci_ar71xx_driver_probe(struct platform_device *pdev) -+{ -+ struct ar71xx_ehci_platform_data *pdata; -+ struct usb_hcd *hcd = NULL; -+ int ret; -+ -+ if (usb_disabled()) -+ return -ENODEV; -+ -+ pdata = pdev->dev.platform_data; -+ if (!pdata) { -+ dev_err(&pdev->dev, "no platform data specified for %s\n", -+ pdev->dev.bus_id); -+ return -ENODEV; -+ } -+ -+ if (pdata->is_ar91xx) -+ ret = ehci_ar71xx_probe(&ehci_ar91xx_hc_driver, &hcd, pdev); -+ else -+ ret = ehci_ar71xx_probe(&ehci_ar71xx_hc_driver, &hcd, pdev); -+ -+ return ret; -+} -+ -+static int ehci_ar71xx_driver_remove(struct platform_device *pdev) -+{ -+ struct usb_hcd *hcd = platform_get_drvdata(pdev); -+ -+ ehci_ar71xx_remove(hcd, pdev); -+ return 0; -+} -+ -+MODULE_ALIAS("platform:ar71xx-ehci"); -+ -+static struct platform_driver ehci_ar71xx_driver = { -+ .probe = ehci_ar71xx_driver_probe, -+ .remove = ehci_ar71xx_driver_remove, -+ .driver = { -+ .name = "ar71xx-ehci", -+ } -+}; -diff -Nur linux-2.6.29.1.orig/drivers/usb/host/ehci-hcd.c linux-2.6.29.1/drivers/usb/host/ehci-hcd.c ---- linux-2.6.29.1.orig/drivers/usb/host/ehci-hcd.c 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/usb/host/ehci-hcd.c 2009-04-13 14:27:34.859087838 +0200 -@@ -1036,6 +1036,11 @@ - #define PLATFORM_DRIVER ixp4xx_ehci_driver - #endif - -+#ifdef CONFIG_USB_EHCI_AR71XX -+#include "ehci-ar71xx.c" -+#define PLATFORM_DRIVER ehci_ar71xx_driver -+#endif -+ - #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ - !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) - #error "missing bus glue for ehci-hcd" -diff -Nur linux-2.6.29.1.orig/drivers/usb/host/ohci-ar71xx.c linux-2.6.29.1/drivers/usb/host/ohci-ar71xx.c ---- linux-2.6.29.1.orig/drivers/usb/host/ohci-ar71xx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/usb/host/ohci-ar71xx.c 2009-04-13 14:27:34.887088611 +0200 -@@ -0,0 +1,165 @@ -+/* -+ * OHCI HCD (Host Controller Driver) for USB. -+ * -+ * Bus Glue for Atheros AR71xx built-in OHCI controller. -+ * -+ * 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 -+ * Copyright (C) 2007 Atheros Communications, Inc. -+ * -+ * 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/delay.h> -+ -+extern int usb_disabled(void); -+ -+static int usb_hcd_ar71xx_probe(const struct hc_driver *driver, -+ struct platform_device *pdev) -+{ -+ struct usb_hcd *hcd; -+ struct resource *res; -+ int irq; -+ int ret; -+ -+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); -+ if (!res) { -+ dev_dbg(&pdev->dev, "no IRQ specified for %s\n", -+ pdev->dev.bus_id); -+ return -ENODEV; -+ } -+ irq = res->start; -+ -+ hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id); -+ if (!hcd) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_dbg(&pdev->dev, "no base address specified for %s\n", -+ pdev->dev.bus_id); -+ ret = -ENODEV; -+ goto err_put_hcd; -+ } -+ hcd->rsrc_start = res->start; -+ hcd->rsrc_len = res->end - res->start + 1; -+ -+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { -+ dev_dbg(&pdev->dev, "controller already in use\n"); -+ ret = -EBUSY; -+ goto err_put_hcd; -+ } -+ -+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); -+ if (!hcd->regs) { -+ dev_dbg(&pdev->dev, "error mapping memory\n"); -+ ret = -EFAULT; -+ goto err_release_region; -+ } -+ -+ ohci_hcd_init(hcd_to_ohci(hcd)); -+ -+ ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); -+ if (ret) -+ goto err_stop_hcd; -+ -+ return 0; -+ -+ err_stop_hcd: -+ iounmap(hcd->regs); -+ err_release_region: -+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -+ err_put_hcd: -+ usb_put_hcd(hcd); -+ return ret; -+} -+ -+void usb_hcd_ar71xx_remove(struct usb_hcd *hcd, struct platform_device *pdev) -+{ -+ usb_remove_hcd(hcd); -+ iounmap(hcd->regs); -+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -+ usb_put_hcd(hcd); -+} -+ -+static int __devinit ohci_ar71xx_start(struct usb_hcd *hcd) -+{ -+ struct ohci_hcd *ohci = hcd_to_ohci(hcd); -+ int ret; -+ -+ ret = ohci_init(ohci); -+ if (ret < 0) -+ return ret; -+ -+ ret = ohci_run(ohci); -+ if (ret < 0) -+ goto err; -+ -+ return 0; -+ -+ err: -+ ohci_stop(hcd); -+ return ret; -+} -+ -+static const struct hc_driver ohci_ar71xx_hc_driver = { -+ .description = hcd_name, -+ .product_desc = "Atheros AR71xx built-in OHCI controller", -+ .hcd_priv_size = sizeof(struct ohci_hcd), -+ -+ .irq = ohci_irq, -+ .flags = HCD_USB11 | HCD_MEMORY, -+ -+ .start = ohci_ar71xx_start, -+ .stop = ohci_stop, -+ .shutdown = ohci_shutdown, -+ -+ .urb_enqueue = ohci_urb_enqueue, -+ .urb_dequeue = ohci_urb_dequeue, -+ .endpoint_disable = ohci_endpoint_disable, -+ -+ /* -+ * scheduling support -+ */ -+ .get_frame_number = ohci_get_frame, -+ -+ /* -+ * root hub support -+ */ -+ .hub_status_data = ohci_hub_status_data, -+ .hub_control = ohci_hub_control, -+ .start_port_reset = ohci_start_port_reset, -+}; -+ -+static int ohci_hcd_ar71xx_drv_probe(struct platform_device *pdev) -+{ -+ if (usb_disabled()) -+ return -ENODEV; -+ -+ return usb_hcd_ar71xx_probe(&ohci_ar71xx_hc_driver, pdev); -+} -+ -+static int ohci_hcd_ar71xx_drv_remove(struct platform_device *pdev) -+{ -+ struct usb_hcd *hcd = platform_get_drvdata(pdev); -+ -+ usb_hcd_ar71xx_remove(hcd, pdev); -+ return 0; -+} -+ -+MODULE_ALIAS("platform:ar71xx-ohci"); -+ -+static struct platform_driver ohci_hcd_ar71xx_driver = { -+ .probe = ohci_hcd_ar71xx_drv_probe, -+ .remove = ohci_hcd_ar71xx_drv_remove, -+ .shutdown = usb_hcd_platform_shutdown, -+ .driver = { -+ .name = "ar71xx-ohci", -+ .owner = THIS_MODULE, -+ }, -+}; -diff -Nur linux-2.6.29.1.orig/drivers/usb/host/ohci-hcd.c linux-2.6.29.1/drivers/usb/host/ohci-hcd.c ---- linux-2.6.29.1.orig/drivers/usb/host/ohci-hcd.c 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/usb/host/ohci-hcd.c 2009-04-13 14:27:34.887088611 +0200 -@@ -1080,6 +1080,11 @@ - #define TMIO_OHCI_DRIVER ohci_hcd_tmio_driver - #endif - -+#ifdef CONFIG_USB_OHCI_AR71XX -+#include "ohci-ar71xx.c" -+#define PLATFORM_DRIVER ohci_hcd_ar71xx_driver -+#endif -+ - #if !defined(PCI_DRIVER) && \ - !defined(PLATFORM_DRIVER) && \ - !defined(OF_PLATFORM_DRIVER) && \ -diff -Nur linux-2.6.29.1.orig/drivers/watchdog/Kconfig linux-2.6.29.1/drivers/watchdog/Kconfig ---- linux-2.6.29.1.orig/drivers/watchdog/Kconfig 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/watchdog/Kconfig 2009-04-13 14:27:34.891089680 +0200 -@@ -766,6 +766,13 @@ - help - Hardware driver for the built-in watchdog timer on TXx9 MIPS SoCs. - -+config AR71XX_WDT -+ tristate "Atheros AR71xx Watchdog Timer" -+ depends on ATHEROS_AR71XX -+ help -+ Hardware driver for the built-in watchdog timer on the Atheros -+ AR71xx SoCs. -+ - # PARISC Architecture - - # POWERPC Architecture -diff -Nur linux-2.6.29.1.orig/drivers/watchdog/Makefile linux-2.6.29.1/drivers/watchdog/Makefile ---- linux-2.6.29.1.orig/drivers/watchdog/Makefile 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/drivers/watchdog/Makefile 2009-04-13 14:27:34.891089680 +0200 -@@ -107,6 +107,7 @@ - obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o - obj-$(CONFIG_AR7_WDT) += ar7_wdt.o - obj-$(CONFIG_TXX9_WDT) += txx9wdt.o -+obj-$(CONFIG_AR71XX_WDT) += ar71xx_wdt.o - - # PARISC Architecture - -diff -Nur linux-2.6.29.1.orig/drivers/watchdog/ar71xx_wdt.c linux-2.6.29.1/drivers/watchdog/ar71xx_wdt.c ---- linux-2.6.29.1.orig/drivers/watchdog/ar71xx_wdt.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/drivers/watchdog/ar71xx_wdt.c 2009-04-13 14:27:34.915091622 +0200 -@@ -0,0 +1,270 @@ -+/* -+ * Driver for the Atheros AR71xx SoC's built-in hardware watchdog timer. -+ * -+ * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org> -+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> -+ * -+ * This driver was based on: drivers/watchdog/ixp4xx_wdt.c -+ * Author: Deepak Saxena <dsaxena@plexity.net> -+ * Copyright 2004 (c) MontaVista, Software, Inc. -+ * -+ * which again was based on sa1100 driver, -+ * Copyright (C) 2000 Oleg Drokin <green@crimea.edu> -+ * -+ * 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/bitops.h> -+#include <linux/errno.h> -+#include <linux/fs.h> -+#include <linux/init.h> -+#include <linux/kernel.h> -+#include <linux/miscdevice.h> -+#include <linux/module.h> -+#include <linux/moduleparam.h> -+#include <linux/platform_device.h> -+#include <linux/types.h> -+#include <linux/watchdog.h> -+ -+#include <asm/mach-ar71xx/ar71xx.h> -+ -+#define DRV_NAME "ar71xx-wdt" -+#define DRV_DESC "Atheros AR71xx hardware watchdog driver" -+#define DRV_VERSION "0.1.0" -+ -+#define WDT_TIMEOUT 15 /* seconds */ -+ -+static int nowayout = WATCHDOG_NOWAYOUT; -+ -+#ifdef CONFIG_WATCHDOG_NOWAYOUT -+module_param(nowayout, int, 0); -+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " -+ "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); -+#endif -+ -+static unsigned long wdt_flags; -+ -+#define WDT_FLAGS_BUSY 0 -+#define WDT_FLAGS_EXPECT_CLOSE 1 -+ -+static int wdt_timeout = WDT_TIMEOUT; -+static int boot_status; -+static int max_timeout; -+ -+static void inline ar71xx_wdt_keepalive(void) -+{ -+ ar71xx_reset_wr(AR71XX_RESET_REG_WDOG, ar71xx_ahb_freq * wdt_timeout); -+} -+ -+static void inline ar71xx_wdt_enable(void) -+{ -+ printk(KERN_DEBUG DRV_NAME ": enabling watchdog timer\n"); -+ ar71xx_wdt_keepalive(); -+ ar71xx_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR); -+} -+ -+static void inline ar71xx_wdt_disable(void) -+{ -+ printk(KERN_DEBUG DRV_NAME ": disabling watchdog timer\n"); -+ ar71xx_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_NONE); -+} -+ -+static int ar71xx_wdt_set_timeout(int val) -+{ -+ if (val < 1 || val > max_timeout) -+ return -EINVAL; -+ -+ wdt_timeout = val; -+ ar71xx_wdt_keepalive(); -+ -+ printk(KERN_DEBUG DRV_NAME ": timeout=%d secs\n", wdt_timeout); -+ -+ return 0; -+} -+ -+static int ar71xx_wdt_open(struct inode *inode, struct file *file) -+{ -+ if (test_and_set_bit(WDT_FLAGS_BUSY, &wdt_flags)) -+ return -EBUSY; -+ -+ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags); -+ -+ ar71xx_wdt_enable(); -+ -+ return nonseekable_open(inode, file); -+} -+ -+static int ar71xx_wdt_release(struct inode *inode, struct file *file) -+{ -+ if (test_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags)) { -+ ar71xx_wdt_disable(); -+ } else { -+ printk(KERN_CRIT DRV_NAME ": device closed unexpectedly, " -+ "watchdog timer will not stop!\n"); -+ } -+ -+ clear_bit(WDT_FLAGS_BUSY, &wdt_flags); -+ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags); -+ -+ return 0; -+} -+ -+static ssize_t ar71xx_wdt_write(struct file *file, const char *data, -+ size_t len, loff_t *ppos) -+{ -+ if (len) { -+ if (!nowayout) { -+ size_t i; -+ -+ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags); -+ -+ for (i = 0; i != len; i++) { -+ char c; -+ -+ if (get_user(c, data + i)) -+ return -EFAULT; -+ -+ if (c == 'V') -+ set_bit(WDT_FLAGS_EXPECT_CLOSE, -+ &wdt_flags); -+ } -+ } -+ -+ ar71xx_wdt_keepalive(); -+ } -+ -+ return len; -+} -+ -+static struct watchdog_info ar71xx_wdt_info = { -+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | -+ WDIOF_MAGICCLOSE | WDIOF_CARDRESET, -+ .firmware_version = 0, -+ .identity = "AR71XX watchdog", -+}; -+ -+static int ar71xx_wdt_ioctl(struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ int t; -+ int ret; -+ -+ switch (cmd) { -+ case WDIOC_GETSUPPORT: -+ ret = copy_to_user((struct watchdog_info *)arg, -+ &ar71xx_wdt_info, -+ sizeof(&ar71xx_wdt_info)) ? -EFAULT : 0; -+ break; -+ -+ case WDIOC_GETSTATUS: -+ ret = put_user(0, (int *)arg) ? -EFAULT : 0; -+ break; -+ -+ case WDIOC_GETBOOTSTATUS: -+ ret = put_user(boot_status, (int *)arg) ? -EFAULT : 0; -+ break; -+ -+ case WDIOC_KEEPALIVE: -+ ar71xx_wdt_keepalive(); -+ ret = 0; -+ break; -+ -+ case WDIOC_SETTIMEOUT: -+ ret = get_user(t, (int *)arg) ? -EFAULT : 0; -+ if (ret) -+ break; -+ -+ ret = ar71xx_wdt_set_timeout(t); -+ if (ret) -+ break; -+ -+ /* fallthrough */ -+ case WDIOC_GETTIMEOUT: -+ ret = put_user(wdt_timeout, (int *)arg) ? -EFAULT : 0; -+ break; -+ -+ default: -+ ret = -ENOTTY; -+ break; -+ } -+ -+ return ret; -+} -+ -+static const struct file_operations ar71xx_wdt_fops = { -+ .owner = THIS_MODULE, -+ .write = ar71xx_wdt_write, -+ .ioctl = ar71xx_wdt_ioctl, -+ .open = ar71xx_wdt_open, -+ .release = ar71xx_wdt_release, -+}; -+ -+static struct miscdevice ar71xx_wdt_miscdev = { -+ .minor = WATCHDOG_MINOR, -+ .name = "watchdog", -+ .fops = &ar71xx_wdt_fops, -+}; -+ -+static int __devinit ar71xx_wdt_probe(struct platform_device *pdev) -+{ -+ int ret; -+ -+ max_timeout = (0xfffffffful / ar71xx_ahb_freq); -+ wdt_timeout = (max_timeout < WDT_TIMEOUT) ? max_timeout : WDT_TIMEOUT; -+ -+ boot_status = -+ (ar71xx_reset_rr(AR71XX_RESET_REG_WDOG_CTRL) & WDOG_CTRL_LAST_RESET) ? -+ WDIOF_CARDRESET : 0; -+ -+ ret = misc_register(&ar71xx_wdt_miscdev); -+ if (ret) -+ goto err_out; -+ -+ printk(KERN_INFO DRV_DESC " version " DRV_VERSION "\n"); -+ -+ printk(KERN_DEBUG DRV_NAME ": timeout=%d secs (max=%d)\n", -+ wdt_timeout, max_timeout); -+ -+ return 0; -+ -+err_out: -+ return ret; -+} -+ -+static int __devexit ar71xx_wdt_remove(struct platform_device *pdev) -+{ -+ misc_deregister(&ar71xx_wdt_miscdev); -+ return 0; -+} -+ -+static struct platform_driver ar71xx_wdt_driver = { -+ .probe = ar71xx_wdt_probe, -+ .remove = __devexit_p(ar71xx_wdt_remove), -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init ar71xx_wdt_init(void) -+{ -+ return platform_driver_register(&ar71xx_wdt_driver); -+} -+module_init(ar71xx_wdt_init); -+ -+static void __exit ar71xx_wdt_exit(void) -+{ -+ platform_driver_unregister(&ar71xx_wdt_driver); -+} -+module_exit(ar71xx_wdt_exit); -+ -+MODULE_DESCRIPTION(DRV_DESC); -+MODULE_VERSION(DRV_VERSION); -+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org"); -+MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" DRV_NAME); -+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); -diff -Nur linux-2.6.29.1.orig/include/asm-mips/mips_machine.h linux-2.6.29.1/include/asm-mips/mips_machine.h ---- linux-2.6.29.1.orig/include/asm-mips/mips_machine.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/include/asm-mips/mips_machine.h 2009-04-13 14:27:34.915091622 +0200 -@@ -0,0 +1,47 @@ -+/* -+ * Copyright (C) 2008 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 __ASM_MIPS_MACHINE_H -+#define __ASM_MIPS_MACHINE_H -+ -+#include <linux/init.h> -+#include <linux/list.h> -+ -+#define MIPS_MACHINE_NAME_LEN 64 -+ -+struct mips_machine { -+ unsigned long mach_type; -+ void (*mach_setup)(void); -+ unsigned char mach_name[MIPS_MACHINE_NAME_LEN]; -+ struct list_head list; -+}; -+ -+void mips_machine_register(struct mips_machine *) __init; -+void mips_machine_setup(unsigned long machtype) __init; -+ -+extern unsigned char mips_machine_name[MIPS_MACHINE_NAME_LEN]; -+ -+#define MIPS_MACHINE(_type, _name, _setup) \ -+static struct mips_machine machine_##_type __initdata = \ -+{ \ -+ .mach_type = _type, \ -+ .mach_name = _name, \ -+ .mach_setup = _setup, \ -+}; \ -+ \ -+static int __init register_machine_##_type(void) \ -+{ \ -+ mips_machine_register(&machine_##_type); \ -+ return 0; \ -+} \ -+ \ -+pure_initcall(register_machine_##_type) -+ -+#endif /* __ASM_MIPS_MACHINE_H */ -+ -diff -Nur linux-2.6.29.1.orig/include/linux/ath9k_platform.h linux-2.6.29.1/include/linux/ath9k_platform.h ---- linux-2.6.29.1.orig/include/linux/ath9k_platform.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/include/linux/ath9k_platform.h 2009-04-13 14:27:34.915091622 +0200 -@@ -0,0 +1,20 @@ -+/* -+ * ath9k platform data defines -+ * -+ * Copyright (C) 2008 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 _LINUX_ATH9K_PLATFORM_H -+#define _LINUX_ATH9L_PLATFORM_H -+ -+#define ATH9K_PLAT_EEP_MAX_WORDS 2048 -+ -+struct ath9k_platform_data { -+ u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS]; -+}; -+ -+#endif /* _LINUX_ATH9K_PLATFORM_H */ -diff -Nur linux-2.6.29.1.orig/include/linux/gpio_buttons.h linux-2.6.29.1/include/linux/gpio_buttons.h ---- linux-2.6.29.1.orig/include/linux/gpio_buttons.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/include/linux/gpio_buttons.h 2009-04-13 14:27:34.919091574 +0200 -@@ -0,0 +1,35 @@ -+/* -+ * Definitions for the GPIO buttons interface driver -+ * -+ * Copyright (C) 2007,2008 Gabor Juhos <juhosg at openwrt.org> -+ * -+ * This file was based on: /include/linux/gpio_keys.h -+ * The original gpio_keys.h seems not to have a license. -+ * -+ * 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 _GPIO_BUTTONS_H_ -+#define _GPIO_BUTTONS_H_ -+ -+struct gpio_button { -+ int gpio; /* GPIO line number */ -+ int active_low; -+ char *desc; /* button description */ -+ int type; /* input event type (EV_KEY, EV_SW) */ -+ int code; /* input event code (KEY_*, SW_*) */ -+ int count; -+ int threshold; /* count threshold */ -+}; -+ -+struct gpio_buttons_platform_data { -+ struct gpio_button *buttons; -+ int nbuttons; /* number of buttons */ -+ int poll_interval; /* polling interval */ -+}; -+ -+#endif /* _GPIO_BUTTONS_H_ */ -+ -diff -Nur linux-2.6.29.1.orig/include/linux/phy.h linux-2.6.29.1/include/linux/phy.h ---- linux-2.6.29.1.orig/include/linux/phy.h 2009-04-02 22:55:27.000000000 +0200 -+++ linux-2.6.29.1/include/linux/phy.h 2009-04-13 17:29:37.057990291 +0200 -@@ -478,6 +478,7 @@ - void phy_stop_machine(struct phy_device *phydev); - int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd); - int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd); -+int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr); - int phy_mii_ioctl(struct phy_device *phydev, - struct mii_ioctl_data *mii_data, int cmd); - int phy_start_interrupts(struct phy_device *phydev); -diff -Nur linux-2.6.29.1.orig/include/linux/phy.h.orig linux-2.6.29.1/include/linux/phy.h.orig ---- linux-2.6.29.1.orig/include/linux/phy.h.orig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.29.1/include/linux/phy.h.orig 2009-04-02 22:55:27.000000000 +0200 -@@ -0,0 +1,500 @@ -+/* -+ * include/linux/phy.h -+ * -+ * Framework and drivers for configuring and reading different PHYs -+ * Based on code in sungem_phy.c and gianfar_phy.c -+ * -+ * Author: Andy Fleming -+ * -+ * Copyright (c) 2004 Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ * -+ */ -+ -+#ifndef __PHY_H -+#define __PHY_H -+ -+#include <linux/spinlock.h> -+#include <linux/device.h> -+#include <linux/ethtool.h> -+#include <linux/mii.h> -+#include <linux/timer.h> -+#include <linux/workqueue.h> -+ -+#include <asm/atomic.h> -+ -+#define PHY_BASIC_FEATURES (SUPPORTED_10baseT_Half | \ -+ SUPPORTED_10baseT_Full | \ -+ SUPPORTED_100baseT_Half | \ -+ SUPPORTED_100baseT_Full | \ -+ SUPPORTED_Autoneg | \ -+ SUPPORTED_TP | \ -+ SUPPORTED_MII) -+ -+#define PHY_GBIT_FEATURES (PHY_BASIC_FEATURES | \ -+ SUPPORTED_1000baseT_Half | \ -+ SUPPORTED_1000baseT_Full) -+ -+/* -+ * Set phydev->irq to PHY_POLL if interrupts are not supported, -+ * or not desired for this PHY. Set to PHY_IGNORE_INTERRUPT if -+ * the attached driver handles the interrupt -+ */ -+#define PHY_POLL -1 -+#define PHY_IGNORE_INTERRUPT -2 -+ -+#define PHY_HAS_INTERRUPT 0x00000001 -+#define PHY_HAS_MAGICANEG 0x00000002 -+ -+/* Interface Mode definitions */ -+typedef enum { -+ PHY_INTERFACE_MODE_MII, -+ PHY_INTERFACE_MODE_GMII, -+ PHY_INTERFACE_MODE_SGMII, -+ PHY_INTERFACE_MODE_TBI, -+ PHY_INTERFACE_MODE_RMII, -+ PHY_INTERFACE_MODE_RGMII, -+ PHY_INTERFACE_MODE_RGMII_ID, -+ PHY_INTERFACE_MODE_RGMII_RXID, -+ PHY_INTERFACE_MODE_RGMII_TXID, -+ PHY_INTERFACE_MODE_RTBI -+} phy_interface_t; -+ -+ -+#define PHY_INIT_TIMEOUT 100000 -+#define PHY_STATE_TIME 1 -+#define PHY_FORCE_TIMEOUT 10 -+#define PHY_AN_TIMEOUT 10 -+ -+#define PHY_MAX_ADDR 32 -+ -+/* Used when trying to connect to a specific phy (mii bus id:phy device id) */ -+#define PHY_ID_FMT "%s:%02x" -+ -+/* -+ * Need to be a little smaller than phydev->dev.bus_id to leave room -+ * for the ":%02x" -+ */ -+#define MII_BUS_ID_SIZE (BUS_ID_SIZE - 3) -+ -+/* -+ * The Bus class for PHYs. Devices which provide access to -+ * PHYs should register using this structure -+ */ -+struct mii_bus { -+ const char *name; -+ char id[MII_BUS_ID_SIZE]; -+ void *priv; -+ int (*read)(struct mii_bus *bus, int phy_id, int regnum); -+ int (*write)(struct mii_bus *bus, int phy_id, int regnum, u16 val); -+ int (*reset)(struct mii_bus *bus); -+ -+ /* -+ * A lock to ensure that only one thing can read/write -+ * the MDIO bus at a time -+ */ -+ struct mutex mdio_lock; -+ -+ struct device *parent; -+ enum { -+ MDIOBUS_ALLOCATED = 1, -+ MDIOBUS_REGISTERED, -+ MDIOBUS_UNREGISTERED, -+ MDIOBUS_RELEASED, -+ } state; -+ struct device dev; -+ -+ /* list of all PHYs on bus */ -+ struct phy_device *phy_map[PHY_MAX_ADDR]; -+ -+ /* Phy addresses to be ignored when probing */ -+ u32 phy_mask; -+ -+ /* -+ * Pointer to an array of interrupts, each PHY's -+ * interrupt at the index matching its address -+ */ -+ int *irq; -+}; -+#define to_mii_bus(d) container_of(d, struct mii_bus, dev) -+ -+struct mii_bus *mdiobus_alloc(void); -+int mdiobus_register(struct mii_bus *bus); -+void mdiobus_unregister(struct mii_bus *bus); -+void mdiobus_free(struct mii_bus *bus); -+struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr); -+int mdiobus_read(struct mii_bus *bus, int addr, u16 regnum); -+int mdiobus_write(struct mii_bus *bus, int addr, u16 regnum, u16 val); -+ -+ -+#define PHY_INTERRUPT_DISABLED 0x0 -+#define PHY_INTERRUPT_ENABLED 0x80000000 -+ -+/* PHY state machine states: -+ * -+ * DOWN: PHY device and driver are not ready for anything. probe -+ * should be called if and only if the PHY is in this state, -+ * given that the PHY device exists. -+ * - PHY driver probe function will, depending on the PHY, set -+ * the state to STARTING or READY -+ * -+ * STARTING: PHY device is coming up, and the ethernet driver is -+ * not ready. PHY drivers may set this in the probe function. -+ * If they do, they are responsible for making sure the state is -+ * eventually set to indicate whether the PHY is UP or READY, -+ * depending on the state when the PHY is done starting up. -+ * - PHY driver will set the state to READY -+ * - start will set the state to PENDING -+ * -+ * READY: PHY is ready to send and receive packets, but the -+ * controller is not. By default, PHYs which do not implement -+ * probe will be set to this state by phy_probe(). If the PHY -+ * driver knows the PHY is ready, and the PHY state is STARTING, -+ * then it sets this STATE. -+ * - start will set the state to UP -+ * -+ * PENDING: PHY device is coming up, but the ethernet driver is -+ * ready. phy_start will set this state if the PHY state is -+ * STARTING. -+ * - PHY driver will set the state to UP when the PHY is ready -+ * -+ * UP: The PHY and attached device are ready to do work. -+ * Interrupts should be started here. -+ * - timer moves to AN -+ * -+ * AN: The PHY is currently negotiating the link state. Link is -+ * therefore down for now. phy_timer will set this state when it -+ * detects the state is UP. config_aneg will set this state -+ * whenever called with phydev->autoneg set to AUTONEG_ENABLE. -+ * - If autonegotiation finishes, but there's no link, it sets -+ * the state to NOLINK. -+ * - If aneg finishes with link, it sets the state to RUNNING, -+ * and calls adjust_link -+ * - If autonegotiation did not finish after an arbitrary amount -+ * of time, autonegotiation should be tried again if the PHY -+ * supports "magic" autonegotiation (back to AN) -+ * - If it didn't finish, and no magic_aneg, move to FORCING. -+ * -+ * NOLINK: PHY is up, but not currently plugged in. -+ * - If the timer notes that the link comes back, we move to RUNNING -+ * - config_aneg moves to AN -+ * - phy_stop moves to HALTED -+ * -+ * FORCING: PHY is being configured with forced settings -+ * - if link is up, move to RUNNING -+ * - If link is down, we drop to the next highest setting, and -+ * retry (FORCING) after a timeout -+ * - phy_stop moves to HALTED -+ * -+ * RUNNING: PHY is currently up, running, and possibly sending -+ * and/or receiving packets -+ * - timer will set CHANGELINK if we're polling (this ensures the -+ * link state is polled every other cycle of this state machine, -+ * which makes it every other second) -+ * - irq will set CHANGELINK -+ * - config_aneg will set AN -+ * - phy_stop moves to HALTED -+ * -+ * CHANGELINK: PHY experienced a change in link state -+ * - timer moves to RUNNING if link -+ * - timer moves to NOLINK if the link is down -+ * - phy_stop moves to HALTED -+ * -+ * HALTED: PHY is up, but no polling or interrupts are done. Or -+ * PHY is in an error state. -+ * -+ * - phy_start moves to RESUMING -+ * -+ * RESUMING: PHY was halted, but now wants to run again. -+ * - If we are forcing, or aneg is done, timer moves to RUNNING -+ * - If aneg is not done, timer moves to AN -+ * - phy_stop moves to HALTED -+ */ -+enum phy_state { -+ PHY_DOWN=0, -+ PHY_STARTING, -+ PHY_READY, -+ PHY_PENDING, -+ PHY_UP, -+ PHY_AN, -+ PHY_RUNNING, -+ PHY_NOLINK, -+ PHY_FORCING, -+ PHY_CHANGELINK, -+ PHY_HALTED, -+ PHY_RESUMING -+}; -+ -+/* phy_device: An instance of a PHY -+ * -+ * drv: Pointer to the driver for this PHY instance -+ * bus: Pointer to the bus this PHY is on -+ * dev: driver model device structure for this PHY -+ * phy_id: UID for this device found during discovery -+ * state: state of the PHY for management purposes -+ * dev_flags: Device-specific flags used by the PHY driver. -+ * addr: Bus address of PHY -+ * link_timeout: The number of timer firings to wait before the -+ * giving up on the current attempt at acquiring a link -+ * irq: IRQ number of the PHY's interrupt (-1 if none) -+ * phy_timer: The timer for handling the state machine -+ * phy_queue: A work_queue for the interrupt -+ * attached_dev: The attached enet driver's device instance ptr -+ * adjust_link: Callback for the enet controller to respond to -+ * changes in the link state. -+ * adjust_state: Callback for the enet driver to respond to -+ * changes in the state machine. -+ * -+ * speed, duplex, pause, supported, advertising, and -+ * autoneg are used like in mii_if_info -+ * -+ * interrupts currently only supports enabled or disabled, -+ * but could be changed in the future to support enabling -+ * and disabling specific interrupts -+ * -+ * Contains some infrastructure for polling and interrupt -+ * handling, as well as handling shifts in PHY hardware state -+ */ -+struct phy_device { -+ /* Information about the PHY type */ -+ /* And management functions */ -+ struct phy_driver *drv; -+ -+ struct mii_bus *bus; -+ -+ struct device dev; -+ -+ u32 phy_id; -+ -+ enum phy_state state; -+ -+ u32 dev_flags; -+ -+ phy_interface_t interface; -+ -+ /* Bus address of the PHY (0-32) */ -+ int addr; -+ -+ /* -+ * forced speed & duplex (no autoneg) -+ * partner speed & duplex & pause (autoneg) -+ */ -+ int speed; -+ int duplex; -+ int pause; -+ int asym_pause; -+ -+ /* The most recently read link state */ -+ int link; -+ -+ /* Enabled Interrupts */ -+ u32 interrupts; -+ -+ /* Union of PHY and Attached devices' supported modes */ -+ /* See mii.h for more info */ -+ u32 supported; -+ u32 advertising; -+ -+ int autoneg; -+ -+ int link_timeout; -+ -+ /* -+ * Interrupt number for this PHY -+ * -1 means no interrupt -+ */ -+ int irq; -+ -+ /* private data pointer */ -+ /* For use by PHYs to maintain extra state */ -+ void *priv; -+ -+ /* Interrupt and Polling infrastructure */ -+ struct work_struct phy_queue; -+ struct work_struct state_queue; -+ struct timer_list phy_timer; -+ atomic_t irq_disable; -+ -+ struct mutex lock; -+ -+ struct net_device *attached_dev; -+ -+ void (*adjust_link)(struct net_device *dev); -+ -+ void (*adjust_state)(struct net_device *dev); -+}; -+#define to_phy_device(d) container_of(d, struct phy_device, dev) -+ -+/* struct phy_driver: Driver structure for a particular PHY type -+ * -+ * phy_id: The result of reading the UID registers of this PHY -+ * type, and ANDing them with the phy_id_mask. This driver -+ * only works for PHYs with IDs which match this field -+ * name: The friendly name of this PHY type -+ * phy_id_mask: Defines the important bits of the phy_id -+ * features: A list of features (speed, duplex, etc) supported -+ * by this PHY -+ * flags: A bitfield defining certain other features this PHY -+ * supports (like interrupts) -+ * -+ * The drivers must implement config_aneg and read_status. All -+ * other functions are optional. Note that none of these -+ * functions should be called from interrupt time. The goal is -+ * for the bus read/write functions to be able to block when the -+ * bus transaction is happening, and be freed up by an interrupt -+ * (The MPC85xx has this ability, though it is not currently -+ * supported in the driver). -+ */ -+struct phy_driver { -+ u32 phy_id; -+ char *name; -+ unsigned int phy_id_mask; -+ u32 features; -+ u32 flags; -+ -+ /* -+ * Called to initialize the PHY, -+ * including after a reset -+ */ -+ int (*config_init)(struct phy_device *phydev); -+ -+ /* -+ * Called during discovery. Used to set -+ * up device-specific structures, if any -+ */ -+ int (*probe)(struct phy_device *phydev); -+ -+ /* PHY Power Management */ -+ int (*suspend)(struct phy_device *phydev); -+ int (*resume)(struct phy_device *phydev); -+ -+ /* -+ * Configures the advertisement and resets -+ * autonegotiation if phydev->autoneg is on, -+ * forces the speed to the current settings in phydev -+ * if phydev->autoneg is off -+ */ -+ int (*config_aneg)(struct phy_device *phydev); -+ -+ /* Determines the negotiated speed and duplex */ -+ int (*read_status)(struct phy_device *phydev); -+ -+ /* Clears any pending interrupts */ -+ int (*ack_interrupt)(struct phy_device *phydev); -+ -+ /* Enables or disables interrupts */ -+ int (*config_intr)(struct phy_device *phydev); -+ -+ /* Clears up any memory if needed */ -+ void (*remove)(struct phy_device *phydev); -+ -+ struct device_driver driver; -+}; -+#define to_phy_driver(d) container_of(d, struct phy_driver, driver) -+ -+#define PHY_ANY_ID "MATCH ANY PHY" -+#define PHY_ANY_UID 0xffffffff -+ -+/* A Structure for boards to register fixups with the PHY Lib */ -+struct phy_fixup { -+ struct list_head list; -+ char bus_id[BUS_ID_SIZE]; -+ u32 phy_uid; -+ u32 phy_uid_mask; -+ int (*run)(struct phy_device *phydev); -+}; -+ -+/** -+ * phy_read - Convenience function for reading a given PHY register -+ * @phydev: the phy_device struct -+ * @regnum: register number to read -+ * -+ * NOTE: MUST NOT be called from interrupt context, -+ * because the bus read/write functions may wait for an interrupt -+ * to conclude the operation. -+ */ -+static inline int phy_read(struct phy_device *phydev, u16 regnum) -+{ -+ return mdiobus_read(phydev->bus, phydev->addr, regnum); -+} -+ -+/** -+ * phy_write - Convenience function for writing a given PHY register -+ * @phydev: the phy_device struct -+ * @regnum: register number to write -+ * @val: value to write to @regnum -+ * -+ * NOTE: MUST NOT be called from interrupt context, -+ * because the bus read/write functions may wait for an interrupt -+ * to conclude the operation. -+ */ -+static inline int phy_write(struct phy_device *phydev, u16 regnum, u16 val) -+{ -+ return mdiobus_write(phydev->bus, phydev->addr, regnum, val); -+} -+ -+int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id); -+struct phy_device* get_phy_device(struct mii_bus *bus, int addr); -+int phy_clear_interrupt(struct phy_device *phydev); -+int phy_config_interrupt(struct phy_device *phydev, u32 interrupts); -+struct phy_device * phy_attach(struct net_device *dev, -+ const char *bus_id, u32 flags, phy_interface_t interface); -+struct phy_device * phy_connect(struct net_device *dev, const char *bus_id, -+ void (*handler)(struct net_device *), u32 flags, -+ phy_interface_t interface); -+void phy_disconnect(struct phy_device *phydev); -+void phy_detach(struct phy_device *phydev); -+void phy_start(struct phy_device *phydev); -+void phy_stop(struct phy_device *phydev); -+int phy_start_aneg(struct phy_device *phydev); -+ -+void phy_sanitize_settings(struct phy_device *phydev); -+int phy_stop_interrupts(struct phy_device *phydev); -+int phy_enable_interrupts(struct phy_device *phydev); -+int phy_disable_interrupts(struct phy_device *phydev); -+ -+static inline int phy_read_status(struct phy_device *phydev) { -+ return phydev->drv->read_status(phydev); -+} -+ -+int genphy_config_advert(struct phy_device *phydev); -+int genphy_setup_forced(struct phy_device *phydev); -+int genphy_restart_aneg(struct phy_device *phydev); -+int genphy_config_aneg(struct phy_device *phydev); -+int genphy_update_link(struct phy_device *phydev); -+int genphy_read_status(struct phy_device *phydev); -+int genphy_suspend(struct phy_device *phydev); -+int genphy_resume(struct phy_device *phydev); -+void phy_driver_unregister(struct phy_driver *drv); -+int phy_driver_register(struct phy_driver *new_driver); -+void phy_prepare_link(struct phy_device *phydev, -+ void (*adjust_link)(struct net_device *)); -+void phy_start_machine(struct phy_device *phydev, -+ void (*handler)(struct net_device *)); -+void phy_stop_machine(struct phy_device *phydev); -+int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd); -+int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd); -+int phy_mii_ioctl(struct phy_device *phydev, -+ struct mii_ioctl_data *mii_data, int cmd); -+int phy_start_interrupts(struct phy_device *phydev); -+void phy_print_status(struct phy_device *phydev); -+struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id); -+void phy_device_free(struct phy_device *phydev); -+ -+int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask, -+ int (*run)(struct phy_device *)); -+int phy_register_fixup_for_id(const char *bus_id, -+ int (*run)(struct phy_device *)); -+int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask, -+ int (*run)(struct phy_device *)); -+int phy_scan_fixups(struct phy_device *phydev); -+ -+int __init mdio_bus_init(void); -+void mdio_bus_exit(void); -+ -+extern struct bus_type mdio_bus_type; -+#endif /* __PHY_H */ |