aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorImre Kaloz <kaloz@openwrt.org>2008-04-28 22:20:49 +0000
committerImre Kaloz <kaloz@openwrt.org>2008-04-28 22:20:49 +0000
commit8f54e06573d9d3693ca9bf5efebfe42c5362d02b (patch)
tree2d59a01370fc18bed1f7f22e33f80e0672c1d788
parentef0a202a8f52384d143a043834495bd1b0df6148 (diff)
downloadupstream-8f54e06573d9d3693ca9bf5efebfe42c5362d02b.tar.gz
upstream-8f54e06573d9d3693ca9bf5efebfe42c5362d02b.tar.bz2
upstream-8f54e06573d9d3693ca9bf5efebfe42c5362d02b.zip
add support for the Gateworks Cambria
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@10973 3c298f89-4303-0410-b956-a3cf2f4a3e73
-rwxr-xr-xscripts/arm-magic.sh2
-rw-r--r--target/linux/ixp4xx/config-default1
-rw-r--r--target/linux/ixp4xx/patches-2.6.24/190-cambria_support.patch420
-rw-r--r--target/linux/ixp4xx/patches-2.6.24/204-npe_driver_ixp43x_support.patch86
4 files changed, 508 insertions, 1 deletions
diff --git a/scripts/arm-magic.sh b/scripts/arm-magic.sh
index 4c41b475e2..cb9d8f320f 100755
--- a/scripts/arm-magic.sh
+++ b/scripts/arm-magic.sh
@@ -22,7 +22,7 @@
# NOTE: for now it's for only IXP4xx in big endian mode
# list of supported boards, in "boardname machtypeid" format
-for board in "avila 526" "gateway7001 731" "nslu2 597" "nas100d 865" "wg302v1 889" "wg302v2 890" "pronghornmetro 1040" "compex 1273" "wrt300nv2 1077" "loft 849" "dsmg600 964" "fsg3 1091" "ap1000 1543" "tw2662 1658" "tw5334 1664" "ixdpg425 604"
+for board in "avila 526" "gateway7001 731" "nslu2 597" "nas100d 865" "wg302v1 889" "wg302v2 890" "pronghornmetro 1040" "compex 1273" "wrt300nv2 1077" "loft 849" "dsmg600 964" "fsg3 1091" "ap1000 1543" "tw2662 1658" "tw5334 1664" "ixdpg425 604" "cambria 1468"
do
set -- $board
hexid=$(printf %x\\n $2)
diff --git a/target/linux/ixp4xx/config-default b/target/linux/ixp4xx/config-default
index 69cbd67a78..a9a3ace8a3 100644
--- a/target/linux/ixp4xx/config-default
+++ b/target/linux/ixp4xx/config-default
@@ -209,6 +209,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_LLC2 is not set
CONFIG_MACH_AP1000=y
CONFIG_MACH_AVILA=y
+CONFIG_MACH_CAMBRIA=y
CONFIG_MACH_COMPEX=y
CONFIG_MACH_DSMG600=y
CONFIG_MACH_FSG=y
diff --git a/target/linux/ixp4xx/patches-2.6.24/190-cambria_support.patch b/target/linux/ixp4xx/patches-2.6.24/190-cambria_support.patch
new file mode 100644
index 0000000000..4f7f996b2f
--- /dev/null
+++ b/target/linux/ixp4xx/patches-2.6.24/190-cambria_support.patch
@@ -0,0 +1,420 @@
+diff -Nur linux-2.6.24.5/arch/arm/mach-ixp4xx/Kconfig linux-2.6.24.5-owrt/arch/arm/mach-ixp4xx/Kconfig
+--- linux-2.6.24.5/arch/arm/mach-ixp4xx/Kconfig 2008-04-28 20:22:27.000000000 +0200
++++ linux-2.6.24.5-owrt/arch/arm/mach-ixp4xx/Kconfig 2008-04-28 20:26:44.000000000 +0200
+@@ -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
+diff -Nur linux-2.6.24.5/arch/arm/mach-ixp4xx/Makefile linux-2.6.24.5-owrt/arch/arm/mach-ixp4xx/Makefile
+--- linux-2.6.24.5/arch/arm/mach-ixp4xx/Makefile 2008-04-28 20:22:27.000000000 +0200
++++ linux-2.6.24.5-owrt/arch/arm/mach-ixp4xx/Makefile 2008-04-28 20:26:44.000000000 +0200
+@@ -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
+diff -Nur linux-2.6.24.5/arch/arm/mach-ixp4xx/cambria-pci.c linux-2.6.24.5-owrt/arch/arm/mach-ixp4xx/cambria-pci.c
+--- linux-2.6.24.5/arch/arm/mach-ixp4xx/cambria-pci.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24.5-owrt/arch/arm/mach-ixp4xx/cambria-pci.c 2008-04-28 20:30:35.000000000 +0200
+@@ -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);
+diff -Nur linux-2.6.24.5/arch/arm/mach-ixp4xx/cambria-setup.c linux-2.6.24.5-owrt/arch/arm/mach-ixp4xx/cambria-setup.c
+--- linux-2.6.24.5/arch/arm/mach-ixp4xx/cambria-setup.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24.5-owrt/arch/arm/mach-ixp4xx/cambria-setup.c 2008-04-28 21:07:16.000000000 +0200
+@@ -0,0 +1,280 @@
++/*
++ * 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/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>
++
++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_plat_eth[] = {
++ {
++ .phy = 2,
++ .rxq = 4,
++ .txreadyq = 21,
++ }, {
++ .phy = 1,
++ .rxq = 2,
++ .txreadyq = 19,
++ }
++};
++
++static struct platform_device cambria_eth[] = {
++ {
++ .name = "ixp4xx_eth",
++ .id = IXP4XX_ETH_NPEC,
++ .dev.platform_data = cambria_plat_eth,
++ }, {
++ .name = "ixp4xx_eth",
++ .id = IXP4XX_ETH_NPEA,
++ .dev.platform_data = cambria_plat_eth + 1,
++ }
++};
++
++#ifdef CONFIG_LEDS_IXP4XX
++static struct platform_device cambria_leds_pld = {
++ .name = "IXP4XX-PLD-LED",
++ .id = -1,
++ .num_resources = 0,
++};
++
++static struct platform_device cambria_leds_mem = {
++ .name = "IXP4XX-MEM-LED",
++ .id = -1,
++ .num_resources = 0,
++};
++#endif
++
++static struct platform_device *cambria_devices[] __initdata = {
++ &cambria_i2c_gpio,
++ &cambria_flash,
++ &cambria_uart,
++#ifdef CONFIG_LEDS_IXP4XX
++ &cambria_leds_pld,
++ &cambria_leds_mem,
++#endif
++ &cambria_eth[0],
++ &cambria_eth[1],
++};
++
++static char cambria_rtc_probe[] __initdata = "rtc-ds1672.probe=0,0x68 ";
++
++static void __init cambria_fixup(struct machine_desc *desc,
++ struct tag *tags, char **cmdline, struct meminfo *mi)
++{
++ struct tag *t = tags;
++ char *p = *cmdline;
++
++ /* Find the end of the tags table, taking note of any cmdline tag. */
++ for (; t->hdr.size; t = tag_next(t)) {
++ if (t->hdr.tag == ATAG_CMDLINE) {
++ p = t->u.cmdline.cmdline;
++ }
++ }
++
++ /* Overwrite the end of the table with a new cmdline tag. */
++ t->hdr.tag = ATAG_CMDLINE;
++ t->hdr.size = (sizeof (struct tag_header) +
++ strlen(cambria_rtc_probe) + strlen(p) + 1 + 4) >> 2;
++ strlcpy(t->u.cmdline.cmdline, cambria_rtc_probe, COMMAND_LINE_SIZE);
++ strlcpy(t->u.cmdline.cmdline + strlen(cambria_rtc_probe), p,
++ COMMAND_LINE_SIZE - strlen(cambria_rtc_probe));
++
++ /* Terminate the table. */
++ t = tag_next(t);
++ t->hdr.tag = ATAG_NONE;
++ t->hdr.size = 0;
++}
++
++#ifdef CONFIG_SENSORS_EEPROM
++static int cambria_eeprom_do(struct notifier_block *self, unsigned long event, void *t)
++{
++ struct eeprom_data *data = t;
++ struct sockaddr address;
++ struct net_device * netdev;
++
++ char macs[12];
++
++ /* The MACs are the first 12 bytes in the eeprom at address 0x51 */
++ if (event == EEPROM_REGISTER && data->client.addr == 0x51) {
++ data->attr->read(&data->client.dev.kobj, data->attr, macs, 0, 12);
++ /* eth0 */
++ memcpy(address.sa_data, macs, ETH_ALEN);
++ memcpy(&cambria_plat_eth[0].hwaddr, macs, ETH_ALEN);
++ if ( (netdev = dev_get_by_name(&init_net, "eth0")) )
++ netdev->set_mac_address(netdev, &address);
++
++ /* eth1 */
++ memcpy(address.sa_data, macs + ETH_ALEN, ETH_ALEN);
++ memcpy(&cambria_plat_eth[1].hwaddr, macs + ETH_ALEN, ETH_ALEN);
++ if ( (netdev = dev_get_by_name(&init_net, "eth1")) )
++ netdev->set_mac_address(netdev, &address);
++ }
++
++ return NOTIFY_DONE;
++}
++
++static struct notifier_block cambria_eeprom_notifier = {
++ .notifier_call = cambria_eeprom_do
++};
++#endif
++
++static void __init cambria_init(void)
++{
++ ixp4xx_sys_init();
++
++#ifdef CONFIG_SENSORS_EEPROM
++ register_eeprom_notifier(&cambria_eeprom_notifier);
++#endif
++
++ 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;
++
++ platform_device_register(&cambria_pata);
++}
++
++#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,
++ .fixup = cambria_fixup,
++ .map_io = ixp4xx_map_io,
++ .init_irq = ixp4xx_init_irq,
++ .timer = &ixp4xx_timer,
++ .boot_params = 0x0100,
++ .init_machine = cambria_init,
++MACHINE_END
++#endif
+diff -Nur linux-2.6.24.5/include/asm-arm/arch-ixp4xx/hardware.h linux-2.6.24.5-owrt/include/asm-arm/arch-ixp4xx/hardware.h
+--- linux-2.6.24.5/include/asm-arm/arch-ixp4xx/hardware.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.24.5-owrt/include/asm-arm/arch-ixp4xx/hardware.h 2008-04-28 21:07:16.000000000 +0200
+@@ -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.
diff --git a/target/linux/ixp4xx/patches-2.6.24/204-npe_driver_ixp43x_support.patch b/target/linux/ixp4xx/patches-2.6.24/204-npe_driver_ixp43x_support.patch
new file mode 100644
index 0000000000..c0b55aa118
--- /dev/null
+++ b/target/linux/ixp4xx/patches-2.6.24/204-npe_driver_ixp43x_support.patch
@@ -0,0 +1,86 @@
+diff -Nur linux-2.6.24.2/arch/arm/mach-ixp4xx/ixp4xx_npe.c linux-2.6.24.2-owrt/arch/arm/mach-ixp4xx/ixp4xx_npe.c
+--- linux-2.6.24.2/arch/arm/mach-ixp4xx/ixp4xx_npe.c 2008-04-22 12:24:29.000000000 +0200
++++ linux-2.6.24.2-owrt/arch/arm/mach-ixp4xx/ixp4xx_npe.c 2008-04-24 13:26:56.000000000 +0200
+@@ -571,8 +571,8 @@
+ for (i = 0; i < image->size; i++)
+ image->data[i] = swab32(image->data[i]);
+
+- if (!cpu_is_ixp46x() && ((image->id >> 28) & 0xF /* device ID */)) {
+- print_npe(KERN_INFO, npe, "IXP46x firmware ignored on "
++ if (cpu_is_ixp42x() && ((image->id >> 28) & 0xF /* device ID */)) {
++ print_npe(KERN_INFO, npe, "IXP46x/IXP43x firmware ignored on "
+ "IXP42x\n");
+ goto err;
+ }
+@@ -594,7 +594,7 @@
+ "revision 0x%X:%X\n", (image->id >> 16) & 0xFF,
+ (image->id >> 8) & 0xFF, image->id & 0xFF);
+
+- if (!cpu_is_ixp46x()) {
++ if (cpu_is_ixp42x()) {
+ if (!npe->id)
+ instr_size = NPE_A_42X_INSTR_SIZE;
+ else
+diff -Nur linux-2.6.24.2/drivers/net/arm/ixp4xx_eth.c linux-2.6.24.2-owrt/drivers/net/arm/ixp4xx_eth.c
+--- linux-2.6.24.2/drivers/net/arm/ixp4xx_eth.c 2008-04-22 12:24:29.000000000 +0200
++++ linux-2.6.24.2-owrt/drivers/net/arm/ixp4xx_eth.c 2008-04-24 18:23:24.000000000 +0200
+@@ -32,6 +32,7 @@
+ #include <linux/kernel.h>
+ #include <linux/mii.h>
+ #include <linux/platform_device.h>
++#include <asm/arch/cpu.h>
+ #include <asm/arch/npe.h>
+ #include <asm/arch/qmgr.h>
+
+@@ -1238,12 +1239,16 @@
+
+ static int __init eth_init_module(void)
+ {
+- if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0))
+- return -ENOSYS;
+
+- /* All MII PHY accesses use NPE-B Ethernet registers */
+ spin_lock_init(&mdio_lock);
+- mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT;
++ if (!cpu_is_ixp43x())
++ /* All MII PHY accesses use NPE-B Ethernet registers */
++ mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT;
++
++ else
++ /* IXP43x lacks NPE-B and uses NPE-C for MII PHY access */
++ mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT;
++
+ __raw_writel(DEFAULT_CORE_CNTRL, &mdio_regs->core_control);
+
+ return platform_driver_register(&drv);
+diff -Nur linux-2.6.24.2/include/asm-arm/arch-ixp4xx/cpu.h linux-2.6.24.2-owrt/include/asm-arm/arch-ixp4xx/cpu.h
+--- linux-2.6.24.2/include/asm-arm/arch-ixp4xx/cpu.h 2008-04-22 12:24:29.000000000 +0200
++++ linux-2.6.24.2-owrt/include/asm-arm/arch-ixp4xx/cpu.h 2008-04-24 18:15:29.000000000 +0200
+@@ -34,6 +34,8 @@
+ val &= ~IXP4XX_FEATURE_RESERVED;
+ if (!cpu_is_ixp46x())
+ val &= ~IXP4XX_FEATURE_IXP46X_ONLY;
++ if (cpu_is_ixp42x())
++ val &= ~IXP4XX_FEATURE_IXP43X_46X;
+
+ return val;
+ }
+diff -Nur linux-2.6.24.2/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h linux-2.6.24.2-owrt/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
+--- linux-2.6.24.2/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h 2008-04-22 12:24:29.000000000 +0200
++++ linux-2.6.24.2-owrt/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h 2008-04-24 18:15:13.000000000 +0200
+@@ -628,11 +628,12 @@
+ #define IXP4XX_FEATURE_XSCALE_MAX_FREQ (3 << 22)
+ #define IXP4XX_FEATURE_RESERVED (0xFF << 24)
+
+-#define IXP4XX_FEATURE_IXP46X_ONLY (IXP4XX_FEATURE_ECC_TIMESYNC | \
++#define IXP4XX_FEATURE_IXP43X_46X (IXP4XX_FEATURE_ECC_TIMESYNC | \
+ IXP4XX_FEATURE_USB_HOST | \
+ IXP4XX_FEATURE_NPEA_ETH | \
+- IXP4XX_FEATURE_NPEB_ETH_1_TO_3 | \
+- IXP4XX_FEATURE_RSA | \
+ IXP4XX_FEATURE_XSCALE_MAX_FREQ)
+
++#define IXP4XX_FEATURE_IXP46X_ONLY (IXP4XX_FEATURE_NPEB_ETH_1_TO_3 | \
++ IXP4XX_FEATURE_RSA)
++
+ #endif