diff options
Diffstat (limited to 'target/linux/ixp4xx/patches-2.6.26/190-cambria_support.patch')
-rw-r--r-- | target/linux/ixp4xx/patches-2.6.26/190-cambria_support.patch | 579 |
1 files changed, 579 insertions, 0 deletions
diff --git a/target/linux/ixp4xx/patches-2.6.26/190-cambria_support.patch b/target/linux/ixp4xx/patches-2.6.26/190-cambria_support.patch new file mode 100644 index 0000000..5e682b0 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.26/190-cambria_support.patch @@ -0,0 +1,579 @@ +--- a/arch/arm/mach-ixp4xx/Kconfig ++++ b/arch/arm/mach-ixp4xx/Kconfig +@@ -25,6 +25,14 @@ + Avila Network Platform. For more information on this platform, + see <file:Documentation/arm/IXP4xx>. + ++config MACH_CAMBRIA ++ bool "Cambria" ++ select PCI ++ help ++ Say 'Y' here if you want your kernel to support the Gateworks ++ Cambria series. For more information on this platform, ++ see <file:Documentation/arm/IXP4xx>. ++ + config MACH_LOFT + bool "Loft" + depends on MACH_AVILA +@@ -200,7 +208,7 @@ + + config CPU_IXP43X + bool +- depends on MACH_KIXRP435 ++ depends on MACH_KIXRP435 || MACH_CAMBRIA + default y + + config MACH_GTWX5715 +--- a/arch/arm/mach-ixp4xx/Makefile ++++ b/arch/arm/mach-ixp4xx/Makefile +@@ -7,6 +7,7 @@ + + obj-pci-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o + obj-pci-$(CONFIG_MACH_AVILA) += avila-pci.o ++obj-pci-$(CONFIG_MACH_CAMBRIA) += cambria-pci.o + obj-pci-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o + obj-pci-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o + obj-pci-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o +@@ -28,6 +29,7 @@ + + obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-setup.o + obj-$(CONFIG_MACH_AVILA) += avila-setup.o ++obj-$(CONFIG_MACH_CAMBRIA) += cambria-setup.o + obj-$(CONFIG_MACH_IXDPG425) += coyote-setup.o + obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-setup.o + obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o +--- /dev/null ++++ b/arch/arm/mach-ixp4xx/cambria-pci.c +@@ -0,0 +1,74 @@ ++/* ++ * arch/arch/mach-ixp4xx/cambria-pci.c ++ * ++ * PCI setup routines for Gateworks Cambria series ++ * ++ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> ++ * ++ * based on coyote-pci.c: ++ * Copyright (C) 2002 Jungo Software Technologies. ++ * Copyright (C) 2003 MontaVista Softwrae, Inc. ++ * ++ * Maintainer: 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/pci.h> ++#include <linux/init.h> ++#include <linux/irq.h> ++ ++#include <asm/mach-types.h> ++#include <asm/hardware.h> ++#include <asm/irq.h> ++ ++#include <asm/mach/pci.h> ++ ++extern void ixp4xx_pci_preinit(void); ++extern int ixp4xx_setup(int nr, struct pci_sys_data *sys); ++extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys); ++ ++void __init cambria_pci_preinit(void) ++{ ++ set_irq_type(IRQ_IXP4XX_GPIO11, IRQT_LOW); ++ set_irq_type(IRQ_IXP4XX_GPIO10, IRQT_LOW); ++ set_irq_type(IRQ_IXP4XX_GPIO9, IRQT_LOW); ++ set_irq_type(IRQ_IXP4XX_GPIO8, IRQT_LOW); ++ ++ ixp4xx_pci_preinit(); ++} ++ ++static int __init cambria_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++ if (slot == 1) ++ return IRQ_IXP4XX_GPIO11; ++ else if (slot == 2) ++ return IRQ_IXP4XX_GPIO10; ++ else if (slot == 3) ++ return IRQ_IXP4XX_GPIO9; ++ else if (slot == 4) ++ return IRQ_IXP4XX_GPIO8; ++ else return -1; ++} ++ ++struct hw_pci cambria_pci __initdata = { ++ .nr_controllers = 1, ++ .preinit = cambria_pci_preinit, ++ .swizzle = pci_std_swizzle, ++ .setup = ixp4xx_setup, ++ .scan = ixp4xx_scan_bus, ++ .map_irq = cambria_map_irq, ++}; ++ ++int __init cambria_pci_init(void) ++{ ++ if (machine_is_cambria()) ++ pci_common_init(&cambria_pci); ++ return 0; ++} ++ ++subsys_initcall(cambria_pci_init); +--- /dev/null ++++ b/arch/arm/mach-ixp4xx/cambria-setup.c +@@ -0,0 +1,444 @@ ++/* ++ * arch/arm/mach-ixp4xx/cambria-setup.c ++ * ++ * Board setup for the Gateworks Cambria series ++ * ++ * Copyright (C) 2008 Imre Kaloz <Kaloz@openwrt.org> ++ * ++ * based on coyote-setup.c: ++ * Copyright (C) 2003-2005 MontaVista Software, Inc. ++ * ++ * Author: Imre Kaloz <Kaloz@openwrt.org> ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/device.h> ++#include <linux/if_ether.h> ++#include <linux/socket.h> ++#include <linux/netdevice.h> ++#include <linux/serial.h> ++#include <linux/tty.h> ++#include <linux/serial_8250.h> ++#include <linux/slab.h> ++#ifdef CONFIG_SENSORS_EEPROM ++# include <linux/i2c.h> ++# include <linux/eeprom.h> ++#endif ++ ++#include <linux/leds.h> ++#include <linux/i2c-gpio.h> ++#include <asm/types.h> ++#include <asm/setup.h> ++#include <asm/memory.h> ++#include <asm/hardware.h> ++#include <asm/irq.h> ++#include <asm/mach-types.h> ++#include <asm/mach/arch.h> ++#include <asm/mach/flash.h> ++ ++struct cambria_board_info { ++ unsigned char *model; ++ void (* setup)(void); ++}; ++ ++static struct cambria_board_info *cambria_info __initdata; ++ ++static struct flash_platform_data cambria_flash_data = { ++ .map_name = "cfi_probe", ++ .width = 2, ++}; ++ ++static struct resource cambria_flash_resource = { ++ .flags = IORESOURCE_MEM, ++}; ++ ++static struct platform_device cambria_flash = { ++ .name = "IXP4XX-Flash", ++ .id = 0, ++ .dev = { ++ .platform_data = &cambria_flash_data, ++ }, ++ .num_resources = 1, ++ .resource = &cambria_flash_resource, ++}; ++ ++static struct i2c_gpio_platform_data cambria_i2c_gpio_data = { ++ .sda_pin = 7, ++ .scl_pin = 6, ++}; ++ ++static struct platform_device cambria_i2c_gpio = { ++ .name = "i2c-gpio", ++ .id = 0, ++ .dev = { ++ .platform_data = &cambria_i2c_gpio_data, ++ }, ++}; ++ ++static struct resource cambria_uart_resource = { ++ .start = IXP4XX_UART1_BASE_PHYS, ++ .end = IXP4XX_UART1_BASE_PHYS + 0x0fff, ++ .flags = IORESOURCE_MEM, ++}; ++ ++static struct plat_serial8250_port cambria_uart_data[] = { ++ { ++ .mapbase = IXP4XX_UART1_BASE_PHYS, ++ .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET, ++ .irq = IRQ_IXP4XX_UART1, ++ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, ++ .iotype = UPIO_MEM, ++ .regshift = 2, ++ .uartclk = IXP4XX_UART_XTAL, ++ }, ++ { }, ++}; ++ ++static struct platform_device cambria_uart = { ++ .name = "serial8250", ++ .id = PLAT8250_DEV_PLATFORM, ++ .dev = { ++ .platform_data = cambria_uart_data, ++ }, ++ .num_resources = 1, ++ .resource = &cambria_uart_resource, ++}; ++ ++static struct resource cambria_pata_resources[] = { ++ { ++ .flags = IORESOURCE_MEM ++ }, ++ { ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .name = "intrq", ++ .start = IRQ_IXP4XX_GPIO12, ++ .end = IRQ_IXP4XX_GPIO12, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct ixp4xx_pata_data cambria_pata_data = { ++ .cs0_bits = 0xbfff3c03, ++ .cs1_bits = 0xbfff3c03, ++}; ++ ++static struct platform_device cambria_pata = { ++ .name = "pata_ixp4xx_cf", ++ .id = 0, ++ .dev.platform_data = &cambria_pata_data, ++ .num_resources = ARRAY_SIZE(cambria_pata_resources), ++ .resource = cambria_pata_resources, ++}; ++ ++static struct eth_plat_info cambria_npec_data = { ++ .phy = 1, ++ .rxq = 4, ++ .txreadyq = 21, ++}; ++ ++static struct eth_plat_info cambria_npea_data = { ++ .phy = 2, ++ .rxq = 2, ++ .txreadyq = 19, ++}; ++ ++static struct platform_device cambria_npec_device = { ++ .name = "ixp4xx_eth", ++ .id = IXP4XX_ETH_NPEC, ++ .dev.platform_data = &cambria_npec_data, ++}; ++ ++static struct platform_device cambria_npea_device = { ++ .name = "ixp4xx_eth", ++ .id = IXP4XX_ETH_NPEA, ++ .dev.platform_data = &cambria_npea_data, ++}; ++ ++static struct gpio_led cambria_gpio_leds[] = { ++ { ++ .name = "user", /* green led */ ++ .gpio = 5, ++ .active_low = 1, ++ } ++}; ++ ++static struct gpio_led_platform_data cambria_gpio_leds_data = { ++ .num_leds = 1, ++ .leds = cambria_gpio_leds, ++}; ++ ++static struct platform_device cambria_gpio_leds_device = { ++ .name = "leds-gpio", ++ .id = -1, ++ .dev.platform_data = &cambria_gpio_leds_data, ++}; ++ ++ ++static struct latch_led cambria_latch_leds[] = { ++ { ++ .name = "ledA", /* green led */ ++ .bit = 0, ++ }, ++ { ++ .name = "ledB", /* green led */ ++ .bit = 1, ++ }, ++ { ++ .name = "ledC", /* green led */ ++ .bit = 2, ++ }, ++ { ++ .name = "ledD", /* green led */ ++ .bit = 3, ++ }, ++ { ++ .name = "ledE", /* green led */ ++ .bit = 4, ++ }, ++ { ++ .name = "ledF", /* green led */ ++ .bit = 5, ++ }, ++ { ++ .name = "ledG", /* green led */ ++ .bit = 6, ++ }, ++ { ++ .name = "ledH", /* green led */ ++ .bit = 7, ++ } ++}; ++ ++static struct latch_led_platform_data cambria_latch_leds_data = { ++ .num_leds = 8, ++ .leds = cambria_latch_leds, ++ .mem = 0x53F40000, ++}; ++ ++static struct platform_device cambria_latch_leds_device = { ++ .name = "leds-latch", ++ .id = -1, ++ .dev.platform_data = &cambria_latch_leds_data, ++}; ++ ++static struct resource cambria_usb0_resources[] = { ++ { ++ .start = 0xCD000000, ++ .end = 0xCD000300, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = 32, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct resource cambria_usb1_resources[] = { ++ { ++ .start = 0xCE000000, ++ .end = 0xCE000300, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = 33, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static u64 ehci_dma_mask = ~(u32)0; ++ ++static struct platform_device cambria_usb0_device = { ++ .name = "ixp4xx-ehci", ++ .id = 0, ++ .resource = cambria_usb0_resources, ++ .num_resources = ARRAY_SIZE(cambria_usb0_resources), ++ .dev = { ++ .dma_mask = &ehci_dma_mask, ++ .coherent_dma_mask = 0xffffffff, ++ }, ++}; ++ ++static struct platform_device cambria_usb1_device = { ++ .name = "ixp4xx-ehci", ++ .id = 1, ++ .resource = cambria_usb1_resources, ++ .num_resources = ARRAY_SIZE(cambria_usb1_resources), ++ .dev = { ++ .dma_mask = &ehci_dma_mask, ++ .coherent_dma_mask = 0xffffffff, ++ }, ++}; ++ ++static struct platform_device *cambria_devices[] __initdata = { ++ &cambria_i2c_gpio, ++ &cambria_flash, ++ &cambria_uart, ++}; ++ ++static void __init cambria_gw23xx_setup(void) ++{ ++ platform_device_register(&cambria_npec_device); ++ platform_device_register(&cambria_npea_device); ++} ++ ++#ifdef CONFIG_SENSORS_EEPROM ++static void __init cambria_gw2350_setup(void) ++{ ++ platform_device_register(&cambria_npec_device); ++ platform_device_register(&cambria_npea_device); ++ ++ platform_device_register(&cambria_usb0_device); ++ platform_device_register(&cambria_usb1_device); ++ ++ platform_device_register(&cambria_gpio_leds_device); ++} ++ ++static void __init cambria_gw2358_setup(void) ++{ ++ platform_device_register(&cambria_npec_device); ++ platform_device_register(&cambria_npea_device); ++ ++ platform_device_register(&cambria_usb0_device); ++ platform_device_register(&cambria_usb1_device); ++ ++ platform_device_register(&cambria_pata); ++ ++ platform_device_register(&cambria_latch_leds_device); ++} ++ ++static struct cambria_board_info cambria_boards[] __initdata = { ++ { ++ .model = "GW2350", ++ .setup = cambria_gw2350_setup, ++ }, { ++ .model = "GW2358", ++ .setup = cambria_gw2358_setup, ++ } ++}; ++ ++static struct cambria_board_info * __init cambria_find_board_info(char *model) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(cambria_boards); i++) { ++ struct cambria_board_info *info = &cambria_boards[i]; ++ if (strncmp(info->model, model, strlen(info->model)) == 0) ++ return info; ++ } ++ ++ return NULL; ++} ++ ++struct cambria_eeprom_header { ++ unsigned char mac0[ETH_ALEN]; ++ unsigned char mac1[ETH_ALEN]; ++ unsigned char res0[4]; ++ unsigned char magic[2]; ++ unsigned char config[14]; ++ unsigned char model[16]; ++}; ++ ++static int __init cambria_eeprom_notify(struct notifier_block *self, ++ unsigned long event, void *t) ++{ ++ struct eeprom_data *ee = t; ++ struct cambria_eeprom_header hdr; ++ ++ if (cambria_info) ++ return NOTIFY_DONE; ++ ++ /* The eeprom is at address 0x51 */ ++ if (event != EEPROM_REGISTER || ee->client.addr != 0x51) ++ return NOTIFY_DONE; ++ ++ ee->attr->read(&ee->client.dev.kobj, ee->attr, (char *)&hdr, ++ 0, sizeof(hdr)); ++ ++ if (hdr.magic[0] != 'G' || hdr.magic[1] != 'W') ++ return NOTIFY_DONE; ++ ++ memcpy(&cambria_npec_data.hwaddr, hdr.mac0, ETH_ALEN); ++ memcpy(&cambria_npea_data.hwaddr, hdr.mac1, ETH_ALEN); ++ ++ cambria_info = cambria_find_board_info(hdr.model); ++ ++ return NOTIFY_OK; ++} ++ ++static struct notifier_block cambria_eeprom_notifier __initdata = { ++ .notifier_call = cambria_eeprom_notify ++}; ++ ++static void __init cambria_register_eeprom_notifier(void) ++{ ++ register_eeprom_notifier(&cambria_eeprom_notifier); ++} ++ ++static void __init cambria_unregister_eeprom_notifier(void) ++{ ++ unregister_eeprom_notifier(&cambria_eeprom_notifier); ++} ++#else /* CONFIG_SENSORS_EEPROM */ ++static inline void cambria_register_eeprom_notifier(void) {}; ++static inline void cambria_unregister_eeprom_notifier(void) {}; ++#endif /* CONFIG_SENSORS_EEPROM */ ++ ++static void __init cambria_init(void) ++{ ++ ixp4xx_sys_init(); ++ ++ cambria_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); ++ cambria_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1; ++ ++ *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE; ++ *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0; ++ ++ platform_add_devices(cambria_devices, ARRAY_SIZE(cambria_devices)); ++ ++ cambria_pata_resources[0].start = 0x53e00000; ++ cambria_pata_resources[0].end = 0x53e3ffff; ++ ++ cambria_pata_resources[1].start = 0x53e40000; ++ cambria_pata_resources[1].end = 0x53e7ffff; ++ ++ cambria_pata_data.cs0_cfg = IXP4XX_EXP_CS3; ++ cambria_pata_data.cs1_cfg = IXP4XX_EXP_CS3; ++ ++ cambria_register_eeprom_notifier(); ++} ++ ++static int __init cambria_model_setup(void) ++{ ++ if (!machine_is_cambria()) ++ return 0; ++ ++ if (cambria_info) { ++ printk(KERN_DEBUG "Running on Gateworks Cambria %s\n", ++ cambria_info->model); ++ cambria_info->setup(); ++ } else { ++ printk(KERN_INFO "Unknown/missing Cambria model number" ++ " -- defaults will be used\n"); ++ cambria_gw23xx_setup(); ++ } ++ ++ cambria_unregister_eeprom_notifier(); ++ return 0; ++} ++late_initcall(cambria_model_setup); ++ ++#ifdef CONFIG_MACH_CAMBRIA ++MACHINE_START(CAMBRIA, "Gateworks Cambria series") ++ /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */ ++ .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, ++ .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, ++ .map_io = ixp4xx_map_io, ++ .init_irq = ixp4xx_init_irq, ++ .timer = &ixp4xx_timer, ++ .boot_params = 0x0100, ++ .init_machine = cambria_init, ++MACHINE_END ++#endif +--- a/include/asm-arm/arch-ixp4xx/hardware.h ++++ b/include/asm-arm/arch-ixp4xx/hardware.h +@@ -18,7 +18,7 @@ + #define __ASM_ARCH_HARDWARE_H__ + + #define PCIBIOS_MIN_IO 0x00001000 +-#define PCIBIOS_MIN_MEM (cpu_is_ixp43x() ? 0x40000000 : 0x48000000) ++#define PCIBIOS_MIN_MEM (cpu_is_ixp43x() ? 0x48000000 : 0x48000000) + + /* + * We override the standard dma-mask routines for bouncing. |