Merge branch 'master' into vblank-rework, fixup remaining drivers
authorJesse Barnes <jesse.barnes@intel.com>
Tue, 30 Oct 2007 19:52:46 +0000 (12:52 -0700)
committerJesse Barnes <jesse.barnes@intel.com>
Tue, 30 Oct 2007 19:52:46 +0000 (12:52 -0700)
Conflicts:

linux-core/drmP.h
linux-core/drm_drv.c
linux-core/drm_irq.c
shared-core/i915_drv.h
shared-core/i915_irq.c
shared-core/mga_drv.h
shared-core/mga_irq.c
shared-core/radeon_drv.h
shared-core/radeon_irq.c

Merge in the latest master bits and update the remaining drivers (except
mach64 which math_b is working on).  Also remove the 9xx hack from the i915
driver; it seems to be correct.

20 files changed:
1  2 
linux-core/drmP.h
linux-core/drm_drv.c
linux-core/drm_irq.c
linux-core/i915_drv.c
linux-core/mga_drv.c
linux-core/r128_drv.c
shared-core/drm.h
shared-core/i915_drv.h
shared-core/i915_irq.c
shared-core/mga_drv.h
shared-core/mga_irq.c
shared-core/nouveau_drv.h
shared-core/nouveau_irq.c
shared-core/r128_drv.h
shared-core/r128_irq.c
shared-core/radeon_drv.h
shared-core/radeon_irq.c
shared-core/via_drv.c
shared-core/via_drv.h
shared-core/via_irq.c

@@@ -687,16 -658,17 +698,17 @@@ struct drm_driver 
  /* these have to be filled in */
         irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
        void (*irq_preinstall) (struct drm_device * dev);
 -      void (*irq_postinstall) (struct drm_device * dev);
 +      int (*irq_postinstall) (struct drm_device * dev);
        void (*irq_uninstall) (struct drm_device * dev);
-       void (*reclaim_buffers) (struct drm_device *dev, struct file * filp);
+       void (*reclaim_buffers) (struct drm_device *dev,
+                                struct drm_file *file_priv);
        void (*reclaim_buffers_locked) (struct drm_device *dev,
-                                       struct file * filp);
+                                       struct drm_file *file_priv);
        void (*reclaim_buffers_idlelocked) (struct drm_device *dev,
-                                       struct file * filp);
-       unsigned long (*get_map_ofs) (drm_map_t * map);
+                                           struct drm_file *file_priv);
+       unsigned long (*get_map_ofs) (struct drm_map * map);
        unsigned long (*get_reg_ofs) (struct drm_device * dev);
-       void (*set_version) (struct drm_device * dev, drm_set_version_t * sv);
+       void (*set_version) (struct drm_device * dev, struct drm_set_version * sv);
  
        struct drm_fence_driver *fence_driver;
        struct drm_bo_driver *bo_driver;
@@@ -854,10 -821,9 +867,10 @@@ struct drm_device 
  #ifdef __alpha__
        struct pci_controller *hose;
  #endif
-       drm_sg_mem_t *sg;               /**< Scatter gather memory */
 +      int num_crtcs;                  /**< Number of CRTCs on this device */
+       struct drm_sg_mem *sg;          /**< Scatter gather memory */
        void *dev_private;              /**< device private data */
-       drm_sigdata_t sigdata;          /**< For block_all_signals */
+       struct drm_sigdata sigdata;             /**< For block_all_signals */
        sigset_t sigmask;
  
        struct drm_driver *driver;
@@@ -1072,94 -1040,90 +1087,98 @@@ extern void drm_idlelock_release(struc
   * DMA quiscent + idle. DMA quiescent usually requires the hardware lock.
   */
  
- extern int drm_i_have_hw_lock(struct file *filp);
extern int drm_kernel_take_hw_lock(struct file *filp);
+ extern int drm_i_have_hw_lock(struct drm_device *dev,
                            struct drm_file *file_priv);
  
                                /* Buffer management support (drm_bufs.h) */
- extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request);
- extern int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request);
- extern int drm_addbufs_fb (drm_device_t * dev, drm_buf_desc_t * request);
- extern int drm_addmap(drm_device_t * dev, unsigned int offset,
-                     unsigned int size, drm_map_type_t type,
-                     drm_map_flags_t flags, drm_local_map_t ** map_ptr);
- extern int drm_addmap_ioctl(struct inode *inode, struct file *filp,
-                           unsigned int cmd, unsigned long arg);
- extern int drm_rmmap(drm_device_t *dev, drm_local_map_t *map);
- extern int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map);
- extern int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
-                          unsigned int cmd, unsigned long arg);
- extern int drm_addbufs(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
- extern int drm_infobufs(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
- extern int drm_markbufs(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
- extern int drm_freebufs(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
- extern int drm_mapbufs(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
+ extern int drm_addbufs_agp(struct drm_device *dev, struct drm_buf_desc * request);
+ extern int drm_addbufs_pci(struct drm_device *dev, struct drm_buf_desc * request);
+ extern int drm_addbufs_fb (struct drm_device *dev, struct drm_buf_desc * request);
+ extern int drm_addmap(struct drm_device *dev, unsigned int offset,
+                     unsigned int size, enum drm_map_type type,
+                     enum drm_map_flags flags, drm_local_map_t ** map_ptr);
+ extern int drm_addmap_ioctl(struct drm_device *dev, void *data,
+                           struct drm_file *file_priv);
+ extern int drm_rmmap(struct drm_device *dev, drm_local_map_t *map);
+ extern int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map);
+ extern int drm_rmmap_ioctl(struct drm_device *dev, void *data,
+                          struct drm_file *file_priv);
+ extern int drm_addbufs(struct drm_device *dev, void *data,
+                      struct drm_file *file_priv);
+ extern int drm_infobufs(struct drm_device *dev, void *data,
+                       struct drm_file *file_priv);
+ extern int drm_markbufs(struct drm_device *dev, void *data,
+                       struct drm_file *file_priv);
+ extern int drm_freebufs(struct drm_device *dev, void *data,
+                       struct drm_file *file_priv);
+ extern int drm_mapbufs(struct drm_device *dev, void *data,
+                      struct drm_file *file_priv);
  extern int drm_order(unsigned long size);
- extern unsigned long drm_get_resource_start(drm_device_t *dev,
+ extern unsigned long drm_get_resource_start(struct drm_device *dev,
                                            unsigned int resource);
- extern unsigned long drm_get_resource_len(drm_device_t *dev,
+ extern unsigned long drm_get_resource_len(struct drm_device *dev,
                                          unsigned int resource);
+ extern struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
+                                                 drm_local_map_t *map);
  
                                /* DMA support (drm_dma.h) */
- extern int drm_dma_setup(drm_device_t * dev);
- extern void drm_dma_takedown(drm_device_t * dev);
- extern void drm_free_buffer(drm_device_t * dev, drm_buf_t * buf);
- extern void drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp);
+ extern int drm_dma_setup(struct drm_device *dev);
+ extern void drm_dma_takedown(struct drm_device *dev);
+ extern void drm_free_buffer(struct drm_device *dev, struct drm_buf * buf);
+ extern void drm_core_reclaim_buffers(struct drm_device *dev,
+                                    struct drm_file *filp);
  
                                /* IRQ support (drm_irq.h) */
- extern int drm_control(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
+ extern int drm_control(struct drm_device *dev, void *data,
+                      struct drm_file *file_priv);
  extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS);
- extern int drm_irq_uninstall(drm_device_t *dev);
- extern void drm_driver_irq_preinstall(drm_device_t * dev);
- extern void drm_driver_irq_postinstall(drm_device_t * dev);
- extern void drm_driver_irq_uninstall(drm_device_t * dev);
- extern int drm_vblank_init(drm_device_t *dev, int num_crtcs);
- extern int drm_wait_vblank(struct inode *inode, struct file *filp,
-                          unsigned int cmd, unsigned long arg);
- extern int drm_vblank_wait(drm_device_t * dev, unsigned int *vbl_seq);
- extern void drm_locked_tasklet(drm_device_t *dev, void(*func)(drm_device_t*));
- extern u32 drm_vblank_count(drm_device_t *dev, int crtc);
- extern void drm_update_vblank_count(drm_device_t *dev, int crtc);
- extern void drm_handle_vblank(drm_device_t *dev, int crtc);
- extern int drm_vblank_get(drm_device_t *dev, int crtc);
- extern void drm_vblank_put(drm_device_t *dev, int crtc);
+ extern int drm_irq_install(struct drm_device *dev);
+ extern int drm_irq_uninstall(struct drm_device *dev);
+ extern void drm_driver_irq_preinstall(struct drm_device *dev);
+ extern void drm_driver_irq_postinstall(struct drm_device *dev);
+ extern void drm_driver_irq_uninstall(struct drm_device *dev);
 -extern int drm_wait_vblank(struct drm_device *dev, void *data,
 -                         struct drm_file *file_priv);
 -extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq);
 -extern void drm_vbl_send_signals(struct drm_device *dev);
++extern int drm_vblank_init(struct drm_device *dev, int num_crtcs);
++extern int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *filp);
++extern int drm_vblank_wait(struct drm_device * dev, unsigned int *vbl_seq);
+ extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*));
++extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
++extern void drm_update_vblank_count(struct drm_device *dev, int crtc);
++extern void drm_handle_vblank(struct drm_device *dev, int crtc);
++extern int drm_vblank_get(struct drm_device *dev, int crtc);
++extern void drm_vblank_put(struct drm_device *dev, int crtc);
 +
 +                              /* Modesetting support */
- extern int drm_modeset_ctl(struct inode *inode, struct file *filp,
-                          unsigned int cmd, unsigned long arg);
++extern int drm_modeset_ctl(struct drm_device *dev, void *data,
++                         struct drm_file *file_priv);
  
                                /* AGP/GART support (drm_agpsupport.h) */
- extern drm_agp_head_t *drm_agp_init(drm_device_t *dev);
- extern int drm_agp_acquire(drm_device_t * dev);
- extern int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp,
-                          unsigned int cmd, unsigned long arg);
- extern int drm_agp_release(drm_device_t *dev);
- extern int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
-                          unsigned int cmd, unsigned long arg);
- extern int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode);
- extern int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
- extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t *info);
- extern int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
- extern int drm_agp_alloc(drm_device_t *dev, drm_agp_buffer_t *request);
- extern int drm_agp_alloc_ioctl(struct inode *inode, struct file *filp,
-                        unsigned int cmd, unsigned long arg);
- extern int drm_agp_free(drm_device_t *dev, drm_agp_buffer_t *request);
- extern int drm_agp_free_ioctl(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
- extern int drm_agp_unbind(drm_device_t *dev, drm_agp_binding_t *request);
- extern int drm_agp_unbind_ioctl(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
- extern int drm_agp_bind(drm_device_t *dev, drm_agp_binding_t *request);
- extern int drm_agp_bind_ioctl(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
+ extern struct drm_agp_head *drm_agp_init(struct drm_device *dev);
+ extern int drm_agp_acquire(struct drm_device *dev);
+ extern int drm_agp_acquire_ioctl(struct drm_device *dev, void *data,
+                                struct drm_file *file_priv);
+ extern int drm_agp_release(struct drm_device *dev);
+ extern int drm_agp_release_ioctl(struct drm_device *dev, void *data,
+                                struct drm_file *file_priv);
+ extern int drm_agp_enable(struct drm_device *dev, struct drm_agp_mode mode);
+ extern int drm_agp_enable_ioctl(struct drm_device *dev, void *data,
+                               struct drm_file *file_priv);
+ extern int drm_agp_info(struct drm_device *dev, struct drm_agp_info *info);
+ extern int drm_agp_info_ioctl(struct drm_device *dev, void *data,
+                       struct drm_file *file_priv);
+ extern int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request);
+ extern int drm_agp_alloc_ioctl(struct drm_device *dev, void *data,
+                        struct drm_file *file_priv);
+ extern int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request);
+ extern int drm_agp_free_ioctl(struct drm_device *dev, void *data,
+                       struct drm_file *file_priv);
+ extern int drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request);
+ extern int drm_agp_unbind_ioctl(struct drm_device *dev, void *data,
+                         struct drm_file *file_priv);
+ extern int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request);
+ extern int drm_agp_bind_ioctl(struct drm_device *dev, void *data,
+                       struct drm_file *file_priv);
  #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11)
  extern DRM_AGP_MEM *drm_agp_allocate_memory(size_t pages, u32 type);
  #else
  #include "drmP.h"
  #include "drm_core.h"
  
- static void drm_cleanup(drm_device_t * dev);
+ static void drm_cleanup(struct drm_device * dev);
  int drm_fb_loaded = 0;
  
- static int drm_version(struct inode *inode, struct file *filp,
-               unsigned int cmd, unsigned long arg);
+ static int drm_version(struct drm_device *dev, void *data,
+                      struct drm_file *file_priv);
  
  /** Ioctl table */
- static drm_ioctl_desc_t drm_ioctls[] = {
-       [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = {drm_version, 0},
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = {drm_getunique, 0},
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = {drm_getmagic, 0},
-       [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = {drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = {drm_getmap, 0},
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = {drm_getclient, 0},
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = {drm_getstats, 0},
-       [DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = {drm_setversion, DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = {drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = {drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = {drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = {drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = {drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = {drm_rmmap_ioctl, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, DRM_AUTH|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = {drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = {drm_resctx, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = {drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = {drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = {drm_lock, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = {drm_unlock, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = {drm_noop, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = {drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = {drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = {drm_infobufs, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = {drm_mapbufs, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = {drm_freebufs, DRM_AUTH},
+ static struct drm_ioctl_desc drm_ioctls[] = {
+       DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0),
+       DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
+       DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
+       DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0),
+       DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0),
+       DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0),
+       DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_getctx, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_resctx, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_infobufs, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_mapbufs, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_freebufs, DRM_AUTH),
        /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */
-       [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = {NULL, DRM_AUTH},
+       DRM_IOCTL_DEF(DRM_IOCTL_DMA, NULL, DRM_AUTH),
  
-       [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = {drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+       DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
  
  #if __OS_HAS_AGP
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info_ioctl, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
+       DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
  #endif
  
-       [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0},
-       [DRM_IOCTL_NR(DRM_IOCTL_FENCE)] = {drm_fence_ioctl, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_IOCTL_BUFOBJ)] = {drm_bo_ioctl, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_IOCTL_MM_INIT)] = {drm_mm_init_ioctl, 
-                                            DRM_AUTH },
-       [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW)] = {drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_MODESET_CTL)] = {drm_modeset_ctl, 0},
+       DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 -
+       DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
 -      //      DRM_IOCTL_DEF(DRM_IOCTL_BUFOBJ, drm_bo_ioctl, DRM_AUTH),
++      DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
+       DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 -
+       DRM_IOCTL_DEF(DRM_IOCTL_MM_INIT, drm_mm_init_ioctl, 
+                     DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_MM_TAKEDOWN, drm_mm_takedown_ioctl, 
+                     DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_MM_LOCK, drm_mm_lock_ioctl, 
+                     DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_MM_UNLOCK, drm_mm_unlock_ioctl, 
+                     DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_IOCTL_FENCE_CREATE, drm_fence_create_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_FENCE_REFERENCE, drm_fence_reference_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_FENCE_UNREFERENCE, drm_fence_unreference_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_FENCE_SIGNALED, drm_fence_signaled_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_FENCE_FLUSH, drm_fence_flush_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_FENCE_WAIT, drm_fence_wait_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_FENCE_EMIT, drm_fence_emit_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_FENCE_BUFFERS, drm_fence_buffers_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_BO_CREATE, drm_bo_create_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_BO_MAP, drm_bo_map_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_BO_UNMAP, drm_bo_unmap_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_BO_REFERENCE, drm_bo_reference_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_BO_UNREFERENCE, drm_bo_unreference_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_BO_SETSTATUS, drm_bo_setstatus_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_BO_INFO, drm_bo_info_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_BO_WAIT_IDLE, drm_bo_wait_idle_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_BO_VERSION, drm_bo_version_ioctl, 0),
  };
  
  #define DRM_CORE_IOCTL_COUNT  ARRAY_SIZE( drm_ioctls )
@@@ -74,93 -71,6 +71,90 @@@ int drm_irq_by_busid(struct drm_device 
        return 0;
  }
  
-       drm_device_t *dev = (drm_device_t *)arg;
 +static void vblank_disable_fn(unsigned long arg)
 +{
- int drm_vblank_init(drm_device_t *dev, int num_crtcs)
++      struct drm_device *dev = (struct drm_device *)arg;
 +      int i;
 +
 +      for (i = 0; i < dev->num_crtcs; i++)
 +              if (atomic_read(&dev->vblank_refcount[i]) == 0)
 +                      dev->driver->disable_vblank(dev, i);
 +}
 +
++int drm_vblank_init(struct drm_device *dev, int num_crtcs)
 +{
 +      int i, ret = -ENOMEM;
 +
 +      setup_timer(&dev->vblank_disable_timer, vblank_disable_fn,\
 +                  (unsigned long)dev);
 +      spin_lock_init(&dev->vbl_lock);
 +      atomic_set(&dev->vbl_signal_pending, 0);
 +      dev->num_crtcs = num_crtcs;
 +
 +      dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs,
 +                                 DRM_MEM_DRIVER);
 +      if (!dev->vbl_queue)
 +              goto err;
 +
 +      dev->vbl_sigs = drm_alloc(sizeof(struct list_head) * num_crtcs,
 +                                DRM_MEM_DRIVER);
 +      if (!dev->vbl_sigs)
 +              goto err;
 +
 +      dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs,
 +                                    DRM_MEM_DRIVER);
 +      if (!dev->_vblank_count)
 +              goto err;
 +
 +      dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs,
 +                                       DRM_MEM_DRIVER);
 +      if (!dev->vblank_refcount)
 +              goto err;
 +
 +      dev->last_vblank = drm_calloc(1, sizeof(u32) * num_crtcs,
 +                                    DRM_MEM_DRIVER);
 +      if (!dev->last_vblank)
 +              goto err;
 +
 +      dev->vblank_premodeset = drm_calloc(1, sizeof(u32) * num_crtcs,
 +                                          DRM_MEM_DRIVER);
 +      if (!dev->vblank_premodeset)
 +              goto err;
 +
 +      dev->vblank_offset = drm_calloc(1, sizeof(u32) * num_crtcs,
 +                                      DRM_MEM_DRIVER);
 +      if (!dev->vblank_offset)
 +              goto err;
 +
 +      /* Zero per-crtc vblank stuff */
 +      for (i = 0; i < num_crtcs; i++) {
 +              init_waitqueue_head(&dev->vbl_queue[i]);
 +              INIT_LIST_HEAD(&dev->vbl_sigs[i]);
 +              atomic_set(&dev->_vblank_count[i], 0);
 +              atomic_set(&dev->vblank_refcount[i], 0);
 +      }
 +
 +      return 0;
 +
 +err:
 +      drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * num_crtcs,
 +               DRM_MEM_DRIVER);
 +      drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * num_crtcs,
 +               DRM_MEM_DRIVER);
 +      drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) * num_crtcs,
 +               DRM_MEM_DRIVER);
 +      drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) *
 +               num_crtcs, DRM_MEM_DRIVER);
 +      drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * num_crtcs,
 +               DRM_MEM_DRIVER);
 +      drm_free(dev->vblank_premodeset, sizeof(*dev->vblank_premodeset) *
 +               num_crtcs, DRM_MEM_DRIVER);
 +      drm_free(dev->vblank_offset, sizeof(*dev->vblank_offset) * num_crtcs,
 +               DRM_MEM_DRIVER);
 +      return ret;
 +}
 +EXPORT_SYMBOL(drm_vblank_init);
 +
  /**
   * Install IRQ handler.
   *
   * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
   * before and after the installation.
   */
static int drm_irq_install(drm_device_t * dev)
int drm_irq_install(struct drm_device * dev)
  {
 -      int ret;
 +      int ret = 0;
        unsigned long sh_flags = 0;
  
        if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
        }
  
        /* After installing handler */
 -      dev->driver->irq_postinstall(dev);
 +      ret = dev->driver->irq_postinstall(dev);
  
 -      return 0;
 +      return ret;
  }
+ EXPORT_SYMBOL(drm_irq_install);
  
  /**
   * Uninstall the IRQ handler.
@@@ -295,150 -213,6 +286,149 @@@ int drm_control(struct drm_device *dev
  }
  
  /**
- u32 drm_vblank_count(drm_device_t *dev, int crtc)
 + * drm_vblank_count - retrieve "cooked" vblank counter value
 + * @dev: DRM device
 + * @crtc: which counter to retrieve
 + *
 + * Fetches the "cooked" vblank count value that represents the number of
 + * vblank events since the system was booted, including lost events due to
 + * modesetting activity.
 + */
- void drm_update_vblank_count(drm_device_t *dev, int crtc)
++u32 drm_vblank_count(struct drm_device *dev, int crtc)
 +{
 +      return atomic_read(&dev->_vblank_count[crtc]) +
 +              dev->vblank_offset[crtc];
 +}
 +EXPORT_SYMBOL(drm_vblank_count);
 +
 +/**
 + * drm_update_vblank_count - update the master vblank counter
 + * @dev: DRM device
 + * @crtc: counter to update
 + *
 + * Call back into the driver to update the appropriate vblank counter
 + * (specified by @crtc).  Deal with wraparound, if it occurred, and
 + * update the last read value so we can deal with wraparound on the next
 + * call if necessary.
 + */
- int drm_vblank_get(drm_device_t *dev, int crtc)
++void drm_update_vblank_count(struct drm_device *dev, int crtc)
 +{
 +      unsigned long irqflags;
 +      u32 cur_vblank, diff;
 +
 +      /*
 +       * Interrupts were disabled prior to this call, so deal with counter
 +       * wrap if needed.
 +       * NOTE!  It's possible we lost a full dev->max_vblank_count events
 +       * here if the register is small or we had vblank interrupts off for
 +       * a long time.
 +       */
 +      cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
 +      spin_lock_irqsave(&dev->vbl_lock, irqflags);
 +      if (cur_vblank < dev->last_vblank[crtc]) {
 +              diff = dev->max_vblank_count -
 +                      dev->last_vblank[crtc];
 +              diff += cur_vblank;
 +      } else {
 +              diff = cur_vblank - dev->last_vblank[crtc];
 +      }
 +      dev->last_vblank[crtc] = cur_vblank;
 +      spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
 +
 +      atomic_add(diff, &dev->_vblank_count[crtc]);
 +}
 +EXPORT_SYMBOL(drm_update_vblank_count);
 +
 +/**
 + * drm_vblank_get - get a reference count on vblank events
 + * @dev: DRM device
 + * @crtc: which CRTC to own
 + *
 + * Acquire a reference count on vblank events to avoid having them disabled
 + * while in use.  Note callers will probably want to update the master counter
 + * using drm_update_vblank_count() above before calling this routine so that
 + * wakeups occur on the right vblank event.
 + *
 + * RETURNS
 + * Zero on success, nonzero on failure.
 + */
- void drm_vblank_put(drm_device_t *dev, int crtc)
++int drm_vblank_get(struct drm_device *dev, int crtc)
 +{
 +      int ret = 0;
 +
 +      /* Going from 0->1 means we have to enable interrupts again */
 +      if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) {
 +              ret = dev->driver->enable_vblank(dev, crtc);
 +              if (ret)
 +                      atomic_dec(&dev->vblank_refcount[crtc]);
 +      }
 +
 +      return ret;
 +}
 +EXPORT_SYMBOL(drm_vblank_get);
 +
 +/**
 + * drm_vblank_put - give up ownership of vblank events
 + * @dev: DRM device
 + * @crtc: which counter to give up
 + *
 + * Release ownership of a given vblank counter, turning off interrupts
 + * if possible.
 + */
- int drm_modeset_ctl(DRM_IOCTL_ARGS)
++void drm_vblank_put(struct drm_device *dev, int crtc)
 +{
 +      /* Last user schedules interrupt disable */
 +      if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
 +              mod_timer(&dev->vblank_disable_timer,
 +                        round_jiffies_relative(DRM_HZ));
 +}
 +EXPORT_SYMBOL(drm_vblank_put);
 +
 +/**
 + * drm_modeset_ctl - handle vblank event counter changes across mode switch
 + * @DRM_IOCTL_ARGS: standard ioctl arguments
 + *
 + * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET
 + * ioctls around modesetting so that any lost vblank events are accounted for.
 + */
-       drm_file_t *priv = filp->private_data;
-       drm_device_t *dev = priv->head->dev;
++int drm_modeset_ctl(struct drm_device *dev, void *data,
++                  struct drm_file *file_priv)
 +{
 +      drm_modeset_ctl_t __user *argp = (void __user *)data;
 +      drm_modeset_ctl_t modeset;
 +      int crtc, ret = 0;
 +      u32 new;
 +
 +      if (copy_from_user(&modeset, argp, sizeof(modeset))) {
 +              ret = -EFAULT;
 +              goto out;
 +      }
 +
 +      crtc = modeset.arg;
 +      if (crtc >= dev->num_crtcs) {
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +      switch (modeset.cmd) {
 +      case _DRM_PRE_MODESET:
 +              dev->vblank_premodeset[crtc] =
 +                      dev->driver->get_vblank_counter(dev, crtc);
 +              break;
 +      case _DRM_POST_MODESET:
 +              new = dev->driver->get_vblank_counter(dev, crtc);
 +              dev->vblank_offset[crtc] = dev->vblank_premodeset[crtc] - new;
 +              break;
 +      default:
 +              ret = -EINVAL;
 +              break;
 +      }
 +
 +out:
 +      return ret;
 +}
 +
 +/**
   * Wait for VBLANK.
   *
   * \param inode device inode.
   *
   * If a signal is not requested, then calls vblank_wait().
   */
- int drm_wait_vblank(DRM_IOCTL_ARGS)
 -int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv)
++int drm_wait_vblank(struct drm_device *dev, void *data,
++                  struct drm_file *file_priv)
  {
-       drm_file_t *priv = filp->private_data;
-       drm_device_t *dev = priv->head->dev;
-       drm_wait_vblank_t __user *argp = (void __user *)data;
-       drm_wait_vblank_t vblwait;
+       union drm_wait_vblank *vblwait = data;
        struct timeval now;
        int ret = 0;
 -      unsigned int flags, seq;
 +      unsigned int flags, seq, crtc;
  
        if ((!dev->irq) || (!dev->irq_enabled))
                return -EINVAL;
                return -EINVAL;
        }
  
-       flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
+       flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
 +      crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
  
 -      if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ?
 -                                  DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL))
 +      if (crtc >= dev->num_crtcs)
                return -EINVAL;
  
 -      seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2
 -                        : &dev->vbl_received);
 +      drm_update_vblank_count(dev, crtc);
 +      seq = drm_vblank_count(dev, crtc);
  
-       switch (vblwait.request.type & _DRM_VBLANK_TYPES_MASK) {
+       switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
        case _DRM_VBLANK_RELATIVE:
-               vblwait.request.sequence += seq;
-               vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
+               vblwait->request.sequence += seq;
+               vblwait->request.type &= ~_DRM_VBLANK_RELATIVE;
        case _DRM_VBLANK_ABSOLUTE:
                break;
        default:
  
        if (flags & _DRM_VBLANK_SIGNAL) {
                unsigned long irqflags;
 -              struct list_head *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY)
 -                                    ? &dev->vbl_sigs2 : &dev->vbl_sigs;
 +              struct list_head *vbl_sigs = &dev->vbl_sigs[crtc];
-               drm_vbl_sig_t *vbl_sig;
+               struct drm_vbl_sig *vbl_sig;
  
                spin_lock_irqsave(&dev->vbl_lock, irqflags);
  
                        return -EBUSY;
                }
  
 -              dev->vbl_pending++;
 -
                spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
  
-               vbl_sig = drm_calloc(1, sizeof(drm_vbl_sig_t), DRM_MEM_DRIVER);
-               if (!vbl_sig) {
 -              if (!
 -                  (vbl_sig =
 -                   drm_alloc(sizeof(struct drm_vbl_sig), DRM_MEM_DRIVER))) {
++              vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig),
++                                   DRM_MEM_DRIVER);
++              if (!vbl_sig)
                        return -ENOMEM;
-               }
 +
 +              ret = drm_vblank_get(dev, crtc);
 +              if (ret) {
-                       drm_free(vbl_sig, sizeof(drm_vbl_sig_t),
++                      drm_free(vbl_sig, sizeof(struct drm_vbl_sig),
 +                               DRM_MEM_DRIVER);
 +                      return ret;
                }
  
 -              memset((void *)vbl_sig, 0, sizeof(*vbl_sig));
 +              atomic_inc(&dev->vbl_signal_pending);
  
-               vbl_sig->sequence = vblwait.request.sequence;
-               vbl_sig->info.si_signo = vblwait.request.signal;
+               vbl_sig->sequence = vblwait->request.sequence;
+               vbl_sig->info.si_signo = vblwait->request.signal;
                vbl_sig->task = current;
  
                spin_lock_irqsave(&dev->vbl_lock, irqflags);
  
                spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
  
-               vblwait.reply.sequence = seq;
+               vblwait->reply.sequence = seq;
        } else {
 -              if (flags & _DRM_VBLANK_SECONDARY) {
 -                      if (dev->driver->vblank_wait2)
 -                              ret = dev->driver->vblank_wait2(dev, &vblwait->request.sequence);
 -              } else if (dev->driver->vblank_wait)
 -                      ret =
 -                          dev->driver->vblank_wait(dev,
 -                                                   &vblwait->request.sequence);
 -
 +              unsigned long cur_vblank;
 +
 +              ret = drm_vblank_get(dev, crtc);
 +              if (ret)
 +                      return ret;
 +              DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
 +                          (((cur_vblank = drm_vblank_count(dev, crtc))
-                             - vblwait.request.sequence) <= (1 << 23)));
++                            - vblwait->request.sequence) <= (1 << 23)));
 +              drm_vblank_put(dev, crtc);
                do_gettimeofday(&now);
-               vblwait.reply.tval_sec = now.tv_sec;
-               vblwait.reply.tval_usec = now.tv_usec;
-               vblwait.reply.sequence = cur_vblank;
++
+               vblwait->reply.tval_sec = now.tv_sec;
+               vblwait->reply.tval_usec = now.tv_usec;
++              vblwait->reply.sequence = cur_vblank;
        }
  
        done:
   *
   * If a signal is not requested, then calls vblank_wait().
   */
- static void drm_vbl_send_signals(drm_device_t * dev, int crtc)
 -void drm_vbl_send_signals(struct drm_device * dev)
++static void drm_vbl_send_signals(struct drm_device * dev, int crtc)
  {
-       drm_vbl_sig_t *vbl_sig, *tmp;
++      struct drm_vbl_sig *vbl_sig, *tmp;
 +      struct list_head *vbl_sigs;
 +      unsigned int vbl_seq;
        unsigned long flags;
 -      int i;
  
        spin_lock_irqsave(&dev->vbl_lock, flags);
  
  
        spin_unlock_irqrestore(&dev->vbl_lock, flags);
  }
 -EXPORT_SYMBOL(drm_vbl_send_signals);
 +
 +/**
 + * drm_handle_vblank - handle a vblank event
 + * @dev: DRM device
 + * @crtc: where this event occurred
 + *
 + * Drivers should call this routine in their vblank interrupt handlers to
 + * update the vblank counter and send any signals that may be pending.
 + */
- void drm_handle_vblank(drm_device_t *dev, int crtc)
++void drm_handle_vblank(struct drm_device *dev, int crtc)
 +{
 +      drm_update_vblank_count(dev, crtc);
 +      DRM_WAKEUP(&dev->vbl_queue[crtc]);
 +      drm_vbl_send_signals(dev, crtc);
 +}
 +EXPORT_SYMBOL(drm_handle_vblank);
  
  /**
   * Tasklet wrapper function.
@@@ -76,15 -529,18 +529,18 @@@ static struct drm_driver driver = 
         */
        .driver_features =
            DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR | */
 -          DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL |
 -          DRIVER_IRQ_VBL2,
 +          DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
        .load = i915_driver_load,
+       .unload = i915_driver_unload,
        .firstopen = i915_driver_firstopen,
        .lastclose = i915_driver_lastclose,
        .preclose = i915_driver_preclose,
+       .suspend = i915_suspend,
+       .resume = i915_resume,
        .device_is_agp = i915_driver_device_is_agp,
 -      .vblank_wait = i915_driver_vblank_wait,
 -      .vblank_wait2 = i915_driver_vblank_wait2,
 +      .get_vblank_counter = i915_get_vblank_counter,
 +      .enable_vblank = i915_enable_vblank,
 +      .disable_vblank = i915_disable_vblank,
        .irq_preinstall = i915_driver_irq_preinstall,
        .irq_postinstall = i915_driver_irq_postinstall,
        .irq_uninstall = i915_driver_irq_uninstall,
Simple merge
@@@ -44,12 -44,12 +44,13 @@@ static int probe(struct pci_dev *pdev, 
  static struct drm_driver driver = {
        .driver_features =
            DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
--          DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
--          DRIVER_IRQ_VBL,
++          DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
        .dev_priv_size = sizeof(drm_r128_buf_priv_t),
        .preclose = r128_driver_preclose,
        .lastclose = r128_driver_lastclose,
--      .vblank_wait = r128_driver_vblank_wait,
++      .get_vblank_counter = r128_get_vblank_counter,
++      .enable_vblank = r128_enable_vblank,
++      .disable_vblank = r128_disable_vblank,
        .irq_preinstall = r128_driver_irq_preinstall,
        .irq_postinstall = r128_driver_irq_postinstall,
        .irq_uninstall = r128_driver_irq_uninstall,
@@@ -582,26 -549,11 +549,26 @@@ struct drm_wait_vblank_reply 
   *
   * \sa drmWaitVBlank().
   */
typedef union drm_wait_vblank {
+ union drm_wait_vblank {
        struct drm_wait_vblank_request request;
        struct drm_wait_vblank_reply reply;
- } drm_wait_vblank_t;
+ };
  
-       drm_u64_t arg;
 +typedef enum {
 +      _DRM_PRE_MODESET = 1,
 +      _DRM_POST_MODESET = 2,
 +} drm_modeset_ctl_cmd_t;
 +
 +/**
 + * DRM_IOCTL_MODESET_CTL ioctl argument type
 + *
 + * \sa drmModesetCtl().
 + */
 +typedef struct drm_modeset_ctl {
++      u64 arg;
 +      drm_modeset_ctl_cmd_t cmd;
 +} drm_modeset_ctl_t;
 +
  /**
   * DRM_IOCTL_AGP_ENABLE ioctl argument type.
   *
@@@ -950,26 -939,45 +954,47 @@@ struct drm_mm_init_arg 
  
  #define DRM_IOCTL_AGP_ACQUIRE         DRM_IO(  0x30)
  #define DRM_IOCTL_AGP_RELEASE         DRM_IO(  0x31)
- #define DRM_IOCTL_AGP_ENABLE          DRM_IOW( 0x32, drm_agp_mode_t)
- #define DRM_IOCTL_AGP_INFO            DRM_IOR( 0x33, drm_agp_info_t)
- #define DRM_IOCTL_AGP_ALLOC           DRM_IOWR(0x34, drm_agp_buffer_t)
- #define DRM_IOCTL_AGP_FREE            DRM_IOW( 0x35, drm_agp_buffer_t)
- #define DRM_IOCTL_AGP_BIND            DRM_IOW( 0x36, drm_agp_binding_t)
- #define DRM_IOCTL_AGP_UNBIND          DRM_IOW( 0x37, drm_agp_binding_t)
- #define DRM_IOCTL_SG_ALLOC            DRM_IOW( 0x38, drm_scatter_gather_t)
- #define DRM_IOCTL_SG_FREE             DRM_IOW( 0x39, drm_scatter_gather_t)
- #define DRM_IOCTL_WAIT_VBLANK         DRM_IOWR(0x3a, drm_wait_vblank_t)
+ #define DRM_IOCTL_AGP_ENABLE          DRM_IOW( 0x32, struct drm_agp_mode)
+ #define DRM_IOCTL_AGP_INFO            DRM_IOR( 0x33, struct drm_agp_info)
+ #define DRM_IOCTL_AGP_ALLOC           DRM_IOWR(0x34, struct drm_agp_buffer)
+ #define DRM_IOCTL_AGP_FREE            DRM_IOW( 0x35, struct drm_agp_buffer)
+ #define DRM_IOCTL_AGP_BIND            DRM_IOW( 0x36, struct drm_agp_binding)
+ #define DRM_IOCTL_AGP_UNBIND          DRM_IOW( 0x37, struct drm_agp_binding)
+ #define DRM_IOCTL_SG_ALLOC            DRM_IOW( 0x38, struct drm_scatter_gather)
+ #define DRM_IOCTL_SG_FREE             DRM_IOW( 0x39, struct drm_scatter_gather)
+ #define DRM_IOCTL_WAIT_VBLANK         DRM_IOWR(0x3a, union drm_wait_vblank)
+ #define DRM_IOCTL_UPDATE_DRAW           DRM_IOW(0x3f, struct drm_update_draw)
+ #define DRM_IOCTL_MM_INIT               DRM_IOWR(0xc0, struct drm_mm_init_arg)
+ #define DRM_IOCTL_MM_TAKEDOWN           DRM_IOWR(0xc1, struct drm_mm_type_arg)
+ #define DRM_IOCTL_MM_LOCK               DRM_IOWR(0xc2, struct drm_mm_type_arg)
+ #define DRM_IOCTL_MM_UNLOCK             DRM_IOWR(0xc3, struct drm_mm_type_arg)
+ #define DRM_IOCTL_FENCE_CREATE          DRM_IOWR(0xc4, struct drm_fence_arg)
+ #define DRM_IOCTL_FENCE_REFERENCE       DRM_IOWR(0xc6, struct drm_fence_arg)
+ #define DRM_IOCTL_FENCE_UNREFERENCE     DRM_IOWR(0xc7, struct drm_fence_arg)
+ #define DRM_IOCTL_FENCE_SIGNALED        DRM_IOWR(0xc8, struct drm_fence_arg)
+ #define DRM_IOCTL_FENCE_FLUSH           DRM_IOWR(0xc9, struct drm_fence_arg)
+ #define DRM_IOCTL_FENCE_WAIT            DRM_IOWR(0xca, struct drm_fence_arg)
+ #define DRM_IOCTL_FENCE_EMIT            DRM_IOWR(0xcb, struct drm_fence_arg)
+ #define DRM_IOCTL_FENCE_BUFFERS         DRM_IOWR(0xcc, struct drm_fence_arg)
+ #define DRM_IOCTL_BO_CREATE             DRM_IOWR(0xcd, struct drm_bo_create_arg)
+ #define DRM_IOCTL_BO_MAP                DRM_IOWR(0xcf, struct drm_bo_map_wait_idle_arg)
+ #define DRM_IOCTL_BO_UNMAP              DRM_IOWR(0xd0, struct drm_bo_handle_arg)
+ #define DRM_IOCTL_BO_REFERENCE          DRM_IOWR(0xd1, struct drm_bo_reference_info_arg)
+ #define DRM_IOCTL_BO_UNREFERENCE        DRM_IOWR(0xd2, struct drm_bo_handle_arg)
+ #define DRM_IOCTL_BO_SETSTATUS          DRM_IOWR(0xd3, struct drm_bo_map_wait_idle_arg)
+ #define DRM_IOCTL_BO_INFO               DRM_IOWR(0xd4, struct drm_bo_reference_info_arg)
+ #define DRM_IOCTL_BO_WAIT_IDLE          DRM_IOWR(0xd5, struct drm_bo_map_wait_idle_arg)
+ #define DRM_IOCTL_BO_VERSION          DRM_IOR(0xd6, struct drm_bo_version_arg)
  
- #define DRM_IOCTL_FENCE                 DRM_IOWR(0x3b, drm_fence_arg_t)
- #define DRM_IOCTL_BUFOBJ                DRM_IOWR(0x3d, drm_bo_arg_t)
- #define DRM_IOCTL_MM_INIT               DRM_IOWR(0x3e, drm_mm_init_arg_t)
- #define DRM_IOCTL_UPDATE_DRAW           DRM_IOW(0x3f, drm_update_draw_t)
  
 +#define DRM_IOCTL_MODESET_CTL           DRM_IOW(0xa0, drm_modeset_ctl_t)
 +
  /*@}*/
  
  /**
@@@ -158,31 -252,40 +252,41 @@@ extern int i915_emit_mi_flush(struct dr
  extern int i915_driver_firstopen(struct drm_device *dev);
  
  /* i915_irq.c */
- extern int i915_irq_emit(DRM_IOCTL_ARGS);
- extern int i915_irq_wait(DRM_IOCTL_ARGS);
+ extern int i915_irq_emit(struct drm_device *dev, void *data,
+                        struct drm_file *file_priv);
+ extern int i915_irq_wait(struct drm_device *dev, void *data,
+                        struct drm_file *file_priv);
  
 -extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence);
 -extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
  extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
- extern void i915_driver_irq_preinstall(drm_device_t * dev);
- extern int i915_driver_irq_postinstall(drm_device_t * dev);
- extern void i915_driver_irq_uninstall(drm_device_t * dev);
- extern int i915_vblank_pipe_set(DRM_IOCTL_ARGS);
- extern int i915_vblank_pipe_get(DRM_IOCTL_ARGS);
- extern int i915_emit_irq(drm_device_t * dev);
+ extern void i915_driver_irq_preinstall(struct drm_device * dev);
 -extern void i915_driver_irq_postinstall(struct drm_device * dev);
++extern int i915_driver_irq_postinstall(struct drm_device * dev);
+ extern void i915_driver_irq_uninstall(struct drm_device * dev);
+ extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
+                               struct drm_file *file_priv);
+ extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
+                               struct drm_file *file_priv);
+ extern int i915_emit_irq(struct drm_device * dev);
 -extern void i915_user_irq_on(drm_i915_private_t *dev_priv);
 -extern void i915_user_irq_off(drm_i915_private_t *dev_priv);
++extern int i915_enable_vblank(struct drm_device *dev, int crtc);
++extern void i915_disable_vblank(struct drm_device *dev, int crtc);
++extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
+ extern int i915_vblank_swap(struct drm_device *dev, void *data,
+                           struct drm_file *file_priv);
 +extern void i915_user_irq_on(drm_i915_private_t *dev_priv);
 +extern void i915_user_irq_off(drm_i915_private_t *dev_priv);
- extern int i915_vblank_swap(DRM_IOCTL_ARGS);
- extern int i915_enable_vblank(drm_device_t *dev, int crtc);
- extern void i915_disable_vblank(drm_device_t *dev, int crtc);
- extern u32 i915_get_vblank_counter(drm_device_t *dev, int crtc);
  
  /* i915_mem.c */
- extern int i915_mem_alloc(DRM_IOCTL_ARGS);
- extern int i915_mem_free(DRM_IOCTL_ARGS);
- extern int i915_mem_init_heap(DRM_IOCTL_ARGS);
- extern int i915_mem_destroy_heap(DRM_IOCTL_ARGS);
+ extern int i915_mem_alloc(struct drm_device *dev, void *data,
+                         struct drm_file *file_priv);
+ extern int i915_mem_free(struct drm_device *dev, void *data,
+                        struct drm_file *file_priv);
+ extern int i915_mem_init_heap(struct drm_device *dev, void *data,
+                             struct drm_file *file_priv);
+ extern int i915_mem_destroy_heap(struct drm_device *dev, void *data,
+                                struct drm_file *file_priv);
  extern void i915_mem_takedown(struct mem_block **heap);
- extern void i915_mem_release(drm_device_t * dev,
-                            DRMFILE filp, struct mem_block *heap);
+ extern void i915_mem_release(struct drm_device * dev,
+                            struct drm_file *file_priv,
+                            struct mem_block *heap);
  #ifdef I915_HAVE_FENCE
  /* i915_fence.c */
  
@@@ -86,14 -109,14 +109,13 @@@ i915_dispatch_vsync_flip(struct drm_dev
   *
   * This function will be called with the HW lock held.
   */
- static void i915_vblank_tasklet(drm_device_t *dev)
+ static void i915_vblank_tasklet(struct drm_device *dev)
  {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       unsigned long irqflags;
        struct list_head *list, *tmp, hits, *hit;
        int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages;
 -      unsigned counter[2] = { atomic_read(&dev->vbl_received),
 -                              atomic_read(&dev->vbl_received2) };
 +      unsigned counter[2];
-       drm_drawable_info_t *drw;
+       struct drm_drawable_info *drw;
        drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
        u32 cpp = dev_priv->cpp,  offsets[3];
        u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
        list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
                drm_i915_vbl_swap_t *vbl_swap =
                        list_entry(list, drm_i915_vbl_swap_t, head);
-               int crtc = vbl_swap->pipe;
 -              int pipe = i915_get_pipe(dev, vbl_swap->plane);
++              int crtc = i915_get_pipe(dev, vbl_swap->plane);
  
-               if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23))
 -              if ((counter[pipe] - vbl_swap->sequence) > (1<<23))
++              if ((counter[crtc] - vbl_swap->sequence) > (1<<23))
                        continue;
  
                list_del(list);
                dev_priv->swaps_pending--;
 +              drm_vblank_put(dev, crtc);
  
-               spin_unlock(&dev_priv->swaps_lock);
-               spin_lock(&dev->drw_lock);
+               DRM_SPINUNLOCK(&dev_priv->swaps_lock);
+               DRM_SPINLOCK(&dev->drw_lock);
  
                drw = drm_get_drawable_info(dev, vbl_swap->drw_id);
  
        }
  }
  
- u32 i915_get_vblank_counter(drm_device_t *dev, int crtc)
++u32 i915_get_vblank_counter(struct drm_device *dev, int crtc)
 +{
 +      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 +      unsigned long high_frame = crtc ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
 +      unsigned long low_frame = crtc ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
 +      u32 high1, high2, low, count;
 +
-       if (!IS_I965G(dev))
-               return 0;
 +      /*
 +       * High & low register fields aren't synchronized, so make sure
 +       * we get a low value that's stable across two reads of the high
 +       * register.
 +       */
 +      do {
 +              high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
 +                       PIPE_FRAME_HIGH_SHIFT);
 +              low =  ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
 +                      PIPE_FRAME_LOW_SHIFT);
 +              high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
 +                       PIPE_FRAME_HIGH_SHIFT);
 +      } while (high1 != high2);
 +
 +      count = (high1 << 8) | low;
 +
 +      return count;
 +}
 +
  irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
  {
-       drm_device_t *dev = (drm_device_t *) arg;
+       struct drm_device *dev = (struct drm_device *) arg;
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        u16 temp;
        u32 pipea_stats, pipeb_stats;
  #endif
        }
  
-       if (!IS_I965G(dev)) {
-               if (temp & VSYNC_PIPEA_FLAG)
-                       atomic_inc(&dev->_vblank_count[0]);
-               if (temp & VSYNC_PIPEB_FLAG)
-                       atomic_inc(&dev->_vblank_count[1]);
-       }
 -      if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
 -              int vblank_pipe = dev_priv->vblank_pipe;
 -
 -              if ((vblank_pipe &
 -                   (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
 -                  == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
 -                      if (temp & VSYNC_PIPEA_FLAG)
 -                              atomic_inc(&dev->vbl_received);
 -                      if (temp & VSYNC_PIPEB_FLAG)
 -                              atomic_inc(&dev->vbl_received2);
 -              } else if (((temp & VSYNC_PIPEA_FLAG) &&
 -                          (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
 -                         ((temp & VSYNC_PIPEB_FLAG) &&
 -                          (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
 -                      atomic_inc(&dev->vbl_received);
--
 -              DRM_WAKEUP(&dev->vbl_queue);
 -              drm_vbl_send_signals(dev);
 +      /*
 +       * Use drm_update_vblank_counter here to deal with potential lost
 +       * interrupts
 +       */
 +      if (temp & VSYNC_PIPEA_FLAG)
 +              drm_handle_vblank(dev, 0);
 +      if (temp & VSYNC_PIPEB_FLAG)
 +              drm_handle_vblank(dev, 1);
  
 +      if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
                if (dev_priv->swaps_pending > 0)
                        drm_locked_tasklet(dev, i915_vblank_tasklet);
                I915_WRITE(I915REG_PIPEASTAT, 
@@@ -442,16 -437,47 +458,15 @@@ static int i915_wait_irq(struct drm_dev
        return ret;
  }
  
 -static int i915_driver_vblank_do_wait(struct drm_device *dev,
 -                                    unsigned int *sequence,
 -                                    atomic_t *counter)
 -{
 -      drm_i915_private_t *dev_priv = dev->dev_private;
 -      unsigned int cur_vblank;
 -      int ret = 0;
 -
 -      if (!dev_priv) {
 -              DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
 -              return -EINVAL;
 -      }
 -
 -      DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
 -                  (((cur_vblank = atomic_read(counter))
 -                      - *sequence) <= (1<<23)));
 -      
 -      *sequence = cur_vblank;
 -
 -      return ret;
 -}
 -
 -int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
 -{
 -      return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received);
 -}
 -
 -int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
 -{
 -      return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2);
 -}
 -
  /* Needs the lock as it touches the ring.
   */
- int i915_irq_emit(DRM_IOCTL_ARGS)
+ int i915_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv)
  {
-       DRM_DEVICE;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       drm_i915_irq_emit_t emit;
+       drm_i915_irq_emit_t *emit = data;
        int result;
  
-       LOCK_TEST_WITH_RETURN(dev, filp);
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
  
        if (!dev_priv) {
                DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
@@@ -481,68 -504,21 +493,59 @@@ int i915_irq_wait(struct drm_device *de
  
        if (!dev_priv) {
                DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
-               return DRM_ERR(EINVAL);
+               return -EINVAL;
        }
  
-       DRM_COPY_FROM_USER_IOCTL(irqwait, (drm_i915_irq_wait_t __user *) data,
-                                sizeof(irqwait));
-       return i915_wait_irq(dev, irqwait.irq_seq);
+       return i915_wait_irq(dev, irqwait->irq_seq);
  }
  
- int i915_enable_vblank(drm_device_t *dev, int crtc)
 -static void i915_enable_interrupt (struct drm_device *dev)
++int i915_enable_vblank(struct drm_device *dev, int crtc)
  {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 -      
 -      dev_priv->irq_enable_reg = USER_INT_FLAG; 
 -      if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
 +
-       if (!IS_I965G(dev))
-               return 0;
 +      switch (crtc) {
 +      case 0:
                dev_priv->irq_enable_reg |= VSYNC_PIPEA_FLAG;
 -      if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
 +              break;
 +      case 1:
                dev_priv->irq_enable_reg |= VSYNC_PIPEB_FLAG;
- void i915_disable_vblank(drm_device_t *dev, int crtc)
 +              break;
 +      default:
 +              DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
 +                        crtc);
 +              break;
 +      }
 +
 +      I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
 +
 +      return 0;
 +}
 +
-       if (!IS_I965G(dev))
-               return;
++void i915_disable_vblank(struct drm_device *dev, int crtc)
 +{
 +      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 +
- static void i915_enable_interrupt (drm_device_t *dev)
 +      switch (crtc) {
 +      case 0:
 +              dev_priv->irq_enable_reg &= ~VSYNC_PIPEA_FLAG;
 +              break;
 +      case 1:
 +              dev_priv->irq_enable_reg &= ~VSYNC_PIPEB_FLAG;
 +              break;
 +      default:
 +              DRM_ERROR("tried to disable vblank on non-existent crtc %d\n",
 +                        crtc);
 +              break;
 +      }
 +
 +      I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
 +}
 +
++static void i915_enable_interrupt (struct drm_device *dev)
 +{
 +      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 +      
 +      dev_priv->irq_enable_reg |= USER_INT_FLAG;
  
        I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
        dev_priv->irq_enabled = 1;
@@@ -558,20 -534,19 +561,17 @@@ int i915_vblank_pipe_set(struct drm_dev
  
        if (!dev_priv) {
                DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
-               return DRM_ERR(EINVAL);
+               return -EINVAL;
        }
  
-       DRM_COPY_FROM_USER_IOCTL(pipe, (drm_i915_vblank_pipe_t __user *) data,
-                                sizeof(pipe));
-       if (pipe.pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
+       if (pipe->pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
                DRM_ERROR("%s called with invalid pipe 0x%x\n", 
-                         __FUNCTION__, pipe.pipe);
-               return DRM_ERR(EINVAL);
+                         __FUNCTION__, pipe->pipe);
+               return -EINVAL;
        }
  
-       dev_priv->vblank_pipe = pipe.pipe;
+       dev_priv->vblank_pipe = pipe->pipe;
  
 -      i915_enable_interrupt (dev);
 -
        return 0;
  }
  
@@@ -601,16 -575,15 +600,16 @@@ int i915_vblank_pipe_get(struct drm_dev
  /**
   * Schedule buffer swap at given vertical blank.
   */
- int i915_vblank_swap(DRM_IOCTL_ARGS)
+ int i915_vblank_swap(struct drm_device *dev, void *data,
+                    struct drm_file *file_priv)
  {
-       DRM_DEVICE;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       drm_i915_vblank_swap_t swap;
+       drm_i915_vblank_swap_t *swap = data;
        drm_i915_vbl_swap_t *vbl_swap;
-       unsigned int pipe, seqtype, curseq;
+       unsigned int pipe, seqtype, curseq, plane;
        unsigned long irqflags;
        struct list_head *list;
 +      int ret;
  
        if (!dev_priv) {
                DRM_ERROR("%s called with no initialization\n", __func__);
  
        if (!(dev_priv->vblank_pipe & (1 << pipe))) {
                DRM_ERROR("Invalid pipe %d\n", pipe);
-               return DRM_ERR(EINVAL);
+               return -EINVAL;
        }
  
-       spin_lock_irqsave(&dev->drw_lock, irqflags);
+       DRM_SPINLOCK_IRQSAVE(&dev->drw_lock, irqflags);
  
-       if (!drm_get_drawable_info(dev, swap.drawable)) {
-               spin_unlock_irqrestore(&dev->drw_lock, irqflags);
-               DRM_DEBUG("Invalid drawable ID %d\n", swap.drawable);
-               return DRM_ERR(EINVAL);
+       /* It makes no sense to schedule a swap for a drawable that doesn't have
+        * valid information at this point. E.g. this could mean that the X
+        * server is too old to push drawable information to the DRM, in which
+        * case all such swaps would become ineffective.
+        */
+       if (!drm_get_drawable_info(dev, swap->drawable)) {
+               DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock, irqflags);
+               DRM_DEBUG("Invalid drawable ID %d\n", swap->drawable);
+               return -EINVAL;
        }
  
-       spin_unlock_irqrestore(&dev->drw_lock, irqflags);
+       DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock, irqflags);
  
 -      curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received);
 +      drm_update_vblank_count(dev, pipe);
 +      curseq = drm_vblank_count(dev, pipe);
  
        if (seqtype == _DRM_VBLANK_RELATIVE)
-               swap.sequence += curseq;
+               swap->sequence += curseq;
  
-       if ((curseq - swap.sequence) <= (1<<23)) {
-               if (swap.seqtype & _DRM_VBLANK_NEXTONMISS) {
-                       swap.sequence = curseq + 1;
+       if ((curseq - swap->sequence) <= (1<<23)) {
+               if (swap->seqtype & _DRM_VBLANK_NEXTONMISS) {
+                       swap->sequence = curseq + 1;
                } else {
                        DRM_DEBUG("Missed target sequence\n");
-                       return DRM_ERR(EINVAL);
+                       return -EINVAL;
                }
        }
  
  
        DRM_DEBUG("\n");
  
-       vbl_swap->drw_id = swap.drawable;
-       vbl_swap->pipe = pipe;
-       vbl_swap->sequence = swap.sequence;
-       vbl_swap->flip = (swap.seqtype & _DRM_VBLANK_FLIP);
 +      ret = drm_vblank_get(dev, pipe);
 +      if (ret) {
 +              drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
 +              return ret;
 +      }
 +
+       vbl_swap->drw_id = swap->drawable;
+       vbl_swap->plane = plane;
+       vbl_swap->sequence = swap->sequence;
+       vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP);
  
        if (vbl_swap->flip)
-               swap.sequence++;
+               swap->sequence++;
  
-       spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
+       DRM_SPINLOCK_IRQSAVE(&dev_priv->swaps_lock, irqflags);
  
        list_add_tail((struct list_head *)vbl_swap, &dev_priv->vbl_swaps.head);
        dev_priv->swaps_pending++;
@@@ -762,30 -729,17 +762,25 @@@ void i915_driver_irq_preinstall(struct 
        I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
  }
  
- int i915_driver_irq_postinstall(drm_device_t * dev)
 -void i915_driver_irq_postinstall(struct drm_device * dev)
++int i915_driver_irq_postinstall(struct drm_device * dev)
  {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 +      int ret, num_pipes = 2;
  
-       spin_lock_init(&dev_priv->swaps_lock);
+       DRM_SPININIT(&dev_priv->swaps_lock, "swap");
        INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
        dev_priv->swaps_pending = 0;
  
-       dev_priv->user_irq_lock = SPIN_LOCK_UNLOCKED;
+       DRM_SPININIT(&dev_priv->user_irq_lock, "userirq");
        dev_priv->user_irq_refcount = 0;
 +      dev_priv->irq_enable_reg = 0;
 +
 +      ret = drm_vblank_init(dev, num_pipes);
 +      if (ret)
 +              return ret;
 +
 +      dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
  
-       if (!IS_I965G(dev)) {
-               dev_priv->irq_enable_reg |= VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG;
-               I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
-       }
        i915_enable_interrupt(dev);
        DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
  
         */
  
        I915_WRITE(I915REG_INSTPM, ( 1 << 5) | ( 1 << 21));
 +      return 0;
  }
  
- void i915_driver_irq_uninstall(drm_device_t * dev)
+ void i915_driver_irq_uninstall(struct drm_device * dev)
  {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        u16 temp;
@@@ -177,14 -181,12 +182,15 @@@ extern int mga_warp_install_microcode(d
  extern int mga_warp_init(drm_mga_private_t * dev_priv);
  
                                /* mga_irq.c */
- extern int mga_driver_fence_wait(drm_device_t * dev, unsigned int *sequence);
- extern int mga_enable_vblank(drm_device_t *dev, int crtc);
- extern void mga_disable_vblank(drm_device_t *dev, int crtc);
- extern u32 mga_get_vblank_counter(drm_device_t *dev, int crtc);
++extern int mga_enable_vblank(struct drm_device *dev, int crtc);
++extern void mga_disable_vblank(struct drm_device *dev, int crtc);
++extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc);
+ extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence);
+ extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
  extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS);
- extern void mga_driver_irq_preinstall(drm_device_t * dev);
- extern int mga_driver_irq_postinstall(drm_device_t * dev);
- extern void mga_driver_irq_uninstall(drm_device_t * dev);
+ extern void mga_driver_irq_preinstall(struct drm_device * dev);
 -extern void mga_driver_irq_postinstall(struct drm_device * dev);
++extern int mga_driver_irq_postinstall(struct drm_device * dev);
+ extern void mga_driver_irq_uninstall(struct drm_device * dev);
  extern long mga_compat_ioctl(struct file *filp, unsigned int cmd,
                             unsigned long arg);
  
  #include "mga_drm.h"
  #include "mga_drv.h"
  
- u32 mga_get_vblank_counter(drm_device_t *dev, int crtc)
++u32 mga_get_vblank_counter(struct drm_device *dev, int crtc)
 +{
 +      const drm_mga_private_t *const dev_priv = 
 +              (drm_mga_private_t *) dev->dev_private;
 +
 +      if (crtc != 0) {
 +              return 0;
 +      }
 +
 +
 +      return atomic_read(&dev_priv->vbl_received);
 +}
 +
 +
  irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
  {
-       drm_device_t *dev = (drm_device_t *) arg;
+       struct drm_device *dev = (struct drm_device *) arg;
        drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
        int status;
        int handled = 0;
                handled = 1;
        }
  
 -      if ( handled ) {
 -              return IRQ_HANDLED;
 -      }
 -      return IRQ_NONE;
 +      return (handled) ? IRQ_HANDLED : IRQ_NONE;
  }
  
- int mga_enable_vblank(drm_device_t *dev, int crtc)
 -int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)
++int mga_enable_vblank(struct drm_device *dev, int crtc)
  {
 -      unsigned int cur_vblank;
 -      int ret = 0;
 +      drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
  
 -      /* Assume that the user has missed the current sequence number
 -       * by about a day rather than she wants to wait for years
 -       * using vertical blanks...
 -       */
 -      DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
 -                  (((cur_vblank = atomic_read(&dev->vbl_received))
 -                    - *sequence) <= (1 << 23)));
 +      if (crtc != 0) {
 +              DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
 +                        crtc);
 +              return 0;
 +      }
  
 -      *sequence = cur_vblank;
 +      MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
 +      return 0;
 +}
  
 -      return ret;
 +
- void mga_disable_vblank(drm_device_t *dev, int crtc)
++void mga_disable_vblank(struct drm_device *dev, int crtc)
 +{
 +      if (crtc != 0) {
 +              DRM_ERROR("tried to disable vblank on non-existent crtc %d\n",
 +                        crtc);
 +      }
 +
 +      /* Do *NOT* disable the vertical refresh interrupt.  MGA doesn't have
 +       * a nice hardware counter that tracks the number of refreshes when
 +       * the interrupt is disabled, and the kernel doesn't know the refresh
 +       * rate to calculate an estimate.
 +       */
 +      /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */
  }
  
- int mga_driver_fence_wait(drm_device_t * dev, unsigned int *sequence)
+ int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence)
  {
        drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
        unsigned int cur_fence;
@@@ -151,26 -127,17 +149,25 @@@ void mga_driver_irq_preinstall(struct d
        MGA_WRITE(MGA_ICLEAR, ~0);
  }
  
- int mga_driver_irq_postinstall(drm_device_t * dev)
 -void mga_driver_irq_postinstall(struct drm_device * dev)
++int mga_driver_irq_postinstall(struct drm_device * dev)
  {
        drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
 +      int ret;
  
 -      DRM_INIT_WAITQUEUE( &dev_priv->fence_queue );
 +      ret = drm_vblank_init(dev, 1);
 +      if (ret)
 +              return ret;
  
 -      /* Turn on vertical blank interrupt and soft trap interrupt. */
 -      MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
 +      DRM_INIT_WAITQUEUE(&dev_priv->fence_queue);
 +
 +      /* Turn on soft trap interrupt.  Vertical blank interrupts are enabled
 +       * in mga_enable_vblank.
 +       */
 +      MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN);
 +      return 0;
  }
  
- void mga_driver_irq_uninstall(drm_device_t * dev)
+ void mga_driver_irq_uninstall(struct drm_device * dev)
  {
        drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
        if (!dev_priv)
@@@ -228,66 -415,143 +415,143 @@@ extern int nouveau_ioctl_gpuobj_free(st
  
  /* nouveau_irq.c */
  extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS);
- extern void        nouveau_irq_preinstall(drm_device_t*);
- extern void        nouveau_irq_postinstall(drm_device_t*);
- extern void        nouveau_irq_uninstall(drm_device_t*);
+ extern void        nouveau_irq_preinstall(struct drm_device *);
 -extern void        nouveau_irq_postinstall(struct drm_device *);
++extern int         nouveau_irq_postinstall(struct drm_device *);
+ extern void        nouveau_irq_uninstall(struct drm_device *);
+ /* nouveau_sgdma.c */
+ extern int nouveau_sgdma_init(struct drm_device *);
+ extern void nouveau_sgdma_takedown(struct drm_device *);
+ extern int nouveau_sgdma_get_page(struct drm_device *, uint32_t offset,
+                                 uint32_t *page);
+ extern struct drm_ttm_backend *nouveau_sgdma_init_ttm(struct drm_device *);
+ extern int nouveau_sgdma_nottm_hack_init(struct drm_device *);
+ extern void nouveau_sgdma_nottm_hack_takedown(struct drm_device *);
+ /* nouveau_dma.c */
+ extern int  nouveau_dma_channel_init(struct drm_device *);
+ extern void nouveau_dma_channel_takedown(struct drm_device *);
+ extern int  nouveau_dma_wait(struct drm_device *, int size);
  
  /* nv04_fb.c */
- extern int  nv04_fb_init(drm_device_t *dev);
- extern void nv04_fb_takedown(drm_device_t *dev);
+ extern int  nv04_fb_init(struct drm_device *);
+ extern void nv04_fb_takedown(struct drm_device *);
  
  /* nv10_fb.c */
- extern int  nv10_fb_init(drm_device_t *dev);
- extern void nv10_fb_takedown(drm_device_t *dev);
+ extern int  nv10_fb_init(struct drm_device *);
+ extern void nv10_fb_takedown(struct drm_device *);
  
  /* nv40_fb.c */
- extern int  nv40_fb_init(drm_device_t *dev);
- extern void nv40_fb_takedown(drm_device_t *dev);
+ extern int  nv40_fb_init(struct drm_device *);
+ extern void nv40_fb_takedown(struct drm_device *);
+ /* nv04_fifo.c */
+ extern int  nv04_fifo_create_context(struct nouveau_channel *);
+ extern void nv04_fifo_destroy_context(struct nouveau_channel *);
+ extern int  nv04_fifo_load_context(struct nouveau_channel *);
+ extern int  nv04_fifo_save_context(struct nouveau_channel *);
+ /* nv10_fifo.c */
+ extern int  nv10_fifo_create_context(struct nouveau_channel *);
+ extern void nv10_fifo_destroy_context(struct nouveau_channel *);
+ extern int  nv10_fifo_load_context(struct nouveau_channel *);
+ extern int  nv10_fifo_save_context(struct nouveau_channel *);
+ /* nv40_fifo.c */
+ extern int  nv40_fifo_init(struct drm_device *);
+ extern int  nv40_fifo_create_context(struct nouveau_channel *);
+ extern void nv40_fifo_destroy_context(struct nouveau_channel *);
+ extern int  nv40_fifo_load_context(struct nouveau_channel *);
+ extern int  nv40_fifo_save_context(struct nouveau_channel *);
+ /* nv50_fifo.c */
+ extern int  nv50_fifo_init(struct drm_device *);
+ extern void nv50_fifo_takedown(struct drm_device *);
+ extern int  nv50_fifo_create_context(struct nouveau_channel *);
+ extern void nv50_fifo_destroy_context(struct nouveau_channel *);
+ extern int  nv50_fifo_load_context(struct nouveau_channel *);
+ extern int  nv50_fifo_save_context(struct nouveau_channel *);
  
  /* nv04_graph.c */
- extern void nouveau_nv04_context_switch(drm_device_t *dev);
- extern int nv04_graph_init(drm_device_t *dev);
- extern void nv04_graph_takedown(drm_device_t *dev);
- extern int nv04_graph_context_create(drm_device_t *dev, int channel);
+ extern void nouveau_nv04_context_switch(struct drm_device *);
+ extern int  nv04_graph_init(struct drm_device *);
+ extern void nv04_graph_takedown(struct drm_device *);
+ extern int  nv04_graph_create_context(struct nouveau_channel *);
+ extern void nv04_graph_destroy_context(struct nouveau_channel *);
+ extern int  nv04_graph_load_context(struct nouveau_channel *);
+ extern int  nv04_graph_save_context(struct nouveau_channel *);
  
  /* nv10_graph.c */
- extern void nouveau_nv10_context_switch(drm_device_t *dev);
- extern int nv10_graph_init(drm_device_t *dev);
- extern void nv10_graph_takedown(drm_device_t *dev);
- extern int nv10_graph_context_create(drm_device_t *dev, int channel);
+ extern void nouveau_nv10_context_switch(struct drm_device *);
+ extern int  nv10_graph_init(struct drm_device *);
+ extern void nv10_graph_takedown(struct drm_device *);
+ extern int  nv10_graph_create_context(struct nouveau_channel *);
+ extern void nv10_graph_destroy_context(struct nouveau_channel *);
+ extern int  nv10_graph_load_context(struct nouveau_channel *);
+ extern int  nv10_graph_save_context(struct nouveau_channel *);
  
  /* nv20_graph.c */
- extern void nouveau_nv20_context_switch(drm_device_t *dev);
- extern int nv20_graph_init(drm_device_t *dev);
- extern void nv20_graph_takedown(drm_device_t *dev);
- extern int nv20_graph_context_create(drm_device_t *dev, int channel);
- /* nv30_graph.c */
- extern int nv30_graph_init(drm_device_t *dev);
- extern void nv30_graph_takedown(drm_device_t *dev);
- extern int nv30_graph_context_create(drm_device_t *dev, int channel);
+ extern int  nv20_graph_create_context(struct nouveau_channel *);
+ extern void nv20_graph_destroy_context(struct nouveau_channel *);
+ extern int  nv20_graph_load_context(struct nouveau_channel *);
+ extern int  nv20_graph_save_context(struct nouveau_channel *);
+ extern int  nv20_graph_init(struct drm_device *);
+ extern void nv20_graph_takedown(struct drm_device *);
+ extern int  nv30_graph_init(struct drm_device *);
  
  /* nv40_graph.c */
- extern int  nv40_graph_init(drm_device_t *dev);
- extern void nv40_graph_takedown(drm_device_t *dev);
- extern int  nv40_graph_context_create(drm_device_t *dev, int channel);
- extern void nv40_graph_context_save_current(drm_device_t *dev);
- extern void nv40_graph_context_restore(drm_device_t *dev, int channel);
+ extern int  nv40_graph_init(struct drm_device *);
+ extern void nv40_graph_takedown(struct drm_device *);
+ extern int  nv40_graph_create_context(struct nouveau_channel *);
+ extern void nv40_graph_destroy_context(struct nouveau_channel *);
+ extern int  nv40_graph_load_context(struct nouveau_channel *);
+ extern int  nv40_graph_save_context(struct nouveau_channel *);
+ /* nv50_graph.c */
+ extern int  nv50_graph_init(struct drm_device *);
+ extern void nv50_graph_takedown(struct drm_device *);
+ extern int  nv50_graph_create_context(struct nouveau_channel *);
+ extern void nv50_graph_destroy_context(struct nouveau_channel *);
+ extern int  nv50_graph_load_context(struct nouveau_channel *);
+ extern int  nv50_graph_save_context(struct nouveau_channel *);
+ /* nv04_instmem.c */
+ extern int  nv04_instmem_init(struct drm_device *);
+ extern void nv04_instmem_takedown(struct drm_device *);
+ extern int  nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
+                                 uint32_t *size);
+ extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
+ extern int  nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
+ extern int  nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
+ /* nv50_instmem.c */
+ extern int  nv50_instmem_init(struct drm_device *);
+ extern void nv50_instmem_takedown(struct drm_device *);
+ extern int  nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
+                                 uint32_t *size);
+ extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
+ extern int  nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
+ extern int  nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
  
  /* nv04_mc.c */
- extern int  nv04_mc_init(drm_device_t *dev);
- extern void nv04_mc_takedown(drm_device_t *dev);
+ extern int  nv04_mc_init(struct drm_device *);
+ extern void nv04_mc_takedown(struct drm_device *);
  
  /* nv40_mc.c */
- extern int  nv40_mc_init(drm_device_t *dev);
- extern void nv40_mc_takedown(drm_device_t *dev);
+ extern int  nv40_mc_init(struct drm_device *);
+ extern void nv40_mc_takedown(struct drm_device *);
+ /* nv50_mc.c */
+ extern int  nv50_mc_init(struct drm_device *);
+ extern void nv50_mc_takedown(struct drm_device *);
  
  /* nv04_timer.c */
- extern int  nv04_timer_init(drm_device_t *dev);
- extern void nv04_timer_takedown(drm_device_t *dev);
+ extern int  nv04_timer_init(struct drm_device *);
+ extern uint64_t nv04_timer_read(struct drm_device *);
+ extern void nv04_timer_takedown(struct drm_device *);
  
- extern long nouveau_compat_ioctl(struct file *filp, unsigned int cmd,
-                               unsigned long arg);
+ extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd,
+                                unsigned long arg);
  
  #if defined(__powerpc__)
  #define NV_READ(reg)        in_be32((void __iomem *)(dev_priv->mmio)->handle + (reg) )
@@@ -71,89 -46,20 +46,22 @@@ nouveau_irq_preinstall(struct drm_devic
        NV_WRITE(NV03_PMC_INTR_EN_0, 0);
  }
  
- void nouveau_irq_postinstall(drm_device_t *dev)
 -void
++int
+ nouveau_irq_postinstall(struct drm_device *dev)
  {
-       drm_nouveau_private_t *dev_priv = dev->dev_private;
-       if (!dev_priv) {
-               DRM_ERROR("AIII, no dev_priv\n");
-               return;
-       }
-       if (!dev_priv->mmio) {
-               DRM_ERROR("AIII, no dev_priv->mmio\n");
-               return;
-       }
-       DRM_DEBUG("IRQ: postinst\n");
-       /* Enable PFIFO error reporting */
-       NV_WRITE(NV03_PFIFO_INTR_EN_0 , 
-                       NV_PFIFO_INTR_CACHE_ERROR |
-                       NV_PFIFO_INTR_RUNOUT |
-                       NV_PFIFO_INTR_RUNOUT_OVERFLOW |
-                       NV_PFIFO_INTR_DMA_PUSHER |
-                       NV_PFIFO_INTR_DMA_PT |
-                       NV_PFIFO_INTR_SEMAPHORE |
-                       NV_PFIFO_INTR_ACQUIRE_TIMEOUT
-                       );
-       NV_WRITE(NV03_PFIFO_INTR_0, 0xFFFFFFFF);
-       /* Enable PGRAPH interrupts */
-       if (dev_priv->card_type<NV_40)
-               NV_WRITE(NV03_PGRAPH_INTR_EN,
-                               NV_PGRAPH_INTR_NOTIFY |
-                               NV_PGRAPH_INTR_MISSING_HW |
-                               NV_PGRAPH_INTR_CONTEXT_SWITCH |
-                               NV_PGRAPH_INTR_BUFFER_NOTIFY |
-                               NV_PGRAPH_INTR_ERROR
-                               );
-       else
-               NV_WRITE(NV40_PGRAPH_INTR_EN,
-                               NV_PGRAPH_INTR_NOTIFY |
-                               NV_PGRAPH_INTR_MISSING_HW |
-                               NV_PGRAPH_INTR_CONTEXT_SWITCH |
-                               NV_PGRAPH_INTR_BUFFER_NOTIFY |
-                               NV_PGRAPH_INTR_ERROR
-                               );
-       NV_WRITE(NV03_PGRAPH_INTR, 0xFFFFFFFF);
- #if 0
-       /* Enable CRTC0/1 interrupts */
-       NV_WRITE(NV_CRTC0_INTEN, NV_CRTC_INTR_VBLANK);
-       NV_WRITE(NV_CRTC1_INTEN, NV_CRTC_INTR_VBLANK);
- #endif
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
  
        /* Master enable */
        NV_WRITE(NV03_PMC_INTR_EN_0, NV_PMC_INTR_EN_0_MASTER_ENABLE);
++
++      return 0;
  }
  
- void nouveau_irq_uninstall(drm_device_t *dev)
+ void
+ nouveau_irq_uninstall(struct drm_device *dev)
  {
-       drm_nouveau_private_t *dev_priv = dev->dev_private;
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
  
-       if (!dev_priv) {
-               DRM_ERROR("AIII, no dev_priv\n");
-               return;
-       }
-       if (!dev_priv->mmio) {
-               DRM_ERROR("AIII, no dev_priv->mmio\n");
-               return;
-       }
-       DRM_DEBUG("IRQ: uninst\n");
-       /* Disable PFIFO interrupts */
-       NV_WRITE(NV03_PFIFO_INTR_EN_0, 0);
-       /* Disable PGRAPH interrupts */
-       if (dev_priv->card_type<NV_40)
-               NV_WRITE(NV03_PGRAPH_INTR_EN, 0);
-       else
-               NV_WRITE(NV40_PGRAPH_INTR_EN, 0);
- #if 0
-       /* Disable CRTC0/1 interrupts */
-       NV_WRITE(NV_CRTC0_INTEN, 0);
-       NV_WRITE(NV_CRTC1_INTEN, 0);
- #endif
        /* Master disable */
        NV_WRITE(NV03_PMC_INTR_EN_0, 0);
  }
@@@ -97,6 -97,6 +97,8 @@@ typedef struct drm_r128_private 
        u32 crtc_offset;
        u32 crtc_offset_cntl;
  
++      atomic_t vbl_received;
++
        u32 color_fmt;
        unsigned int front_offset;
        unsigned int front_pitch;
@@@ -147,16 -147,17 +149,18 @@@ extern void r128_freelist_reset(struct 
  extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n);
  
  extern int r128_do_cce_idle(drm_r128_private_t * dev_priv);
- extern int r128_do_cleanup_cce(drm_device_t * dev);
- extern int r128_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence);
+ extern int r128_do_cleanup_cce(struct drm_device * dev);
  
 -extern int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
 -
++extern int r128_enable_vblank(struct drm_device *dev, int crtc);
++extern void r128_disable_vblank(struct drm_device *dev, int crtc);
++extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc);
  extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS);
- extern void r128_driver_irq_preinstall(drm_device_t * dev);
- extern void r128_driver_irq_postinstall(drm_device_t * dev);
- extern void r128_driver_irq_uninstall(drm_device_t * dev);
- extern void r128_driver_lastclose(drm_device_t * dev);
- extern void r128_driver_preclose(drm_device_t * dev, DRMFILE filp);
+ extern void r128_driver_irq_preinstall(struct drm_device * dev);
 -extern void r128_driver_irq_postinstall(struct drm_device * dev);
++extern int r128_driver_irq_postinstall(struct drm_device * dev);
+ extern void r128_driver_irq_uninstall(struct drm_device * dev);
+ extern void r128_driver_lastclose(struct drm_device * dev);
+ extern void r128_driver_preclose(struct drm_device * dev,
+                                struct drm_file *file_priv);
  
  extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
                              unsigned long arg);
  #include "r128_drm.h"
  #include "r128_drv.h"
  
++u32 r128_get_vblank_counter(struct drm_device *dev, int crtc)
++{
++      const drm_r128_private_t *dev_priv = dev->dev_private;
++
++      if (crtc != 0)
++              return 0;
++
++      return atomic_read(&dev_priv->vbl_received);
++}
++
  irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS)
  {
-       drm_device_t *dev = (drm_device_t *) arg;
+       struct drm_device *dev = (struct drm_device *) arg;
        drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
        int status;
  
        /* VBLANK interrupt */
        if (status & R128_CRTC_VBLANK_INT) {
                R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
--              atomic_inc(&dev->vbl_received);
--              DRM_WAKEUP(&dev->vbl_queue);
--              drm_vbl_send_signals(dev);
++              atomic_inc(&dev_priv->vbl_received);
++              drm_handle_vblank(dev, 0);
                return IRQ_HANDLED;
        }
        return IRQ_NONE;
  }
  
- int r128_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
 -int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)
++int r128_enable_vblank(struct drm_device *dev, int crtc)
  {
--      unsigned int cur_vblank;
--      int ret = 0;
++      drm_r128_private_t *dev_priv = dev->dev_private;
  
--      /* Assume that the user has missed the current sequence number
--       * by about a day rather than she wants to wait for years
--       * using vertical blanks...
--       */
--      DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
--                  (((cur_vblank = atomic_read(&dev->vbl_received))
--                    - *sequence) <= (1 << 23)));
++      if (crtc != 0) {
++              DRM_ERROR("%s:  bad crtc %d\n", __FUNCTION__, crtc);
++              return -EINVAL;
++      }
  
--      *sequence = cur_vblank;
++      R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
++      return 0;
++}
++
++void r128_disable_vblank(struct drm_device *dev, int crtc)
++{
++      if (crtc != 0)
++              DRM_ERROR("%s:  bad crtc %d\n", __FUNCTION__, crtc);
  
--      return ret;
++      /*
++       * FIXME: implement proper interrupt disable by using the vblank
++       * counter register (if available)
++       *
++       * R128_WRITE(R128_GEN_INT_CNTL,
++       *            R128_READ(R128_GEN_INT_CNTL) & ~R128_CRTC_VBLANK_INT_EN);
++       */
  }
  
- void r128_driver_irq_preinstall(drm_device_t * dev)
+ void r128_driver_irq_preinstall(struct drm_device * dev)
  {
        drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
  
        R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
  }
  
- void r128_driver_irq_postinstall(drm_device_t * dev)
 -void r128_driver_irq_postinstall(struct drm_device * dev)
++int r128_driver_irq_postinstall(struct drm_device * dev)
  {
--      drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
--
--      /* Turn on VBL interrupt */
--      R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
++      return drm_vblank_init(dev, 1);
  }
  
- void r128_driver_irq_uninstall(drm_device_t * dev)
+ void r128_driver_irq_uninstall(struct drm_device * dev)
  {
        drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
        if (!dev_priv)
@@@ -355,26 -352,28 +355,28 @@@ extern int radeon_wait_ring(drm_radeon_
  
  extern int radeon_do_cp_idle(drm_radeon_private_t * dev_priv);
  
- extern int radeon_mem_alloc(DRM_IOCTL_ARGS);
- extern int radeon_mem_free(DRM_IOCTL_ARGS);
- extern int radeon_mem_init_heap(DRM_IOCTL_ARGS);
+ extern int radeon_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int radeon_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *file_priv);
  extern void radeon_mem_takedown(struct mem_block **heap);
- extern void radeon_mem_release(DRMFILE filp, struct mem_block *heap);
+ extern void radeon_mem_release(struct drm_file *file_priv,
+                              struct mem_block *heap);
  
                                /* radeon_irq.c */
- extern int radeon_irq_emit(DRM_IOCTL_ARGS);
- extern int radeon_irq_wait(DRM_IOCTL_ARGS);
- extern void radeon_do_release(drm_device_t * dev);
- extern u32 radeon_get_vblank_counter(drm_device_t *dev, int crtc);
- extern int radeon_enable_vblank(drm_device_t *dev, int crtc);
- extern void radeon_disable_vblank(drm_device_t *dev, int crtc);
+ extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern void radeon_do_release(struct drm_device * dev);
 -extern int radeon_driver_vblank_wait(struct drm_device * dev,
 -                                   unsigned int *sequence);
 -extern int radeon_driver_vblank_wait2(struct drm_device * dev,
 -                                    unsigned int *sequence);
++extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc);
++extern int radeon_enable_vblank(struct drm_device *dev, int crtc);
++extern void radeon_disable_vblank(struct drm_device *dev, int crtc);
++extern void radeon_do_release(struct drm_device * dev);
  extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS);
- extern void radeon_driver_irq_preinstall(drm_device_t * dev);
- extern int radeon_driver_irq_postinstall(drm_device_t * dev);
- extern void radeon_driver_irq_uninstall(drm_device_t * dev);
- extern int radeon_vblank_crtc_get(drm_device_t *dev);
- extern int radeon_vblank_crtc_set(drm_device_t *dev, int64_t value);
+ extern void radeon_driver_irq_preinstall(struct drm_device * dev);
 -extern void radeon_driver_irq_postinstall(struct drm_device * dev);
++extern int radeon_driver_irq_postinstall(struct drm_device * dev);
+ extern void radeon_driver_irq_uninstall(struct drm_device * dev);
+ extern int radeon_vblank_crtc_get(struct drm_device *dev);
+ extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value);
  
  extern int radeon_driver_load(struct drm_device *dev, unsigned long flags);
  extern int radeon_driver_unload(struct drm_device *dev);
  #include "radeon_drm.h"
  #include "radeon_drv.h"
  
- static void radeon_irq_set_state(drm_device_t *dev, u32 mask, int state)
 -static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv,
 -                                            u32 mask)
++static void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state)
  {
 -      u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask;
 +      drm_radeon_private_t *dev_priv = dev->dev_private;
 +
 +      if (state)
 +              dev_priv->irq_enable_reg |= mask;
 +      else
 +              dev_priv->irq_enable_reg &= ~mask;
 +
 +      RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
 +}
 +
- int radeon_enable_vblank(drm_device_t *dev, int crtc)
++int radeon_enable_vblank(struct drm_device *dev, int crtc)
 +{
 +      switch (crtc) {
 +      case 0:
 +              radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1);
 +              break;
 +      case 1:
 +              radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1);
 +              break;
 +      default:
 +              DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
 +                        crtc);
-               return DRM_ERR(EINVAL);
++              return EINVAL;
 +      }
 +
 +      return 0;
 +}
 +
- void radeon_disable_vblank(drm_device_t *dev, int crtc)
++void radeon_disable_vblank(struct drm_device *dev, int crtc)
 +{
 +      switch (crtc) {
 +      case 0:
 +              radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0);
 +              break;
 +      case 1:
 +              radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0);
 +              break;
 +      default:
 +              DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
 +                        crtc);
 +              break;
 +      }
 +}
 +
 +static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv)
 +{
 +      u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) &
 +              (RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT |
 +               RADEON_CRTC2_VBLANK_STAT);
 +
        if (irqs)
                RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs);
 +
        return irqs;
  }
  
@@@ -175,21 -144,55 +175,27 @@@ static int radeon_wait_irq(struct drm_d
        return ret;
  }
  
- u32 radeon_get_vblank_counter(drm_device_t *dev, int crtc)
 -static int radeon_driver_vblank_do_wait(struct drm_device * dev,
 -                                      unsigned int *sequence,
 -                                      int crtc)
++u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc)
  {
 -      drm_radeon_private_t *dev_priv =
 -          (drm_radeon_private_t *) dev->dev_private;
 -      unsigned int cur_vblank;
 -      int ret = 0;
 -      int ack = 0;
 -      atomic_t *counter;
 +      drm_radeon_private_t *dev_priv = dev->dev_private;
 +      u32 crtc_cnt_reg, crtc_status_reg;
 +
+       if (!dev_priv) {
+               DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+               return -EINVAL;
+       }
 -      if (crtc == DRM_RADEON_VBLANK_CRTC1) {
 -              counter = &dev->vbl_received;
 -              ack |= RADEON_CRTC_VBLANK_STAT;
 -      } else if (crtc == DRM_RADEON_VBLANK_CRTC2) {
 -              counter = &dev->vbl_received2;
 -              ack |= RADEON_CRTC2_VBLANK_STAT;
 -      } else
 +      if (crtc == 0) {
 +              crtc_cnt_reg = RADEON_CRTC_CRNT_FRAME;
 +              crtc_status_reg = RADEON_CRTC_STATUS;
 +      } else if (crtc == 1) {
 +              crtc_cnt_reg = RADEON_CRTC2_CRNT_FRAME;
 +              crtc_status_reg = RADEON_CRTC2_STATUS;
-       } else
-               return 0;
++      } else {
+               return -EINVAL;
++      }
  
 -      radeon_acknowledge_irqs(dev_priv, ack);
 -
 -      dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
 -
 -      /* Assume that the user has missed the current sequence number
 -       * by about a day rather than she wants to wait for years
 -       * using vertical blanks...
 -       */
 -      DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
 -                  (((cur_vblank = atomic_read(counter))
 -                    - *sequence) <= (1 << 23)));
 -
 -      *sequence = cur_vblank;
 -
 -      return ret;
 -}
 -
 -int radeon_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
 -{
 -      return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1);
 -}
 -
 -int radeon_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
 -{
 -      return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2);
 +      return RADEON_READ(crtc_cnt_reg) + (RADEON_READ(crtc_status_reg) & 1);
  }
  
  /* Needs the lock as it touches the ring.
@@@ -231,20 -229,30 +232,15 @@@ int radeon_irq_wait(struct drm_device *
  
        if (!dev_priv) {
                DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
-               return DRM_ERR(EINVAL);
+               return -EINVAL;
        }
  
-       DRM_COPY_FROM_USER_IOCTL(irqwait, (drm_radeon_irq_wait_t __user *) data,
-                                sizeof(irqwait));
-       return radeon_wait_irq(dev, irqwait.irq_seq);
+       return radeon_wait_irq(dev, irqwait->irq_seq);
  }
  
 -static void radeon_enable_interrupt(struct drm_device *dev)
 -{
 -      drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
 -
 -      dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE;
 -      if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1)
 -              dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK;
 -
 -      if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2)
 -              dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK;
--
 -      RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
 -      dev_priv->irq_enabled = 1;
 -}
--
  /* drm_dma.h hooks
  */
- void radeon_driver_irq_preinstall(drm_device_t * dev)
+ void radeon_driver_irq_preinstall(struct drm_device * dev)
  {
        drm_radeon_private_t *dev_priv =
            (drm_radeon_private_t *) dev->dev_private;
        RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
  
        /* Clear bits if they're already high */
 -      radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
 -                                         RADEON_CRTC_VBLANK_STAT |
 -                                         RADEON_CRTC2_VBLANK_STAT));
 +      radeon_acknowledge_irqs(dev_priv);
  }
  
- int radeon_driver_irq_postinstall(drm_device_t * dev)
 -void radeon_driver_irq_postinstall(struct drm_device * dev)
++int radeon_driver_irq_postinstall(struct drm_device * dev)
  {
        drm_radeon_private_t *dev_priv =
            (drm_radeon_private_t *) dev->dev_private;
        atomic_set(&dev_priv->swi_emitted, 0);
        DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
  
 -      radeon_enable_interrupt(dev);
 +      ret = drm_vblank_init(dev, 2);
 +      if (ret)
 +              return ret;
 +
 +      dev->max_vblank_count = 0x001fffff;
 +
 +      radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
 +
 +      return 0;
  }
  
- void radeon_driver_irq_uninstall(drm_device_t * dev)
+ void radeon_driver_irq_uninstall(struct drm_device * dev)
  {
        drm_radeon_private_t *dev_priv =
            (drm_radeon_private_t *) dev->dev_private;
@@@ -312,8 -313,9 +308,8 @@@ int radeon_vblank_crtc_set(struct drm_d
        drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
        if (value & ~(DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) {
                DRM_ERROR("called with invalid crtc 0x%x\n", (unsigned int)value);
-               return DRM_ERR(EINVAL);
+               return -EINVAL;
        }
        dev_priv->vblank_crtc = (unsigned int)value;
 -      radeon_enable_interrupt(dev);
        return 0;
  }
@@@ -83,14 -83,14 +83,16 @@@ static int probe(struct pci_dev *pdev, 
  static struct drm_driver driver = {
        .driver_features =
            DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ |
--          DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
++          DRIVER_IRQ_SHARED,
        .load = via_driver_load,
        .unload = via_driver_unload,
  #ifndef VIA_HAVE_CORE_MM
        .context_ctor = via_init_context,
  #endif
        .context_dtor = via_final_context,
--      .vblank_wait = via_driver_vblank_wait,
++      .get_vblank_counter = via_get_vblank_counter,
++      .enable_vblank = via_enable_vblank,
++      .disable_vblank = via_disable_vblank,
        .irq_preinstall = via_driver_irq_preinstall,
        .irq_postinstall = via_driver_irq_postinstall,
        .irq_uninstall = via_driver_irq_uninstall,
@@@ -102,6 -102,6 +102,7 @@@ typedef struct drm_via_private 
        struct timeval last_vblank;
        int last_vblank_valid;
        unsigned usec_per_vblank;
++      atomic_t vbl_received;
        drm_via_state_t hc_state;
        char pci_buf[VIA_PCI_BUF_SIZE];
        const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE];
@@@ -148,34 -148,34 +149,36 @@@ enum via_family 
  #define VIA_READ8(reg)                DRM_READ8(VIA_BASE, reg)
  #define VIA_WRITE8(reg,val)   DRM_WRITE8(VIA_BASE, reg, val)
  
- extern drm_ioctl_desc_t via_ioctls[];
+ extern struct drm_ioctl_desc via_ioctls[];
  extern int via_max_ioctl;
  
- extern int via_fb_init(DRM_IOCTL_ARGS);
- extern int via_mem_alloc(DRM_IOCTL_ARGS);
- extern int via_mem_free(DRM_IOCTL_ARGS);
- extern int via_agp_init(DRM_IOCTL_ARGS);
- extern int via_map_init(DRM_IOCTL_ARGS);
- extern int via_decoder_futex(DRM_IOCTL_ARGS);
- extern int via_wait_irq(DRM_IOCTL_ARGS);
- extern int via_dma_blit_sync( DRM_IOCTL_ARGS );
- extern int via_dma_blit( DRM_IOCTL_ARGS );
- extern int via_driver_load(drm_device_t *dev, unsigned long chipset);
- extern int via_driver_unload(drm_device_t *dev);
- extern int via_final_context(drm_device_t * dev, int context);
- extern int via_do_cleanup_map(drm_device_t * dev);
- extern int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence);
+ extern int via_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int via_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int via_map_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_priv );
+ extern int via_dma_blit( struct drm_device *dev, void *data, struct drm_file *file_priv );
+ extern int via_driver_load(struct drm_device *dev, unsigned long chipset);
+ extern int via_driver_unload(struct drm_device *dev);
+ extern int via_final_context(struct drm_device * dev, int context);
+ extern int via_do_cleanup_map(struct drm_device * dev);
 -extern int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
++extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc);
++extern int via_enable_vblank(struct drm_device *dev, int crtc);
++extern void via_disable_vblank(struct drm_device *dev, int crtc);
  
  extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS);
- extern void via_driver_irq_preinstall(drm_device_t * dev);
- extern void via_driver_irq_postinstall(drm_device_t * dev);
- extern void via_driver_irq_uninstall(drm_device_t * dev);
+ extern void via_driver_irq_preinstall(struct drm_device * dev);
 -extern void via_driver_irq_postinstall(struct drm_device * dev);
++extern int via_driver_irq_postinstall(struct drm_device * dev);
+ extern void via_driver_irq_uninstall(struct drm_device * dev);
  
- extern int via_dma_cleanup(drm_device_t * dev);
+ extern int via_dma_cleanup(struct drm_device * dev);
  extern void via_init_command_verifier(void);
- extern int via_driver_dma_quiescent(drm_device_t * dev);
+ extern int via_driver_dma_quiescent(struct drm_device * dev);
  extern void via_init_futex(drm_via_private_t *dev_priv);
  extern void via_cleanup_futex(drm_via_private_t *dev_priv);
  extern void via_release_futex(drm_via_private_t *dev_priv, int context);
@@@ -97,9 -97,9 +97,18 @@@ static unsigned time_diff(struct timeva
        1000000 - (then->tv_usec - now->tv_usec);
  }
  
++u32 via_get_vblank_counter(struct drm_device *dev, int crtc)
++{
++      drm_via_private_t *dev_priv = dev->dev_private;
++      if (crtc != 0)
++              return 0;
++
++      return atomic_read(&dev_priv->vbl_received);
++}
++
  irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
  {
-       drm_device_t *dev = (drm_device_t *) arg;
+       struct drm_device *dev = (struct drm_device *) arg;
        drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
        u32 status;
        int handled = 0;
  
        status = VIA_READ(VIA_REG_INTERRUPT);
        if (status & VIA_IRQ_VBLANK_PENDING) {
--              atomic_inc(&dev->vbl_received);
--              if (!(atomic_read(&dev->vbl_received) & 0x0F)) {
++              atomic_inc(&dev_priv->vbl_received);
++              if (!(atomic_read(&dev_priv->vbl_received) & 0x0F)) {
  #ifdef __linux__
                        do_gettimeofday(&cur_vblank);
  #else
                        dev_priv->last_vblank = cur_vblank;
                        dev_priv->last_vblank_valid = 1;
                }
--              if (!(atomic_read(&dev->vbl_received) & 0xFF)) {
++              if (!(atomic_read(&dev_priv->vbl_received) & 0xFF)) {
                        DRM_DEBUG("US per vblank is: %u\n",
                                dev_priv->usec_per_vblank);
                }
--              DRM_WAKEUP(&dev->vbl_queue);
--              drm_vbl_send_signals(dev);
++              drm_handle_vblank(dev, 0);
                handled = 1;
        }
        
@@@ -171,31 -171,31 +179,30 @@@ static __inline__ void viadrv_acknowled
        }
  }
  
- int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
 -int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)
++int via_enable_vblank(struct drm_device *dev, int crtc)
  {
--      drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
--      unsigned int cur_vblank;
--      int ret = 0;
++      drm_via_private_t *dev_priv = dev->dev_private;
++      u32 status;
  
--      DRM_DEBUG("viadrv_vblank_wait\n");
--      if (!dev_priv) {
--              DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
++      if (crtc != 0) {
++              DRM_ERROR("%s:  bad crtc %d\n", __FUNCTION__, crtc);
                return -EINVAL;
        }
  
--      viadrv_acknowledge_irqs(dev_priv);
++      status = VIA_READ(VIA_REG_INTERRUPT);
++      VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE);
++      return 0;
++}
  
--      /* Assume that the user has missed the current sequence number
--       * by about a day rather than she wants to wait for years
--       * using vertical blanks...
--       */
++void via_disable_vblank(struct drm_device *dev, int crtc)
++{
++      if (crtc != 0)
++              DRM_ERROR("%s:  bad crtc %d\n", __FUNCTION__, crtc);
  
--      DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
--                  (((cur_vblank = atomic_read(&dev->vbl_received)) -
--                    *sequence) <= (1 << 23)));
--      
--      *sequence = cur_vblank;
--      return ret;
++      /*
++       * FIXME: implement proper interrupt disable by using the vblank
++       * counter register (if available).
++       */
  }
  
  static int
@@@ -302,26 -302,26 +309,27 @@@ void via_driver_irq_preinstall(struct d
        }
  }
  
- void via_driver_irq_postinstall(drm_device_t * dev)
 -void via_driver_irq_postinstall(struct drm_device * dev)
++int via_driver_irq_postinstall(struct drm_device * dev)
  {
        drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
        u32 status;
  
        DRM_DEBUG("via_driver_irq_postinstall\n");
--      if (dev_priv) {
--              status = VIA_READ(VIA_REG_INTERRUPT);
--              VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
--                        | dev_priv->irq_enable_mask);
++      if (!dev_priv)
++              return -EINVAL;
  
--              /* Some magic, oh for some data sheets ! */
++      status = VIA_READ(VIA_REG_INTERRUPT);
++      VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
++                | dev_priv->irq_enable_mask);
  
--              VIA_WRITE8(0x83d4, 0x11);
--              VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
--              
--      }
++      /* Some magic, oh for some data sheets ! */
++      VIA_WRITE8(0x83d4, 0x11);
++      VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
++
++      return 0;
  }
  
- void via_driver_irq_uninstall(drm_device_t * dev)
+ void via_driver_irq_uninstall(struct drm_device * dev)
  {
        drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
        u32 status;