--- linuxppc_2_4_devel/drivers/video/S3triofb.c	Mon Nov 26 17:09:51 2001
+++ linuxppc_2_4_devel-140/drivers/video/S3triofb.c	Tue Dec  4 22:25:53 2001
@@ -38,7 +38,7 @@
 #include <linux/init.h>
 #include <linux/selection.h>
 #include <asm/io.h>
-#include <asm/prom.h>
+/* #include <asm/prom.h> */
 #include <asm/pci-bridge.h>
 #include <linux/pci.h>
 #ifdef CONFIG_FB_COMPAT_XPMAC
@@ -61,6 +61,7 @@
 #define IO_OUT16VAL(v, r)       (((v) << 8) | (r))
 
 static int currcon = 0;
+static int disabled;
 static struct display disp;
 static struct fb_info fb_info;
 static struct { u_char red, green, blue, pad; } palette[256];
@@ -68,14 +69,20 @@
 static char *s3trio_base;
 
 static struct fb_fix_screeninfo fb_fix;
-static struct fb_var_screeninfo fb_var = { 0, };
-
+static struct fb_var_screeninfo S3triofb_default_var = {
+	640, 480, 640, 480, 0, 0, 8, 0,
+	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	0, 0, -1, FB_ACCELF_TEXT, 39722, 40, 24, 32, 11, 96, 2,
+	FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
+	FB_VMODE_NONINTERLACED
+};
+static struct fb_var_screeninfo fb_var = { 0,};
 
     /*
      *  Interface used by the world
      */
 
-static void __init s3triofb_of_init(struct device_node *dp);
+static void __init s3triofb_pci_init(struct pci_dev *dp);
 static int s3trio_get_fix(struct fb_fix_screeninfo *fix, int con,
 			  struct fb_info *info);
 static int s3trio_get_var(struct fb_var_screeninfo *var, int con,
@@ -260,16 +267,43 @@
 }
 
 
+#ifndef MODULE
+
+int __init s3triofb_setup(char *options) {
+	char *this_opt;
+
+	if (!options || !*options)
+		return 0;
+
+	while ((this_opt = strsep(&options, ",")) != NULL) {
+		if (!*this_opt)
+			continue;
+
+		if (!strcmp(this_opt, "disabled"))
+			disabled = 1;
+	}
+	return 0;
+}
+
+
+
 int __init s3triofb_init(void)
 {
-	struct device_node *dp;
+	struct pci_dev *dp = NULL;
 
-	dp = find_devices("S3Trio");
-	if (dp != 0)
-	    s3triofb_of_init(dp);
-	return 0;
+	if (disabled)
+		return -ENXIO;
+
+	dp = pci_find_device(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_TRIO, dp);
+	if ((dp != 0) && ((dp->class >> 16) == PCI_BASE_CLASS_DISPLAY)) {
+		s3triofb_pci_init(dp);
+		return 0;
+	} else
+		return -ENODEV;
 }
 
+#endif
+
 void __init s3trio_resetaccel(void){
 
 
@@ -313,57 +347,48 @@
 	outw( MF_PIX_CONTROL | MFA_SRC_FOREGR_MIX,  0xbee8);
 }
 
-int __init s3trio_init(struct device_node *dp){
+int __init s3trio_init(struct pci_dev *dp){
 
-    u_char bus, dev;
     unsigned int t32;
     unsigned short cmd;
 
-	pci_device_loc(dp,&bus,&dev);
-                pcibios_read_config_dword(bus, dev, PCI_VENDOR_ID, &t32);
-                if(t32 == (PCI_DEVICE_ID_S3_TRIO << 16) + PCI_VENDOR_ID_S3) {
-                        pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_0, &t32);
-                        pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_1, &t32);
-			pcibios_read_config_word(bus, dev, PCI_COMMAND,&cmd);
-
-			pcibios_write_config_word(bus, dev, PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
-
-			pcibios_write_config_dword(bus, dev, PCI_BASE_ADDRESS_0,0xffffffff);
-                        pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_0, &t32);
+	pci_read_config_dword(dp, PCI_VENDOR_ID, &t32);
+	if(t32 == (PCI_DEVICE_ID_S3_TRIO << 16) + PCI_VENDOR_ID_S3) {
+		pci_read_config_dword(dp, PCI_BASE_ADDRESS_0, &t32);
+		pci_read_config_dword(dp, PCI_BASE_ADDRESS_1, &t32);
+		pci_read_config_word(dp, PCI_COMMAND,&cmd);
 
-/* This is a gross hack as OF only maps enough memory for the framebuffer and
-   we want to use MMIO too. We should find out which chunk of address space
-   we can use here */
-			pcibios_write_config_dword(bus,dev,PCI_BASE_ADDRESS_0,0xc6000000);
+		pci_write_config_word(dp, PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
 
-			/* unlock s3 */
-
-			outb(0x01, 0x3C3);
-
-			outb(inb(0x03CC) | 1, 0x3c2);
-
-			outw(IO_OUT16VAL(0x48, 0x38),0x03D4);
-			outw(IO_OUT16VAL(0xA0, 0x39),0x03D4);
-			outb(0x33,0x3d4);
-			outw(IO_OUT16VAL((inb(0x3d5) & ~(0x2 | 0x10 |  0x40)) |
-					  0x20, 0x33), 0x3d4);
-
-			outw(IO_OUT16VAL(0x6, 0x8), 0x3c4);
-
-			/* switch to MMIO only mode */
-
-			outb(0x58, 0x3d4);
-			outw(IO_OUT16VAL(inb(0x3d5) | 3 | 0x10, 0x58), 0x3d4);
-			outw(IO_OUT16VAL(8, 0x53), 0x3d4);
+		/* LBB: not sure what this is for, disable it for now */
+#if 0
+		pci_write_config_dword(dp, PCI_BASE_ADDRESS_0,0xffffffff); 
+		pci_read_config_dword(dp, PCI_BASE_ADDRESS_0, &t32);
+#endif
 
-			/* switch off I/O accesses */
+		/* unlock s3 */
+		outb(0x01, 0x3C3);
+		outb(inb(0x03CC) | 1, 0x3c2);
+		outw(IO_OUT16VAL(0x48, 0x38),0x03D4);
+		outw(IO_OUT16VAL(0xA0, 0x39),0x03D4);
+		outb(0x33,0x3d4);
+		outw(IO_OUT16VAL((inb(0x3d5) & ~(0x2 | 0x10 |  0x40)) |
+				  0x20, 0x33), 0x3d4);
+
+		outw(IO_OUT16VAL(0x6, 0x8), 0x3c4);
+
+		/* switch to MMIO only mode */
+		outb(0x58, 0x3d4);
+		outw(IO_OUT16VAL(inb(0x3d5) | 3 | 0x10, 0x58), 0x3d4);
+		outw(IO_OUT16VAL(8, 0x53), 0x3d4);
 
+		/* switch off I/O accesses */
 #if 0
 			pcibios_write_config_word(bus, dev, PCI_COMMAND,
 				        PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
 #endif
-			return 1;
-                }
+		return 1;
+	}
 
 	return 0;
 }
@@ -371,51 +396,23 @@
 
     /*
      *  Initialisation
-     *  We heavily rely on OF for the moment. This needs fixing.
      */
 
-static void __init s3triofb_of_init(struct device_node *dp)
+static void __init s3triofb_pci_init(struct pci_dev *dp)
 {
-    int i, *pp, len;
+    int i;
     unsigned long address, size;
     u_long *CursorBase;
 
-    strncat(s3trio_name, dp->name, sizeof(s3trio_name));
-    s3trio_name[sizeof(s3trio_name)-1] = '\0';
     strcpy(fb_fix.id, s3trio_name);
 
-    if((pp = (int *)get_property(dp, "vendor-id", &len)) != NULL
-	&& *pp!=PCI_VENDOR_ID_S3) {
-	printk("%s: can't find S3 Trio board\n", dp->full_name);
-	return;
-    }
-
-    if((pp = (int *)get_property(dp, "device-id", &len)) != NULL
-	&& *pp!=PCI_DEVICE_ID_S3_TRIO) {
-	printk("%s: can't find S3 Trio board\n", dp->full_name);
-	return;
-    }
-
-    if ((pp = (int *)get_property(dp, "depth", &len)) != NULL
-	&& len == sizeof(int) && *pp != 8) {
-	printk("%s: can't use depth = %d\n", dp->full_name, *pp);
-	return;
-    }
-    if ((pp = (int *)get_property(dp, "width", &len)) != NULL
-	&& len == sizeof(int))
-	fb_var.xres = fb_var.xres_virtual = *pp;
-    if ((pp = (int *)get_property(dp, "height", &len)) != NULL
-	&& len == sizeof(int))
-	fb_var.yres = fb_var.yres_virtual = *pp;
-    if ((pp = (int *)get_property(dp, "linebytes", &len)) != NULL
-	&& len == sizeof(int))
-	fb_fix.line_length = *pp;
-    else
-	fb_fix.line_length = fb_var.xres_virtual;
+    fb_var = S3triofb_default_var;
+    fb_fix.line_length = fb_var.xres_virtual;
     fb_fix.smem_len = fb_fix.line_length*fb_var.yres;
 
-    address = 0xc6000000;
-    size = 64*1024*1024;
+    /* There is only one memory region and it covers the mmio and fb areas */
+    address = pci_resource_start(dp, 0);
+    size    = pci_resource_len(dp, 0); /* size = 64*1024*1024; */
     if (!request_mem_region(address, size, "S3triofb"))
 	return;
 
@@ -553,7 +550,7 @@
     disp.scrollmode = fb_var.accel_flags & FB_ACCELF_TEXT ? 0 : SCROLL_YREDRAW;
 
     strcpy(fb_info.modename, "Trio64 ");
-    strncat(fb_info.modename, dp->full_name, sizeof(fb_info.modename));
+/*    strncat(fb_info.modename, dp->full_name, sizeof(fb_info.modename)); */
     fb_info.node = -1;
     fb_info.fbops = &s3trio_ops;
 #if 0
@@ -591,7 +588,7 @@
 	return;
 
     printk("fb%d: S3 Trio frame buffer device on %s\n",
-	   GET_FB_IDX(fb_info.node), dp->full_name);
+	   GET_FB_IDX(fb_info.node), fb_info.modename);
 }
 
 
--- linuxppc_2_4_devel/drivers/video/fbmem.c	Mon Nov 26 17:11:03 2001
+++ linuxppc_2_4_devel-140/drivers/video/fbmem.c	Fri Nov 30 15:35:05 2001
@@ -83,6 +83,7 @@
 extern int virgefb_setup(char*);
 extern int resolver_video_setup(char*);
 extern int s3triofb_init(void);
+extern int s3triofb_setup(char*);
 extern int vesafb_init(void);
 extern int vesafb_setup(char*);
 extern int vga16fb_init(void);
@@ -197,7 +198,7 @@
 	{ "imsttfb", imsttfb_init, imsttfb_setup },
 #endif
 #ifdef CONFIG_FB_S3TRIO
-	{ "s3trio", s3triofb_init, NULL },
+	{ "s3trio", s3triofb_init, s3triofb_setup },
 #endif 
 #ifdef CONFIG_FB_FM2
 	{ "fm2fb", fm2fb_init, fm2fb_setup },
