* Looks up the ioctl function in the ::ioctls table, checking for root
  * previleges if so required, and dispatches to the respective function.
  */
-int drm_ioctl(struct inode *inode, struct file *filp,
+long drm_ioctl(struct file *filp,
              unsigned int cmd, unsigned long arg)
 {
        struct drm_file *file_priv = filp->private_data;
-       struct drm_device *dev = file_priv->minor->dev;
+       struct drm_device *dev;
        struct drm_ioctl_desc *ioctl;
        drm_ioctl_t *func;
        unsigned int nr = DRM_IOCTL_NR(cmd);
        char stack_kdata[128];
        char *kdata = NULL;
 
+       dev = file_priv->minor->dev;
        atomic_inc(&dev->ioctl_count);
        atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
        ++file_priv->ioctl_count;
                                goto err_i1;
                        }
                }
-               retcode = func(dev, kdata, file_priv);
+               if (ioctl->flags & DRM_UNLOCKED)
+                       retcode = func(dev, kdata, file_priv);
+               else {
+                       lock_kernel();
+                       retcode = func(dev, kdata, file_priv);
+                       unlock_kernel();
+               }
 
                if (cmd & IOC_OUT) {
                        if (copy_to_user((void __user *)arg, kdata,
 
                          &version->desc))
                return -EFAULT;
 
-       err = drm_ioctl(file->f_path.dentry->d_inode, file,
+       err = drm_ioctl(file,
                        DRM_IOCTL_VERSION, (unsigned long)version);
        if (err)
                return err;
                          &u->unique))
                return -EFAULT;
 
-       err = drm_ioctl(file->f_path.dentry->d_inode, file,
-                       DRM_IOCTL_GET_UNIQUE, (unsigned long)u);
+       err = drm_ioctl(file, DRM_IOCTL_GET_UNIQUE, (unsigned long)u);
        if (err)
                return err;
 
                          &u->unique))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_SET_UNIQUE, (unsigned long)u);
+       return drm_ioctl(file, DRM_IOCTL_SET_UNIQUE, (unsigned long)u);
 }
 
 typedef struct drm_map32 {
        if (__put_user(idx, &map->offset))
                return -EFAULT;
 
-       err = drm_ioctl(file->f_path.dentry->d_inode, file,
-                       DRM_IOCTL_GET_MAP, (unsigned long)map);
+       err = drm_ioctl(file, DRM_IOCTL_GET_MAP, (unsigned long)map);
        if (err)
                return err;
 
            || __put_user(m32.flags, &map->flags))
                return -EFAULT;
 
-       err = drm_ioctl(file->f_path.dentry->d_inode, file,
-                       DRM_IOCTL_ADD_MAP, (unsigned long)map);
+       err = drm_ioctl(file, DRM_IOCTL_ADD_MAP, (unsigned long)map);
        if (err)
                return err;
 
        if (__put_user((void *)(unsigned long)handle, &map->handle))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_RM_MAP, (unsigned long)map);
+       return drm_ioctl(file, DRM_IOCTL_RM_MAP, (unsigned long)map);
 }
 
 typedef struct drm_client32 {
        if (__put_user(idx, &client->idx))
                return -EFAULT;
 
-       err = drm_ioctl(file->f_path.dentry->d_inode, file,
-                       DRM_IOCTL_GET_CLIENT, (unsigned long)client);
+       err = drm_ioctl(file, DRM_IOCTL_GET_CLIENT, (unsigned long)client);
        if (err)
                return err;
 
        if (!access_ok(VERIFY_WRITE, stats, sizeof(*stats)))
                return -EFAULT;
 
-       err = drm_ioctl(file->f_path.dentry->d_inode, file,
-                       DRM_IOCTL_GET_STATS, (unsigned long)stats);
+       err = drm_ioctl(file, DRM_IOCTL_GET_STATS, (unsigned long)stats);
        if (err)
                return err;
 
            || __put_user(agp_start, &buf->agp_start))
                return -EFAULT;
 
-       err = drm_ioctl(file->f_path.dentry->d_inode, file,
-                       DRM_IOCTL_ADD_BUFS, (unsigned long)buf);
+       err = drm_ioctl(file, DRM_IOCTL_ADD_BUFS, (unsigned long)buf);
        if (err)
                return err;
 
            || __put_user(b32.high_mark, &buf->high_mark))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_MARK_BUFS, (unsigned long)buf);
+       return drm_ioctl(file, DRM_IOCTL_MARK_BUFS, (unsigned long)buf);
 }
 
 typedef struct drm_buf_info32 {
            || __put_user(list, &request->list))
                return -EFAULT;
 
-       err = drm_ioctl(file->f_path.dentry->d_inode, file,
-                       DRM_IOCTL_INFO_BUFS, (unsigned long)request);
+       err = drm_ioctl(file, DRM_IOCTL_INFO_BUFS, (unsigned long)request);
        if (err)
                return err;
 
            || __put_user(list, &request->list))
                return -EFAULT;
 
-       err = drm_ioctl(file->f_path.dentry->d_inode, file,
-                       DRM_IOCTL_MAP_BUFS, (unsigned long)request);
+       err = drm_ioctl(file, DRM_IOCTL_MAP_BUFS, (unsigned long)request);
        if (err)
                return err;
 
                          &request->list))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_FREE_BUFS, (unsigned long)request);
+       return drm_ioctl(file, DRM_IOCTL_FREE_BUFS, (unsigned long)request);
 }
 
 typedef struct drm_ctx_priv_map32 {
                          &request->handle))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request);
+       return drm_ioctl(file, DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request);
 }
 
 static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
        if (__put_user(ctx_id, &request->ctx_id))
                return -EFAULT;
 
-       err = drm_ioctl(file->f_path.dentry->d_inode, file,
-                       DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request);
+       err = drm_ioctl(file, DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request);
        if (err)
                return err;
 
                          &res->contexts))
                return -EFAULT;
 
-       err = drm_ioctl(file->f_path.dentry->d_inode, file,
-                       DRM_IOCTL_RES_CTX, (unsigned long)res);
+       err = drm_ioctl(file, DRM_IOCTL_RES_CTX, (unsigned long)res);
        if (err)
                return err;
 
                          &d->request_sizes))
                return -EFAULT;
 
-       err = drm_ioctl(file->f_path.dentry->d_inode, file,
-                       DRM_IOCTL_DMA, (unsigned long)d);
+       err = drm_ioctl(file, DRM_IOCTL_DMA, (unsigned long)d);
        if (err)
                return err;
 
        if (put_user(m32.mode, &mode->mode))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_AGP_ENABLE, (unsigned long)mode);
+       return drm_ioctl(file, DRM_IOCTL_AGP_ENABLE, (unsigned long)mode);
 }
 
 typedef struct drm_agp_info32 {
        if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
                return -EFAULT;
 
-       err = drm_ioctl(file->f_path.dentry->d_inode, file,
-                       DRM_IOCTL_AGP_INFO, (unsigned long)info);
+       err = drm_ioctl(file, DRM_IOCTL_AGP_INFO, (unsigned long)info);
        if (err)
                return err;
 
            || __put_user(req32.type, &request->type))
                return -EFAULT;
 
-       err = drm_ioctl(file->f_path.dentry->d_inode, file,
-                       DRM_IOCTL_AGP_ALLOC, (unsigned long)request);
+       err = drm_ioctl(file, DRM_IOCTL_AGP_ALLOC, (unsigned long)request);
        if (err)
                return err;
 
        if (__get_user(req32.handle, &request->handle)
            || __get_user(req32.physical, &request->physical)
            || copy_to_user(argp, &req32, sizeof(req32))) {
-               drm_ioctl(file->f_path.dentry->d_inode, file,
-                         DRM_IOCTL_AGP_FREE, (unsigned long)request);
+               drm_ioctl(file, DRM_IOCTL_AGP_FREE, (unsigned long)request);
                return -EFAULT;
        }
 
            || __put_user(handle, &request->handle))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_AGP_FREE, (unsigned long)request);
+       return drm_ioctl(file, DRM_IOCTL_AGP_FREE, (unsigned long)request);
 }
 
 typedef struct drm_agp_binding32 {
            || __put_user(req32.offset, &request->offset))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_AGP_BIND, (unsigned long)request);
+       return drm_ioctl(file, DRM_IOCTL_AGP_BIND, (unsigned long)request);
 }
 
 static int compat_drm_agp_unbind(struct file *file, unsigned int cmd,
            || __put_user(handle, &request->handle))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_AGP_UNBIND, (unsigned long)request);
+       return drm_ioctl(file, DRM_IOCTL_AGP_UNBIND, (unsigned long)request);
 }
 #endif                         /* __OS_HAS_AGP */
 
            || __put_user(x, &request->size))
                return -EFAULT;
 
-       err = drm_ioctl(file->f_path.dentry->d_inode, file,
-                       DRM_IOCTL_SG_ALLOC, (unsigned long)request);
+       err = drm_ioctl(file, DRM_IOCTL_SG_ALLOC, (unsigned long)request);
        if (err)
                return err;
 
            || __put_user(x << PAGE_SHIFT, &request->handle))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_SG_FREE, (unsigned long)request);
+       return drm_ioctl(file, DRM_IOCTL_SG_FREE, (unsigned long)request);
 }
 
 #if defined(CONFIG_X86) || defined(CONFIG_IA64)
            __put_user(update32.data, &request->data))
                return -EFAULT;
 
-       err = drm_ioctl(file->f_path.dentry->d_inode, file,
-                       DRM_IOCTL_UPDATE_DRAW, (unsigned long)request);
+       err = drm_ioctl(file, DRM_IOCTL_UPDATE_DRAW, (unsigned long)request);
        return err;
 }
 #endif
            || __put_user(req32.request.signal, &request->request.signal))
                return -EFAULT;
 
-       err = drm_ioctl(file->f_path.dentry->d_inode, file,
-                       DRM_IOCTL_WAIT_VBLANK, (unsigned long)request);
+       err = drm_ioctl(file, DRM_IOCTL_WAIT_VBLANK, (unsigned long)request);
        if (err)
                return err;
 
         * than always failing.
         */
        if (nr >= ARRAY_SIZE(drm_compat_ioctls))
-               return drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+               return drm_ioctl(filp, cmd, arg);
 
        fn = drm_compat_ioctls[nr];
 
-       lock_kernel();          /* XXX for now */
        if (fn != NULL)
                ret = (*fn) (filp, cmd, arg);
        else
-               ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
-       unlock_kernel();
+               ret = drm_ioctl(filp, cmd, arg);
 
        return ret;
 }
 
 static const struct file_operations i810_buffer_fops = {
        .open = drm_open,
        .release = drm_release,
-       .ioctl = drm_ioctl,
+       .unlocked_ioctl = drm_ioctl,
        .mmap = i810_mmap_buffers,
        .fasync = drm_fasync,
 };
 
                 .owner = THIS_MODULE,
                 .open = drm_open,
                 .release = drm_release,
-                .ioctl = drm_ioctl,
+                .unlocked_ioctl = drm_ioctl,
                 .mmap = drm_mmap,
                 .poll = drm_poll,
                 .fasync = drm_fasync,
 
 static const struct file_operations i830_buffer_fops = {
        .open = drm_open,
        .release = drm_release,
-       .ioctl = drm_ioctl,
+       .unlocked_ioctl = drm_ioctl,
        .mmap = i830_mmap_buffers,
        .fasync = drm_fasync,
 };
 
                 .owner = THIS_MODULE,
                 .open = drm_open,
                 .release = drm_release,
-                .ioctl = drm_ioctl,
+                .unlocked_ioctl = drm_ioctl,
                 .mmap = drm_mmap,
                 .poll = drm_poll,
                 .fasync = drm_fasync,
 
                 .owner = THIS_MODULE,
                 .open = drm_open,
                 .release = drm_release,
-                .ioctl = drm_ioctl,
+                .unlocked_ioctl = drm_ioctl,
                 .mmap = drm_gem_mmap,
                 .poll = drm_poll,
                 .fasync = drm_fasync,
 
                          &batchbuffer->cliprects))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_I915_BATCHBUFFER,
+       return drm_ioctl(file, DRM_IOCTL_I915_BATCHBUFFER,
                         (unsigned long)batchbuffer);
 }
 
                          &cmdbuffer->cliprects))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_I915_CMDBUFFER, (unsigned long)cmdbuffer);
+       return drm_ioctl(file, DRM_IOCTL_I915_CMDBUFFER,
+                        (unsigned long)cmdbuffer);
 }
 
 typedef struct drm_i915_irq_emit32 {
                          &request->irq_seq))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_I915_IRQ_EMIT, (unsigned long)request);
+       return drm_ioctl(file, DRM_IOCTL_I915_IRQ_EMIT,
+                        (unsigned long)request);
 }
 typedef struct drm_i915_getparam32 {
        int param;
                          &request->value))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_I915_GETPARAM, (unsigned long)request);
+       return drm_ioctl(file, DRM_IOCTL_I915_GETPARAM,
+                        (unsigned long)request);
 }
 
 typedef struct drm_i915_mem_alloc32 {
                          &request->region_offset))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_I915_ALLOC, (unsigned long)request);
+       return drm_ioctl(file, DRM_IOCTL_I915_ALLOC,
+                        (unsigned long)request);
 }
 
 drm_ioctl_compat_t *i915_compat_ioctls[] = {
        if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls))
                fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE];
 
-       lock_kernel();          /* XXX for now */
        if (fn != NULL)
                ret = (*fn) (filp, cmd, arg);
        else
-               ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
-       unlock_kernel();
+               ret = drm_ioctl(filp, cmd, arg);
 
        return ret;
 }
 
                .owner = THIS_MODULE,
                .open = drm_open,
                .release = drm_release,
-               .ioctl = drm_ioctl,
+               .unlocked_ioctl = drm_ioctl,
                .mmap = drm_mmap,
                .poll = drm_poll,
                .fasync = drm_fasync,
 
        if (err)
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_MGA_INIT, (unsigned long)init);
+       return drm_ioctl(file, DRM_IOCTL_MGA_INIT, (unsigned long)init);
 }
 
 typedef struct drm_mga_getparam32 {
                          &getparam->value))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam);
+       return drm_ioctl(file, DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam);
 }
 
 typedef struct drm_mga_drm_bootstrap32 {
            || __put_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size))
                return -EFAULT;
 
-       err = drm_ioctl(file->f_path.dentry->d_inode, file,
-                       DRM_IOCTL_MGA_DMA_BOOTSTRAP,
+       err = drm_ioctl(file, DRM_IOCTL_MGA_DMA_BOOTSTRAP,
                        (unsigned long)dma_bootstrap);
        if (err)
                return err;
        if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls))
                fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE];
 
-       lock_kernel();          /* XXX for now */
        if (fn != NULL)
                ret = (*fn) (filp, cmd, arg);
        else
-               ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
-       unlock_kernel();
+               ret = drm_ioctl(filp, cmd, arg);
 
        return ret;
 }
 
                .owner = THIS_MODULE,
                .open = drm_open,
                .release = drm_release,
-               .ioctl = drm_ioctl,
+               .unlocked_ioctl = drm_ioctl,
                .mmap = nouveau_ttm_mmap,
                .poll = drm_poll,
                .fasync = drm_fasync,
 
        if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls))
                fn = nouveau_compat_ioctls[nr - DRM_COMMAND_BASE];
 #endif
-       lock_kernel();    /* XXX for now */
        if (fn != NULL)
                ret = (*fn)(filp, cmd, arg);
        else
-               ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
-       unlock_kernel();
+               ret = drm_ioctl(filp, cmd, arg);
 
        return ret;
 }
 
                .owner = THIS_MODULE,
                .open = drm_open,
                .release = drm_release,
-               .ioctl = drm_ioctl,
+               .unlocked_ioctl = drm_ioctl,
                .mmap = drm_mmap,
                .poll = drm_poll,
                .fasync = drm_fasync,
 
                          &init->agp_textures_offset))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_R128_INIT, (unsigned long)init);
+       return drm_ioctl(file, DRM_IOCTL_R128_INIT, (unsigned long)init);
 }
 
 typedef struct drm_r128_depth32 {
                          &depth->mask))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_R128_DEPTH, (unsigned long)depth);
+       return drm_ioctl(file, DRM_IOCTL_R128_DEPTH, (unsigned long)depth);
 
 }
 
                          &stipple->mask))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_R128_STIPPLE, (unsigned long)stipple);
+       return drm_ioctl(file, DRM_IOCTL_R128_STIPPLE, (unsigned long)stipple);
 }
 
 typedef struct drm_r128_getparam32 {
                          &getparam->value))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam);
+       return drm_ioctl(file, DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam);
 }
 
 drm_ioctl_compat_t *r128_compat_ioctls[] = {
        if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(r128_compat_ioctls))
                fn = r128_compat_ioctls[nr - DRM_COMMAND_BASE];
 
-       lock_kernel();          /* XXX for now */
        if (fn != NULL)
                ret = (*fn) (filp, cmd, arg);
        else
-               ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
-       unlock_kernel();
+               ret = drm_ioctl(filp, cmd, arg);
 
        return ret;
 }
 
                 .owner = THIS_MODULE,
                 .open = drm_open,
                 .release = drm_release,
-                .ioctl = drm_ioctl,
+                .unlocked_ioctl = drm_ioctl,
                 .mmap = drm_mmap,
                 .poll = drm_poll,
                 .fasync = drm_fasync,
                 .owner = THIS_MODULE,
                 .open = drm_open,
                 .release = drm_release,
-                .ioctl = drm_ioctl,
+                .unlocked_ioctl = drm_ioctl,
                 .mmap = radeon_mmap,
                 .poll = drm_poll,
                 .fasync = drm_fasync,
 
                          &init->gart_textures_offset))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init);
+       return drm_ioctl(file, DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init);
 }
 
 typedef struct drm_radeon_clear32 {
                          &clr->depth_boxes))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr);
+       return drm_ioctl(file, DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr);
 }
 
 typedef struct drm_radeon_stipple32 {
                          &request->mask))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request);
+       return drm_ioctl(file, DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request);
 }
 
 typedef struct drm_radeon_tex_image32 {
                          &image->data))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request);
+       return drm_ioctl(file, DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request);
 }
 
 typedef struct drm_radeon_vertex2_32 {
                          &request->prim))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request);
+       return drm_ioctl(file, DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request);
 }
 
 typedef struct drm_radeon_cmd_buffer32 {
                          &request->boxes))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request);
+       return drm_ioctl(file, DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request);
 }
 
 typedef struct drm_radeon_getparam32 {
                          &request->value))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request);
+       return drm_ioctl(file, DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request);
 }
 
 typedef struct drm_radeon_mem_alloc32 {
                          &request->region_offset))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_RADEON_ALLOC, (unsigned long)request);
+       return drm_ioctl(file, DRM_IOCTL_RADEON_ALLOC, (unsigned long)request);
 }
 
 typedef struct drm_radeon_irq_emit32 {
                          &request->irq_seq))
                return -EFAULT;
 
-       return drm_ioctl(file->f_path.dentry->d_inode, file,
-                        DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request);
+       return drm_ioctl(file, DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request);
 }
 
 /* The two 64-bit arches where alignof(u64)==4 in 32-bit code */
                          &request->value))
                return -EFAULT;
 
-       return drm_ioctl(file->f_dentry->d_inode, file,
-                        DRM_IOCTL_RADEON_SETPARAM, (unsigned long) request);
+       return drm_ioctl(file, DRM_IOCTL_RADEON_SETPARAM, (unsigned long) request);
 }
 #else
 #define compat_radeon_cp_setparam NULL
        if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_ioctls))
                fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE];
 
-       lock_kernel();          /* XXX for now */
        if (fn != NULL)
                ret = (*fn) (filp, cmd, arg);
        else
-               ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
-       unlock_kernel();
+               ret = drm_ioctl(filp, cmd, arg);
 
        return ret;
 }
        if (nr < DRM_COMMAND_BASE)
                return drm_compat_ioctl(filp, cmd, arg);
 
-       lock_kernel();          /* XXX for now */
-       ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
-       unlock_kernel();
+       ret = drm_ioctl(filp, cmd, arg);
 
        return ret;
 }
 
                 .owner = THIS_MODULE,
                 .open = drm_open,
                 .release = drm_release,
-                .ioctl = drm_ioctl,
+                .unlocked_ioctl = drm_ioctl,
                 .mmap = drm_mmap,
                 .poll = drm_poll,
                 .fasync = drm_fasync,
 
                 .owner = THIS_MODULE,
                 .open = drm_open,
                 .release = drm_release,
-                .ioctl = drm_ioctl,
+                .unlocked_ioctl = drm_ioctl,
                 .mmap = drm_mmap,
                 .poll = drm_poll,
                 .fasync = drm_fasync,
 
                 .owner = THIS_MODULE,
                 .open = drm_open,
                 .release = drm_release,
-                .ioctl = drm_ioctl,
+                .unlocked_ioctl = drm_ioctl,
                 .mmap = drm_mmap,
                 .poll = drm_poll,
                 .fasync = drm_fasync,
 
                .owner = THIS_MODULE,
                .open = drm_open,
                .release = drm_release,
-               .ioctl = drm_ioctl,
+               .unlocked_ioctl = drm_ioctl,
                .mmap = drm_mmap,
                .poll = drm_poll,
                .fasync = drm_fasync,
 
 #define        DRM_MASTER      0x2
 #define DRM_ROOT_ONLY  0x4
 #define DRM_CONTROL_ALLOW 0x8
+#define DRM_UNLOCKED   0x10
 
 struct drm_ioctl_desc {
        unsigned int cmd;
                                /* Driver support (drm_drv.h) */
 extern int drm_init(struct drm_driver *driver);
 extern void drm_exit(struct drm_driver *driver);
-extern int drm_ioctl(struct inode *inode, struct file *filp,
-                    unsigned int cmd, unsigned long arg);
+extern long drm_ioctl(struct file *filp,
+                     unsigned int cmd, unsigned long arg);
 extern long drm_compat_ioctl(struct file *filp,
                             unsigned int cmd, unsigned long arg);
 extern int drm_lastclose(struct drm_device *dev);