Signed-off-by: Lennert Buytenhek Tested-by: Dirk Teurlings Tested-by: Peter van Valderen --- arch/arm/mach-orion5x/Kconfig | 6 + arch/arm/mach-orion5x/Makefile | 1 + arch/arm/mach-orion5x/wrt350n-v2-setup.c | 170 ++++++++++++++++++++++++++++++ 3 files changed, 177 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-orion5x/wrt350n-v2-setup.c --- a/arch/arm/mach-orion5x/Kconfig +++ b/arch/arm/mach-orion5x/Kconfig @@ -50,6 +50,12 @@ Say 'Y' here if you want your kernel to support the QNAP TS-409 platform. +config MACH_WRT350N_V2 + bool "Linksys WRT350N v2" + help + Say 'Y' here if you want your kernel to support the + Linksys WRT350N v2 platform. + endmenu endif --- a/arch/arm/mach-orion5x/Makefile +++ b/arch/arm/mach-orion5x/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_MACH_DNS323) += dns323-setup.o obj-$(CONFIG_MACH_TS209) += ts209-setup.o obj-$(CONFIG_MACH_TS409) += ts409-setup.o +obj-$(CONFIG_MACH_WRT350N_V2) += wrt350n-v2-setup.o --- /dev/null +++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c @@ -0,0 +1,170 @@ +/* + * arch/arm/mach-orion5x/wrt350n-v2-setup.c + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +/* + * 8M NOR flash Device bus boot chip select + */ +#define WRT350N_V2_NOR_BOOT_BASE 0xf4000000 +#define WRT350N_V2_NOR_BOOT_SIZE SZ_8M + +static struct mtd_partition wrt350n_v2_nor_flash_partitions[] = { + { + .name = "kernel", + .offset = 0x00000000, + .size = 0x00760000, + }, { + .name = "rootfs", + .offset = 0x001a0000, + .size = 0x005c0000, + }, { + .name = "lang", + .offset = 0x00760000, + .size = 0x00040000, + }, { + .name = "nvram", + .offset = 0x007a0000, + .size = 0x00020000, + }, { + .name = "u-boot", + .offset = 0x007c0000, + .size = 0x00040000, + }, +}; + +static struct physmap_flash_data wrt350n_v2_nor_flash_data = { + .width = 1, + .parts = wrt350n_v2_nor_flash_partitions, + .nr_parts = ARRAY_SIZE(wrt350n_v2_nor_flash_partitions), +}; + +static struct resource wrt350n_v2_nor_flash_resource = { + .flags = IORESOURCE_MEM, + .start = WRT350N_V2_NOR_BOOT_BASE, + .end = WRT350N_V2_NOR_BOOT_BASE + WRT350N_V2_NOR_BOOT_SIZE - 1, +}; + +static struct platform_device wrt350n_v2_nor_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &wrt350n_v2_nor_flash_data, + }, + .num_resources = 1, + .resource = &wrt350n_v2_nor_flash_resource, +}; + +static struct mv643xx_eth_platform_data wrt350n_v2_eth_data = { + .phy_addr = -1, +}; + +static void __init wrt350n_v2_init(void) +{ + /* + * Setup basic Orion functions. Need to be called early. + */ + orion5x_init(); + + orion5x_mpp_conf(0, MPP_GPIO); /* Power LED green (0=on) */ + orion5x_mpp_conf(1, MPP_GPIO); /* Security LED (0=on) */ + orion5x_mpp_conf(2, MPP_GPIO); /* Internal Button (0=on) */ + orion5x_mpp_conf(3, MPP_GPIO); /* Reset Button (0=on) */ + orion5x_mpp_conf(4, MPP_GPIO); /* PCI int */ + orion5x_mpp_conf(5, MPP_GPIO); /* Power LED orange (0=on) */ + orion5x_mpp_conf(6, MPP_GPIO); /* USB LED (0=on) */ + orion5x_mpp_conf(7, MPP_GPIO); /* Wireless LED (0=on) */ + orion5x_mpp_conf(8, MPP_UNUSED); /* ??? */ + orion5x_mpp_conf(9, MPP_GIGE); /* GE_RXERR */ + orion5x_mpp_conf(10, MPP_UNUSED); /* ??? */ + orion5x_mpp_conf(11, MPP_UNUSED); /* ??? */ + orion5x_mpp_conf(12, MPP_GIGE); /* GE_TXD[4] */ + orion5x_mpp_conf(13, MPP_GIGE); /* GE_TXD[5] */ + orion5x_mpp_conf(14, MPP_GIGE); /* GE_TXD[6] */ + orion5x_mpp_conf(15, MPP_GIGE); /* GE_TXD[7] */ + orion5x_mpp_conf(16, MPP_GIGE); /* GE_RXD[4] */ + orion5x_mpp_conf(17, MPP_GIGE); /* GE_RXD[5] */ + orion5x_mpp_conf(18, MPP_GIGE); /* GE_RXD[6] */ + orion5x_mpp_conf(19, MPP_GIGE); /* GE_RXD[7] */ + + /* + * Configure peripherals. + */ + orion5x_ehci0_init(); + orion5x_eth_init(&wrt350n_v2_eth_data); + orion5x_uart0_init(); + + orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE, + WRT350N_V2_NOR_BOOT_SIZE); + platform_device_register(&wrt350n_v2_nor_flash); +} + +static int __init wrt350n_v2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq; + + /* + * Check for devices with hard-wired IRQs. + */ + irq = orion5x_pci_map_irq(dev, slot, pin); + if (irq != -1) + return irq; + + /* + * Mini-PCI slot. + */ + if (slot == 7) + return gpio_to_irq(4); + + printk(KERN_ERR "wrt350n_v2_pci_map_irq failed, unknown bus\n"); + + return -1; +} + +static struct hw_pci wrt350n_v2_pci __initdata = { + .nr_controllers = 2, + .swizzle = pci_std_swizzle, + .setup = orion5x_pci_sys_setup, + .scan = orion5x_pci_sys_scan_bus, + .map_irq = wrt350n_v2_pci_map_irq, +}; + +static int __init wrt350n_v2_pci_init(void) +{ + if (machine_is_wrt350n_v2()) + pci_common_init(&wrt350n_v2_pci); + + return 0; +} +subsys_initcall(wrt350n_v2_pci_init); + +MACHINE_START(WRT350N_V2, "Linksys WRT350N v2") + /* Maintainer: Lennert Buytenhek */ + .phys_io = ORION5X_REGS_PHYS_BASE, + .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, + .boot_params = 0x00000100, + .init_machine = wrt350n_v2_init, + .map_io = orion5x_map_io, + .init_irq = orion5x_init_irq, + .timer = &orion5x_timer, + .fixup = tag_fixup_mem32, +MACHINE_END