Commit sysfs and drm PCI changes for 2.6 kernel
authorDave Airlie <airlied@linux.ie>
Sun, 9 May 2004 06:45:17 +0000 (06:45 +0000)
committerDave Airlie <airlied@linux.ie>
Sun, 9 May 2004 06:45:17 +0000 (06:45 +0000)
13 files changed:
bsd-core/drm_drv.c
bsd/drm_drv.h
linux-core/drmP.h
linux-core/drm_drv.c
linux/drmP.h
linux/drm_drv.h
linux/gamma.h
linux/i810.h
linux/i830.h
shared/mach64.h
shared/mga.h
shared/r128.h
shared/radeon.h

index 1b5d170..02e3436 100644 (file)
 #endif
 
 #ifndef DRIVER_PREINIT
-#define DRIVER_PREINIT()
+#define DRIVER_PREINIT(dev) 0
 #endif
 #ifndef DRIVER_POSTINIT
-#define DRIVER_POSTINIT()
+#define DRIVER_POSTINIT(dev) 0
 #endif
 #ifndef DRIVER_PRERELEASE
 #define DRIVER_PRERELEASE()
 #endif
 #ifndef DRIVER_PRETAKEDOWN
-#define DRIVER_PRETAKEDOWN()
+#define DRIVER_PRETAKEDOWN(dev)
 #endif
 #ifndef DRIVER_POSTCLEANUP
 #define DRIVER_POSTCLEANUP()
@@ -512,7 +512,7 @@ static int DRM(takedown)( drm_device_t *dev )
 
        DRM_DEBUG( "\n" );
 
-       DRIVER_PRETAKEDOWN();
+       DRIVER_PRETAKEDOWN(dev);
 #if __HAVE_IRQ
        if (dev->irq_enabled)
                DRM(irq_uninstall)( dev );
@@ -627,7 +627,7 @@ static int DRM(init)( device_t nbdev )
        int retcode;
 #endif
        DRM_DEBUG( "\n" );
-       DRIVER_PREINIT();
+       DRIVER_PREINIT(dev);
 
 #ifdef __FreeBSD__
        unit = device_get_unit(nbdev);
@@ -705,7 +705,7 @@ static int DRM(init)( device_t nbdev )
                DRIVER_DATE,
                unit );
 
-       DRIVER_POSTINIT();
+       DRIVER_POSTINIT(dev);
 
        return 0;
 
index 1b5d170..02e3436 100644 (file)
 #endif
 
 #ifndef DRIVER_PREINIT
-#define DRIVER_PREINIT()
+#define DRIVER_PREINIT(dev) 0
 #endif
 #ifndef DRIVER_POSTINIT
-#define DRIVER_POSTINIT()
+#define DRIVER_POSTINIT(dev) 0
 #endif
 #ifndef DRIVER_PRERELEASE
 #define DRIVER_PRERELEASE()
 #endif
 #ifndef DRIVER_PRETAKEDOWN
-#define DRIVER_PRETAKEDOWN()
+#define DRIVER_PRETAKEDOWN(dev)
 #endif
 #ifndef DRIVER_POSTCLEANUP
 #define DRIVER_POSTCLEANUP()
@@ -512,7 +512,7 @@ static int DRM(takedown)( drm_device_t *dev )
 
        DRM_DEBUG( "\n" );
 
-       DRIVER_PRETAKEDOWN();
+       DRIVER_PRETAKEDOWN(dev);
 #if __HAVE_IRQ
        if (dev->irq_enabled)
                DRM(irq_uninstall)( dev );
@@ -627,7 +627,7 @@ static int DRM(init)( device_t nbdev )
        int retcode;
 #endif
        DRM_DEBUG( "\n" );
-       DRIVER_PREINIT();
+       DRIVER_PREINIT(dev);
 
 #ifdef __FreeBSD__
        unit = device_get_unit(nbdev);
@@ -705,7 +705,7 @@ static int DRM(init)( device_t nbdev )
                DRIVER_DATE,
                unit );
 
-       DRIVER_POSTINIT();
+       DRIVER_POSTINIT(dev);
 
        return 0;
 
index 2800246..ade3e38 100644 (file)
@@ -831,6 +831,7 @@ extern int           DRM(lock)(struct inode *inode, struct file *filp,
                               unsigned int cmd, unsigned long arg);
 extern int           DRM(unlock)(struct inode *inode, struct file *filp,
                                 unsigned int cmd, unsigned long arg);
+extern int           DRM(fb_loaded);
 
                                /* Device support (drm_fops.h) */
 extern int          DRM(open_helper)(struct inode *inode, struct file *filp,
index feeaf4d..67f2eac 100644 (file)
 #endif
 
 #ifndef DRIVER_PREINIT
-#define DRIVER_PREINIT()
+#define DRIVER_PREINIT(dev) 0
 #endif
 #ifndef DRIVER_POSTINIT
-#define DRIVER_POSTINIT()
+#define DRIVER_POSTINIT(dev) 0
 #endif
 #ifndef DRIVER_PRERELEASE
 #define DRIVER_PRERELEASE()
 #endif
 #ifndef DRIVER_PRETAKEDOWN
-#define DRIVER_PRETAKEDOWN()
+#define DRIVER_PRETAKEDOWN(dev)
 #endif
 #ifndef DRIVER_POSTCLEANUP
 #define DRIVER_POSTCLEANUP()
@@ -144,6 +144,8 @@ static struct file_operations       DRM(fops) = {   \
 }
 #endif
 
+static void __exit drm_cleanup( drm_device_t *dev );
+
 /** Stub information */
 struct drm_stub_info {
        int (*info_register)(const char *name, struct file_operations *fops,
@@ -172,8 +174,9 @@ __setup( DRIVER_NAME "=", DRM_OPTIONS_FUNC );
 #endif
 
 #define MAX_DEVICES 4
-static drm_device_t    DRM(device)[MAX_DEVICES];
-static int             DRM(numdevs) = 0;
+drm_device_t            DRM(device)[MAX_DEVICES];
+int DRM(numdevs) = 0;
+int DRM(fb_loaded) = 0;
 
 DRIVER_FOPS;
 
@@ -405,7 +408,7 @@ static int DRM(takedown)( drm_device_t *dev )
 
        DRM_DEBUG( "\n" );
 
-       DRIVER_PRETAKEDOWN();
+       DRIVER_PRETAKEDOWN(dev);
 #if __HAVE_IRQ
        if ( dev->irq_enabled ) DRM(irq_uninstall)( dev );
 #endif
@@ -544,6 +547,9 @@ static int DRM(takedown)( drm_device_t *dev )
                dev->lock.filp = 0;
                wake_up_interruptible( &dev->lock.lock_queue );
        }
+       
+       if (DRM(fb_loaded)==0)
+               pci_disable_device(dev->pdev);
        up( &dev->struct_sem );
 
        return 0;
@@ -555,30 +561,19 @@ static struct pci_device_id DRM(pciidlist)[] = {
        DRM(PCI_IDS)
 };
 
-static int DRM(probe)(struct pci_dev *pdev)
+static int drm_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        drm_device_t *dev;
-#if __HAVE_CTX_BITMAP
        int retcode;
-#endif
-       int i;
-       int is_compat = 0;
 
        DRM_DEBUG( "\n" );
 
-       for (i = 0; DRM(pciidlist)[i].vendor != 0; i++) {
-               if ((DRM(pciidlist)[i].vendor == pdev->vendor) &&
-                   (DRM(pciidlist)[i].device == pdev->device)) {
-                       is_compat = 1;
-               }
-       }
-       if (is_compat == 0)
-               return -ENODEV;
-
        if (DRM(numdevs) >= MAX_DEVICES)
                return -ENODEV;
 
        dev = &(DRM(device)[DRM(numdevs)]);
+       if (DRM(fb_loaded)==0)
+               pci_set_drvdata(pdev, dev);
 
        memset( (void *)dev, 0, sizeof(*dev) );
        dev->count_lock = SPIN_LOCK_UNLOCKED;
@@ -587,11 +582,16 @@ static int DRM(probe)(struct pci_dev *pdev)
        sema_init( &dev->ctxlist_sem, 1 );
 
        if ((dev->minor = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)
-               return -EPERM;
+       {
+               retcode = -EPERM;
+               goto error_out;
+       }
+                       
        dev->device = MKDEV(DRM_MAJOR, dev->minor );
        dev->name   = DRIVER_NAME;
 
        dev->pdev   = pdev;
+       pci_enable_device(pdev);
 #ifdef __alpha__
        dev->hose   = pdev->sysdata;
        dev->pci_domain = dev->hose->bus->number;
@@ -603,16 +603,16 @@ static int DRM(probe)(struct pci_dev *pdev)
        dev->pci_func = PCI_FUNC(pdev->devfn);
        dev->irq = pdev->irq;
 
-       DRIVER_PREINIT();
+       if ((retcode = DRIVER_PREINIT(dev)))
+         goto error_out_unreg;
 
 #if __REALLY_HAVE_AGP
        dev->agp = DRM(agp_init)();
 #if __MUST_HAVE_AGP
        if ( dev->agp == NULL ) {
                DRM_ERROR( "Cannot initialize the agpgart module.\n" );
-               DRM(stub_unregister)(dev->minor);
-               DRM(takedown)( dev );
-               return -EINVAL;
+               retcode = -EINVAL;
+               goto error_out_unreg;
        }
 #endif
 #if __REALLY_HAVE_MTRR
@@ -628,9 +628,7 @@ static int DRM(probe)(struct pci_dev *pdev)
        retcode = DRM(ctxbitmap_init)( dev );
        if( retcode ) {
                DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );
-               DRM(stub_unregister)(dev->minor);
-               DRM(takedown)( dev );
-               return retcode;
+               goto error_out_unreg;
        }
 #endif
        DRM(numdevs)++; /* no errors, mark it reserved */
@@ -645,16 +643,37 @@ static int DRM(probe)(struct pci_dev *pdev)
                pci_pretty_name(pdev)
                );
 
-       DRIVER_POSTINIT();
+       if ((retcode = DRIVER_POSTINIT(dev)))
+               goto error_out_unreg;
+
+
        /*
         * don't move this earlier, for upcoming hotplugging support
         */
        class_simple_device_add(DRM(stub_info).drm_class, 
                                        MKDEV(DRM_MAJOR, dev->minor), &pdev->dev, "card%d", dev->minor);
+       
+ error_out_unreg:
+       DRM(stub_unregister)(dev->minor);
+       DRM(takedown)(dev);
+ error_out:
+       return retcode;
+}
 
-       return 0;
+static void __exit drm_cleanup_pci(struct pci_dev *pdev)
+{
+       drm_device_t *dev = pci_get_drvdata(pdev);
+
+       pci_set_drvdata(pdev, NULL);
+       drm_cleanup(dev);
 }
 
+static struct pci_driver drm_driver = {
+       .name          = DRIVER_NAME,
+       .id_table      = DRM(pciidlist),
+       .probe         = drm_probe,
+       .remove        = __devexit_p(drm_cleanup_pci),
+};
 
 /**
  * Module initialization. Called via init_module at module load time, or via
@@ -672,7 +691,9 @@ static int DRM(probe)(struct pci_dev *pdev)
 static int __init drm_init( void )
 {
        struct pci_dev *pdev = NULL;
-
+       struct pci_driver *pdriver = NULL;
+       int i;
+       
        DRM_DEBUG( "\n" );
 
 #ifdef MODULE
@@ -680,10 +701,26 @@ static int __init drm_init( void )
 #endif
 
        DRM(mem_init)();
-
-       while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
-               DRM(probe)(pdev);
+       
+       for (i=0; DRM(pciidlist)[i].vendor != 0; i++) {
+               pdev = pci_get_subsys(DRM(pciidlist[i]).vendor, DRM(pciidlist[i]).device, DRM(pciidlist[i]).subvendor, DRM(pciidlist[i]).subdevice, NULL);
+               if (pdev)
+               {
+                       pdriver = pci_dev_driver(pdev);
+                       if (pdriver)
+                       {
+                               DRM(fb_loaded)=1;
+                               drm_probe(pdev, &DRM(pciidlist[i]));
+                       }
+                       else
+                               pci_dev_put(pdev);
+               }
        }
+       
+       if (DRM(fb_loaded)==0)
+               pci_register_driver(&drm_driver);
+       else
+               DRM_INFO("Used old pci detect: framebuffer loaded\n");
        return 0;
 }
 
@@ -694,54 +731,71 @@ static int __init drm_init( void )
  * 
  * \sa drm_init().
  */
-static void __exit drm_cleanup( void )
+static void __exit drm_cleanup( drm_device_t *dev )
 {
-       drm_device_t *dev;
-       int i;
-
        DRM_DEBUG( "\n" );
+       if (!dev) {
+               DRM_ERROR("cleanup called no dev\n");
+               return;
+       }
 
-       for (i = DRM(numdevs) - 1; i >= 0; i--) {
-               dev = &(DRM(device)[i]);
-               if ( DRM(stub_unregister)(dev->minor) ) {
-                       DRM_ERROR( "Cannot unload module\n" );
-               } else {
-                       DRM_DEBUG("minor %d unregistered\n", dev->minor);
-                       if (i == 0) {
-                               DRM_INFO( "Module unloaded\n" );
-                       }
-               }
+       DRM(takedown)(dev);
+
+       if ( DRM(stub_unregister)(dev->minor) ) {
+               DRM_ERROR( "Cannot unload module\n" );
+       } else {
+               DRM_DEBUG( "minor %d unregistered\n", dev->minor);
+       }
+       
 #if __HAVE_CTX_BITMAP
-               DRM(ctxbitmap_cleanup)( dev );
+       DRM(ctxbitmap_cleanup)( dev );
 #endif
 
 #if __REALLY_HAVE_AGP && __REALLY_HAVE_MTRR
-               if ( dev->agp && dev->agp->agp_mtrr >= 0) {
-                       int retval;
-                       retval = mtrr_del( dev->agp->agp_mtrr,
+       if ( dev->agp && dev->agp->agp_mtrr >= 0) {
+               int retval;
+               retval = mtrr_del( dev->agp->agp_mtrr,
                                   dev->agp->agp_info.aper_base,
                                   dev->agp->agp_info.aper_size*1024*1024 );
-                       DRM_DEBUG( "mtrr_del=%d\n", retval );
-               }
+               DRM_DEBUG( "mtrr_del=%d\n", retval );
+       }
 #endif
 
-               DRM(takedown)( dev );
 
 #if __REALLY_HAVE_AGP
-               if ( dev->agp ) {
-                       DRM(agp_uninit)();
-                       DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS );
-                       dev->agp = NULL;
-               }
-#endif
+       if ( dev->agp ) {
+               DRM(agp_uninit)();
+               DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS );
+               dev->agp = NULL;
        }
+#endif
+
        class_simple_device_remove(MKDEV(DRM_MAJOR, 0));
-       DRIVER_POSTCLEANUP();
-       DRM(numdevs) = 0;
 }
 
+static void __exit drm_exit (void)
+{
+       if (DRM(fb_loaded)==1)
+       {
+               int i;
+               drm_device_t *dev;
+
+               for (i = DRM(numdevs) - 1; i >= 0; i--) {
+                       dev = &(DRM(device)[i]);
+                       /* release the pci driver */
+                       if (dev->pdev)
+                               pci_dev_put(dev->pdev);
+                       drm_cleanup(dev);
+               }
+       }
+       else
+               pci_unregister_driver(&drm_driver);
+       DRM_INFO( "Module unloaded\n" );
+}
+
+       
 module_init( drm_init );
-module_exit( drm_cleanup );
+module_exit( drm_exit );
 
 
 /**
index 2800246..ade3e38 100644 (file)
@@ -831,6 +831,7 @@ extern int           DRM(lock)(struct inode *inode, struct file *filp,
                               unsigned int cmd, unsigned long arg);
 extern int           DRM(unlock)(struct inode *inode, struct file *filp,
                                 unsigned int cmd, unsigned long arg);
+extern int           DRM(fb_loaded);
 
                                /* Device support (drm_fops.h) */
 extern int          DRM(open_helper)(struct inode *inode, struct file *filp,
index feeaf4d..67f2eac 100644 (file)
 #endif
 
 #ifndef DRIVER_PREINIT
-#define DRIVER_PREINIT()
+#define DRIVER_PREINIT(dev) 0
 #endif
 #ifndef DRIVER_POSTINIT
-#define DRIVER_POSTINIT()
+#define DRIVER_POSTINIT(dev) 0
 #endif
 #ifndef DRIVER_PRERELEASE
 #define DRIVER_PRERELEASE()
 #endif
 #ifndef DRIVER_PRETAKEDOWN
-#define DRIVER_PRETAKEDOWN()
+#define DRIVER_PRETAKEDOWN(dev)
 #endif
 #ifndef DRIVER_POSTCLEANUP
 #define DRIVER_POSTCLEANUP()
@@ -144,6 +144,8 @@ static struct file_operations       DRM(fops) = {   \
 }
 #endif
 
+static void __exit drm_cleanup( drm_device_t *dev );
+
 /** Stub information */
 struct drm_stub_info {
        int (*info_register)(const char *name, struct file_operations *fops,
@@ -172,8 +174,9 @@ __setup( DRIVER_NAME "=", DRM_OPTIONS_FUNC );
 #endif
 
 #define MAX_DEVICES 4
-static drm_device_t    DRM(device)[MAX_DEVICES];
-static int             DRM(numdevs) = 0;
+drm_device_t            DRM(device)[MAX_DEVICES];
+int DRM(numdevs) = 0;
+int DRM(fb_loaded) = 0;
 
 DRIVER_FOPS;
 
@@ -405,7 +408,7 @@ static int DRM(takedown)( drm_device_t *dev )
 
        DRM_DEBUG( "\n" );
 
-       DRIVER_PRETAKEDOWN();
+       DRIVER_PRETAKEDOWN(dev);
 #if __HAVE_IRQ
        if ( dev->irq_enabled ) DRM(irq_uninstall)( dev );
 #endif
@@ -544,6 +547,9 @@ static int DRM(takedown)( drm_device_t *dev )
                dev->lock.filp = 0;
                wake_up_interruptible( &dev->lock.lock_queue );
        }
+       
+       if (DRM(fb_loaded)==0)
+               pci_disable_device(dev->pdev);
        up( &dev->struct_sem );
 
        return 0;
@@ -555,30 +561,19 @@ static struct pci_device_id DRM(pciidlist)[] = {
        DRM(PCI_IDS)
 };
 
-static int DRM(probe)(struct pci_dev *pdev)
+static int drm_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        drm_device_t *dev;
-#if __HAVE_CTX_BITMAP
        int retcode;
-#endif
-       int i;
-       int is_compat = 0;
 
        DRM_DEBUG( "\n" );
 
-       for (i = 0; DRM(pciidlist)[i].vendor != 0; i++) {
-               if ((DRM(pciidlist)[i].vendor == pdev->vendor) &&
-                   (DRM(pciidlist)[i].device == pdev->device)) {
-                       is_compat = 1;
-               }
-       }
-       if (is_compat == 0)
-               return -ENODEV;
-
        if (DRM(numdevs) >= MAX_DEVICES)
                return -ENODEV;
 
        dev = &(DRM(device)[DRM(numdevs)]);
+       if (DRM(fb_loaded)==0)
+               pci_set_drvdata(pdev, dev);
 
        memset( (void *)dev, 0, sizeof(*dev) );
        dev->count_lock = SPIN_LOCK_UNLOCKED;
@@ -587,11 +582,16 @@ static int DRM(probe)(struct pci_dev *pdev)
        sema_init( &dev->ctxlist_sem, 1 );
 
        if ((dev->minor = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)
-               return -EPERM;
+       {
+               retcode = -EPERM;
+               goto error_out;
+       }
+                       
        dev->device = MKDEV(DRM_MAJOR, dev->minor );
        dev->name   = DRIVER_NAME;
 
        dev->pdev   = pdev;
+       pci_enable_device(pdev);
 #ifdef __alpha__
        dev->hose   = pdev->sysdata;
        dev->pci_domain = dev->hose->bus->number;
@@ -603,16 +603,16 @@ static int DRM(probe)(struct pci_dev *pdev)
        dev->pci_func = PCI_FUNC(pdev->devfn);
        dev->irq = pdev->irq;
 
-       DRIVER_PREINIT();
+       if ((retcode = DRIVER_PREINIT(dev)))
+         goto error_out_unreg;
 
 #if __REALLY_HAVE_AGP
        dev->agp = DRM(agp_init)();
 #if __MUST_HAVE_AGP
        if ( dev->agp == NULL ) {
                DRM_ERROR( "Cannot initialize the agpgart module.\n" );
-               DRM(stub_unregister)(dev->minor);
-               DRM(takedown)( dev );
-               return -EINVAL;
+               retcode = -EINVAL;
+               goto error_out_unreg;
        }
 #endif
 #if __REALLY_HAVE_MTRR
@@ -628,9 +628,7 @@ static int DRM(probe)(struct pci_dev *pdev)
        retcode = DRM(ctxbitmap_init)( dev );
        if( retcode ) {
                DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );
-               DRM(stub_unregister)(dev->minor);
-               DRM(takedown)( dev );
-               return retcode;
+               goto error_out_unreg;
        }
 #endif
        DRM(numdevs)++; /* no errors, mark it reserved */
@@ -645,16 +643,37 @@ static int DRM(probe)(struct pci_dev *pdev)
                pci_pretty_name(pdev)
                );
 
-       DRIVER_POSTINIT();
+       if ((retcode = DRIVER_POSTINIT(dev)))
+               goto error_out_unreg;
+
+
        /*
         * don't move this earlier, for upcoming hotplugging support
         */
        class_simple_device_add(DRM(stub_info).drm_class, 
                                        MKDEV(DRM_MAJOR, dev->minor), &pdev->dev, "card%d", dev->minor);
+       
+ error_out_unreg:
+       DRM(stub_unregister)(dev->minor);
+       DRM(takedown)(dev);
+ error_out:
+       return retcode;
+}
 
-       return 0;
+static void __exit drm_cleanup_pci(struct pci_dev *pdev)
+{
+       drm_device_t *dev = pci_get_drvdata(pdev);
+
+       pci_set_drvdata(pdev, NULL);
+       drm_cleanup(dev);
 }
 
+static struct pci_driver drm_driver = {
+       .name          = DRIVER_NAME,
+       .id_table      = DRM(pciidlist),
+       .probe         = drm_probe,
+       .remove        = __devexit_p(drm_cleanup_pci),
+};
 
 /**
  * Module initialization. Called via init_module at module load time, or via
@@ -672,7 +691,9 @@ static int DRM(probe)(struct pci_dev *pdev)
 static int __init drm_init( void )
 {
        struct pci_dev *pdev = NULL;
-
+       struct pci_driver *pdriver = NULL;
+       int i;
+       
        DRM_DEBUG( "\n" );
 
 #ifdef MODULE
@@ -680,10 +701,26 @@ static int __init drm_init( void )
 #endif
 
        DRM(mem_init)();
-
-       while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
-               DRM(probe)(pdev);
+       
+       for (i=0; DRM(pciidlist)[i].vendor != 0; i++) {
+               pdev = pci_get_subsys(DRM(pciidlist[i]).vendor, DRM(pciidlist[i]).device, DRM(pciidlist[i]).subvendor, DRM(pciidlist[i]).subdevice, NULL);
+               if (pdev)
+               {
+                       pdriver = pci_dev_driver(pdev);
+                       if (pdriver)
+                       {
+                               DRM(fb_loaded)=1;
+                               drm_probe(pdev, &DRM(pciidlist[i]));
+                       }
+                       else
+                               pci_dev_put(pdev);
+               }
        }
+       
+       if (DRM(fb_loaded)==0)
+               pci_register_driver(&drm_driver);
+       else
+               DRM_INFO("Used old pci detect: framebuffer loaded\n");
        return 0;
 }
 
@@ -694,54 +731,71 @@ static int __init drm_init( void )
  * 
  * \sa drm_init().
  */
-static void __exit drm_cleanup( void )
+static void __exit drm_cleanup( drm_device_t *dev )
 {
-       drm_device_t *dev;
-       int i;
-
        DRM_DEBUG( "\n" );
+       if (!dev) {
+               DRM_ERROR("cleanup called no dev\n");
+               return;
+       }
 
-       for (i = DRM(numdevs) - 1; i >= 0; i--) {
-               dev = &(DRM(device)[i]);
-               if ( DRM(stub_unregister)(dev->minor) ) {
-                       DRM_ERROR( "Cannot unload module\n" );
-               } else {
-                       DRM_DEBUG("minor %d unregistered\n", dev->minor);
-                       if (i == 0) {
-                               DRM_INFO( "Module unloaded\n" );
-                       }
-               }
+       DRM(takedown)(dev);
+
+       if ( DRM(stub_unregister)(dev->minor) ) {
+               DRM_ERROR( "Cannot unload module\n" );
+       } else {
+               DRM_DEBUG( "minor %d unregistered\n", dev->minor);
+       }
+       
 #if __HAVE_CTX_BITMAP
-               DRM(ctxbitmap_cleanup)( dev );
+       DRM(ctxbitmap_cleanup)( dev );
 #endif
 
 #if __REALLY_HAVE_AGP && __REALLY_HAVE_MTRR
-               if ( dev->agp && dev->agp->agp_mtrr >= 0) {
-                       int retval;
-                       retval = mtrr_del( dev->agp->agp_mtrr,
+       if ( dev->agp && dev->agp->agp_mtrr >= 0) {
+               int retval;
+               retval = mtrr_del( dev->agp->agp_mtrr,
                                   dev->agp->agp_info.aper_base,
                                   dev->agp->agp_info.aper_size*1024*1024 );
-                       DRM_DEBUG( "mtrr_del=%d\n", retval );
-               }
+               DRM_DEBUG( "mtrr_del=%d\n", retval );
+       }
 #endif
 
-               DRM(takedown)( dev );
 
 #if __REALLY_HAVE_AGP
-               if ( dev->agp ) {
-                       DRM(agp_uninit)();
-                       DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS );
-                       dev->agp = NULL;
-               }
-#endif
+       if ( dev->agp ) {
+               DRM(agp_uninit)();
+               DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS );
+               dev->agp = NULL;
        }
+#endif
+
        class_simple_device_remove(MKDEV(DRM_MAJOR, 0));
-       DRIVER_POSTCLEANUP();
-       DRM(numdevs) = 0;
 }
 
+static void __exit drm_exit (void)
+{
+       if (DRM(fb_loaded)==1)
+       {
+               int i;
+               drm_device_t *dev;
+
+               for (i = DRM(numdevs) - 1; i >= 0; i--) {
+                       dev = &(DRM(device)[i]);
+                       /* release the pci driver */
+                       if (dev->pdev)
+                               pci_dev_put(dev->pdev);
+                       drm_cleanup(dev);
+               }
+       }
+       else
+               pci_unregister_driver(&drm_driver);
+       DRM_INFO( "Module unloaded\n" );
+}
+
+       
 module_init( drm_init );
-module_exit( drm_cleanup );
+module_exit( drm_exit );
 
 
 /**
index dcd6490..899d411 100644 (file)
@@ -65,7 +65,7 @@
 
 /* Driver customization:
  */
-#define DRIVER_PRETAKEDOWN() do {                                      \
+#define DRIVER_PRETAKEDOWN( dev ) do {                                 \
        gamma_do_cleanup_dma( dev );                                    \
 } while (0)
 
index aee2eff..847a540 100644 (file)
@@ -91,7 +91,7 @@
        i810_reclaim_buffers( filp );                                   \
 } while (0)
 
-#define DRIVER_PRETAKEDOWN() do {                                      \
+#define DRIVER_PRETAKEDOWN( dev ) do {                                 \
        i810_dma_cleanup( dev );                                        \
 } while (0)
 
index 48d9cdd..56f7a11 100644 (file)
@@ -90,7 +90,7 @@
        i830_reclaim_buffers( filp );                                   \
 } while (0)
 
-#define DRIVER_PRETAKEDOWN() do {                                      \
+#define DRIVER_PRETAKEDOWN( dev ) do {                                 \
        i830_dma_cleanup( dev );                                        \
 } while (0)
 
index f8be393..2fde446 100644 (file)
@@ -73,7 +73,7 @@
 
 /* Driver customization:
  */
-#define DRIVER_PRETAKEDOWN() do {                                      \
+#define DRIVER_PRETAKEDOWN(dev) do {                                   \
        mach64_do_cleanup_dma( dev );                                   \
 } while (0)
 
index 702857a..6ee3952 100644 (file)
@@ -71,7 +71,7 @@
 
 /* Driver customization:
  */
-#define DRIVER_PRETAKEDOWN() do {                                      \
+#define DRIVER_PRETAKEDOWN( dev ) do {                                 \
        mga_do_cleanup_dma( dev );                                      \
 } while (0)
 
index 9dfe189..de64773 100644 (file)
@@ -90,7 +90,7 @@
        }                                                               \
 } while (0)
 
-#define DRIVER_PRETAKEDOWN() do {                                      \
+#define DRIVER_PRETAKEDOWN(dev) do {                                   \
        r128_do_cleanup_cce( dev );                                     \
 } while (0)
 
index 77e36ef..4219384 100644 (file)
@@ -146,7 +146,7 @@ do {                                                                        \
 /* When the last client dies, shut down the CP and free dev->dev_priv.
  */
 /* #define __HAVE_RELEASE 1 */
-#define DRIVER_PRETAKEDOWN()                   \
+#define DRIVER_PRETAKEDOWN( dev )              \
 do {                                           \
     radeon_do_release( dev );                  \
 } while (0)