diff options
Diffstat (limited to 'target')
41 files changed, 6158 insertions, 0 deletions
| diff --git a/target/linux/ixp4xx/config-2.6.31 b/target/linux/ixp4xx/config-2.6.31 new file mode 100644 index 000000000..79bb193f6 --- /dev/null +++ b/target/linux/ixp4xx/config-2.6.31 @@ -0,0 +1,157 @@ +# CONFIG_AEABI is not set +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_ARCH_ADI_COYOTE is not set +CONFIG_ARCH_IXCDP1100=y +CONFIG_ARCH_IXDP425=y +CONFIG_ARCH_IXDP4XX=y +CONFIG_ARCH_IXP4XX=y +# CONFIG_ARCH_PRPMC1100 is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM=y +# CONFIG_ARM_THUMB is not set +# CONFIG_ARPD is not set +CONFIG_BASE_SMALL=0 +CONFIG_BITREVERSE=y +CONFIG_BOUNCE=y +CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=squashfs,jffs2 noinitrd console=ttyS0,115200" +CONFIG_CPU_32=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +CONFIG_CPU_ENDIAN_BE32=y +# CONFIG_CPU_ENDIAN_BE8 is not set +CONFIG_CPU_IXP43X=y +CONFIG_CPU_IXP46X=y +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_XSCALE=y +CONFIG_CRC16=y +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_USER is not set +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DEVPORT=y +# CONFIG_DM9000 is not set +CONFIG_DMABOUNCE=y +CONFIG_DNOTIFY=y +CONFIG_EEPROM_AT24=y +# CONFIG_FPE_FASTFPE is not set +# CONFIG_FPE_NWFPE is not set +CONFIG_FRAME_POINTER=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_DEVICE=y +CONFIG_GPIO_GW_I2C_PLD=y +CONFIG_GPIO_SYSFS=y +# CONFIG_HAMRADIO is not set +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_AOUT=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_HAVE_MTD_OTP=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_IXP4XX=y +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_GPIO=y +# CONFIG_I2C_IOP3XX is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ISDN is not set +# CONFIG_IWMMXT is not set +CONFIG_IXP4XX_ETH=y +# CONFIG_IXP4XX_INDIRECT_PCI is not set +CONFIG_IXP4XX_LEGACY_DMABOUNCE=y +CONFIG_IXP4XX_NPE=y +CONFIG_IXP4XX_QMGR=y +CONFIG_IXP4XX_WATCHDOG=y +CONFIG_LEDS_FSG=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_LATCH=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_MACH_AP1000=y +CONFIG_MACH_AVILA=y +CONFIG_MACH_CAMBRIA=y +CONFIG_MACH_COMPEX=y +CONFIG_MACH_DSMG600=y +CONFIG_MACH_FSG=y +CONFIG_MACH_GATEWAY7001=y +# CONFIG_MACH_GORAMO_MLR is not set +# CONFIG_MACH_GTWX5715 is not set +# CONFIG_MACH_IXDP465 is not set +CONFIG_MACH_IXDPG425=y +# CONFIG_MACH_KIXRP435 is not set +CONFIG_MACH_LOFT=y +CONFIG_MACH_MI424WR=y +CONFIG_MACH_NAS100D=y +CONFIG_MACH_NSLU2=y +CONFIG_MACH_PRONGHORN=y +CONFIG_MACH_PRONGHORNMETRO=y +CONFIG_MACH_SIDEWINDER=y +CONFIG_MACH_TW5334=y +CONFIG_MACH_USR8200=y +CONFIG_MACH_WG302V1=y +CONFIG_MACH_WG302V2=y +CONFIG_MACH_WRT300NV2=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_IXP4XX=y +CONFIG_MTD_OTP=y +CONFIG_MTD_REDBOOT_PARTS=y +# CONFIG_NATSEMI is not set +# CONFIG_NVRAM is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PCI=y +CONFIG_PCI_SYSCALL=y +CONFIG_PHYLIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_DS1672=y +CONFIG_RTC_DRV_ISL1208=y +CONFIG_RTC_DRV_PCF8563=y +CONFIG_RTC_DRV_X1205=y +# CONFIG_SCSI_DMA is not set +CONFIG_SENSORS_AD7418=y +CONFIG_SENSORS_MAX6650=y +CONFIG_SENSORS_W83781D=y +# CONFIG_SERIAL_8250_EXTENDED is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SPLIT_PTLOCK_CPUS=4096 +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_TICK_ONESHOT=y +CONFIG_UID16=y +CONFIG_USB_SUPPORT=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_WATCHDOG_NOWAYOUT=y +CONFIG_XSCALE_PMU=y +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_ZBOOT_ROM_TEXT=0x0 diff --git a/target/linux/ixp4xx/patches-2.6.31/010-ixp43x_pci_fixup.patch b/target/linux/ixp4xx/patches-2.6.31/010-ixp43x_pci_fixup.patch new file mode 100644 index 000000000..35af7f4fa --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/010-ixp43x_pci_fixup.patch @@ -0,0 +1,11 @@ +--- a/arch/arm/mach-ixp4xx/include/mach/hardware.h ++++ b/arch/arm/mach-ixp4xx/include/mach/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		0x48000000 +  + /* +  * We override the standard dma-mask routines for bouncing. diff --git a/target/linux/ixp4xx/patches-2.6.31/020-gateworks_i2c_pld.patch b/target/linux/ixp4xx/patches-2.6.31/020-gateworks_i2c_pld.patch new file mode 100644 index 000000000..782daf75a --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/020-gateworks_i2c_pld.patch @@ -0,0 +1,421 @@ +--- /dev/null ++++ b/drivers/gpio/gw_i2c_pld.c +@@ -0,0 +1,371 @@ ++/* ++ * Gateworks I2C PLD GPIO expander ++ * ++ * Copyright (C) 2009 Gateworks Corporation ++ * ++ * 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. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/slab.h> ++#include <linux/hardirq.h> ++#include <linux/i2c.h> ++#include <linux/i2c/gw_i2c_pld.h> ++#include <asm/gpio.h> ++ ++static const struct i2c_device_id gw_i2c_pld_id[] = { ++	{ "gw_i2c_pld", 8 }, ++	{ } ++}; ++MODULE_DEVICE_TABLE(i2c, gw_i2c_pld_id); ++ ++/* ++ * The Gateworks I2C PLD chip only expose one read and one ++ * write register.  Writing a "one" bit (to match the reset state) lets ++ * that pin be used as an input. It is an open-drain model. ++ */ ++ ++struct gw_i2c_pld { ++	struct gpio_chip	chip; ++	struct i2c_client	*client; ++	unsigned		out;		/* software latch */ ++}; ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * The Gateworks I2C PLD chip does not properly send the acknowledge bit ++ * thus we cannot use standard i2c_smbus functions. We have recreated ++ * our own here, but we still use the mutex_lock to lock the i2c_bus ++ * as the device still exists on the I2C bus. ++*/ ++ ++#define PLD_SCL_GPIO 6 ++#define PLD_SDA_GPIO 7 ++ ++#define SCL_LO()  gpio_line_set(PLD_SCL_GPIO, IXP4XX_GPIO_LOW) ++#define SCL_HI()  gpio_line_set(PLD_SCL_GPIO, IXP4XX_GPIO_HIGH) ++#define SCL_EN()  gpio_line_config(PLD_SCL_GPIO, IXP4XX_GPIO_OUT) ++#define SDA_LO()  gpio_line_set(PLD_SDA_GPIO, IXP4XX_GPIO_LOW) ++#define SDA_HI()  gpio_line_set(PLD_SDA_GPIO, IXP4XX_GPIO_HIGH) ++#define SDA_EN()  gpio_line_config(PLD_SDA_GPIO, IXP4XX_GPIO_OUT) ++#define SDA_DIS() gpio_line_config(PLD_SDA_GPIO, IXP4XX_GPIO_IN) ++#define SDA_IN(x) gpio_line_get(PLD_SDA_GPIO, &x); ++ ++static int i2c_pld_write_byte(int address, int byte) ++{ ++	int i; ++ ++	address = (address << 1) & ~0x1; ++ ++	SDA_HI(); ++	SDA_EN(); ++	SCL_EN(); ++	SCL_HI(); ++	SDA_LO(); ++	SCL_LO(); ++ ++	for (i = 7; i >= 0; i--) ++	{ ++		if (address & (1 << i)) ++			SDA_HI(); ++		else ++			SDA_LO(); ++ ++		SCL_HI(); ++		SCL_LO(); ++	} ++ ++	SDA_DIS(); ++	SCL_HI(); ++	SDA_IN(i); ++	SCL_LO(); ++	SDA_EN(); ++ ++	for (i = 7; i >= 0; i--) ++	{ ++		if (byte & (1 << i)) ++      SDA_HI(); ++		else ++			SDA_LO(); ++		SCL_HI(); ++		SCL_LO(); ++	} ++ ++	SDA_DIS(); ++	SCL_HI(); ++	SDA_IN(i); ++	SCL_LO(); ++ ++	SDA_HI(); ++	SDA_EN(); ++ ++	SDA_LO(); ++	SCL_HI(); ++	SDA_HI(); ++	SCL_LO(); ++	SCL_HI(); ++ ++	return 0; ++} ++ ++static unsigned int i2c_pld_read_byte(int address) ++{ ++	int i = 0, byte = 0; ++	int bit; ++ ++	address = (address << 1) | 0x1; ++ ++	SDA_HI(); ++	SDA_EN(); ++	SCL_EN(); ++	SCL_HI(); ++	SDA_LO(); ++	SCL_LO(); ++ ++	for (i = 7; i >= 0; i--) ++	{ ++		if (address & (1 << i)) ++			SDA_HI(); ++		else ++			SDA_LO(); ++ ++		SCL_HI(); ++		SCL_LO(); ++	} ++ ++	SDA_DIS(); ++	SCL_HI(); ++	SDA_IN(i); ++	SCL_LO(); ++	SDA_EN(); ++ ++	SDA_DIS(); ++	for (i = 7; i >= 0; i--) ++	{ ++		SCL_HI(); ++		SDA_IN(bit); ++		byte |= bit << i; ++		SCL_LO(); ++	} ++ ++	SDA_LO(); ++	SCL_HI(); ++	SDA_HI(); ++	SCL_LO(); ++	SCL_HI(); ++ ++	return byte; ++} ++ ++ ++static int gw_i2c_pld_input8(struct gpio_chip *chip, unsigned offset) ++{ ++	int ret; ++	struct gw_i2c_pld *gpio = container_of(chip, struct gw_i2c_pld, chip); ++	struct i2c_adapter *adap = gpio->client->adapter; ++	 ++	if (in_atomic() || irqs_disabled()) { ++		ret = mutex_trylock(&adap->bus_lock); ++		if (!ret) ++			/* I2C activity is ongoing. */ ++			return -EAGAIN; ++	} else { ++		mutex_lock_nested(&adap->bus_lock, adap->level); ++	} ++ ++	gpio->out |= (1 << offset); ++ ++	ret = i2c_pld_write_byte(gpio->client->addr, gpio->out); ++ ++	mutex_unlock(&adap->bus_lock); ++ ++	return ret; ++} ++ ++static int gw_i2c_pld_get8(struct gpio_chip *chip, unsigned offset) ++{ ++	int ret; ++	s32	value; ++	struct gw_i2c_pld *gpio = container_of(chip, struct gw_i2c_pld, chip); ++	struct i2c_adapter *adap = gpio->client->adapter; ++	 ++	if (in_atomic() || irqs_disabled()) { ++		ret = mutex_trylock(&adap->bus_lock); ++		if (!ret) ++			/* I2C activity is ongoing. */ ++			return -EAGAIN; ++	} else { ++		mutex_lock_nested(&adap->bus_lock, adap->level); ++	} ++ ++	value = i2c_pld_read_byte(gpio->client->addr); ++ ++	mutex_unlock(&adap->bus_lock); ++ ++	return (value < 0) ? 0 : (value & (1 << offset)); ++} ++ ++static int gw_i2c_pld_output8(struct gpio_chip *chip, unsigned offset, int value) ++{ ++	int ret; ++ ++	struct gw_i2c_pld *gpio = container_of(chip, struct gw_i2c_pld, chip); ++	struct i2c_adapter *adap = gpio->client->adapter; ++ ++	unsigned bit = 1 << offset; ++	 ++	if (in_atomic() || irqs_disabled()) { ++		ret = mutex_trylock(&adap->bus_lock); ++		if (!ret) ++			/* I2C activity is ongoing. */ ++			return -EAGAIN; ++	} else { ++		mutex_lock_nested(&adap->bus_lock, adap->level); ++	} ++ ++ ++	if (value) ++		gpio->out |= bit; ++	else ++		gpio->out &= ~bit; ++ ++	ret = i2c_pld_write_byte(gpio->client->addr, gpio->out); ++ ++	mutex_unlock(&adap->bus_lock); ++ ++	return ret; ++} ++ ++static void gw_i2c_pld_set8(struct gpio_chip *chip, unsigned offset, int value) ++{ ++	gw_i2c_pld_output8(chip, offset, value); ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int gw_i2c_pld_probe(struct i2c_client *client, ++			 const struct i2c_device_id *id) ++{ ++	struct gw_i2c_pld_platform_data	*pdata; ++	struct gw_i2c_pld *gpio; ++	int status; ++ ++	pdata = client->dev.platform_data; ++	if (!pdata) ++		return -ENODEV; ++ ++	/* Allocate, initialize, and register this gpio_chip. */ ++	gpio = kzalloc(sizeof *gpio, GFP_KERNEL); ++	if (!gpio) ++		return -ENOMEM; ++ ++	gpio->chip.base = pdata->gpio_base; ++	gpio->chip.can_sleep = 1; ++	gpio->chip.dev = &client->dev; ++	gpio->chip.owner = THIS_MODULE; ++ ++	gpio->chip.ngpio = pdata->nr_gpio; ++	gpio->chip.direction_input = gw_i2c_pld_input8; ++	gpio->chip.get = gw_i2c_pld_get8; ++	gpio->chip.direction_output = gw_i2c_pld_output8; ++	gpio->chip.set = gw_i2c_pld_set8; ++ ++	gpio->chip.label = client->name; ++ ++	gpio->client = client; ++	i2c_set_clientdata(client, gpio); ++ ++	gpio->out = 0xFF; ++ ++	status = gpiochip_add(&gpio->chip); ++	if (status < 0) ++		goto fail; ++ ++	dev_info(&client->dev, "gpios %d..%d on a %s%s\n", ++			gpio->chip.base, ++			gpio->chip.base + gpio->chip.ngpio - 1, ++			client->name, ++			client->irq ? " (irq ignored)" : ""); ++ ++	/* Let platform code set up the GPIOs and their users. ++	 * Now is the first time anyone could use them. ++	 */ ++	if (pdata->setup) { ++		status = pdata->setup(client, ++				gpio->chip.base, gpio->chip.ngpio, ++				pdata->context); ++		if (status < 0) ++			dev_warn(&client->dev, "setup --> %d\n", status); ++	} ++ ++	return 0; ++ ++fail: ++	dev_dbg(&client->dev, "probe error %d for '%s'\n", ++			status, client->name); ++	kfree(gpio); ++	return status; ++} ++ ++static int gw_i2c_pld_remove(struct i2c_client *client) ++{ ++	struct gw_i2c_pld_platform_data	*pdata = client->dev.platform_data; ++	struct gw_i2c_pld *gpio = i2c_get_clientdata(client); ++	int				status = 0; ++ ++	if (pdata->teardown) { ++		status = pdata->teardown(client, ++				gpio->chip.base, gpio->chip.ngpio, ++				pdata->context); ++		if (status < 0) { ++			dev_err(&client->dev, "%s --> %d\n", ++					"teardown", status); ++			return status; ++		} ++	} ++ ++	status = gpiochip_remove(&gpio->chip); ++	if (status == 0) ++		kfree(gpio); ++	else ++		dev_err(&client->dev, "%s --> %d\n", "remove", status); ++	return status; ++} ++ ++static struct i2c_driver gw_i2c_pld_driver = { ++	.driver = { ++		.name	= "gw_i2c_pld", ++		.owner	= THIS_MODULE, ++	}, ++	.probe	= gw_i2c_pld_probe, ++	.remove	= gw_i2c_pld_remove, ++	.id_table = gw_i2c_pld_id, ++}; ++ ++static int __init gw_i2c_pld_init(void) ++{ ++	return i2c_add_driver(&gw_i2c_pld_driver); ++} ++module_init(gw_i2c_pld_init); ++ ++static void __exit gw_i2c_pld_exit(void) ++{ ++	i2c_del_driver(&gw_i2c_pld_driver); ++} ++module_exit(gw_i2c_pld_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Chris Lang"); +--- a/drivers/gpio/Kconfig ++++ b/drivers/gpio/Kconfig +@@ -173,6 +173,14 @@ config GPIO_BT8XX +  + 	  If unsure, say N. +  ++config GPIO_GW_I2C_PLD ++	tristate "Gateworks I2C PLD GPIO Expander" ++	depends on I2C ++	help ++		Say yes here to provide access to the Gateworks I2C PLD GPIO ++		Expander. This is used at least on the GW2358-4. ++ ++ + comment "SPI GPIO expanders:" +  + config GPIO_MAX7301 +--- a/drivers/gpio/Makefile ++++ b/drivers/gpio/Makefile +@@ -14,3 +14,4 @@ obj-$(CONFIG_GPIO_TWL4030)	+= twl4030-gp + obj-$(CONFIG_GPIO_XILINX)	+= xilinx_gpio.o + obj-$(CONFIG_GPIO_BT8XX)	+= bt8xxgpio.o + obj-$(CONFIG_GPIO_VR41XX)	+= vr41xx_giu.o ++obj-$(CONFIG_GPIO_GW_I2C_PLD)	+= gw_i2c_pld.o +--- /dev/null ++++ b/include/linux/i2c/gw_i2c_pld.h +@@ -0,0 +1,20 @@ ++#ifndef __LINUX_GW_I2C_PLD_H ++#define __LINUX_GW_I2C_PLD_H ++ ++/** ++ * The Gateworks I2C PLD Implements an additional 8 bits of GPIO through the PLD ++ */ ++ ++struct gw_i2c_pld_platform_data { ++	unsigned gpio_base; ++	unsigned nr_gpio; ++	int		(*setup)(struct i2c_client *client, ++					int gpio, unsigned ngpio, ++					void *context); ++	int		(*teardown)(struct i2c_client *client, ++					int gpio, unsigned ngpio, ++					void *context); ++	void		*context; ++}; ++ ++#endif /* __LINUX_GW_I2C_PLD_H */ diff --git a/target/linux/ixp4xx/patches-2.6.31/050-disable_dmabounce.patch b/target/linux/ixp4xx/patches-2.6.31/050-disable_dmabounce.patch new file mode 100644 index 000000000..ad7cbdd98 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/050-disable_dmabounce.patch @@ -0,0 +1,164 @@ +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -384,7 +384,6 @@ config ARCH_IXP4XX + 	select GENERIC_GPIO + 	select GENERIC_TIME + 	select GENERIC_CLOCKEVENTS +-	select DMABOUNCE if PCI + 	help + 	  Support for Intel's IXP4XX (XScale) family of processors. +  +--- a/arch/arm/mach-ixp4xx/Kconfig ++++ b/arch/arm/mach-ixp4xx/Kconfig +@@ -199,6 +199,45 @@ config IXP4XX_INDIRECT_PCI + 	  need to use the indirect method instead. If you don't know + 	  what you need, leave this option unselected. +  ++config IXP4XX_LEGACY_DMABOUNCE ++	bool "legacy PCI DMA bounce support" ++	depends on PCI ++	default n ++	select DMABOUNCE ++	help ++	  The IXP4xx is limited to a 64MB window for PCI DMA, which ++	  requires that PCI accesses above 64MB are bounced via buffers ++	  below 64MB. Furthermore the IXP4xx has an erratum where PCI ++	  read prefetches just below the 64MB limit can trigger lockups. ++ ++	  The kernel has traditionally handled these two issue by using ++	  ARM specific DMA bounce support code for all accesses >= 64MB. ++	  That code causes problems of its own, so it is desirable to ++	  disable it. As the kernel now has a workaround for the PCI read ++	  prefetch erratum, it no longer requires the ARM bounce code. ++ ++	  Enabling this option makes IXP4xx continue to use the problematic ++	  ARM DMA bounce code. Disabling this option makes IXP4xx use the ++	  kernel's generic bounce code. ++ ++	  Say 'N'. ++ ++config IXP4XX_ZONE_DMA ++	bool "Support > 64MB RAM" ++	depends on !IXP4XX_LEGACY_DMABOUNCE ++	default y ++	select ZONE_DMA ++	help ++	  The IXP4xx is limited to a 64MB window for PCI DMA, which ++	  requires that PCI accesses above 64MB are bounced via buffers ++	  below 64MB. ++ ++	  Disabling this option allows you to omit the support code for ++	  DMA-able memory allocations and DMA bouncing, but the kernel ++	  will then not work properly if more than 64MB of RAM is present. ++ ++	  Say 'Y' unless your platform is limited to <= 64MB of RAM. ++ + config IXP4XX_QMGR + 	tristate "IXP4xx Queue Manager support" + 	help +--- a/arch/arm/mach-ixp4xx/common-pci.c ++++ b/arch/arm/mach-ixp4xx/common-pci.c +@@ -321,27 +321,38 @@ static int abort_handler(unsigned long a +  */ + static int ixp4xx_pci_platform_notify(struct device *dev) + { +-	if(dev->bus == &pci_bus_type) { +-		*dev->dma_mask =  SZ_64M - 1; ++	if (dev->bus == &pci_bus_type) { ++		*dev->dma_mask = SZ_64M - 1; + 		dev->coherent_dma_mask = SZ_64M - 1; ++#ifdef CONFIG_DMABOUNCE + 		dmabounce_register_dev(dev, 2048, 4096); ++#endif + 	} + 	return 0; + } +  + static int ixp4xx_pci_platform_notify_remove(struct device *dev) + { +-	if(dev->bus == &pci_bus_type) { ++#ifdef CONFIG_DMABOUNCE ++	if (dev->bus == &pci_bus_type) + 		dmabounce_unregister_dev(dev); +-	} ++#endif + 	return 0; + } +  ++#ifdef CONFIG_DMABOUNCE + int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) + { ++	/* Note that this returns true for the last page below 64M due to ++	 * IXP4xx erratum 15 (SCR 1289), which states that PCI prefetches ++	 * can cross the boundary between valid memory and a reserved region ++	 * causing AHB bus errors and a lock-up. ++	 */ + 	return (dev->bus == &pci_bus_type ) && ((dma_addr + size) >= SZ_64M); + } ++#endif +  ++#ifdef CONFIG_ZONE_DMA + /* +  * Only first 64MB of memory can be accessed via PCI. +  * We use GFP_DMA to allocate safe buffers to do map/unmap. +@@ -364,6 +375,7 @@ void __init ixp4xx_adjust_zones(int node + 	zhole_size[1] = zhole_size[0]; + 	zhole_size[0] = 0; + } ++#endif +  + void __init ixp4xx_pci_preinit(void) + { +@@ -517,19 +529,35 @@ struct pci_bus * __devinit ixp4xx_scan_b + int + pci_set_dma_mask(struct pci_dev *dev, u64 mask) + { +-	if (mask >= SZ_64M - 1 ) ++#ifdef CONFIG_DMABOUNCE ++	if (mask >= SZ_64M - 1) + 		return 0; +  + 	return -EIO; ++#else ++	/* Only honour masks < SZ_64M. Silently ignore masks >= SZ_64M ++	   as generic drivers do not know about IXP4xx PCI DMA quirks. */ ++	if (mask < SZ_64M) ++		dev->dma_mask = mask; ++	return 0; ++#endif + } +      + int + pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) + { +-	if (mask >= SZ_64M - 1 ) ++#ifdef CONFIG_DMABOUNCE ++	if (mask >= SZ_64M - 1) + 		return 0; +  + 	return -EIO; ++#else ++	/* Only honour masks < SZ_64M. Silently ignore masks >= SZ_64M ++	   as generic drivers do not know about IXP4xx PCI DMA quirks. */ ++	if (mask < SZ_64M) ++		dev->dev.coherent_dma_mask = mask; ++	return 0; ++#endif + } +  + EXPORT_SYMBOL(ixp4xx_pci_read); +--- a/arch/arm/mach-ixp4xx/include/mach/memory.h ++++ b/arch/arm/mach-ixp4xx/include/mach/memory.h +@@ -16,10 +16,12 @@ +  + #if !defined(__ASSEMBLY__) && defined(CONFIG_PCI) +  ++#ifdef CONFIG_ZONE_DMA + void ixp4xx_adjust_zones(int node, unsigned long *size, unsigned long *holes); +  + #define arch_adjust_zones(node, size, holes) \ + 	ixp4xx_adjust_zones(node, size, holes) ++#endif +  + #define ISA_DMA_THRESHOLD (SZ_64M - 1) + #define MAX_DMA_ADDRESS		(PAGE_OFFSET + SZ_64M) diff --git a/target/linux/ixp4xx/patches-2.6.31/090-increase_entropy_pools.patch b/target/linux/ixp4xx/patches-2.6.31/090-increase_entropy_pools.patch new file mode 100644 index 000000000..bb168fa84 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/090-increase_entropy_pools.patch @@ -0,0 +1,15 @@ +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -263,9 +263,9 @@ + /* +  * Configuration information +  */ +-#define INPUT_POOL_WORDS 128 +-#define OUTPUT_POOL_WORDS 32 +-#define SEC_XFER_SIZE 512 ++#define INPUT_POOL_WORDS 256 ++#define OUTPUT_POOL_WORDS 64 ++#define SEC_XFER_SIZE 1024 +  + /* +  * The minimum number of bits of entropy before we wake up a read on diff --git a/target/linux/ixp4xx/patches-2.6.31/100-wg302v2_gateway7001_mac_plat_info.patch b/target/linux/ixp4xx/patches-2.6.31/100-wg302v2_gateway7001_mac_plat_info.patch new file mode 100644 index 000000000..a19a4085a --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/100-wg302v2_gateway7001_mac_plat_info.patch @@ -0,0 +1,68 @@ +--- a/arch/arm/mach-ixp4xx/gateway7001-setup.c ++++ b/arch/arm/mach-ixp4xx/gateway7001-setup.c +@@ -76,9 +76,35 @@ static struct platform_device gateway700 + 	.resource	= &gateway7001_uart_resource, + }; +  ++static struct eth_plat_info gateway7001_plat_eth[] = { ++	{ ++		.phy		= 1, ++		.rxq		= 3, ++		.txreadyq	= 20, ++	}, { ++		.phy		= 2, ++		.rxq		= 4, ++		.txreadyq	= 21, ++	} ++}; ++ ++static struct platform_device gateway7001_eth[] = { ++	{ ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEB, ++		.dev.platform_data	= gateway7001_plat_eth, ++	}, { ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEC, ++		.dev.platform_data	= gateway7001_plat_eth + 1, ++	} ++}; ++ + static struct platform_device *gateway7001_devices[] __initdata = { + 	&gateway7001_flash, +-	&gateway7001_uart ++	&gateway7001_uart, ++	&gateway7001_eth[0], ++	&gateway7001_eth[1], + }; +  + static void __init gateway7001_init(void) +--- a/arch/arm/mach-ixp4xx/wg302v2-setup.c ++++ b/arch/arm/mach-ixp4xx/wg302v2-setup.c +@@ -77,9 +77,26 @@ static struct platform_device wg302v2_ua + 	.resource	= &wg302v2_uart_resource, + }; +  ++static struct eth_plat_info wg302v2_plat_eth[] = { ++	{ ++		.phy		= 8, ++		.rxq		= 3, ++		.txreadyq	= 20, ++	} ++}; ++ ++static struct platform_device wg302v2_eth[] = { ++	{ ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEB, ++		.dev.platform_data	= wg302v2_plat_eth, ++	} ++}; ++ + static struct platform_device *wg302v2_devices[] __initdata = { + 	&wg302v2_flash, + 	&wg302v2_uart, ++	&wg302v2_eth[0], + }; +  + static void __init wg302v2_init(void) diff --git a/target/linux/ixp4xx/patches-2.6.31/105-wg302v1_support.patch b/target/linux/ixp4xx/patches-2.6.31/105-wg302v1_support.patch new file mode 100644 index 000000000..e8b4342e7 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/105-wg302v1_support.patch @@ -0,0 +1,257 @@ +--- a/arch/arm/configs/ixp4xx_defconfig ++++ b/arch/arm/configs/ixp4xx_defconfig +@@ -155,6 +155,7 @@ CONFIG_MACH_AVILA=y + CONFIG_MACH_LOFT=y + CONFIG_ARCH_ADI_COYOTE=y + CONFIG_MACH_GATEWAY7001=y ++CONFIG_MACH_WG302V1=y + CONFIG_MACH_WG302V2=y + CONFIG_ARCH_IXDP425=y + CONFIG_MACH_IXDPG425=y +--- a/arch/arm/mach-ixp4xx/Kconfig ++++ b/arch/arm/mach-ixp4xx/Kconfig +@@ -49,6 +49,14 @@ config MACH_GATEWAY7001 + 	  7001 Access Point. For more information on this platform, + 	  see http://openwrt.org +  ++config MACH_WG302V1 ++	bool "Netgear WG302 v1 / WAG302 v1" ++	select PCI ++	help ++	  Say 'Y' here if you want your kernel to support Netgear's ++	  WG302 v1 or WAG302 v1 Access Points. For more information ++	  on this platform, see http://openwrt.org ++ + config MACH_WG302V2 + 	bool "Netgear WG302 v2 / WAG302 v2" + 	select PCI +--- a/arch/arm/mach-ixp4xx/Makefile ++++ b/arch/arm/mach-ixp4xx/Makefile +@@ -14,6 +14,7 @@ obj-pci-$(CONFIG_MACH_NSLU2)		+= nslu2-p + obj-pci-$(CONFIG_MACH_NAS100D)		+= nas100d-pci.o + obj-pci-$(CONFIG_MACH_DSMG600)		+= dsmg600-pci.o + obj-pci-$(CONFIG_MACH_GATEWAY7001)	+= gateway7001-pci.o ++obj-pci-$(CONFIG_MACH_WG302V1)		+= wg302v1-pci.o + obj-pci-$(CONFIG_MACH_WG302V2)		+= wg302v2-pci.o + obj-pci-$(CONFIG_MACH_FSG)		+= fsg-pci.o +  +@@ -28,6 +29,7 @@ obj-$(CONFIG_MACH_NSLU2)	+= nslu2-setup. + obj-$(CONFIG_MACH_NAS100D)	+= nas100d-setup.o + obj-$(CONFIG_MACH_DSMG600)      += dsmg600-setup.o + obj-$(CONFIG_MACH_GATEWAY7001)	+= gateway7001-setup.o ++obj-$(CONFIG_MACH_WG302V1)	+= wg302v1-setup.o + obj-$(CONFIG_MACH_WG302V2)	+= wg302v2-setup.o + obj-$(CONFIG_MACH_FSG)		+= fsg-setup.o + obj-$(CONFIG_MACH_GORAMO_MLR)	+= goramo_mlr.o +--- /dev/null ++++ b/arch/arm/mach-ixp4xx/wg302v1-pci.c +@@ -0,0 +1,64 @@ ++/* ++ * arch/arch/mach-ixp4xx/wg302v1-pci.c ++ * ++ * PCI setup routines for the Netgear WG302 v1 and WAG302 v1 ++ * ++ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> ++ * ++ * based on coyote-pci.c: ++ *	Copyright (C) 2002 Jungo Software Technologies. ++ *	Copyright (C) 2003 MontaVista Software, 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 <mach/hardware.h> ++ ++#include <asm/mach/pci.h> ++ ++void __init wg302v1_pci_preinit(void) ++{ ++	set_irq_type(IRQ_IXP4XX_GPIO8, IRQ_TYPE_LEVEL_LOW); ++	set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW); ++ ++	ixp4xx_pci_preinit(); ++} ++ ++static int __init wg302v1_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++	if (slot == 1) ++		return IRQ_IXP4XX_GPIO8; ++	else if (slot == 2) ++		return IRQ_IXP4XX_GPIO10; ++	else ++		return -1; ++} ++ ++struct hw_pci wg302v1_pci __initdata = { ++	.nr_controllers = 1, ++	.preinit =        wg302v1_pci_preinit, ++	.swizzle =        pci_std_swizzle, ++	.setup =          ixp4xx_setup, ++	.scan =           ixp4xx_scan_bus, ++	.map_irq =        wg302v1_map_irq, ++}; ++ ++int __init wg302v1_pci_init(void) ++{ ++	if (machine_is_wg302v1()) ++		pci_common_init(&wg302v1_pci); ++	return 0; ++} ++ ++subsys_initcall(wg302v1_pci_init); +--- /dev/null ++++ b/arch/arm/mach-ixp4xx/wg302v1-setup.c +@@ -0,0 +1,142 @@ ++/* ++ * arch/arm/mach-ixp4xx/wg302v1-setup.c ++ * ++ * Board setup for the Netgear WG302 v1 and WAG302 v1 ++ * ++ * 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/serial.h> ++#include <linux/tty.h> ++#include <linux/serial_8250.h> ++#include <linux/slab.h> ++#include <linux/types.h> ++#include <linux/memory.h> ++ ++#include <asm/setup.h> ++#include <mach/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 wg302v1_flash_data = { ++	.map_name	= "cfi_probe", ++	.width		= 2, ++}; ++ ++static struct resource wg302v1_flash_resource = { ++	.flags		= IORESOURCE_MEM, ++}; ++ ++static struct platform_device wg302v1_flash = { ++	.name		= "IXP4XX-Flash", ++	.id		= 0, ++	.dev		= { ++		.platform_data = &wg302v1_flash_data, ++	}, ++	.num_resources	= 1, ++	.resource	= &wg302v1_flash_resource, ++}; ++ ++static struct resource wg302v1_uart_resources[] = { ++	{ ++		.start	= IXP4XX_UART1_BASE_PHYS, ++		.end	= IXP4XX_UART1_BASE_PHYS + 0x0fff, ++		.flags	= IORESOURCE_MEM, ++	}, ++	{ ++		.start	= IXP4XX_UART2_BASE_PHYS, ++		.end	= IXP4XX_UART2_BASE_PHYS + 0x0fff, ++		.flags	= IORESOURCE_MEM, ++	} ++}; ++ ++static struct plat_serial8250_port wg302v1_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, ++	}, ++	{ ++		.mapbase	= IXP4XX_UART2_BASE_PHYS, ++		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, ++		.irq		= IRQ_IXP4XX_UART2, ++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, ++		.iotype		= UPIO_MEM, ++		.regshift	= 2, ++		.uartclk	= IXP4XX_UART_XTAL, ++	}, ++	{ }, ++}; ++ ++static struct platform_device wg302v1_uart = { ++	.name		= "serial8250", ++	.id		= PLAT8250_DEV_PLATFORM, ++	.dev			= { ++		.platform_data	= wg302v1_uart_data, ++	}, ++	.num_resources	= 2, ++	.resource	= wg302v1_uart_resources, ++}; ++ ++static struct eth_plat_info wg302v1_plat_eth[] = { ++	{ ++		.phy		= 30, ++		.rxq		= 3, ++		.txreadyq	= 20, ++	} ++}; ++ ++static struct platform_device wg302v1_eth[] = { ++	{ ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEB, ++		.dev.platform_data	= wg302v1_plat_eth, ++	} ++}; ++ ++static struct platform_device *wg302v1_devices[] __initdata = { ++	&wg302v1_flash, ++	&wg302v1_uart, ++	&wg302v1_eth[0], ++}; ++ ++static void __init wg302v1_init(void) ++{ ++	ixp4xx_sys_init(); ++ ++	wg302v1_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); ++	wg302v1_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(wg302v1_devices, ARRAY_SIZE(wg302v1_devices)); ++} ++ ++#ifdef CONFIG_MACH_WG302V1 ++MACHINE_START(WG302V1, "Netgear WG302 v1 / WAG302 v1") ++	/* 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	= wg302v1_init, ++MACHINE_END ++#endif diff --git a/target/linux/ixp4xx/patches-2.6.31/110-pronghorn_series_support.patch b/target/linux/ixp4xx/patches-2.6.31/110-pronghorn_series_support.patch new file mode 100644 index 000000000..c03869226 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/110-pronghorn_series_support.patch @@ -0,0 +1,387 @@ +--- a/arch/arm/configs/ixp4xx_defconfig ++++ b/arch/arm/configs/ixp4xx_defconfig +@@ -157,6 +157,8 @@ CONFIG_ARCH_ADI_COYOTE=y + CONFIG_MACH_GATEWAY7001=y + CONFIG_MACH_WG302V1=y + CONFIG_MACH_WG302V2=y ++CONFIG_MACH_PRONGHORN=y ++CONFIG_MACH_PRONGHORNMETRO=y + CONFIG_ARCH_IXDP425=y + CONFIG_MACH_IXDPG425=y + CONFIG_MACH_IXDP465=y +--- a/arch/arm/mach-ixp4xx/Kconfig ++++ b/arch/arm/mach-ixp4xx/Kconfig +@@ -65,6 +65,22 @@ config MACH_WG302V2 + 	  WG302 v2 or WAG302 v2 Access Points. For more information + 	  on this platform, see http://openwrt.org +  ++config MACH_PRONGHORN ++	bool "ADI Pronghorn series" ++	select PCI ++	help ++	  Say 'Y' here if you want your kernel to support the ADI  ++	  Engineering Pronghorn series. For more ++	  information on this platform, see http://www.adiengineering.com ++ ++# ++# There're only minimal differences kernel-wise between the Pronghorn and ++# Pronghorn Metro boards - they use different chip selects to drive the ++# CF slot connected to the expansion bus, so we just enable them together. ++# ++config MACH_PRONGHORNMETRO ++	def_bool MACH_PRONGHORN ++ + config ARCH_IXDP425 + 	bool "IXDP425" + 	help +--- a/arch/arm/mach-ixp4xx/Makefile ++++ b/arch/arm/mach-ixp4xx/Makefile +@@ -17,6 +17,7 @@ obj-pci-$(CONFIG_MACH_GATEWAY7001)	+= ga + obj-pci-$(CONFIG_MACH_WG302V1)		+= wg302v1-pci.o + obj-pci-$(CONFIG_MACH_WG302V2)		+= wg302v2-pci.o + obj-pci-$(CONFIG_MACH_FSG)		+= fsg-pci.o ++obj-pci-$(CONFIG_MACH_PRONGHORN)	+= pronghorn-pci.o +  + obj-y	+= common.o +  +@@ -33,6 +34,7 @@ obj-$(CONFIG_MACH_WG302V1)	+= wg302v1-se + obj-$(CONFIG_MACH_WG302V2)	+= wg302v2-setup.o + obj-$(CONFIG_MACH_FSG)		+= fsg-setup.o + obj-$(CONFIG_MACH_GORAMO_MLR)	+= goramo_mlr.o ++obj-$(CONFIG_MACH_PRONGHORN)	+= pronghorn-setup.o +  + obj-$(CONFIG_PCI)		+= $(obj-pci-$(CONFIG_PCI)) common-pci.o + obj-$(CONFIG_IXP4XX_QMGR)	+= ixp4xx_qmgr.o +--- /dev/null ++++ b/arch/arm/mach-ixp4xx/pronghorn-pci.c +@@ -0,0 +1,70 @@ ++/* ++ * arch/arch/mach-ixp4xx/pronghorn-pci.c ++ * ++ * PCI setup routines for ADI Engineering Pronghorn 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 <mach/hardware.h> ++ ++#include <asm/mach/pci.h> ++ ++void __init pronghorn_pci_preinit(void) ++{ ++	set_irq_type(IRQ_IXP4XX_GPIO4, IRQ_TYPE_LEVEL_LOW); ++	set_irq_type(IRQ_IXP4XX_GPIO6, IRQ_TYPE_LEVEL_LOW); ++	set_irq_type(IRQ_IXP4XX_GPIO11, IRQ_TYPE_LEVEL_LOW); ++	set_irq_type(IRQ_IXP4XX_GPIO1, IRQ_TYPE_LEVEL_LOW); ++ ++	ixp4xx_pci_preinit(); ++} ++ ++static int __init pronghorn_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++	if (slot == 13) ++		return IRQ_IXP4XX_GPIO4; ++	else if (slot == 14) ++		return IRQ_IXP4XX_GPIO6; ++	else if (slot == 15) ++		return IRQ_IXP4XX_GPIO11; ++	else if (slot == 16) ++		return IRQ_IXP4XX_GPIO1; ++	else ++		return -1; ++} ++ ++struct hw_pci pronghorn_pci __initdata = { ++	.nr_controllers	= 1, ++	.preinit	= pronghorn_pci_preinit, ++	.swizzle	= pci_std_swizzle, ++	.setup		= ixp4xx_setup, ++	.scan		= ixp4xx_scan_bus, ++	.map_irq	= pronghorn_map_irq, ++}; ++ ++int __init pronghorn_pci_init(void) ++{ ++	if (machine_is_pronghorn() || machine_is_pronghorn_metro()) ++		pci_common_init(&pronghorn_pci); ++	return 0; ++} ++ ++subsys_initcall(pronghorn_pci_init); +--- /dev/null ++++ b/arch/arm/mach-ixp4xx/pronghorn-setup.c +@@ -0,0 +1,245 @@ ++/* ++ * arch/arm/mach-ixp4xx/pronghorn-setup.c ++ * ++ * Board setup for the ADI Engineering Pronghorn 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/serial.h> ++#include <linux/tty.h> ++#include <linux/serial_8250.h> ++#include <linux/slab.h> ++#include <linux/types.h> ++#include <linux/memory.h> ++#include <linux/i2c-gpio.h> ++#include <linux/leds.h> ++ ++#include <asm/setup.h> ++#include <mach/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 pronghorn_flash_data = { ++	.map_name	= "cfi_probe", ++	.width		= 2, ++}; ++ ++static struct resource pronghorn_flash_resource = { ++	.flags		= IORESOURCE_MEM, ++}; ++ ++static struct platform_device pronghorn_flash = { ++	.name		= "IXP4XX-Flash", ++	.id		= 0, ++	.dev		= { ++		.platform_data	= &pronghorn_flash_data, ++	}, ++	.num_resources	= 1, ++	.resource	= &pronghorn_flash_resource, ++}; ++ ++static struct resource pronghorn_uart_resources [] = { ++	{ ++		.start		= IXP4XX_UART1_BASE_PHYS, ++		.end		= IXP4XX_UART1_BASE_PHYS + 0x0fff, ++		.flags		= IORESOURCE_MEM ++	}, ++	{ ++		.start		= IXP4XX_UART2_BASE_PHYS, ++		.end		= IXP4XX_UART2_BASE_PHYS + 0x0fff, ++		.flags		= IORESOURCE_MEM ++	} ++}; ++ ++static struct plat_serial8250_port pronghorn_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, ++	}, ++	{ ++		.mapbase	= IXP4XX_UART2_BASE_PHYS, ++		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, ++		.irq		= IRQ_IXP4XX_UART2, ++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, ++		.iotype		= UPIO_MEM, ++		.regshift	= 2, ++		.uartclk	= IXP4XX_UART_XTAL, ++	}, ++	{ }, ++}; ++ ++static struct platform_device pronghorn_uart = { ++	.name		= "serial8250", ++	.id		= PLAT8250_DEV_PLATFORM, ++	.dev		= { ++		.platform_data	= pronghorn_uart_data, ++	}, ++	.num_resources	= 2, ++	.resource	= pronghorn_uart_resources, ++}; ++ ++static struct i2c_gpio_platform_data pronghorn_i2c_gpio_data = { ++	.sda_pin	= 9, ++	.scl_pin	= 10, ++}; ++ ++static struct platform_device pronghorn_i2c_gpio = { ++	.name		= "i2c-gpio", ++	.id		= 0, ++	.dev		= { ++		.platform_data	= &pronghorn_i2c_gpio_data, ++	}, ++}; ++ ++static struct gpio_led pronghorn_led_pin[] = { ++	{ ++		.name		= "pronghorn:green:status", ++		.gpio		= 7, ++	} ++}; ++ ++static struct gpio_led_platform_data pronghorn_led_data = { ++	.num_leds		= 1, ++	.leds			= pronghorn_led_pin, ++}; ++ ++static struct platform_device pronghorn_led = { ++	.name			= "leds-gpio", ++	.id			= -1, ++	.dev.platform_data	= &pronghorn_led_data, ++}; ++ ++static struct resource pronghorn_pata_resources[] = { ++	{ ++		.flags	= IORESOURCE_MEM ++	}, ++	{ ++		.flags	= IORESOURCE_MEM, ++	}, ++	{ ++		.name	= "intrq", ++		.start	= IRQ_IXP4XX_GPIO0, ++		.end	= IRQ_IXP4XX_GPIO0, ++		.flags	= IORESOURCE_IRQ, ++	}, ++}; ++ ++static struct ixp4xx_pata_data pronghorn_pata_data = { ++	.cs0_bits	= 0xbfff0043, ++	.cs1_bits	= 0xbfff0043, ++}; ++ ++static struct platform_device pronghorn_pata = { ++	.name			= "pata_ixp4xx_cf", ++	.id			= 0, ++	.dev.platform_data      = &pronghorn_pata_data, ++	.num_resources		= ARRAY_SIZE(pronghorn_pata_resources), ++	.resource		= pronghorn_pata_resources, ++}; ++ ++static struct eth_plat_info pronghorn_plat_eth[] = { ++	{ ++		.phy		= 0, ++		.rxq		= 3, ++		.txreadyq	= 20, ++	}, { ++		.phy		= 1, ++		.rxq		= 4, ++		.txreadyq	= 21, ++	} ++}; ++ ++static struct platform_device pronghorn_eth[] = { ++	{ ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEB, ++		.dev.platform_data	= pronghorn_plat_eth, ++	}, { ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEC, ++		.dev.platform_data	= pronghorn_plat_eth + 1, ++	} ++}; ++ ++static struct platform_device *pronghorn_devices[] __initdata = { ++	&pronghorn_flash, ++	&pronghorn_uart, ++	&pronghorn_led, ++	&pronghorn_eth[0], ++	&pronghorn_eth[1], ++}; ++ ++static void __init pronghorn_init(void) ++{ ++	ixp4xx_sys_init(); ++ ++	pronghorn_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); ++	pronghorn_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(pronghorn_devices, ARRAY_SIZE(pronghorn_devices)); ++ ++	if (machine_is_pronghorn()) { ++		pronghorn_pata_resources[0].start = IXP4XX_EXP_BUS_BASE(2); ++		pronghorn_pata_resources[0].end = IXP4XX_EXP_BUS_END(2); ++ ++		pronghorn_pata_resources[1].start = IXP4XX_EXP_BUS_BASE(3); ++		pronghorn_pata_resources[1].end = IXP4XX_EXP_BUS_END(3); ++ ++		pronghorn_pata_data.cs0_cfg = IXP4XX_EXP_CS2; ++		pronghorn_pata_data.cs1_cfg = IXP4XX_EXP_CS3; ++	} else { ++		pronghorn_pata_resources[0].start = IXP4XX_EXP_BUS_BASE(3); ++		pronghorn_pata_resources[0].end = IXP4XX_EXP_BUS_END(3); ++ ++		pronghorn_pata_resources[1].start = IXP4XX_EXP_BUS_BASE(4); ++		pronghorn_pata_resources[1].end = IXP4XX_EXP_BUS_END(4); ++ ++		pronghorn_pata_data.cs0_cfg = IXP4XX_EXP_CS3; ++		pronghorn_pata_data.cs1_cfg = IXP4XX_EXP_CS4; ++ ++		platform_device_register(&pronghorn_i2c_gpio); ++	} ++ ++	platform_device_register(&pronghorn_pata); ++} ++ ++MACHINE_START(PRONGHORN, "ADI Engineering Pronghorn") ++	/* 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	= pronghorn_init, ++MACHINE_END ++ ++MACHINE_START(PRONGHORNMETRO, "ADI Engineering Pronghorn Metro") ++	/* 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	= pronghorn_init, ++MACHINE_END +--- a/arch/arm/mach-ixp4xx/include/mach/uncompress.h ++++ b/arch/arm/mach-ixp4xx/include/mach/uncompress.h +@@ -41,7 +41,8 @@ static __inline__ void __arch_decomp_set + 	 * Some boards are using UART2 as console + 	 */ + 	if (machine_is_adi_coyote() || machine_is_gtwx5715() || +-			 machine_is_gateway7001() || machine_is_wg302v2()) ++			 machine_is_gateway7001() || machine_is_wg302v2() || ++			 machine_is_pronghorn() || machine_is_pronghorn_metro()) + 		uart_base = (volatile u32*) IXP4XX_UART2_BASE_PHYS; + 	else + 		uart_base = (volatile u32*) IXP4XX_UART1_BASE_PHYS; diff --git a/target/linux/ixp4xx/patches-2.6.31/111-pronghorn_swap_uarts.patch b/target/linux/ixp4xx/patches-2.6.31/111-pronghorn_swap_uarts.patch new file mode 100644 index 000000000..b9fa50768 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/111-pronghorn_swap_uarts.patch @@ -0,0 +1,44 @@ +--- a/arch/arm/mach-ixp4xx/pronghorn-setup.c ++++ b/arch/arm/mach-ixp4xx/pronghorn-setup.c +@@ -51,31 +51,31 @@ static struct platform_device pronghorn_ +  + static struct resource pronghorn_uart_resources [] = { + 	{ +-		.start		= IXP4XX_UART1_BASE_PHYS, +-		.end		= IXP4XX_UART1_BASE_PHYS + 0x0fff, ++		.start		= IXP4XX_UART2_BASE_PHYS, ++		.end		= IXP4XX_UART2_BASE_PHYS + 0x0fff, + 		.flags		= IORESOURCE_MEM + 	}, + 	{ +-		.start		= IXP4XX_UART2_BASE_PHYS, +-		.end		= IXP4XX_UART2_BASE_PHYS + 0x0fff, ++		.start		= IXP4XX_UART1_BASE_PHYS, ++		.end		= IXP4XX_UART1_BASE_PHYS + 0x0fff, + 		.flags		= IORESOURCE_MEM + 	} + }; +  + static struct plat_serial8250_port pronghorn_uart_data[] = { + 	{ +-		.mapbase	= IXP4XX_UART1_BASE_PHYS, +-		.membase	= (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET, +-		.irq		= IRQ_IXP4XX_UART1, ++		.mapbase	= IXP4XX_UART2_BASE_PHYS, ++		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, ++		.irq		= IRQ_IXP4XX_UART2, + 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + 		.iotype		= UPIO_MEM, + 		.regshift	= 2, + 		.uartclk	= IXP4XX_UART_XTAL, + 	}, + 	{ +-		.mapbase	= IXP4XX_UART2_BASE_PHYS, +-		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, +-		.irq		= IRQ_IXP4XX_UART2, ++		.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, diff --git a/target/linux/ixp4xx/patches-2.6.31/115-sidewinder_support.patch b/target/linux/ixp4xx/patches-2.6.31/115-sidewinder_support.patch new file mode 100644 index 000000000..bad0826c8 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/115-sidewinder_support.patch @@ -0,0 +1,282 @@ +From 60bdaaaf3446b4237566c6e04855186fc7bd766b Mon Sep 17 00:00:00 2001 +From: Imre Kaloz <kaloz@openwrt.org> +Date: Sun, 13 Jul 2008 22:46:45 +0200 +Subject: [PATCH] Add support for the ADI Sidewinder + +Signed-off-by: Imre Kaloz <kaloz@openwrt.org> +--- + arch/arm/mach-ixp4xx/Kconfig            |   10 ++- + arch/arm/mach-ixp4xx/Makefile           |    2 + + arch/arm/mach-ixp4xx/sidewinder-pci.c   |   68 ++++++++++++++ + arch/arm/mach-ixp4xx/sidewinder-setup.c |  151 +++++++++++++++++++++++++++++++ + 4 files changed, 230 insertions(+), 1 deletions(-) + create mode 100644 arch/arm/mach-ixp4xx/sidewinder-pci.c + create mode 100644 arch/arm/mach-ixp4xx/sidewinder-setup.c + +--- a/arch/arm/mach-ixp4xx/Kconfig ++++ b/arch/arm/mach-ixp4xx/Kconfig +@@ -81,6 +81,14 @@ config MACH_PRONGHORN + config MACH_PRONGHORNMETRO + 	def_bool MACH_PRONGHORN +  ++config MACH_SIDEWINDER ++	bool "ADI Sidewinder" ++	select PCI ++	help ++	  Say 'Y' here if you want your kernel to support the ADI  ++	  Engineering Sidewinder board. For more information on this ++	  platform, see http://www.adiengineering.com ++ + config ARCH_IXDP425 + 	bool "IXDP425" + 	help +@@ -169,7 +177,7 @@ config MACH_FSG + # + config CPU_IXP46X + 	bool +-	depends on MACH_IXDP465 ++	depends on MACH_IXDP465 || MACH_SIDEWINDER + 	default y +  + config CPU_IXP43X +--- a/arch/arm/mach-ixp4xx/Makefile ++++ b/arch/arm/mach-ixp4xx/Makefile +@@ -18,6 +18,7 @@ obj-pci-$(CONFIG_MACH_WG302V1)		+= wg302 + obj-pci-$(CONFIG_MACH_WG302V2)		+= wg302v2-pci.o + obj-pci-$(CONFIG_MACH_FSG)		+= fsg-pci.o + obj-pci-$(CONFIG_MACH_PRONGHORN)	+= pronghorn-pci.o ++obj-pci-$(CONFIG_MACH_SIDEWINDER)	+= sidewinder-pci.o +  + obj-y	+= common.o +  +@@ -35,6 +36,7 @@ obj-$(CONFIG_MACH_WG302V2)	+= wg302v2-se + obj-$(CONFIG_MACH_FSG)		+= fsg-setup.o + obj-$(CONFIG_MACH_GORAMO_MLR)	+= goramo_mlr.o + obj-$(CONFIG_MACH_PRONGHORN)	+= pronghorn-setup.o ++obj-$(CONFIG_MACH_SIDEWINDER)	+= sidewinder-setup.o +  + obj-$(CONFIG_PCI)		+= $(obj-pci-$(CONFIG_PCI)) common-pci.o + obj-$(CONFIG_IXP4XX_QMGR)	+= ixp4xx_qmgr.o +--- /dev/null ++++ b/arch/arm/mach-ixp4xx/sidewinder-pci.c +@@ -0,0 +1,68 @@ ++/* ++ * arch/arch/mach-ixp4xx/pronghornmetro-pci.c ++ * ++ * PCI setup routines for ADI Engineering Sidewinder ++ * ++ * 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 <mach/hardware.h> ++#include <asm/irq.h> ++ ++#include <asm/mach/pci.h> ++ ++void __init sidewinder_pci_preinit(void) ++{ ++	set_irq_type(IRQ_IXP4XX_GPIO11, IRQ_TYPE_LEVEL_LOW); ++	set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW); ++	set_irq_type(IRQ_IXP4XX_GPIO9, IRQ_TYPE_LEVEL_LOW); ++ ++	ixp4xx_pci_preinit(); ++} ++ ++static int __init sidewinder_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 ++		return -1; ++} ++ ++struct hw_pci sidewinder_pci __initdata = { ++	.nr_controllers	= 1, ++	.preinit	= sidewinder_pci_preinit, ++	.swizzle	= pci_std_swizzle, ++	.setup		= ixp4xx_setup, ++	.scan		= ixp4xx_scan_bus, ++	.map_irq	= sidewinder_map_irq, ++}; ++ ++int __init sidewinder_pci_init(void) ++{ ++	if (machine_is_sidewinder()) ++		pci_common_init(&sidewinder_pci); ++	return 0; ++} ++ ++subsys_initcall(sidewinder_pci_init); +--- /dev/null ++++ b/arch/arm/mach-ixp4xx/sidewinder-setup.c +@@ -0,0 +1,149 @@ ++/* ++ * arch/arm/mach-ixp4xx/sidewinder-setup.c ++ * ++ * Board setup for the ADI Engineering Sidewinder ++ * ++ * 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/serial.h> ++#include <linux/serial_8250.h> ++ ++#include <asm/mach-types.h> ++#include <asm/mach/arch.h> ++#include <asm/mach/flash.h> ++ ++static struct flash_platform_data sidewinder_flash_data = { ++	.map_name	= "cfi_probe", ++	.width		= 2, ++}; ++ ++static struct resource sidewinder_flash_resource = { ++	.flags		= IORESOURCE_MEM, ++}; ++ ++static struct platform_device sidewinder_flash = { ++	.name		= "IXP4XX-Flash", ++	.id		= 0, ++	.dev		= { ++		.platform_data = &sidewinder_flash_data, ++	}, ++	.num_resources	= 1, ++	.resource	= &sidewinder_flash_resource, ++}; ++ ++static struct resource sidewinder_uart_resources[] = { ++	{ ++		.start	= IXP4XX_UART1_BASE_PHYS, ++		.end	= IXP4XX_UART1_BASE_PHYS + 0x0fff, ++		.flags	= IORESOURCE_MEM, ++	}, ++	{ ++		.start	= IXP4XX_UART2_BASE_PHYS, ++		.end	= IXP4XX_UART2_BASE_PHYS + 0x0fff, ++		.flags	= IORESOURCE_MEM, ++	} ++}; ++ ++static struct plat_serial8250_port sidewinder_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, ++	}, ++	{ ++		.mapbase	= IXP4XX_UART2_BASE_PHYS, ++		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, ++		.irq		= IRQ_IXP4XX_UART2, ++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, ++		.iotype		= UPIO_MEM, ++		.regshift	= 2, ++		.uartclk	= IXP4XX_UART_XTAL, ++	}, ++	{ }, ++}; ++ ++static struct platform_device sidewinder_uart = { ++	.name		= "serial8250", ++	.id		= PLAT8250_DEV_PLATFORM, ++	.dev		= { ++		.platform_data	= sidewinder_uart_data, ++	}, ++	.num_resources	= ARRAY_SIZE(sidewinder_uart_resources), ++	.resource	= sidewinder_uart_resources, ++}; ++ ++static struct eth_plat_info sidewinder_plat_eth[] = { ++	{ ++		.phy		= 5, ++		.rxq		= 3, ++		.txreadyq	= 20, ++	}, { ++		.phy		= IXP4XX_ETH_PHY_MAX_ADDR, ++		.phy_mask	= 0x1e, ++		.rxq		= 4, ++		.txreadyq	= 21, ++	}, { ++		.phy		= 31, ++		.rxq		= 2, ++		.txreadyq	= 19, ++	} ++}; ++ ++static struct platform_device sidewinder_eth[] = { ++	{ ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEB, ++		.dev.platform_data	= sidewinder_plat_eth, ++	}, { ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEC, ++		.dev.platform_data	= sidewinder_plat_eth + 1, ++	}, { ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEA, ++		.dev.platform_data	= sidewinder_plat_eth + 2, ++	} ++}; ++ ++static struct platform_device *sidewinder_devices[] __initdata = { ++	&sidewinder_flash, ++	&sidewinder_uart, ++	&sidewinder_eth[0], ++	&sidewinder_eth[1], ++	&sidewinder_eth[2], ++}; ++ ++static void __init sidewinder_init(void) ++{ ++	ixp4xx_sys_init(); ++ ++	sidewinder_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); ++	sidewinder_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_64M - 1; ++ ++	*IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE; ++	*IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0; ++ ++	platform_add_devices(sidewinder_devices, ARRAY_SIZE(sidewinder_devices)); ++} ++ ++MACHINE_START(SIDEWINDER, "ADI Engineering Sidewinder") ++	/* 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	= sidewinder_init, ++MACHINE_END diff --git a/target/linux/ixp4xx/patches-2.6.31/116-sidewinder_fis_location.patch b/target/linux/ixp4xx/patches-2.6.31/116-sidewinder_fis_location.patch new file mode 100644 index 000000000..1d0a98398 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/116-sidewinder_fis_location.patch @@ -0,0 +1,30 @@ +--- a/drivers/mtd/redboot.c ++++ b/drivers/mtd/redboot.c +@@ -13,6 +13,8 @@ +  + #define BOARD_CONFIG_PART		"boardconfig" +  ++#include <asm/mach-types.h> ++ + struct fis_image_desc { +     unsigned char name[16];      // Null terminated name +     uint32_t	  flash_base;    // Address within FLASH of image +@@ -30,7 +32,8 @@ struct fis_list { + 	struct fis_list *next; + }; +  +-static int directory = CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK; ++int directory = CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK; ++ + module_param(directory, int, 0); +  + static inline int redboot_checksum(struct fis_image_desc *img) +@@ -59,6 +62,8 @@ static int parse_redboot_partitions(stru + #ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED + 	static char nullstring[] = "unallocated"; + #endif ++	if (machine_is_sidewinder()) ++		directory = -5; +  + 	if ( directory < 0 ) { + 		offset = master->size + directory * master->erasesize; diff --git a/target/linux/ixp4xx/patches-2.6.31/120-compex_support.patch b/target/linux/ixp4xx/patches-2.6.31/120-compex_support.patch new file mode 100644 index 000000000..ccac8cc78 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/120-compex_support.patch @@ -0,0 +1,212 @@ +From 24025a2dcf1248079dd3019fac6ed955252d277f Mon Sep 17 00:00:00 2001 +From: Imre Kaloz <kaloz@openwrt.org> +Date: Mon, 14 Jul 2008 21:56:34 +0200 +Subject: [PATCH] Add support for the Compex WP18 / NP18A boards + +Signed-off-by: Imre Kaloz <kaloz@openwrt.org> +--- + arch/arm/mach-ixp4xx/Kconfig        |    8 ++ + arch/arm/mach-ixp4xx/Makefile       |    2 + + arch/arm/mach-ixp4xx/compex-setup.c |  136 +++++++++++++++++++++++++++++++++++ + arch/arm/mach-ixp4xx/ixdp425-pci.c  |    3 +- + arch/arm/tools/mach-types           |    2 +- + 5 files changed, 149 insertions(+), 2 deletions(-) + create mode 100644 arch/arm/mach-ixp4xx/compex-setup.c + +--- a/arch/arm/mach-ixp4xx/Kconfig ++++ b/arch/arm/mach-ixp4xx/Kconfig +@@ -89,6 +89,14 @@ config MACH_SIDEWINDER + 	  Engineering Sidewinder board. For more information on this + 	  platform, see http://www.adiengineering.com +  ++config MACH_COMPEX ++	bool "Compex WP18 / NP18A" ++	select PCI ++	help ++	  Say 'Y' here if you want your kernel to support Compex'  ++	  WP18 or NP18A boards. For more information on this ++	  platform, see http://www.compex.com.sg/home/OEM/product_ap.htm ++ + config ARCH_IXDP425 + 	bool "IXDP425" + 	help +--- a/arch/arm/mach-ixp4xx/Makefile ++++ b/arch/arm/mach-ixp4xx/Makefile +@@ -19,6 +19,7 @@ obj-pci-$(CONFIG_MACH_WG302V2)		+= wg302 + obj-pci-$(CONFIG_MACH_FSG)		+= fsg-pci.o + obj-pci-$(CONFIG_MACH_PRONGHORN)	+= pronghorn-pci.o + obj-pci-$(CONFIG_MACH_SIDEWINDER)	+= sidewinder-pci.o ++obj-pci-$(CONFIG_MACH_COMPEX)		+= ixdp425-pci.o +  + obj-y	+= common.o +  +@@ -37,6 +38,7 @@ obj-$(CONFIG_MACH_FSG)		+= fsg-setup.o + obj-$(CONFIG_MACH_GORAMO_MLR)	+= goramo_mlr.o + obj-$(CONFIG_MACH_PRONGHORN)	+= pronghorn-setup.o + obj-$(CONFIG_MACH_SIDEWINDER)	+= sidewinder-setup.o ++obj-$(CONFIG_MACH_COMPEX)	+= compex-setup.o +  + obj-$(CONFIG_PCI)		+= $(obj-pci-$(CONFIG_PCI)) common-pci.o + obj-$(CONFIG_IXP4XX_QMGR)	+= ixp4xx_qmgr.o +--- /dev/null ++++ b/arch/arm/mach-ixp4xx/compex-setup.c +@@ -0,0 +1,136 @@ ++/* ++ * arch/arm/mach-ixp4xx/compex-setup.c ++ * ++ * Compex WP18 / NP18A board-setup ++ * ++ * 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/serial.h> ++#include <linux/serial_8250.h> ++ ++#include <asm/mach-types.h> ++#include <asm/mach/arch.h> ++#include <asm/mach/flash.h> ++ ++static struct flash_platform_data compex_flash_data = { ++	.map_name	= "cfi_probe", ++	.width		= 2, ++}; ++ ++static struct resource compex_flash_resource = { ++	.flags		= IORESOURCE_MEM, ++}; ++ ++static struct platform_device compex_flash = { ++	.name		= "IXP4XX-Flash", ++	.id		= 0, ++	.dev		= { ++		.platform_data = &compex_flash_data, ++	}, ++	.num_resources	= 1, ++	.resource	= &compex_flash_resource, ++}; ++ ++static struct resource compex_uart_resources[] = { ++	{ ++		.start		= IXP4XX_UART1_BASE_PHYS, ++		.end		= IXP4XX_UART1_BASE_PHYS + 0x0fff, ++		.flags		= IORESOURCE_MEM ++	}, ++	{ ++		.start		= IXP4XX_UART2_BASE_PHYS, ++		.end		= IXP4XX_UART2_BASE_PHYS + 0x0fff, ++		.flags		= IORESOURCE_MEM ++	} ++}; ++ ++static struct plat_serial8250_port compex_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, ++	}, ++	{ ++		.mapbase	= IXP4XX_UART2_BASE_PHYS, ++		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, ++		.irq		= IRQ_IXP4XX_UART2, ++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, ++		.iotype		= UPIO_MEM, ++		.regshift	= 2, ++		.uartclk	= IXP4XX_UART_XTAL, ++	}, ++	{ }, ++}; ++ ++static struct platform_device compex_uart = { ++	.name			= "serial8250", ++	.id			= PLAT8250_DEV_PLATFORM, ++	.dev.platform_data	= compex_uart_data, ++	.num_resources		= 2, ++	.resource		= compex_uart_resources, ++}; ++ ++static struct eth_plat_info compex_plat_eth[] = { ++	{ ++		.phy		= IXP4XX_ETH_PHY_MAX_ADDR, ++		.phy_mask	= 0xf0000, ++		.rxq		= 3, ++		.txreadyq	= 20, ++	}, { ++		.phy		= 3, ++		.rxq		= 4, ++		.txreadyq	= 21, ++	} ++}; ++ ++static struct platform_device compex_eth[] = { ++	{ ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEB, ++		.dev.platform_data	= compex_plat_eth, ++	}, { ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEC, ++		.dev.platform_data	= compex_plat_eth + 1, ++	} ++}; ++ ++static struct platform_device *compex_devices[] __initdata = { ++	&compex_flash, ++	&compex_uart, ++	&compex_eth[0], ++	&compex_eth[1], ++}; ++ ++static void __init compex_init(void) ++{ ++	ixp4xx_sys_init(); ++ ++	compex_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); ++	compex_flash_resource.end = ++		IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1; ++ ++	platform_add_devices(compex_devices, ARRAY_SIZE(compex_devices)); ++} ++ ++MACHINE_START(COMPEX, "Compex WP18 / NP18A") ++	/* 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	= compex_init, ++MACHINE_END +--- a/arch/arm/mach-ixp4xx/ixdp425-pci.c ++++ b/arch/arm/mach-ixp4xx/ixdp425-pci.c +@@ -66,7 +66,8 @@ struct hw_pci ixdp425_pci __initdata = { + int __init ixdp425_pci_init(void) + { + 	if (machine_is_ixdp425() || machine_is_ixcdp1100() || +-			machine_is_ixdp465() || machine_is_kixrp435()) ++			machine_is_ixdp465() || machine_is_kixrp435() || ++			machine_is_compex()) + 		pci_common_init(&ixdp425_pci); + 	return 0; + } +--- a/arch/arm/tools/mach-types ++++ b/arch/arm/tools/mach-types +@@ -1273,7 +1273,7 @@ oiab			MACH_OIAB		OIAB			1269 + smdk6400		MACH_SMDK6400		SMDK6400		1270 + nokia_n800		MACH_NOKIA_N800		NOKIA_N800		1271 + greenphone		MACH_GREENPHONE		GREENPHONE		1272 +-compex42x		MACH_COMPEXWP18		COMPEXWP18		1273 ++compex			MACH_COMPEX		COMPEX			1273 + xmate			MACH_XMATE		XMATE			1274 + energizer		MACH_ENERGIZER		ENERGIZER		1275 + ime1			MACH_IME1		IME1			1276 diff --git a/target/linux/ixp4xx/patches-2.6.31/130-wrt300nv2_support.patch b/target/linux/ixp4xx/patches-2.6.31/130-wrt300nv2_support.patch new file mode 100644 index 000000000..c184a6c6c --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/130-wrt300nv2_support.patch @@ -0,0 +1,225 @@ +--- a/arch/arm/mach-ixp4xx/Kconfig ++++ b/arch/arm/mach-ixp4xx/Kconfig +@@ -97,6 +97,14 @@ config MACH_COMPEX + 	  WP18 or NP18A boards. For more information on this + 	  platform, see http://www.compex.com.sg/home/OEM/product_ap.htm +  ++config MACH_WRT300NV2 ++	bool "Linksys WRT300N v2" ++	select PCI ++	help ++	  Say 'Y' here if you want your kernel to support Linksys'  ++	  WRT300N v2 router. For more information on this ++	  platform, see http://openwrt.org ++ + config ARCH_IXDP425 + 	bool "IXDP425" + 	help +--- a/arch/arm/mach-ixp4xx/Makefile ++++ b/arch/arm/mach-ixp4xx/Makefile +@@ -20,6 +20,7 @@ obj-pci-$(CONFIG_MACH_FSG)		+= fsg-pci.o + obj-pci-$(CONFIG_MACH_PRONGHORN)	+= pronghorn-pci.o + obj-pci-$(CONFIG_MACH_SIDEWINDER)	+= sidewinder-pci.o + obj-pci-$(CONFIG_MACH_COMPEX)		+= ixdp425-pci.o ++obj-pci-$(CONFIG_MACH_WRT300NV2)		+= wrt300nv2-pci.o +  + obj-y	+= common.o +  +@@ -39,6 +40,7 @@ obj-$(CONFIG_MACH_GORAMO_MLR)	+= goramo_ + obj-$(CONFIG_MACH_PRONGHORN)	+= pronghorn-setup.o + obj-$(CONFIG_MACH_SIDEWINDER)	+= sidewinder-setup.o + obj-$(CONFIG_MACH_COMPEX)	+= compex-setup.o ++obj-$(CONFIG_MACH_WRT300NV2)	+= wrt300nv2-setup.o +  + obj-$(CONFIG_PCI)		+= $(obj-pci-$(CONFIG_PCI)) common-pci.o + obj-$(CONFIG_IXP4XX_QMGR)	+= ixp4xx_qmgr.o +--- /dev/null ++++ b/arch/arm/mach-ixp4xx/wrt300nv2-pci.c +@@ -0,0 +1,65 @@ ++/* ++ * arch/arch/mach-ixp4xx/wrt300nv2-pci.c ++ * ++ * PCI setup routines for Linksys WRT300N v2 ++ * ++ * Copyright (C) 2007 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 <mach/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 wrt300nv2_pci_preinit(void) ++{ ++	set_irq_type(IRQ_IXP4XX_GPIO8, IRQ_TYPE_LEVEL_LOW); ++ ++	ixp4xx_pci_preinit(); ++} ++ ++static int __init wrt300nv2_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++	if (slot == 1) ++		return IRQ_IXP4XX_GPIO8; ++	else return -1; ++} ++ ++struct hw_pci wrt300nv2_pci __initdata = { ++	.nr_controllers = 1, ++	.preinit =        wrt300nv2_pci_preinit, ++	.swizzle =        pci_std_swizzle, ++	.setup =          ixp4xx_setup, ++	.scan =           ixp4xx_scan_bus, ++	.map_irq =        wrt300nv2_map_irq, ++}; ++ ++int __init wrt300nv2_pci_init(void) ++{ ++	if (machine_is_wrt300nv2()) ++		pci_common_init(&wrt300nv2_pci); ++	return 0; ++} ++ ++subsys_initcall(wrt300nv2_pci_init); +--- /dev/null ++++ b/arch/arm/mach-ixp4xx/wrt300nv2-setup.c +@@ -0,0 +1,108 @@ ++/* ++ * arch/arm/mach-ixp4xx/wrt300nv2-setup.c ++ * ++ * Board setup for the Linksys WRT300N v2 ++ * ++ * Copyright (C) 2007 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/serial.h> ++#include <linux/tty.h> ++#include <linux/serial_8250.h> ++#include <linux/slab.h> ++ ++#include <asm/types.h> ++#include <asm/setup.h> ++#include <asm/memory.h> ++#include <mach/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 wrt300nv2_flash_data = { ++	.map_name	= "cfi_probe", ++	.width		= 2, ++}; ++ ++static struct resource wrt300nv2_flash_resource = { ++	.flags		= IORESOURCE_MEM, ++}; ++ ++static struct platform_device wrt300nv2_flash = { ++	.name		= "IXP4XX-Flash", ++	.id		= 0, ++	.dev		= { ++		.platform_data = &wrt300nv2_flash_data, ++	}, ++	.num_resources	= 1, ++	.resource	= &wrt300nv2_flash_resource, ++}; ++ ++static struct resource wrt300nv2_uart_resource = { ++	.start	= IXP4XX_UART2_BASE_PHYS, ++	.end	= IXP4XX_UART2_BASE_PHYS + 0x0fff, ++	.flags	= IORESOURCE_MEM, ++}; ++ ++static struct plat_serial8250_port wrt300nv2_uart_data[] = { ++	{ ++		.mapbase	= IXP4XX_UART2_BASE_PHYS, ++		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, ++		.irq		= IRQ_IXP4XX_UART2, ++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, ++		.iotype		= UPIO_MEM, ++		.regshift	= 2, ++		.uartclk	= IXP4XX_UART_XTAL, ++	}, ++	{ }, ++}; ++ ++static struct platform_device wrt300nv2_uart = { ++	.name		= "serial8250", ++	.id		= PLAT8250_DEV_PLATFORM, ++	.dev			= { ++		.platform_data	= wrt300nv2_uart_data, ++	}, ++	.num_resources	= 1, ++	.resource	= &wrt300nv2_uart_resource, ++}; ++ ++static struct platform_device *wrt300nv2_devices[] __initdata = { ++	&wrt300nv2_flash, ++	&wrt300nv2_uart ++}; ++ ++static void __init wrt300nv2_init(void) ++{ ++	ixp4xx_sys_init(); ++ ++	wrt300nv2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); ++	wrt300nv2_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(wrt300nv2_devices, ARRAY_SIZE(wrt300nv2_devices)); ++} ++ ++#ifdef CONFIG_MACH_WRT300NV2 ++MACHINE_START(WRT300NV2, "Linksys WRT300N v2") ++	/* 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	= wrt300nv2_init, ++MACHINE_END ++#endif +--- a/arch/arm/mach-ixp4xx/include/mach/uncompress.h ++++ b/arch/arm/mach-ixp4xx/include/mach/uncompress.h +@@ -42,7 +42,7 @@ static __inline__ void __arch_decomp_set + 	 */ + 	if (machine_is_adi_coyote() || machine_is_gtwx5715() || + 			 machine_is_gateway7001() || machine_is_wg302v2() || +-			 machine_is_pronghorn() || machine_is_pronghorn_metro()) ++			 machine_is_pronghorn() || machine_is_pronghorn_metro() || machine_is_wrt300nv2()) + 		uart_base = (volatile u32*) IXP4XX_UART2_BASE_PHYS; + 	else + 		uart_base = (volatile u32*) IXP4XX_UART1_BASE_PHYS; diff --git a/target/linux/ixp4xx/patches-2.6.31/131-wrt300nv2_mac_plat_info.patch b/target/linux/ixp4xx/patches-2.6.31/131-wrt300nv2_mac_plat_info.patch new file mode 100644 index 000000000..3ab68c4f3 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/131-wrt300nv2_mac_plat_info.patch @@ -0,0 +1,40 @@ +--- a/arch/arm/mach-ixp4xx/wrt300nv2-setup.c ++++ b/arch/arm/mach-ixp4xx/wrt300nv2-setup.c +@@ -76,9 +76,36 @@ static struct platform_device wrt300nv2_ + 	.resource	= &wrt300nv2_uart_resource, + }; +  ++/* Built-in 10/100 Ethernet MAC interfaces */ ++static struct eth_plat_info wrt300nv2_plat_eth[] = { ++	{ ++		.phy		= -1, ++		.rxq		= 3, ++		.txreadyq	= 20, ++	}, { ++		.phy		= 1, ++		.rxq		= 4, ++		.txreadyq	= 21, ++	} ++}; ++ ++static struct platform_device wrt300nv2_eth[] = { ++	{ ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEB, ++		.dev.platform_data	= wrt300nv2_plat_eth, ++	}, { ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEC, ++		.dev.platform_data	= wrt300nv2_plat_eth + 1, ++	} ++}; ++ + static struct platform_device *wrt300nv2_devices[] __initdata = { + 	&wrt300nv2_flash, +-	&wrt300nv2_uart ++	&wrt300nv2_uart, ++	&wrt300nv2_eth[0], ++	&wrt300nv2_eth[1], + }; +  + static void __init wrt300nv2_init(void) diff --git a/target/linux/ixp4xx/patches-2.6.31/150-lanready_ap1000_support.patch b/target/linux/ixp4xx/patches-2.6.31/150-lanready_ap1000_support.patch new file mode 100644 index 000000000..378786e27 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/150-lanready_ap1000_support.patch @@ -0,0 +1,200 @@ +--- /dev/null ++++ b/arch/arm/mach-ixp4xx/ap1000-setup.c +@@ -0,0 +1,151 @@ ++/* ++ * arch/arm/mach-ixp4xx/ap1000-setup.c ++ * ++ * Lanready AP-1000 ++ * ++ * Copyright (C) 2007 Imre Kaloz <Kaloz@openwrt.org> ++ * ++ * based on ixdp425-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/serial.h> ++#include <linux/tty.h> ++#include <linux/serial_8250.h> ++#include <linux/slab.h> ++ ++#include <asm/types.h> ++#include <asm/setup.h> ++#include <asm/memory.h> ++#include <mach/hardware.h> ++#include <asm/mach-types.h> ++#include <asm/irq.h> ++#include <asm/mach/arch.h> ++#include <asm/mach/flash.h> ++ ++static struct flash_platform_data ap1000_flash_data = { ++	.map_name	= "cfi_probe", ++	.width		= 2, ++}; ++ ++static struct resource ap1000_flash_resource = { ++	.flags		= IORESOURCE_MEM, ++}; ++ ++static struct platform_device ap1000_flash = { ++	.name		= "IXP4XX-Flash", ++	.id		= 0, ++	.dev		= { ++		.platform_data = &ap1000_flash_data, ++	}, ++	.num_resources	= 1, ++	.resource	= &ap1000_flash_resource, ++}; ++ ++static struct resource ap1000_uart_resources[] = { ++	{ ++		.start		= IXP4XX_UART1_BASE_PHYS, ++		.end		= IXP4XX_UART1_BASE_PHYS + 0x0fff, ++		.flags		= IORESOURCE_MEM ++	}, ++	{ ++		.start		= IXP4XX_UART2_BASE_PHYS, ++		.end		= IXP4XX_UART2_BASE_PHYS + 0x0fff, ++		.flags		= IORESOURCE_MEM ++	} ++}; ++ ++static struct plat_serial8250_port ap1000_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, ++	}, ++	{ ++		.mapbase	= IXP4XX_UART2_BASE_PHYS, ++		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, ++		.irq		= IRQ_IXP4XX_UART2, ++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, ++		.iotype		= UPIO_MEM, ++		.regshift	= 2, ++		.uartclk	= IXP4XX_UART_XTAL, ++	}, ++	{ }, ++}; ++ ++static struct platform_device ap1000_uart = { ++	.name			= "serial8250", ++	.id			= PLAT8250_DEV_PLATFORM, ++	.dev.platform_data	= ap1000_uart_data, ++	.num_resources		= 2, ++	.resource		= ap1000_uart_resources ++}; ++ ++static struct platform_device *ap1000_devices[] __initdata = { ++	&ap1000_flash, ++	&ap1000_uart ++}; ++ ++static char ap1000_mem_fixup[] __initdata = "mem=64M "; ++ ++static void __init ap1000_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(ap1000_mem_fixup) + strlen(p) + 1 + 4) >> 2; ++	strlcpy(t->u.cmdline.cmdline, ap1000_mem_fixup, COMMAND_LINE_SIZE); ++	strlcpy(t->u.cmdline.cmdline + strlen(ap1000_mem_fixup), p, ++		COMMAND_LINE_SIZE - strlen(ap1000_mem_fixup)); ++ ++	/* Terminate the table. */ ++	t = tag_next(t); ++	t->hdr.tag = ATAG_NONE; ++	t->hdr.size = 0; ++} ++ ++static void __init ap1000_init(void) ++{ ++	ixp4xx_sys_init(); ++ ++	ap1000_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); ++	ap1000_flash_resource.end = ++		IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; ++ ++	platform_add_devices(ap1000_devices, ARRAY_SIZE(ap1000_devices)); ++} ++ ++#ifdef CONFIG_MACH_AP1000 ++MACHINE_START(AP1000, "Lanready AP-1000") ++	/* Maintainer: Imre Kaloz <Kaloz@openwrt.org> */ ++	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS, ++	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, ++	.fixup		= ap1000_fixup, ++	.map_io		= ixp4xx_map_io, ++	.init_irq	= ixp4xx_init_irq, ++	.timer		= &ixp4xx_timer, ++	.boot_params	= 0x0100, ++	.init_machine	= ap1000_init, ++MACHINE_END ++#endif +--- a/arch/arm/mach-ixp4xx/ixdp425-pci.c ++++ b/arch/arm/mach-ixp4xx/ixdp425-pci.c +@@ -67,7 +67,7 @@ int __init ixdp425_pci_init(void) + { + 	if (machine_is_ixdp425() || machine_is_ixcdp1100() || + 			machine_is_ixdp465() || machine_is_kixrp435() || +-			machine_is_compex()) ++			machine_is_compex() || machine_is_ap1000()) + 		pci_common_init(&ixdp425_pci); + 	return 0; + } +--- a/arch/arm/mach-ixp4xx/Kconfig ++++ b/arch/arm/mach-ixp4xx/Kconfig +@@ -105,6 +105,14 @@ config MACH_WRT300NV2 + 	  WRT300N v2 router. For more information on this + 	  platform, see http://openwrt.org +  ++config MACH_AP1000 ++	bool "Lanready AP-1000" ++	select PCI ++	help ++	  Say 'Y' here if you want your kernel to support Lanready's ++	  AP1000 board. For more information on this ++	  platform, see http://openwrt.org ++ + config ARCH_IXDP425 + 	bool "IXDP425" + 	help +--- a/arch/arm/mach-ixp4xx/Makefile ++++ b/arch/arm/mach-ixp4xx/Makefile +@@ -21,6 +21,7 @@ obj-pci-$(CONFIG_MACH_PRONGHORN)	+= pron + obj-pci-$(CONFIG_MACH_SIDEWINDER)	+= sidewinder-pci.o + obj-pci-$(CONFIG_MACH_COMPEX)		+= ixdp425-pci.o + obj-pci-$(CONFIG_MACH_WRT300NV2)		+= wrt300nv2-pci.o ++obj-pci-$(CONFIG_MACH_AP1000)		+= ixdp425-pci.o +  + obj-y	+= common.o +  +@@ -41,6 +42,7 @@ obj-$(CONFIG_MACH_PRONGHORN)	+= pronghor + obj-$(CONFIG_MACH_SIDEWINDER)	+= sidewinder-setup.o + obj-$(CONFIG_MACH_COMPEX)	+= compex-setup.o + obj-$(CONFIG_MACH_WRT300NV2)	+= wrt300nv2-setup.o ++obj-$(CONFIG_MACH_AP1000)	+= ap1000-setup.o +  + obj-$(CONFIG_PCI)		+= $(obj-pci-$(CONFIG_PCI)) common-pci.o + obj-$(CONFIG_IXP4XX_QMGR)	+= ixp4xx_qmgr.o diff --git a/target/linux/ixp4xx/patches-2.6.31/151-lanready_ap1000_mac_plat_info.patch b/target/linux/ixp4xx/patches-2.6.31/151-lanready_ap1000_mac_plat_info.patch new file mode 100644 index 000000000..a1214d567 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/151-lanready_ap1000_mac_plat_info.patch @@ -0,0 +1,41 @@ +--- a/arch/arm/mach-ixp4xx/ap1000-setup.c ++++ b/arch/arm/mach-ixp4xx/ap1000-setup.c +@@ -90,9 +90,37 @@ static struct platform_device ap1000_uar + 	.resource		= ap1000_uart_resources + }; +  ++/* Built-in 10/100 Ethernet MAC interfaces */ ++static struct eth_plat_info ap1000_plat_eth[] = { ++	{ ++		.phy		= IXP4XX_ETH_PHY_MAX_ADDR, ++		.phy_mask	= 0x1e, ++		.rxq		= 3, ++		.txreadyq	= 20, ++	}, { ++		.phy		= 5, ++		.rxq		= 4, ++		.txreadyq	= 21, ++	} ++}; ++ ++static struct platform_device ap1000_eth[] = { ++	{ ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEB, ++		.dev.platform_data	= ap1000_plat_eth, ++	}, { ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEC, ++		.dev.platform_data	= ap1000_plat_eth + 1, ++	} ++}; ++ + static struct platform_device *ap1000_devices[] __initdata = { + 	&ap1000_flash, +-	&ap1000_uart ++	&ap1000_uart, ++	&ap1000_eth[0], ++	&ap1000_eth[1], + }; +  + static char ap1000_mem_fixup[] __initdata = "mem=64M "; diff --git a/target/linux/ixp4xx/patches-2.6.31/162-wg302v1_mem_fixup.patch b/target/linux/ixp4xx/patches-2.6.31/162-wg302v1_mem_fixup.patch new file mode 100644 index 000000000..684db4475 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/162-wg302v1_mem_fixup.patch @@ -0,0 +1,47 @@ +--- a/arch/arm/mach-ixp4xx/wg302v1-setup.c ++++ b/arch/arm/mach-ixp4xx/wg302v1-setup.c +@@ -115,6 +115,36 @@ static struct platform_device *wg302v1_d + 	&wg302v1_eth[0], + }; +  ++static char wg302v1_mem_fixup[] __initdata = "mem=32M "; ++ ++static void __init wg302v1_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(wg302v1_mem_fixup) + strlen(p) + 1 + 4) >> 2; ++	strlcpy(t->u.cmdline.cmdline, wg302v1_mem_fixup, COMMAND_LINE_SIZE); ++	strlcpy(t->u.cmdline.cmdline + strlen(wg302v1_mem_fixup), p, ++		COMMAND_LINE_SIZE - strlen(wg302v1_mem_fixup)); ++ ++	/* Terminate the table. */ ++	t = tag_next(t); ++	t->hdr.tag = ATAG_NONE; ++	t->hdr.size = 0; ++} ++ + static void __init wg302v1_init(void) + { + 	ixp4xx_sys_init(); +@@ -133,6 +163,7 @@ MACHINE_START(WG302V1, "Netgear WG302 v1 + 	/* Maintainer: Imre Kaloz <kaloz@openwrt.org> */ + 	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS, + 	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, ++	.fixup		= wg302v1_fixup, + 	.map_io		= ixp4xx_map_io, + 	.init_irq	= ixp4xx_init_irq, + 	.timer		= &ixp4xx_timer, diff --git a/target/linux/ixp4xx/patches-2.6.31/170-ixdpg425_mac_plat_info.patch b/target/linux/ixp4xx/patches-2.6.31/170-ixdpg425_mac_plat_info.patch new file mode 100644 index 000000000..772b697aa --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/170-ixdpg425_mac_plat_info.patch @@ -0,0 +1,41 @@ +--- a/arch/arm/mach-ixp4xx/coyote-setup.c ++++ b/arch/arm/mach-ixp4xx/coyote-setup.c +@@ -73,9 +73,37 @@ static struct platform_device coyote_uar + 	.resource	= &coyote_uart_resource, + }; +  ++/* Built-in 10/100 Ethernet MAC interfaces */ ++static struct eth_plat_info ixdpg425_plat_eth[] = { ++        { ++                .phy            = 5, ++                .rxq            = 3, ++                .txreadyq       = 20, ++        }, { ++                .phy            = 4, ++                .rxq            = 4, ++                .txreadyq       = 21, ++        } ++}; ++ ++static struct platform_device ixdpg425_eth[] = { ++	{ ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEB, ++		.dev.platform_data	= ixdpg425_plat_eth, ++	}, { ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEC, ++		.dev.platform_data	= ixdpg425_plat_eth + 1, ++	} ++}; ++ ++ + static struct platform_device *coyote_devices[] __initdata = { + 	&coyote_flash, +-	&coyote_uart ++	&coyote_uart, ++	&ixdpg425_eth[0], ++	&ixdpg425_eth[1], + }; +  + static void __init coyote_init(void) diff --git a/target/linux/ixp4xx/patches-2.6.31/180-tw5334_support.patch b/target/linux/ixp4xx/patches-2.6.31/180-tw5334_support.patch new file mode 100644 index 000000000..f59792a53 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/180-tw5334_support.patch @@ -0,0 +1,284 @@ +--- a/arch/arm/mach-ixp4xx/Kconfig ++++ b/arch/arm/mach-ixp4xx/Kconfig +@@ -164,6 +164,14 @@ config ARCH_PRPMC1100 + 	  PrPCM1100 Processor Mezanine Module. For more information on + 	  this platform, see <file:Documentation/arm/IXP4xx>. +  ++config MACH_TW5334 ++	bool "Titan Wireless TW-533-4" ++	select PCI ++	help ++	  Say 'Y' here if you want your kernel to support the Titan ++	  Wireless TW533-4. For more information on this platform, ++	  see http://openwrt.org ++ + config MACH_NAS100D + 	bool + 	prompt "NAS100D" +--- a/arch/arm/mach-ixp4xx/Makefile ++++ b/arch/arm/mach-ixp4xx/Makefile +@@ -22,6 +22,7 @@ obj-pci-$(CONFIG_MACH_SIDEWINDER)	+= sid + obj-pci-$(CONFIG_MACH_COMPEX)		+= ixdp425-pci.o + obj-pci-$(CONFIG_MACH_WRT300NV2)		+= wrt300nv2-pci.o + obj-pci-$(CONFIG_MACH_AP1000)		+= ixdp425-pci.o ++obj-pci-$(CONFIG_MACH_TW5334)		+= tw5334-pci.o +  + obj-y	+= common.o +  +@@ -43,6 +44,7 @@ obj-$(CONFIG_MACH_SIDEWINDER)	+= sidewin + obj-$(CONFIG_MACH_COMPEX)	+= compex-setup.o + obj-$(CONFIG_MACH_WRT300NV2)	+= wrt300nv2-setup.o + obj-$(CONFIG_MACH_AP1000)	+= ap1000-setup.o ++obj-$(CONFIG_MACH_TW5334)	+= tw5334-setup.o +  + obj-$(CONFIG_PCI)		+= $(obj-pci-$(CONFIG_PCI)) common-pci.o + obj-$(CONFIG_IXP4XX_QMGR)	+= ixp4xx_qmgr.o +--- /dev/null ++++ b/arch/arm/mach-ixp4xx/tw5334-setup.c +@@ -0,0 +1,162 @@ ++/* ++ * arch/arm/mach-ixp4xx/tw5334-setup.c ++ * ++ * Board setup for the Titan Wireless TW-533-4 ++ * ++ * 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/if_ether.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/device.h> ++#include <linux/serial.h> ++#include <linux/tty.h> ++#include <linux/serial_8250.h> ++#include <linux/slab.h> ++ ++#include <asm/types.h> ++#include <asm/setup.h> ++#include <asm/memory.h> ++#include <mach/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 tw5334_flash_data = { ++	.map_name	= "cfi_probe", ++	.width		= 2, ++}; ++ ++static struct resource tw5334_flash_resource = { ++	.flags		= IORESOURCE_MEM, ++}; ++ ++static struct platform_device tw5334_flash = { ++	.name		= "IXP4XX-Flash", ++	.id		= 0, ++	.dev		= { ++		.platform_data = &tw5334_flash_data, ++	}, ++	.num_resources	= 1, ++	.resource	= &tw5334_flash_resource, ++}; ++ ++static struct resource tw5334_uart_resource = { ++	.start	= IXP4XX_UART2_BASE_PHYS, ++	.end	= IXP4XX_UART2_BASE_PHYS + 0x0fff, ++	.flags	= IORESOURCE_MEM, ++}; ++ ++static struct plat_serial8250_port tw5334_uart_data[] = { ++	{ ++		.mapbase	= IXP4XX_UART2_BASE_PHYS, ++		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, ++		.irq		= IRQ_IXP4XX_UART2, ++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, ++		.iotype		= UPIO_MEM, ++		.regshift	= 2, ++		.uartclk	= IXP4XX_UART_XTAL, ++	}, ++	{ }, ++}; ++ ++static struct platform_device tw5334_uart = { ++	.name		= "serial8250", ++	.id		= PLAT8250_DEV_PLATFORM, ++	.dev			= { ++		.platform_data	= tw5334_uart_data, ++	}, ++	.num_resources	= 1, ++	.resource	= &tw5334_uart_resource, ++}; ++ ++/* Built-in 10/100 Ethernet MAC interfaces */ ++static struct eth_plat_info tw5334_plat_eth[] = { ++        { ++                .phy            = 0, ++                .rxq            = 3, ++		.txreadyq	= 20, ++        }, { ++                .phy            = 1, ++                .rxq            = 4, ++		.txreadyq	= 21, ++	} ++}; ++ ++static struct platform_device tw5334_eth[] = { ++        { ++                .name                   = "ixp4xx_eth", ++                .id                     = IXP4XX_ETH_NPEB, ++                .dev.platform_data      = tw5334_plat_eth, ++        }, { ++                .name                   = "ixp4xx_eth", ++                .id                     = IXP4XX_ETH_NPEC, ++                .dev.platform_data      = tw5334_plat_eth + 1, ++	} ++}; ++ ++static struct platform_device *tw5334_devices[] __initdata = { ++	&tw5334_flash, ++	&tw5334_uart, ++	&tw5334_eth[0], ++	&tw5334_eth[1], ++}; ++ ++static void __init tw5334_init(void) ++{ ++	DECLARE_MAC_BUF(mac_buf); ++	uint8_t __iomem *f; ++	int i; ++ ++	ixp4xx_sys_init(); ++ ++	tw5334_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); ++	tw5334_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(tw5334_devices, ARRAY_SIZE(tw5334_devices)); ++ ++	/* ++	 * Map in a portion of the flash and read the MAC addresses. ++	 * Since it is stored in BE in the flash itself, we need to ++	 * byteswap it if we're in LE mode. ++	 */ ++	f = ioremap(IXP4XX_EXP_BUS_BASE(0), 0x1000000); ++	if (f) { ++		for (i = 0; i < 6; i++) ++#ifdef __ARMEB__ ++		tw5334_plat_eth[0].hwaddr[i] = readb(f + 0xFC0422 + i); ++		tw5334_plat_eth[1].hwaddr[i] = readb(f + 0xFC043B + i); ++#else ++		tw5334_plat_eth[0].hwaddr[i] = readb(f + 0xFC0422 + (i^3)); ++		tw5334_plat_eth[1].hwaddr[i] = readb(f + 0xFC043B + (i^3)); ++#endif ++		iounmap(f); ++	} ++	printk(KERN_INFO "TW-533-4: Using MAC address %s for port 0\n", ++		print_mac(mac_buf, tw5334_plat_eth[0].hwaddr)); ++	printk(KERN_INFO "TW-533-4: Using MAC address %s for port 1\n", ++		print_mac(mac_buf, tw5334_plat_eth[1].hwaddr)); ++} ++ ++#ifdef CONFIG_MACH_TW5334 ++MACHINE_START(TW5334, "Titan Wireless TW-533-4") ++	/* 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	= tw5334_init, ++MACHINE_END ++#endif +--- /dev/null ++++ b/arch/arm/mach-ixp4xx/tw5334-pci.c +@@ -0,0 +1,69 @@ ++/* ++ * arch/arch/mach-ixp4xx/tw5334-pci.c ++ * ++ * PCI setup routines for the Titan Wireless TW-533-4 ++ * ++ * 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 <mach/hardware.h> ++ ++#include <asm/mach/pci.h> ++ ++void __init tw5334_pci_preinit(void) ++{ ++	set_irq_type(IRQ_IXP4XX_GPIO6, IRQ_TYPE_LEVEL_LOW); ++	set_irq_type(IRQ_IXP4XX_GPIO2, IRQ_TYPE_LEVEL_LOW); ++	set_irq_type(IRQ_IXP4XX_GPIO1, IRQ_TYPE_LEVEL_LOW); ++	set_irq_type(IRQ_IXP4XX_GPIO0, IRQ_TYPE_LEVEL_LOW); ++ ++	ixp4xx_pci_preinit(); ++} ++ ++static int __init tw5334_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++	if (slot == 12) ++		return IRQ_IXP4XX_GPIO6; ++	else if (slot == 13) ++		return IRQ_IXP4XX_GPIO2; ++	else if (slot == 14) ++		return IRQ_IXP4XX_GPIO1; ++	else if (slot == 15) ++		return IRQ_IXP4XX_GPIO0; ++	else return -1; ++} ++ ++struct hw_pci tw5334_pci __initdata = { ++	.nr_controllers = 1, ++	.preinit =        tw5334_pci_preinit, ++	.swizzle =        pci_std_swizzle, ++	.setup =          ixp4xx_setup, ++	.scan =           ixp4xx_scan_bus, ++	.map_irq =        tw5334_map_irq, ++}; ++ ++int __init tw5334_pci_init(void) ++{ ++	if (machine_is_tw5334()) ++		pci_common_init(&tw5334_pci); ++	return 0; ++} ++ ++subsys_initcall(tw5334_pci_init); +--- a/arch/arm/mach-ixp4xx/include/mach/uncompress.h ++++ b/arch/arm/mach-ixp4xx/include/mach/uncompress.h +@@ -42,7 +42,8 @@ static __inline__ void __arch_decomp_set + 	 */ + 	if (machine_is_adi_coyote() || machine_is_gtwx5715() || + 			 machine_is_gateway7001() || machine_is_wg302v2() || +-			 machine_is_pronghorn() || machine_is_pronghorn_metro() || machine_is_wrt300nv2()) ++			 machine_is_pronghorn() || machine_is_pronghorn_metro() || machine_is_wrt300nv2() || ++			 machine_is_tw5334()) + 		uart_base = (volatile u32*) IXP4XX_UART2_BASE_PHYS; + 	else + 		uart_base = (volatile u32*) IXP4XX_UART1_BASE_PHYS; diff --git a/target/linux/ixp4xx/patches-2.6.31/185-mi424wr_support.patch b/target/linux/ixp4xx/patches-2.6.31/185-mi424wr_support.patch new file mode 100644 index 000000000..1b8ee89c9 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/185-mi424wr_support.patch @@ -0,0 +1,465 @@ +--- /dev/null ++++ b/arch/arm/mach-ixp4xx/mi424wr-pci.c +@@ -0,0 +1,71 @@ ++/* ++ * arch/arm/mach-ixp4xx/mi424wr-pci.c ++ * ++ * Actiontec MI424WR board-level PCI initialization ++ * ++ * Copyright (C) 2008 Jose Vasconcellos ++ * ++ * Maintainer: Jose Vasconcellos <jvasco@verizon.net> ++ * ++ * 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/mach/pci.h> ++ ++/* PCI controller GPIO to IRQ pin mappings ++ * This information was obtained from Actiontec's GPL release. ++ * ++ *		INTA		INTB ++ * SLOT 13	8		6 ++ * SLOT 14	7		8 ++ * SLOT 15	6		7 ++ */ ++ ++void __init mi424wr_pci_preinit(void) ++{ ++	set_irq_type(IRQ_IXP4XX_GPIO6, IRQ_TYPE_LEVEL_LOW); ++	set_irq_type(IRQ_IXP4XX_GPIO7, IRQ_TYPE_LEVEL_LOW); ++	set_irq_type(IRQ_IXP4XX_GPIO8, IRQ_TYPE_LEVEL_LOW); ++ ++	ixp4xx_pci_preinit(); ++} ++ ++static int __init mi424wr_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++	if (slot == 13) ++		return IRQ_IXP4XX_GPIO8; ++	if (slot == 14) ++		return IRQ_IXP4XX_GPIO7; ++	if (slot == 15) ++		return IRQ_IXP4XX_GPIO6; ++ ++	return -1; ++} ++ ++struct hw_pci mi424wr_pci __initdata = { ++	.nr_controllers = 1, ++	.preinit	= mi424wr_pci_preinit, ++	.swizzle	= pci_std_swizzle, ++	.setup		= ixp4xx_setup, ++	.scan		= ixp4xx_scan_bus, ++	.map_irq	= mi424wr_map_irq, ++}; ++ ++int __init mi424wr_pci_init(void) ++{ ++	if (machine_is_mi424wr()) ++		pci_common_init(&mi424wr_pci); ++	return 0; ++} ++ ++subsys_initcall(mi424wr_pci_init); ++ +--- /dev/null ++++ b/arch/arm/mach-ixp4xx/mi424wr-setup.c +@@ -0,0 +1,344 @@ ++/* ++ * arch/arm/mach-ixp4xx/mi424wr-setup.c ++ * ++ * Actiontec MI424-WR board setup ++ * Copyright (c) 2008 Jose Vasconcellos ++ * ++ * Based on Gemtek GTWX5715 by ++ * Copyright (C) 2004 George T. Joseph ++ * Derived from Coyote ++ * ++ * 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. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. ++ * ++ */ ++ ++#include <linux/init.h> ++#include <linux/device.h> ++#include <linux/serial.h> ++#include <linux/serial_8250.h> ++#include <linux/types.h> ++#include <linux/memory.h> ++#include <linux/leds.h> ++#include <linux/spi/spi_gpio_old.h> ++ ++#include <asm/setup.h> ++#include <asm/irq.h> ++#include <asm/io.h> ++#include <asm/mach-types.h> ++#include <asm/mach/arch.h> ++#include <asm/mach/flash.h> ++ ++/* ++ * GPIO 2,3,4 and 9 are hard wired to the Micrel/Kendin KS8995M Switch ++ * and operate as an SPI type interface.  The details of the interface ++ * are available on Kendin/Micrel's web site. ++ */ ++ ++#define MI424WR_KSSPI_SELECT		9 ++#define MI424WR_KSSPI_TXD		4 ++#define MI424WR_KSSPI_CLOCK		2 ++#define MI424WR_KSSPI_RXD		3 ++ ++/* ++ * The "reset" button is wired to GPIO 10. ++ * The GPIO is brought "low" when the button is pushed. ++ */ ++ ++#define MI424WR_BUTTON_GPIO	10 ++#define MI424WR_BUTTON_IRQ	IRQ_IXP4XX_GPIO10 ++ ++#define MI424WR_MOCA_WAN_LED	11 ++ ++/* Latch on CS1 - taken from Actiontec's 2.4 source code ++ *  ++ * default latch value ++ * 0  - power alarm led (red)           0 (off) ++ * 1  - power led (green)               0 (off) ++ * 2  - wireless led    (green)         1 (off) ++ * 3  - no internet led (red)           0 (off) ++ * 4  - internet ok led (green)         0 (off) ++ * 5  - moca LAN                        0 (off) ++ * 6  - WAN alarm led (red)		0 (off) ++ * 7  - PCI reset                       1 (not reset) ++ * 8  - IP phone 1 led (green)          1 (off) ++ * 9  - IP phone 2 led (green)          1 (off) ++ * 10 - VOIP ready led (green)          1 (off) ++ * 11 - PSTN relay 1 control            0 (PSTN) ++ * 12 - PSTN relay 1 control            0 (PSTN) ++ * 13 - N/A ++ * 14 - N/A ++ * 15 - N/A ++ */ ++ ++#define MI424WR_LATCH_MASK              0x04 ++#define MI424WR_LATCH_DEFAULT           0x1f86 ++ ++#define MI424WR_LATCH_ALARM_LED         0x00 ++#define MI424WR_LATCH_POWER_LED         0x01 ++#define MI424WR_LATCH_WIRELESS_LED      0x02 ++#define MI424WR_LATCH_INET_DOWN_LED     0x03 ++#define MI424WR_LATCH_INET_OK_LED       0x04 ++#define MI424WR_LATCH_MOCA_LAN_LED      0x05 ++#define MI424WR_LATCH_WAN_ALARM_LED     0x06 ++#define MI424WR_LATCH_PCI_RESET         0x07 ++#define MI424WR_LATCH_PHONE1_LED        0x08 ++#define MI424WR_LATCH_PHONE2_LED        0x09 ++#define MI424WR_LATCH_VOIP_LED          0x10 ++#define MI424WR_LATCH_PSTN_RELAY1       0x11 ++#define MI424WR_LATCH_PSTN_RELAY2       0x12 ++ ++/* initialize CS1 to default timings, Intel style, 16-bit bus */ ++#define MI424WR_CS1_CONFIG	0x80000002 ++ ++/* Define both UARTs but they are not easily accessible. ++ */ ++ ++static struct resource mi424wr_uart_resources[] = { ++	{ ++		.start	= IXP4XX_UART1_BASE_PHYS, ++		.end	= IXP4XX_UART1_BASE_PHYS + 0x0fff, ++		.flags	= IORESOURCE_MEM, ++	}, ++	{ ++		.start	= IXP4XX_UART2_BASE_PHYS, ++		.end	= IXP4XX_UART2_BASE_PHYS + 0x0fff, ++		.flags	= IORESOURCE_MEM, ++	} ++}; ++ ++ ++static struct plat_serial8250_port mi424wr_uart_platform_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, ++	}, ++	{ ++		.mapbase	= IXP4XX_UART2_BASE_PHYS, ++		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, ++		.irq		= IRQ_IXP4XX_UART2, ++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, ++		.iotype		= UPIO_MEM, ++		.regshift	= 2, ++		.uartclk	= IXP4XX_UART_XTAL, ++	}, ++	{ }, ++}; ++ ++static struct platform_device mi424wr_uart_device = { ++	.name		= "serial8250", ++	.id		= PLAT8250_DEV_PLATFORM, ++	.dev.platform_data	= mi424wr_uart_platform_data, ++	.num_resources	= ARRAY_SIZE(mi424wr_uart_resources), ++	.resource	= mi424wr_uart_resources, ++}; ++ ++static struct flash_platform_data mi424wr_flash_data = { ++	.map_name	= "cfi_probe", ++	.width		= 2, ++}; ++ ++static struct resource mi424wr_flash_resource = { ++	.flags		= IORESOURCE_MEM, ++}; ++ ++static struct platform_device mi424wr_flash = { ++	.name		= "IXP4XX-Flash", ++	.id		= 0, ++	.dev.platform_data = &mi424wr_flash_data, ++	.num_resources	= 1, ++	.resource	= &mi424wr_flash_resource, ++}; ++ ++static int mi424wr_spi_boardinfo_setup(struct spi_board_info *bi, ++		struct spi_master *master, void *data) ++{ ++ ++	strlcpy(bi->modalias, "spi-ks8995", sizeof(bi->modalias)); ++ ++	bi->max_speed_hz = 5000000 /* Hz */; ++	bi->bus_num = master->bus_num; ++	bi->mode = SPI_MODE_0; ++ ++	return 0; ++} ++ ++static struct spi_gpio_platform_data mi424wr_spi_bus_data = { ++	.pin_cs			= MI424WR_KSSPI_SELECT, ++	.pin_clk		= MI424WR_KSSPI_CLOCK, ++	.pin_miso		= MI424WR_KSSPI_RXD, ++	.pin_mosi		= MI424WR_KSSPI_TXD, ++	.cs_activelow		= 1, ++	.no_spi_delay		= 1, ++	.boardinfo_setup	= mi424wr_spi_boardinfo_setup, ++}; ++ ++static struct gpio_led mi424wr_gpio_led[] = { ++	{ ++		.name		= "moca-wan",	/* green led */ ++		.gpio		= MI424WR_MOCA_WAN_LED, ++		.active_low	= 0, ++	} ++}; ++ ++static struct gpio_led_platform_data mi424wr_gpio_leds_data = { ++	.num_leds	= 1, ++	.leds		= mi424wr_gpio_led, ++}; ++ ++static struct platform_device mi424wr_gpio_leds = { ++	.name		= "leds-gpio", ++	.id		= -1, ++	.dev.platform_data = &mi424wr_gpio_leds_data, ++}; ++ ++static uint16_t latch_value = MI424WR_LATCH_DEFAULT; ++static uint16_t __iomem *iobase; ++ ++static void mi424wr_latch_set_led(u8 bit, enum led_brightness value) ++{ ++ ++	if (((MI424WR_LATCH_MASK >> bit) & 1) ^ (value == LED_OFF)) ++		latch_value &= ~(0x1 << bit); ++	else ++		latch_value |= (0x1 << bit); ++ ++	__raw_writew(latch_value, iobase); ++ ++} ++ ++static struct latch_led mi424wr_latch_led[] = { ++	{ ++		.name	= "power-alarm", ++		.bit	= MI424WR_LATCH_ALARM_LED, ++	}, ++	{ ++		.name	= "power-ok", ++		.bit	= MI424WR_LATCH_POWER_LED, ++	}, ++	{ ++		.name	= "wireless",	/* green led */ ++		.bit	= MI424WR_LATCH_WIRELESS_LED, ++	}, ++	{ ++		.name	= "inet-down",	/* red led */ ++		.bit	= MI424WR_LATCH_INET_DOWN_LED, ++	}, ++	{ ++		.name	= "inet-up",	/* green led */ ++		.bit	= MI424WR_LATCH_INET_OK_LED, ++	}, ++	{ ++		.name	= "moca-lan",	/* green led */ ++		.bit	= MI424WR_LATCH_MOCA_LAN_LED, ++	}, ++	{ ++		.name	= "wan-alarm",	/* red led */ ++		.bit	= MI424WR_LATCH_WAN_ALARM_LED, ++	} ++}; ++ ++static struct latch_led_platform_data mi424wr_latch_leds_data = { ++	.num_leds	= ARRAY_SIZE(mi424wr_latch_led), ++	.mem		= 0x51000000, ++	.leds		= mi424wr_latch_led, ++	.set_led        = mi424wr_latch_set_led, ++}; ++ ++static struct platform_device mi424wr_latch_leds = { ++	.name		= "leds-latch", ++	.id		= -1, ++	.dev.platform_data = &mi424wr_latch_leds_data, ++}; ++ ++static struct platform_device mi424wr_spi_bus = { ++	.name		= "spi-gpio", ++	.id		= 0, ++	.dev.platform_data = &mi424wr_spi_bus_data, ++}; ++ ++static struct eth_plat_info mi424wr_npeb_data = { ++	.phy		= 17,	/* KS8721 */ ++	.rxq		= 3, ++	.txreadyq	= 20, ++}; ++ ++static struct eth_plat_info mi424wr_npec_data = { ++	.phy		= IXP4XX_ETH_PHY_MAX_ADDR, ++	.phy_mask	= 0x1e, /* ports 1-4 of the KS8995 switch */ ++	.rxq		= 4, ++	.txreadyq	= 21, ++}; ++ ++static struct platform_device mi424wr_npe_devices[] = { ++	{ ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEC, ++		.dev.platform_data	= &mi424wr_npec_data, ++	}, { ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEB, ++		.dev.platform_data	= &mi424wr_npeb_data, ++	} ++}; ++ ++static struct platform_device *mi424wr_devices[] __initdata = { ++	&mi424wr_uart_device, ++	&mi424wr_flash, ++	&mi424wr_gpio_leds, ++	&mi424wr_latch_leds, ++	&mi424wr_spi_bus, ++	&mi424wr_npe_devices[0], ++	&mi424wr_npe_devices[1], ++}; ++ ++static void __init mi424wr_init(void) ++{ ++	ixp4xx_sys_init(); ++ ++	mi424wr_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); ++	mi424wr_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_8M - 1; ++ ++	*IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE; ++	*IXP4XX_EXP_CS1 = MI424WR_CS1_CONFIG; ++ ++	/* configure button as input ++	 */ ++	gpio_line_config(MI424WR_BUTTON_GPIO, IXP4XX_GPIO_IN); ++ ++	/* Initialize LEDs and enables PCI bus. ++	 */ ++	iobase = ioremap_nocache(IXP4XX_EXP_BUS_BASE(1), 0x1000); ++	__raw_writew(latch_value, iobase); ++ ++	platform_add_devices(mi424wr_devices, ARRAY_SIZE(mi424wr_devices)); ++} ++ ++ ++MACHINE_START(MI424WR, "Actiontec MI424WR") ++	/* Maintainer: Jose Vasconcellos */ ++	.phys_io	= IXP4XX_UART2_BASE_PHYS, ++	.io_pg_offst	= ((IXP4XX_UART2_BASE_VIRT) >> 18) & 0xfffc, ++	.map_io		= ixp4xx_map_io, ++	.init_irq	= ixp4xx_init_irq, ++	.timer		= &ixp4xx_timer, ++	.boot_params	= 0x0100, ++	.init_machine	= mi424wr_init, ++MACHINE_END ++ +--- a/arch/arm/mach-ixp4xx/Makefile ++++ b/arch/arm/mach-ixp4xx/Makefile +@@ -23,6 +23,7 @@ obj-pci-$(CONFIG_MACH_COMPEX)		+= ixdp42 + obj-pci-$(CONFIG_MACH_WRT300NV2)		+= wrt300nv2-pci.o + obj-pci-$(CONFIG_MACH_AP1000)		+= ixdp425-pci.o + obj-pci-$(CONFIG_MACH_TW5334)		+= tw5334-pci.o ++obj-pci-$(CONFIG_MACH_MI424WR)		+= mi424wr-pci.o +  + obj-y	+= common.o +  +@@ -45,6 +46,7 @@ obj-$(CONFIG_MACH_COMPEX)	+= compex-setu + obj-$(CONFIG_MACH_WRT300NV2)	+= wrt300nv2-setup.o + obj-$(CONFIG_MACH_AP1000)	+= ap1000-setup.o + obj-$(CONFIG_MACH_TW5334)	+= tw5334-setup.o ++obj-$(CONFIG_MACH_MI424WR)	+= mi424wr-setup.o +  + obj-$(CONFIG_PCI)		+= $(obj-pci-$(CONFIG_PCI)) common-pci.o + obj-$(CONFIG_IXP4XX_QMGR)	+= ixp4xx_qmgr.o +--- a/arch/arm/mach-ixp4xx/Kconfig ++++ b/arch/arm/mach-ixp4xx/Kconfig +@@ -235,6 +235,13 @@ config MACH_GTWX5715 + 		"High Speed" UART is n/c (as far as I can tell) + 		20 Pin ARM/Xscale JTAG interface on J2 +  ++config MACH_MI424WR ++	bool "Actiontec MI424WR" ++	depends on ARCH_IXP4XX ++	select PCI ++	help ++		Add support for the Actiontec MI424-WR. ++ + comment "IXP4xx Options" +  + config IXP4XX_INDIRECT_PCI +--- a/arch/arm/configs/ixp4xx_defconfig ++++ b/arch/arm/configs/ixp4xx_defconfig +@@ -172,6 +172,7 @@ CONFIG_MACH_FSG=y + CONFIG_CPU_IXP46X=y + CONFIG_CPU_IXP43X=y + CONFIG_MACH_GTWX5715=y ++CONFIG_MACH_MI424WR=y +  + # + # IXP4xx Options diff --git a/target/linux/ixp4xx/patches-2.6.31/190-cambria_support.patch b/target/linux/ixp4xx/patches-2.6.31/190-cambria_support.patch new file mode 100644 index 000000000..c3791c690 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/190-cambria_support.patch @@ -0,0 +1,553 @@ +--- /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 <mach/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, IRQ_TYPE_LEVEL_LOW); ++	set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW); ++	set_irq_type(IRQ_IXP4XX_GPIO9, IRQ_TYPE_LEVEL_LOW); ++	set_irq_type(IRQ_IXP4XX_GPIO8, IRQ_TYPE_LEVEL_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,429 @@ ++/* ++ * 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/device.h> ++#include <linux/i2c.h> ++#include <linux/i2c-gpio.h> ++#include <linux/i2c/at24.h> ++#include <linux/if_ether.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/leds.h> ++#include <linux/memory.h> ++#include <linux/netdevice.h> ++#include <linux/serial.h> ++#include <linux/serial_8250.h> ++#include <linux/slab.h> ++#include <linux/socket.h> ++#include <linux/types.h> ++#include <linux/tty.h> ++ ++#include <mach/hardware.h> ++#include <asm/irq.h> ++#include <asm/mach-types.h> ++#include <asm/mach/arch.h> ++#include <asm/mach/flash.h> ++#include <asm/setup.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 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 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 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); ++} ++ ++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 (strcmp(info->model, model) == 0) ++			return info; ++	} ++ ++	return NULL; ++} ++ ++static struct memory_accessor *at24_mem_acc; ++ ++static int at24_setup(struct memory_accessor *mem_acc, void *context) ++{ ++	char mac_addr[ETH_ALEN]; ++	char model[6]; ++ ++	at24_mem_acc = mem_acc; ++ ++	/* Read MAC addresses */ ++	if (at24_mem_acc->read(at24_mem_acc, mac_addr, 0x0, 6) == 6) { ++		memcpy(&cambria_npec_data.hwaddr, mac_addr, ETH_ALEN); ++	} ++	if (at24_mem_acc->read(at24_mem_acc, mac_addr, 0x6, 6) == 6) { ++		memcpy(&cambria_npea_data.hwaddr, mac_addr, ETH_ALEN); ++	} ++ ++	/* Read the first 6 bytes of the model number */ ++	if (at24_mem_acc->read(at24_mem_acc, model, 0x20, 6) == 6) { ++		cambria_info = cambria_find_board_info(model); ++	} ++ ++	return 0; ++} ++ ++static struct at24_platform_data cambria_eeprom_info = { ++	.byte_len	= 1024, ++	.page_size	= 16, ++	.flags		= AT24_FLAG_READONLY, ++	.setup		= at24_setup, ++}; ++ ++static struct i2c_board_info __initdata cambria_i2c_board_info[] = { ++	{ ++		I2C_BOARD_INFO("ds1672", 0x68), ++	}, ++	{ ++		I2C_BOARD_INFO("ad7418", 0x28), ++	}, ++	{ ++		I2C_BOARD_INFO("24c08", 0x51), ++		.platform_data	= &cambria_eeprom_info ++	}, ++}; ++ ++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; ++ ++	i2c_register_board_info(0, cambria_i2c_board_info, ++				ARRAY_SIZE(cambria_i2c_board_info)); ++} ++ ++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(); ++	} ++ ++	return 0; ++} ++late_initcall(cambria_model_setup); ++ ++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 +--- a/arch/arm/mach-ixp4xx/Kconfig ++++ b/arch/arm/mach-ixp4xx/Kconfig +@@ -25,6 +25,14 @@ config MACH_AVILA + 	  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 +@@ -214,7 +222,7 @@ config CPU_IXP46X +  + 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-n	:= +  + 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 +@@ -29,6 +30,7 @@ obj-y	+= common.o +  + 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 --git a/target/linux/ixp4xx/patches-2.6.31/191-cambria_optional_uart.patch b/target/linux/ixp4xx/patches-2.6.31/191-cambria_optional_uart.patch new file mode 100644 index 000000000..1495766ff --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/191-cambria_optional_uart.patch @@ -0,0 +1,217 @@ +--- a/arch/arm/mach-ixp4xx/cambria-setup.c ++++ b/arch/arm/mach-ixp4xx/cambria-setup.c +@@ -34,6 +34,7 @@ + #include <asm/mach/arch.h> + #include <asm/mach/flash.h> + #include <asm/setup.h> ++#include <linux/irq.h> +  + struct cambria_board_info { + 	unsigned char	*model; +@@ -127,6 +128,45 @@ static struct platform_device cambria_ua + 	.resource	= &cambria_uart_resource, + }; +  ++static struct resource cambria_optional_uart_resources[] = { ++	{ ++		.start	= 0x52000000, ++		.end	= 0x52000fff, ++		.flags	= IORESOURCE_MEM ++	}, ++	{ ++		.start	= 0x53000000, ++		.end	= 0x53000fff, ++		.flags	= IORESOURCE_MEM ++	} ++}; ++ ++static struct plat_serial8250_port cambria_optional_uart_data[] = { ++	{ ++		.flags		= UPF_BOOT_AUTOCONF, ++		.iotype		= UPIO_MEM_DELAY, ++		.regshift	= 0, ++		.uartclk	= 1843200, ++		.rw_delay	= 2, ++	}, ++	{ ++		.flags		= UPF_BOOT_AUTOCONF, ++		.iotype		= UPIO_MEM_DELAY, ++		.regshift	= 0, ++		.uartclk	= 1843200, ++		.rw_delay	= 2, ++	}, ++  { }, ++}; ++ ++static struct platform_device cambria_optional_uart = { ++	.name		= "serial8250", ++	.id		= PLAT8250_DEV_PLATFORM1, ++	.dev.platform_data	= cambria_optional_uart_data, ++	.num_resources	= 2, ++	.resource	= cambria_optional_uart_resources, ++}; ++ + static struct resource cambria_pata_resources[] = { + 	{ + 		.flags	= IORESOURCE_MEM +@@ -283,6 +323,19 @@ static void __init cambria_gw23xx_setup( +  + static void __init cambria_gw2350_setup(void) + { ++	*IXP4XX_EXP_CS2 = 0xBFFF3C43; ++	set_irq_type(IRQ_IXP4XX_GPIO3, IRQ_TYPE_EDGE_RISING); ++	cambria_optional_uart_data[0].mapbase	= 0x52FF0000; ++	cambria_optional_uart_data[0].membase	= (void __iomem *)ioremap(0x52FF0000, 0x0fff); ++	cambria_optional_uart_data[0].irq		= IRQ_IXP4XX_GPIO3; ++ ++	*IXP4XX_EXP_CS3 = 0xBFFF3C43; ++	set_irq_type(IRQ_IXP4XX_GPIO4, IRQ_TYPE_EDGE_RISING); ++	cambria_optional_uart_data[1].mapbase	= 0x53FF0000; ++	cambria_optional_uart_data[1].membase	= (void __iomem *)ioremap(0x53FF0000, 0x0fff); ++	cambria_optional_uart_data[1].irq		= IRQ_IXP4XX_GPIO4; ++ ++	platform_device_register(&cambria_optional_uart); + 	platform_device_register(&cambria_npec_device); + 	platform_device_register(&cambria_npea_device); +  +@@ -294,6 +347,19 @@ static void __init cambria_gw2350_setup( +  + static void __init cambria_gw2358_setup(void) + { ++	*IXP4XX_EXP_CS3 = 0xBFFF3C43; ++	set_irq_type(IRQ_IXP4XX_GPIO3, IRQ_TYPE_EDGE_RISING); ++	cambria_optional_uart_data[0].mapbase	= 0x53FC0000; ++	cambria_optional_uart_data[0].membase	= (void __iomem *)ioremap(0x53FC0000, 0x0fff); ++	cambria_optional_uart_data[0].irq		= IRQ_IXP4XX_GPIO3; ++ ++	set_irq_type(IRQ_IXP4XX_GPIO4, IRQ_TYPE_EDGE_RISING); ++	cambria_optional_uart_data[1].mapbase	= 0x53F80000; ++	cambria_optional_uart_data[1].membase	= (void __iomem *)ioremap(0x53F80000, 0x0fff); ++	cambria_optional_uart_data[1].irq		= IRQ_IXP4XX_GPIO4; ++ ++	platform_device_register(&cambria_optional_uart); ++ + 	platform_device_register(&cambria_npec_device); + 	platform_device_register(&cambria_npea_device); +  +--- a/include/linux/serial_8250.h ++++ b/include/linux/serial_8250.h +@@ -26,6 +26,7 @@ struct plat_serial8250_port { + 	void            *private_data; + 	unsigned char	regshift;	/* register shift */ + 	unsigned char	iotype;		/* UPIO_* */ ++	unsigned int rw_delay;	/* udelay for slower busses IXP4XX Expansion Bus */ + 	unsigned char	hub6; + 	upf_t		flags;		/* UPF_* flags */ + 	unsigned int	type;		/* If UPF_FIXED_TYPE */ +--- a/include/linux/serial_core.h ++++ b/include/linux/serial_core.h +@@ -280,6 +280,7 @@ struct uart_port { + #define UPIO_TSI		(5)			/* Tsi108/109 type IO */ + #define UPIO_DWAPB		(6)			/* DesignWare APB UART */ + #define UPIO_RM9000		(7)			/* RM9000 type IO */ ++#define UPIO_MEM_DELAY	(8) +  + 	unsigned int		read_status_mask;	/* driver specific */ + 	unsigned int		ignore_status_mask;	/* driver specific */ +@@ -322,6 +323,7 @@ struct uart_port { +  + 	unsigned int		mctrl;			/* current modem ctrl settings */ + 	unsigned int		timeout;		/* character-based timeout */ ++	unsigned int		rw_delay;		/* udelay for slow busses, IXP4XX Expansion Bus */ + 	unsigned int		type;			/* port type */ + 	const struct uart_ops	*ops; + 	unsigned int		custom_divisor; +--- a/drivers/serial/8250.c ++++ b/drivers/serial/8250.c +@@ -404,6 +404,20 @@ static void mem_serial_out(struct uart_p + 	writeb(value, p->membase + offset); + } +  ++static unsigned int memdelay_serial_in(struct uart_port *p, int offset) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)p; ++	udelay(up->port.rw_delay); ++	return mem_serial_in(p, offset); ++} ++ ++static void memdelay_serial_out(struct uart_port *p, int offset, int value) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)p; ++	udelay(up->port.rw_delay); ++	mem_serial_out(p, offset, value); ++} ++ + static void mem32_serial_out(struct uart_port *p, int offset, int value) + { + 	offset = map_8250_out_reg(p, offset) << p->regshift; +@@ -497,6 +511,11 @@ static void set_io_from_upio(struct uart + 		p->serial_out = mem32_serial_out; + 		break; +  ++	case UPIO_MEM_DELAY: ++		p->serial_in = memdelay_serial_in; ++		p->serial_out = memdelay_serial_out; ++		break; ++ + #ifdef CONFIG_SERIAL_8250_AU1X00 + 	case UPIO_AU: + 		p->serial_in = au_serial_in; +@@ -529,6 +548,7 @@ serial_out_sync(struct uart_8250_port *u + 	switch (p->iotype) { + 	case UPIO_MEM: + 	case UPIO_MEM32: ++	case UPIO_MEM_DELAY: + #ifdef CONFIG_SERIAL_8250_AU1X00 + 	case UPIO_AU: + #endif +@@ -2447,6 +2467,7 @@ static int serial8250_request_std_resour + 	case UPIO_MEM32: + 	case UPIO_MEM: + 	case UPIO_DWAPB: ++	case UPIO_MEM_DELAY: + 		if (!up->port.mapbase) + 			break; +  +@@ -2484,6 +2505,7 @@ static void serial8250_release_std_resou + 	case UPIO_MEM32: + 	case UPIO_MEM: + 	case UPIO_DWAPB: ++	case UPIO_MEM_DELAY: + 		if (!up->port.mapbase) + 			break; +  +@@ -2953,6 +2975,7 @@ static int __devinit serial8250_probe(st + 		port.serial_in		= p->serial_in; + 		port.serial_out		= p->serial_out; + 		port.dev		= &dev->dev; ++		port.rw_delay	= p->rw_delay; + 		if (share_irqs) + 			port.flags |= UPF_SHARE_IRQ; + 		ret = serial8250_register_port(&port); +@@ -3102,6 +3125,7 @@ int serial8250_register_port(struct uart + 		uart->port.iotype       = port->iotype; + 		uart->port.flags        = port->flags | UPF_BOOT_AUTOCONF; + 		uart->port.mapbase      = port->mapbase; ++		uart->port.rw_delay			= port->rw_delay; + 		uart->port.private_data = port->private_data; + 		if (port->dev) + 			uart->port.dev = port->dev; +--- a/drivers/serial/serial_core.c ++++ b/drivers/serial/serial_core.c +@@ -2138,6 +2138,7 @@ uart_report_port(struct uart_driver *drv + 		snprintf(address, sizeof(address), + 			 "I/O 0x%lx offset 0x%x", port->iobase, port->hub6); + 		break; ++	case UPIO_MEM_DELAY: + 	case UPIO_MEM: + 	case UPIO_MEM32: + 	case UPIO_AU: +@@ -2552,6 +2553,7 @@ int uart_match_port(struct uart_port *po + 	case UPIO_HUB6: + 		return (port1->iobase == port2->iobase) && + 		       (port1->hub6   == port2->hub6); ++	case UPIO_MEM_DELAY: + 	case UPIO_MEM: + 	case UPIO_MEM32: + 	case UPIO_AU: diff --git a/target/linux/ixp4xx/patches-2.6.31/192-cambria_gpio_device.patch b/target/linux/ixp4xx/patches-2.6.31/192-cambria_gpio_device.patch new file mode 100644 index 000000000..d785c3a8c --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/192-cambria_gpio_device.patch @@ -0,0 +1,46 @@ +--- a/arch/arm/mach-ixp4xx/cambria-setup.c ++++ b/arch/arm/mach-ixp4xx/cambria-setup.c +@@ -214,6 +214,20 @@ static struct platform_device cambria_gp + 	.dev.platform_data = &cambria_gpio_leds_data, + }; +  ++static struct resource cambria_gpio_resources[] = { ++	{ ++		.name = "gpio", ++		.flags  = 0, ++	}, ++}; ++ ++static struct platform_device cambria_gpio = { ++	.name     = "GPIODEV", ++	.id     = -1, ++	.num_resources    = ARRAY_SIZE(cambria_gpio_resources), ++	.resource   = cambria_gpio_resources, ++}; ++ + static struct latch_led cambria_latch_leds[] = { + 	{ + 		.name	= "ledA",  /* green led */ +@@ -335,6 +349,11 @@ static void __init cambria_gw2350_setup( + 	cambria_optional_uart_data[1].membase	= (void __iomem *)ioremap(0x53FF0000, 0x0fff); + 	cambria_optional_uart_data[1].irq		= IRQ_IXP4XX_GPIO4; +  ++	cambria_gpio_resources[0].start = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) |\ ++																		(1 << 5) | (1 << 8) | (1 << 9) | (1 << 12); ++	cambria_gpio_resources[0].end = cambria_gpio_resources[0].start; ++ ++	platform_device_register(&cambria_gpio); + 	platform_device_register(&cambria_optional_uart); + 	platform_device_register(&cambria_npec_device); + 	platform_device_register(&cambria_npea_device); +@@ -358,6 +377,10 @@ static void __init cambria_gw2358_setup( + 	cambria_optional_uart_data[1].membase	= (void __iomem *)ioremap(0x53F80000, 0x0fff); + 	cambria_optional_uart_data[1].irq		= IRQ_IXP4XX_GPIO4; +  ++	cambria_gpio_resources[0].start = (1 << 14); ++	cambria_gpio_resources[0].end = cambria_gpio_resources[0].start; ++ ++	platform_device_register(&cambria_gpio); + 	platform_device_register(&cambria_optional_uart); +  + 	platform_device_register(&cambria_npec_device); diff --git a/target/linux/ixp4xx/patches-2.6.31/193-cambria_pld_gpio.patch b/target/linux/ixp4xx/patches-2.6.31/193-cambria_pld_gpio.patch new file mode 100644 index 000000000..299630f17 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/193-cambria_pld_gpio.patch @@ -0,0 +1,107 @@ +--- a/arch/arm/mach-ixp4xx/cambria-setup.c ++++ b/arch/arm/mach-ixp4xx/cambria-setup.c +@@ -12,11 +12,14 @@ +  */ +  + #include <linux/device.h> ++#include <linux/gpio_buttons.h> + #include <linux/i2c.h> + #include <linux/i2c-gpio.h> + #include <linux/i2c/at24.h> ++#include <linux/i2c/gw_i2c_pld.h> + #include <linux/if_ether.h> + #include <linux/init.h> ++#include <linux/input.h> + #include <linux/kernel.h> + #include <linux/leds.h> + #include <linux/memory.h> +@@ -323,6 +326,39 @@ static struct platform_device cambria_us + 	}, + }; +  ++static struct gw_i2c_pld_platform_data gw_i2c_pld_data0 = { ++	.gpio_base	= 16, ++	.nr_gpio	= 8, ++}; ++ ++static struct gw_i2c_pld_platform_data gw_i2c_pld_data1 = { ++	.gpio_base	= 24, ++	.nr_gpio	= 2, ++}; ++ ++ ++static struct gpio_button cambria_gpio_buttons[] = { ++	{ ++		.desc		= "user", ++		.type		= EV_KEY, ++		.code		= BTN_0, ++		.threshold	= 2, ++		.gpio		= 25, ++	} ++}; ++ ++static struct gpio_buttons_platform_data cambria_gpio_buttons_data = { ++	.poll_interval	= 500, ++	.nbuttons	= 1, ++	.buttons	= cambria_gpio_buttons,	 ++}; ++ ++static struct platform_device cambria_gpio_buttons_device = { ++	.name			= "gpio-buttons", ++	.id			= -1, ++	.dev.platform_data	= &cambria_gpio_buttons_data, ++}; ++ + static struct platform_device *cambria_devices[] __initdata = { + 	&cambria_i2c_gpio, + 	&cambria_flash, +@@ -331,6 +367,11 @@ static struct platform_device *cambria_d +  + static void __init cambria_gw23xx_setup(void) + { ++	cambria_gpio_resources[0].start = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) |\ ++																		(1 << 5) | (1 << 8) | (1 << 9) | (1 << 12); ++	cambria_gpio_resources[0].end = cambria_gpio_resources[0].start; ++ ++	platform_device_register(&cambria_gpio); + 	platform_device_register(&cambria_npec_device); + 	platform_device_register(&cambria_npea_device); + } +@@ -377,7 +418,8 @@ static void __init cambria_gw2358_setup( + 	cambria_optional_uart_data[1].membase	= (void __iomem *)ioremap(0x53F80000, 0x0fff); + 	cambria_optional_uart_data[1].irq		= IRQ_IXP4XX_GPIO4; +  +-	cambria_gpio_resources[0].start = (1 << 14); ++	cambria_gpio_resources[0].start = (1 << 14) | (1 << 16) | (1 << 17) | (1 << 18) |\ ++																		(1 << 19) | (1 << 20) | (1 << 24) | (1 << 25); + 	cambria_gpio_resources[0].end = cambria_gpio_resources[0].start; +  + 	platform_device_register(&cambria_gpio); +@@ -391,7 +433,12 @@ static void __init cambria_gw2358_setup( +  + 	platform_device_register(&cambria_pata); +  ++	cambria_gpio_leds[0].gpio = 24; ++	platform_device_register(&cambria_gpio_leds_device); ++ + 	platform_device_register(&cambria_latch_leds_device); ++ ++	platform_device_register(&cambria_gpio_buttons_device); + } +  + static struct cambria_board_info cambria_boards[] __initdata = { +@@ -460,6 +507,14 @@ static struct i2c_board_info __initdata  + 		I2C_BOARD_INFO("24c08", 0x51), + 		.platform_data	= &cambria_eeprom_info + 	}, ++	{ ++		I2C_BOARD_INFO("gw_i2c_pld", 0x56), ++		.platform_data	= &gw_i2c_pld_data0, ++	}, ++	{ ++		I2C_BOARD_INFO("gw_i2c_pld", 0x57), ++		.platform_data	= &gw_i2c_pld_data1, ++	}, + }; +  + static void __init cambria_init(void) diff --git a/target/linux/ixp4xx/patches-2.6.31/201-npe_driver_print_license_location.patch b/target/linux/ixp4xx/patches-2.6.31/201-npe_driver_print_license_location.patch new file mode 100644 index 000000000..b97dd77dc --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/201-npe_driver_print_license_location.patch @@ -0,0 +1,11 @@ +--- a/arch/arm/mach-ixp4xx/ixp4xx_npe.c ++++ b/arch/arm/mach-ixp4xx/ixp4xx_npe.c +@@ -583,6 +583,8 @@ int npe_load_firmware(struct npe *npe, c + 	npe_reset(npe); + #endif +  ++	print_npe(KERN_INFO, npe, "firmware's license can be found in /usr/share/doc/LICENSE.IPL\n"); ++ + 	print_npe(KERN_INFO, npe, "firmware functionality 0x%X, " + 		  "revision 0x%X:%X\n", (image->id >> 16) & 0xFF, + 		  (image->id >> 8) & 0xFF, image->id & 0xFF); diff --git a/target/linux/ixp4xx/patches-2.6.31/203-npe_driver_mask_phy_features.patch b/target/linux/ixp4xx/patches-2.6.31/203-npe_driver_mask_phy_features.patch new file mode 100644 index 000000000..eacf35d07 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/203-npe_driver_mask_phy_features.patch @@ -0,0 +1,13 @@ +--- a/drivers/net/arm/ixp4xx_eth.c ++++ b/drivers/net/arm/ixp4xx_eth.c +@@ -1217,6 +1217,10 @@ static int __devinit eth_init_one(struct + 	if ((err = IS_ERR(port->phydev))) + 		goto err_free_mem; +  ++	/* mask with MAC supported features */ ++	port->phydev->supported &= PHY_BASIC_FEATURES; ++	port->phydev->advertising = port->phydev->supported; ++ + 	port->phydev->irq = PHY_POLL; +  + 	if ((err = register_netdev(dev))) diff --git a/target/linux/ixp4xx/patches-2.6.31/204-npe_driver_add_missing_phy_disconnect.patch b/target/linux/ixp4xx/patches-2.6.31/204-npe_driver_add_missing_phy_disconnect.patch new file mode 100644 index 000000000..b77dc0633 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/204-npe_driver_add_missing_phy_disconnect.patch @@ -0,0 +1,10 @@ +--- a/drivers/net/arm/ixp4xx_eth.c ++++ b/drivers/net/arm/ixp4xx_eth.c +@@ -1249,6 +1249,7 @@ static int __devexit eth_remove_one(stru + 	struct net_device *dev = platform_get_drvdata(pdev); + 	struct port *port = netdev_priv(dev); +  ++	phy_disconnect(port->phydev); + 	unregister_netdev(dev); + 	phy_disconnect(port->phydev); + 	npe_port_tab[NPE_ID(port->id)] = NULL; diff --git a/target/linux/ixp4xx/patches-2.6.31/205-npe_driver_separate_phy_functions.patch b/target/linux/ixp4xx/patches-2.6.31/205-npe_driver_separate_phy_functions.patch new file mode 100644 index 000000000..c1fc76d2a --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/205-npe_driver_separate_phy_functions.patch @@ -0,0 +1,113 @@ +--- a/drivers/net/arm/ixp4xx_eth.c ++++ b/drivers/net/arm/ixp4xx_eth.c +@@ -396,6 +396,53 @@ static void ixp4xx_adjust_link(struct ne + 	       dev->name, port->speed, port->duplex ? "full" : "half"); + } +  ++static int ixp4xx_phy_connect(struct net_device *dev) ++{ ++	struct port *port = netdev_priv(dev); ++	struct eth_plat_info *plat = port->plat; ++	char phy_id[MII_BUS_ID_SIZE + 3]; ++ ++	snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, "0", plat->phy); ++	port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0, ++				   PHY_INTERFACE_MODE_MII); ++	if (IS_ERR(port->phydev)) { ++		printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); ++		return PTR_ERR(port->phydev); ++	} ++ ++	/* mask with MAC supported features */ ++	port->phydev->supported &= PHY_BASIC_FEATURES; ++	port->phydev->advertising = port->phydev->supported; ++ ++	port->phydev->irq = PHY_POLL; ++ ++	printk(KERN_INFO "%s: MII PHY %i on %s\n", dev->name, plat->phy, ++	       npe_name(port->npe)); ++ ++	return 0; ++} ++ ++static void ixp4xx_phy_disconnect(struct net_device *dev) ++{ ++	struct port *port = netdev_priv(dev); ++ ++	phy_disconnect(port->phydev); ++} ++ ++static void ixp4xx_phy_start(struct net_device *dev) ++{ ++	struct port *port = netdev_priv(dev); ++ ++	port->speed = 0;	/* force "link up" message */ ++	phy_start(port->phydev); ++} ++ ++static void ixp4xx_phy_stop(struct net_device *dev) ++{ ++	struct port *port = netdev_priv(dev); ++ ++	phy_stop(port->phydev); ++} +  + static inline void debug_pkt(struct net_device *dev, const char *func, + 			     u8 *data, int len) +@@ -1005,8 +1052,7 @@ static int eth_open(struct net_device *d + 		return err; + 	} +  +-	port->speed = 0;	/* force "link up" message */ +-	phy_start(port->phydev); ++	ixp4xx_phy_start(dev); +  + 	for (i = 0; i < ETH_ALEN; i++) + 		__raw_writel(dev->dev_addr[i], &port->regs->hw_addr[i]); +@@ -1127,7 +1173,7 @@ static int eth_close(struct net_device * + 		printk(KERN_CRIT "%s: unable to disable loopback\n", + 		       dev->name); +  +-	phy_stop(port->phydev); ++	ixp4xx_phy_stop(dev); +  + 	if (!ports_open) + 		qmgr_disable_irq(TXDONE_QUEUE); +@@ -1153,7 +1199,6 @@ static int __devinit eth_init_one(struct + 	struct net_device *dev; + 	struct eth_plat_info *plat = pdev->dev.platform_data; + 	u32 regs_phys; +-	char phy_id[MII_BUS_ID_SIZE + 3]; + 	int err; +  + 	if (!(dev = alloc_etherdev(sizeof(struct port)))) +@@ -1211,18 +1256,10 @@ static int __devinit eth_init_one(struct + 	__raw_writel(DEFAULT_CORE_CNTRL, &port->regs->core_control); + 	udelay(50); +  +-	snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, "0", plat->phy); +-	port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0, +-				   PHY_INTERFACE_MODE_MII); +-	if ((err = IS_ERR(port->phydev))) ++	err = ixp4xx_phy_connect(dev); ++	if (err) + 		goto err_free_mem; +  +-	/* mask with MAC supported features */ +-	port->phydev->supported &= PHY_BASIC_FEATURES; +-	port->phydev->advertising = port->phydev->supported; +- +-	port->phydev->irq = PHY_POLL; +- + 	if ((err = register_netdev(dev))) + 		goto err_phy_dis; +  +@@ -1249,7 +1286,7 @@ static int __devexit eth_remove_one(stru + 	struct net_device *dev = platform_get_drvdata(pdev); + 	struct port *port = netdev_priv(dev); +  +-	phy_disconnect(port->phydev); ++	ixp4xx_phy_disconnect(dev); + 	unregister_netdev(dev); + 	phy_disconnect(port->phydev); + 	npe_port_tab[NPE_ID(port->id)] = NULL; diff --git a/target/linux/ixp4xx/patches-2.6.31/206-npe_driver_add_update_link_function.patch b/target/linux/ixp4xx/patches-2.6.31/206-npe_driver_add_update_link_function.patch new file mode 100644 index 000000000..9529cce2c --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/206-npe_driver_add_update_link_function.patch @@ -0,0 +1,98 @@ +--- a/drivers/net/arm/ixp4xx_eth.c ++++ b/drivers/net/arm/ixp4xx_eth.c +@@ -168,7 +168,7 @@ struct port { + 	struct desc *desc_tab;	/* coherent */ + 	u32 desc_tab_phys; + 	int id;			/* logical port ID */ +-	int speed, duplex; ++	int link, speed, duplex; + 	u8 firmware[4]; + }; +  +@@ -365,37 +365,52 @@ static void ixp4xx_mdio_remove(void) + 	mdiobus_free(mdio_bus); + } +  +- +-static void ixp4xx_adjust_link(struct net_device *dev) ++static void ixp4xx_update_link(struct net_device *dev) + { + 	struct port *port = netdev_priv(dev); +-	struct phy_device *phydev = port->phydev; +  +-	if (!phydev->link) { +-		if (port->speed) { +-			port->speed = 0; +-			printk(KERN_INFO "%s: link down\n", dev->name); +-		} ++	if (!port->link) { ++		netif_carrier_off(dev); ++		printk(KERN_INFO "%s: link down\n", dev->name); + 		return; + 	} +  +-	if (port->speed == phydev->speed && port->duplex == phydev->duplex) +-		return; +- +-	port->speed = phydev->speed; +-	port->duplex = phydev->duplex; +- +-	if (port->duplex) ++	if (port->duplex == DUPLEX_FULL) + 		__raw_writel(DEFAULT_TX_CNTRL0 & ~TX_CNTRL0_HALFDUPLEX, + 			     &port->regs->tx_control[0]); + 	else + 		__raw_writel(DEFAULT_TX_CNTRL0 | TX_CNTRL0_HALFDUPLEX, + 			     &port->regs->tx_control[0]); +  ++	netif_carrier_on(dev); + 	printk(KERN_INFO "%s: link up, speed %u Mb/s, %s duplex\n", + 	       dev->name, port->speed, port->duplex ? "full" : "half"); + } +  ++static void ixp4xx_adjust_link(struct net_device *dev) ++{ ++	struct port *port = netdev_priv(dev); ++	struct phy_device *phydev = port->phydev; ++	int status_change = 0; ++ ++	if (phydev->link) { ++		if (port->duplex != phydev->duplex ++		    || port->speed != phydev->speed) { ++			status_change = 1; ++		} ++	} ++ ++	if (phydev->link != port->link) ++		status_change = 1; ++ ++	port->link = phydev->link; ++	port->speed = phydev->speed; ++	port->duplex = phydev->duplex; ++ ++	if (status_change) ++		ixp4xx_update_link(dev); ++} ++ + static int ixp4xx_phy_connect(struct net_device *dev) + { + 	struct port *port = netdev_priv(dev); +@@ -416,6 +431,10 @@ static int ixp4xx_phy_connect(struct net +  + 	port->phydev->irq = PHY_POLL; +  ++	port->link = 0; ++	port->speed = 0; ++	port->duplex = -1; ++ + 	printk(KERN_INFO "%s: MII PHY %i on %s\n", dev->name, plat->phy, + 	       npe_name(port->npe)); +  +@@ -433,7 +452,6 @@ static void ixp4xx_phy_start(struct net_ + { + 	struct port *port = netdev_priv(dev); +  +-	port->speed = 0;	/* force "link up" message */ + 	phy_start(port->phydev); + } +  diff --git a/target/linux/ixp4xx/patches-2.6.31/207-npe_driver_multiphy_support.patch b/target/linux/ixp4xx/patches-2.6.31/207-npe_driver_multiphy_support.patch new file mode 100644 index 000000000..3eefdcc8c --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/207-npe_driver_multiphy_support.patch @@ -0,0 +1,155 @@ +TODO: take care of additional PHYs through the PHY abstraction layer + +--- a/arch/arm/mach-ixp4xx/include/mach/platform.h ++++ b/arch/arm/mach-ixp4xx/include/mach/platform.h +@@ -72,7 +72,7 @@ extern unsigned long ixp4xx_exp_bus_size + /* +  * Clock Speed Definitions. +  */ +-#define IXP4XX_PERIPHERAL_BUS_CLOCK 	(66) /* 66Mhzi APB BUS   */  ++#define IXP4XX_PERIPHERAL_BUS_CLOCK 	(66) /* 66Mhzi APB BUS   */ + #define IXP4XX_UART_XTAL        	14745600 +  + /* +@@ -95,12 +95,23 @@ struct sys_timer; + #define IXP4XX_ETH_NPEB		0x10 + #define IXP4XX_ETH_NPEC		0x20 +  ++#define IXP4XX_ETH_PHY_MAX_ADDR	32 ++ + /* Information about built-in Ethernet MAC interfaces */ + struct eth_plat_info { + 	u8 phy;		/* MII PHY ID, 0 - 31 */ + 	u8 rxq;		/* configurable, currently 0 - 31 only */ + 	u8 txreadyq; + 	u8 hwaddr[6]; ++ ++	u32 phy_mask; ++#if 0 ++	int speed; ++	int duplex; ++#else ++	int speed_10; ++	int half_duplex; ++#endif + }; +  + /* Information about built-in HSS (synchronous serial) interfaces */ +--- a/drivers/net/arm/ixp4xx_eth.c ++++ b/drivers/net/arm/ixp4xx_eth.c +@@ -417,6 +417,37 @@ static int ixp4xx_phy_connect(struct net + 	struct eth_plat_info *plat = port->plat; + 	char phy_id[MII_BUS_ID_SIZE + 3]; +  ++	if (plat->phy == IXP4XX_ETH_PHY_MAX_ADDR) { ++#if 0 ++		switch (plat->speed) { ++		case SPEED_10: ++		case SPEED_100: ++			break; ++		default: ++			printk(KERN_ERR "%s: invalid speed (%d)\n", ++					dev->name, plat->speed); ++			return -EINVAL; ++		} ++ ++		switch (plat->duplex) { ++		case DUPLEX_HALF: ++		case DUPLEX_FULL: ++			break; ++		default: ++			printk(KERN_ERR "%s: invalid duplex mode (%d)\n", ++					dev->name, plat->duplex); ++			return -EINVAL; ++		} ++		port->speed = plat->speed; ++		port->duplex = plat->duplex; ++#else ++		port->speed = plat->speed_10 ? SPEED_10 : SPEED_100; ++		port->duplex = plat->half_duplex ? DUPLEX_HALF : DUPLEX_FULL; ++#endif ++ ++		return 0; ++	} ++ + 	snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, "0", plat->phy); + 	port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0, + 				   PHY_INTERFACE_MODE_MII); +@@ -445,21 +476,32 @@ static void ixp4xx_phy_disconnect(struct + { + 	struct port *port = netdev_priv(dev); +  +-	phy_disconnect(port->phydev); ++	if (port->phydev) ++		phy_disconnect(port->phydev); + } +  + static void ixp4xx_phy_start(struct net_device *dev) + { + 	struct port *port = netdev_priv(dev); +  +-	phy_start(port->phydev); ++	if (port->phydev) { ++		phy_start(port->phydev); ++	} else { ++		port->link = 1; ++		ixp4xx_update_link(dev); ++	} + } +  + static void ixp4xx_phy_stop(struct net_device *dev) + { + 	struct port *port = netdev_priv(dev); +  +-	phy_stop(port->phydev); ++	if (port->phydev) { ++		phy_stop(port->phydev); ++	} else { ++		port->link = 0; ++		ixp4xx_update_link(dev); ++	} + } +  + static inline void debug_pkt(struct net_device *dev, const char *func, +@@ -833,6 +875,10 @@ static int eth_ioctl(struct net_device * +  + 	if (!netif_running(dev)) + 		return -EINVAL; ++ ++	if (!port->phydev) ++		return -EOPNOTSUPP; ++ + 	return phy_mii_ioctl(port->phydev, if_mii(req), cmd); + } +  +@@ -852,18 +898,30 @@ static void ixp4xx_get_drvinfo(struct ne + static int ixp4xx_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) + { + 	struct port *port = netdev_priv(dev); ++ ++	if (!port->phydev) ++		return -EOPNOTSUPP; ++ + 	return phy_ethtool_gset(port->phydev, cmd); + } +  + static int ixp4xx_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) + { + 	struct port *port = netdev_priv(dev); ++ ++	if (!port->phydev) ++		return -EOPNOTSUPP; ++ + 	return phy_ethtool_sset(port->phydev, cmd); + } +  + static int ixp4xx_nway_reset(struct net_device *dev) + { + 	struct port *port = netdev_priv(dev); ++ ++	if (!port->phydev) ++		return -EOPNOTSUPP; ++ + 	return phy_start_aneg(port->phydev); + } +  diff --git a/target/linux/ixp4xx/patches-2.6.31/295-latch_led_driver.patch b/target/linux/ixp4xx/patches-2.6.31/295-latch_led_driver.patch new file mode 100644 index 000000000..853636d31 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/295-latch_led_driver.patch @@ -0,0 +1,200 @@ +--- a/drivers/leds/Kconfig ++++ b/drivers/leds/Kconfig +@@ -157,6 +157,13 @@ config LEDS_LP3944 + 	  To compile this driver as a module, choose M here: the + 	  module will be called leds-lp3944. +  ++config LEDS_LATCH ++	tristate "LED Support for Memory Latched LEDs" ++	depends on LEDS_CLASS ++	help ++		-- To Do -- ++ ++ + config LEDS_CLEVO_MAIL + 	tristate "Mail LED on Clevo notebook" + 	depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI +--- /dev/null ++++ b/drivers/leds/leds-latch.c +@@ -0,0 +1,149 @@ ++/* ++ * LEDs driver for Memory Latched Devices ++ * ++ * Copyright (C) 2008 Gateworks Corp. ++ * Chris Lang <clang@gateworks.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/kernel.h> ++#include <linux/init.h> ++#include <linux/platform_device.h> ++#include <linux/leds.h> ++#include <linux/workqueue.h> ++#include <asm/io.h> ++#include <linux/spinlock.h> ++ ++static unsigned int mem_keep = 0xFF; ++static spinlock_t mem_lock; ++static unsigned char *iobase; ++ ++struct latch_led_data { ++	struct led_classdev cdev; ++	struct work_struct work; ++	u8 new_level; ++	u8 bit; ++	void (*set_led)(u8 bit, enum led_brightness value); ++}; ++ ++static void latch_set_led(u8 bit, enum led_brightness value) ++{ ++	if (value == LED_OFF) ++		mem_keep |= (0x1 << bit); ++	else ++		mem_keep &= ~(0x1 << bit); ++ ++	writeb(mem_keep, iobase); ++} ++ ++static void latch_led_set(struct led_classdev *led_cdev, ++	enum led_brightness value) ++{ ++	struct latch_led_data *led_dat = ++		container_of(led_cdev, struct latch_led_data, cdev); ++ ++	spin_lock(mem_lock); ++ ++	led_dat->set_led(led_dat->bit, value); ++ ++	spin_unlock(mem_lock); ++} ++ ++static int latch_led_probe(struct platform_device *pdev) ++{ ++	struct latch_led_platform_data *pdata = pdev->dev.platform_data; ++	struct latch_led *cur_led; ++	struct latch_led_data *leds_data, *led_dat; ++	int i, ret = 0; ++ ++	if (!pdata) ++		return -EBUSY; ++ ++	leds_data = kzalloc(sizeof(struct latch_led_data) * pdata->num_leds, ++				GFP_KERNEL); ++	if (!leds_data) ++		return -ENOMEM; ++ ++	for (i = 0; i < pdata->num_leds; i++) { ++		cur_led = &pdata->leds[i]; ++		led_dat = &leds_data[i]; ++ ++		led_dat->cdev.name = cur_led->name; ++		led_dat->cdev.default_trigger = cur_led->default_trigger; ++		led_dat->cdev.brightness_set = latch_led_set; ++		led_dat->cdev.brightness = LED_OFF; ++		led_dat->bit = cur_led->bit; ++		led_dat->set_led = pdata->set_led ? pdata->set_led : latch_set_led; ++ ++		ret = led_classdev_register(&pdev->dev, &led_dat->cdev); ++		if (ret < 0) { ++			goto err; ++		} ++	} ++ ++	if (!pdata->set_led) { ++		iobase = ioremap_nocache(pdata->mem, 0x1000); ++		writeb(0xFF, iobase); ++	} ++	platform_set_drvdata(pdev, leds_data); ++ ++	return 0; ++ ++err: ++	if (i > 0) { ++		for (i = i - 1; i >= 0; i--) { ++			led_classdev_unregister(&leds_data[i].cdev); ++		} ++	} ++ ++	kfree(leds_data); ++ ++	return ret; ++} ++ ++static int __devexit latch_led_remove(struct platform_device *pdev) ++{ ++	int i; ++	struct latch_led_platform_data *pdata = pdev->dev.platform_data; ++	struct latch_led_data *leds_data; ++ ++	leds_data = platform_get_drvdata(pdev); ++ ++	for (i = 0; i < pdata->num_leds; i++) { ++		led_classdev_unregister(&leds_data[i].cdev); ++		cancel_work_sync(&leds_data[i].work); ++	} ++ ++	kfree(leds_data); ++ ++	return 0; ++} ++ ++static struct platform_driver latch_led_driver = { ++	.probe		= latch_led_probe, ++	.remove		= __devexit_p(latch_led_remove), ++	.driver		= { ++		.name	= "leds-latch", ++		.owner	= THIS_MODULE, ++	}, ++}; ++ ++static int __init latch_led_init(void) ++{ ++	return platform_driver_register(&latch_led_driver); ++} ++ ++static void __exit latch_led_exit(void) ++{ ++	platform_driver_unregister(&latch_led_driver); ++} ++ ++module_init(latch_led_init); ++module_exit(latch_led_exit); ++ ++MODULE_AUTHOR("Chris Lang <clang@gateworks.com>"); ++MODULE_DESCRIPTION("Latch LED driver"); ++MODULE_LICENSE("GPL"); +--- a/drivers/leds/Makefile ++++ b/drivers/leds/Makefile +@@ -20,6 +20,7 @@ obj-$(CONFIG_LEDS_COBALT_RAQ)		+= leds-c + obj-$(CONFIG_LEDS_SUNFIRE)		+= leds-sunfire.o + obj-$(CONFIG_LEDS_PCA9532)		+= leds-pca9532.o + obj-$(CONFIG_LEDS_GPIO)			+= leds-gpio.o ++obj-$(CONFIG_LEDS_LATCH)		+= leds-latch.o + obj-$(CONFIG_LEDS_LP3944)		+= leds-lp3944.o + obj-$(CONFIG_LEDS_CLEVO_MAIL)		+= leds-clevo-mail.o + obj-$(CONFIG_LEDS_HP6XX)		+= leds-hp6xx.o +--- a/include/linux/leds.h ++++ b/include/linux/leds.h +@@ -161,5 +161,19 @@ struct gpio_led_platform_data { + 					unsigned long *delay_off); + }; +  ++/* For the leds-latch driver */ ++struct latch_led { ++	const char *name; ++	char *default_trigger; ++	unsigned  bit; ++}; ++ ++struct latch_led_platform_data { ++	int     num_leds; ++	u32     mem; ++	struct latch_led *leds; ++	void	(*set_led)(u8 bit, enum led_brightness value); ++}; ++ +  + #endif		/* __LINUX_LEDS_H_INCLUDED */ diff --git a/target/linux/ixp4xx/patches-2.6.31/300-avila_fetch_mac.patch b/target/linux/ixp4xx/patches-2.6.31/300-avila_fetch_mac.patch new file mode 100644 index 000000000..ca8cae12c --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/300-avila_fetch_mac.patch @@ -0,0 +1,244 @@ +--- a/arch/arm/mach-ixp4xx/avila-setup.c ++++ b/arch/arm/mach-ixp4xx/avila-setup.c +@@ -14,10 +14,16 @@ + #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> ++#include <linux/i2c.h> ++#include <linux/i2c/at24.h> ++ + #include <linux/i2c-gpio.h> +  + #include <asm/types.h> +@@ -29,6 +35,13 @@ + #include <asm/mach/arch.h> + #include <asm/mach/flash.h> +  ++struct avila_board_info { ++	unsigned char	*model; ++	void		(*setup)(void); ++}; ++ ++static struct avila_board_info *avila_info __initdata; ++ + static struct flash_platform_data avila_flash_data = { + 	.map_name	= "cfi_probe", + 	.width		= 2, +@@ -132,16 +145,181 @@ static struct platform_device avila_pata + 	.resource		= avila_pata_resources, + }; +  ++/* Built-in 10/100 Ethernet MAC interfaces */ ++static struct eth_plat_info avila_npeb_data = { ++	.phy		= 0, ++	.rxq		= 3, ++	.txreadyq	= 20, ++}; ++ ++static struct eth_plat_info avila_npec_data = { ++	.phy		= 1, ++	.rxq		= 4, ++	.txreadyq	= 21, ++}; ++ ++static struct platform_device avila_npeb_device = { ++	.name			= "ixp4xx_eth", ++	.id			= IXP4XX_ETH_NPEB, ++	.dev.platform_data	= &avila_npeb_data, ++}; ++ ++static struct platform_device avila_npec_device = { ++	.name			= "ixp4xx_eth", ++	.id			= IXP4XX_ETH_NPEC, ++	.dev.platform_data	= &avila_npec_data, ++}; ++ + static struct platform_device *avila_devices[] __initdata = { + 	&avila_i2c_gpio, + 	&avila_flash, + 	&avila_uart + }; +  ++static void __init avila_gw23xx_setup(void) ++{ ++	platform_device_register(&avila_npeb_device); ++	platform_device_register(&avila_npec_device); ++} ++ ++static void __init avila_gw2342_setup(void) ++{ ++	platform_device_register(&avila_npeb_device); ++	platform_device_register(&avila_npec_device); ++} ++ ++static void __init avila_gw2345_setup(void) ++{ ++	avila_npeb_data.phy = IXP4XX_ETH_PHY_MAX_ADDR; ++	avila_npeb_data.phy_mask = 0x1e; /* ports 1-4 of the KS8995 switch */ ++	platform_device_register(&avila_npeb_device); ++ ++	avila_npec_data.phy = 5; /* port 5 of the KS8995 switch */ ++	platform_device_register(&avila_npec_device); ++} ++ ++static void __init avila_gw2347_setup(void) ++{ ++	platform_device_register(&avila_npeb_device); ++} ++ ++static void __init avila_gw2348_setup(void) ++{ ++	platform_device_register(&avila_npeb_device); ++	platform_device_register(&avila_npec_device); ++} ++ ++static void __init avila_gw2353_setup(void) ++{ ++	platform_device_register(&avila_npeb_device); ++} ++ ++static void __init avila_gw2355_setup(void) ++{ ++	avila_npeb_data.phy = IXP4XX_ETH_PHY_MAX_ADDR; ++	avila_npeb_data.phy_mask = 0x1e; /* ports 1-4 of the KS8995 switch */ ++	platform_device_register(&avila_npeb_device); ++ ++	avila_npec_data.phy = 16; ++	platform_device_register(&avila_npec_device); ++} ++ ++static void __init avila_gw2357_setup(void) ++{ ++	platform_device_register(&avila_npeb_device); ++} ++ ++static struct avila_board_info avila_boards[] __initdata = { ++	{ ++		.model		= "GW2342", ++		.setup		= avila_gw2342_setup, ++	}, { ++		.model		= "GW2345", ++		.setup		= avila_gw2345_setup, ++	}, { ++		.model		= "GW2347", ++		.setup		= avila_gw2347_setup, ++	}, { ++		.model		= "GW2348", ++		.setup		= avila_gw2348_setup, ++	}, { ++		.model		= "GW2353", ++		.setup		= avila_gw2353_setup, ++	}, { ++		.model		= "GW2355", ++		.setup		= avila_gw2355_setup, ++	}, { ++		.model		= "GW2357", ++		.setup		= avila_gw2357_setup, ++	} ++}; ++ ++static struct avila_board_info * __init avila_find_board_info(char *model) ++{ ++	int i; ++ ++	for (i = 0; i < ARRAY_SIZE(avila_boards); i++) { ++		struct avila_board_info *info = &avila_boards[i]; ++		if (strcmp(info->model, model) == 0) ++			return info; ++	} ++ ++	return NULL; ++} ++ ++static struct memory_accessor *at24_mem_acc; ++ ++static int at24_setup(struct memory_accessor *mem_acc, void *context) ++{ ++	char mac_addr[ETH_ALEN]; ++	char model[6]; ++ ++	at24_mem_acc = mem_acc; ++ ++	/* Read MAC addresses */ ++	if (at24_mem_acc->read(at24_mem_acc, mac_addr, 0x0, 6) == 6) { ++		memcpy(&avila_npeb_data.hwaddr, mac_addr, ETH_ALEN); ++	} ++	if (at24_mem_acc->read(at24_mem_acc, mac_addr, 0x6, 6) == 6) { ++		memcpy(&avila_npec_data.hwaddr, mac_addr, ETH_ALEN); ++	} ++ ++	/* Read the first 6 bytes of the model number */ ++	if (at24_mem_acc->read(at24_mem_acc, model, 0x20, 6) == 6) { ++		avila_info = avila_find_board_info(model); ++	} ++ ++	return 0; ++} ++ ++static struct at24_platform_data avila_eeprom_info = { ++	.byte_len	= 1024, ++	.page_size	= 16, ++	.flags		= AT24_FLAG_READONLY, ++	.setup		= at24_setup, ++}; ++ ++static struct i2c_board_info __initdata avila_i2c_board_info[] = { ++	{ ++		I2C_BOARD_INFO("ds1672", 0x68), ++	}, ++	{ ++		I2C_BOARD_INFO("ad7418", 0x28), ++	}, ++	{ ++		I2C_BOARD_INFO("24c08", 0x51), ++		.platform_data	= &avila_eeprom_info ++	}, ++}; ++ + static void __init avila_init(void) + { + 	ixp4xx_sys_init(); +  ++	/* ++	 * These devices are present on all Avila models and don't need any ++	 * model specific setup. ++	 */ + 	avila_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); + 	avila_flash_resource.end = + 		IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; +@@ -159,7 +337,28 @@ static void __init avila_init(void) +  + 	platform_device_register(&avila_pata); +  ++		i2c_register_board_info(0, avila_i2c_board_info, ++				ARRAY_SIZE(avila_i2c_board_info)); ++} ++ ++static int __init avila_model_setup(void) ++{ ++	if (!machine_is_avila()) ++		return 0; ++ ++	if (avila_info) { ++		printk(KERN_DEBUG "Running on Gateworks Avila %s\n", ++							avila_info->model); ++		avila_info->setup(); ++	} else { ++		printk(KERN_INFO "Unknown/missing Avila model number" ++						" -- defaults will be used\n"); ++		avila_gw23xx_setup(); ++	} ++ ++	return 0; + } ++late_initcall(avila_model_setup); +  + MACHINE_START(AVILA, "Gateworks Avila Network Platform") + 	/* Maintainer: Deepak Saxena <dsaxena@plexity.net> */ diff --git a/target/linux/ixp4xx/patches-2.6.31/301-avila_led.patch b/target/linux/ixp4xx/patches-2.6.31/301-avila_led.patch new file mode 100644 index 000000000..2bd0e1609 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/301-avila_led.patch @@ -0,0 +1,171 @@ +--- a/arch/arm/mach-ixp4xx/avila-setup.c ++++ b/arch/arm/mach-ixp4xx/avila-setup.c +@@ -24,6 +24,7 @@ + #include <linux/i2c.h> + #include <linux/i2c/at24.h> +  ++#include <linux/leds.h> + #include <linux/i2c-gpio.h> +  + #include <asm/types.h> +@@ -170,6 +171,72 @@ static struct platform_device avila_npec + 	.dev.platform_data	= &avila_npec_data, + }; +  ++static struct gpio_led avila_gpio_leds[] = { ++	{ ++		.name		= "user",  /* green led */ ++		.gpio		= AVILA_GW23XX_LED_USER_GPIO, ++		.active_low	= 1, ++	} ++}; ++ ++static struct gpio_led_platform_data avila_gpio_leds_data = { ++	.num_leds		= 1, ++	.leds			= avila_gpio_leds, ++}; ++ ++static struct platform_device avila_gpio_leds_device = { ++	.name			= "leds-gpio", ++	.id			= -1, ++	.dev.platform_data	= &avila_gpio_leds_data, ++}; ++ ++static struct latch_led avila_latch_leds[] = { ++	{ ++		.name	= "led0",  /* green led */ ++		.bit	= 0, ++	}, ++	{ ++		.name	= "led1",  /* green led */ ++		.bit	= 1, ++	}, ++	{ ++		.name	= "led2",  /* green led */ ++		.bit	= 2, ++	}, ++	{ ++		.name	= "led3",  /* green led */ ++		.bit	= 3, ++	}, ++	{ ++		.name	= "led4",  /* green led */ ++		.bit	= 4, ++	}, ++	{ ++		.name	= "led5",  /* green led */ ++		.bit	= 5, ++	}, ++	{ ++		.name	= "led6",  /* green led */ ++		.bit	= 6, ++	}, ++	{ ++		.name	= "led7",  /* green led */ ++		.bit	= 7, ++	} ++}; ++ ++static struct latch_led_platform_data avila_latch_leds_data = { ++	.num_leds	= 8, ++	.leds		= avila_latch_leds, ++	.mem		= 0x51000000, ++}; ++ ++static struct platform_device avila_latch_leds_device = { ++	.name			= "leds-latch", ++	.id			= -1, ++	.dev.platform_data	= &avila_latch_leds_data, ++}; ++ + static struct platform_device *avila_devices[] __initdata = { + 	&avila_i2c_gpio, + 	&avila_flash, +@@ -180,12 +247,16 @@ static void __init avila_gw23xx_setup(vo + { + 	platform_device_register(&avila_npeb_device); + 	platform_device_register(&avila_npec_device); ++ ++	platform_device_register(&avila_gpio_leds_device); + } +  + static void __init avila_gw2342_setup(void) + { + 	platform_device_register(&avila_npeb_device); + 	platform_device_register(&avila_npec_device); ++ ++	platform_device_register(&avila_gpio_leds_device); + } +  + static void __init avila_gw2345_setup(void) +@@ -196,22 +267,30 @@ static void __init avila_gw2345_setup(vo +  + 	avila_npec_data.phy = 5; /* port 5 of the KS8995 switch */ + 	platform_device_register(&avila_npec_device); ++ ++	platform_device_register(&avila_gpio_leds_device); + } +  + static void __init avila_gw2347_setup(void) + { + 	platform_device_register(&avila_npeb_device); ++ ++	avila_gpio_leds[0].gpio = AVILA_GW23X7_LED_USER_GPIO; ++	platform_device_register(&avila_gpio_leds_device); + } +  + static void __init avila_gw2348_setup(void) + { + 	platform_device_register(&avila_npeb_device); + 	platform_device_register(&avila_npec_device); ++ ++	platform_device_register(&avila_gpio_leds_device); + } +  + static void __init avila_gw2353_setup(void) + { + 	platform_device_register(&avila_npeb_device); ++	platform_device_register(&avila_gpio_leds_device); + } +  + static void __init avila_gw2355_setup(void) +@@ -222,11 +301,29 @@ static void __init avila_gw2355_setup(vo +  + 	avila_npec_data.phy = 16; + 	platform_device_register(&avila_npec_device); ++ ++	platform_device_register(&avila_gpio_leds_device); ++ ++	*IXP4XX_EXP_CS4 |= 0xbfff3c03; ++	avila_latch_leds[0].name = "RXD"; ++	avila_latch_leds[1].name = "TXD"; ++	avila_latch_leds[2].name = "POL"; ++	avila_latch_leds[3].name = "LNK"; ++	avila_latch_leds[4].name = "ERR"; ++	avila_latch_leds_data.num_leds = 5; ++	avila_latch_leds_data.mem = 0x54000000; ++	platform_device_register(&avila_latch_leds_device); + } +  + static void __init avila_gw2357_setup(void) + { + 	platform_device_register(&avila_npeb_device); ++ ++	avila_gpio_leds[0].gpio = AVILA_GW23X7_LED_USER_GPIO; ++	platform_device_register(&avila_gpio_leds_device); ++ ++	*IXP4XX_EXP_CS1 |= 0xbfff3c03; ++	platform_device_register(&avila_latch_leds_device); + } +  + static struct avila_board_info avila_boards[] __initdata = { +--- a/arch/arm/mach-ixp4xx/include/mach/avila.h ++++ b/arch/arm/mach-ixp4xx/include/mach/avila.h +@@ -36,4 +36,6 @@ + #define AVILA_PCI_INTC_PIN	9 + #define AVILA_PCI_INTD_PIN	8 +  +- ++/* User LEDs */ ++#define AVILA_GW23XX_LED_USER_GPIO	3 ++#define AVILA_GW23X7_LED_USER_GPIO	4 diff --git a/target/linux/ixp4xx/patches-2.6.31/302-avila_gpio_device.patch b/target/linux/ixp4xx/patches-2.6.31/302-avila_gpio_device.patch new file mode 100644 index 000000000..3b75a59f7 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/302-avila_gpio_device.patch @@ -0,0 +1,41 @@ +--- a/arch/arm/mach-ixp4xx/avila-setup.c ++++ b/arch/arm/mach-ixp4xx/avila-setup.c +@@ -237,10 +237,28 @@ static struct platform_device avila_latc + 	.dev.platform_data	= &avila_latch_leds_data, + }; +  ++static struct resource avila_gpio_resources[] = { ++	{ ++		.name	= "gpio", ++		/* FIXME: gpio mask should be model specific */ ++		.start	= AVILA_GPIO_MASK, ++		.end	= AVILA_GPIO_MASK, ++		.flags	= 0, ++	}, ++}; ++ ++static struct platform_device avila_gpio = { ++	.name			= "GPIODEV", ++	.id			= -1, ++	.num_resources		= ARRAY_SIZE(avila_gpio_resources), ++	.resource		= avila_gpio_resources, ++}; ++ + static struct platform_device *avila_devices[] __initdata = { + 	&avila_i2c_gpio, + 	&avila_flash, +-	&avila_uart ++	&avila_uart, ++	&avila_gpio, + }; +  + static void __init avila_gw23xx_setup(void) +--- a/arch/arm/mach-ixp4xx/include/mach/avila.h ++++ b/arch/arm/mach-ixp4xx/include/mach/avila.h +@@ -39,3 +39,6 @@ + /* User LEDs */ + #define AVILA_GW23XX_LED_USER_GPIO	3 + #define AVILA_GW23X7_LED_USER_GPIO	4 ++ ++/* gpio mask used by platform device */ ++#define AVILA_GPIO_MASK	(1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) diff --git a/target/linux/ixp4xx/patches-2.6.31/304-ixp4xx_eth_jumboframe.patch b/target/linux/ixp4xx/patches-2.6.31/304-ixp4xx_eth_jumboframe.patch new file mode 100644 index 000000000..d3d8af6ab --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/304-ixp4xx_eth_jumboframe.patch @@ -0,0 +1,80 @@ +--- a/drivers/net/arm/ixp4xx_eth.c ++++ b/drivers/net/arm/ixp4xx_eth.c +@@ -52,7 +52,7 @@ +  + #define POOL_ALLOC_SIZE		(sizeof(struct desc) * (RX_DESCS + TX_DESCS)) + #define REGS_SIZE		0x1000 +-#define MAX_MRU			1536 /* 0x600 */ ++#define MAX_MRU			(16320 - ETH_HLEN - ETH_FCS_LEN) + #define RX_BUFF_SIZE		ALIGN((NET_IP_ALIGN) + MAX_MRU, 4) +  + #define NAPI_WEIGHT		16 +@@ -1068,6 +1068,32 @@ static void destroy_queues(struct port * + 	} + } +  ++static int eth_do_change_mtu(struct net_device *dev, int mtu) ++{ ++	struct port *port; ++	struct msg msg; ++	/* adjust for ethernet headers */ ++	int framesize = mtu + ETH_HLEN + ETH_FCS_LEN; ++ ++	port = netdev_priv(dev); ++ ++	memset(&msg, 0, sizeof(msg)); ++	msg.cmd = NPE_SETMAXFRAMELENGTHS; ++	msg.eth_id = port->id; ++ ++	/* max rx/tx 64 byte blocks */ ++	msg.byte2 = ((framesize + 63) / 64) << 8; ++	msg.byte3 = ((framesize + 63) / 64) << 8; ++ ++	msg.byte4 = msg.byte6 = framesize >> 8; ++	msg.byte5 = msg.byte7 = framesize & 0xff; ++ ++	if (npe_send_recv_message(port->npe, &msg, "ETH_SET_MAX_FRAME_LENGTH")) ++		return -EIO; ++ ++	return 0; ++} ++ + static int eth_open(struct net_device *dev) + { + 	struct port *port = netdev_priv(dev); +@@ -1119,6 +1145,8 @@ static int eth_open(struct net_device *d + 	if (npe_send_recv_message(port->npe, &msg, "ETH_SET_FIREWALL_MODE")) + 		return -EIO; +  ++	eth_do_change_mtu(dev, dev->mtu); ++ + 	if ((err = request_queues(port)) != 0) + 		return err; +  +@@ -1258,7 +1286,26 @@ static int eth_close(struct net_device * + 	return 0; + } +  ++static int ixp_eth_change_mtu(struct net_device *dev, int mtu) ++{ ++	int ret; ++ ++	if (mtu > MAX_MRU) ++		return -EINVAL; ++ ++	if (dev->flags & IFF_UP) { ++		ret = eth_do_change_mtu(dev, mtu); ++		if (ret < 0) ++			return ret; ++	} ++ ++	dev->mtu = mtu; ++ ++	return 0; ++} ++ + static const struct net_device_ops ixp4xx_netdev_ops = { ++	.ndo_change_mtu = ixp_eth_change_mtu, + 	.ndo_open = eth_open, + 	.ndo_stop = eth_close, + 	.ndo_start_xmit = eth_xmit, diff --git a/target/linux/ixp4xx/patches-2.6.31/310-gtwx5717_spi_bus.patch b/target/linux/ixp4xx/patches-2.6.31/310-gtwx5717_spi_bus.patch new file mode 100644 index 000000000..e6013d758 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/310-gtwx5717_spi_bus.patch @@ -0,0 +1,53 @@ +--- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c ++++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c +@@ -29,6 +29,8 @@ + #include <linux/serial_8250.h> + #include <linux/slab.h> +  ++#include <linux/spi/spi_gpio_old.h> ++ + #include <asm/types.h> + #include <asm/setup.h> + #include <asm/memory.h> +@@ -121,9 +123,41 @@ static struct platform_device gtwx5715_f + 	.resource	= >wx5715_flash_resource, + }; +  ++static int gtwx5715_spi_boardinfo_setup(struct spi_board_info *bi, ++		struct spi_master *master, void *data) ++{ ++ ++	strlcpy(bi->modalias, "spi-ks8995", sizeof(bi->modalias)); ++ ++	bi->max_speed_hz = 5000000 /* Hz */; ++	bi->bus_num = master->bus_num; ++	bi->mode = SPI_MODE_0; ++ ++	return 0; ++} ++ ++static struct spi_gpio_platform_data gtwx5715_spi_bus_data = { ++	.pin_cs			= GTWX5715_KSSPI_SELECT, ++	.pin_clk		= GTWX5715_KSSPI_CLOCK, ++	.pin_miso		= GTWX5715_KSSPI_RXD, ++	.pin_mosi		= GTWX5715_KSSPI_TXD, ++	.cs_activelow		= 1, ++	.no_spi_delay		= 1, ++	.boardinfo_setup	= gtwx5715_spi_boardinfo_setup, ++}; ++ ++static struct platform_device gtwx5715_spi_bus = { ++	.name		= "spi-gpio", ++	.id		= 0, ++	.dev		= { ++		.platform_data = >wx5715_spi_bus_data, ++	}, ++}; ++ + static struct platform_device *gtwx5715_devices[] __initdata = { + 	>wx5715_uart_device, + 	>wx5715_flash, ++	>wx5715_spi_bus, + }; +  + static void __init gtwx5715_init(void) diff --git a/target/linux/ixp4xx/patches-2.6.31/311-gtwx5717_mac_plat_info.patch b/target/linux/ixp4xx/patches-2.6.31/311-gtwx5717_mac_plat_info.patch new file mode 100644 index 000000000..29f329017 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/311-gtwx5717_mac_plat_info.patch @@ -0,0 +1,40 @@ +--- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c ++++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c +@@ -154,10 +154,37 @@ static struct platform_device gtwx5715_s + 	}, + }; +  ++static struct eth_plat_info gtwx5715_npeb_data = { ++	.phy		= IXP4XX_ETH_PHY_MAX_ADDR, ++	.phy_mask	= 0x1e, /* ports 1-4 of the KS8995 switch */ ++	.rxq		= 3, ++	.txreadyq	= 20, ++}; ++ ++static struct eth_plat_info gtwx5715_npec_data = { ++	.phy		= 5,	/* port 5 of the KS8995 switch */ ++	.rxq		= 4, ++	.txreadyq	= 21, ++}; ++ ++static struct platform_device gtwx5715_npeb_device = { ++	.name			= "ixp4xx_eth", ++	.id			= IXP4XX_ETH_NPEB, ++	.dev.platform_data	= >wx5715_npeb_data, ++}; ++ ++static struct platform_device gtwx5715_npec_device = { ++	.name			= "ixp4xx_eth", ++	.id			= IXP4XX_ETH_NPEC, ++	.dev.platform_data	= >wx5715_npec_data, ++}; ++ + static struct platform_device *gtwx5715_devices[] __initdata = { + 	>wx5715_uart_device, + 	>wx5715_flash, + 	>wx5715_spi_bus, ++	>wx5715_npeb_device, ++	>wx5715_npec_device, + }; +  + static void __init gtwx5715_init(void) diff --git a/target/linux/ixp4xx/patches-2.6.31/312-ixp4xx_pata_optimization.patch b/target/linux/ixp4xx/patches-2.6.31/312-ixp4xx_pata_optimization.patch new file mode 100644 index 000000000..3bf1b7497 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/312-ixp4xx_pata_optimization.patch @@ -0,0 +1,137 @@ +--- a/drivers/ata/pata_ixp4xx_cf.c ++++ b/drivers/ata/pata_ixp4xx_cf.c +@@ -24,16 +24,58 @@ + #include <scsi/scsi_host.h> +  + #define DRV_NAME	"pata_ixp4xx_cf" +-#define DRV_VERSION	"0.2" ++#define DRV_VERSION	"0.3" +  + static int ixp4xx_set_mode(struct ata_link *link, struct ata_device **error) + { + 	struct ata_device *dev; ++	struct ixp4xx_pata_data *data = link->ap->host->dev->platform_data; ++	unsigned int pio_mask; +  + 	ata_for_each_dev(dev, link, ENABLED) { +-		ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n"); +-		dev->pio_mode = XFER_PIO_0; +-		dev->xfer_mode = XFER_PIO_0; ++		if (dev->id[ATA_ID_FIELD_VALID] & (1 << 1)) { ++			pio_mask = dev->id[ATA_ID_PIO_MODES] & 0x03; ++			if (pio_mask & (1 << 1)) { ++				pio_mask = 4; ++			} else { ++				pio_mask = 3; ++			} ++		} else { ++			pio_mask = (dev->id[ATA_ID_OLD_PIO_MODES] >> 8); ++		} ++ ++		switch (pio_mask){ ++			case 0: ++				ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n"); ++				dev->pio_mode = XFER_PIO_0; ++				dev->xfer_mode = XFER_PIO_0; ++				*data->cs0_cfg = 0x8a473c03; ++				break; ++			case 1: ++				ata_dev_printk(dev, KERN_INFO, "configured for PIO1\n"); ++				dev->pio_mode = XFER_PIO_1; ++				dev->xfer_mode = XFER_PIO_1; ++				*data->cs0_cfg = 0x86433c03; ++				break; ++			case 2: ++				ata_dev_printk(dev, KERN_INFO, "configured for PIO2\n"); ++				dev->pio_mode = XFER_PIO_2; ++				dev->xfer_mode = XFER_PIO_2; ++				*data->cs0_cfg = 0x82413c03; ++				break; ++			case 3: ++				ata_dev_printk(dev, KERN_INFO, "configured for PIO3\n"); ++				dev->pio_mode = XFER_PIO_3; ++				dev->xfer_mode = XFER_PIO_3; ++				*data->cs0_cfg = 0x80823c03; ++				break; ++			case 4: ++				ata_dev_printk(dev, KERN_INFO, "configured for PIO4\n"); ++				dev->pio_mode = XFER_PIO_4; ++				dev->xfer_mode = XFER_PIO_4; ++				*data->cs0_cfg = 0x80403c03; ++				break; ++		} + 		dev->xfer_shift = ATA_SHIFT_PIO; + 		dev->flags |= ATA_DFLAG_PIO; + 	} +@@ -46,6 +88,7 @@ static unsigned int ixp4xx_mmio_data_xfe + 	unsigned int i; + 	unsigned int words = buflen >> 1; + 	u16 *buf16 = (u16 *) buf; ++	unsigned int pio_mask; + 	struct ata_port *ap = dev->link->ap; + 	void __iomem *mmio = ap->ioaddr.data_addr; + 	struct ixp4xx_pata_data *data = ap->host->dev->platform_data; +@@ -53,8 +96,34 @@ static unsigned int ixp4xx_mmio_data_xfe + 	/* set the expansion bus in 16bit mode and restore + 	 * 8 bit mode after the transaction. + 	 */ +-	*data->cs0_cfg &= ~(0x01); +-	udelay(100); ++	if (dev->id[ATA_ID_FIELD_VALID] & (1 << 1)){ ++		pio_mask = dev->id[ATA_ID_PIO_MODES] & 0x03; ++		if (pio_mask & (1 << 1)){ ++			pio_mask = 4; ++		}else{ ++			pio_mask = 3; ++		} ++	}else{ ++		pio_mask = (dev->id[ATA_ID_OLD_PIO_MODES] >> 8); ++	} ++	switch (pio_mask){ ++		case 0: ++			*data->cs0_cfg = 0xa9643c42; ++		break; ++		case 1: ++			*data->cs0_cfg = 0x85033c42; ++		break; ++		case 2: ++			*data->cs0_cfg = 0x80b23c42; ++		break; ++		case 3: ++			*data->cs0_cfg = 0x80823c42; ++		break; ++		case 4: ++			*data->cs0_cfg = 0x80403c42; ++		break; ++	} ++	udelay(5); +  + 	/* Transfer multiple of 2 bytes */ + 	if (rw == READ) +@@ -79,8 +148,24 @@ static unsigned int ixp4xx_mmio_data_xfe + 		words++; + 	} +  +-	udelay(100); +-	*data->cs0_cfg |= 0x01; ++	udelay(5); ++	switch (pio_mask){ ++		case 0: ++			*data->cs0_cfg = 0x8a473c03; ++		break; ++		case 1: ++			*data->cs0_cfg = 0x86433c03; ++		break; ++		case 2: ++			*data->cs0_cfg = 0x82413c03; ++		break; ++		case 3: ++			*data->cs0_cfg = 0x80823c03; ++		break; ++		case 4: ++			*data->cs0_cfg = 0x80403c03; ++		break; ++	} +  + 	return words << 1; + } diff --git a/target/linux/ixp4xx/patches-2.6.31/401-avila_pci_dev.patch b/target/linux/ixp4xx/patches-2.6.31/401-avila_pci_dev.patch new file mode 100644 index 000000000..3e5087f34 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/401-avila_pci_dev.patch @@ -0,0 +1,11 @@ +--- a/arch/arm/mach-ixp4xx/include/mach/avila.h ++++ b/arch/arm/mach-ixp4xx/include/mach/avila.h +@@ -25,7 +25,7 @@ + /* +  * AVILA PCI IRQs +  */ +-#define AVILA_PCI_MAX_DEV	4 ++#define AVILA_PCI_MAX_DEV	6 + #define LOFT_PCI_MAX_DEV    6 + #define AVILA_PCI_IRQ_LINES	4 +  diff --git a/target/linux/ixp4xx/patches-2.6.31/402-ixp4xx_gpiolib.patch b/target/linux/ixp4xx/patches-2.6.31/402-ixp4xx_gpiolib.patch new file mode 100644 index 000000000..b148d96b4 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/402-ixp4xx_gpiolib.patch @@ -0,0 +1,125 @@ +--- a/arch/arm/mach-ixp4xx/common.c ++++ b/arch/arm/mach-ixp4xx/common.c +@@ -36,6 +36,7 @@ + #include <asm/pgtable.h> + #include <asm/page.h> + #include <asm/irq.h> ++#include <asm/gpio.h> +  + #include <asm/mach/map.h> + #include <asm/mach/irq.h> +@@ -374,12 +375,39 @@ static struct platform_device *ixp46x_de + unsigned long ixp4xx_exp_bus_size; + EXPORT_SYMBOL(ixp4xx_exp_bus_size); +  ++static int ixp4xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) ++{ ++	gpio_line_config(gpio, IXP4XX_GPIO_IN); ++	return 0; ++} ++EXPORT_SYMBOL(ixp4xx_gpio_direction_input); ++ ++static int ixp4xx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int level) ++{ ++	gpio_line_set(gpio, level); ++	gpio_line_config(gpio, IXP4XX_GPIO_OUT); ++	return 0; ++} ++EXPORT_SYMBOL(ixp4xx_gpio_direction_output); ++ ++static struct gpio_chip ixp4xx_gpio_chip = { ++	.label			= "IXP4XX_GPIO_CHIP", ++	.direction_input	= ixp4xx_gpio_direction_input, ++	.direction_output	= ixp4xx_gpio_direction_output, ++	.get			= gpio_get_value, ++	.set			= gpio_set_value, ++	.base			= 0, ++	.ngpio			= 16, ++}; ++ + void __init ixp4xx_sys_init(void) + { + 	ixp4xx_exp_bus_size = SZ_16M; +  + 	platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices)); +  ++	gpiochip_add(&ixp4xx_gpio_chip); ++ + 	if (cpu_is_ixp46x()) { + 		int region; +  +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -384,6 +384,7 @@ config ARCH_IXP4XX + 	select GENERIC_GPIO + 	select GENERIC_TIME + 	select GENERIC_CLOCKEVENTS ++	select ARCH_REQUIRE_GPIOLIB + 	help + 	  Support for Intel's IXP4XX (XScale) family of processors. +  +--- a/arch/arm/mach-ixp4xx/include/mach/gpio.h ++++ b/arch/arm/mach-ixp4xx/include/mach/gpio.h +@@ -27,47 +27,31 @@ +  + #include <linux/kernel.h> + #include <mach/hardware.h> ++#include <asm-generic/gpio.h>			/* cansleep wrappers */ +  +-static inline int gpio_request(unsigned gpio, const char *label) +-{ +-	return 0; +-} +- +-static inline void gpio_free(unsigned gpio) +-{ +-	might_sleep(); +- +-	return; +-} +- +-static inline int gpio_direction_input(unsigned gpio) +-{ +-	gpio_line_config(gpio, IXP4XX_GPIO_IN); +-	return 0; +-} +- +-static inline int gpio_direction_output(unsigned gpio, int level) +-{ +-	gpio_line_set(gpio, level); +-	gpio_line_config(gpio, IXP4XX_GPIO_OUT); +-	return 0; +-} ++#define NR_BUILTIN_GPIO 16 +  + static inline int gpio_get_value(unsigned gpio) + { +-	int value; +- +-	gpio_line_get(gpio, &value); +- +-	return value; ++	if (gpio < NR_BUILTIN_GPIO) ++	{ ++		int value; ++		gpio_line_get(gpio, &value); ++		return value; ++	} ++	else ++		return __gpio_get_value(gpio); + } +  + static inline void gpio_set_value(unsigned gpio, int value) + { +-	gpio_line_set(gpio, value); ++	if (gpio < NR_BUILTIN_GPIO) ++		gpio_line_set(gpio, value); ++	else ++		__gpio_set_value(gpio, value); + } +  +-#include <asm-generic/gpio.h>			/* cansleep wrappers */ ++#define gpio_cansleep __gpio_cansleep +  + extern int gpio_to_irq(int gpio); + extern int irq_to_gpio(int gpio); diff --git a/target/linux/ixp4xx/patches-2.6.31/500-usr8200_support.patch b/target/linux/ixp4xx/patches-2.6.31/500-usr8200_support.patch new file mode 100644 index 000000000..2d78425f4 --- /dev/null +++ b/target/linux/ixp4xx/patches-2.6.31/500-usr8200_support.patch @@ -0,0 +1,342 @@ +--- a/arch/arm/mach-ixp4xx/Kconfig ++++ b/arch/arm/mach-ixp4xx/Kconfig +@@ -97,6 +97,14 @@ config MACH_SIDEWINDER + 	  Engineering Sidewinder board. For more information on this + 	  platform, see http://www.adiengineering.com +  ++config MACH_USR8200 ++	bool "USRobotics USR8200" ++	select PCI ++	help ++	  Say 'Y' here if you want your kernel to support the USRobotics ++	  USR8200 router board. For more information on this platform, see ++	  http://openwrt.org ++ + config MACH_COMPEX + 	bool "Compex WP18 / NP18A" + 	select PCI +--- a/arch/arm/mach-ixp4xx/Makefile ++++ b/arch/arm/mach-ixp4xx/Makefile +@@ -25,6 +25,7 @@ obj-pci-$(CONFIG_MACH_WRT300NV2)		+= wrt + obj-pci-$(CONFIG_MACH_AP1000)		+= ixdp425-pci.o + obj-pci-$(CONFIG_MACH_TW5334)		+= tw5334-pci.o + obj-pci-$(CONFIG_MACH_MI424WR)		+= mi424wr-pci.o ++obj-pci-$(CONFIG_MACH_USR8200)		+= usr8200-pci.o +  + obj-y	+= common.o +  +@@ -49,6 +50,7 @@ obj-$(CONFIG_MACH_WRT300NV2)	+= wrt300nv + obj-$(CONFIG_MACH_AP1000)	+= ap1000-setup.o + obj-$(CONFIG_MACH_TW5334)	+= tw5334-setup.o + obj-$(CONFIG_MACH_MI424WR)	+= mi424wr-setup.o ++obj-$(CONFIG_MACH_USR8200)	+= usr8200-setup.o +  + obj-$(CONFIG_PCI)		+= $(obj-pci-$(CONFIG_PCI)) common-pci.o + obj-$(CONFIG_IXP4XX_QMGR)	+= ixp4xx_qmgr.o +--- /dev/null ++++ b/arch/arm/mach-ixp4xx/usr8200-pci.c +@@ -0,0 +1,78 @@ ++/* ++ * arch/arch/mach-ixp4xx/usr8200-pci.c ++ * ++ * PCI setup routines for USRobotics USR8200 ++ * ++ * Copyright (C) 2008 Peter Denison <openwrt@marshadder.org> ++ * ++ * based on pronghorn-pci.c ++ * 	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: Peter Denison <openwrt@marshadder.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 <mach/hardware.h> ++ ++#include <asm/mach/pci.h> ++ ++void __init usr8200_pci_preinit(void) ++{ ++	set_irq_type(IRQ_IXP4XX_GPIO7, IRQ_TYPE_LEVEL_LOW); ++	set_irq_type(IRQ_IXP4XX_GPIO8, IRQ_TYPE_LEVEL_LOW); ++	set_irq_type(IRQ_IXP4XX_GPIO9, IRQ_TYPE_LEVEL_LOW); ++	set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW); ++	set_irq_type(IRQ_IXP4XX_GPIO11, IRQ_TYPE_LEVEL_LOW); ++ ++	ixp4xx_pci_preinit(); ++} ++ ++static int __init usr8200_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++	if (slot == 14) ++		return IRQ_IXP4XX_GPIO7; ++	else if (slot == 15) ++		return IRQ_IXP4XX_GPIO8; ++	else if (slot == 16) { ++		if (pin == 1) ++			return IRQ_IXP4XX_GPIO11; ++		else if (pin == 2) ++			return IRQ_IXP4XX_GPIO10; ++		else if (pin == 3) ++			return IRQ_IXP4XX_GPIO9; ++		else ++			return -1; ++	} else ++		return -1; ++} ++ ++struct hw_pci usr8200_pci __initdata = { ++	.nr_controllers	= 1, ++	.preinit	= usr8200_pci_preinit, ++	.swizzle	= pci_std_swizzle, ++	.setup		= ixp4xx_setup, ++	.scan		= ixp4xx_scan_bus, ++	.map_irq	= usr8200_map_irq, ++}; ++ ++int __init usr8200_pci_init(void) ++{ ++	if (machine_is_usr8200()) ++		pci_common_init(&usr8200_pci); ++	return 0; ++} ++ ++subsys_initcall(usr8200_pci_init); +--- /dev/null ++++ b/arch/arm/mach-ixp4xx/usr8200-setup.c +@@ -0,0 +1,212 @@ ++/* ++ * arch/arm/mach-ixp4xx/usr8200-setup.c ++ * ++ * Board setup for the USRobotics USR8200 ++ * ++ * Copyright (C) 2008 Peter Denison <openwrt@marshadder.org> ++ * ++ * based on pronghorn-setup.c: ++ * 	Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> ++ * based on coyote-setup.c: ++ *      Copyright (C) 2003-2005 MontaVista Software, Inc. ++ * ++ * Author: Peter Denison <openwrt@marshadder.org> ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/device.h> ++#include <linux/serial.h> ++#include <linux/tty.h> ++#include <linux/serial_8250.h> ++#include <linux/slab.h> ++#include <linux/types.h> ++#include <linux/memory.h> ++#include <linux/i2c-gpio.h> ++#include <linux/leds.h> ++ ++#include <asm/setup.h> ++#include <mach/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 usr8200_flash_data = { ++	.map_name	= "cfi_probe", ++	.width		= 2, ++}; ++ ++static struct resource usr8200_flash_resource = { ++	.flags		= IORESOURCE_MEM, ++}; ++ ++static struct platform_device usr8200_flash = { ++	.name		= "IXP4XX-Flash", ++	.id		= 0, ++	.dev		= { ++		.platform_data	= &usr8200_flash_data, ++	}, ++	.num_resources	= 1, ++	.resource	= &usr8200_flash_resource, ++}; ++ ++static struct resource usr8200_uart_resources [] = { ++	{ ++		.start		= IXP4XX_UART2_BASE_PHYS, ++		.end		= IXP4XX_UART2_BASE_PHYS + 0x0fff, ++		.flags		= IORESOURCE_MEM ++	}, ++	{ ++		.start		= IXP4XX_UART1_BASE_PHYS, ++		.end		= IXP4XX_UART1_BASE_PHYS + 0x0fff, ++		.flags		= IORESOURCE_MEM ++	} ++}; ++ ++static struct plat_serial8250_port usr8200_uart_data[] = { ++	{ ++		.mapbase	= IXP4XX_UART2_BASE_PHYS, ++		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, ++		.irq		= IRQ_IXP4XX_UART2, ++		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, ++		.iotype		= UPIO_MEM, ++		.regshift	= 2, ++		.uartclk	= IXP4XX_UART_XTAL, ++	}, ++	{ ++		.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 usr8200_uart = { ++	.name		= "serial8250", ++	.id		= PLAT8250_DEV_PLATFORM, ++	.dev		= { ++		.platform_data	= usr8200_uart_data, ++	}, ++	.num_resources	= 2, ++	.resource	= usr8200_uart_resources, ++}; ++ ++static struct gpio_led usr8200_led_pin[] = { ++	{ ++		.name		= "usr8200:usb1", ++		.gpio		= 0, ++		.active_low	= 1, ++	}, ++	{ ++		.name		= "usr8200:usb2", ++		.gpio		= 1, ++		.active_low	= 1, ++	}, ++	{ ++		.name		= "usr8200:ieee1394", ++		.gpio		= 2, ++		.active_low	= 1, ++	}, ++	{ ++		.name		= "usr8200:internal", ++		.gpio		= 3, ++		.active_low	= 1, ++	}, ++	{ ++		.name		= "usr8200:power", ++		.gpio		= 14, ++	} ++}; ++ ++static struct gpio_led_platform_data usr8200_led_data = { ++	.num_leds		= ARRAY_SIZE(usr8200_led_pin), ++	.leds			= usr8200_led_pin, ++}; ++ ++static struct platform_device usr8200_led = { ++	.name			= "leds-gpio", ++	.id			= -1, ++	.dev.platform_data	= &usr8200_led_data, ++}; ++ ++static struct eth_plat_info usr8200_plat_eth[] = { ++	{ /* NPEC - LAN with Marvell 88E6060 switch */ ++		.phy		= IXP4XX_ETH_PHY_MAX_ADDR, ++		.phy_mask	= 0x0F0000, ++		.rxq		= 4, ++		.txreadyq	= 21, ++	}, { /* NPEB - WAN */ ++		.phy		= 9, ++		.rxq		= 3, ++		.txreadyq	= 20, ++	} ++}; ++ ++static struct platform_device usr8200_eth[] = { ++	{ ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEC, ++		.dev.platform_data	= usr8200_plat_eth, ++	}, { ++		.name			= "ixp4xx_eth", ++		.id			= IXP4XX_ETH_NPEB, ++		.dev.platform_data	= usr8200_plat_eth + 1, ++	} ++}; ++ ++static struct resource usr8200_rtc_resources = { ++	.flags		= IORESOURCE_MEM ++}; ++ ++static struct platform_device usr8200_rtc = { ++	.name		= "rtc7301", ++	.id		= 0, ++	.num_resources	= 1, ++	.resource	= &usr8200_rtc_resources, ++}; ++ ++static struct platform_device *usr8200_devices[] __initdata = { ++	&usr8200_flash, ++	&usr8200_uart, ++	&usr8200_led, ++	&usr8200_eth[0], ++	&usr8200_eth[1], ++	&usr8200_rtc, ++}; ++ ++static void __init usr8200_init(void) ++{ ++	ixp4xx_sys_init(); ++ ++	usr8200_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); ++	usr8200_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_16M - 1; ++ ++	usr8200_rtc_resources.start = IXP4XX_EXP_BUS_BASE(2); ++	usr8200_rtc_resources.end = IXP4XX_EXP_BUS_BASE(2) + 0x01ff; ++ ++	*IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE; ++	*IXP4XX_EXP_CS2 = 0x3fff000 | IXP4XX_EXP_BUS_SIZE(0) | IXP4XX_EXP_BUS_WR_EN | ++	                  IXP4XX_EXP_BUS_CS_EN | IXP4XX_EXP_BUS_BYTE_EN; ++	*IXP4XX_GPIO_GPCLKR = 0x01100000; ++ ++	/* configure button as input */ ++	gpio_line_config(12, IXP4XX_GPIO_IN); ++ ++	platform_add_devices(usr8200_devices, ARRAY_SIZE(usr8200_devices)); ++} ++ ++MACHINE_START(USR8200, "USRobotics USR8200") ++	/* Maintainer: Peter Denison <openwrt@marshadder.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	= usr8200_init, ++MACHINE_END +--- a/arch/arm/mach-ixp4xx/include/mach/uncompress.h ++++ b/arch/arm/mach-ixp4xx/include/mach/uncompress.h +@@ -43,7 +43,7 @@ static __inline__ void __arch_decomp_set + 	if (machine_is_adi_coyote() || machine_is_gtwx5715() || + 			 machine_is_gateway7001() || machine_is_wg302v2() || + 			 machine_is_pronghorn() || machine_is_pronghorn_metro() || machine_is_wrt300nv2() || +-			 machine_is_tw5334()) ++			 machine_is_tw5334() || machine_is_usr8200()) + 		uart_base = (volatile u32*) IXP4XX_UART2_BASE_PHYS; + 	else + 		uart_base = (volatile u32*) IXP4XX_UART1_BASE_PHYS; | 
