diff --git a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile
index 7444dec..71f715b 100644
--- a/drivers/char/drm/Makefile
+++ b/drivers/char/drm/Makefile
@@ -15,15 +15,19 @@ mga-objs    := mga_drv.o mga_dma.o mga_s
 i810-objs   := i810_drv.o i810_dma.o
 i830-objs   := i830_drv.o i830_dma.o i830_irq.o
 i915-objs   := i915_drv.o i915_dma.o i915_irq.o i915_mem.o
-radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o
+radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o
 ffb-objs    := ffb_drv.o ffb_context.o
 sis-objs    := sis_drv.o sis_ds.o sis_mm.o
 
 ifeq ($(CONFIG_COMPAT),y)
 drm-objs    += drm_ioc32.o
-radeon-objs += radeon_ioc32.o
+radeon-y += radeon_ioc32.o
 endif
 
+radeon-$(CONFIG_RADEON_LL) += radeon_drmll.o
+radeon-objs := $(radeon-y) $(radeon-m)
+
+
 obj-$(CONFIG_DRM)	+= drm.o
 obj-$(CONFIG_DRM_GAMMA) += gamma.o
 obj-$(CONFIG_DRM_TDFX)	+= tdfx.o
@@ -36,3 +40,5 @@ obj-$(CONFIG_DRM_I915)  += i915.o
 obj-$(CONFIG_DRM_FFB)   += ffb.o
 obj-$(CONFIG_DRM_SIS)   += sis.o
 
+
+
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index b04ddf1..4844db1 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -74,6 +74,7 @@
 #include <linux/workqueue.h>
 #include <linux/poll.h>
 #include <asm/pgalloc.h>
+#include <linux/vga_lowlevel.h>
 #include "drm.h"
 
 #define __OS_HAS_AGP (defined(CONFIG_AGP) || (defined(CONFIG_AGP_MODULE) && defined(MODULE)))
@@ -552,7 +553,10 @@ typedef struct drm_vbl_sig {
 	struct task_struct	*task;
 } drm_vbl_sig_t;
 
-
+enum drm_drv_type {
+	DRM_DRIVER_PCI=1,
+	DRM_DRIVER_VLL
+};
 /**
  * DRM driver structure. This structure represent the common code for
  * a family of cards. There will one drm_device for each card present
@@ -594,9 +598,15 @@ struct drm_driver {
 	drm_ioctl_desc_t *ioctls;
 	int num_ioctls;
 	struct file_operations fops;
-	struct pci_driver pci_driver;
+	enum drm_drv_type driver_type;
+	union {
+		struct pci_driver pci_driver;
+		struct vll_driver vll_driver;
+	} u;
 };
 
+#define radeondrm_to_vll_driver(n) container_of(n, struct drm_driver, u.vll_driver)
+
 /**
  * DRM head structure. This structure represent a video head on a card
  * that may contain multiple heads. Embed one per head of these in the
diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c
index 8d94c0b..c05c3d5 100644
--- a/drivers/char/drm/drm_agpsupport.c
+++ b/drivers/char/drm/drm_agpsupport.c
@@ -413,6 +413,7 @@ drm_agp_head_t *drm_agp_init(drm_device_
 
 	return head;
 }
+EXPORT_SYMBOL(drm_agp_init);
 
 /** Calls agp_allocate_memory() */
 DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size_t pages, u32 type)
diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c
index fdf661f..a524962 100644
--- a/drivers/char/drm/drm_context.c
+++ b/drivers/char/drm/drm_context.c
@@ -166,6 +166,7 @@ int drm_ctxbitmap_init( drm_device_t *de
 
 	return 0;
 }
+EXPORT_SYMBOL(drm_ctxbitmap_init);
 
 /**
  * Context bitmap cleanup.
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index 1e37ed0..048866b 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -263,6 +263,7 @@ int drm_takedown( drm_device_t *dev )
 
 	return 0;
 }
+EXPORT_SYMBOL(drm_takedown);
 
 
 
@@ -289,8 +290,8 @@ int drm_init( struct drm_driver *driver 
 
 	drm_mem_init();
 
-	for (i=0; driver->pci_driver.id_table[i].vendor != 0; i++) {
-		pid = (struct pci_device_id *)&driver->pci_driver.id_table[i];
+	for (i=0; driver->u.pci_driver.id_table[i].vendor != 0; i++) {
+		pid = (struct pci_device_id *)&driver->u.pci_driver.id_table[i];
 		
 		pdev=NULL;
 		/* pass back in pdev to account for multiple identical cards */		
diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c
index 39afda0..2d8a152 100644
--- a/drivers/char/drm/drm_ioctl.c
+++ b/drivers/char/drm/drm_ioctl.c
@@ -106,12 +106,12 @@ int drm_setunique(struct inode *inode, s
 
 	dev->unique[dev->unique_len] = '\0';
 
-	dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + strlen(dev->unique) + 2,
+	dev->devname = drm_alloc(strlen(dev->driver->u.pci_driver.name) + strlen(dev->unique) + 2,
 				  DRM_MEM_DRIVER);
 	if (!dev->devname)
 		return -ENOMEM;
 
-	sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique);
+	sprintf(dev->devname, "%s@%s", dev->driver->u.pci_driver.name, dev->unique);
 
 	/* Return error if the busid submitted doesn't match the device's actual
 	 * busid.
@@ -145,12 +145,12 @@ drm_set_busid(drm_device_t *dev)
 	snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d",
 		dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
 
-	dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + 2,
+	dev->devname = drm_alloc(strlen(dev->driver->u.pci_driver.name) + dev->unique_len + 2,
 				DRM_MEM_DRIVER);
 	if (dev->devname == NULL)
 		return ENOMEM;
 
-	sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique);
+	sprintf(dev->devname, "%s@%s", dev->driver->u.pci_driver.name, dev->unique);
 
 	return 0;
 }
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
index 6e06e8c..b80a716 100644
--- a/drivers/char/drm/drm_proc.c
+++ b/drivers/char/drm/drm_proc.c
@@ -176,9 +176,9 @@ static int drm_name_info(char *buf, char
 
 	if (dev->unique) {
 		DRM_PROC_PRINT("%s %s %s\n",
-			       dev->driver->pci_driver.name, pci_name(dev->pdev), dev->unique);
+			       dev->driver->u.pci_driver.name, pci_name(dev->pdev), dev->unique);
 	} else {
-		DRM_PROC_PRINT("%s %s\n", dev->driver->pci_driver.name, pci_name(dev->pdev));
+		DRM_PROC_PRINT("%s %s\n", dev->driver->u.pci_driver.name, pci_name(dev->pdev));
 	}
 
 	if (len > request + offset) return request;
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
index 8ccbdef..4054262 100644
--- a/drivers/char/drm/drm_stub.c
+++ b/drivers/char/drm/drm_stub.c
@@ -261,6 +261,7 @@ err_g1:
 	*head = (drm_head_t) {.dev = NULL};
 	return ret;
 }
+EXPORT_SYMBOL(drm_get_head);
 		
 
 /**
@@ -275,7 +276,7 @@ err_g1:
  */
 int drm_put_dev(drm_device_t * dev)
 {
-	DRM_DEBUG("release primary %s\n", dev->driver->pci_driver.name);
+	DRM_DEBUG("release primary %s\n", dev->driver->u.pci_driver.name);
 
 	if (dev->unique) {
 		drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER);
diff --git a/drivers/char/drm/i810_drv.c b/drivers/char/drm/i810_drv.c
index ff51b32..4a8f942 100644
--- a/drivers/char/drm/i810_drv.c
+++ b/drivers/char/drm/i810_drv.c
@@ -101,10 +101,12 @@ static struct drm_driver driver = {
 		.poll = drm_poll,
 		.fasync = drm_fasync,
 	},
-	.pci_driver = {
-		.name          = DRIVER_NAME,
-		.id_table      = pciidlist,
-	},
+	.u = {
+		 .pci_driver = {
+			 .name          = DRIVER_NAME,
+			 .id_table      = pciidlist,
+		 },
+	 },
 };
 
 static int __init i810_init(void)
diff --git a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c
index aa80ad6..94dd1f2 100644
--- a/drivers/char/drm/i830_drv.c
+++ b/drivers/char/drm/i830_drv.c
@@ -111,10 +111,12 @@ static struct drm_driver driver = {
 		.poll = drm_poll,
 		.fasync = drm_fasync,
 	},
-	.pci_driver = {
-		.name          = DRIVER_NAME,
-		.id_table      = pciidlist,
-	}
+	.u = {
+		 .pci_driver = {
+			 .name          = DRIVER_NAME,
+			 .id_table      = pciidlist,
+		 }
+	 },
 
 };
 
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
index e6a9e1d..7439b8a 100644
--- a/drivers/char/drm/i915_drv.c
+++ b/drivers/char/drm/i915_drv.c
@@ -98,10 +98,12 @@ static struct drm_driver driver = {
 		.poll = drm_poll,
 		.fasync = drm_fasync,
 	},
-	.pci_driver = {
-		.name          = DRIVER_NAME,
-		.id_table      = pciidlist,
-	}
+	.u = {
+		 .pci_driver = {
+			 .name          = DRIVER_NAME,
+			 .id_table      = pciidlist,
+		 }
+	 },
 };
 
 static int __init i915_init(void)
diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c
index 22dab3e..68cd0ad 100644
--- a/drivers/char/drm/mga_drv.c
+++ b/drivers/char/drm/mga_drv.c
@@ -102,10 +102,12 @@ static struct drm_driver driver = {
 		.poll = drm_poll,
 		.fasync = drm_fasync,
 	},
-	.pci_driver = {
-		.name = DRIVER_NAME,
-		.id_table = pciidlist,
-	}
+	.u = {
+		 .pci_driver = {
+			 .name = DRIVER_NAME,
+			 .id_table = pciidlist,
+		 }
+	 }
 };
 
 static int __init mga_init(void)
diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c
index ced6381..2a756d6 100644
--- a/drivers/char/drm/r128_drv.c
+++ b/drivers/char/drm/r128_drv.c
@@ -97,10 +97,12 @@ static struct drm_driver driver = {
 		.poll = drm_poll,
 		.fasync = drm_fasync,
 	},
-	.pci_driver = {
-		.name          = DRIVER_NAME,
-		.id_table      = pciidlist,
-	}
+	.u = {
+		 .pci_driver = {
+			 .name          = DRIVER_NAME,
+			 .id_table      = pciidlist,
+		 }
+	 }
 };
 
 static int __init r128_init(void)
diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c
index 18e4e5b..5695bc3 100644
--- a/drivers/char/drm/radeon_drv.c
+++ b/drivers/char/drm/radeon_drv.c
@@ -65,9 +65,11 @@ static int version( drm_version_t *versi
 	return 0;
 }
 
+#if !defined(CONFIG_RADEON_LL) && !defined(CONFIG_RADEON_LL_MODULE)
 static struct pci_device_id pciidlist[] = {
 	radeon_PCI_IDS
 };
+#endif
 
 extern drm_ioctl_desc_t radeon_ioctls[];
 extern int radeon_max_ioctl;
@@ -105,16 +107,38 @@ static struct drm_driver driver = {
 		.compat_ioctl = radeon_compat_ioctl,
 #endif
 	},
-	.pci_driver = {
-		.name          = DRIVER_NAME,
-		.id_table      = pciidlist,
-	}
+#if !defined(CONFIG_RADEON_LL) && !defined(CONFIG_RADEON_LL_MODULE)
+	.driver_type = DRM_DRIVER_PCI,
+	.u = {
+		 .pci_driver = {
+			 .name = DRIVER_NAME,
+			 .id_table = pciidlist,
+		 }
+	 },
+#else
+	.driver_type = DRM_DRIVER_VLL,
+	.u = {
+		 .vll_driver = {
+			 .name = DRIVER_NAME,
+			 .type = VGA_DRM,
+			 .probe = radeondrm_register,
+			 .remove = __devexit_p(radeondrm_unregister),
+			 .suspend = radeondrm_suspend,
+			 .resume = radeondrm_resume,
+			 .get_entrypoints = radeondrm_getentrypoints,
+		 }
+	 },
+#endif
 };
 
 static int __init radeon_init(void)
 {
-	driver.num_ioctls = radeon_max_ioctl;
+	driver.num_ioctls = radeon_max_ioctl;	
+#if defined(CONFIG_RADEON_LL) || defined(CONFIG_RADEON_LL_MODULE)
+	return radeonll_register_driver (&driver.u.vll_driver);
+#else
 	return drm_init(&driver);
+#endif
 }
 
 static void __exit radeon_exit(void)
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index 771aa80..b770ac8 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -93,7 +93,7 @@
 /*
  * Radeon chip families
  */
-enum radeon_family {
+enum radeondrm_family {
 	CHIP_R100,
 	CHIP_RS100,
 	CHIP_RV100,
@@ -119,6 +119,7 @@ enum radeon_cp_microcode_version {
 /*
  * Chip flags
  */
+#if 0
 enum radeon_chip_flags {
 	CHIP_FAMILY_MASK = 0x0000ffffUL,
 	CHIP_FLAGS_MASK = 0xffff0000UL,
@@ -128,6 +129,7 @@ enum radeon_chip_flags {
 	CHIP_IS_AGP = 0x00080000UL,
 	CHIP_HAS_HIERZ = 0x00100000UL, 
 };
+#endif
 
 typedef struct drm_radeon_freelist {
    	unsigned int age;
@@ -320,6 +322,15 @@ extern int radeon_postcleanup( struct dr
 extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
 				unsigned long arg);
 
+#if defined(CONFIG_RADEON_LL) || defined(CONFIG_RADEON_LL_MODULE)
+#include <linux/radeon_lowlevel.h>
+extern int radeondrm_register(struct vll_driver *vdrv, struct vll_dev *vdev);
+extern void radeondrm_unregister(struct vll_dev *vdev);
+extern int radeondrm_suspend(struct vll_dev *vdev, pm_message_t state);
+extern int radeondrm_resume(struct vll_dev *vdev);
+extern void *radeondrm_getentrypoints(void);
+#endif
+
 /* Flags for stats.boxes
  */
 #define RADEON_BOX_DMA_IDLE      0x1
diff --git a/drivers/char/drm/sis_drv.c b/drivers/char/drm/sis_drv.c
index f441714..77a5912 100644
--- a/drivers/char/drm/sis_drv.c
+++ b/drivers/char/drm/sis_drv.c
@@ -85,10 +85,12 @@ static struct drm_driver driver = {
 		.poll = drm_poll,
 		.fasync = drm_fasync,
 	},
-	.pci_driver = {
-		.name          = DRIVER_NAME,
-		.id_table      = pciidlist,
-	}
+	.u = {
+		 .pci_driver = {
+			 .name          = DRIVER_NAME,
+			 .id_table      = pciidlist,
+		 }
+	 },
 };
 
 static int __init sis_init(void)
diff --git a/drivers/char/drm/tdfx_drv.c b/drivers/char/drm/tdfx_drv.c
index 0e7943e..5a23bfe 100644
--- a/drivers/char/drm/tdfx_drv.c
+++ b/drivers/char/drm/tdfx_drv.c
@@ -83,10 +83,12 @@ static struct drm_driver driver = {
 		.poll = drm_poll,
 		.fasync = drm_fasync,
 	},
-	.pci_driver = {
-		.name          = DRIVER_NAME,
-		.id_table      = pciidlist,
-	}
+	.u = {
+		 .pci_driver = {
+			 .name          = DRIVER_NAME,
+			 .id_table      = pciidlist,
+		 }
+	 },
 };
 
 static int __init tdfx_init(void)
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 04d3120..62f8ffd 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -4,6 +4,12 @@
 
 menu "Graphics support"
 
+config RADEON_LL
+	tristate "Radeon lowlevel driver"
+	depends on PCI
+	---help---
+	   Lowlevel driver for radeon card
+
 config FB
 	tristate "Support for frame buffer devices"
 	---help---
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index b018df4..b87b131 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -4,6 +4,7 @@
 
 # Each configuration option enables a list of files.
 
+obj-y				  += vga_lowlevel.o
 obj-$(CONFIG_VT)		  += console/
 obj-$(CONFIG_LOGO)		  += logo/
 obj-$(CONFIG_SYSFS)		  += backlight/
@@ -100,3 +101,5 @@ obj-$(CONFIG_FB_OF)               += off
 
 # the test framebuffer is last
 obj-$(CONFIG_FB_VIRTUAL)          += vfb.o
+
+obj-$(CONFIG_RADEON_LL)		  += radeon_lowlevel.o
diff --git a/drivers/video/aty/radeon_accel.c b/drivers/video/aty/radeon_accel.c
index 3ca27cb..72a1574 100644
--- a/drivers/video/aty/radeon_accel.c
+++ b/drivers/video/aty/radeon_accel.c
@@ -203,9 +203,9 @@ void radeonfb_engine_reset(struct radeon
 	host_path_cntl = INREG(HOST_PATH_CNTL);
 	rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
 
-	if (rinfo->family == CHIP_FAMILY_R300 ||
-	    rinfo->family == CHIP_FAMILY_R350 ||
-	    rinfo->family == CHIP_FAMILY_RV350) {
+	if (rinfo->lowlevel->family == CHIP_FAMILY_R300 ||
+	    rinfo->lowlevel->family == CHIP_FAMILY_R350 ||
+	    rinfo->lowlevel->family == CHIP_FAMILY_RV350) {
 		u32 tmp;
 
 		OUTREG(RBBM_SOFT_RESET, (rbbm_soft_reset |
@@ -241,9 +241,9 @@ void radeonfb_engine_reset(struct radeon
 	INREG(HOST_PATH_CNTL);
 	OUTREG(HOST_PATH_CNTL, host_path_cntl);
 
-	if (rinfo->family != CHIP_FAMILY_R300 ||
-	    rinfo->family != CHIP_FAMILY_R350 ||
-	    rinfo->family != CHIP_FAMILY_RV350)
+	if (rinfo->lowlevel->family != CHIP_FAMILY_R300 ||
+	    rinfo->lowlevel->family != CHIP_FAMILY_R350 ||
+	    rinfo->lowlevel->family != CHIP_FAMILY_RV350)
 		OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
 
 	OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
@@ -260,9 +260,9 @@ void radeonfb_engine_init (struct radeon
 	radeonfb_engine_reset(rinfo);
 
 	radeon_fifo_wait (1);
-	if ((rinfo->family != CHIP_FAMILY_R300) &&
-	    (rinfo->family != CHIP_FAMILY_R350) &&
-	    (rinfo->family != CHIP_FAMILY_RV350))
+	if ((rinfo->lowlevel->family != CHIP_FAMILY_R300) &&
+	    (rinfo->lowlevel->family != CHIP_FAMILY_R350) &&
+	    (rinfo->lowlevel->family != CHIP_FAMILY_RV350))
 		OUTREG(RB2D_DSTCACHE_MODE, 0);
 
 	radeon_fifo_wait (3);
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 47a6b12..f6d3a04 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -103,135 +103,6 @@
 #define MAX_MAPPED_VRAM	(2048*2048*4)
 #define MIN_MAPPED_VRAM	(1024*768*1)
 
-#define CHIP_DEF(id, family, flags)					\
-	{ PCI_VENDOR_ID_ATI, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (flags) | (CHIP_FAMILY_##family) }
-
-static struct pci_device_id radeonfb_pci_table[] = {
-	/* Mobility M6 */
-	CHIP_DEF(PCI_CHIP_RADEON_LY, 	RV100,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	CHIP_DEF(PCI_CHIP_RADEON_LZ,	RV100,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	/* Radeon VE/7000 */
-	CHIP_DEF(PCI_CHIP_RV100_QY, 	RV100,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_RV100_QZ, 	RV100,	CHIP_HAS_CRTC2),
-	/* Radeon IGP320M (U1) */
-	CHIP_DEF(PCI_CHIP_RS100_4336,	RS100,	CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
-	/* Radeon IGP320 (A3) */
-	CHIP_DEF(PCI_CHIP_RS100_4136,	RS100,	CHIP_HAS_CRTC2 | CHIP_IS_IGP), 
-	/* IGP330M/340M/350M (U2) */
-	CHIP_DEF(PCI_CHIP_RS200_4337,	RS200,	CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
-	/* IGP330/340/350 (A4) */
-	CHIP_DEF(PCI_CHIP_RS200_4137,	RS200,	CHIP_HAS_CRTC2 | CHIP_IS_IGP),
-	/* Mobility 7000 IGP */
-	CHIP_DEF(PCI_CHIP_RS250_4437,	RS200,	CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
-	/* 7000 IGP (A4+) */
-	CHIP_DEF(PCI_CHIP_RS250_4237,	RS200,	CHIP_HAS_CRTC2 | CHIP_IS_IGP),
-	/* 8500 AIW */
-	CHIP_DEF(PCI_CHIP_R200_BB,	R200,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R200_BC,	R200,	CHIP_HAS_CRTC2),
-	/* 8700/8800 */
-	CHIP_DEF(PCI_CHIP_R200_QH,	R200,	CHIP_HAS_CRTC2),
-	/* 8500 */
-	CHIP_DEF(PCI_CHIP_R200_QL,	R200,	CHIP_HAS_CRTC2),
-	/* 9100 */
-	CHIP_DEF(PCI_CHIP_R200_QM,	R200,	CHIP_HAS_CRTC2),
-	/* Mobility M7 */
-	CHIP_DEF(PCI_CHIP_RADEON_LW,	RV200,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	CHIP_DEF(PCI_CHIP_RADEON_LX,	RV200,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	/* 7500 */
-	CHIP_DEF(PCI_CHIP_RV200_QW,	RV200,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_RV200_QX,	RV200,	CHIP_HAS_CRTC2),
-	/* Mobility M9 */
-	CHIP_DEF(PCI_CHIP_RV250_Ld,	RV250,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	CHIP_DEF(PCI_CHIP_RV250_Le,	RV250,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	CHIP_DEF(PCI_CHIP_RV250_Lf,	RV250,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	CHIP_DEF(PCI_CHIP_RV250_Lg,	RV250,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	/* 9000/Pro */
-	CHIP_DEF(PCI_CHIP_RV250_If,	RV250,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_RV250_Ig,	RV250,	CHIP_HAS_CRTC2),
-	/* Mobility 9100 IGP (U3) */
-	CHIP_DEF(PCI_CHIP_RS300_5835,	RS300,	CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
-	CHIP_DEF(PCI_CHIP_RS350_7835,	RS300,	CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
-	/* 9100 IGP (A5) */
-	CHIP_DEF(PCI_CHIP_RS300_5834,	RS300,	CHIP_HAS_CRTC2 | CHIP_IS_IGP),
-	CHIP_DEF(PCI_CHIP_RS350_7834,	RS300,	CHIP_HAS_CRTC2 | CHIP_IS_IGP),
-	/* Mobility 9200 (M9+) */
-	CHIP_DEF(PCI_CHIP_RV280_5C61,	RV280,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	CHIP_DEF(PCI_CHIP_RV280_5C63,	RV280,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	/* 9200 */
-	CHIP_DEF(PCI_CHIP_RV280_5960,	RV280,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_RV280_5961,	RV280,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_RV280_5962,	RV280,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_RV280_5964,	RV280,	CHIP_HAS_CRTC2),
-	/* 9500 */
-	CHIP_DEF(PCI_CHIP_R300_AD,	R300,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R300_AE,	R300,	CHIP_HAS_CRTC2),
-	/* 9600TX / FireGL Z1 */
-	CHIP_DEF(PCI_CHIP_R300_AF,	R300,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R300_AG,	R300,	CHIP_HAS_CRTC2),
-	/* 9700/9500/Pro/FireGL X1 */
-	CHIP_DEF(PCI_CHIP_R300_ND,	R300,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R300_NE,	R300,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R300_NF,	R300,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R300_NG,	R300,	CHIP_HAS_CRTC2),
-	/* Mobility M10/M11 */
-	CHIP_DEF(PCI_CHIP_RV350_NP,	RV350,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	CHIP_DEF(PCI_CHIP_RV350_NQ,	RV350,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	CHIP_DEF(PCI_CHIP_RV350_NR,	RV350,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	CHIP_DEF(PCI_CHIP_RV350_NS,	RV350,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	CHIP_DEF(PCI_CHIP_RV350_NT,	RV350,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	CHIP_DEF(PCI_CHIP_RV350_NV,	RV350,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	/* 9600/FireGL T2 */
-	CHIP_DEF(PCI_CHIP_RV350_AP,	RV350,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_RV350_AQ,	RV350,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_RV360_AR,	RV350,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_RV350_AS,	RV350,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_RV350_AT,	RV350,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_RV350_AV,	RV350,	CHIP_HAS_CRTC2),
-	/* 9800/Pro/FileGL X2 */
-	CHIP_DEF(PCI_CHIP_R350_AH,	R350,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R350_AI,	R350,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R350_AJ,	R350,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R350_AK,	R350,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R350_NH,	R350,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R350_NI,	R350,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R360_NJ,	R350,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R350_NK,	R350,	CHIP_HAS_CRTC2),
-	/* Newer stuff */
-	CHIP_DEF(PCI_CHIP_RV380_3E50,	RV380,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_RV380_3E54,	RV380,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_RV380_3150,	RV380,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	CHIP_DEF(PCI_CHIP_RV380_3154,	RV380,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	CHIP_DEF(PCI_CHIP_RV370_5B60,	RV380,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_RV370_5B62,	RV380,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_RV370_5B64,	RV380,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_RV370_5B65,	RV380,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_RV370_5460,	RV380,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	CHIP_DEF(PCI_CHIP_RV370_5464,	RV380,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	CHIP_DEF(PCI_CHIP_R420_JH,	R420,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R420_JI,	R420,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R420_JJ,	R420,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R420_JK,	R420,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R420_JL,	R420,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R420_JM,	R420,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R420_JN,	R420,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
-	CHIP_DEF(PCI_CHIP_R420_JP,	R420,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R423_UH,	R420,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R423_UI,	R420,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R423_UJ,	R420,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R423_UK,	R420,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R423_UQ,	R420,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R423_UR,	R420,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R423_UT,	R420,	CHIP_HAS_CRTC2),
-	CHIP_DEF(PCI_CHIP_R423_5D57,	R420,	CHIP_HAS_CRTC2),
-	/* Original Radeon/7200 */
-	CHIP_DEF(PCI_CHIP_RADEON_QD,	RADEON,	0),
-	CHIP_DEF(PCI_CHIP_RADEON_QE,	RADEON,	0),
-	CHIP_DEF(PCI_CHIP_RADEON_QF,	RADEON,	0),
-	CHIP_DEF(PCI_CHIP_RADEON_QG,	RADEON,	0),
-	{ 0, }
-};
-MODULE_DEVICE_TABLE(pci, radeonfb_pci_table);
-
 
 typedef struct {
 	u16 reg;
@@ -298,7 +169,7 @@ static void radeon_unmap_ROM(struct rade
 	pci_unmap_rom(dev, rinfo->bios_seg);
 }
 
-static int __devinit radeon_map_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev)
+static int __devinit radeon_map_ROM(struct radeonfb_info *rinfo, struct pci_dev *pdev)
 {
 	void __iomem *rom;
 	u16 dptr;
@@ -318,10 +189,10 @@ static int __devinit radeon_map_ROM(stru
 	OUTREG(MPP_TB_CONFIG, temp);
 	temp = INREG(MPP_TB_CONFIG);
                                                                                                           
-	rom = pci_map_rom(dev, &rom_size);
+	rom = pci_map_rom(pdev, &rom_size);
 	if (!rom) {
 		printk(KERN_ERR "radeonfb (%s): ROM failed to map\n",
-		       pci_name(rinfo->pdev));
+		       pci_name(pdev));
 		return -ENOMEM;
 	}
 	
@@ -330,7 +201,7 @@ static int __devinit radeon_map_ROM(stru
 	/* Very simple test to make sure it appeared */
 	if (BIOS_IN16(0) != 0xaa55) {
 		printk(KERN_ERR "radeonfb (%s): Invalid ROM signature %x should be"
-		       "0xaa55\n", pci_name(rinfo->pdev), BIOS_IN16(0));
+		       "0xaa55\n", pci_name(pdev), BIOS_IN16(0));
 		goto failed;
 	}
 	/* Look for the PCI data to check the ROM type */
@@ -362,7 +233,7 @@ static int __devinit radeon_map_ROM(stru
 	 */
 	if (BIOS_IN32(dptr) !=  (('R' << 24) | ('I' << 16) | ('C' << 8) | 'P')) {
 		printk(KERN_WARNING "radeonfb (%s): PCI DATA signature in ROM"
-		       "incorrect: %08x\n", pci_name(rinfo->pdev), BIOS_IN32(dptr));
+		       "incorrect: %08x\n", pci_name(pdev), BIOS_IN32(dptr));
 		goto anyway;
 	}
 	rom_type = BIOS_IN8(dptr + 0x14);
@@ -387,7 +258,7 @@ static int __devinit radeon_map_ROM(stru
 
  failed:
 	rinfo->bios_seg = NULL;
-	radeon_unmap_ROM(rinfo, dev);
+	radeon_unmap_ROM(rinfo, pdev);
 	return -ENXIO;
 }
 
@@ -530,7 +401,7 @@ static int __devinit radeon_probe_pll_pa
 	}
 
 	ppll_div_sel = INREG8(CLOCK_CNTL_INDEX + 1) & 0x3;
-	radeon_pll_errata_after_index(rinfo);
+	radeon_pll_errata_after_index(rinfo->lowlevel);
 
 	n = (INPLL(PPLL_DIV_0 + ppll_div_sel) & 0x7ff);
 	m = (INPLL(PPLL_REF_DIV) & 0x3ff);
@@ -602,7 +473,7 @@ static void __devinit radeon_get_pllinfo
 	 * incomplete, however.  It does provide ppll_max and _min values
 	 * even for most other methods, however.
 	 */
-	switch (rinfo->chipset) {
+	switch (rinfo->lowlevel->chipset) {
 	case PCI_DEVICE_ID_ATI_RADEON_QW:
 	case PCI_DEVICE_ID_ATI_RADEON_QX:
 		rinfo->pll.ppll_max = 35000;
@@ -878,7 +749,7 @@ static int radeonfb_ioctl (struct inode 
 		 *        routing to second output
 		 */
 		case FBIO_RADEON_SET_MIRROR:
-			if (!rinfo->is_mobility)
+			if (!rinfo->lowlevel->is_mobility)
 				return -EINVAL;
 
 			rc = get_user(value, (__u32 __user *)arg);
@@ -915,7 +786,7 @@ static int radeonfb_ioctl (struct inode 
 
 			return 0;
 		case FBIO_RADEON_GET_MIRROR:
-			if (!rinfo->is_mobility)
+			if (!rinfo->lowlevel->is_mobility)
 				return -EINVAL;
 
 			tmp = INREG(LVDS_GEN_CNTL);
@@ -1019,7 +890,7 @@ int radeon_screen_blank(struct radeonfb_
 			 * RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
 			 */
 			tmp_pix_clks = INPLL(PIXCLKS_CNTL);
-			if (rinfo->is_mobility || rinfo->is_IGP)
+			if (rinfo->lowlevel->is_mobility || rinfo->lowlevel->is_IGP)
 				OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb);
 			val &= ~(LVDS_BL_MOD_EN);
 			OUTREG(LVDS_GEN_CNTL, val);
@@ -1033,7 +904,7 @@ int radeon_screen_blank(struct radeonfb_
 				  msecs_to_jiffies(rinfo->panel_info.pwr_delay));
 			rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
 			rinfo->init_state.lvds_gen_cntl |= val & LVDS_STATE_MASK;
-			if (rinfo->is_mobility || rinfo->is_IGP)
+			if (rinfo->lowlevel->is_mobility || rinfo->lowlevel->is_IGP)
 				OUTPLL(PIXCLKS_CNTL, tmp_pix_clks);
 		}
 		break;
@@ -1138,14 +1009,14 @@ static int radeonfb_setcolreg (unsigned 
 	int rc;
 
         if (!rinfo->asleep) {
-		if (rinfo->is_mobility) {
+		if (rinfo->lowlevel->is_mobility) {
 			vclk_cntl = INPLL(VCLK_ECP_CNTL);
 			OUTPLL(VCLK_ECP_CNTL,
 			       vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb);
 		}
 
 		/* Make sure we are on first palette */
-		if (rinfo->has_CRTC2) {
+		if (rinfo->lowlevel->has_CRTC2) {
 			dac_cntl2 = INREG(DAC_CNTL2);
 			dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL;
 			OUTREG(DAC_CNTL2, dac_cntl2);
@@ -1154,7 +1025,7 @@ static int radeonfb_setcolreg (unsigned 
 
 	rc = radeon_setcolreg (regno, red, green, blue, transp, rinfo);
 
-	if (!rinfo->asleep && rinfo->is_mobility)
+	if (!rinfo->asleep && rinfo->lowlevel->is_mobility)
 		OUTPLL(VCLK_ECP_CNTL, vclk_cntl);
 
 	return rc;
@@ -1168,14 +1039,14 @@ static int radeonfb_setcmap(struct fb_cm
 	int i, start, rc = 0;
 
         if (!rinfo->asleep) {
-		if (rinfo->is_mobility) {
+		if (rinfo->lowlevel->is_mobility) {
 			vclk_cntl = INPLL(VCLK_ECP_CNTL);
 			OUTPLL(VCLK_ECP_CNTL,
 			       vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb);
 		}
 
 		/* Make sure we are on first palette */
-		if (rinfo->has_CRTC2) {
+		if (rinfo->lowlevel->has_CRTC2) {
 			dac_cntl2 = INREG(DAC_CNTL2);
 			dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL;
 			OUTREG(DAC_CNTL2, dac_cntl2);
@@ -1202,7 +1073,7 @@ static int radeonfb_setcmap(struct fb_cm
 			break;
 	}
 
-	if (!rinfo->asleep && rinfo->is_mobility)
+	if (!rinfo->asleep && rinfo->lowlevel->is_mobility)
 		OUTPLL(VCLK_ECP_CNTL, vclk_cntl);
 
 	return rc;
@@ -1239,7 +1110,7 @@ static void radeon_save_state (struct ra
 
 	/* PLL regs */
 	save->clk_cntl_index = INREG(CLOCK_CNTL_INDEX) & ~0x3f;
-	radeon_pll_errata_after_index(rinfo);
+	radeon_pll_errata_after_index(rinfo->lowlevel);
 	save->ppll_div_3 = INPLL(PPLL_DIV_3);
 	save->ppll_ref_div = INPLL(PPLL_REF_DIV);
 }
@@ -1252,7 +1123,7 @@ static void radeon_write_pll_regs(struct
 	radeon_fifo_wait(20);
 
 	/* Workaround from XFree */
-	if (rinfo->is_mobility) {
+	if (rinfo->lowlevel->is_mobility) {
 	        /* A temporal workaround for the occational blanking on certain laptop
 		 * panels. This appears to related to the PLL divider registers
 		 * (fail to lock?). It occurs even when all dividers are the same
@@ -1269,8 +1140,8 @@ static void radeon_write_pll_regs(struct
 			OUTREGP(CLOCK_CNTL_INDEX,
 				mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
 				~PPLL_DIV_SEL_MASK);
-			radeon_pll_errata_after_index(rinfo);
-			radeon_pll_errata_after_data(rinfo);
+			radeon_pll_errata_after_index(rinfo->lowlevel);
+			radeon_pll_errata_after_data(rinfo->lowlevel);
             		return;
 		}
 	}
@@ -1287,14 +1158,14 @@ static void radeon_write_pll_regs(struct
 	OUTREGP(CLOCK_CNTL_INDEX,
 		mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
 		~PPLL_DIV_SEL_MASK);
-	radeon_pll_errata_after_index(rinfo);
-	radeon_pll_errata_after_data(rinfo);
+	radeon_pll_errata_after_index(rinfo->lowlevel);
+	radeon_pll_errata_after_data(rinfo->lowlevel);
 
 	/* Set PPLL ref. div */
-	if (rinfo->family == CHIP_FAMILY_R300 ||
-	    rinfo->family == CHIP_FAMILY_RS300 ||
-	    rinfo->family == CHIP_FAMILY_R350 ||
-	    rinfo->family == CHIP_FAMILY_RV350) {
+	if (rinfo->lowlevel->family == CHIP_FAMILY_R300 ||
+	    rinfo->lowlevel->family == CHIP_FAMILY_RS300 ||
+	    rinfo->lowlevel->family == CHIP_FAMILY_R350 ||
+	    rinfo->lowlevel->family == CHIP_FAMILY_RV350) {
 		if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
 			/* When restoring console mode, use saved PPLL_REF_DIV
 			 * setting.
@@ -1454,7 +1325,7 @@ static void radeon_calc_pll_regs(struct 
 	 * divider. I'll find a better fix once I have more infos on the
 	 * real cause of the problem.
 	 */
-	while (rinfo->has_CRTC2) {
+	while (rinfo->lowlevel->has_CRTC2) {
 		u32 fp2_gen_cntl = INREG(FP2_GEN_CNTL);
 		u32 disp_output_cntl;
 		int source;
@@ -1465,10 +1336,10 @@ static void radeon_calc_pll_regs(struct 
 		/* Not all chip revs have the same format for this register,
 		 * extract the source selection
 		 */
-		if (rinfo->family == CHIP_FAMILY_R200 ||
-		    rinfo->family == CHIP_FAMILY_R300 ||
-		    rinfo->family == CHIP_FAMILY_R350 ||
-		    rinfo->family == CHIP_FAMILY_RV350) {
+		if (rinfo->lowlevel->family == CHIP_FAMILY_R200 ||
+		    rinfo->lowlevel->family == CHIP_FAMILY_R300 ||
+		    rinfo->lowlevel->family == CHIP_FAMILY_R350 ||
+		    rinfo->lowlevel->family == CHIP_FAMILY_RV350) {
 			source = (fp2_gen_cntl >> 10) & 0x3;
 			/* sourced from transform unit, check for transform unit
 			 * own source
@@ -1791,8 +1662,8 @@ static int radeonfb_set_par(struct fb_in
 					FP_CRTC_DONT_SHADOW_HEND |
 					FP_PANEL_FORMAT);
 
-		if (IS_R300_VARIANT(rinfo) ||
-		    (rinfo->family == CHIP_FAMILY_R200)) {
+		if (IS_R300_VARIANT(rinfo->lowlevel) ||
+		    (rinfo->lowlevel->family == CHIP_FAMILY_R200)) {
 			newmode->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
 			if (use_rmx)
 				newmode->fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX;
@@ -1814,8 +1685,8 @@ static int radeonfb_set_par(struct fb_in
 			newmode->fp_gen_cntl |= (FP_FPON | FP_TMDS_EN);
 			newmode->tmds_transmitter_cntl &= ~(TMDS_PLLRST);
 			/* TMDS_PLL_EN bit is reversed on RV (and mobility) chips */
-			if (IS_R300_VARIANT(rinfo) ||
-			    (rinfo->family == CHIP_FAMILY_R200) || !rinfo->has_CRTC2)
+			if (IS_R300_VARIANT(rinfo->lowlevel) ||
+			    (rinfo->lowlevel->family == CHIP_FAMILY_R200) || !rinfo->lowlevel->has_CRTC2)
 				newmode->tmds_transmitter_cntl &= ~TMDS_PLL_EN;
 			else
 				newmode->tmds_transmitter_cntl |= TMDS_PLL_EN;
@@ -1851,7 +1722,7 @@ static int radeonfb_set_par(struct fb_in
 
 #ifdef CONFIG_BOOTX_TEXT
 	/* Update debug text engine */
-	btext_update_display(rinfo->fb_base_phys, mode->xres, mode->yres,
+	btext_update_display(rinfo->lowlevel->fb_base_phys, mode->xres, mode->yres,
 			     rinfo->depth, info->fix.line_length);
 #endif
 
@@ -1893,7 +1764,7 @@ static int __devinit radeon_set_fbinfo (
 	info->screen_size = rinfo->mapped_vram;
 	/* Fill fix common fields */
 	strlcpy(info->fix.id, rinfo->name, sizeof(info->fix.id));
-        info->fix.smem_start = rinfo->fb_base_phys;
+        info->fix.smem_start = rinfo->lowlevel->fb_base_phys;
         info->fix.smem_len = rinfo->video_ram;
         info->fix.type = FB_TYPE_PACKED_PIXELS;
         info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
@@ -1901,7 +1772,7 @@ static int __devinit radeon_set_fbinfo (
         info->fix.ypanstep = 1;
         info->fix.ywrapstep = 0;
         info->fix.type_aux = 0;
-        info->fix.mmio_start = rinfo->mmio_base_phys;
+        info->fix.mmio_start = rinfo->lowlevel->mmio_base_phys;
         info->fix.mmio_len = RADEON_REGSIZE;
 	info->fix.accel = FB_ACCEL_ATI_RADEON;
 
@@ -1949,10 +1820,10 @@ static int radeon_set_backlight_enable(i
 	 * out in what direction backlight should work on a given
 	 * panel ?
 	 */
-	if ((rinfo->family == CHIP_FAMILY_RV200 ||
-	     rinfo->family == CHIP_FAMILY_RV250 ||
-	     rinfo->family == CHIP_FAMILY_RV280 ||
-	     rinfo->family == CHIP_FAMILY_RV350) &&
+	if ((rinfo->lowlevel->family == CHIP_FAMILY_RV200 ||
+	     rinfo->lowlevel->family == CHIP_FAMILY_RV250 ||
+	     rinfo->lowlevel->family == CHIP_FAMILY_RV280 ||
+	     rinfo->lowlevel->family == CHIP_FAMILY_RV350) &&
 	    !machine_is_compatible("PowerBook4,3") &&
 	    !machine_is_compatible("PowerBook6,3") &&
 	    !machine_is_compatible("PowerBook6,5"))
@@ -1992,7 +1863,7 @@ static int radeon_set_backlight_enable(i
 		   RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
 		*/
 		tmpPixclksCntl = INPLL(PIXCLKS_CNTL);
-		if (rinfo->is_mobility || rinfo->is_IGP)
+		if (rinfo->lowlevel->is_mobility || rinfo->lowlevel->is_IGP)
 			OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb);
 		lvds_gen_cntl &= ~(LVDS_BL_MOD_LEVEL_MASK | LVDS_BL_MOD_EN);
 		lvds_gen_cntl |= (conv_table[0] <<
@@ -2006,7 +1877,7 @@ static int radeon_set_backlight_enable(i
 		rinfo->pending_lvds_gen_cntl = lvds_gen_cntl;
 		mod_timer(&rinfo->lvds_timer,
 			  jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay));
-		if (rinfo->is_mobility || rinfo->is_IGP)
+		if (rinfo->lowlevel->is_mobility || rinfo->lowlevel->is_IGP)
 			OUTPLL(PIXCLKS_CNTL, tmpPixclksCntl);
 	}
 	rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
@@ -2044,7 +1915,7 @@ static void fixup_memory_mappings(struct
 	u32 agp_base;
 
 	/* First, we disable display to avoid interfering */
-	if (rinfo->has_CRTC2) {
+	if (rinfo->lowlevel->has_CRTC2) {
 		save_crtc2_gen_cntl = INREG(CRTC2_GEN_CNTL);
 		OUTREG(CRTC2_GEN_CNTL, save_crtc2_gen_cntl | CRTC2_DISP_REQ_EN_B);
 	}
@@ -2086,12 +1957,12 @@ static void fixup_memory_mappings(struct
 	 */
 #ifdef SET_MC_FB_FROM_APERTURE
 	OUTREG(DISPLAY_BASE_ADDR, aper_base);
-	if (rinfo->has_CRTC2)
+	if (rinfo->lowlevel->has_CRTC2)
 		OUTREG(CRTC2_DISPLAY_BASE_ADDR, aper_base);
 	OUTREG(OV0_BASE_ADDR, aper_base);
 #else
 	OUTREG(DISPLAY_BASE_ADDR, 0);
-	if (rinfo->has_CRTC2)
+	if (rinfo->lowlevel->has_CRTC2)
 		OUTREG(CRTC2_DISPLAY_BASE_ADDR, 0);
 	OUTREG(OV0_BASE_ADDR, 0);
 #endif
@@ -2100,7 +1971,7 @@ static void fixup_memory_mappings(struct
 	/* Restore display settings */
 	OUTREG(CRTC_GEN_CNTL, save_crtc_gen_cntl);
 	OUTREG(CRTC_EXT_CNTL, save_crtc_ext_cntl);
-	if (rinfo->has_CRTC2)
+	if (rinfo->lowlevel->has_CRTC2)
 		OUTREG(CRTC2_GEN_CNTL, save_crtc2_gen_cntl);	
 
 	RTRACE("aper_base: %08x MC_FB_LOC to: %08x, MC_AGP_LOC to: %08x\n",
@@ -2114,11 +1985,12 @@ static void fixup_memory_mappings(struct
 static void radeon_identify_vram(struct radeonfb_info *rinfo)
 {
 	u32 tmp;
+	struct pci_dev *pdev = to_pci_dev(rinfo->lowlevel->vll.dev.parent);
 
 	/* framebuffer size */
-        if ((rinfo->family == CHIP_FAMILY_RS100) ||
-            (rinfo->family == CHIP_FAMILY_RS200) ||
-            (rinfo->family == CHIP_FAMILY_RS300)) {
+        if ((rinfo->lowlevel->family == CHIP_FAMILY_RS100) ||
+            (rinfo->lowlevel->family == CHIP_FAMILY_RS200) ||
+            (rinfo->lowlevel->family == CHIP_FAMILY_RS300)) {
           u32 tom = INREG(NB_TOM);
           tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
 
@@ -2131,8 +2003,8 @@ static void radeon_identify_vram(struct 
           /* This is supposed to fix the crtc2 noise problem. */
           OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000);
 
-          if ((rinfo->family == CHIP_FAMILY_RS100) ||
-              (rinfo->family == CHIP_FAMILY_RS200)) {
+          if ((rinfo->lowlevel->family == CHIP_FAMILY_RS100) ||
+              (rinfo->lowlevel->family == CHIP_FAMILY_RS200)) {
              /* This is to workaround the asic bug for RMX, some versions
                 of BIOS dosen't have this register initialized correctly.
              */
@@ -2151,7 +2023,7 @@ static void radeon_identify_vram(struct 
 	 * reporting no ram
 	 */
 	if (rinfo->video_ram == 0) {
-		switch (rinfo->pdev->device) {
+		switch (pdev->device) {
 	       	case PCI_CHIP_RADEON_LY:
 		case PCI_CHIP_RADEON_LZ:
 	       		rinfo->video_ram = 8192 * 1024;
@@ -2165,14 +2037,14 @@ static void radeon_identify_vram(struct 
 	/*
 	 * Now try to identify VRAM type
 	 */
-	if (rinfo->is_IGP || (rinfo->family >= CHIP_FAMILY_R300) ||
+	if (rinfo->lowlevel->is_IGP || (rinfo->lowlevel->family >= CHIP_FAMILY_R300) ||
 	    (INREG(MEM_SDRAM_MODE_REG) & (1<<30)))
 		rinfo->vram_ddr = 1;
 	else
 		rinfo->vram_ddr = 0;
 
 	tmp = INREG(MEM_CNTL);
-	if (IS_R300_VARIANT(rinfo)) {
+	if (IS_R300_VARIANT(rinfo->lowlevel)) {
 		tmp &=  R300_MEM_NUM_CHANNELS_MASK;
 		switch (tmp) {
 		case 0:  rinfo->vram_width = 64; break;
@@ -2180,9 +2052,9 @@ static void radeon_identify_vram(struct 
 		case 2:  rinfo->vram_width = 256; break;
 		default: rinfo->vram_width = 128; break;
 		}
-	} else if ((rinfo->family == CHIP_FAMILY_RV100) ||
-		   (rinfo->family == CHIP_FAMILY_RS100) ||
-		   (rinfo->family == CHIP_FAMILY_RS200)){
+	} else if ((rinfo->lowlevel->family == CHIP_FAMILY_RV100) ||
+		   (rinfo->lowlevel->family == CHIP_FAMILY_RS100) ||
+		   (rinfo->lowlevel->family == CHIP_FAMILY_RS200)){
 		if (tmp & RV100_MEM_HALF_MODE)
 			rinfo->vram_width = 32;
 		else
@@ -2199,7 +2071,7 @@ static void radeon_identify_vram(struct 
 	 */
 
 	RTRACE("radeonfb (%s): Found %ldk of %s %d bits wide videoram\n",
-	       pci_name(rinfo->pdev),
+	       pci_name(pdev),
 	       rinfo->video_ram / 1024,
 	       rinfo->vram_ddr ? "DDR" : "SDRAM",
 	       rinfo->vram_width);
@@ -2265,24 +2137,17 @@ static struct bin_attribute edid2_attr =
 };
 
 
-static int radeonfb_pci_register (struct pci_dev *pdev,
-				  const struct pci_device_id *ent)
+static int radeonfb_register(struct vll_driver *vdrv, struct vll_dev *vdev)
 {
 	struct fb_info *info;
 	struct radeonfb_info *rinfo;
+	struct pci_dev *pdev = to_pci_dev(vdev->dev.parent);
 	int ret;
-
-	RTRACE("radeonfb_pci_register BEGIN\n");
 	
-	/* Enable device in PCI config */
-	ret = pci_enable_device(pdev);
-	if (ret < 0) {
-		printk(KERN_ERR "radeonfb (%s): Cannot enable PCI device\n",
-		       pci_name(pdev));
-		goto err_out;
-	}
-
-	info = framebuffer_alloc(sizeof(struct radeonfb_info), &pdev->dev);
+	printk("radeonfb_register BEGIN %p\n", pdev);
+	//	RTRACE("radeonfb_pci_register BEGIN\n");
+	
+	info = framebuffer_alloc(sizeof(struct radeonfb_info), &vdev->dev);
 	if (!info) {
 		printk (KERN_ERR "radeonfb (%s): could not allocate memory\n",
 			pci_name(pdev));
@@ -2290,63 +2155,20 @@ static int radeonfb_pci_register (struct
 		goto err_disable;
 	}
 	rinfo = info->par;
-	rinfo->info = info;	
-	rinfo->pdev = pdev;
+	rinfo->info = info;
 	
-	spin_lock_init(&rinfo->reg_lock);
+	rinfo->lowlevel = to_radeonll_info(vdev);
 	init_timer(&rinfo->lvds_timer);
 	rinfo->lvds_timer.function = radeon_lvds_timer_func;
 	rinfo->lvds_timer.data = (unsigned long)rinfo;
-
+	
+	printk("pdev device is %04X\n", pdev->device);
 	strcpy(rinfo->name, "ATI Radeon XX ");
-	rinfo->name[11] = ent->device >> 8;
-	rinfo->name[12] = ent->device & 0xFF;
-	rinfo->family = ent->driver_data & CHIP_FAMILY_MASK;
-	rinfo->chipset = pdev->device;
-	rinfo->has_CRTC2 = (ent->driver_data & CHIP_HAS_CRTC2) != 0;
-	rinfo->is_mobility = (ent->driver_data & CHIP_IS_MOBILITY) != 0;
-	rinfo->is_IGP = (ent->driver_data & CHIP_IS_IGP) != 0;
-
-	/* Set base addrs */
-	rinfo->fb_base_phys = pci_resource_start (pdev, 0);
-	rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
-
-	/* request the mem regions */
-	ret = pci_request_regions(pdev, "radeonfb");
-	if (ret < 0) {
-		printk( KERN_ERR "radeonfb (%s): cannot reserve PCI regions."
-			"  Someone already got them?\n", pci_name(rinfo->pdev));
-		goto err_release_fb;
-	}
-
-	/* map the regions */
-	rinfo->mmio_base = ioremap(rinfo->mmio_base_phys, RADEON_REGSIZE);
-	if (!rinfo->mmio_base) {
-		printk(KERN_ERR "radeonfb (%s): cannot map MMIO\n", pci_name(rinfo->pdev));
-		ret = -EIO;
-		goto err_release_pci;
-	}
+	rinfo->name[11] = pdev->device >> 8;
+	rinfo->name[12] = pdev->device & 0xFF;
 
 	rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
 
-	/*
-	 * Check for errata
-	 */
-	rinfo->errata = 0;
-	if (rinfo->family == CHIP_FAMILY_R300 &&
-	    (INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK)
-	    == CFG_ATI_REV_A11)
-		rinfo->errata |= CHIP_ERRATA_R300_CG;
-
-	if (rinfo->family == CHIP_FAMILY_RV200 ||
-	    rinfo->family == CHIP_FAMILY_RS200)
-		rinfo->errata |= CHIP_ERRATA_PLL_DUMMYREADS;
-
-	if (rinfo->family == CHIP_FAMILY_RV100 ||
-	    rinfo->family == CHIP_FAMILY_RS100 ||
-	    rinfo->family == CHIP_FAMILY_RS200)
-		rinfo->errata |= CHIP_ERRATA_PLL_DELAY;
-
 #ifdef CONFIG_PPC_OF
 	/* On PPC, we obtain the OF device-node pointer to the firmware
 	 * data for this chip
@@ -2354,7 +2176,7 @@ static int radeonfb_pci_register (struct
 	rinfo->of_node = pci_device_to_OF_node(pdev);
 	if (rinfo->of_node == NULL)
 		printk(KERN_WARNING "radeonfb (%s): Cannot match card to OF node !\n",
-		       pci_name(rinfo->pdev));
+		       pci_name(pdev));
 
 	/* On PPC, the firmware sets up a memory mapping that tends
 	 * to cause lockups when enabling the engine. We reconfigure
@@ -2369,19 +2191,19 @@ static int radeonfb_pci_register (struct
 	rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM, rinfo->video_ram);
 
 	do {
-		rinfo->fb_base = ioremap (rinfo->fb_base_phys,
+		rinfo->fb_base = ioremap (rinfo->lowlevel->fb_base_phys,
 					  rinfo->mapped_vram);
 	} while (   rinfo->fb_base == 0 &&
 		  ((rinfo->mapped_vram /=2) >= MIN_MAPPED_VRAM) );
 
 	if (rinfo->fb_base == NULL) {
 		printk (KERN_ERR "radeonfb (%s): cannot map FB\n",
-			pci_name(rinfo->pdev));
+			pci_name(pdev));
 		ret = -EIO;
 		goto err_unmap_rom;
 	}
 
-	RTRACE("radeonfb (%s): mapped %ldk videoram\n", pci_name(rinfo->pdev),
+	RTRACE("radeonfb (%s): mapped %ldk videoram\n", pci_name(pdev),
 	       rinfo->mapped_vram/1024);
 
 	/*
@@ -2395,7 +2217,7 @@ static int radeonfb_pci_register (struct
 	 * archs who would store that elsewhere and/or could initialize
 	 * more than one adapter during boot).
 	 */
-	if (!rinfo->is_mobility)
+	if (!rinfo->lowlevel->is_mobility)
 		radeon_map_ROM(rinfo, pdev);
 
 	/*
@@ -2412,7 +2234,7 @@ static int radeonfb_pci_register (struct
 	/* If both above failed, try the BIOS ROM again for mobility
 	 * chips
 	 */
-	if (rinfo->bios_seg == NULL && rinfo->is_mobility)
+	if (rinfo->bios_seg == NULL && rinfo->lowlevel->is_mobility)
 		radeon_map_ROM(rinfo, pdev);
 
 	/* Get informations about the board's PLL */
@@ -2434,9 +2256,9 @@ static int radeonfb_pci_register (struct
 
 	/* Register some sysfs stuff (should be done better) */
 	if (rinfo->mon1_EDID)
-		sysfs_create_bin_file(&rinfo->pdev->dev.kobj, &edid1_attr);
+		sysfs_create_bin_file(&pdev->dev.kobj, &edid1_attr);
 	if (rinfo->mon2_EDID)
-		sysfs_create_bin_file(&rinfo->pdev->dev.kobj, &edid2_attr);
+		sysfs_create_bin_file(&pdev->dev.kobj, &edid2_attr);
 
 	/* save current mode regs before we switch into the new one
 	 * so we can restore this upon __exit
@@ -2449,22 +2271,22 @@ static int radeonfb_pci_register (struct
 		/* -2 is special: means  ON on mobility chips and do not
 		 * change on others
 		 */
-		radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1);
+		radeonfb_pm_init(rinfo, rinfo->lowlevel->is_mobility ? 1 : -1);
 	} else
 		radeonfb_pm_init(rinfo, default_dynclk);
 
-	pci_set_drvdata(pdev, info);
+	vll_set_drvdata(vdev, info);
 
 	/* Register with fbdev layer */
 	ret = register_framebuffer(info);
 	if (ret < 0) {
 		printk (KERN_ERR "radeonfb (%s): could not register framebuffer\n",
-			pci_name(rinfo->pdev));
+			pci_name(pdev));
 		goto err_unmap_fb;
 	}
 
 #ifdef CONFIG_MTRR
-	rinfo->mtrr_hdl = nomtrr ? -1 : mtrr_add(rinfo->fb_base_phys,
+	rinfo->mtrr_hdl = nomtrr ? -1 : mtrr_add(rinfo->lowlevel->fb_base_phys,
 						 rinfo->video_ram,
 						 MTRR_TYPE_WRCOMB, 1);
 #endif
@@ -2478,7 +2300,7 @@ static int radeonfb_pci_register (struct
 	}
 #endif
 
-	printk ("radeonfb (%s): %s\n", pci_name(rinfo->pdev), rinfo->name);
+	printk ("radeonfb (%s): %s\n", pci_name(pdev), rinfo->name);
 
 	if (rinfo->bios_seg)
 		radeon_unmap_ROM(rinfo, pdev);
@@ -2498,9 +2320,9 @@ err_unmap_rom:
 #endif
 	if (rinfo->bios_seg)
 		radeon_unmap_ROM(rinfo, pdev);
-	iounmap(rinfo->mmio_base);
+//	iounmap(rinfo->mmio_base);
 err_release_pci:
-	pci_release_regions(pdev);
+//	pci_release_regions(pdev);
 err_release_fb:
 	framebuffer_release(info);
 err_disable:
@@ -2510,10 +2332,9 @@ err_out:
 }
 
 
-
-static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
+static void __devexit radeonfb_unregister (struct vll_dev *vdev)
 {
-        struct fb_info *info = pci_get_drvdata(pdev);
+	struct fb_info *info = vll_get_drvdata(vdev);
         struct radeonfb_info *rinfo = info->par;
  
         if (!rinfo)
@@ -2540,11 +2361,9 @@ static void __devexit radeonfb_pci_unreg
 
         unregister_framebuffer(info);
 
-        iounmap(rinfo->mmio_base);
+//        iounmap(rinfo->mmio_base);
         iounmap(rinfo->fb_base);
  
- 	pci_release_regions(pdev);
-
 	kfree(rinfo->mon1_EDID);
 	kfree(rinfo->mon2_EDID);
 	if (rinfo->mon1_modedb)
@@ -2554,10 +2373,9 @@ static void __devexit radeonfb_pci_unreg
 #endif        
 	fb_dealloc_cmap(&info->cmap);
         framebuffer_release(info);
-	pci_disable_device(pdev);
 }
 
-
+#if 0
 static struct pci_driver radeonfb_driver = {
 	.name		= "radeonfb",
 	.id_table	= radeonfb_pci_table,
@@ -2568,6 +2386,23 @@ static struct pci_driver radeonfb_driver
 	.resume		= radeonfb_pci_resume,
 #endif /* CONFIG_PM */
 };
+#endif
+
+void *radeonfb_getentrypoints(void)
+{
+	return NULL;
+}
+
+static struct vll_driver radeonfb_driver = {
+	.name = "radeonfb",
+	.type = VGA_FB,
+ 	.probe = radeonfb_register,
+	.remove = __devexit_p(radeonfb_unregister),
+	.suspend = radeonfb_suspend,
+	.resume = radeonfb_resume,
+	.get_entrypoints = radeonfb_getentrypoints,
+};
+  
 
 #ifndef MODULE
 static int __init radeonfb_setup (char *options)
@@ -2615,13 +2450,13 @@ static int __init radeonfb_init (void)
 		return -ENODEV;
 	radeonfb_setup(option);
 #endif
-	return pci_register_driver (&radeonfb_driver);
+	return radeonll_register_driver (&radeonfb_driver);
 }
 
 
 static void __exit radeonfb_exit (void)
 {
-	pci_unregister_driver (&radeonfb_driver);
+	radeonll_unregister_driver (&radeonfb_driver);
 }
 
 module_init(radeonfb_init);
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c
index 7622441..572eeba 100644
--- a/drivers/video/aty/radeon_i2c.c
+++ b/drivers/video/aty/radeon_i2c.c
@@ -72,12 +72,13 @@ static int radeon_gpio_getsda(void* data
 static int radeon_setup_i2c_bus(struct radeon_i2c_chan *chan, const char *name)
 {
 	int rc;
+	struct pci_dev *pdev = to_pci_dev(chan->rinfo->lowlevel->vll.dev.parent);
 
 	strcpy(chan->adapter.name, name);
 	chan->adapter.owner		= THIS_MODULE;
 	chan->adapter.id		= I2C_ALGO_ATI;
 	chan->adapter.algo_data		= &chan->algo;
-	chan->adapter.dev.parent	= &chan->rinfo->pdev->dev;
+	chan->adapter.dev.parent	= &pdev->dev;
 	chan->algo.setsda		= radeon_gpio_setsda;
 	chan->algo.setscl		= radeon_gpio_setscl;
 	chan->algo.getsda		= radeon_gpio_getsda;
@@ -95,9 +96,9 @@ static int radeon_setup_i2c_bus(struct r
 
 	rc = i2c_bit_add_bus(&chan->adapter);
 	if (rc == 0)
-		dev_dbg(&chan->rinfo->pdev->dev, "I2C bus %s registered.\n", name);
+		dev_dbg(&pdev->dev, "I2C bus %s registered.\n", name);
 	else
-		dev_warn(&chan->rinfo->pdev->dev, "Failed to register I2C bus %s.\n", name);
+		dev_warn(&pdev->dev, "Failed to register I2C bus %s.\n", name);
 	return rc;
 }
 
@@ -143,6 +144,7 @@ void radeon_delete_i2c_busses(struct rad
 static u8 *radeon_do_probe_i2c_edid(struct radeon_i2c_chan *chan)
 {
 	u8 start = 0x0;
+	struct pci_dev *pdev = to_pci_dev(chan->rinfo->lowlevel->vll.dev.parent);
 	struct i2c_msg msgs[] = {
 		{
 			.addr	= RADEON_DDC,
@@ -158,14 +160,14 @@ static u8 *radeon_do_probe_i2c_edid(stru
 
 	buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
 	if (!buf) {
-		dev_warn(&chan->rinfo->pdev->dev, "Out of memory!\n");
+		dev_warn(&pdev->dev, "Out of memory!\n");
 		return NULL;
 	}
 	msgs[1].buf = buf;
 
 	if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
 		return buf;
-	dev_dbg(&chan->rinfo->pdev->dev, "Unable to read EDID block.\n");
+	dev_dbg(&pdev->dev, "Unable to read EDID block.\n");
 	kfree(buf);
 	return NULL;
 }
@@ -250,7 +252,7 @@ int radeon_probe_i2c_connector(struct ra
 	}
 	if (edid[0x14] & 0x80) {
 		/* Fix detection using BIOS tables */
-		if (rinfo->is_mobility /*&& conn == ddc_dvi*/ &&
+		if (rinfo->lowlevel->is_mobility /*&& conn == ddc_dvi*/ &&
 		    (INREG(LVDS_GEN_CNTL) & LVDS_ON)) {
 			RTRACE("radeonfb: I2C (port %d) ... found LVDS panel\n", conn);
 			return MT_LCD;
diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/aty/radeon_monitor.c
index ea7c863..b74b53f 100644
--- a/drivers/video/aty/radeon_monitor.c
+++ b/drivers/video/aty/radeon_monitor.c
@@ -329,8 +329,8 @@ static int __devinit radeon_crt_is_conne
 	ulData            |=  (DAC_FORCE_BLANK_OFF_EN
 			       |DAC_FORCE_DATA_EN
 			       |DAC_FORCE_DATA_SEL_MASK);
-	if ((rinfo->family == CHIP_FAMILY_RV250) ||
-	    (rinfo->family == CHIP_FAMILY_RV280))
+	if ((rinfo->lowlevel->family == CHIP_FAMILY_RV250) ||
+	    (rinfo->lowlevel->family == CHIP_FAMILY_RV280))
 	    ulData |= (0x01b6 << DAC_FORCE_DATA_SHIFT);
 	else
 	    ulData |= (0x01ac << DAC_FORCE_DATA_SHIFT);
@@ -491,7 +491,7 @@ void __devinit radeon_probe_screens(stru
 		/*
 		 * Old single head cards
 		 */
-		if (!rinfo->has_CRTC2) {
+		if (!rinfo->lowlevel->has_CRTC2) {
 #ifdef CONFIG_PPC_OF
 			if (rinfo->mon1_type == MT_NONE)
 				rinfo->mon1_type = radeon_probe_OF_head(rinfo, 0,
@@ -557,7 +557,7 @@ void __devinit radeon_probe_screens(stru
 				ddc_crt2_used = 1;
 		}
 #endif /* CONFIG_FB_RADEON_I2C */
-		if (rinfo->mon1_type == MT_NONE && rinfo->is_mobility &&
+		if (rinfo->mon1_type == MT_NONE && rinfo->lowlevel->is_mobility &&
 		    ((rinfo->bios_seg && (INREG(BIOS_4_SCRATCH) & 4))
 		     || (INREG(LVDS_GEN_CNTL) & LVDS_ON))) {
 			rinfo->mon1_type = MT_LCD;
@@ -629,7 +629,7 @@ void __devinit radeon_probe_screens(stru
 	       radeon_get_mon_name(rinfo->mon1_type));
 	if (rinfo->mon1_EDID)
 		printk(KERN_INFO "radeonfb: EDID probed\n");
-	if (!rinfo->has_CRTC2)
+	if (!rinfo->lowlevel->has_CRTC2)
 		return;
 	printk(KERN_INFO "radeonfb: Monitor 2 type %s found\n",
 	       radeon_get_mon_name(rinfo->mon2_type));
@@ -652,7 +652,7 @@ static void radeon_fixup_panel_info(stru
 	 * PPC only for now...
 	 */
 	if (!rinfo->panel_info.use_bios_dividers && rinfo->mon1_type == MT_LCD
-	    && rinfo->is_mobility) {
+	    && rinfo->lowlevel->is_mobility) {
 		int ppll_div_sel;
 		u32 ppll_divn;
 		ppll_div_sel = INREG8(CLOCK_CNTL_INDEX + 1) & 0x3;
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index 98352af..c71de39 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -32,8 +32,8 @@ static void radeon_pm_disable_dynamic_mo
 	u32 tmp;
 
 	/* RV100 */
-	if ((rinfo->family == CHIP_FAMILY_RV100) && (!rinfo->is_mobility)) {
-		if (rinfo->has_CRTC2) {
+	if ((rinfo->lowlevel->family == CHIP_FAMILY_RV100) && (!rinfo->lowlevel->is_mobility)) {
+		if (rinfo->lowlevel->has_CRTC2) {
 			tmp = INPLL(pllSCLK_CNTL);
 			tmp &= ~SCLK_CNTL__DYN_STOP_LAT_MASK;
 			tmp |= SCLK_CNTL__CP_MAX_DYN_STOP_LAT | SCLK_CNTL__FORCEON_MASK;
@@ -50,7 +50,7 @@ static void radeon_pm_disable_dynamic_mo
 		return;
 	}
 	/* R100 */
-	if (!rinfo->has_CRTC2) {
+	if (!rinfo->lowlevel->has_CRTC2) {
                 tmp = INPLL(pllSCLK_CNTL);
                 tmp |= (SCLK_CNTL__FORCE_CP	| SCLK_CNTL__FORCE_HDP	|
 			SCLK_CNTL__FORCE_DISP1	| SCLK_CNTL__FORCE_TOP	|
@@ -63,7 +63,7 @@ static void radeon_pm_disable_dynamic_mo
 		return;
 	}
 	/* RV350 (M10) */
-	if (rinfo->family == CHIP_FAMILY_RV350) {
+	if (rinfo->lowlevel->family == CHIP_FAMILY_RV350) {
                 /* for RV350/M10, no delays are required. */
                 tmp = INPLL(pllSCLK_CNTL2);
                 tmp |= (SCLK_CNTL2__R300_FORCE_TCL |
@@ -130,7 +130,7 @@ static void radeon_pm_disable_dynamic_mo
 	/* XFree doesn't do that case, but we had this code from Apple and it
 	 * seem necessary for proper suspend/resume operations
 	 */
-	if (rinfo->is_mobility) {
+	if (rinfo->lowlevel->is_mobility) {
 		tmp |= 	SCLK_CNTL__FORCE_HDP|
 			SCLK_CNTL__FORCE_DISP1|
 			SCLK_CNTL__FORCE_DISP2|
@@ -147,8 +147,8 @@ static void radeon_pm_disable_dynamic_mo
 			SCLK_CNTL__FORCE_SUBPIC|
 			SCLK_CNTL__FORCE_OV0;
 	}
-	else if (rinfo->family == CHIP_FAMILY_R300 ||
-		   rinfo->family == CHIP_FAMILY_R350) {
+	else if (rinfo->lowlevel->family == CHIP_FAMILY_R300 ||
+		   rinfo->lowlevel->family == CHIP_FAMILY_R350) {
 		tmp |=  SCLK_CNTL__FORCE_HDP   |
 			SCLK_CNTL__FORCE_DISP1 |
 			SCLK_CNTL__FORCE_DISP2 |
@@ -159,7 +159,7 @@ static void radeon_pm_disable_dynamic_mo
     	OUTPLL(pllSCLK_CNTL, tmp);
 	radeon_msleep(16);
 
-	if (rinfo->family == CHIP_FAMILY_R300 || rinfo->family == CHIP_FAMILY_R350) {
+	if (rinfo->lowlevel->family == CHIP_FAMILY_R300 || rinfo->lowlevel->family == CHIP_FAMILY_R350) {
 		tmp = INPLL(pllSCLK_CNTL2);
 		tmp |=  SCLK_CNTL2__R300_FORCE_TCL |
 			SCLK_CNTL2__R300_FORCE_GA  |
@@ -173,7 +173,7 @@ static void radeon_pm_disable_dynamic_mo
 	OUTPLL(pllCLK_PIN_CNTL, tmp);
 	radeon_msleep(15);
 
-	if (rinfo->is_IGP) {
+	if (rinfo->lowlevel->is_IGP) {
 		/* Weird  ... X is _un_ forcing clocks here, I think it's
 		 * doing backward. Imitate it for now...
 		 */
@@ -184,7 +184,7 @@ static void radeon_pm_disable_dynamic_mo
 		radeon_msleep(16);
 	}
 	/* Hrm... same shit, X doesn't do that but I have to */
-	else if (rinfo->is_mobility) {
+	else if (rinfo->lowlevel->is_mobility) {
 		tmp = INPLL(pllMCLK_CNTL);
 		tmp |= (MCLK_CNTL__FORCE_MCLKA |
 			MCLK_CNTL__FORCE_MCLKB |
@@ -202,7 +202,7 @@ static void radeon_pm_disable_dynamic_mo
 		radeon_msleep(15);
 	}
 
-	if (rinfo->is_mobility) {
+	if (rinfo->lowlevel->is_mobility) {
 		tmp = INPLL(pllSCLK_MORE_CNTL);
 		tmp |= 	SCLK_MORE_CNTL__FORCE_DISPREGS|
 			SCLK_MORE_CNTL__FORCE_MC_GUI|
@@ -234,7 +234,7 @@ static void radeon_pm_enable_dynamic_mod
 	u32 tmp;
 
 	/* R100 */
-	if (!rinfo->has_CRTC2) {
+	if (!rinfo->lowlevel->has_CRTC2) {
                 tmp = INPLL(pllSCLK_CNTL);
 
 		if ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) > CFG_ATI_REV_A13)
@@ -249,7 +249,7 @@ static void radeon_pm_enable_dynamic_mod
 	}
 
 	/* M10 */
-	if (rinfo->family == CHIP_FAMILY_RV350) {
+	if (rinfo->lowlevel->family == CHIP_FAMILY_RV350) {
 		tmp = INPLL(pllSCLK_CNTL2);
 		tmp &= ~(SCLK_CNTL2__R300_FORCE_TCL |
 			 SCLK_CNTL2__R300_FORCE_GA  |
@@ -334,7 +334,7 @@ static void radeon_pm_enable_dynamic_mod
 	}
 
 	/* R300 */
-	if (rinfo->family == CHIP_FAMILY_R300 || rinfo->family == CHIP_FAMILY_R350) {
+	if (rinfo->lowlevel->family == CHIP_FAMILY_R300 || rinfo->lowlevel->family == CHIP_FAMILY_R350) {
 		tmp = INPLL(pllSCLK_CNTL);
 		tmp &= ~(SCLK_CNTL__R300_FORCE_VAP);
 		tmp |= SCLK_CNTL__FORCE_CP;
@@ -371,9 +371,9 @@ static void radeon_pm_enable_dynamic_mod
 	tmp &= ~SCLK_CNTL__FORCEON_MASK;
 
 	/*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300*/
-	if ((rinfo->family == CHIP_FAMILY_RV250 &&
+	if ((rinfo->lowlevel->family == CHIP_FAMILY_RV250 &&
 	     ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) ||
-	    ((rinfo->family == CHIP_FAMILY_RV100) &&
+	    ((rinfo->lowlevel->family == CHIP_FAMILY_RV100) &&
 	     ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) <= CFG_ATI_REV_A13))) {
 		tmp |= SCLK_CNTL__FORCE_CP;
 		tmp |= SCLK_CNTL__FORCE_VIP;
@@ -381,15 +381,15 @@ static void radeon_pm_enable_dynamic_mod
 	OUTPLL(pllSCLK_CNTL, tmp);
 	radeon_msleep(15);
 
-	if ((rinfo->family == CHIP_FAMILY_RV200) ||
-	    (rinfo->family == CHIP_FAMILY_RV250) ||
-	    (rinfo->family == CHIP_FAMILY_RV280)) {
+	if ((rinfo->lowlevel->family == CHIP_FAMILY_RV200) ||
+	    (rinfo->lowlevel->family == CHIP_FAMILY_RV250) ||
+	    (rinfo->lowlevel->family == CHIP_FAMILY_RV280)) {
 		tmp = INPLL(pllSCLK_MORE_CNTL);
 		tmp &= ~SCLK_MORE_CNTL__FORCEON;
 
 		/* RV200::A11 A12 RV250::A11 A12 */
-		if (((rinfo->family == CHIP_FAMILY_RV200) ||
-		     (rinfo->family == CHIP_FAMILY_RV250)) &&
+		if (((rinfo->lowlevel->family == CHIP_FAMILY_RV200) ||
+		     (rinfo->lowlevel->family == CHIP_FAMILY_RV250)) &&
 		    ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13))
 			tmp |= SCLK_MORE_CNTL__FORCEON;
 
@@ -399,8 +399,8 @@ static void radeon_pm_enable_dynamic_mod
 	
 
 	/* RV200::A11 A12, RV250::A11 A12 */
-	if (((rinfo->family == CHIP_FAMILY_RV200) ||
-	     (rinfo->family == CHIP_FAMILY_RV250)) &&
+	if (((rinfo->lowlevel->family == CHIP_FAMILY_RV200) ||
+	     (rinfo->lowlevel->family == CHIP_FAMILY_RV250)) &&
 	    ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) {
 		tmp = INPLL(pllPLL_PWRMGT_CNTL);
 		tmp |= PLL_PWRMGT_CNTL__TCL_BYPASS_DISABLE;
@@ -426,7 +426,7 @@ static void radeon_pm_enable_dynamic_mod
 
 	/* X doesn't do that ... hrm, we do on mobility && Macs */
 #ifdef CONFIG_PPC_OF
-	if (rinfo->is_mobility) {
+	if (rinfo->lowlevel->is_mobility) {
 		tmp  = INPLL(pllMCLK_CNTL);
 		tmp &= ~(MCLK_CNTL__FORCE_MCLKA |
 			 MCLK_CNTL__FORCE_MCLKB |
@@ -507,7 +507,7 @@ static void radeon_pm_save_regs(struct r
 	rinfo->save_regs[37] = INREG(MPP_TB_CONFIG);
 	rinfo->save_regs[38] = INREG(FCP_CNTL);
 
-	if (rinfo->is_mobility) {
+	if (rinfo->lowlevel->is_mobility) {
 		rinfo->save_regs[12] = INREG(LVDS_PLL_CNTL);
 		rinfo->save_regs[43] = INPLL(pllSSPLL_CNTL);
 		rinfo->save_regs[44] = INPLL(pllSSPLL_REF_DIV);
@@ -517,7 +517,7 @@ static void radeon_pm_save_regs(struct r
 		rinfo->save_regs[81] = INREG(LVDS_GEN_CNTL);
 	}
 
-	if (rinfo->family >= CHIP_FAMILY_RV200) {
+	if (rinfo->lowlevel->family >= CHIP_FAMILY_RV200) {
 		rinfo->save_regs[42] = INREG(MEM_REFRESH_CNTL);
 		rinfo->save_regs[46] = INREG(MC_CNTL);
 		rinfo->save_regs[47] = INREG(MC_INIT_GFX_LAT_TIMER);
@@ -533,7 +533,7 @@ static void radeon_pm_save_regs(struct r
 	rinfo->save_regs[56] = INREG(PAD_CTLR_MISC);
 	rinfo->save_regs[57] = INREG(FW_CNTL);
 
-	if (rinfo->family >= CHIP_FAMILY_R300) {
+	if (rinfo->lowlevel->family >= CHIP_FAMILY_R300) {
 		rinfo->save_regs[58] = INMC(rinfo, ixR300_MC_MC_INIT_WR_LAT_TIMER);
 		rinfo->save_regs[59] = INMC(rinfo, ixR300_MC_IMP_CNTL);
 		rinfo->save_regs[60] = INMC(rinfo, ixR300_MC_CHP_IO_CNTL_C0);
@@ -598,7 +598,7 @@ static void radeon_pm_restore_regs(struc
 	OUTPLL(VCLK_ECP_CNTL, rinfo->save_regs[5]);
 	OUTPLL(PIXCLKS_CNTL, rinfo->save_regs[6]);
 	OUTPLL(MCLK_MISC, rinfo->save_regs[7]);
-	if (rinfo->family == CHIP_FAMILY_RV350)
+	if (rinfo->lowlevel->family == CHIP_FAMILY_RV350)
 		OUTPLL(SCLK_MORE_CNTL, rinfo->save_regs[34]);
 
 	OUTREG(SURFACE_CNTL, rinfo->save_regs[29]);
@@ -649,9 +649,9 @@ static void radeon_pm_disable_iopad(stru
 static void radeon_pm_program_v2clk(struct radeonfb_info *rinfo)
 {
 	/* Set v2clk to 65MHz */
-	if (rinfo->family <= CHIP_FAMILY_RV280) {
+	if (rinfo->lowlevel->family <= CHIP_FAMILY_RV280) {
 		OUTPLL(pllPIXCLKS_CNTL,
-			 __INPLL(rinfo, pllPIXCLKS_CNTL)
+			 radeon_INPLL(rinfo->lowlevel, pllPIXCLKS_CNTL)
 			 & ~PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK);
 	 
 		OUTPLL(pllP2PLL_REF_DIV, 0x0000000c);
@@ -681,7 +681,7 @@ static void radeon_pm_low_current(struct
 	u32 reg;
 
 	reg  = INREG(BUS_CNTL1);
-	if (rinfo->family <= CHIP_FAMILY_RV280) {
+	if (rinfo->lowlevel->family <= CHIP_FAMILY_RV280) {
 		reg &= ~BUS_CNTL1_MOBILE_PLATFORM_SEL_MASK;
 		reg |= BUS_CNTL1_AGPCLK_VALID | (1<<BUS_CNTL1_MOBILE_PLATFORM_SEL_SHIFT);
 	} else {
@@ -761,7 +761,7 @@ static void radeon_pm_setup_for_suspend(
 			SCLK_CNTL__FORCE_TV_SCLK|
 			SCLK_CNTL__FORCE_SUBPIC|
 			SCLK_CNTL__FORCE_OV0;
-	if (rinfo->family <= CHIP_FAMILY_RV280)
+	if (rinfo->lowlevel->family <= CHIP_FAMILY_RV280)
 		sclk_cntl |= SCLK_CNTL__FORCE_RE;
 	else
 		sclk_cntl |= SCLK_CNTL__SE_MAX_DYN_STOP_LAT |
@@ -854,7 +854,7 @@ static void radeon_pm_setup_for_suspend(
 	OUTPLL( pllMCLK_MISC, tmp);
 	
 	/* AGP PLL control */
-	if (rinfo->family <= CHIP_FAMILY_RV280) {
+	if (rinfo->lowlevel->family <= CHIP_FAMILY_RV280) {
 		OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) |  BUS_CNTL1__AGPCLK_VALID);
 
 		OUTREG(BUS_CNTL1,
@@ -1156,7 +1156,7 @@ static void radeon_pm_full_reset_sdram(s
 	OUTREG( CRTC2_GEN_CNTL, (crtcGenCntl2 | CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B) );
   
 	/* This is the code for the Aluminium PowerBooks M10 */
-	if (rinfo->family == CHIP_FAMILY_RV350) {
+	if (rinfo->lowlevel->family == CHIP_FAMILY_RV350) {
 		u32 sdram_mode_reg = rinfo->save_regs[35];
 		static u32 default_mrtable[] =
 			{ 0x21320032,
@@ -1217,7 +1217,7 @@ static void radeon_pm_full_reset_sdram(s
 
 	}
 	/* Here come the desktop RV200 "QW" card */
-	else if (!rinfo->is_mobility && rinfo->family == CHIP_FAMILY_RV200) {
+	else if (!rinfo->lowlevel->is_mobility && rinfo->lowlevel->family == CHIP_FAMILY_RV200) {
 		/* Disable refresh */
 		memRefreshCntl 	= INREG( MEM_REFRESH_CNTL)
 			& ~MEM_REFRESH_CNTL__MEM_REFRESH_DIS;
@@ -1240,7 +1240,7 @@ static void radeon_pm_full_reset_sdram(s
 
 	}
 	/* The M6 */
-	else if (rinfo->is_mobility && rinfo->family == CHIP_FAMILY_RV100) {
+	else if (rinfo->lowlevel->is_mobility && rinfo->lowlevel->family == CHIP_FAMILY_RV100) {
 		/* Disable refresh */
 		memRefreshCntl = INREG(EXT_MEM_CNTL) & ~(1 << 20);
 		OUTREG( EXT_MEM_CNTL, memRefreshCntl | (1 << 20));
@@ -1270,7 +1270,7 @@ static void radeon_pm_full_reset_sdram(s
 		OUTREG(EXT_MEM_CNTL, memRefreshCntl);
 	}
 	/* And finally, the M7..M9 models, including M9+ (RV280) */
-	else if (rinfo->is_mobility) {
+	else if (rinfo->lowlevel->is_mobility) {
 
 		/* Disable refresh */
 		memRefreshCntl 	= INREG( MEM_REFRESH_CNTL)
@@ -1290,7 +1290,7 @@ static void radeon_pm_full_reset_sdram(s
 		radeon_pm_yclk_mclk_sync(rinfo);
 
 		/* M6, M7 and M9 so far ... */
-		if (rinfo->family <= CHIP_FAMILY_RV250) {
+		if (rinfo->lowlevel->family <= CHIP_FAMILY_RV250) {
 			radeon_pm_program_mode_reg(rinfo, 0x2000, 1);
 			radeon_pm_program_mode_reg(rinfo, 0x2001, 1);
 			radeon_pm_program_mode_reg(rinfo, 0x2002, 1);
@@ -1298,7 +1298,7 @@ static void radeon_pm_full_reset_sdram(s
 			radeon_pm_program_mode_reg(rinfo, 0x0032, 1);
 		}
 		/* M9+ (iBook G4) */
-		else if (rinfo->family == CHIP_FAMILY_RV280) {
+		else if (rinfo->lowlevel->family == CHIP_FAMILY_RV280) {
 			radeon_pm_program_mode_reg(rinfo, 0x2000, 1);
 			radeon_pm_program_mode_reg(rinfo, 0x0132, 1);
 			radeon_pm_program_mode_reg(rinfo, 0x0032, 1);
@@ -2408,7 +2408,7 @@ static void radeon_set_suspend(struct ra
 	u16 pwr_cmd;
 	u32 tmp;
 	int i;
-
+	struct pci_dev *pdev = to_pci_dev(rinfo->lowlevel->vll.dev.parent);
 	if (!rinfo->pm_reg)
 		return;
 
@@ -2418,7 +2418,7 @@ static void radeon_set_suspend(struct ra
 	 */
 	if (suspend) {
 		printk(KERN_DEBUG "radeonfb (%s): switching to D2 state...\n",
-		       pci_name(rinfo->pdev));
+		       pci_name(pdev));
 
 		/* Disable dynamic power management of clocks for the
 		 * duration of the suspend/resume process
@@ -2430,7 +2430,7 @@ static void radeon_set_suspend(struct ra
 
 		/* Prepare mobility chips for suspend.
 		 */
-		if (rinfo->is_mobility) {
+		if (rinfo->lowlevel->is_mobility) {
 			/* Program V2CLK */
 			radeon_pm_program_v2clk(rinfo);
 		
@@ -2443,7 +2443,7 @@ static void radeon_set_suspend(struct ra
 			/* Prepare chip for power management */
 			radeon_pm_setup_for_suspend(rinfo);
 
-			if (rinfo->family <= CHIP_FAMILY_RV280) {
+			if (rinfo->lowlevel->family <= CHIP_FAMILY_RV280) {
 				/* Reset the MDLL */
 				/* because both INPLL and OUTPLL take the same
 				 * lock, that's why. */
@@ -2454,32 +2454,32 @@ static void radeon_set_suspend(struct ra
 		}
 
 		for (i = 0; i < 64; ++i)
-			pci_read_config_dword(rinfo->pdev, i * 4,
+			pci_read_config_dword(pdev, i * 4,
 					      &rinfo->cfg_save[i]);
 
 		/* Switch PCI power managment to D2. */
-		pci_disable_device(rinfo->pdev);
+		pci_disable_device(pdev);
 		for (;;) {
 			pci_read_config_word(
-				rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
+				pdev, rinfo->pm_reg+PCI_PM_CTRL,
 				&pwr_cmd);
 			if (pwr_cmd & 2)
 				break;			
 			pci_write_config_word(
-				rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
+				pdev, rinfo->pm_reg+PCI_PM_CTRL,
 				(pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2);
 			mdelay(500);
 		}
 	} else {
 		printk(KERN_DEBUG "radeonfb (%s): switching to D0 state...\n",
-		       pci_name(rinfo->pdev));
+		       pci_name(pdev));
 
 		/* Switch back PCI powermanagment to D0 */
 		mdelay(200);
-		pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0);
+		pci_write_config_word(pdev, rinfo->pm_reg+PCI_PM_CTRL, 0);
 		mdelay(500);
 
-		if (rinfo->family <= CHIP_FAMILY_RV250) {
+		if (rinfo->lowlevel->family <= CHIP_FAMILY_RV250) {
 			/* Reset the SDRAM controller  */
 			radeon_pm_full_reset_sdram(rinfo);
 
@@ -2496,11 +2496,13 @@ static void radeon_set_suspend(struct ra
 
 static int radeon_restore_pci_cfg(struct radeonfb_info *rinfo)
 {
+	struct pci_dev *pdev = to_pci_dev(rinfo->lowlevel->vll.dev.parent);
 	int i;
 	static u32 radeon_cfg_after_resume[64];
 
+
 	for (i = 0; i < 64; ++i)
-		pci_read_config_dword(rinfo->pdev, i * 4,
+		pci_read_config_dword(pdev, i * 4,
 				      &radeon_cfg_after_resume[i]);
 
 	if (radeon_cfg_after_resume[PCI_BASE_ADDRESS_0/4]
@@ -2509,20 +2511,21 @@ static int radeon_restore_pci_cfg(struct
 
 	for (i = PCI_BASE_ADDRESS_0/4; i < 64; ++i) {
 		if (radeon_cfg_after_resume[i] != rinfo->cfg_save[i])
-			pci_write_config_dword(rinfo->pdev, i * 4,
+			pci_write_config_dword(pdev, i * 4,
 					       rinfo->cfg_save[i]);
 	}
-	pci_write_config_word(rinfo->pdev, PCI_CACHE_LINE_SIZE,
+	pci_write_config_word(pdev, PCI_CACHE_LINE_SIZE,
 			      rinfo->cfg_save[PCI_CACHE_LINE_SIZE/4]);
-	pci_write_config_word(rinfo->pdev, PCI_COMMAND,
+	pci_write_config_word(pdev, PCI_COMMAND,
 			      rinfo->cfg_save[PCI_COMMAND/4]);
 	return 1;
 }
 
 
-int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+int radeonfb_suspend(struct vll_dev *vdev, pm_message_t state)
 {
-        struct fb_info *info = pci_get_drvdata(pdev);
+	struct pci_dev *pdev = to_pci_dev(vdev->dev.parent);
+        struct fb_info *info = vll_get_drvdata(vdev);
         struct radeonfb_info *rinfo = info->par;
 	int i;
 
@@ -2581,7 +2584,7 @@ int radeonfb_pci_suspend(struct pci_dev 
 		mdelay(50);
 		radeon_pm_save_regs(rinfo, 1);
 
-		if (rinfo->is_mobility && !(rinfo->pm_mode & radeon_pm_d2)) {
+		if (rinfo->lowlevel->is_mobility && !(rinfo->pm_mode & radeon_pm_d2)) {
 			/* Switch off LVDS interface */
 			mdelay(1);
 			OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) & ~(LVDS_BL_MOD_EN));
@@ -2610,16 +2613,17 @@ int radeonfb_pci_suspend(struct pci_dev 
 	return 0;
 }
 
-int radeonfb_pci_resume(struct pci_dev *pdev)
+int radeonfb_resume(struct vll_dev *vdev)
 {
-        struct fb_info *info = pci_get_drvdata(pdev);
+	struct pci_dev *pdev = to_pci_dev(vdev->dev.parent);
+        struct fb_info *info = vll_get_drvdata(vdev);
         struct radeonfb_info *rinfo = info->par;
 	int rc = 0;
 
 	if (pdev->dev.power.power_state == 0)
 		return 0;
 
-	if (rinfo->no_schedule) {
+	if (rinfo->lowlevel->no_schedule) {
 		if (try_acquire_console_sem())
 			return 0;
 	} else
@@ -2705,9 +2709,9 @@ static void radeonfb_early_resume(void *
 {
         struct radeonfb_info *rinfo = data;
 
-	rinfo->no_schedule = 1;
+	rinfo->lowlevel->no_schedule = 1;
 	radeonfb_pci_resume(rinfo->pdev);
-	rinfo->no_schedule = 0;
+	rinfo->lowlevel->no_schedule = 0;
 }
 #endif /* CONFIG_PPC_OF */
 
@@ -2715,8 +2719,9 @@ static void radeonfb_early_resume(void *
 
 void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk)
 {
+	struct pci_dev *pdev = to_pci_dev(rinfo->lowlevel->vll.dev.parent);
 	/* Find PM registers in config space if any*/
-	rinfo->pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM);
+	rinfo->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
 
 	/* Enable/Disable dynamic clocks: TODO add sysfs access */
 	rinfo->dynclk = dynclk;
@@ -2736,8 +2741,8 @@ void radeonfb_pm_init(struct radeonfb_in
 	 */
 #if defined(CONFIG_PM) && defined(CONFIG_PPC_OF)
 	if (_machine == _MACH_Pmac && rinfo->of_node) {
-		if (rinfo->is_mobility && rinfo->pm_reg &&
-		    rinfo->family <= CHIP_FAMILY_RV250)
+		if (rinfo->lowlevel->is_mobility && rinfo->pm_reg &&
+		    rinfo->lowlevel->family <= CHIP_FAMILY_RV250)
 			rinfo->pm_mode |= radeon_pm_d2;
 
 		/* We can restart Jasper (M10 chip in albooks), BlueStone (7500 chip
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index 659bc9f..2c12d3c 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -26,67 +26,7 @@
  * Most of the definitions here are adapted right from XFree86 *
  ***************************************************************/
 
-
-/*
- * Chip families. Must fit in the low 16 bits of a long word
- */
-enum radeon_family {
-	CHIP_FAMILY_UNKNOW,
-	CHIP_FAMILY_LEGACY,
-	CHIP_FAMILY_RADEON,
-	CHIP_FAMILY_RV100,
-	CHIP_FAMILY_RS100,    /* U1 (IGP320M) or A3 (IGP320)*/
-	CHIP_FAMILY_RV200,
-	CHIP_FAMILY_RS200,    /* U2 (IGP330M/340M/350M) or A4 (IGP330/340/345/350),
-				 RS250 (IGP 7000) */
-	CHIP_FAMILY_R200,
-	CHIP_FAMILY_RV250,
-	CHIP_FAMILY_RS300,    /* Radeon 9000 IGP */
-	CHIP_FAMILY_RV280,
-	CHIP_FAMILY_R300,
-	CHIP_FAMILY_R350,
-	CHIP_FAMILY_RV350,
-	CHIP_FAMILY_RV380,    /* RV370/RV380/M22/M24 */
-	CHIP_FAMILY_R420,     /* R420/R423/M18 */
-	CHIP_FAMILY_LAST,
-};
-
-#define IS_RV100_VARIANT(rinfo) (((rinfo)->family == CHIP_FAMILY_RV100)  || \
-				 ((rinfo)->family == CHIP_FAMILY_RV200)  || \
-				 ((rinfo)->family == CHIP_FAMILY_RS100)  || \
-				 ((rinfo)->family == CHIP_FAMILY_RS200)  || \
-				 ((rinfo)->family == CHIP_FAMILY_RV250)  || \
-				 ((rinfo)->family == CHIP_FAMILY_RV280)  || \
-				 ((rinfo)->family == CHIP_FAMILY_RS300))
-
-
-#define IS_R300_VARIANT(rinfo) (((rinfo)->family == CHIP_FAMILY_R300)  || \
-				((rinfo)->family == CHIP_FAMILY_RV350) || \
-				((rinfo)->family == CHIP_FAMILY_R350)  || \
-				((rinfo)->family == CHIP_FAMILY_RV380) || \
-				((rinfo)->family == CHIP_FAMILY_R420))
-
-/*
- * Chip flags
- */
-enum radeon_chip_flags {
-	CHIP_FAMILY_MASK	= 0x0000ffffUL,
-	CHIP_FLAGS_MASK		= 0xffff0000UL,
-	CHIP_IS_MOBILITY	= 0x00010000UL,
-	CHIP_IS_IGP		= 0x00020000UL,
-	CHIP_HAS_CRTC2		= 0x00040000UL,	
-};
-
-/*
- * Errata workarounds
- */
-enum radeon_errata {
-	CHIP_ERRATA_R300_CG		= 0x00000001,
-	CHIP_ERRATA_PLL_DUMMYREADS	= 0x00000002,
-	CHIP_ERRATA_PLL_DELAY		= 0x00000004,
-};
-
-
+#include <linux/radeon_lowlevel.h>
 /*
  * Monitor types
  */
@@ -276,20 +216,17 @@ enum radeon_pm_mode {
 struct radeonfb_info {
 	struct fb_info		*info;
 
+	struct radeonll_info    *lowlevel;
 	struct radeon_regs 	state;
 	struct radeon_regs	init_state;
 
 	char			name[DEVICE_NAME_SIZE];
 
-	unsigned long		mmio_base_phys;
-	unsigned long		fb_base_phys;
-
-	void __iomem		*mmio_base;
 	void __iomem		*fb_base;
-
 	unsigned long		fb_local_base;
 
-	struct pci_dev		*pdev;
+	struct vll_dev          *vdev;
+
 #ifdef CONFIG_PPC_OF
 	struct device_node	*of_node;
 #endif
@@ -301,10 +238,6 @@ struct radeonfb_info {
 	struct { u8 red, green, blue, pad; }
 				palette[256];
 
-	int			chipset;
-	u8			family;
-	u8			rev;
-	unsigned int		errata;
 	unsigned long		video_ram;
 	unsigned long		mapped_vram;
 	int			vram_width;
@@ -312,9 +245,6 @@ struct radeonfb_info {
 
 	int			pitch, bpp, depth;
 
-	int			has_CRTC2;
-	int			is_mobility;
-	int			is_IGP;
 	int			reversed_DAC;
 	int			reversed_TMDS;
 	struct panel_info	panel_info;
@@ -336,13 +266,9 @@ struct radeonfb_info {
 	int			asleep;
 	int			lock_blank;
 	int			dynclk;
-	int			no_schedule;
 	enum radeon_pm_mode	pm_mode;
 	void			(*reinit_func)(struct radeonfb_info *rinfo);
 
-	/* Lock on register access */
-	spinlock_t		reg_lock;
-
 	/* Timer used for delayed LVDS operations */
 	struct timer_list	lvds_timer;
 	u32			pending_lvds_gen_cntl;
@@ -374,125 +300,15 @@ struct radeonfb_info {
 #endif
 
 
-/*
- * IO macros
- */
-
-/* Note about this function: we have some rare cases where we must not schedule,
- * this typically happen with our special "wake up early" hook which allows us to
- * wake up the graphic chip (and thus get the console back) before everything else
- * on some machines that support that mecanism. At this point, interrupts are off
- * and scheduling is not permitted
- */
-static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms)
-{
-	if (rinfo->no_schedule || oops_in_progress)
-		mdelay(ms);
-	else
-		msleep(ms);
-}
-
-
-#define INREG8(addr)		readb((rinfo->mmio_base)+addr)
-#define OUTREG8(addr,val)	writeb(val, (rinfo->mmio_base)+addr)
-#define INREG(addr)		readl((rinfo->mmio_base)+addr)
-#define OUTREG(addr,val)	writel(val, (rinfo->mmio_base)+addr)
-
-static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr,
-		       u32 val, u32 mask)
-{
-	unsigned long flags;
-	unsigned int tmp;
-
-	spin_lock_irqsave(&rinfo->reg_lock, flags);
-	tmp = INREG(addr);
-	tmp &= (mask);
-	tmp |= (val);
-	OUTREG(addr, tmp);
-	spin_unlock_irqrestore(&rinfo->reg_lock, flags);
-}
-
-#define OUTREGP(addr,val,mask)	_OUTREGP(rinfo, addr, val,mask)
-
-/*
- * Note about PLL register accesses:
- *
- * I have removed the spinlock on them on purpose. The driver now
- * expects that it will only manipulate the PLL registers in normal
- * task environment, where radeon_msleep() will be called, protected
- * by a semaphore (currently the console semaphore) so that no conflict
- * will happen on the PLL register index.
- *
- * With the latest changes to the VT layer, this is guaranteed for all
- * calls except the actual drawing/blits which aren't supposed to use
- * the PLL registers anyway
- *
- * This is very important for the workarounds to work properly. The only
- * possible exception to this rule is the call to unblank(), which may
- * be done at irq time if an oops is in progress.
- */
-static inline void radeon_pll_errata_after_index(struct radeonfb_info *rinfo)
-{
-	if (!(rinfo->errata & CHIP_ERRATA_PLL_DUMMYREADS))
-		return;
-
-	(void)INREG(CLOCK_CNTL_DATA);
-	(void)INREG(CRTC_GEN_CNTL);
-}
-
-static inline void radeon_pll_errata_after_data(struct radeonfb_info *rinfo)
-{
-	if (rinfo->errata & CHIP_ERRATA_PLL_DELAY) {
-		/* we can't deal with posted writes here ... */
-		_radeon_msleep(rinfo, 5);
-	}
-	if (rinfo->errata & CHIP_ERRATA_R300_CG) {
-		u32 save, tmp;
-		save = INREG(CLOCK_CNTL_INDEX);
-		tmp = save & ~(0x3f | PLL_WR_EN);
-		OUTREG(CLOCK_CNTL_INDEX, tmp);
-		tmp = INREG(CLOCK_CNTL_DATA);
-		OUTREG(CLOCK_CNTL_INDEX, save);
-	}
-}
-
-static inline u32 __INPLL(struct radeonfb_info *rinfo, u32 addr)
-{
-	u32 data;
-
-	OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f);
-	radeon_pll_errata_after_index(rinfo);
-	data = INREG(CLOCK_CNTL_DATA);
-	radeon_pll_errata_after_data(rinfo);
-	return data;
-}
-
-static inline void __OUTPLL(struct radeonfb_info *rinfo, unsigned int index,
-			    u32 val)
-{
-
-	OUTREG8(CLOCK_CNTL_INDEX, (index & 0x0000003f) | 0x00000080);
-	radeon_pll_errata_after_index(rinfo);
-	OUTREG(CLOCK_CNTL_DATA, val);
-	radeon_pll_errata_after_data(rinfo);
-}
-
-
-static inline void __OUTPLLP(struct radeonfb_info *rinfo, unsigned int index,
-			     u32 val, u32 mask)
-{
-	unsigned int tmp;
-
-	tmp  = __INPLL(rinfo, index);
-	tmp &= (mask);
-	tmp |= (val);
-	__OUTPLL(rinfo, index, tmp);
-}
-
-
-#define INPLL(addr)			__INPLL(rinfo, addr)
-#define OUTPLL(index, val)		__OUTPLL(rinfo, index, val)
-#define OUTPLLP(index, val, mask)	__OUTPLLP(rinfo, index, val, mask)
+#define INREG8(addr)		radeon_INREG8(rinfo->lowlevel, addr)
+#define OUTREG8(addr,val)	radeon_OUTREG8(rinfo->lowlevel, addr, val)
+#define INREG(addr)		radeon_INREG(rinfo->lowlevel, addr)
+#define OUTREG(addr,val)	radeon_OUTREG(rinfo->lowlevel, addr, val)
+
+#define INPLL(index) radeon_INPLL(rinfo->lowlevel, index)
+#define OUTPLL(index, val) radeon_OUTPLL(rinfo->lowlevel, index, val)
+#define OUTPLLP(index, val, mask) radeon_OUTPLLP(rinfo->lowlevel, index, val, mask)
+#define OUTREGP(addr, val, mask) radeon_OUTREGP(rinfo->lowlevel, addr, val, mask)
 
 
 #define BIOS_IN8(v)  	(readb(rinfo->bios_seg + (v)))
@@ -587,7 +403,7 @@ static inline void _radeon_engine_idle(s
 
 #define radeon_engine_idle()		_radeon_engine_idle(rinfo)
 #define radeon_fifo_wait(entries)	_radeon_fifo_wait(rinfo,entries)
-#define radeon_msleep(ms)		_radeon_msleep(rinfo,ms)
+#define radeon_msleep(ms)		_radeon_msleep(rinfo->lowlevel,ms)
 
 
 /* I2C Functions */
@@ -596,8 +412,8 @@ extern void radeon_delete_i2c_busses(str
 extern int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8 **out_edid);
 
 /* PM Functions */
-extern int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t state);
-extern int radeonfb_pci_resume(struct pci_dev *pdev);
+extern int radeonfb_suspend(struct vll_dev *vdev, pm_message_t state);
+extern int radeonfb_resume(struct vll_dev *vdev);
 extern void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk);
 extern void radeonfb_pm_exit(struct radeonfb_info *rinfo);
 
diff --git a/drivers/video/radeon_lowlevel.c b/drivers/video/radeon_lowlevel.c
new file mode 100644
index 0000000..cac4152
--- /dev/null
+++ b/drivers/video/radeon_lowlevel.c
@@ -0,0 +1,312 @@
+/* Radeon Lowlevel driver */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/time.h>
+#include <linux/fb.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include "aty/ati_ids.h"
+#include <linux/radeon_lowlevel.h>
+
+#define CHIP_DEF(id, family, flags)					\
+	{ PCI_VENDOR_ID_ATI, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (flags) | (CHIP_FAMILY_##family) }
+
+static struct pci_device_id radeonll_pci_table[] = {
+	/* Mobility M6 */
+	CHIP_DEF(PCI_CHIP_RADEON_LY, 	RV100,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RADEON_LZ,	RV100,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	/* Radeon VE/7000 */
+	CHIP_DEF(PCI_CHIP_RV100_QY, 	RV100,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV100_QZ, 	RV100,	CHIP_HAS_CRTC2),
+	/* Radeon IGP320M (U1) */
+	CHIP_DEF(PCI_CHIP_RS100_4336,	RS100,	CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
+	/* Radeon IGP320 (A3) */
+	CHIP_DEF(PCI_CHIP_RS100_4136,	RS100,	CHIP_HAS_CRTC2 | CHIP_IS_IGP), 
+	/* IGP330M/340M/350M (U2) */
+	CHIP_DEF(PCI_CHIP_RS200_4337,	RS200,	CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
+	/* IGP330/340/350 (A4) */
+	CHIP_DEF(PCI_CHIP_RS200_4137,	RS200,	CHIP_HAS_CRTC2 | CHIP_IS_IGP),
+	/* Mobility 7000 IGP */
+	CHIP_DEF(PCI_CHIP_RS250_4437,	RS200,	CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
+	/* 7000 IGP (A4+) */
+	CHIP_DEF(PCI_CHIP_RS250_4237,	RS200,	CHIP_HAS_CRTC2 | CHIP_IS_IGP),
+	/* 8500 AIW */
+	CHIP_DEF(PCI_CHIP_R200_BB,	R200,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R200_BC,	R200,	CHIP_HAS_CRTC2),
+	/* 8700/8800 */
+	CHIP_DEF(PCI_CHIP_R200_QH,	R200,	CHIP_HAS_CRTC2),
+	/* 8500 */
+	CHIP_DEF(PCI_CHIP_R200_QL,	R200,	CHIP_HAS_CRTC2),
+	/* 9100 */
+	CHIP_DEF(PCI_CHIP_R200_QM,	R200,	CHIP_HAS_CRTC2),
+	/* Mobility M7 */
+	CHIP_DEF(PCI_CHIP_RADEON_LW,	RV200,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RADEON_LX,	RV200,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	/* 7500 */
+	CHIP_DEF(PCI_CHIP_RV200_QW,	RV200,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV200_QX,	RV200,	CHIP_HAS_CRTC2),
+	/* Mobility M9 */
+	CHIP_DEF(PCI_CHIP_RV250_Ld,	RV250,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RV250_Le,	RV250,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RV250_Lf,	RV250,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RV250_Lg,	RV250,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	/* 9000/Pro */
+	CHIP_DEF(PCI_CHIP_RV250_If,	RV250,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV250_Ig,	RV250,	CHIP_HAS_CRTC2),
+	/* Mobility 9100 IGP (U3) */
+	CHIP_DEF(PCI_CHIP_RS300_5835,	RS300,	CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RS350_7835,	RS300,	CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
+	/* 9100 IGP (A5) */
+	CHIP_DEF(PCI_CHIP_RS300_5834,	RS300,	CHIP_HAS_CRTC2 | CHIP_IS_IGP),
+	CHIP_DEF(PCI_CHIP_RS350_7834,	RS300,	CHIP_HAS_CRTC2 | CHIP_IS_IGP),
+	/* Mobility 9200 (M9+) */
+	CHIP_DEF(PCI_CHIP_RV280_5C61,	RV280,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RV280_5C63,	RV280,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	/* 9200 */
+	CHIP_DEF(PCI_CHIP_RV280_5960,	RV280,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV280_5961,	RV280,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV280_5962,	RV280,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV280_5964,	RV280,	CHIP_HAS_CRTC2),
+	/* 9500 */
+	CHIP_DEF(PCI_CHIP_R300_AD,	R300,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R300_AE,	R300,	CHIP_HAS_CRTC2),
+	/* 9600TX / FireGL Z1 */
+	CHIP_DEF(PCI_CHIP_R300_AF,	R300,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R300_AG,	R300,	CHIP_HAS_CRTC2),
+	/* 9700/9500/Pro/FireGL X1 */
+	CHIP_DEF(PCI_CHIP_R300_ND,	R300,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R300_NE,	R300,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R300_NF,	R300,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R300_NG,	R300,	CHIP_HAS_CRTC2),
+	/* Mobility M10/M11 */
+	CHIP_DEF(PCI_CHIP_RV350_NP,	RV350,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RV350_NQ,	RV350,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RV350_NR,	RV350,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RV350_NS,	RV350,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RV350_NT,	RV350,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RV350_NV,	RV350,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	/* 9600/FireGL T2 */
+	CHIP_DEF(PCI_CHIP_RV350_AP,	RV350,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV350_AQ,	RV350,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV360_AR,	RV350,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV350_AS,	RV350,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV350_AT,	RV350,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV350_AV,	RV350,	CHIP_HAS_CRTC2),
+	/* 9800/Pro/FileGL X2 */
+	CHIP_DEF(PCI_CHIP_R350_AH,	R350,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R350_AI,	R350,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R350_AJ,	R350,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R350_AK,	R350,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R350_NH,	R350,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R350_NI,	R350,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R360_NJ,	R350,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R350_NK,	R350,	CHIP_HAS_CRTC2),
+	/* Newer stuff */
+	CHIP_DEF(PCI_CHIP_RV380_3E50,	RV380,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV380_3E54,	RV380,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV380_3150,	RV380,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RV380_3154,	RV380,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RV370_5B60,	RV380,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV370_5B62,	RV380,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV370_5B64,	RV380,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV370_5B65,	RV380,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_RV370_5460,	RV380,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_RV370_5464,	RV380,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_R420_JH,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R420_JI,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R420_JJ,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R420_JK,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R420_JL,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R420_JM,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R420_JN,	R420,	CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
+	CHIP_DEF(PCI_CHIP_R420_JP,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R423_UH,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R423_UI,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R423_UJ,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R423_UK,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R423_UQ,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R423_UR,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R423_UT,	R420,	CHIP_HAS_CRTC2),
+	CHIP_DEF(PCI_CHIP_R423_5D57,	R420,	CHIP_HAS_CRTC2),
+	/* Original Radeon/7200 */
+	CHIP_DEF(PCI_CHIP_RADEON_QD,	RADEON,	0),
+	CHIP_DEF(PCI_CHIP_RADEON_QE,	RADEON,	0),
+	CHIP_DEF(PCI_CHIP_RADEON_QF,	RADEON,	0),
+	CHIP_DEF(PCI_CHIP_RADEON_QG,	RADEON,	0),
+	{ 0, }
+};
+MODULE_DEVICE_TABLE(pci, radeonll_pci_table);
+
+MODULE_AUTHOR("Dave Airlie");
+MODULE_DESCRIPTION("Lowlevel driver for Radeon Chipset");
+MODULE_LICENSE("GPL");
+
+#define RADEON_MAXCARDS 64
+struct radeon_busmap {
+	unsigned long busmap [ RADEON_MAXCARDS / (8*sizeof(unsigned long))];
+};
+static struct radeon_busmap busmap;
+struct bus_type radeon_bus_type;
+EXPORT_SYMBOL(radeon_bus_type);
+
+int radeonll_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	return 0;
+}
+
+int radeonll_pci_resume(struct pci_dev *pdev)
+{
+	return 0;
+}
+
+static int radeonll_pci_register(struct pci_dev *pdev,
+				 const struct pci_device_id *ent)
+{
+	int ret;
+	struct radeonll_info *rll_info;
+	int busnum;
+	busnum = find_next_zero_bit(busmap.busmap, RADEON_MAXCARDS, 1);
+	if (busnum < RADEON_MAXCARDS) {
+		set_bit(busnum, busmap.busmap);
+		
+	}
+	else
+	{
+		printk(KERN_ERR "radeon: too many cards\n");
+		return -E2BIG;
+	}
+
+	/* Enable device in PCI config */
+	ret = pci_enable_device(pdev);
+	if (ret < 0) {
+		printk(KERN_ERR "radeonll (%s): Cannot enable PCI device\n",
+		       pci_name(pdev));
+		goto err_out;
+	}
+	
+	rll_info = (struct radeonll_info *)kcalloc(1, sizeof(struct radeonll_info), GFP_KERNEL);
+	if (!rll_info) {
+		printk(KERN_ERR "radeonll (%s): Unable to allocate radeon lowlevel\n",
+		       pci_name(pdev));
+		goto err_out;
+	}
+	
+	spin_lock_init(&rll_info->reg_lock);
+	
+	rll_info->family = ent->driver_data & CHIP_FAMILY_MASK;
+	rll_info->chipset = pdev->device;
+	rll_info->has_CRTC2 = (ent->driver_data & CHIP_HAS_CRTC2) != 0;
+	rll_info->is_mobility = (ent->driver_data & CHIP_IS_MOBILITY) != 0;
+	rll_info->is_IGP = (ent->driver_data & CHIP_IS_IGP) != 0;
+	
+	/* Set base addrs */
+	rll_info->fb_base_phys = pci_resource_start (pdev, 0);
+	rll_info->mmio_base_phys = pci_resource_start (pdev, 2);
+	
+	/* request the mem regions */
+	ret = pci_request_regions(pdev, "radeonll");
+	if (ret < 0) {
+		printk( KERN_ERR "radeonll (%s): cannot reserve PCI regions."
+			"  Someone already got them?\n", pci_name(pdev));
+		goto err_free_info;
+	}
+	
+	/* map the regions */
+	rll_info->mmio_base = ioremap(rll_info->mmio_base_phys, RADEON_REGSIZE);
+	if (!rll_info->mmio_base) {
+		printk(KERN_ERR "radeonll (%s): cannot map MMIO\n", pci_name(pdev));
+		ret = -EIO;
+		goto err_release_pci;
+	}
+	
+	/*
+	 * Check for errata
+	 */
+	rll_info->errata = 0;
+	if (rll_info->family == CHIP_FAMILY_R300 &&
+	    (radeon_INREG(rll_info, CONFIG_CNTL) & CFG_ATI_REV_ID_MASK)
+	    == CFG_ATI_REV_A11)
+		rll_info->errata |= CHIP_ERRATA_R300_CG;
+	
+	if (rll_info->family == CHIP_FAMILY_RV200 ||
+	    rll_info->family == CHIP_FAMILY_RS200)
+		rll_info->errata |= CHIP_ERRATA_PLL_DUMMYREADS;
+	
+	if (rll_info->family == CHIP_FAMILY_RV100 ||
+	    rll_info->family == CHIP_FAMILY_RS100 ||
+	    rll_info->family == CHIP_FAMILY_RS200)
+		rll_info->errata |= CHIP_ERRATA_PLL_DELAY;
+	
+	pci_set_drvdata(pdev, rll_info);
+	
+	printk("Radeon ll pdev is %p\n", pdev);
+	vll_init_devices(&rll_info->vll, radeon_bus_type);
+	rll_info->vll.dev.parent = &pdev->dev;
+	rll_info->vll.dev.bus = &radeon_bus_type;
+	//	rll_info->vll.dev.driver = pdev->dev->driver;
+	sprintf(rll_info->vll.dev.bus_id, "radeon%d", busnum);
+	vll_device_register(&rll_info->vll);
+	return 0;
+	
+err_release_pci:
+err_free_info:
+	kfree(rll_info);
+err_out:
+	return ret;
+}
+
+static void __devexit radeonll_pci_unregister (struct pci_dev *pdev)
+{
+	struct radeonll_info *rll_info = pci_get_drvdata(pdev);
+
+	vll_device_unregister(&rll_info->vll);
+	pci_set_drvdata(pdev, NULL);
+	iounmap(rll_info->mmio_base);
+	pci_release_regions(pdev);
+	kfree(rll_info);
+}
+
+static struct pci_driver radeonll_driver = {
+	.name		= "radeonll",
+	.id_table	= radeonll_pci_table,
+	.probe		= radeonll_pci_register,
+	.remove		= __devexit_p(radeonll_pci_unregister),
+#ifdef CONFIG_PM
+	.suspend       	= radeonll_pci_suspend,
+	.resume		= radeonll_pci_resume,
+#endif /* CONFIG_PM */
+};
+ 
+static int __init radeonll_init (void)
+{
+	radeon_bus_type.name = "radeon";
+	vll_bus_driver_register(&radeon_bus_type);
+	return pci_register_driver (&radeonll_driver);
+}
+
+
+static void __exit radeonll_exit (void)
+{
+	vll_bus_driver_unregister(&radeon_bus_type);
+	pci_unregister_driver (&radeonll_driver);
+}
+
+module_init(radeonll_init);
+module_exit(radeonll_exit);
diff --git a/drivers/video/vga_lowlevel.c b/drivers/video/vga_lowlevel.c
new file mode 100644
index 0000000..1486a27
--- /dev/null
+++ b/drivers/video/vga_lowlevel.c
@@ -0,0 +1,202 @@
+/*
+ * @file video_ll.c 
+ *
+ * @remark Copyright 2005 Dave Airlie
+ * @remark Read the COPYING file.
+ * 
+ * @author Dave Airlie <airlied@linux.ie>
+ */
+#include <linux/device.h>
+#include <linux/vga_lowlevel.h>
+
+/**
+ * match the device to a driver on the bus 
+ */
+int vga_bus_match(struct device *dev, struct device_driver *drv)
+{
+	const struct vll_dev *vdev = to_vll_dev(dev);
+
+	printk("%s called\n", __FUNCTION__);
+	return 1;
+}
+EXPORT_SYMBOL(vga_bus_match);
+
+/**
+ * hotplug method for video lowlevel bus
+ */
+int vga_bus_hotplug(struct device *dev, char **envp, int num_envp,
+		      char *buffer, int buffer_size)
+{
+	printk("%s called\n", __FUNCTION__);
+	return -ENODEV;
+}
+EXPORT_SYMBOL(vga_bus_hotplug);
+
+/**
+ * bus suspend function
+ */
+int vga_bus_device_suspend(struct device *dev, u32 state)
+{
+	return 0;
+}
+EXPORT_SYMBOL(vga_bus_device_suspend);
+
+/**
+ * bus resume function
+ */
+int vga_bus_device_resume(struct device *dev)
+{
+	return 0;
+}
+EXPORT_SYMBOL(vga_bus_device_resume);
+		     
+
+#define kobj_to_vga_driver(obj) container_of(obj, struct device_driver, kobj)
+#define attr_to_driver_attribute(obj) container_of(obj, struct driver_attribute, attr)
+
+static ssize_t
+vga_driver_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
+{
+	struct device_driver *driver = kobj_to_vga_driver(kobj);
+	struct driver_attribute *dattr = attr_to_driver_attribute(attr);
+	ssize_t ret;
+
+	if (!get_driver(driver))
+		return -ENODEV;
+
+	ret = dattr->show ? dattr->show(driver, buf) : -EIO;
+	
+	put_driver(driver);
+	return ret;
+}
+
+static ssize_t 
+vga_driver_attr_store(struct kobject *kobj, struct attribute *attr, 
+			const char *buf, size_t count)
+{
+	struct device_driver *driver = kobj_to_vga_driver(kobj);
+	struct driver_attribute *dattr = attr_to_driver_attribute(attr);
+	ssize_t ret;
+
+	if (!get_driver(driver))
+		return -ENODEV;
+	
+	ret = dattr->store ? dattr->store(driver, buf, count) : -EIO;
+
+	put_driver(driver);
+	return ret;
+}
+
+static struct sysfs_ops vga_driver_sysfs_ops = {
+	.show = vga_driver_attr_show,
+	.store = vga_driver_attr_store,
+};
+
+static struct kobj_type vga_driver_kobj_type = {
+	.sysfs_ops = &vga_driver_sysfs_ops,
+};
+
+static int 
+__vga_device_probe(struct vll_driver *drv, struct vll_dev *vll_dev)
+{
+	int error = 0;
+	
+	if (drv->probe) {
+		error = drv->probe(drv, vll_dev);
+	}
+
+	if (error>=0) {
+		vll_dev->driver = drv;
+		error = 0;
+	}
+
+	return error;
+}
+
+static int vga_device_probe(struct device *dev)
+{
+	int error = 0;
+	struct vll_driver *drv;
+	struct vll_dev *vll_dev;
+
+	drv = to_vll_driver(dev->driver);
+	vll_dev = to_vll_dev(dev);
+//	vll_dev_get(vll_dev);
+	error = __vga_device_probe(drv, vll_dev);
+//	if (error)
+		//vll_dev_put(vll_dev);
+	printk("%s called\n", __FUNCTION__);
+	
+	return error;
+}
+
+static int vga_driver_remove(struct device *dev)
+{
+	printk("%s called\n", __FUNCTION__);
+	return 0;
+}
+/*
+  register a video lowlevel driver.
+*/
+int vll_register_driver(struct bus_type *bus_type, struct vll_driver *vdrv)
+{
+	vdrv->driver.name = vdrv->name;
+	vdrv->driver.bus = bus_type;
+	vdrv->driver.probe = vga_device_probe;
+	vdrv->driver.remove = vga_driver_remove;
+	vdrv->driver.kobj.ktype = &vga_driver_kobj_type;
+	return driver_register(&vdrv->driver);
+}
+EXPORT_SYMBOL(vll_register_driver);
+
+/*
+  unregister a video lowlevel driver
+*/
+void vll_unregister_driver(struct vll_driver *vdrv)
+{
+	return driver_unregister(&vdrv->driver);
+}
+EXPORT_SYMBOL(vll_unregister_driver);
+
+/*
+  register a video lowlevel bus
+*/
+int vll_bus_driver_register(struct bus_type *bus_type)
+{
+	bus_type->match = vga_bus_match;
+	bus_type->hotplug = vga_bus_hotplug;
+	bus_type->suspend = vga_bus_device_suspend;
+	bus_type->resume = vga_bus_device_resume;
+	
+	if (bus_register(bus_type) < 0)
+		printk(KERN_ERR "Unable to register %s bus type.\n", bus_type->name);
+	return 0;
+}
+EXPORT_SYMBOL(vll_bus_driver_register);
+
+/*
+  unregister a video lowlevel bus
+*/
+void vll_bus_driver_unregister(struct bus_type *bus_type)
+{
+	bus_unregister(bus_type);
+}
+EXPORT_SYMBOL(vll_bus_driver_unregister);
+
+/*
+  register a video lowlevel device
+*/
+int vll_device_register(struct vll_dev *vll)
+{
+	return device_register(&vll->dev);
+}
+EXPORT_SYMBOL(vll_device_register);
+
+/*
+  unregister a video lowlevel device
+*/
+void vll_device_unregister(struct vll_dev *vll)
+{
+	device_unregister(&vll->dev);
+}
+EXPORT_SYMBOL(vll_device_unregister);
diff --git a/include/linux/vga_lowlevel.h b/include/linux/vga_lowlevel.h
new file mode 100644
index 0000000..106881e
--- /dev/null
+++ b/include/linux/vga_lowlevel.h
@@ -0,0 +1,74 @@
+/*
+ *      vga_lowlevel.h
+ *
+ * Author : Dave Airlie <airlied@linux.ie>
+ * Copyright 2005 David Airlie
+ */
+   
+#ifndef _VGA_LOWLEVEL_H_
+#define _VGA_LOWLEVEL_H_
+
+#include <linux/interrupt.h>
+#define VGA_COMMON 1 // common should always be loaded otherwise this layer won't exist
+#define VGA_FB 2
+#define VGA_DRM 3
+#define VGA_LAST VGA_DRM
+
+struct vll_dev;
+
+/* video lowlevel driver structure */
+struct vll_driver {
+	char *name; /* name of driver */
+	int type; /* type of driver to register */
+	irqreturn_t (*irq_handler)(int irq, void *arg, struct pt_regs *regs);
+	int (*probe)(struct vll_driver *vdrv, struct vll_dev *vdev);
+	void (*remove)(struct vll_dev *vdev);
+	int (*suspend)(struct vll_dev *vdev, pm_message_t state);
+	int (*resume)(struct vll_dev *vdev);
+	void *(*get_entrypoints)(void);
+	struct device_driver driver;
+};
+#define to_vll_driver(n) container_of(n, struct vll_driver, driver)
+
+/* this is the vll device */
+struct vll_dev {
+	struct device *devices[VGA_DRM];
+  //	struct device dev;
+	struct vll_driver *driver;
+};
+#define to_vll_dev(n) container_of(n, struct vll_dev, dev)
+
+extern int vll_register_driver(struct bus_type *bus_type, struct vll_driver *vdrv);
+extern void vll_unregister_driver(struct vll_driver *driver);
+extern int vll_bus_driver_register(struct bus_type *bus_type);
+extern void vll_bus_driver_unregister(struct bus_type *bus_type);
+extern int vll_device_register(struct vll_dev *vll);
+extern void vll_device_unregister(struct vll_dev *vll);
+
+extern int vga_bus_device_resume(struct device *dev);
+extern int vga_bus_device_suspend(struct device *dev, u32 state);
+extern int vga_bus_hotplug(struct device *dev, char **envp, int num_envp,
+			     char *buffer, int buffer_size);
+extern int vga_bus_match(struct device *dev, struct device_driver *drv);
+
+static __inline__ int vll_is_driver_loaded(struct vll_dev *vga_ll, int drv_type)
+{
+	return 0;
+}
+
+static __inline__ void *vll_get_entrypoints(struct vll_dev *vga_ll, int drv_type)
+{
+	return NULL;
+}
+
+static __inline__ void vll_set_drvdata(struct vll_dev *vdev, void *data)
+{
+	dev_set_drvdata(&vdev->dev, data);
+}
+
+static __inline__ void *vll_get_drvdata(struct vll_dev *vdev)
+{
+	return dev_get_drvdata(&vdev->dev);
+}
+
+#endif
