I have tested it on a powerbook 3400, which has a C&T 65550 video chip
with 1MB of VRAM, and it seems to work just fine, at least in 8 bit
mode.  I guess I still need to add the pseudo_palette stuff for 16 bit
mode.  Unfortunately I can't test it under X at the moment because the
X server I have installed on the 3400 is Xpmac, which doesn't work any
more because the VC_GETMODE etc. ioctls have been removed.  The 3400
is an old and slow machine with a small hard disk and an old Linux/PPC
installation on it, and I don't really want to compile up XFree86 on
it.
Paul.
--- linux-2.5/drivers/video/chipsfb.c	2002-12-10 15:20:32.000000000 +1100
+++ pmac-2.5/drivers/video/chipsfb.c	2002-12-18 22:05:59.000000000 +1100
@@ -2,7 +2,7 @@
  *  drivers/video/chipsfb.c -- frame buffer device for
  *  Chips & Technologies 65550 chip.
  *
- *  Copyright (C) 1998 Paul Mackerras
+ *  Copyright (C) 1998-2002 Paul Mackerras
  *
  *  This file is derived from the Powermac "chips" driver:
  *  Copyright (C) 1997 Fabio Riccardi.
@@ -39,34 +39,11 @@
 #include <linux/pmu.h>
 #endif
 
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/macmodes.h>
-
-struct fb_info_chips {
-	struct fb_info info;
-	struct fb_fix_screeninfo fix;
-	struct fb_var_screeninfo var;
-	struct display disp;
-	struct {
-		__u8 red, green, blue;
-	} palette[256];
-	struct pci_dev *pdev;
-	unsigned long frame_buffer_phys;
-	__u8 *frame_buffer;
-	unsigned long blitter_regs_phys;
-	__u32 *blitter_regs;
-	unsigned long blitter_data_phys;
-	__u8 *blitter_data;
-	struct fb_info_chips *next;
-#ifdef CONFIG_PMAC_PBOOK
-	unsigned char *save_framebuffer;
-#endif
-#ifdef FBCON_HAS_CFB16
-	u16 fbcon_cfb16_cmap[16];
-#endif
-};
+/*
+ * Since we access the display with inb/outb to fixed port numbers,
+ * we can only handle one 6555x chip.  -- paulus
+ */
+static struct fb_info chipsfb_info;
 
 #define write_ind(num, val, ap, dp)	do { \
 	outb((num), (ap)); outb((val), (dp)); \
@@ -98,9 +75,8 @@
 	inb(0x3da); read_ind(num, var, 0x3c0, 0x3c1); \
 } while (0)
 
-static struct fb_info_chips *all_chips;
-
 #ifdef CONFIG_PMAC_PBOOK
+static unsigned char *save_framebuffer;
 int chips_sleep_notify(struct pmu_sleep_notifier *self, int when);
 static struct pmu_sleep_notifier chips_sleep_notifier = {
 	chips_sleep_notify, SLEEP_LEVEL_VIDEO,
@@ -112,58 +88,29 @@
  */
 int chips_init(void);
 
-static void chips_pci_init(struct pci_dev *dp);
-static int chips_get_fix(struct fb_fix_screeninfo *fix, int con,
-			 struct fb_info *info);
-static int chips_get_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info);
-static int chips_set_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info);
-static int chips_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			  struct fb_info *info);
+static int chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *);
+static int chipsfb_check_var(struct fb_var_screeninfo *var,
+			     struct fb_info *info);
+static int chipsfb_set_par(struct fb_info *info);
 static int chipsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 			     u_int transp, struct fb_info *info);
 static int chipsfb_blank(int blank, struct fb_info *info);
 
 static struct fb_ops chipsfb_ops = {
-	.owner =	THIS_MODULE,
-	.fb_get_fix =	chips_get_fix,
-	.fb_get_var =	chips_get_var,
-	.fb_set_var =	chips_set_var,
-	.fb_get_cmap =	chips_get_cmap,
-	.fb_set_cmap =	gen_set_cmap,
-	.fb_setcolreg =	chipsfb_setcolreg,
-	.fb_blank =	chipsfb_blank,
-};
-
-static int chipsfb_getcolreg(u_int regno, u_int *red, u_int *green,
-			     u_int *blue, u_int *transp, struct fb_info *info);
-static void chips_set_bitdepth(struct fb_info_chips *p, struct display* disp, int con, int bpp);
-
-static int chips_get_fix(struct fb_fix_screeninfo *fix, int con,
-			 struct fb_info *info)
-{
-	struct fb_info_chips *cp = (struct fb_info_chips *) info;
-
-	*fix = cp->fix;
-	return 0;
-}
-
-static int chips_get_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info)
-{
-	struct fb_info_chips *cp = (struct fb_info_chips *) info;
-
-	*var = cp->var;
-	return 0;
-}
+	.owner		= THIS_MODULE,
+	.fb_check_var	= chipsfb_check_var,
+	.fb_set_par	= chipsfb_set_par,
+	.fb_setcolreg	= chipsfb_setcolreg,
+	.fb_blank	= chipsfb_blank,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
+};
 
-static int chips_set_var(struct fb_var_screeninfo *var, int con,
-			 struct fb_info *info)
+static int chipsfb_check_var(struct fb_var_screeninfo *var,
+			     struct fb_info *info)
 {
-	struct fb_info_chips *cp = (struct fb_info_chips *) info;
-	struct display *disp = (con >= 0)? &fb_display[con]: &cp->disp;
-
 	if (var->xres > 800 || var->yres > 600
 	    || var->xres_virtual > 800 || var->yres_virtual > 600
 	    || (var->bits_per_pixel != 8 && var->bits_per_pixel != 16)
@@ -171,198 +118,76 @@
 	    || (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
 		return -EINVAL;
 
-	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW &&
-		var->bits_per_pixel != disp->var.bits_per_pixel) {
-		chips_set_bitdepth(cp, disp, con, var->bits_per_pixel);
-	}
+	var->xres = var->xres_virtual = 800;
+	var->yres = var->yres_virtual = 600;
 
 	return 0;
 }
 
-static int chips_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			  struct fb_info *info)
+static int chipsfb_set_par(struct fb_info *info)
 {
-	if (con == info->currcon)		/* current console? */
-		return fb_get_cmap(cmap, kspc, chipsfb_getcolreg, info);
-	if (fb_display[con].cmap.len)	/* non default colormap? */
-		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
-	else {
-		int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
-		fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
+	if (info->var.bits_per_pixel == 16) {
+		write_cr(0x13, 200);		// Set line length (doublewords)
+		write_xr(0x81, 0x14);		// 15 bit (555) color mode
+		write_xr(0x82, 0x00);		// Disable palettes
+		write_xr(0x20, 0x10);		// 16 bit blitter mode
+
+		info->fix.line_length = 800*2;
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
+
+		info->var.red.offset = 10;
+		info->var.green.offset = 5;
+		info->var.blue.offset = 0;
+		info->var.red.length = info->var.green.length =
+			info->var.blue.length = 5;
+		
+	} else {
+		/* p->var.bits_per_pixel == 8 */
+		write_cr(0x13, 100);		// Set line length (doublewords)
+		write_xr(0x81, 0x12);		// 8 bit color mode
+		write_xr(0x82, 0x08);		// Graphics gamma enable
+		write_xr(0x20, 0x00);		// 8 bit blitter mode
+
+		info->fix.line_length = 800;
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;		
+
+ 		info->var.red.offset = info->var.green.offset =
+			info->var.blue.offset = 0;
+		info->var.red.length = info->var.green.length =
+			info->var.blue.length = 8;
+		
 	}
 	return 0;
 }
 
-static int chipsfbcon_switch(int con, struct fb_info *info)
-{
-	struct fb_info_chips *p = (struct fb_info_chips *) info;
-	int new_bpp, old_bpp;
-
-	/* Do we have to save the colormap? */
-	if (fb_display[info->currcon].cmap.len)
-		fb_get_cmap(&fb_display[info->currcon].cmap, 1, chipsfb_getcolreg, info);
-
-	new_bpp = fb_display[con].var.bits_per_pixel;
-	old_bpp = fb_display[info->currcon].var.bits_per_pixel;
-	info->currcon = con;
-
-	if (new_bpp != old_bpp)
-		chips_set_bitdepth(p, &fb_display[con], con, new_bpp);
-	
-	do_install_cmap(con, info);
-	return 0;
-}
-
-static int chipsfb_updatevar(int con, struct fb_info *info)
-{
-	return 0;
-}
-
 static int chipsfb_blank(int blank, struct fb_info *info)
 {
-	struct fb_info_chips *p = (struct fb_info_chips *) info;
-	int i;
-
+#ifdef CONFIG_PMAC_BACKLIGHT
 	// used to disable backlight only for blank > 1, but it seems
 	// useful at blank = 1 too (saves battery, extends backlight life)
-	if (blank) {
-#ifdef CONFIG_PMAC_BACKLIGHT
-		set_backlight_enable(0);
-#endif /* CONFIG_PMAC_BACKLIGHT */
-		/* get the palette from the chip */
-		for (i = 0; i < 256; ++i) {
-			outb(i, 0x3c7);
-			udelay(1);
-			p->palette[i].red = inb(0x3c9);
-			p->palette[i].green = inb(0x3c9);
-			p->palette[i].blue = inb(0x3c9);
-		}
-		for (i = 0; i < 256; ++i) {
-			outb(i, 0x3c8);
-			udelay(1);
-			outb(0, 0x3c9);
-			outb(0, 0x3c9);
-			outb(0, 0x3c9);
-		}
-	} else {
-#ifdef CONFIG_PMAC_BACKLIGHT
-		set_backlight_enable(1);
+	set_backlight_enable(!blank);
 #endif /* CONFIG_PMAC_BACKLIGHT */
-		for (i = 0; i < 256; ++i) {
-			outb(i, 0x3c8);
-			udelay(1);
-			outb(p->palette[i].red, 0x3c9);
-			outb(p->palette[i].green, 0x3c9);
-			outb(p->palette[i].blue, 0x3c9);
-		}
-	}
-	return 0;
-}
-
-static int chipsfb_getcolreg(u_int regno, u_int *red, u_int *green,
-			     u_int *blue, u_int *transp, struct fb_info *info)
-{
-	struct fb_info_chips *p = (struct fb_info_chips *) info;
 
-	if (regno > 255)
-		return 1;
-	*red = (p->palette[regno].red<<8) | p->palette[regno].red;
-	*green = (p->palette[regno].green<<8) | p->palette[regno].green;
-	*blue = (p->palette[regno].blue<<8) | p->palette[regno].blue;
-	*transp = 0;
-	return 0;
+	return 1;	/* get fb_blank to set the colormap to all black */
 }
 
 static int chipsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 			     u_int transp, struct fb_info *info)
 {
-	struct fb_info_chips *p = (struct fb_info_chips *) info;
-
 	if (regno > 255)
 		return 1;
 	red >>= 8;
 	green >>= 8;
 	blue >>= 8;
-	p->palette[regno].red = red;
-	p->palette[regno].green = green;
-	p->palette[regno].blue = blue;
 	outb(regno, 0x3c8);
 	udelay(1);
 	outb(red, 0x3c9);
 	outb(green, 0x3c9);
 	outb(blue, 0x3c9);
 
-#ifdef FBCON_HAS_CFB16
-	if (regno < 16)
-		p->fbcon_cfb16_cmap[regno] = ((red & 0xf8) << 7)
-			| ((green & 0xf8) << 2) | ((blue & 0xf8) >> 3);
-#endif
-
 	return 0;
 }
 
-static void chips_set_bitdepth(struct fb_info_chips *p, struct display* disp, int con, int bpp)
-{
-	int err;
-	struct fb_fix_screeninfo* fix = &p->fix;
-	struct fb_var_screeninfo* var = &p->var;
-	
-	if (bpp == 16) {
-		if (con == p->info.currcon) {
-			write_cr(0x13, 200);		// Set line length (doublewords)
-			write_xr(0x81, 0x14);		// 15 bit (555) color mode
-			write_xr(0x82, 0x00);		// Disable palettes
-			write_xr(0x20, 0x10);		// 16 bit blitter mode
-		}
-
-		fix->line_length = 800*2;
-		fix->visual = FB_VISUAL_TRUECOLOR;
-
-		var->red.offset = 10;
-		var->green.offset = 5;
-		var->blue.offset = 0;
-		var->red.length = var->green.length = var->blue.length = 5;
-		
-#ifdef FBCON_HAS_CFB16
-		disp->dispsw = &fbcon_cfb16;
-		disp->dispsw_data = p->fbcon_cfb16_cmap;
-#else
-		disp->dispsw = &fbcon_dummy;
-#endif
-	} else if (bpp == 8) {
-		if (con == p->info.currcon) {
-			write_cr(0x13, 100);		// Set line length (doublewords)
-			write_xr(0x81, 0x12);		// 8 bit color mode
-			write_xr(0x82, 0x08);		// Graphics gamma enable
-			write_xr(0x20, 0x00);		// 8 bit blitter mode
-		}
-
-		fix->line_length = 800;
-		fix->visual = FB_VISUAL_PSEUDOCOLOR;		
-
- 		var->red.offset = var->green.offset = var->blue.offset = 0;
-		var->red.length = var->green.length = var->blue.length = 8;
-		
-#ifdef FBCON_HAS_CFB8
-		disp->dispsw = &fbcon_cfb8;
-#else
-		disp->dispsw = &fbcon_dummy;
-#endif
-	}
-
-	var->bits_per_pixel = bpp;
-	disp->line_length = p->fix.line_length;
-	disp->visual = fix->visual;
-	disp->var = *var;
-
-	if (p->info.changevar)
-		(*p->info.changevar)(con);
-
-	if ((err = fb_alloc_cmap(&disp->cmap, 0, 0)))
-		return;
-	do_install_cmap(con, (struct fb_info *)p);
-}
-
 struct chips_init_reg {
 	unsigned char addr;
 	unsigned char data;
@@ -473,7 +298,7 @@
 	{ 0xa8, 0x00 }
 };
 
-static void __init chips_hw_init(struct fb_info_chips *p)
+static void __init chips_hw_init(void)
 {
 	int i;
 
@@ -492,12 +317,12 @@
 		write_fr(chips_init_fr[i].addr, chips_init_fr[i].data);
 }
 
-static void __init init_chips(struct fb_info_chips *p)
-{
-	int i;
-
-	strcpy(p->fix.id, "C&T 65550");
-	p->fix.smem_start = p->frame_buffer_phys;
+static struct fb_fix_screeninfo chipsfb_fix __initdata = {
+	.id =		"C&T 65550",
+	.type =		FB_TYPE_PACKED_PIXELS,
+	.visual =	FB_VISUAL_PSEUDOCOLOR,
+	.accel =	FB_ACCEL_NONE,
+	.line_length =	800,
 
 // FIXME: Assumes 1MB frame buffer, but 65550 supports 1MB or 2MB.
 // * "3500" PowerBook G3 (the original PB G3) has 2MB.
@@ -506,115 +331,75 @@
 //   for a second pair of DRAMs.  (Thanks, Apple!)
 // * 3400 has 1MB (I think).  Don't know if it's expandable.
 // -- Tim Seufert
-	p->fix.smem_len = 0x100000;	// 1MB
-	p->fix.type = FB_TYPE_PACKED_PIXELS;
-	p->fix.visual = FB_VISUAL_PSEUDOCOLOR;
-	p->fix.line_length = 800;
-
-	p->var.xres = 800;
-	p->var.yres = 600;
-	p->var.xres_virtual = 800;
-	p->var.yres_virtual = 600;
-	p->var.bits_per_pixel = 8;
-	p->var.red.length = p->var.green.length = p->var.blue.length = 8;
-	p->var.height = p->var.width = -1;
-	p->var.vmode = FB_VMODE_NONINTERLACED;
-	p->var.pixclock = 10000;
-	p->var.left_margin = p->var.right_margin = 16;
-	p->var.upper_margin = p->var.lower_margin = 16;
-	p->var.hsync_len = p->var.vsync_len = 8;
-
-	p->disp.var = p->var;
-	p->disp.cmap.red = NULL;
-	p->disp.cmap.green = NULL;
-	p->disp.cmap.blue = NULL;
-	p->disp.cmap.transp = NULL;
-	p->disp.visual = p->fix.visual;
-	p->disp.type = p->fix.type;
-	p->disp.type_aux = p->fix.type_aux;
-	p->disp.line_length = p->fix.line_length;
-	p->disp.can_soft_blank = 1;
-	p->disp.dispsw = &fbcon_cfb8;
-	p->disp.scrollmode = SCROLL_YREDRAW;
-
-	strcpy(p->info.modename, p->fix.id);
-	p->info.node = NODEV;
-	p->info.fbops = &chipsfb_ops;
-	p->info.screen_base = p->frame_buffer;
-	p->info.disp = &p->disp;
-	p->info.currcon = -1;
-	p->info.fontname[0] = 0;
-	p->info.changevar = NULL;
-	p->info.switch_con = &chipsfbcon_switch;
-	p->info.updatevar = &chipsfb_updatevar;
-	p->info.flags = FBINFO_FLAG_DEFAULT;
-
-	for (i = 0; i < 16; ++i) {
-		int j = color_table[i];
-		p->palette[i].red = default_red[j];
-		p->palette[i].green = default_grn[j];
-		p->palette[i].blue = default_blu[j];
-	}
+	.smem_len =	0x100000,	/* 1MB */
+};
 
-	if (register_framebuffer(&p->info) < 0) {
-		kfree(p);
-		return;
-	}
+static struct fb_var_screeninfo chipsfb_var __initdata = {
+	.xres = 800,
+	.yres = 600,
+	.xres_virtual = 800,
+	.yres_virtual = 600,
+	.bits_per_pixel = 8,
+	.red = { .length = 8 },
+	.green = { .length = 8 },
+	.blue = { .length = 8 },
+	.height = -1,
+	.width = -1,
+	.vmode = FB_VMODE_NONINTERLACED,
+	.pixclock = 10000,
+	.left_margin = 16,
+	.right_margin = 16,
+	.upper_margin = 16,
+	.lower_margin = 16,
+	.hsync_len = 8,
+	.vsync_len = 8,
+};
+
+static void __init init_chips(struct fb_info *p, unsigned long addr)
+{
+	p->fix = chipsfb_fix;
+	p->fix.smem_start = addr;
 
-	printk("fb%d: Chips 65550 frame buffer (%dK RAM detected)\n",
-		minor(p->info.node), p->fix.smem_len / 1024);
+	p->var = chipsfb_var;
 
-	chips_hw_init(p);
+	p->node = NODEV;
+	p->fbops = &chipsfb_ops;
+	p->flags = FBINFO_FLAG_DEFAULT;
 
-#ifdef CONFIG_PMAC_PBOOK
-	if (all_chips == NULL)
-		pmu_register_sleep_notifier(&chips_sleep_notifier);
-#endif /* CONFIG_PMAC_PBOOK */
-	p->next = all_chips;
-	all_chips = p;
-}
+	fb_alloc_cmap(&p->cmap, 256, 0);
 
-int __init chips_init(void)
-{
-	struct pci_dev *dp = NULL;
+	if (register_framebuffer(p) < 0) {
+		printk(KERN_ERR "C&T 65550 framebuffer failed to register\n");
+		return;
+	}
 
-	while ((dp = pci_find_device(PCI_VENDOR_ID_CT,
-				     PCI_DEVICE_ID_CT_65550, dp)) != NULL)
-		if ((dp->class >> 16) == PCI_BASE_CLASS_DISPLAY)
-			chips_pci_init(dp);
-	return all_chips? 0: -ENODEV;
+	printk(KERN_INFO "fb%d: Chips 65550 frame buffer (%dK RAM detected)\n",
+		minor(p->node), p->fix.smem_len / 1024);
+
+	chips_hw_init();
 }
 
-static void __init chips_pci_init(struct pci_dev *dp)
+static int __devinit
+chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
 {
-	struct fb_info_chips *p;
+	struct fb_info *p = &chipsfb_info;
 	unsigned long addr, size;
 	unsigned short cmd;
 
 	if ((dp->resource[0].flags & IORESOURCE_MEM) == 0)
-		return;
-	addr = dp->resource[0].start;
-	size = dp->resource[0].end + 1 - addr;
+		return -ENODEV;
+	addr = pci_resource_start(dp, 0);
+	size = pci_resource_len(dp, 0);
 	if (addr == 0)
-		return;
-	p = kmalloc(sizeof(*p), GFP_ATOMIC);
-	if (p == 0)
-		return;
-	memset(p, 0, sizeof(*p));
-	if (!request_mem_region(addr, size, "chipsfb")) {
-		kfree(p);
-		return;
-	}
+		return -ENODEV;
+	if (p->screen_base != 0)
+		return -EBUSY;
+	if (!request_mem_region(addr, size, "chipsfb"))
+		return -EBUSY;
+
 #ifdef __BIG_ENDIAN
 	addr += 0x800000;	// Use big-endian aperture
 #endif
-	p->pdev = dp;
-	p->frame_buffer_phys = addr;
-	p->frame_buffer = __ioremap(addr, 0x200000, _PAGE_NO_CACHE);
-	p->blitter_regs_phys = addr + 0x400000;
-	p->blitter_regs = ioremap(addr + 0x400000, 0x1000);
-	p->blitter_data_phys = addr + 0x410000;
-	p->blitter_data = ioremap(addr + 0x410000, 0x10000);
 
 	/* we should use pci_enable_device here, but,
 	   the device doesn't declare its I/O ports in its BARs
@@ -623,15 +408,68 @@
 	cmd |= 3;	/* enable memory and IO space */
 	pci_write_config_word(dp, PCI_COMMAND, cmd);
 
-	/* Clear the entire framebuffer */
-	memset(p->frame_buffer, 0, 0x100000);
-
 #ifdef CONFIG_PMAC_BACKLIGHT
 	/* turn on the backlight */
 	set_backlight_enable(1);
 #endif /* CONFIG_PMAC_BACKLIGHT */
 
-	init_chips(p);
+	p->screen_base = __ioremap(addr, 0x200000, _PAGE_NO_CACHE);
+	if (p->screen_base == NULL) {
+		release_mem_region(addr, size);
+		return -ENOMEM;
+	}
+
+	init_chips(p, addr);
+
+#ifdef CONFIG_PMAC_PBOOK
+	pmu_register_sleep_notifier(&chips_sleep_notifier);
+#endif /* CONFIG_PMAC_PBOOK */
+
+	/* Clear the entire framebuffer */
+	memset(p->screen_base, 0, 0x100000);
+
+	pci_set_drvdata(dp, p);
+	return 0;
+}
+
+static void __devexit chipsfb_remove(struct pci_dev *dp)
+{
+	struct fb_info *p = pci_get_drvdata(dp);
+
+	if (p != &chipsfb_info || p->screen_base == NULL)
+		return;
+	unregister_framebuffer(p);
+	iounmap(p->screen_base);
+	p->screen_base = NULL;
+	release_mem_region(pci_resource_start(dp, 0), pci_resource_len(dp, 0));
+
+#ifdef CONFIG_PMAC_PBOOK
+	pmu_unregister_sleep_notifier(&chips_sleep_notifier);
+#endif /* CONFIG_PMAC_PBOOK */
+}
+
+static struct pci_device_id chipsfb_pci_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_65550, PCI_ANY_ID, PCI_ANY_ID },
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, chipsfb_pci_tbl);
+
+static struct pci_driver chipsfb_driver = {
+	.name =		"chipsfb",
+	.id_table =	chipsfb_pci_tbl,
+	.probe =	chipsfb_pci_init,
+	.remove =	__devexit_p(chipsfb_remove),
+};
+
+int __init chips_init(void)
+{
+	return pci_module_init(&chipsfb_driver);
+}
+
+static void __exit chipsfb_exit(void)
+{
+	pci_unregister_driver(&chipsfb_driver);
 }
 
 #ifdef CONFIG_PMAC_PBOOK
@@ -642,40 +480,37 @@
 int
 chips_sleep_notify(struct pmu_sleep_notifier *self, int when)
 {
-	struct fb_info_chips *p;
+	struct fb_info *p = &chipsfb_info;
+	int nb = p->var.yres * p->fix.line_length;
 
-	for (p = all_chips; p != NULL; p = p->next) {
-		int nb = p->var.yres * p->fix.line_length;
+	if (p->screen_base == NULL)
+		return PBOOK_SLEEP_OK;
 
-		switch (when) {
-		case PBOOK_SLEEP_REQUEST:
-			p->save_framebuffer = vmalloc(nb);
-			if (p->save_framebuffer == NULL)
-				return PBOOK_SLEEP_REFUSE;
-			break;
-		case PBOOK_SLEEP_REJECT:
-			if (p->save_framebuffer) {
-				vfree(p->save_framebuffer);
-				p->save_framebuffer = 0;
-			}
-			break;
-
-		case PBOOK_SLEEP_NOW:
-			chipsfb_blank(1, (struct fb_info *)p);
-			if (p->save_framebuffer)
-				memcpy(p->save_framebuffer,
-				       p->frame_buffer, nb);
-			break;
-		case PBOOK_WAKE:
-			if (p->save_framebuffer) {
-				memcpy(p->frame_buffer,
-				       p->save_framebuffer, nb);
-				vfree(p->save_framebuffer);
-				p->save_framebuffer = 0;
-			}
-			chipsfb_blank(0, (struct fb_info *)p);
-			break;
+	switch (when) {
+	case PBOOK_SLEEP_REQUEST:
+		save_framebuffer = vmalloc(nb);
+		if (save_framebuffer == NULL)
+			return PBOOK_SLEEP_REFUSE;
+		break;
+	case PBOOK_SLEEP_REJECT:
+		if (save_framebuffer) {
+			vfree(save_framebuffer);
+			save_framebuffer = 0;
+		}
+		break;
+	case PBOOK_SLEEP_NOW:
+		chipsfb_blank(1, p);
+		if (save_framebuffer)
+			memcpy(save_framebuffer, p->screen_base, nb);
+		break;
+	case PBOOK_WAKE:
+		if (save_framebuffer) {
+			memcpy(p->screen_base, save_framebuffer, nb);
+			vfree(save_framebuffer);
+			save_framebuffer = 0;
 		}
+		chipsfb_blank(0, p);
+		break;
 	}
 	return PBOOK_SLEEP_OK;
 }
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/