diff options
Diffstat (limited to 'linux')
-rw-r--r-- | linux/drmP.h | 1 | ||||
-rw-r--r-- | linux/drm_drv.h | 182 | ||||
-rw-r--r-- | linux/gamma.h | 2 | ||||
-rw-r--r-- | linux/i810.h | 2 | ||||
-rw-r--r-- | linux/i830.h | 2 |
5 files changed, 122 insertions, 67 deletions
diff --git a/linux/drmP.h b/linux/drmP.h index 2800246d..ade3e38d 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -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, diff --git a/linux/drm_drv.h b/linux/drm_drv.h index feeaf4d1..67f2eac0 100644 --- a/linux/drm_drv.h +++ b/linux/drm_drv.h @@ -103,16 +103,16 @@ #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 ); /** diff --git a/linux/gamma.h b/linux/gamma.h index dcd64904..899d4113 100644 --- a/linux/gamma.h +++ b/linux/gamma.h @@ -65,7 +65,7 @@ /* Driver customization: */ -#define DRIVER_PRETAKEDOWN() do { \ +#define DRIVER_PRETAKEDOWN( dev ) do { \ gamma_do_cleanup_dma( dev ); \ } while (0) diff --git a/linux/i810.h b/linux/i810.h index aee2efff..847a540c 100644 --- a/linux/i810.h +++ b/linux/i810.h @@ -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) diff --git a/linux/i830.h b/linux/i830.h index 48d9cdd0..56f7a116 100644 --- a/linux/i830.h +++ b/linux/i830.h @@ -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) |