diff options
Diffstat (limited to 'target/linux/ar7/patches-2.6.30')
8 files changed, 812 insertions, 0 deletions
| diff --git a/target/linux/ar7/patches-2.6.30/100-board_support.patch b/target/linux/ar7/patches-2.6.30/100-board_support.patch new file mode 100644 index 000000000..c3fad1653 --- /dev/null +++ b/target/linux/ar7/patches-2.6.30/100-board_support.patch @@ -0,0 +1,86 @@ +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -19,6 +19,24 @@ choice + 	prompt "System type" + 	default SGI_IP22 +  ++config AR7 ++	bool "Texas Instruments AR7" ++	select BOOT_ELF32 ++	select DMA_NONCOHERENT ++	select CEVT_R4K ++	select CSRC_R4K ++	select IRQ_CPU ++	select NO_EXCEPT_FILL ++	select SWAP_IO_SPACE ++	select SYS_HAS_CPU_MIPS32_R1 ++	select SYS_HAS_EARLY_PRINTK ++	select SYS_SUPPORTS_32BIT_KERNEL ++	select SYS_SUPPORTS_KGDB ++	select SYS_SUPPORTS_LITTLE_ENDIAN ++	select SYS_SUPPORTS_BIG_ENDIAN ++	select GENERIC_GPIO ++	select GENERIC_HARDIRQS_NO__DO_IRQ ++ + config MACH_ALCHEMY + 	bool "Alchemy processor based machines" +  +--- a/arch/mips/kernel/traps.c ++++ b/arch/mips/kernel/traps.c +@@ -1203,9 +1203,22 @@ void *set_except_vector(int n, void *add +  + 	exception_handlers[n] = handler; + 	if (n == 0 && cpu_has_divec) { +-		*(u32 *)(ebase + 0x200) = 0x08000000 | +-					  (0x03ffffff & (handler >> 2)); +-		local_flush_icache_range(ebase + 0x200, ebase + 0x204); ++		if ((handler ^ (ebase + 4)) & 0xfc000000) { ++			/* lui k0, 0x0000 */ ++			*(u32 *)(ebase + 0x200) = 0x3c1a0000 | (handler >> 16); ++			/* ori k0, 0x0000 */ ++			*(u32 *)(ebase + 0x204) = ++					0x375a0000 | (handler & 0xffff); ++			/* jr k0 */ ++			*(u32 *)(ebase + 0x208) = 0x03400008; ++			/* nop */ ++			*(u32 *)(ebase + 0x20C) = 0x00000000; ++			flush_icache_range(ebase + 0x200, ebase + 0x210); ++		} else { ++			*(u32 *)(ebase + 0x200) = ++				0x08000000 | (0x03ffffff & (handler >> 2)); ++			flush_icache_range(ebase + 0x200, ebase + 0x204); ++		} + 	} + 	return (void *)old_handler; + } +--- a/arch/mips/Makefile ++++ b/arch/mips/Makefile +@@ -167,6 +167,13 @@ libs-$(CONFIG_SIBYTE_CFE)	+= arch/mips/s + # +  + # ++# Texas Instruments AR7 ++# ++core-$(CONFIG_AR7)		+= arch/mips/ar7/ ++cflags-$(CONFIG_AR7)		+= -Iinclude/asm-mips/ar7 ++load-$(CONFIG_AR7)		+= 0xffffffff94100000 ++ ++# + # Acer PICA 61, Mips Magnum 4000 and Olivetti M700. + # + core-$(CONFIG_MACH_JAZZ)	+= arch/mips/jazz/ +--- a/arch/mips/include/asm/page.h ++++ b/arch/mips/include/asm/page.h +@@ -182,8 +182,10 @@ typedef struct { unsigned long pgprot; } + #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \ + 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +  +-#define UNCAC_ADDR(addr)	((addr) - PAGE_OFFSET + UNCAC_BASE) +-#define CAC_ADDR(addr)		((addr) - UNCAC_BASE + PAGE_OFFSET) ++#define UNCAC_ADDR(addr)	((addr) - PAGE_OFFSET + UNCAC_BASE +	\ ++				 PHYS_OFFSET) ++#define CAC_ADDR(addr)		((addr) - UNCAC_BASE + PAGE_OFFSET -	\ ++				 PHYS_OFFSET) +  + #include <asm-generic/memory_model.h> + #include <asm-generic/page.h> diff --git a/target/linux/ar7/patches-2.6.30/110-flash.patch b/target/linux/ar7/patches-2.6.30/110-flash.patch new file mode 100644 index 000000000..7311a6734 --- /dev/null +++ b/target/linux/ar7/patches-2.6.30/110-flash.patch @@ -0,0 +1,11 @@ +--- a/drivers/mtd/maps/physmap.c ++++ b/drivers/mtd/maps/physmap.c +@@ -80,7 +80,7 @@ static const char *rom_probe_types[] = { + 					"map_rom", + 					NULL }; + #ifdef CONFIG_MTD_PARTITIONS +-static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; ++static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", "ar7part", NULL }; + #endif +  + static int physmap_flash_probe(struct platform_device *dev) diff --git a/target/linux/ar7/patches-2.6.30/120-gpio_chrdev.patch b/target/linux/ar7/patches-2.6.30/120-gpio_chrdev.patch new file mode 100644 index 000000000..fa61e5ccf --- /dev/null +++ b/target/linux/ar7/patches-2.6.30/120-gpio_chrdev.patch @@ -0,0 +1,28 @@ +--- a/drivers/char/Kconfig ++++ b/drivers/char/Kconfig +@@ -974,6 +974,15 @@ config MWAVE + 	  To compile this driver as a module, choose M here: the + 	  module will be called mwave. +  ++config AR7_GPIO ++	tristate "TI AR7 GPIO Support" ++	depends on AR7 ++	help ++	  Give userspace access to the GPIO pins on the Texas Instruments AR7  ++	  processors. ++ ++	  If compiled as a module, it will be called ar7_gpio. ++ + config SCx200_GPIO + 	tristate "NatSemi SCx200 GPIO Support" + 	depends on SCx200 +--- a/drivers/char/Makefile ++++ b/drivers/char/Makefile +@@ -90,6 +90,7 @@ obj-$(CONFIG_HW_RANDOM)		+= hw_random/ + obj-$(CONFIG_PPDEV)		+= ppdev.o + obj-$(CONFIG_NWBUTTON)		+= nwbutton.o + obj-$(CONFIG_NWFLASH)		+= nwflash.o ++obj-$(CONFIG_AR7_GPIO)		+= ar7_gpio.o + obj-$(CONFIG_SCx200_GPIO)	+= scx200_gpio.o + obj-$(CONFIG_PC8736x_GPIO)	+= pc8736x_gpio.o + obj-$(CONFIG_NSC_GPIO)		+= nsc_gpio.o diff --git a/target/linux/ar7/patches-2.6.30/130-vlynq.patch b/target/linux/ar7/patches-2.6.30/130-vlynq.patch new file mode 100644 index 000000000..9ab3638ea --- /dev/null +++ b/target/linux/ar7/patches-2.6.30/130-vlynq.patch @@ -0,0 +1,20 @@ +--- a/drivers/Kconfig ++++ b/drivers/Kconfig +@@ -100,5 +100,7 @@ source "drivers/auxdisplay/Kconfig" +  + source "drivers/uio/Kconfig" +  ++source "drivers/vlynq/Kconfig" ++ + source "drivers/xen/Kconfig" + endmenu +--- a/drivers/Makefile ++++ b/drivers/Makefile +@@ -96,6 +96,7 @@ obj-$(CONFIG_DCA)		+= dca/ + obj-$(CONFIG_HID)		+= hid/ + obj-$(CONFIG_PPC_PS3)		+= ps3/ + obj-$(CONFIG_OF)		+= of/ ++obj-$(CONFIG_VLYNQ)		+= vlynq/ + obj-$(CONFIG_SSB)		+= ssb/ + obj-$(CONFIG_VIRTIO)		+= virtio/ + obj-$(CONFIG_REGULATOR)		+= regulator/ diff --git a/target/linux/ar7/patches-2.6.30/131-vlynq_fixes.patch b/target/linux/ar7/patches-2.6.30/131-vlynq_fixes.patch new file mode 100644 index 000000000..f68ae4c70 --- /dev/null +++ b/target/linux/ar7/patches-2.6.30/131-vlynq_fixes.patch @@ -0,0 +1,548 @@ +--- a/drivers/vlynq/vlynq.c	2009-05-31 20:41:57.000000000 +0200 ++++ b/drivers/vlynq/vlynq.c	2009-07-28 21:27:52.000000000 +0200 +@@ -14,6 +14,9 @@ +  * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA ++ * ++ * Parts of the VLYNQ specification can be found here: ++ * http://www.ti.com/litv/pdf/sprue36a +  */ +  + #include <linux/init.h> +@@ -25,7 +28,6 @@ + #include <linux/errno.h> + #include <linux/platform_device.h> + #include <linux/interrupt.h> +-#include <linux/device.h> + #include <linux/delay.h> + #include <linux/io.h> +  +@@ -73,15 +75,11 @@ + 	u32 int_device[8]; + }; +  +-#define vlynq_reg_read(reg) readl(&(reg)) +-#define vlynq_reg_write(reg, val)  writel(val, &(reg)) +- +-static int __vlynq_enable_device(struct vlynq_device *dev); +- +-#ifdef VLYNQ_DEBUG ++#ifdef CONFIG_VLYNQ_DEBUG + static void vlynq_dump_regs(struct vlynq_device *dev) + { + 	int i; ++ + 	printk(KERN_DEBUG "VLYNQ local=%p remote=%p\n", + 			dev->local, dev->remote); + 	for (i = 0; i < 32; i++) { +@@ -95,20 +93,23 @@ + static void vlynq_dump_mem(u32 *base, int count) + { + 	int i; ++ + 	for (i = 0; i < (count + 3) / 4; i++) { +-		if (i % 4 == 0) printk(KERN_DEBUG "\nMEM[0x%04x]:", i * 4); ++		if (i % 4 == 0) ++			printk(KERN_DEBUG "\nMEM[0x%04x]:", i * 4); + 		printk(KERN_DEBUG " 0x%08x", *(base + i)); + 	} + 	printk(KERN_DEBUG "\n"); + } + #endif +  +-int vlynq_linked(struct vlynq_device *dev) ++/* Check the VLYNQ link status with a given device */ ++static int vlynq_linked(struct vlynq_device *dev) + { + 	int i; +  + 	for (i = 0; i < 100; i++) +-		if (vlynq_reg_read(dev->local->status) & VLYNQ_STATUS_LINK) ++		if (readl(&dev->local->status) & VLYNQ_STATUS_LINK) + 			return 1; + 		else + 			cpu_relax(); +@@ -118,17 +119,15 @@ +  + static void vlynq_reset(struct vlynq_device *dev) + { +-	vlynq_reg_write(dev->local->control, +-			vlynq_reg_read(dev->local->control) | +-			VLYNQ_CTRL_RESET); ++	writel(readl(&dev->local->control) | VLYNQ_CTRL_RESET, ++			&dev->local->control); +  + 	/* Wait for the devices to finish resetting */ + 	msleep(5); +  + 	/* Remove reset bit */ +-	vlynq_reg_write(dev->local->control, +-			vlynq_reg_read(dev->local->control) & +-			~VLYNQ_CTRL_RESET); ++	writel(readl(&dev->local->control) & ~VLYNQ_CTRL_RESET, ++			&dev->local->control); +  + 	/* Give some time for the devices to settle */ + 	msleep(5); +@@ -142,9 +141,9 @@ +  + 	BUG_ON(!dev); + 	virq = irq - dev->irq_start; +-	val = vlynq_reg_read(dev->remote->int_device[virq >> 2]); ++	val = readl(&dev->remote->int_device[virq >> 2]); + 	val |= (VINT_ENABLE | virq) << VINT_OFFSET(virq); +-	vlynq_reg_write(dev->remote->int_device[virq >> 2], val); ++	writel(val, &dev->remote->int_device[virq >> 2]); + } +  + static void vlynq_irq_mask(unsigned int irq) +@@ -155,9 +154,9 @@ +  + 	BUG_ON(!dev); + 	virq = irq - dev->irq_start; +-	val = vlynq_reg_read(dev->remote->int_device[virq >> 2]); ++	val = readl(&dev->remote->int_device[virq >> 2]); + 	val &= ~(VINT_ENABLE << VINT_OFFSET(virq)); +-	vlynq_reg_write(dev->remote->int_device[virq >> 2], val); ++	writel(val, &dev->remote->int_device[virq >> 2]); + } +  + static int vlynq_irq_type(unsigned int irq, unsigned int flow_type) +@@ -168,7 +167,7 @@ +  + 	BUG_ON(!dev); + 	virq = irq - dev->irq_start; +-	val = vlynq_reg_read(dev->remote->int_device[virq >> 2]); ++	val = readl(&dev->remote->int_device[virq >> 2]); + 	switch (flow_type & IRQ_TYPE_SENSE_MASK) { + 	case IRQ_TYPE_EDGE_RISING: + 	case IRQ_TYPE_EDGE_FALLING: +@@ -187,28 +186,30 @@ + 	default: + 		return -EINVAL; + 	} +-	vlynq_reg_write(dev->remote->int_device[virq >> 2], val); ++	writel(val, &dev->remote->int_device[virq >> 2]); + 	return 0; + } +  + static void vlynq_local_ack(unsigned int irq) + { + 	struct vlynq_device *dev = get_irq_chip_data(irq); +-	u32 status = vlynq_reg_read(dev->local->status); +-	if (printk_ratelimit()) +-		printk(KERN_DEBUG "%s: local status: 0x%08x\n", +-		       dev->dev.bus_id, status); +-	vlynq_reg_write(dev->local->status, status); ++ ++	u32 status = readl(&dev->local->status); ++ ++	pr_debug("%s: local status: 0x%08x\n", ++		       dev_name(&dev->dev), status); ++	writel(status, &dev->local->status); + } +  + static void vlynq_remote_ack(unsigned int irq) + { + 	struct vlynq_device *dev = get_irq_chip_data(irq); +-	u32 status = vlynq_reg_read(dev->remote->status); +-	if (printk_ratelimit()) +-		printk(KERN_DEBUG "%s: remote status: 0x%08x\n", +-		       dev->dev.bus_id, status); +-	vlynq_reg_write(dev->remote->status, status); ++ ++	u32 status = readl(&dev->remote->status); ++ ++	pr_debug("%s: remote status: 0x%08x\n", ++		       dev_name(&dev->dev), status); ++	writel(status, &dev->remote->status); + } +  + static irqreturn_t vlynq_irq(int irq, void *dev_id) +@@ -217,8 +218,8 @@ + 	u32 status; + 	int virq = 0; +  +-	status = vlynq_reg_read(dev->local->int_status); +-	vlynq_reg_write(dev->local->int_status, status); ++	status = readl(&dev->local->int_status); ++	writel(status, &dev->local->int_status); +  + 	if (unlikely(!status)) + 		spurious_interrupt(); +@@ -262,28 +263,28 @@ + 	if (dev->local_irq == dev->remote_irq) { + 		printk(KERN_ERR + 		       "%s: local vlynq irq should be different from remote\n", +-		       dev->dev.bus_id); ++		       dev_name(&dev->dev)); + 		return -EINVAL; + 	} +  + 	/* Clear local and remote error bits */ +-	vlynq_reg_write(dev->local->status, vlynq_reg_read(dev->local->status)); +-	vlynq_reg_write(dev->remote->status, +-			vlynq_reg_read(dev->remote->status)); ++	writel(readl(&dev->local->status), &dev->local->status); ++	writel(readl(&dev->remote->status), &dev->remote->status); +  + 	/* Now setup interrupts */ + 	val = VLYNQ_CTRL_INT_VECTOR(dev->local_irq); + 	val |= VLYNQ_CTRL_INT_ENABLE | VLYNQ_CTRL_INT_LOCAL | + 		VLYNQ_CTRL_INT2CFG; +-	val |= vlynq_reg_read(dev->local->control); +-	vlynq_reg_write(dev->local->int_ptr, VLYNQ_INT_OFFSET); +-	vlynq_reg_write(dev->local->control, val); ++	val |= readl(&dev->local->control); ++	writel(VLYNQ_INT_OFFSET, &dev->local->int_ptr); ++	writel(val, &dev->local->control); +  + 	val = VLYNQ_CTRL_INT_VECTOR(dev->remote_irq); + 	val |= VLYNQ_CTRL_INT_ENABLE; +-	val |= vlynq_reg_read(dev->remote->control); +-	vlynq_reg_write(dev->remote->int_ptr, VLYNQ_INT_OFFSET); +-	vlynq_reg_write(dev->remote->control, val); ++	val |= readl(&dev->remote->control); ++	writel(VLYNQ_INT_OFFSET, &dev->remote->int_ptr); ++	writel(val, &dev->remote->int_ptr); ++	writel(val, &dev->remote->control); +  + 	for (i = dev->irq_start; i <= dev->irq_end; i++) { + 		virq = i - dev->irq_start; +@@ -299,12 +300,13 @@ + 			set_irq_chip_and_handler(i, &vlynq_irq_chip, + 						 handle_simple_irq); + 			set_irq_chip_data(i, dev); +-			vlynq_reg_write(dev->remote->int_device[virq >> 2], 0); ++			writel(0, &dev->remote->int_device[virq >> 2]); + 		} + 	} +  + 	if (request_irq(dev->irq, vlynq_irq, IRQF_SHARED, "vlynq", dev)) { +-		printk(KERN_ERR "%s: request_irq failed\n", dev->dev.bus_id); ++		printk(KERN_ERR "%s: request_irq failed\n", ++					dev_name(&dev->dev)); + 		return -EAGAIN; + 	} +  +@@ -328,11 +330,11 @@ + 		if (ids->id == vdev->dev_id) { + 			vdev->divisor = ids->divisor; + 			vlynq_set_drvdata(vdev, ids); +-			printk(KERN_INFO "Driver found for VLYNQ " \ ++			printk(KERN_INFO "Driver found for VLYNQ " + 				"device: %08x\n", vdev->dev_id); + 			return 1; + 		} +-		printk(KERN_DEBUG "Not using the %08x VLYNQ device's driver" \ ++		printk(KERN_DEBUG "Not using the %08x VLYNQ device's driver" + 			" for VLYNQ device: %08x\n", ids->id, vdev->dev_id); + 		ids++; + 	} +@@ -346,8 +348,7 @@ + 	struct vlynq_device_id *id = vlynq_get_drvdata(vdev); + 	int result = -ENODEV; +  +-	get_device(dev); +-	if (drv && drv->probe) ++	if (drv->probe) + 		result = drv->probe(vdev, id); + 	if (result) + 		put_device(dev); +@@ -357,9 +358,10 @@ + static int vlynq_device_remove(struct device *dev) + { + 	struct vlynq_driver *drv = to_vlynq_driver(dev->driver); +-	if (drv && drv->remove) ++ ++	if (drv->remove) + 		drv->remove(to_vlynq_device(dev)); +-	put_device(dev); ++ + 	return 0; + } +  +@@ -377,6 +379,14 @@ + } + EXPORT_SYMBOL(vlynq_unregister_driver); +  ++/* ++ * A VLYNQ remote device can clock the VLYNQ bus master ++ * using a dedicated clock line. In that case, both the ++ * remove device and the bus master should have the same ++ * serial clock dividers configured. Iterate through the ++ * 8 possible dividers until we actually link with the ++ * device. ++ */ + static int __vlynq_try_remote(struct vlynq_device *dev) + { + 	int i; +@@ -389,21 +399,21 @@ + 		if (!vlynq_linked(dev)) + 			break; +  +-		vlynq_reg_write(dev->remote->control, +-				(vlynq_reg_read(dev->remote->control) & ++		writel((readl(&dev->remote->control) & + 				~VLYNQ_CTRL_CLOCK_MASK) | + 				VLYNQ_CTRL_CLOCK_INT | +-				VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1)); +-		vlynq_reg_write(dev->local->control, +-				((vlynq_reg_read(dev->local->control) ++				VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1), ++				&dev->remote->control); ++		writel((readl(&dev->local->control) + 				& ~(VLYNQ_CTRL_CLOCK_INT | + 				VLYNQ_CTRL_CLOCK_MASK)) | +-				VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1))); ++				VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1), ++				&dev->local->control); +  + 		if (vlynq_linked(dev)) { + 			printk(KERN_DEBUG + 				"%s: using remote clock divisor %d\n", +-				dev->dev.bus_id, i - vlynq_rdiv1 + 1); ++				dev_name(&dev->dev), i - vlynq_rdiv1 + 1); + 			dev->divisor = i; + 			return 0; + 		} else { +@@ -414,26 +424,33 @@ + 	return -ENODEV; + } +  ++/* ++ * A VLYNQ remote device can be clocked by the VLYNQ bus ++ * master using a dedicated clock line. In that case, only ++ * the bus master configures the serial clock divider. ++ * Iterate through the 8 possible dividers until we ++ * actually get a link with the device. ++ */ + static int __vlynq_try_local(struct vlynq_device *dev) + { + 	int i; +-	 ++ + 	vlynq_reset(dev); +  + 	for (i = dev->dev_id ? vlynq_ldiv2 : vlynq_ldiv8; dev->dev_id ? + 			i <= vlynq_ldiv8 : i >= vlynq_ldiv2; + 		dev->dev_id ? i++ : i--) { +  +-		vlynq_reg_write(dev->local->control, +-				(vlynq_reg_read(dev->local->control) & ++		writel((readl(&dev->local->control) & + 				~VLYNQ_CTRL_CLOCK_MASK) | + 				VLYNQ_CTRL_CLOCK_INT | +-				VLYNQ_CTRL_CLOCK_DIV(i - vlynq_ldiv1)); ++				VLYNQ_CTRL_CLOCK_DIV(i - vlynq_ldiv1), ++				&dev->local->control); +  + 		if (vlynq_linked(dev)) { + 			printk(KERN_DEBUG + 				"%s: using local clock divisor %d\n", +-				dev->dev.bus_id, i - vlynq_ldiv1 + 1); ++				dev_name(&dev->dev), i - vlynq_ldiv1 + 1); + 			dev->divisor = i; + 			return 0; + 		} else { +@@ -444,27 +461,33 @@ + 	return -ENODEV; + } +  ++/* ++ * When using external clocking method, serial clock ++ * is supplied by an external oscillator, therefore we ++ * should mask the local clock bit in the clock control ++ * register for both the bus master and the remote device. ++ */ + static int __vlynq_try_external(struct vlynq_device *dev) + { + 	vlynq_reset(dev); + 	if (!vlynq_linked(dev)) + 		return -ENODEV; +  +-	vlynq_reg_write(dev->remote->control, +-			(vlynq_reg_read(dev->remote->control) & +-			~VLYNQ_CTRL_CLOCK_INT)); +- +-	vlynq_reg_write(dev->local->control, +-			(vlynq_reg_read(dev->local->control) & +-			~VLYNQ_CTRL_CLOCK_INT)); ++	writel((readl(&dev->remote->control) & ++			~VLYNQ_CTRL_CLOCK_INT), ++			&dev->remote->control); ++ ++	writel((readl(&dev->local->control) & ++			~VLYNQ_CTRL_CLOCK_INT), ++			&dev->local->control); +  + 	if (vlynq_linked(dev)) { + 		printk(KERN_DEBUG "%s: using external clock\n", +-			dev->dev.bus_id); ++			dev_name(&dev->dev)); + 			dev->divisor = vlynq_div_external; + 		return 0; + 	} +-	 ++ + 	return -ENODEV; + } +  +@@ -481,10 +504,10 @@ + 	case vlynq_div_external: + 	case vlynq_div_auto: + 		/* When the device is brought from reset it should have clock +-		generation negotiated by hardware. +-		Check which device is generating clocks and perform setup +-		accordingly */ +-		if (vlynq_linked(dev) && vlynq_reg_read(dev->remote->control) & ++		 * generation negotiated by hardware. ++		 * Check which device is generating clocks and perform setup ++		 * accordingly */ ++		if (vlynq_linked(dev) && readl(&dev->remote->control) & + 		   VLYNQ_CTRL_CLOCK_INT) { + 			if (!__vlynq_try_remote(dev) || + 				!__vlynq_try_local(dev)  || +@@ -497,31 +520,43 @@ + 				return 0; + 		} + 		break; +-	case vlynq_ldiv1: case vlynq_ldiv2: case vlynq_ldiv3: case vlynq_ldiv4: +-	case vlynq_ldiv5: case vlynq_ldiv6: case vlynq_ldiv7: case vlynq_ldiv8: +-		vlynq_reg_write(dev->local->control, +-				VLYNQ_CTRL_CLOCK_INT | +-				VLYNQ_CTRL_CLOCK_DIV(dev->divisor - +-						     vlynq_ldiv1)); +-		vlynq_reg_write(dev->remote->control, 0); ++	case vlynq_ldiv1: ++	case vlynq_ldiv2: ++	case vlynq_ldiv3: ++	case vlynq_ldiv4: ++	case vlynq_ldiv5: ++	case vlynq_ldiv6: ++	case vlynq_ldiv7: ++	case vlynq_ldiv8: ++		writel(VLYNQ_CTRL_CLOCK_INT | ++			VLYNQ_CTRL_CLOCK_DIV(dev->divisor - ++			vlynq_ldiv1), &dev->local->control); ++		writel(0, &dev->remote->control); + 		if (vlynq_linked(dev)) { + 			printk(KERN_DEBUG +-			       "%s: using local clock divisor %d\n", +-			       dev->dev.bus_id, dev->divisor - vlynq_ldiv1 + 1); ++				"%s: using local clock divisor %d\n", ++				dev_name(&dev->dev), ++				dev->divisor - vlynq_ldiv1 + 1); + 			return 0; + 		} + 		break; +-	case vlynq_rdiv1: case vlynq_rdiv2: case vlynq_rdiv3: case vlynq_rdiv4: +-	case vlynq_rdiv5: case vlynq_rdiv6: case vlynq_rdiv7: case vlynq_rdiv8: +-		vlynq_reg_write(dev->local->control, 0); +-		vlynq_reg_write(dev->remote->control, +-				VLYNQ_CTRL_CLOCK_INT | +-				VLYNQ_CTRL_CLOCK_DIV(dev->divisor - +-						     vlynq_rdiv1)); ++	case vlynq_rdiv1: ++	case vlynq_rdiv2: ++	case vlynq_rdiv3: ++	case vlynq_rdiv4: ++	case vlynq_rdiv5: ++	case vlynq_rdiv6: ++	case vlynq_rdiv7: ++	case vlynq_rdiv8: ++		writel(0, &dev->local->control); ++		writel(VLYNQ_CTRL_CLOCK_INT | ++			VLYNQ_CTRL_CLOCK_DIV(dev->divisor - ++			vlynq_rdiv1), &dev->remote->control); + 		if (vlynq_linked(dev)) { + 			printk(KERN_DEBUG +-			       "%s: using remote clock divisor %d\n", +-			       dev->dev.bus_id, dev->divisor - vlynq_rdiv1 + 1); ++				"%s: using remote clock divisor %d\n", ++				dev_name(&dev->dev), ++				dev->divisor - vlynq_rdiv1 + 1); + 			return 0; + 		} + 		break; +@@ -568,12 +603,10 @@ + 	if (!dev->enabled) + 		return -ENXIO; +  +-	vlynq_reg_write(dev->local->tx_offset, tx_offset); ++	writel(tx_offset, &dev->local->tx_offset); + 	for (i = 0; i < 4; i++) { +-		vlynq_reg_write(dev->local->rx_mapping[i].offset, +-							mapping[i].offset); +-		vlynq_reg_write(dev->local->rx_mapping[i].size, +-							mapping[i].size); ++		writel(mapping[i].offset, &dev->local->rx_mapping[i].offset); ++		writel(mapping[i].size, &dev->local->rx_mapping[i].size); + 	} + 	return 0; + } +@@ -587,12 +620,10 @@ + 	if (!dev->enabled) + 		return -ENXIO; +  +-	vlynq_reg_write(dev->remote->tx_offset, tx_offset); ++	writel(tx_offset, &dev->remote->tx_offset); + 	for (i = 0; i < 4; i++) { +-		vlynq_reg_write(dev->remote->rx_mapping[i].offset, +-							mapping[i].offset); +-		vlynq_reg_write(dev->remote->rx_mapping[i].size, +-							mapping[i].size); ++		writel(mapping[i].offset, &dev->remote->rx_mapping[i].offset); ++		writel(mapping[i].size, &dev->remote->rx_mapping[i].size); + 	} + 	return 0; + } +@@ -662,8 +693,7 @@ + 	dev->id = pdev->id; + 	dev->dev.bus = &vlynq_bus_type; + 	dev->dev.parent = &pdev->dev; +-	snprintf(dev->dev.bus_id, BUS_ID_SIZE, "vlynq%d", dev->id); +-	dev->dev.bus_id[BUS_ID_SIZE - 1] = 0; ++	dev_set_name(&dev->dev, "vlynq%d", dev->id); + 	dev->dev.platform_data = pdev->dev.platform_data; + 	dev->dev.release = vlynq_device_release; +  +@@ -673,9 +703,9 @@ + 	dev->mem_end = mem_res->end; +  + 	len = regs_res->end - regs_res->start; +-	if (!request_mem_region(regs_res->start, len, dev->dev.bus_id)) { ++	if (!request_mem_region(regs_res->start, len, dev_name(&dev->dev))) { + 		printk(KERN_ERR "%s: Can't request vlynq registers\n", +-		       dev->dev.bus_id); ++		       dev_name(&dev->dev)); + 		result = -ENXIO; + 		goto fail_request; + 	} +@@ -683,7 +713,7 @@ + 	dev->local = ioremap(regs_res->start, len); + 	if (!dev->local) { + 		printk(KERN_ERR "%s: Can't remap vlynq registers\n", +-		       dev->dev.bus_id); ++		       dev_name(&dev->dev)); + 		result = -ENXIO; + 		goto fail_remap; + 	} +@@ -702,14 +732,14 @@ + 	platform_set_drvdata(pdev, dev); +  + 	printk(KERN_INFO "%s: regs 0x%p, irq %d, mem 0x%p\n", +-	       dev->dev.bus_id, (void *)dev->regs_start, dev->irq, ++	       dev_name(&dev->dev), (void *)dev->regs_start, dev->irq, + 	       (void *)dev->mem_start); +  + 	dev->dev_id = 0; + 	dev->divisor = vlynq_div_auto; + 	result = __vlynq_enable_device(dev); + 	if (result == 0) { +-		dev->dev_id = vlynq_reg_read(dev->remote->chip); ++		dev->dev_id = readl(&dev->remote->chip); + 		((struct plat_vlynq_ops *)(dev->dev.platform_data))->off(dev); + 	} + 	if (dev->dev_id) diff --git a/target/linux/ar7/patches-2.6.30/150-cpmac_not_broken.patch b/target/linux/ar7/patches-2.6.30/150-cpmac_not_broken.patch new file mode 100644 index 000000000..0c8a20d45 --- /dev/null +++ b/target/linux/ar7/patches-2.6.30/150-cpmac_not_broken.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/Kconfig ++++ b/drivers/net/Kconfig +@@ -1883,7 +1883,7 @@ config SC92031 +  + config CPMAC + 	tristate "TI AR7 CPMAC Ethernet support (EXPERIMENTAL)" +-	depends on NET_ETHERNET && EXPERIMENTAL && AR7 && BROKEN ++	depends on NET_ETHERNET && EXPERIMENTAL && AR7 + 	select PHYLIB + 	help + 	  TI AR7 CPMAC Ethernet support diff --git a/target/linux/ar7/patches-2.6.30/500-serial_kludge.patch b/target/linux/ar7/patches-2.6.30/500-serial_kludge.patch new file mode 100644 index 000000000..d4b02bc91 --- /dev/null +++ b/target/linux/ar7/patches-2.6.30/500-serial_kludge.patch @@ -0,0 +1,38 @@ +--- a/drivers/serial/8250.c ++++ b/drivers/serial/8250.c +@@ -287,6 +287,13 @@ static const struct serial8250_config ua + 		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + 		.flags		= UART_CAP_FIFO, + 	}, ++	[PORT_AR7] = { ++		.name		= "TI-AR7", ++		.fifo_size	= 16, ++		.tx_loadsz	= 16, ++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, ++		.flags		= UART_CAP_FIFO | UART_CAP_AFE, ++	}, + }; +  + #if defined (CONFIG_SERIAL_8250_AU1X00) +@@ -2702,7 +2709,11 @@ static void serial8250_console_putchar(s + { + 	struct uart_8250_port *up = (struct uart_8250_port *)port; +  ++#ifdef CONFIG_AR7 ++	wait_for_xmitr(up, BOTH_EMPTY); ++#else + 	wait_for_xmitr(up, UART_LSR_THRE); ++#endif + 	serial_out(up, UART_TX, ch); + } +  +--- a/include/linux/serial_core.h ++++ b/include/linux/serial_core.h +@@ -41,6 +41,7 @@ + #define PORT_XSCALE	15 + #define PORT_RM9000	16	/* PMC-Sierra RM9xxx internal UART */ + #define PORT_OCTEON	17	/* Cavium OCTEON internal UART */ ++#define PORT_AR7	18	/* TI AR7 internal UART */ + #define PORT_MAX_8250	17	/* max port ID */ +  + /* diff --git a/target/linux/ar7/patches-2.6.30/900-cpmac_multiqueue.patch b/target/linux/ar7/patches-2.6.30/900-cpmac_multiqueue.patch new file mode 100644 index 000000000..3df3d6832 --- /dev/null +++ b/target/linux/ar7/patches-2.6.30/900-cpmac_multiqueue.patch @@ -0,0 +1,70 @@ +This patch fixes the network driver cpmac.c for compilation with +configuration option CONFIG_NETDEVICES_MULTIQUEUE. + +These compiler warnings are fixed by the patch: +drivers/net/cpmac.c: In function 'cpmac_end_xmit': +drivers/net/cpmac.c:630: warning: passing argument 2 of 'netif_subqueue_stopped' makes pointer from integer without a cast +drivers/net/cpmac.c:641: warning: passing argument 2 of 'netif_subqueue_stopped' makes pointer from integer without a cast +drivers/net/cpmac.c: In function 'cpmac_probe': +drivers/net/cpmac.c:1128: warning: unused variable 'i' + +During runtime, the unpatched driver raises a fatal runtime exception. +This is fixed by calling __netif_subqueue_stopped instead +of netif_subqueue_stopped, too. + +Two additional code parts were modified for CONFIG_NETDEVICES_MULTIQUEUE +because other drivers do it in the same way. + +        Signed-off-by: Stefan Weil <weil@mail.berlios.de> + +--- a/drivers/net/cpmac.c ++++ b/drivers/net/cpmac.c +@@ -615,13 +615,13 @@ static void cpmac_end_xmit(struct net_de +  + 		dev_kfree_skb_irq(desc->skb); + 		desc->skb = NULL; +-		if (netif_subqueue_stopped(dev, queue)) ++		if (__netif_subqueue_stopped(dev, queue)) + 			netif_wake_subqueue(dev, queue); + 	} else { + 		if (netif_msg_tx_err(priv) && net_ratelimit()) + 			printk(KERN_WARNING + 			       "%s: end_xmit: spurious interrupt\n", dev->name); +-		if (netif_subqueue_stopped(dev, queue)) ++		if (__netif_subqueue_stopped(dev, queue)) + 			netif_wake_subqueue(dev, queue); + 	} + } +@@ -731,7 +731,6 @@ static void cpmac_clear_tx(struct net_de +  + static void cpmac_hw_error(struct work_struct *work) + { +-	int i; + 	struct cpmac_priv *priv = + 		container_of(work, struct cpmac_priv, reset_work); +  +@@ -818,7 +817,6 @@ static irqreturn_t cpmac_irq(int irq, vo +  + static void cpmac_tx_timeout(struct net_device *dev) + { +-	int i; + 	struct cpmac_priv *priv = netdev_priv(dev); +  + 	spin_lock(&priv->lock); +@@ -1097,7 +1095,7 @@ static int external_switch; +  + static int __devinit cpmac_probe(struct platform_device *pdev) + { +-	int rc, phy_id, i; ++	int rc, phy_id; + 	char *mdio_bus_id = "0"; + 	struct resource *mem; + 	struct cpmac_priv *priv; +@@ -1125,6 +1123,7 @@ static int __devinit cpmac_probe(struct  + 	} +  + 	dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES); ++	//~ dev = alloc_etherdev(sizeof(*priv)); +  + 	if (!dev) { + 		printk(KERN_ERR "cpmac: Unable to allocate net_device\n"); | 
