From 3c4062a45f764d064fb176f98ba3a8f1c1d41e4f Mon Sep 17 00:00:00 2001
From: Eugene Konev <ejka@imfi.kspu.ru>
Date: Fri, 5 Oct 2007 17:54:36 +0000
Subject: [PATCH] cleanup vlynq. drop vlynq-pci

SVN-Revision: 9143
---
 target/linux/ar7/config-2.6.22                |  26 +-
 target/linux/ar7/config-2.6.23                |  24 +-
 target/linux/ar7/files/arch/mips/ar7/Makefile |   6 +-
 .../linux/ar7/files/arch/mips/ar7/platform.c  |   2 +-
 .../linux/ar7/files/arch/mips/ar7/vlynq-pci.c | 436 ------------------
 target/linux/ar7/files/drivers/vlynq/Kconfig  |  13 +
 target/linux/ar7/files/drivers/vlynq/Makefile |   5 +
 .../{arch/mips/ar7 => drivers/vlynq}/vlynq.c  | 217 +++++----
 .../include/{asm-mips/ar7 => linux}/vlynq.h   |  90 +++-
 .../patches-2.6.22/100-board_support.patch    |   3 +-
 .../linux/ar7/patches-2.6.22/130-vlynq.patch  |  20 +
 .../patches-2.6.23/100-board_support.patch    |   3 +-
 .../linux/ar7/patches-2.6.23/130-vlynq.patch  |  20 +
 13 files changed, 264 insertions(+), 601 deletions(-)
 delete mode 100644 target/linux/ar7/files/arch/mips/ar7/vlynq-pci.c
 create mode 100644 target/linux/ar7/files/drivers/vlynq/Kconfig
 create mode 100644 target/linux/ar7/files/drivers/vlynq/Makefile
 rename target/linux/ar7/files/{arch/mips/ar7 => drivers/vlynq}/vlynq.c (81%)
 rename target/linux/ar7/files/include/{asm-mips/ar7 => linux}/vlynq.h (56%)
 create mode 100644 target/linux/ar7/patches-2.6.22/130-vlynq.patch
 create mode 100644 target/linux/ar7/patches-2.6.23/130-vlynq.patch

diff --git a/target/linux/ar7/config-2.6.22 b/target/linux/ar7/config-2.6.22
index 3c2806cb68..07c6afbe73 100644
--- a/target/linux/ar7/config-2.6.22
+++ b/target/linux/ar7/config-2.6.22
@@ -7,10 +7,8 @@ CONFIG_AR7_WDT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_ATMEL is not set
 CONFIG_ATM_DRIVERS=y
 CONFIG_BASE_SMALL=0
-# CONFIG_BCM43XX is not set
 CONFIG_BITREVERSE=y
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_BOOT_ELF32=y
@@ -47,7 +45,6 @@ CONFIG_CPU_SUPPORTS_HIGHMEM=y
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_DDB5477 is not set
-CONFIG_DEVPORT=y
 # CONFIG_DM9000 is not set
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_DMA_NONCOHERENT=y
@@ -58,20 +55,14 @@ CONFIG_FIXED_PHY=y
 CONFIG_FS_POSIX_ACL=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_GPIO=y
-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_GEN_RTC is not set
 CONFIG_HAS_DMA=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
-# CONFIG_HERMES is not set
-# CONFIG_HOSTAP_PCI is not set
-# CONFIG_HOSTAP_PLX is not set
-CONFIG_HW_HAS_PCI=y
 CONFIG_HW_RANDOM=y
 # CONFIG_I2C is not set
 # CONFIG_IDE is not set
-# CONFIG_IPW2100 is not set
-# CONFIG_IPW2200 is not set
 CONFIG_IRQ_CPU=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -130,40 +121,35 @@ CONFIG_MTD_MAP_BANK_WIDTH_4=y
 # CONFIG_MTD_MTDRAM is not set
 # CONFIG_MTD_ONENAND is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_PCI is not set
 # CONFIG_MTD_PHRAM is not set
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_PHYSMAP_BANKWIDTH=2
 CONFIG_MTD_PHYSMAP_LEN=0
 CONFIG_MTD_PHYSMAP_START=0x10000000
 # CONFIG_MTD_PLATRAM is not set
-# CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_NETDEV_1000 is not set
-# CONFIG_NET_PCI is not set
 CONFIG_NET_SCH_FIFO=y
-# CONFIG_NET_VENDOR_3COM is not set
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_NAT_PROTO_GRE=m
 # CONFIG_PAGE_SIZE_16KB is not set
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PCIPCWATCHDOG is not set
 CONFIG_PHYLIB=y
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_PNPACPI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
-# CONFIG_PRISM54 is not set
 # CONFIG_QSEMI_PHY is not set
 # CONFIG_RTC is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SERIAL_8250_EXTENDED is not set
-CONFIG_SERIAL_8250_PCI=y
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP32 is not set
@@ -185,6 +171,7 @@ CONFIG_SYS_HAS_CPU_MIPS32_R1=y
 CONFIG_SYS_HAS_EARLY_PRINTK=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
 CONFIG_SYS_SUPPORTS_KGDB=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
 # CONFIG_TOSHIBA_JMR3927 is not set
@@ -192,6 +179,9 @@ CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_TRAD_SIGNALS=y
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_USB is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
 # CONFIG_VGASTATE is not set
+CONFIG_VLYNQ=y
 CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/ar7/config-2.6.23 b/target/linux/ar7/config-2.6.23
index f1bc7a52b1..fa1e7be5bf 100644
--- a/target/linux/ar7/config-2.6.23
+++ b/target/linux/ar7/config-2.6.23
@@ -6,10 +6,8 @@ CONFIG_AR7_WDT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_ATMEL is not set
 CONFIG_ATM_DRIVERS=y
 CONFIG_BASE_SMALL=0
-# CONFIG_BCM43XX is not set
 CONFIG_BITREVERSE=y
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_BOOT_ELF32=y
@@ -46,7 +44,7 @@ CONFIG_CPU_SUPPORTS_HIGHMEM=y
 # CONFIG_CPU_TX39XX is not set
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_VR41XX is not set
-CONFIG_DEVPORT=y
+# CONFIG_CRYPTO_HW is not set
 # CONFIG_DM9000 is not set
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_DMA_NONCOHERENT=y
@@ -61,15 +59,10 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_HAS_DMA=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
-# CONFIG_HERMES is not set
-# CONFIG_HOSTAP_PCI is not set
-# CONFIG_HOSTAP_PLX is not set
 CONFIG_HW_HAS_PCI=y
 CONFIG_HW_RANDOM=y
 # CONFIG_I2C is not set
 # CONFIG_IDE is not set
-# CONFIG_IPW2100 is not set
-# CONFIG_IPW2200 is not set
 CONFIG_IRQ_CPU=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -124,43 +117,39 @@ CONFIG_MTD_MAP_BANK_WIDTH_4=y
 # CONFIG_MTD_MTDRAM is not set
 # CONFIG_MTD_ONENAND is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_PCI is not set
 # CONFIG_MTD_PHRAM is not set
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_PHYSMAP_BANKWIDTH=2
 CONFIG_MTD_PHYSMAP_LEN=0
 CONFIG_MTD_PHYSMAP_START=0x10000000
 # CONFIG_MTD_PLATRAM is not set
-# CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_NETDEV_1000 is not set
 CONFIG_NET_ACT_POLICE=y
-# CONFIG_NET_PCI is not set
 CONFIG_NET_SCH_FIFO=y
-# CONFIG_NET_VENDOR_3COM is not set
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_NAT_PROTO_GRE=m
 CONFIG_NO_EXCEPT_FILL=y
 # CONFIG_NO_IOPORT is not set
 # CONFIG_PAGE_SIZE_16KB is not set
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_PCI is not set
 CONFIG_PHYLIB=y
 # CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
-# CONFIG_PRISM54 is not set
 # CONFIG_QSEMI_PHY is not set
 # CONFIG_RTC is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SERIAL_8250_EXTENDED is not set
-CONFIG_SERIAL_8250_PCI=y
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP32 is not set
@@ -190,7 +179,10 @@ CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
 # CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_TRAD_SIGNALS=y
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_USB is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
 # CONFIG_USER_NS is not set
 # CONFIG_VGASTATE is not set
+CONFIG_VLYNQ=y
 CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/ar7/files/arch/mips/ar7/Makefile b/target/linux/ar7/files/arch/mips/ar7/Makefile
index bd1095739c..7435e44b39 100644
--- a/target/linux/ar7/files/arch/mips/ar7/Makefile
+++ b/target/linux/ar7/files/arch/mips/ar7/Makefile
@@ -7,8 +7,4 @@ obj-y := \
 	time.o \
 	platform.o \
 	gpio.o \
-	clock.o \
-	vlynq.o
-
-obj-$(CONFIG_PCI) += \
-	vlynq-pci.o
+	clock.o
diff --git a/target/linux/ar7/files/arch/mips/ar7/platform.c b/target/linux/ar7/files/arch/mips/ar7/platform.c
index f3a9372d88..8f410babe7 100644
--- a/target/linux/ar7/files/arch/mips/ar7/platform.c
+++ b/target/linux/ar7/files/arch/mips/ar7/platform.c
@@ -29,6 +29,7 @@
 #include <linux/ioport.h>
 #include <linux/io.h>
 #include <linux/version.h>
+#include <linux/vlynq.h>
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
 #include <linux/leds.h>
 #endif
@@ -37,7 +38,6 @@
 #include <asm/ar7/ar7.h>
 #include <asm/ar7/gpio.h>
 #include <asm/ar7/prom.h>
-#include <asm/ar7/vlynq.h>
 
 struct plat_vlynq_data {
 	struct plat_vlynq_ops ops;
diff --git a/target/linux/ar7/files/arch/mips/ar7/vlynq-pci.c b/target/linux/ar7/files/arch/mips/ar7/vlynq-pci.c
deleted file mode 100644
index 7a640dbef7..0000000000
--- a/target/linux/ar7/files/arch/mips/ar7/vlynq-pci.c
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- * Copyright (C) 2006, 2007 OpenWrt.org
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <asm/ar7/vlynq.h>
-
-#define VLYNQ_PCI_SLOTS 2
-
-struct vlynq_reg_config {
-	u32 offset;
-	u32 value;
-};
-
-struct vlynq_pci_config {
-	u32 chip_id;
-	char name[32];
-	struct vlynq_mapping rx_mapping[4];
-	int irq;
-	int irq_type;
-	u32 chip;
-	u32 class;
-	int num_regs;
-	struct vlynq_reg_config regs[10];
-};
-
-struct vlynq_pci_private {
-	u32 latency;
-	u32 cache_line;
-	u32 command;
-	u32 sz_mask;
-	struct vlynq_pci_config *config;
-};
-
-static struct vlynq_pci_config known_devices[] = {
-	{
-		.chip_id = 0x00000009, .name = "TI TNETW1130",
-		.rx_mapping = {
-			{ .size = 0x22000, .offset = 0xf0000000 },
-			{ .size = 0x40000, .offset = 0xc0000000 },
-			{ .size = 0x0, .offset = 0x0 },
-			{ .size = 0x0, .offset = 0x0 },
-		},
-		.irq = 0, .chip = 0x9066104c,
-		.irq_type = IRQ_TYPE_EDGE_RISING,
-		.class = PCI_CLASS_NETWORK_OTHER,
-		.num_regs = 5,
-		.regs = {
-			{
-				.offset = 0x790,
-				.value = (0xd0000000 - PHYS_OFFSET)
-			},
-			{
-				.offset = 0x794,
-				.value = (0xd0000000 - PHYS_OFFSET)
-			},
-			{ .offset = 0x740, .value = 0 },
-			{ .offset = 0x744, .value = 0x00010000 },
-			{ .offset = 0x764, .value = 0x00010000 },
-		},
-	},
-	{
-		.chip_id = 0x00000029, .name = "TI TNETW1350",
-		.rx_mapping = {
-			{ .size = 0x100000, .offset = 0x00300000 },
-			{ .size = 0x80000, .offset = 0x00000000 },
-			{ .size = 0x0, .offset = 0x0 },
-			{ .size = 0x0, .offset = 0x0 },
-		},
-		.irq = 0, .chip = 0x9066104c,
-		.irq_type = IRQ_TYPE_EDGE_RISING,
-		.class = PCI_CLASS_NETWORK_OTHER,
-		.num_regs = 5,
-		.regs = {
-			{
-				.offset = 0x790,
-				.value = (0x60000000 - PHYS_OFFSET)
-			},
-			{
-				.offset = 0x794,
-				.value = (0x60000000 - PHYS_OFFSET)
-			},
-			{ .offset = 0x740, .value = 0 },
-			{ .offset = 0x744, .value = 0x00010000 },
-			{ .offset = 0x764, .value = 0x00010000 },
-		},
-	},
-};
-
-static struct vlynq_device *slots[VLYNQ_PCI_SLOTS] = { NULL, };
-
-static struct resource vlynq_io_resource = {
-	.start	= 0x00000000,
-	.end	= 0x00000000,
-	.name	= "pci IO space",
-	.flags	= IORESOURCE_IO
-};
-
-static struct resource vlynq_mem_resource = {
-	.start	= 0x00000000,
-	.end	= 0x00000000,
-	.name	= "pci memory space",
-	.flags	= IORESOURCE_MEM
-};
-
-static inline u32 vlynq_get_mapped(struct vlynq_device *dev, int res)
-{
-	int i;
-	struct vlynq_pci_private *priv = dev->priv;
-	u32 ret = dev->mem_start;
-	if (!priv->config->rx_mapping[res].size) return 0;
-	for (i = 0; i < res; i++)
-		ret += priv->config->rx_mapping[i].size;
-
-	return ret;
-}
-
-static inline u32 vlynq_read(u32 val, int size)
-{
-	switch (size) {
-	case 1:
-		return *(u8 *)&val;
-	case 2:
-		return *(u16 *)&val;
-	}
-	return val;
-}
-
-static int vlynq_config_read(struct pci_bus *bus, unsigned int devfn,
-			     int where, int size, u32 *val)
-{
-	struct vlynq_device *dev;
-	struct vlynq_pci_private *priv;
-	int resno, slot = PCI_SLOT(devfn);
-
-	if ((size == 2) && (where & 1))
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	else if ((size == 4) && (where & 3))
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-
-	if (slot >= VLYNQ_PCI_SLOTS)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	dev = slots[slot];
-
-	if (!dev || (PCI_FUNC(devfn) > 0))
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	priv = dev->priv;
-
-	switch (where) {
-	case PCI_VENDOR_ID:
-		*val = vlynq_read(priv->config->chip, size);
-		break;
-	case PCI_DEVICE_ID:
-		*val = priv->config->chip & 0xffff;
-	case PCI_COMMAND:
-		*val = priv->command;
-	case PCI_STATUS:
-/*		*val = PCI_STATUS_CAP_LIST;*/
-		*val = 0;
-		break;
-	case PCI_CLASS_REVISION:
-		*val = priv->config->class;
-		break;
-	case PCI_LATENCY_TIMER:
-		*val = priv->latency;
-		break;
-	case PCI_HEADER_TYPE:
-		*val = PCI_HEADER_TYPE_NORMAL;
-		break;
-	case PCI_CACHE_LINE_SIZE:
-		*val = priv->cache_line;
-		break;
-	case PCI_BASE_ADDRESS_0:
-	case PCI_BASE_ADDRESS_1:
-	case PCI_BASE_ADDRESS_2:
-	case PCI_BASE_ADDRESS_3:
-		resno = (where - PCI_BASE_ADDRESS_0) >> 2;
-		if (priv->sz_mask & (1 << resno)) {
-			priv->sz_mask &= ~(1 << resno);
-			*val = priv->config->rx_mapping[resno].size;
-		} else {
-			*val = vlynq_get_mapped(dev, resno);
-		}
-		break;
-	case PCI_BASE_ADDRESS_4:
-	case PCI_BASE_ADDRESS_5:
-	case PCI_SUBSYSTEM_VENDOR_ID:
-	case PCI_SUBSYSTEM_ID:
-	case PCI_ROM_ADDRESS:
-	case PCI_INTERRUPT_LINE:
-	case PCI_CARDBUS_CIS:
-	case PCI_CAPABILITY_LIST:
-		*val = 0;
-		break;
-	case PCI_INTERRUPT_PIN:
-		*val = 1;
-		break;
-	default:
-		printk(KERN_NOTICE "%s: Read of unknown register 0x%x "
-		       "(size %d)\n", dev->dev.bus_id, where, size);
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	}
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int vlynq_config_write(struct pci_bus *bus, unsigned int devfn,
-			      int where, int size, u32 val)
-{
-	struct vlynq_device *dev;
-	struct vlynq_pci_private *priv;
-	int resno, slot = PCI_SLOT(devfn);
-
-	if ((size == 2) && (where & 1))
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	else if ((size == 4) && (where & 3))
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-
-	if (slot >= VLYNQ_PCI_SLOTS)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	dev = slots[slot];
-
-	if (!dev || (PCI_FUNC(devfn) > 0))
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	priv = dev->priv;
-
-	switch (where) {
-	case PCI_VENDOR_ID:
-	case PCI_DEVICE_ID:
-	case PCI_STATUS:
-	case PCI_CLASS_REVISION:
-	case PCI_HEADER_TYPE:
-	case PCI_CACHE_LINE_SIZE:
-	case PCI_SUBSYSTEM_VENDOR_ID:
-	case PCI_SUBSYSTEM_ID:
-	case PCI_INTERRUPT_LINE:
-	case PCI_INTERRUPT_PIN:
-	case PCI_CARDBUS_CIS:
-	case PCI_CAPABILITY_LIST:
-		return PCIBIOS_FUNC_NOT_SUPPORTED;
-	case PCI_COMMAND:
-		priv->command = val;
-	case PCI_LATENCY_TIMER:
-		priv->latency = val;
-		break;
-	case PCI_BASE_ADDRESS_0:
-	case PCI_BASE_ADDRESS_1:
-	case PCI_BASE_ADDRESS_2:
-	case PCI_BASE_ADDRESS_3:
-		if (val == 0xffffffff) {
-			resno = (where - PCI_BASE_ADDRESS_0) >> 2;
-			priv->sz_mask |= (1 << resno);
-			break;
-		}
-	case PCI_BASE_ADDRESS_4:
-	case PCI_BASE_ADDRESS_5:
-	case PCI_ROM_ADDRESS:
-		break;
-	default:
-		printk(KERN_NOTICE "%s: Write to unknown register 0x%x "
-		       "(size %d) value=0x%x\n", dev->dev.bus_id, where, size,
-		       val);
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	}
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops vlynq_pci_ops = {
-	vlynq_config_read,
-	vlynq_config_write
-};
-
-static struct pci_controller vlynq_controller = {
-	.pci_ops	= &vlynq_pci_ops,
-	.io_resource	= &vlynq_io_resource,
-	.mem_resource	= &vlynq_mem_resource,
-};
-
-static int vlynq_pci_probe(struct vlynq_device *dev)
-{
-	int result, i;
-	u32 chip_id, addr;
-	struct vlynq_pci_private *priv;
-	struct vlynq_mapping mapping[4] = { { 0, }, };
-	struct vlynq_pci_config *config = NULL;
-
-	result = vlynq_set_local_irq(dev, 31);
-	if (result)
-		return result;
-
-	result = vlynq_set_remote_irq(dev, 30);
-	if (result)
-		return result;
-
-	dev->divisor = vlynq_div_auto;
-	result = vlynq_device_enable(dev);
-	if (result)
-		return result;
-
-	chip_id = vlynq_remote_id(dev);
-	for (i = 0; i < ARRAY_SIZE(known_devices); i++)
-		if (chip_id == known_devices[i].chip_id)
-			config = &known_devices[i];
-
-	if (!config) {
-		printk(KERN_DEBUG "vlynq-pci: skipping unknown device "
-		       "%04x:%04x at %s\n", chip_id >> 16,
-		       chip_id & 0xffff, dev->dev.bus_id);
-		result = -ENODEV;
-		goto fail;
-	}
-
-	printk(KERN_NOTICE "vlynq-pci: attaching device %s at %s\n",
-	       config->name, dev->dev.bus_id);
-
-	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-	if (!priv) {
-		printk(KERN_ERR "%s: failed to allocate private data\n",
-		       dev->dev.bus_id);
-		result = -ENOMEM;
-		goto fail;
-	}
-
-	priv->latency = 64;
-	priv->cache_line = 32;
-	priv->config = config;
-
-	mapping[0].offset = ARCH_PFN_OFFSET << PAGE_SHIFT;
-	mapping[0].size = 0x02000000;
-	vlynq_set_local_mapping(dev, dev->mem_start, mapping);
-	vlynq_set_remote_mapping(dev, 0, config->rx_mapping);
-
-	set_irq_type(vlynq_virq_to_irq(dev, config->irq), config->irq_type);
-
-	addr = (u32)ioremap_nocache(dev->mem_start, 0x10000);
-	if (!addr) {
-		printk(KERN_ERR "%s: failed to remap io memory\n",
-		       dev->dev.bus_id);
-		result = -ENXIO;
-		goto fail;
-	}
-
-	for (i = 0; i < config->num_regs; i++)
-		iowrite32(config->regs[i].value,
-			  (u32 *)(addr + config->regs[i].offset));
-
-	dev->priv = priv;
-	for (i = 0; i < VLYNQ_PCI_SLOTS; i++) {
-		if (!slots[i]) {
-			slots[i] = dev;
-			break;
-		}
-	}
-
-	return 0;
-
-fail:
-	vlynq_device_disable(dev);
-
-	return result;
-}
-
-static int vlynq_pci_remove(struct vlynq_device *dev)
-{
-	int i;
-	struct vlynq_pci_private *priv = dev->priv;
-
-	for (i = 0; i < VLYNQ_PCI_SLOTS; i++)
-		if (slots[i] == dev)
-			slots[i] = NULL;
-
-	vlynq_device_disable(dev);
-	kfree(priv);
-
-	return 0;
-}
-
-static struct vlynq_driver vlynq_pci = {
-	.name = "PCI over VLYNQ emulation",
-	.probe = vlynq_pci_probe,
-	.remove = vlynq_pci_remove,
-};
-
-int vlynq_pci_init(void)
-{
-	int res;
-	res = vlynq_register_driver(&vlynq_pci);
-	if (res)
-		return res;
-
-	register_pci_controller(&vlynq_controller);
-
-	return 0;
-}
-
-int pcibios_map_irq(struct pci_dev *pdev, u8 slot, u8 pin)
-{
-	struct vlynq_device *dev;
-	struct vlynq_pci_private *priv;
-
-	dev = slots[slot];
-
-	if (!dev)
-		return 0;
-
-	priv = dev->priv;
-
-	return vlynq_virq_to_irq(dev, priv->config->irq);
-}
-
-/* Do platform specific device initialization at pci_enable_device() time */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
-	return 0;
-}
diff --git a/target/linux/ar7/files/drivers/vlynq/Kconfig b/target/linux/ar7/files/drivers/vlynq/Kconfig
new file mode 100644
index 0000000000..2c8ffe0d19
--- /dev/null
+++ b/target/linux/ar7/files/drivers/vlynq/Kconfig
@@ -0,0 +1,13 @@
+menu "TI VLYNQ"
+
+config VLYNQ
+	bool "TI VLYNQ bus support"
+	depends on AR7 && EXPERIMENTAL
+	help
+	  Support for the TI VLYNQ bus
+
+	  The module will be called vlynq
+
+	  If unsure, say N
+
+endmenu
diff --git a/target/linux/ar7/files/drivers/vlynq/Makefile b/target/linux/ar7/files/drivers/vlynq/Makefile
new file mode 100644
index 0000000000..b3f61149b5
--- /dev/null
+++ b/target/linux/ar7/files/drivers/vlynq/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for kernel vlynq drivers
+#
+
+obj-$(CONFIG_VLYNQ) += vlynq.o
diff --git a/target/linux/ar7/files/arch/mips/ar7/vlynq.c b/target/linux/ar7/files/drivers/vlynq/vlynq.c
similarity index 81%
rename from target/linux/ar7/files/arch/mips/ar7/vlynq.c
rename to target/linux/ar7/files/drivers/vlynq/vlynq.c
index 4c0a86dbaf..0dd6c18307 100644
--- a/target/linux/ar7/files/arch/mips/ar7/vlynq.c
+++ b/target/linux/ar7/files/drivers/vlynq/vlynq.c
@@ -21,15 +21,14 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/device.h>
+#include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/device.h>
 #include <linux/io.h>
 
-#include <asm/ar7/vlynq.h>
-
-#define PER_DEVICE_IRQS			32
+#include <linux/vlynq.h>
 
 #define VLYNQ_CTRL_PM_ENABLE		0x80000000
 #define VLYNQ_CTRL_CLOCK_INT		0x00008000
@@ -74,6 +73,8 @@ struct vlynq_regs {
 #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
 static void vlynq_dump_regs(struct vlynq_device *dev)
 {
@@ -189,7 +190,6 @@ static void vlynq_remote_ack(unsigned int irq)
 	vlynq_reg_write(dev->remote->status, status);
 }
 
-#warning FIXME: process one irq per call
 static irqreturn_t vlynq_irq(int irq, void *dev_id)
 {
 	struct vlynq_device *dev = dev_id;
@@ -236,7 +236,7 @@ static struct irq_chip vlynq_remote_chip = {
 static int vlynq_setup_irq(struct vlynq_device *dev)
 {
 	u32 val;
-	int i;
+	int i, virq;
 
 	if (dev->local_irq == dev->remote_irq) {
 		printk(KERN_ERR
@@ -264,23 +264,21 @@ static int vlynq_setup_irq(struct vlynq_device *dev)
 	vlynq_reg_write(dev->remote->int_ptr, VLYNQ_INT_OFFSET);
 	vlynq_reg_write(dev->remote->control, val);
 
-	for (i = 0; i < PER_DEVICE_IRQS; i++) {
-		if (i == dev->local_irq) {
-			set_irq_chip_and_handler(dev->irq_start + i,
-						 &vlynq_local_chip,
+	for (i = dev->irq_start; i <= dev->irq_end; i++) {
+		virq = i - dev->irq_start;
+		if (virq == dev->local_irq) {
+			set_irq_chip_and_handler(i, &vlynq_local_chip,
 						 handle_level_irq);
-			set_irq_chip_data(dev->irq_start + i, dev);
-		} else if (i == dev->remote_irq) {
-			set_irq_chip_and_handler(dev->irq_start + i,
-						 &vlynq_remote_chip,
+			set_irq_chip_data(i, dev);
+		} else if (virq == dev->remote_irq) {
+			set_irq_chip_and_handler(i, &vlynq_remote_chip,
 						 handle_level_irq);
-			set_irq_chip_data(dev->irq_start + i, dev);
+			set_irq_chip_data(i, dev);
 		} else {
-			set_irq_chip_and_handler(dev->irq_start + i,
-						 &vlynq_irq_chip,
+			set_irq_chip_and_handler(i, &vlynq_irq_chip,
 						 handle_simple_irq);
-			set_irq_chip_data(dev->irq_start + i, dev);
-			vlynq_reg_write(dev->remote->int_device[i >> 2], 0);
+			set_irq_chip_data(i, dev);
+			vlynq_reg_write(dev->remote->int_device[virq >> 2], 0);
 		}
 	}
 
@@ -292,30 +290,59 @@ static int vlynq_setup_irq(struct vlynq_device *dev)
 	return 0;
 }
 
-static void vlynq_free_irq(struct vlynq_device *dev)
+static void vlynq_device_release(struct device *dev)
 {
-	free_irq(dev->irq, dev);
+	struct vlynq_device *vdev = to_vlynq_device(dev);
+	kfree(vdev);
 }
 
-static void vlynq_device_release(struct device *dev)
+static int vlynq_device_match(struct device *dev,
+			      struct device_driver *drv)
 {
 	struct vlynq_device *vdev = to_vlynq_device(dev);
-	kfree(vdev);
+	struct vlynq_driver *vdrv = to_vlynq_driver(drv);
+	struct plat_vlynq_ops *ops = dev->platform_data;
+	struct vlynq_device_id *ids = vdrv->id_table;
+	u32 id = 0;
+	int result;
+
+	while (ids->id) {
+		vdev->divisor = ids->divisor;
+		result = __vlynq_enable_device(vdev);
+		if (result == 0) {
+			id = vlynq_reg_read(vdev->remote->chip);
+			ops->off(vdev);
+			if (ids->id == id) {
+				vlynq_set_drvdata(vdev, ids);
+				return 1;
+			}
+		}
+		ids++;
+	}
+	return 0;
 }
 
 static int vlynq_device_probe(struct device *dev)
 {
+	struct vlynq_device *vdev = to_vlynq_device(dev);
 	struct vlynq_driver *drv = to_vlynq_driver(dev->driver);
-	if (drv->probe)
-		return drv->probe(to_vlynq_device(dev));
-	return 0;
+	struct vlynq_device_id *id = vlynq_get_drvdata(vdev);
+	int result = -ENODEV;
+
+	get_device(dev);
+	if (drv && drv->probe)
+		result = drv->probe(vdev, id);
+	if (result)
+		put_device(dev);
+	return result;
 }
 
 static int vlynq_device_remove(struct device *dev)
 {
 	struct vlynq_driver *drv = to_vlynq_driver(dev->driver);
-	if (drv->remove)
-		return drv->remove(to_vlynq_device(dev));
+	if (drv && drv->remove)
+		drv->remove(to_vlynq_device(dev));
+	put_device(dev);
 	return 0;
 }
 
@@ -333,7 +360,7 @@ void vlynq_unregister_driver(struct vlynq_driver *driver)
 }
 EXPORT_SYMBOL(vlynq_unregister_driver);
 
-int vlynq_device_enable(struct vlynq_device *dev)
+static int __vlynq_enable_device(struct vlynq_device *dev)
 {
 	int i, result;
 	struct plat_vlynq_ops *ops = dev->dev.platform_data;
@@ -344,7 +371,7 @@ int vlynq_device_enable(struct vlynq_device *dev)
 
 	switch (dev->divisor) {
 	case vlynq_div_auto:
-		/* First try locally supplied clock */
+		/* Only try locally supplied clock, others cause problems */
 		vlynq_reg_write(dev->remote->control, 0);
 		for (i = vlynq_ldiv1; i <= vlynq_ldiv8; i++) {
 			vlynq_reg_write(dev->local->control,
@@ -354,30 +381,10 @@ int vlynq_device_enable(struct vlynq_device *dev)
 				printk(KERN_DEBUG
 				       "%s: using local clock divisor %d\n",
 				       dev->dev.bus_id, i - vlynq_ldiv1 + 1);
-				return vlynq_setup_irq(dev);
+				dev->divisor = i;
+				return 0;
 			}
 		}
-		/* Then remotely supplied clock */
-		vlynq_reg_write(dev->local->control, 0);
-		for (i = vlynq_rdiv1; i <= vlynq_rdiv8; i++) {
-			vlynq_reg_write(dev->remote->control,
-					VLYNQ_CTRL_CLOCK_INT |
-					VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1));
-			if (vlynq_linked(dev)) {
-				printk(KERN_DEBUG
-				       "%s: using remote clock divisor %d\n",
-				       dev->dev.bus_id, i - vlynq_rdiv1 + 1);
-				return vlynq_setup_irq(dev);
-			}
-		}
-		/* At last, externally supplied clock */
-		vlynq_reg_write(dev->remote->control, 0);
-		if (vlynq_linked(dev)) {
-			printk(KERN_DEBUG "%s: using external clock\n",
-			       dev->dev.bus_id);
-			return vlynq_setup_irq(dev);
-		}
-		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->remote->control, 0);
@@ -389,7 +396,7 @@ int vlynq_device_enable(struct vlynq_device *dev)
 			printk(KERN_DEBUG
 			       "%s: using local clock divisor %d\n",
 			       dev->dev.bus_id, dev->divisor - vlynq_ldiv1 + 1);
-			return vlynq_setup_irq(dev);
+			return 0;
 		}
 		break;
 	case vlynq_rdiv1: case vlynq_rdiv2: case vlynq_rdiv3: case vlynq_rdiv4:
@@ -403,7 +410,7 @@ int vlynq_device_enable(struct vlynq_device *dev)
 			printk(KERN_DEBUG
 			       "%s: using remote clock divisor %d\n",
 			       dev->dev.bus_id, dev->divisor - vlynq_rdiv1 + 1);
-			return vlynq_setup_irq(dev);
+			return 0;
 		}
 		break;
 	case vlynq_div_external:
@@ -412,32 +419,52 @@ int vlynq_device_enable(struct vlynq_device *dev)
 		if (vlynq_linked(dev)) {
 			printk(KERN_DEBUG "%s: using external clock\n",
 			       dev->dev.bus_id);
-			return vlynq_setup_irq(dev);
+			return 0;
 		}
 		break;
 	}
 
+	ops->off(dev);
 	return -ENODEV;
 }
 
-void vlynq_device_disable(struct vlynq_device *dev)
+int vlynq_enable_device(struct vlynq_device *dev)
 {
 	struct plat_vlynq_ops *ops = dev->dev.platform_data;
+	int result = -ENODEV;
 
-	vlynq_free_irq(dev);
-	ops->off(dev);
+	result = __vlynq_enable_device(dev);
+	if (result)
+		return result;
+
+	result = vlynq_setup_irq(dev);
+	if (result)
+		ops->off(dev);
+
+	dev->enabled = !result;
+	return result;
 }
+EXPORT_SYMBOL(vlynq_enable_device);
+
 
-u32 vlynq_remote_id(struct vlynq_device *dev)
+void vlynq_disable_device(struct vlynq_device *dev)
 {
-	return vlynq_reg_read(dev->remote->chip);
+	struct plat_vlynq_ops *ops = dev->dev.platform_data;
+
+	dev->enabled = 0;
+	free_irq(dev->irq, dev);
+	ops->off(dev);
 }
+EXPORT_SYMBOL(vlynq_disable_device);
 
-void vlynq_set_local_mapping(struct vlynq_device *dev, u32 tx_offset,
-			     struct vlynq_mapping *mapping)
+int vlynq_set_local_mapping(struct vlynq_device *dev, u32 tx_offset,
+			    struct vlynq_mapping *mapping)
 {
 	int i;
 
+	if (!dev->enabled)
+		return -ENXIO;
+
 	vlynq_reg_write(dev->local->tx_offset, tx_offset);
 	for (i = 0; i < 4; i++) {
 		vlynq_reg_write(dev->local->rx_mapping[i].offset,
@@ -445,13 +472,18 @@ void vlynq_set_local_mapping(struct vlynq_device *dev, u32 tx_offset,
 		vlynq_reg_write(dev->local->rx_mapping[i].size,
 							mapping[i].size);
 	}
+	return 0;
 }
+EXPORT_SYMBOL(vlynq_set_local_mapping);
 
-void vlynq_set_remote_mapping(struct vlynq_device *dev, u32 tx_offset,
-			      struct vlynq_mapping *mapping)
+int vlynq_set_remote_mapping(struct vlynq_device *dev, u32 tx_offset,
+			     struct vlynq_mapping *mapping)
 {
 	int i;
 
+	if (!dev->enabled)
+		return -ENXIO;
+
 	vlynq_reg_write(dev->remote->tx_offset, tx_offset);
 	for (i = 0; i < 4; i++) {
 		vlynq_reg_write(dev->remote->rx_mapping[i].offset,
@@ -459,27 +491,17 @@ void vlynq_set_remote_mapping(struct vlynq_device *dev, u32 tx_offset,
 		vlynq_reg_write(dev->remote->rx_mapping[i].size,
 							mapping[i].size);
 	}
+	return 0;
 }
-
-int vlynq_virq_to_irq(struct vlynq_device *dev, int virq)
-{
-	if ((virq < 0) || (virq >= PER_DEVICE_IRQS))
-		return -EINVAL;
-
-	return dev->irq_start + virq;
-}
-
-int vlynq_irq_to_virq(struct vlynq_device *dev, int irq)
-{
-	if ((irq < dev->irq_start) || (irq >= dev->irq_start + PER_DEVICE_IRQS))
-		return -EINVAL;
-
-	return irq - dev->irq_start;
-}
+EXPORT_SYMBOL(vlynq_set_remote_mapping);
 
 int vlynq_set_local_irq(struct vlynq_device *dev, int virq)
 {
-	if ((virq < 0) || (virq >= PER_DEVICE_IRQS))
+	int irq = dev->irq_start + virq;
+	if (dev->enabled)
+		return -EBUSY;
+
+	if ((irq < dev->irq_start) || (irq > dev->irq_end))
 		return -EINVAL;
 
 	if (virq == dev->remote_irq)
@@ -489,10 +511,15 @@ int vlynq_set_local_irq(struct vlynq_device *dev, int virq)
 
 	return 0;
 }
+EXPORT_SYMBOL(vlynq_set_local_irq);
 
 int vlynq_set_remote_irq(struct vlynq_device *dev, int virq)
 {
-	if ((virq < 0) || (virq >= PER_DEVICE_IRQS))
+	int irq = dev->irq_start + virq;
+	if (dev->enabled)
+		return -EBUSY;
+
+	if ((irq < dev->irq_start) || (irq > dev->irq_end))
 		return -EINVAL;
 
 	if (virq == dev->local_irq)
@@ -502,6 +529,7 @@ int vlynq_set_remote_irq(struct vlynq_device *dev, int virq)
 
 	return 0;
 }
+EXPORT_SYMBOL(vlynq_set_remote_irq);
 
 static int vlynq_probe(struct platform_device *pdev)
 {
@@ -509,9 +537,6 @@ static int vlynq_probe(struct platform_device *pdev)
 	struct resource *regs_res, *mem_res, *irq_res;
 	int len, result;
 
-	if (strcmp(pdev->name, "vlynq"))
-		return -ENODEV;
-
 	regs_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
 	if (!regs_res)
 		return -ENODEV;
@@ -560,14 +585,14 @@ static int vlynq_probe(struct platform_device *pdev)
 		goto fail_remap;
 	}
 
-	dev->remote = (struct vlynq_regs *)((u32)dev->local +
+	dev->remote = (struct vlynq_regs *)((void *)dev->local +
 					    VLYNQ_REMOTE_OFFSET);
 
 	dev->irq = platform_get_irq_byname(pdev, "irq");
 	dev->irq_start = irq_res->start;
 	dev->irq_end = irq_res->end;
-	dev->local_irq = 31;
-	dev->remote_irq = 30;
+	dev->local_irq = dev->irq_end - dev->irq_start;
+	dev->remote_irq = dev->local_irq - 1;
 
 	if (device_register(&dev->dev))
 		goto fail_register;
@@ -604,20 +629,18 @@ static int vlynq_remove(struct platform_device *pdev)
 static struct platform_driver vlynq_driver = {
 	.driver.name = "vlynq",
 	.probe = vlynq_probe,
-	.remove = vlynq_remove,
+	.remove = __devexit_p(vlynq_remove),
 };
 
 struct bus_type vlynq_bus_type = {
 	.name = "vlynq",
+	.match = vlynq_device_match,
 	.probe = vlynq_device_probe,
 	.remove = vlynq_device_remove,
 };
 EXPORT_SYMBOL(vlynq_bus_type);
 
-#ifdef CONFIG_PCI
-extern void vlynq_pci_init(void);
-#endif
-static int __init vlynq_init(void)
+static int __devinit vlynq_init(void)
 {
 	int res = 0;
 
@@ -629,10 +652,6 @@ static int __init vlynq_init(void)
 	if (res)
 		goto fail_platform;
 
-#ifdef CONFIG_PCI
-	vlynq_pci_init();
-#endif
-
 	return 0;
 
 fail_platform:
@@ -641,13 +660,11 @@ fail_bus:
 	return res;
 }
 
-/* Add this back when vlynq-pci crap is gone */
-#if 0
 static void __devexit vlynq_exit(void)
 {
 	platform_driver_unregister(&vlynq_driver);
 	bus_unregister(&vlynq_bus_type);
 }
-#endif
 
-subsys_initcall(vlynq_init);
+module_init(vlynq_init);
+module_exit(vlynq_exit);
diff --git a/target/linux/ar7/files/include/asm-mips/ar7/vlynq.h b/target/linux/ar7/files/include/linux/vlynq.h
similarity index 56%
rename from target/linux/ar7/files/include/asm-mips/ar7/vlynq.h
rename to target/linux/ar7/files/include/linux/vlynq.h
index e2cfe8770c..b3f24741bb 100644
--- a/target/linux/ar7/files/include/asm-mips/ar7/vlynq.h
+++ b/target/linux/ar7/files/include/linux/vlynq.h
@@ -23,13 +23,11 @@
 #include <linux/module.h>
 #include <linux/types.h>
 
+#define VLYNQ_NUM_IRQS 32
+
 struct vlynq_mapping {
 	u32 size;
 	u32 offset;
-} __attribute__ ((packed));
-
-struct vlynq_device_id {
-	u32 id;
 };
 
 enum vlynq_divisor {
@@ -53,17 +51,23 @@ enum vlynq_divisor {
 	vlynq_div_external
 };
 
+struct vlynq_device_id {
+	u32 id;
+	enum vlynq_divisor divisor;
+	unsigned long driver_data;
+};
+
 struct vlynq_regs;
 struct vlynq_device {
 	u32 id;
-	int irq;
 	int local_irq;
 	int remote_irq;
 	enum vlynq_divisor divisor;
 	u32 regs_start, regs_end;
 	u32 mem_start, mem_end;
 	u32 irq_start, irq_end;
-	void *priv;
+	int irq;
+	int enabled;
 	struct vlynq_regs *local;
 	struct vlynq_regs *remote;
 	struct device dev;
@@ -71,19 +75,26 @@ struct vlynq_device {
 
 struct vlynq_driver {
 	char *name;
-	int (*probe)(struct vlynq_device *dev);
-	int (*remove)(struct vlynq_device *dev);
+	struct vlynq_device_id *id_table;
+	int (*probe)(struct vlynq_device *dev, struct vlynq_device_id *id);
+	void (*remove)(struct vlynq_device *dev);
 	struct device_driver driver;
 };
 
-#define to_vlynq_driver(drv) container_of(drv, struct vlynq_driver, driver)
-
 struct plat_vlynq_ops {
 	int (*on)(struct vlynq_device *dev);
 	void (*off)(struct vlynq_device *dev);
 };
 
-#define to_vlynq_device(device) container_of(device, struct vlynq_device, dev)
+static inline struct vlynq_driver *to_vlynq_driver(struct device_driver *drv)
+{
+	return container_of(drv, struct vlynq_driver, driver);
+}
+
+static inline struct vlynq_device *to_vlynq_device(struct device *device)
+{
+	return container_of(device, struct vlynq_device, dev);
+}
 
 extern struct bus_type vlynq_bus_type;
 
@@ -95,18 +106,55 @@ static inline int vlynq_register_driver(struct vlynq_driver *driver)
 	return __vlynq_register_driver(driver, THIS_MODULE);
 }
 
+static inline void *vlynq_get_drvdata(struct vlynq_device *dev)
+{
+	return dev_get_drvdata(&dev->dev);
+}
+
+static inline void vlynq_set_drvdata(struct vlynq_device *dev, void *data)
+{
+	dev_set_drvdata(&dev->dev, data);
+}
+
+static inline u32 vlynq_mem_start(struct vlynq_device *dev)
+{
+	return dev->mem_start;
+}
+
+static inline u32 vlynq_mem_end(struct vlynq_device *dev)
+{
+	return dev->mem_end;
+}
+
+static inline u32 vlynq_mem_len(struct vlynq_device *dev)
+{
+	return dev->mem_end - dev->mem_start + 1;
+}
+
+static inline int vlynq_virq_to_irq(struct vlynq_device *dev, int virq)
+{
+	int irq = dev->irq_start + virq;
+	if ((irq < dev->irq_start) || (irq > dev->irq_end))
+		return -EINVAL;
+
+	return irq;
+}
+
+static inline int vlynq_irq_to_virq(struct vlynq_device *dev, int irq)
+{
+	if ((irq < dev->irq_start) || (irq > dev->irq_end))
+		return -EINVAL;
+
+	return irq - dev->irq_start;
+}
+
 extern void vlynq_unregister_driver(struct vlynq_driver *driver);
-extern int vlynq_device_enable(struct vlynq_device *dev);
-extern void vlynq_device_disable(struct vlynq_device *dev);
-extern u32 vlynq_remote_id(struct vlynq_device *dev);
-extern void vlynq_set_local_mapping(struct vlynq_device *dev,
-				    u32 tx_offset,
+extern int vlynq_enable_device(struct vlynq_device *dev);
+extern void vlynq_disable_device(struct vlynq_device *dev);
+extern int vlynq_set_local_mapping(struct vlynq_device *dev, u32 tx_offset,
+				   struct vlynq_mapping *mapping);
+extern int vlynq_set_remote_mapping(struct vlynq_device *dev, u32 tx_offset,
 				    struct vlynq_mapping *mapping);
-extern void vlynq_set_remote_mapping(struct vlynq_device *dev,
-				     u32 tx_offset,
-				     struct vlynq_mapping *mapping);
-extern int vlynq_virq_to_irq(struct vlynq_device *dev, int virq);
-extern int vlynq_irq_to_virq(struct vlynq_device *dev, int irq);
 extern int vlynq_set_local_irq(struct vlynq_device *dev, int virq);
 extern int vlynq_set_remote_irq(struct vlynq_device *dev, int virq);
 
diff --git a/target/linux/ar7/patches-2.6.22/100-board_support.patch b/target/linux/ar7/patches-2.6.22/100-board_support.patch
index b1577150c9..59fafa55a0 100644
--- a/target/linux/ar7/patches-2.6.22/100-board_support.patch
+++ b/target/linux/ar7/patches-2.6.22/100-board_support.patch
@@ -1,7 +1,7 @@
 diff -urN linux-2.6.22/arch/mips/Kconfig linux-2.6.22.new/arch/mips/Kconfig
 --- linux-2.6.22/arch/mips/Kconfig	2007-07-09 01:32:17.000000000 +0200
 +++ linux-2.6.22.new/arch/mips/Kconfig	2007-07-11 02:34:51.000000000 +0200
-@@ -15,6 +15,22 @@
+@@ -15,6 +15,21 @@
  	prompt "System type"
  	default SGI_IP22
  
@@ -9,7 +9,6 @@ diff -urN linux-2.6.22/arch/mips/Kconfig linux-2.6.22.new/arch/mips/Kconfig
 +	bool "Texas Instruments AR7"
 +	select BOOT_ELF32
 +	select DMA_NONCOHERENT
-+	select HW_HAS_PCI
 +	select IRQ_CPU
 +	select SWAP_IO_SPACE
 +	select SYS_HAS_CPU_MIPS32_R1
diff --git a/target/linux/ar7/patches-2.6.22/130-vlynq.patch b/target/linux/ar7/patches-2.6.22/130-vlynq.patch
new file mode 100644
index 0000000000..2e8dea3ed9
--- /dev/null
+++ b/target/linux/ar7/patches-2.6.22/130-vlynq.patch
@@ -0,0 +1,20 @@
+Index: linux-2.6.22.4/drivers/Kconfig
+===================================================================
+--- linux-2.6.22.4.orig/drivers/Kconfig	2007-10-06 01:09:43.000000000 +0800
++++ linux-2.6.22.4/drivers/Kconfig	2007-10-06 01:12:19.000000000 +0800
+@@ -84,4 +84,6 @@
+ 
+ source "drivers/kvm/Kconfig"
+ 
++source "drivers/vlynq/Kconfig"
++
+ endmenu
+Index: linux-2.6.22.4/drivers/Makefile
+===================================================================
+--- linux-2.6.22.4.orig/drivers/Makefile	2007-10-06 01:09:43.000000000 +0800
++++ linux-2.6.22.4/drivers/Makefile	2007-10-06 01:12:37.000000000 +0800
+@@ -81,3 +81,4 @@
+ obj-$(CONFIG_DMA_ENGINE)	+= dma/
+ obj-$(CONFIG_HID)		+= hid/
+ obj-$(CONFIG_PPC_PS3)		+= ps3/
++obj-$(CONFIG_VLYNQ)		+= vlynq/
diff --git a/target/linux/ar7/patches-2.6.23/100-board_support.patch b/target/linux/ar7/patches-2.6.23/100-board_support.patch
index c3da71b267..9269a13a30 100644
--- a/target/linux/ar7/patches-2.6.23/100-board_support.patch
+++ b/target/linux/ar7/patches-2.6.23/100-board_support.patch
@@ -2,7 +2,7 @@ Index: linux-2.6.23-rc6/arch/mips/Kconfig
 ===================================================================
 --- linux-2.6.23-rc6.orig/arch/mips/Kconfig	2007-09-21 16:23:51.000000000 +0800
 +++ linux-2.6.23-rc6/arch/mips/Kconfig	2007-09-21 16:24:11.000000000 +0800
-@@ -15,6 +15,23 @@
+@@ -15,6 +15,22 @@
  	prompt "System type"
  	default SGI_IP22
  
@@ -10,7 +10,6 @@ Index: linux-2.6.23-rc6/arch/mips/Kconfig
 +	bool "Texas Instruments AR7"
 +	select BOOT_ELF32
 +	select DMA_NONCOHERENT
-+	select HW_HAS_PCI
 +	select IRQ_CPU
 +	select NO_EXCEPT_FILL
 +	select SWAP_IO_SPACE
diff --git a/target/linux/ar7/patches-2.6.23/130-vlynq.patch b/target/linux/ar7/patches-2.6.23/130-vlynq.patch
new file mode 100644
index 0000000000..6cdb4df985
--- /dev/null
+++ b/target/linux/ar7/patches-2.6.23/130-vlynq.patch
@@ -0,0 +1,20 @@
+Index: linux-2.6.23-rc9/drivers/Kconfig
+===================================================================
+--- linux-2.6.23-rc9.orig/drivers/Kconfig	2007-10-05 20:47:14.000000000 +0800
++++ linux-2.6.23-rc9/drivers/Kconfig	2007-10-05 20:47:42.000000000 +0800
+@@ -89,4 +89,6 @@
+ source "drivers/uio/Kconfig"
+ 
+ source "drivers/lguest/Kconfig"
++
++source "drivers/vlynq/Kconfig"
+ endmenu
+Index: linux-2.6.23-rc9/drivers/Makefile
+===================================================================
+--- linux-2.6.23-rc9.orig/drivers/Makefile	2007-10-05 20:47:09.000000000 +0800
++++ linux-2.6.23-rc9/drivers/Makefile	2007-10-05 20:47:30.000000000 +0800
+@@ -88,3 +88,4 @@
+ obj-$(CONFIG_HID)		+= hid/
+ obj-$(CONFIG_PPC_PS3)		+= ps3/
+ obj-$(CONFIG_OF)		+= of/
++obj-$(CONFIG_VLYNQ)		+= vlynq/
-- 
GitLab