Merge branch 'master' into modesetting-101 - TTM & typedef removal
authorJesse Barnes <jbarnes@jbarnes-mobile.amr.corp.intel.com>
Mon, 24 Sep 2007 21:41:46 +0000 (14:41 -0700)
committerJesse Barnes <jbarnes@jbarnes-mobile.amr.corp.intel.com>
Mon, 24 Sep 2007 21:41:46 +0000 (14:41 -0700)
Conflicts:

linux-core/drmP.h
linux-core/drm_bo.c
linux-core/drm_drv.c
linux-core/drm_objects.h
shared-core/drm.h
shared-core/i915_dma.c
shared-core/i915_drv.h
shared-core/i915_irq.c

Mostly removing typedefs that snuck into the modesetting code and
updating to the latest TTM APIs.  As of today, the i915 driver builds,
but there are likely to be problems, so debugging and bugfixes will
come next.

30 files changed:
1  2 
linux-core/Makefile.kernel
linux-core/drmP.h
linux-core/drm_bo.c
linux-core/drm_bo_move.c
linux-core/drm_bufs.c
linux-core/drm_compat.h
linux-core/drm_crtc.c
linux-core/drm_crtc.h
linux-core/drm_drv.c
linux-core/drm_edid.c
linux-core/drm_fops.c
linux-core/drm_objects.h
linux-core/drm_stub.c
linux-core/i915_buffer.c
linux-core/i915_drv.c
linux-core/i915_fence.c
linux-core/intel_crt.c
linux-core/intel_display.c
linux-core/intel_drv.h
linux-core/intel_fb.c
linux-core/intel_i2c.c
linux-core/intel_lvds.c
linux-core/intel_sdvo.c
shared-core/drm.h
shared-core/i915_dma.c
shared-core/i915_drm.h
shared-core/i915_drv.h
shared-core/i915_init.c
shared-core/i915_irq.c
shared-core/i915_mem.c

@@@ -20,10 -19,10 +20,11 @@@ r128-objs   := r128_drv.o r128_cce.o r1
  mga-objs    := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o
  i810-objs   := i810_drv.o i810_dma.o
  i915-objs   := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_fence.o \
 -              i915_buffer.o
 +              i915_buffer.o intel_display.o intel_crt.o intel_lvds.o \
 +              intel_sdvo.o intel_modes.o intel_i2c.o i915_init.o intel_fb.o
  nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \
                nouveau_object.o nouveau_irq.o nouveau_notifier.o \
+               nouveau_sgdma.o nouveau_dma.o \
                nv04_timer.o \
                nv04_mc.o nv40_mc.o nv50_mc.o \
                nv04_fb.o nv10_fb.o nv40_fb.o \
@@@ -424,14 -430,13 +432,15 @@@ struct drm_file 
        struct list_head refd_objects;
        struct list_head user_objects;
  
-       drm_open_hash_t refd_object_hash[_DRM_NO_REF_TYPES];
+       struct drm_open_hash refd_object_hash[_DRM_NO_REF_TYPES];
+       struct file *filp;
        void *driver_priv;
- } drm_file_t;
 +
 +      struct list_head fbs;
+ };
  
  /** Wait queue */
typedef struct drm_queue {
+ struct drm_queue {
        atomic_t use_count;             /**< Outstanding uses (+1) */
        atomic_t finalization;          /**< Finalization in progress */
        atomic_t block_count;           /**< Count of processes waiting */
@@@ -653,19 -650,16 +654,20 @@@ struct drm_driver 
        void (*irq_preinstall) (struct drm_device * dev);
        void (*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);
  
 +      /* FB routines, if present */
 +      int (*fb_probe)(struct drm_device *dev, struct drm_crtc *crtc);
 +      int (*fb_remove)(struct drm_device *dev, struct drm_crtc *crtc);
 +
        struct drm_fence_driver *fence_driver;
        struct drm_bo_driver *bo_driver;
  
@@@ -834,14 -828,11 +836,14 @@@ struct drm_device 
        spinlock_t drw_lock;
        struct idr drw_idr;
        /*@} */
- } drm_device_t;
 +
 +      /* DRM mode setting */
 +      struct drm_mode_config mode_config;
+ };
  
  #if __OS_HAS_AGP
typedef struct drm_agp_ttm_backend {
-         drm_ttm_backend_t backend;
+ struct drm_agp_ttm_backend {
+       struct drm_ttm_backend backend;
        DRM_AGP_MEM *mem;
        struct agp_bridge_data *bridge;
        int populated;
@@@ -504,12 -503,12 +503,13 @@@ void drm_bo_usage_deref_locked(struct d
                drm_bo_destroy_locked(tmp_bo);
        }
  }
 +EXPORT_SYMBOL(drm_bo_usage_deref_locked);
  
- static void drm_bo_base_deref_locked(drm_file_t * priv, drm_user_object_t * uo)
+ static void drm_bo_base_deref_locked(struct drm_file * file_priv,
+                                    struct drm_user_object * uo)
  {
-       drm_buffer_object_t *bo =
-           drm_user_object_entry(uo, drm_buffer_object_t, base);
+       struct drm_buffer_object *bo =
+           drm_user_object_entry(uo, struct drm_buffer_object, base);
  
        DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
  
@@@ -1805,6 -1968,119 +1969,120 @@@ int drm_bo_wait_idle_ioctl(struct drm_d
  }
  
  /**
 -static int
+  * Pins or unpins the given buffer object in the given memory area.
+  *
+  * Pinned buffers will not be evicted from or move within their memory area.
+  * Must be called with the hardware lock held for pinning.
+  */
++int
+ drm_bo_set_pin(struct drm_device *dev, struct drm_buffer_object *bo,
+     int pin)
+ {
+       int ret = 0;
+       mutex_lock(&bo->mutex);
+       if (bo->pinned == pin) {
+               mutex_unlock(&bo->mutex);
+               return 0;
+       }
+       if (pin) {
+               ret = drm_bo_wait_unfenced(bo, 0, 0);
+               if (ret) {
+                       mutex_unlock(&bo->mutex);
+                       return ret;
+               }
+               /* Validate the buffer into its pinned location, with no
+                * pending fence.
+                */
+               ret = drm_buffer_object_validate(bo, bo->fence_class, 0, 0);
+               if (ret) {
+                       mutex_unlock(&bo->mutex);
+                       return ret;
+               }
+               /* Pull the buffer off of the LRU and add it to the pinned
+                * list
+                */
+               bo->pinned_mem_type = bo->mem.mem_type;
+               mutex_lock(&dev->struct_mutex);
+               list_del_init(&bo->lru);
+               list_del_init(&bo->pinned_lru);
+               drm_bo_add_to_pinned_lru(bo);
+               if (bo->pinned_node != bo->mem.mm_node) {
+                       if (bo->pinned_node != NULL)
+                               drm_mm_put_block(bo->pinned_node);
+                       bo->pinned_node = bo->mem.mm_node;
+               }
+               bo->pinned = pin;
+               mutex_unlock(&dev->struct_mutex);
+       } else {
+               mutex_lock(&dev->struct_mutex);
+               /* Remove our buffer from the pinned list */
+               if (bo->pinned_node != bo->mem.mm_node)
+                       drm_mm_put_block(bo->pinned_node);
+               list_del_init(&bo->pinned_lru);
+               bo->pinned_node = NULL;
+               bo->pinned = pin;
+               mutex_unlock(&dev->struct_mutex);
+       }
+       mutex_unlock(&bo->mutex);
+       return 0;
+ }
++EXPORT_SYMBOL(drm_bo_set_pin);
+ int drm_bo_set_pin_ioctl(struct drm_device *dev, void *data,
+                        struct drm_file *file_priv)
+ {
+       struct drm_bo_set_pin_arg *arg = data;
+       struct drm_bo_set_pin_req *req = &arg->d.req;
+       struct drm_bo_info_rep *rep = &arg->d.rep;
+       struct drm_buffer_object *bo;
+       int ret;
+       DRM_DEBUG("drm_bo_set_pin_ioctl: buffer %d, pin %d\n",
+           req->handle, req->pin);
+       if (!dev->bm.initialized) {
+               DRM_ERROR("Buffer object manager is not initialized.\n");
+               return -EINVAL;
+       }
+       if (req->pin < 0 || req->pin > 1) {
+               DRM_ERROR("Bad arguments to set_pin\n");
+               return -EINVAL;
+       }
+       if (req->pin)
+               LOCK_TEST_WITH_RETURN(dev, file_priv);
+       mutex_lock(&dev->struct_mutex);
+       bo = drm_lookup_buffer_object(file_priv, req->handle, 1);
+       mutex_unlock(&dev->struct_mutex);
+       if (!bo) {
+               return -EINVAL;
+       }
+       ret = drm_bo_set_pin(dev, bo, req->pin);
+       if (ret) {
+               drm_bo_usage_deref_unlocked(&bo);
+               return ret;
+       }
+       drm_bo_fill_rep_arg(bo, rep);
+       drm_bo_usage_deref_unlocked(&bo);
+       return 0;
+ }
+ /**
   *Clean the unfenced list and put on regular LRU.
   *This is part of the memory manager cleanup and should only be
   *called with the DRI lock held.
@@@ -2134,12 -2408,11 +2411,12 @@@ int drm_bo_driver_finish(struct drm_dev
        mutex_unlock(&dev->bm.init_mutex);
        return ret;
  }
 +EXPORT_SYMBOL(drm_bo_driver_finish);
  
- int drm_bo_driver_init(drm_device_t * dev)
+ int drm_bo_driver_init(struct drm_device * dev)
  {
-       drm_bo_driver_t *driver = dev->driver->bo_driver;
-       drm_buffer_manager_t *bm = &dev->bm;
+       struct drm_bo_driver *driver = dev->driver->bo_driver;
+       struct drm_buffer_manager *bm = &dev->bm;
        int ret = -EINVAL;
  
        mutex_lock(&dev->bm.init_mutex);
Simple merge
Simple merge
Simple merge
index df00a7d,0000000..ed5f1df
mode 100644,000000..100644
--- /dev/null
@@@ -1,1930 -1,0 +1,1908 @@@
- struct drm_framebuffer *drm_framebuffer_create(drm_device_t *dev)
 +/*
 + * Copyright (c) 2006-2007 Intel Corporation
 + * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
 + *
 + * DRM core CRTC related functions
 + *
 + * Permission to use, copy, modify, distribute, and sell this software and its
 + * documentation for any purpose is hereby granted without fee, provided that
 + * the above copyright notice appear in all copies and that both that copyright
 + * notice and this permission notice appear in supporting documentation, and
 + * that the name of the copyright holders not be used in advertising or
 + * publicity pertaining to distribution of the software without specific,
 + * written prior permission.  The copyright holders make no representations
 + * about the suitability of this software for any purpose.  It is provided "as
 + * is" without express or implied warranty.
 + *
 + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 + * OF THIS SOFTWARE.
 + *
 + * Authors:
 + *      Keith Packard
 + *    Eric Anholt <eric@anholt.net>
 + *      Dave Airlie <airlied@linux.ie>
 + *      Jesse Barnes <jesse.barnes@intel.com>
 + */
 +#include <linux/list.h>
 +#include "drm.h"
 +#include "drmP.h"
 +#include "drm_crtc.h"
 +
 +/**
 + * drm_idr_get - allocate a new identifier
 + * @dev: DRM device
 + * @ptr: object pointer, used to generate unique ID
 + *
 + * LOCKING:
 + * Caller must hold DRM mode_config lock.
 + *
 + * Create a unique identifier based on @ptr in @dev's identifier space.  Used
 + * for tracking modes, CRTCs and outputs.
 + *
 + * RETURNS:
 + * New unique (relative to other objects in @dev) integer identifier for the
 + * object.
 + */
 +int drm_idr_get(struct drm_device *dev, void *ptr)
 +{
 +      int new_id = 0;
 +      int ret;
 +again:
 +      if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
 +              DRM_ERROR("Ran out memory getting a mode number\n");
 +              return 0;
 +      }
 +
 +      ret = idr_get_new_above(&dev->mode_config.crtc_idr, ptr, 1, &new_id);
 +      if (ret == -EAGAIN)
 +              goto again;     
 +
 +      return new_id;
 +}
 +
 +/**
 + * drm_idr_put - free an identifer
 + * @dev: DRM device
 + * @id: ID to free
 + *
 + * LOCKING:
 + * Caller must hold DRM mode_config lock.
 + *
 + * Free @id from @dev's unique identifier pool.
 + */
 +void drm_idr_put(struct drm_device *dev, int id)
 +{
 +      idr_remove(&dev->mode_config.crtc_idr, id);
 +}
 +
 +/**
 + * drm_crtc_from_fb - find the CRTC structure associated with an fb
 + * @dev: DRM device
 + * @fb: framebuffer in question
 + *
 + * LOCKING:
 + * Caller must hold mode_config lock.
 + *
 + * Find CRTC in the mode_config structure that matches @fb.
 + *
 + * RETURNS:
 + * Pointer to the CRTC or NULL if it wasn't found.
 + */
 +struct drm_crtc *drm_crtc_from_fb(struct drm_device *dev,
 +                                struct drm_framebuffer *fb)
 +{
 +      struct drm_crtc *crtc;
 +
 +      list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 +              if (crtc->fb == fb)
 +                      return crtc;
 +      }
 +      return NULL;
 +}
 +
 +/**
 + * drm_framebuffer_create - create a new framebuffer object
 + * @dev: DRM device
 + *
 + * LOCKING:
 + * Caller must hold mode config lock.
 + *
 + * Creates a new framebuffer objects and adds it to @dev's DRM mode_config.
 + *
 + * RETURNS:
 + * Pointer to new framebuffer or NULL on error.
 + */
-       drm_device_t *dev = fb->dev;
++struct drm_framebuffer *drm_framebuffer_create(struct drm_device *dev)
 +{
 +      struct drm_framebuffer *fb;
 +
 +      /* Limit to single framebuffer for now */
 +      if (dev->mode_config.num_fb > 1) {
 +              mutex_unlock(&dev->mode_config.mutex);
 +              DRM_ERROR("Attempt to add multiple framebuffers failed\n");
 +              return NULL;
 +      }
 +
 +      fb = kzalloc(sizeof(struct drm_framebuffer), GFP_KERNEL);
 +      if (!fb)
 +              return NULL;
 +      
 +      fb->id = drm_idr_get(dev, fb);
 +      fb->dev = dev;
 +      dev->mode_config.num_fb++;
 +      list_add(&fb->head, &dev->mode_config.fb_list);
 +
 +      return fb;
 +}
 +EXPORT_SYMBOL(drm_framebuffer_create);
 +
 +/**
 + * drm_framebuffer_destroy - remove a framebuffer object
 + * @fb: framebuffer to remove
 + *
 + * LOCKING:
 + * Caller must hold mode config lock.
 + *
 + * Scans all the CRTCs in @dev's mode_config.  If they're using @fb, removes
 + * it, setting it to NULL.
 + */
 +void drm_framebuffer_destroy(struct drm_framebuffer *fb)
 +{
- struct drm_crtc *drm_crtc_create(drm_device_t *dev,
++      struct drm_device *dev = fb->dev;
 +      struct drm_crtc *crtc;
 +
 +      /* remove from any CRTC */
 +      list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 +              if (crtc->fb == fb)
 +                      crtc->fb = NULL;
 +      }
 +
 +      drm_idr_put(dev, fb->id);
 +      list_del(&fb->head);
 +      dev->mode_config.num_fb--;
 +
 +      kfree(fb);
 +}
 +EXPORT_SYMBOL(drm_framebuffer_destroy);
 +
 +/**
 + * drm_crtc_create - create a new CRTC object
 + * @dev: DRM device
 + * @funcs: callbacks for the new CRTC
 + *
 + * LOCKING:
 + * Caller must hold mode config lock.
 + *
 + * Creates a new CRTC object and adds it to @dev's mode_config structure.
 + *
 + * RETURNS:
 + * Pointer to new CRTC object or NULL on error.
 + */
-       drm_device_t *dev = crtc->dev;
++struct drm_crtc *drm_crtc_create(struct drm_device *dev,
 +                               const struct drm_crtc_funcs *funcs)
 +{
 +      struct drm_crtc *crtc;
 +
 +      crtc = kzalloc(sizeof(struct drm_crtc), GFP_KERNEL);
 +      if (!crtc)
 +              return NULL;
 +
 +      crtc->dev = dev;
 +      crtc->funcs = funcs;
 +
 +      crtc->id = drm_idr_get(dev, crtc);
 +
 +      list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
 +      dev->mode_config.num_crtc++;
 +
 +      return crtc;
 +}
 +EXPORT_SYMBOL(drm_crtc_create);
 +
 +/**
 + * drm_crtc_destroy - remove a CRTC object
 + * @crtc: CRTC to remove
 + *
 + * LOCKING:
 + * Caller must hold mode config lock.
 + *
 + * Cleanup @crtc.  Calls @crtc's cleanup function, then removes @crtc from
 + * its associated DRM device's mode_config.  Frees it afterwards.
 + */
 +void drm_crtc_destroy(struct drm_crtc *crtc)
 +{
-       drm_device_t *dev = crtc->dev;
++      struct drm_device *dev = crtc->dev;
 +
 +      if (crtc->funcs->cleanup)
 +              (*crtc->funcs->cleanup)(crtc);
 +
 +      drm_idr_put(dev, crtc->id);
 +      list_del(&crtc->head);
 +      dev->mode_config.num_crtc--;
 +      kfree(crtc);
 +}
 +EXPORT_SYMBOL(drm_crtc_destroy);
 +
 +/**
 + * drm_crtc_in_use - check if a given CRTC is in a mode_config
 + * @crtc: CRTC to check
 + *
 + * LOCKING:
 + * Caller must hold mode config lock.
 + *
 + * Walk @crtc's DRM device's mode_config and see if it's in use.
 + *
 + * RETURNS:
 + * True if @crtc is part of the mode_config, false otherwise.
 + */
 +bool drm_crtc_in_use(struct drm_crtc *crtc)
 +{
 +      struct drm_output *output;
-       drm_device_t *dev = crtc->dev;
++      struct drm_device *dev = crtc->dev;
 +      /* FIXME: Locking around list access? */
 +      list_for_each_entry(output, &dev->mode_config.output_list, head)
 +              if (output->crtc == crtc)
 +                      return true;
 +      return false;
 +}
 +EXPORT_SYMBOL(drm_crtc_in_use);
 +
 +/*
 + * Detailed mode info for a standard 640x480@60Hz monitor
 + */
 +static struct drm_display_mode std_mode[] = {
 +      { DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 25200, 640, 656,
 +                 752, 800, 0, 480, 490, 492, 525, 0,
 +                 V_NHSYNC | V_NVSYNC) }, /* 640x480@60Hz */
 +};
 +
 +/**
 + * drm_crtc_probe_output_modes - get complete set of display modes
 + * @dev: DRM device
 + * @maxX: max width for modes
 + * @maxY: max height for modes
 + *
 + * LOCKING:
 + * Caller must hold mode config lock.
 + *
 + * Based on @dev's mode_config layout, scan all the outputs and try to detect
 + * modes on them.  Modes will first be added to the output's probed_modes
 + * list, then culled (based on validity and the @maxX, @maxY parameters) and
 + * put into the normal modes list.
 + *
 + * Intended to be used either at bootup time or when major configuration
 + * changes have occurred.
 + *
 + * FIXME: take into account monitor limits
 + */
 +void drm_crtc_probe_output_modes(struct drm_device *dev, int maxX, int maxY)
 +{
 +      struct drm_output *output;
 +      struct drm_display_mode *mode, *t;
 +      int ret;
 +      //if (maxX == 0 || maxY == 0) 
 +      // TODO
 +
 +      list_for_each_entry(output, &dev->mode_config.output_list, head) {
 +
 +              /* set all modes to the unverified state */
 +              list_for_each_entry_safe(mode, t, &output->modes, head)
 +                      mode->status = MODE_UNVERIFIED;
 +              
 +              output->status = (*output->funcs->detect)(output);
 +
 +              if (output->status == output_status_disconnected) {
 +                      DRM_DEBUG("%s is disconnected\n", output->name);
 +                      /* TODO set EDID to NULL */
 +                      continue;
 +              }
 +
 +              ret = (*output->funcs->get_modes)(output);
 +
 +              if (ret) {
 +                      drm_mode_output_list_update(output);
 +              }
 +
 +              if (maxX && maxY)
 +                      drm_mode_validate_size(dev, &output->modes, maxX,
 +                                             maxY, 0);
 +              list_for_each_entry_safe(mode, t, &output->modes, head) {
 +                      if (mode->status == MODE_OK)
 +                              mode->status = (*output->funcs->mode_valid)(output,mode);
 +              }
 +              
 +
 +              drm_mode_prune_invalid(dev, &output->modes, TRUE);
 +
 +              if (list_empty(&output->modes)) {
 +                      struct drm_display_mode *stdmode;
 +
 +                      DRM_DEBUG("No valid modes on %s\n", output->name);
 +
 +                      /* Should we do this here ???
 +                       * When no valid EDID modes are available we end up
 +                       * here and bailed in the past, now we add a standard
 +                       * 640x480@60Hz mode and carry on.
 +                       */
 +                      stdmode = drm_mode_duplicate(dev, &std_mode[0]);
 +                      drm_mode_probed_add(output, stdmode);
 +                      drm_mode_list_concat(&output->probed_modes,
 +                                           &output->modes);
 +
 +                      DRM_DEBUG("Adding standard 640x480 @ 60Hz to %s\n",
 +                                                              output->name);
 +              }
 +
 +              drm_mode_sort(&output->modes);
 +
 +              DRM_DEBUG("Probed modes for %s\n", output->name);
 +              list_for_each_entry_safe(mode, t, &output->modes, head) {
 +                      mode->vrefresh = drm_mode_vrefresh(mode);
 +
 +                      drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
 +                      drm_mode_debug_printmodeline(dev, mode);
 +              }
 +      }
 +}
 +
 +/**
 + * drm_crtc_set_mode - set a mode
 + * @crtc: CRTC to program
 + * @mode: mode to use
 + * @x: width of mode
 + * @y: height of mode
 + *
 + * LOCKING:
 + * Caller must hold mode config lock.
 + *
 + * Try to set @mode on @crtc.  Give @crtc and its associated outputs a chance
 + * to fixup or reject the mode prior to trying to set it.
 + *
 + * RETURNS:
 + * True if the mode was set successfully, or false otherwise.
 + */
 +bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
 +                     int x, int y)
 +{
- struct drm_output *drm_output_create(drm_device_t *dev,
++      struct drm_device *dev = crtc->dev;
 +      struct drm_display_mode *adjusted_mode, saved_mode;
 +      int saved_x, saved_y;
 +      bool didLock = false;
 +      bool ret = false;
 +      struct drm_output *output;
 +
 +      adjusted_mode = drm_mode_duplicate(dev, mode);
 +
 +      crtc->enabled = drm_crtc_in_use(crtc);
 +
 +      if (!crtc->enabled) {
 +              return true;
 +      }
 +
 +      didLock = crtc->funcs->lock(crtc);
 +
 +      saved_mode = crtc->mode;
 +      saved_x = crtc->x;
 +      saved_y = crtc->y;
 +      
 +      /* Update crtc values up front so the driver can rely on them for mode
 +       * setting.
 +       */
 +      crtc->mode = *mode;
 +      crtc->x = x;
 +      crtc->y = y;
 +
 +      /* XXX short-circuit changes to base location only */
 +      
 +      /* Pass our mode to the outputs and the CRTC to give them a chance to
 +       * adjust it according to limitations or output properties, and also
 +       * a chance to reject the mode entirely.
 +       */
 +      list_for_each_entry(output, &dev->mode_config.output_list, head) {
 +              
 +              if (output->crtc != crtc)
 +                      continue;
 +              
 +              if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) {
 +                      goto done;
 +              }
 +      }
 +      
 +      if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) {
 +              goto done;
 +      }
 +
 +      /* Prepare the outputs and CRTCs before setting the mode. */
 +      list_for_each_entry(output, &dev->mode_config.output_list, head) {
 +
 +              if (output->crtc != crtc)
 +                      continue;
 +              
 +              /* Disable the output as the first thing we do. */
 +              output->funcs->prepare(output);
 +      }
 +      
 +      crtc->funcs->prepare(crtc);
 +      
 +      /* Set up the DPLL and any output state that needs to adjust or depend
 +       * on the DPLL.
 +       */
 +      crtc->funcs->mode_set(crtc, mode, adjusted_mode, x, y);
 +      list_for_each_entry(output, &dev->mode_config.output_list, head) {
 +              if (output->crtc == crtc) {
 +                      dev_warn(&output->dev->pdev->dev, "%s: set mode %s\n",
 +                              output->name, mode->name);
 +                      output->funcs->mode_set(output, mode, adjusted_mode);
 +              }
 +      }
 +      
 +      /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
 +      crtc->funcs->commit(crtc);
 +      list_for_each_entry(output, &dev->mode_config.output_list, head) {
 +              if (output->crtc == crtc) {
 +                      output->funcs->commit(output);
 +#if 0 // TODO def RANDR_12_INTERFACE
 +                      if (output->randr_output)
 +                              RRPostPendingProperties (output->randr_output);
 +#endif
 +              }
 +      }
 +      
 +      /* XXX free adjustedmode */
 +      drm_mode_destroy(dev, adjusted_mode);
 +      ret = TRUE;
 +      /* TODO */
 +//    if (scrn->pScreen)
 +//            drm_crtc_set_screen_sub_pixel_order(dev);
 +
 +done:
 +      if (!ret) {
 +              crtc->x = saved_x;
 +              crtc->y = saved_y;
 +              crtc->mode = saved_mode;
 +      }
 +      
 +      if (didLock)
 +              crtc->funcs->unlock (crtc);
 +      
 +      return ret;
 +}
 +EXPORT_SYMBOL(drm_crtc_set_mode);
 +
 +/**
 + * drm_disable_unused_functions - disable unused objects
 + * @dev: DRM device
 + *
 + * LOCKING:
 + * Caller must hold mode config lock.
 + *
 + * If an output or CRTC isn't part of @dev's mode_config, it can be disabled
 + * by calling its dpms function, which should power it off.
 + */
 +void drm_disable_unused_functions(struct drm_device *dev)
 +{
 +      struct drm_output *output;
 +      struct drm_crtc *crtc;
 +
 +      list_for_each_entry(output, &dev->mode_config.output_list, head) {
 +              if (!output->crtc)
 +                      (*output->funcs->dpms)(output, DPMSModeOff);
 +      }
 +
 +      list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 +              if (!crtc->enabled)
 +                      crtc->funcs->dpms(crtc, DPMSModeOff);
 +      }
 +}
 +      
 +/**
 + * drm_mode_probed_add - add a mode to the specified output's probed mode list
 + * @output: output the new mode
 + * @mode: mode data
 + *
 + * LOCKING:
 + * Caller must hold mode config lock.
 + * 
 + * Add @mode to @output's mode list for later use.
 + */
 +void drm_mode_probed_add(struct drm_output *output,
 +                       struct drm_display_mode *mode)
 +{
 +      list_add(&mode->head, &output->probed_modes);
 +}
 +EXPORT_SYMBOL(drm_mode_probed_add);
 +
 +/**
 + * drm_mode_remove - remove and free a mode
 + * @output: output list to modify
 + * @mode: mode to remove
 + *
 + * LOCKING:
 + * Caller must hold mode config lock.
 + * 
 + * Remove @mode from @output's mode list, then free it.
 + */
 +void drm_mode_remove(struct drm_output *output, struct drm_display_mode *mode)
 +{
 +      list_del(&mode->head);
 +      kfree(mode);
 +}
 +EXPORT_SYMBOL(drm_mode_remove);
 +
 +/**
 + * drm_output_create - create a new output
 + * @dev: DRM device
 + * @funcs: callbacks for this output
 + * @name: user visible name of the output
 + *
 + * LOCKING:
 + * Caller must hold @dev's mode_config lock.
 + *
 + * Creates a new drm_output structure and adds it to @dev's mode_config
 + * structure.
 + *
 + * RETURNS:
 + * Pointer to the new output or NULL on error.
 + */
- void drm_mode_config_init(drm_device_t *dev)
++struct drm_output *drm_output_create(struct drm_device *dev,
 +                                   const struct drm_output_funcs *funcs,
 +                                   const char *name)
 +{
 +      struct drm_output *output = NULL;
 +
 +      output = kzalloc(sizeof(struct drm_output), GFP_KERNEL);
 +      if (!output)
 +              return NULL;
 +              
 +      output->dev = dev;
 +      output->funcs = funcs;
 +      output->id = drm_idr_get(dev, output);
 +      if (name)
 +              strncpy(output->name, name, DRM_OUTPUT_LEN);
 +      output->name[DRM_OUTPUT_LEN - 1] = 0;
 +      output->subpixel_order = SubPixelUnknown;
 +      INIT_LIST_HEAD(&output->probed_modes);
 +      INIT_LIST_HEAD(&output->modes);
 +      /* randr_output? */
 +      /* output_set_monitor(output)? */
 +      /* check for output_ignored(output)? */
 +
 +      mutex_lock(&dev->mode_config.mutex);
 +      list_add_tail(&output->head, &dev->mode_config.output_list);
 +      dev->mode_config.num_output++;
 +
 +      mutex_unlock(&dev->mode_config.mutex);
 +
 +      return output;
 +
 +}
 +EXPORT_SYMBOL(drm_output_create);
 +
 +/**
 + * drm_output_destroy - remove an output
 + * @output: output to remove
 + *
 + * LOCKING:
 + * Caller must hold @dev's mode_config lock.
 + *
 + * Call @output's cleanup function, then remove the output from the DRM
 + * mode_config after freeing @output's modes.
 + */
 +void drm_output_destroy(struct drm_output *output)
 +{
 +      struct drm_device *dev = output->dev;
 +      struct drm_display_mode *mode, *t;
 +
 +      if (*output->funcs->cleanup)
 +              (*output->funcs->cleanup)(output);
 +
 +      list_for_each_entry_safe(mode, t, &output->probed_modes, head)
 +              drm_mode_remove(output, mode);
 +
 +      list_for_each_entry_safe(mode, t, &output->modes, head)
 +              drm_mode_remove(output, mode);
 +
 +      mutex_lock(&dev->mode_config.mutex);
 +      drm_idr_put(dev, output->id);
 +      list_del(&output->head);
 +      mutex_unlock(&dev->mode_config.mutex);
 +      kfree(output);
 +}
 +EXPORT_SYMBOL(drm_output_destroy);
 +
 +/**
 + * drm_output_rename - rename an output
 + * @output: output to rename
 + * @name: new user visible name
 + *
 + * LOCKING:
 + * None.
 + *
 + * Simply stuff a new name into @output's name field, based on @name.
 + *
 + * RETURNS:
 + * True if the name was changed, false otherwise.
 + */
 +bool drm_output_rename(struct drm_output *output, const char *name)
 +{
 +      if (!name)
 +              return false;
 +
 +      strncpy(output->name, name, DRM_OUTPUT_LEN);
 +      output->name[DRM_OUTPUT_LEN - 1] = 0;
 +
 +      DRM_DEBUG("Changed name to %s\n", output->name);
 +//    drm_output_set_monitor(output);
 +//    if (drm_output_ignored(output))
 +//            return FALSE;
 +
 +      return TRUE;
 +}
 +EXPORT_SYMBOL(drm_output_rename);
 +
 +/**
 + * drm_mode_create - create a new display mode
 + * @dev: DRM device
 + *
 + * LOCKING:
 + * None.
 + *
 + * Create a new drm_display_mode, give it an ID, and return it.
 + *
 + * RETURNS:
 + * Pointer to new mode on success, NULL on error.
 + */
 +struct drm_display_mode *drm_mode_create(struct drm_device *dev)
 +{
 +      struct drm_display_mode *nmode;
 +
 +      nmode = kzalloc(sizeof(struct drm_display_mode), GFP_KERNEL);
 +      if (!nmode)
 +              return NULL;
 +
 +      nmode->mode_id = drm_idr_get(dev, nmode);
 +      return nmode;
 +}
 +EXPORT_SYMBOL(drm_mode_create);
 +
 +/**
 + * drm_mode_destroy - remove a mode
 + * @dev: DRM device
 + * @mode: mode to remove
 + *
 + * LOCKING:
 + * Caller must hold mode config lock.
 + *
 + * Free @mode's unique identifier, then free it.
 + */
 +void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
 +{
 +      drm_idr_put(dev, mode->mode_id);
 +
 +      kfree(mode);
 +}
 +EXPORT_SYMBOL(drm_mode_destroy);
 +
 +/**
 + * drm_mode_config_init - initialize DRM mode_configuration structure
 + * @dev: DRM device
 + *
 + * LOCKING:
 + * None, should happen single threaded at init time.
 + *
 + * Initialize @dev's mode_config structure, used for tracking the graphics
 + * configuration of @dev.
 + */
- static int drm_get_buffer_object(drm_device_t *dev, struct drm_buffer_object **bo, unsigned long handle)
++void drm_mode_config_init(struct drm_device *dev)
 +{
 +      mutex_init(&dev->mode_config.mutex);
 +      INIT_LIST_HEAD(&dev->mode_config.fb_list);
 +      INIT_LIST_HEAD(&dev->mode_config.crtc_list);
 +      INIT_LIST_HEAD(&dev->mode_config.output_list);
 +      INIT_LIST_HEAD(&dev->mode_config.usermode_list);
 +      idr_init(&dev->mode_config.crtc_idr);
 +}
 +EXPORT_SYMBOL(drm_mode_config_init);
 +
 +/**
 + * drm_get_buffer_object - find the buffer object for a given handle
 + * @dev: DRM device
 + * @bo: pointer to caller's buffer_object pointer
 + * @handle: handle to lookup
 + *
 + * LOCKING:
 + * Must take @dev's struct_mutex to protect buffer object lookup.
 + *
 + * Given @handle, lookup the buffer object in @dev and put it in the caller's
 + * @bo pointer.
 + *
 + * RETURNS:
 + * Zero on success, -EINVAL if the handle couldn't be found.
 + */
-       drm_user_object_t *uo;
-       drm_hash_item_t *hash;
++static int drm_get_buffer_object(struct drm_device *dev, struct drm_buffer_object **bo, unsigned long handle)
 +{
-       uo = drm_hash_entry(hash, drm_user_object_t, hash);
++      struct drm_user_object *uo;
++      struct drm_hash_item *hash;
 +      int ret;
 +
 +      *bo = NULL;
 +
 +      mutex_lock(&dev->struct_mutex);
 +      ret = drm_ht_find_item(&dev->object_hash, handle, &hash);
 +      if (ret) {
 +              DRM_ERROR("Couldn't find handle.\n");
 +              ret = -EINVAL;
 +              goto out_err;
 +      }
 +
-       *bo = drm_user_object_entry(uo, drm_buffer_object_t, base);
++      uo = drm_hash_entry(hash, struct drm_user_object, hash);
 +      if (uo->type != drm_buffer_type) {
 +              ret = -EINVAL;
 +              goto out_err;
 +      }
 +      
- static void drm_pick_crtcs (drm_device_t *dev)
++      *bo = drm_user_object_entry(uo, struct drm_buffer_object, base);
 +      ret = 0;
 +out_err:
 +      mutex_unlock(&dev->struct_mutex);
 +      return ret;
 +}
 +
 +/**
 + * drm_pick_crtcs - pick crtcs for output devices
 + * @dev: DRM device
 + *
 + * LOCKING:
 + * Caller must hold mode config lock.
 + */
- bool drm_initial_config(drm_device_t *dev, bool can_grow)
++static void drm_pick_crtcs (struct drm_device *dev)
 +{
 +      int c, o;
 +      struct drm_output *output, *output_equal;
 +      struct drm_crtc   *crtc;
 +      struct drm_display_mode *des_mode = NULL, *modes, *modes_equal;
 +
 +      list_for_each_entry(output, &dev->mode_config.output_list, head) {
 +                      output->crtc = NULL;
 +    
 +              /* Don't hook up outputs that are disconnected ??
 +               *
 +               * This is debateable. Do we want fixed /dev/fbX or
 +               * dynamic on hotplug (need mode code for that though) ?
 +               *
 +               * If we don't hook up outputs now, then we only create
 +               * /dev/fbX for the output that's enabled, that's good as
 +               * the users console will be on that output.
 +               *
 +               * If we do hook up outputs that are disconnected now, then
 +               * the user may end up having to muck about with the fbcon
 +               * map flags to assign his console to the enabled output. Ugh.
 +               */
 +              if (output->status != output_status_connected)
 +                      continue;
 +
 +              des_mode = NULL;
 +              list_for_each_entry(des_mode, &output->modes, head) {
 +                      if (des_mode->type & DRM_MODE_TYPE_PREFERRED)
 +                              break;
 +              }
 +
 +              /* No preferred mode, let's just select the first available */
 +              if (!des_mode || !(des_mode->type & DRM_MODE_TYPE_PREFERRED)) {
 +                      list_for_each_entry(des_mode, &output->modes, head) {
 +                              if (des_mode)
 +                                      break;
 +                      }
 +              }
 +
 +              c = -1;
 +              list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 +                      c++;
 +                      if ((output->possible_crtcs & (1 << c)) == 0)
 +                              continue;
 +      
 +#if 0 /* should we try and clone ?? - code not tested - FIXME */
 +                      o = -1;
 +                      list_for_each_entry(output_equal, &dev->mode_config.output_list, head) {
 +                              o++;
 +                              if (output->id == output_equal->id)
 +                                      continue;
 +
 +                              list_for_each_entry(modes, &output->modes, head) {
 +                                      list_for_each_entry(modes_equal, &output_equal->modes, head) {
 +                                              if (drm_mode_equal (modes, modes_equal)) {
 +                                                      if ((output->possible_clones & (1 << o))) {
 +                                                              goto clone;
 +                                                      }
 +                                              }
 +                                      }
 +                              }
 +                      }
 +
 +clone:
 +#endif
 +                      /* Found a CRTC to attach to, do it ! */
 +                      output->crtc = crtc;
 +                      output->crtc->desired_mode = des_mode;
 +                      output->initial_x = 0;
 +                      output->initial_y = 0;
 +                      DRM_DEBUG("Desired mode for CRTC %d is %s\n",c,des_mode->name);
 +                      break;
 +              }
 +      }
 +}
 +
 +
 +/**
 + * drm_initial_config - setup a sane initial output configuration
 + * @dev: DRM device
 + * @can_grow: this configuration is growable
 + *
 + * LOCKING:
 + * Called at init time, must take mode config lock.
 + *
 + * Scan the CRTCs and outputs and try to put together an initial setup.
 + * At the moment, this is a cloned configuration across all heads with
 + * a new framebuffer object as the backing store.
 + *
 + * RETURNS:
 + * Zero if everything went ok, nonzero otherwise.
 + */
- void drm_mode_config_cleanup(drm_device_t *dev)
++bool drm_initial_config(struct drm_device *dev, bool can_grow)
 +{
 +      struct drm_output *output;
 +      int ret = false;
 +
 +      mutex_lock(&dev->mode_config.mutex);
 +
 +      drm_crtc_probe_output_modes(dev, 2048, 2048);
 +
 +      drm_pick_crtcs(dev);
 +
 +      list_for_each_entry(output, &dev->mode_config.output_list, head) {
 +
 +              /* can't setup the output if there's no assigned crtc or mode */
 +              if (!output->crtc || !output->crtc->desired_mode)
 +                      continue;
 +
 +              dev->driver->fb_probe(dev, output->crtc);
 +      }
 +      drm_disable_unused_functions(dev);
 +
 +      mutex_unlock(&dev->mode_config.mutex);
 +      return ret;
 +}
 +EXPORT_SYMBOL(drm_initial_config);
 +
 +/**
 + * drm_mode_config_cleanup - free up DRM mode_config info
 + * @dev: DRM device
 + *
 + * LOCKING:
 + * Caller must hold mode config lock.
 + *
 + * Free up all the outputs and CRTCs associated with this DRM device, then
 + * free up the framebuffers and associated buffer objects.
 + *
 + * FIXME: cleanup any dangling user buffer objects too
 + */
-       drm_device_t *dev = crtc->dev;
++void drm_mode_config_cleanup(struct drm_device *dev)
 +{
 +      struct drm_output *output, *ot;
 +      struct drm_crtc *crtc, *ct;
 +      struct drm_framebuffer *fb, *fbt;
 +      struct drm_display_mode *mode, *mt;
 +      list_for_each_entry_safe(output, ot, &dev->mode_config.output_list, head) {
 +              drm_output_destroy(output);
 +      }
 +
 +      list_for_each_entry_safe(mode, mt, &dev->mode_config.usermode_list, head) {
 +              drm_mode_destroy(dev, mode);
 +      }
 +              
 +      list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
 +              dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb));
 +              /* If this FB was the kernel one, free it */
 +              if (fb->bo->type == drm_bo_type_kernel) {
 +                      mutex_lock(&dev->struct_mutex);
 +                      drm_bo_usage_deref_locked(&fb->bo);
 +                      mutex_unlock(&dev->struct_mutex);
 +              }
 +              drm_framebuffer_destroy(fb);
 +      }
 +
 +      list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {
 +              drm_crtc_destroy(crtc);
 +      }
 +
 +}
 +EXPORT_SYMBOL(drm_mode_config_cleanup);
 +
 +/**
 + * drm_crtc_set_config - set a new config from userspace
 + * @crtc: CRTC to setup
 + * @crtc_info: user provided configuration
 + * @new_mode: new mode to set
 + * @output_set: set of outputs for the new config
 + * @fb: new framebuffer
 + *
 + * LOCKING:
 + * Caller must hold mode config lock.
 + *
 + * Setup a new configuration, provided by the user in @crtc_info, and enable
 + * it.
 + *
 + * RETURNS:
 + * Zero. (FIXME)
 + */
 +int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, struct drm_display_mode *new_mode, struct drm_output **output_set, struct drm_framebuffer *fb)
 +{
- int drm_mode_getresources(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg)
++      struct drm_device *dev = crtc->dev;
 +      struct drm_crtc **save_crtcs, *new_crtc;
 +      bool save_enabled = crtc->enabled;
 +      bool changed;
 +      struct drm_output *output;
 +      int count = 0, ro;
 +
 +      save_crtcs = kzalloc(dev->mode_config.num_crtc * sizeof(struct drm_crtc *), GFP_KERNEL);
 +      if (!save_crtcs)
 +              return -ENOMEM;
 +
 +      if (crtc->fb != fb)
 +              changed = true;
 +
 +      if (crtc_info->x != crtc->x || crtc_info->y != crtc->y)
 +              changed = true;
 +
 +      if (new_mode && (crtc->mode.mode_id != new_mode->mode_id))
 +              changed = true;
 +
 +      list_for_each_entry(output, &dev->mode_config.output_list, head) {
 +              save_crtcs[count++] = output->crtc;
 +
 +              if (output->crtc == crtc)
 +                      new_crtc = NULL;
 +              else
 +                      new_crtc = output->crtc;
 +
 +              for (ro = 0; ro < crtc_info->count_outputs; ro++) {
 +                      if (output_set[ro] == output)
 +                              new_crtc = crtc;
 +              }
 +              if (new_crtc != output->crtc) {
 +                      changed = true;
 +                      output->crtc = new_crtc;
 +              }
 +      }
 +
 +      if (changed) {
 +              crtc->fb = fb;
 +              crtc->enabled = (new_mode != NULL);
 +              if (new_mode != NULL) {
 +                      DRM_DEBUG("attempting to set mode from userspace\n");
 +                      drm_mode_debug_printmodeline(dev, new_mode);
 +                      if (!drm_crtc_set_mode(crtc, new_mode, crtc_info->x,
 +                                             crtc_info->y)) {
 +                              crtc->enabled = save_enabled;
 +                              count = 0;
 +                              list_for_each_entry(output, &dev->mode_config.output_list, head)
 +                                      output->crtc = save_crtcs[count++];
 +                              kfree(save_crtcs);
 +                              return -EINVAL;
 +                      }
 +                      crtc->desired_x = crtc_info->x;
 +                      crtc->desired_y = crtc_info->y;
 +                      crtc->desired_mode = new_mode;
 +              }
 +              drm_disable_unused_functions(dev);
 +      }
 +      kfree(save_crtcs);
 +      return 0;
 +}
 +
 +/**
 + * drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
 + * @out: drm_mode_modeinfo struct to return to the user
 + * @in: drm_display_mode to use
 + *
 + * LOCKING:
 + * None.
 + *
 + * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
 + * the user.
 + */
 +void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out, struct drm_display_mode *in)
 +{
 +
 +      out->id = in->mode_id;
 +      out->clock = in->clock;
 +      out->hdisplay = in->hdisplay;
 +      out->hsync_start = in->hsync_start;
 +      out->hsync_end = in->hsync_end;
 +      out->htotal = in->htotal;
 +      out->hskew = in->hskew;
 +      out->vdisplay = in->vdisplay;
 +      out->vsync_start = in->vsync_start;
 +      out->vsync_end = in->vsync_end;
 +      out->vtotal = in->vtotal;
 +      out->vscan = in->vscan;
 +      out->vrefresh = in->vrefresh;
 +      out->flags = in->flags;
 +      strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
 +      out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
 +}
 +
 +/**
 + * drm_crtc_convert_to_umode - convert a modeinfo into a drm_display_mode
 + * @out: drm_display_mode to return to the user
 + * @in: drm_mode_modeinfo to use
 + *
 + * LOCKING:
 + * None.
 + *
 + * Convert a drmo_mode_modeinfo into a drm_display_mode structure to return to
 + * the caller.
 + */
 +void drm_crtc_convert_umode(struct drm_display_mode *out, struct drm_mode_modeinfo *in)
 +{
 +      out->clock = in->clock;
 +      out->hdisplay = in->hdisplay;
 +      out->hsync_start = in->hsync_start;
 +      out->hsync_end = in->hsync_end;
 +      out->htotal = in->htotal;
 +      out->hskew = in->hskew;
 +      out->vdisplay = in->vdisplay;
 +      out->vsync_start = in->vsync_start;
 +      out->vsync_end = in->vsync_end;
 +      out->vtotal = in->vtotal;
 +      out->vscan = in->vscan;
 +      out->vrefresh = in->vrefresh;
 +      out->flags = in->flags;
 +      strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
 +      out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
 +}
 +      
 +/**
 + * drm_mode_getresources - get graphics configuration
 + * @inode: inode from the ioctl
 + * @filp: file * from the ioctl
 + * @cmd: cmd from ioctl
 + * @arg: arg from ioctl
 + *
 + * LOCKING:
 + * Takes mode config lock.
 + *
 + * Construct a set of configuration description structures and return
 + * them to the user, including CRTC, output and framebuffer configuration.
 + *
 + * Called by the user via ioctl.
 + *
 + * RETURNS:
 + * Zero on success, errno on failure.
 + */
-       drm_file_t *priv = filp->private_data;
-       drm_device_t *dev = priv->head->dev;
-       struct drm_mode_card_res __user *argp = (void __user *)arg;
++int drm_mode_getresources(struct drm_device *dev,
++                        void *data, struct drm_file *file_priv)
 +{
- int drm_mode_getcrtc(struct inode *inode, struct file *filp,
-                    unsigned int cmd, unsigned long arg)
++      struct drm_mode_card_res __user *argp = (void __user *)data;
 +      struct drm_mode_card_res card_res;
 +      struct list_head *lh;
 +      struct drm_framebuffer *fb;
 +      struct drm_output *output;
 +      struct drm_crtc *crtc;
 +      struct drm_mode_modeinfo u_mode;
 +      struct drm_display_mode *mode;
 +      int ret = 0;
 +      int mode_count= 0;
 +      int output_count = 0;
 +      int crtc_count = 0;
 +      int fb_count = 0;
 +      int copied = 0;
 +      
 +      memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
 +
 +      mutex_lock(&dev->mode_config.mutex);
 +
 +      list_for_each(lh, &dev->mode_config.fb_list)
 +              fb_count++;
 +
 +      list_for_each(lh, &dev->mode_config.crtc_list)
 +              crtc_count++;
 +
 +      list_for_each_entry(output, &dev->mode_config.output_list,
 +                          head) {
 +              output_count++;
 +              list_for_each(lh, &output->modes)
 +                      mode_count++;
 +      }
 +      list_for_each(lh, &dev->mode_config.usermode_list)
 +              mode_count++;
 +
 +      if (copy_from_user(&card_res, argp, sizeof(card_res))) {
 +              ret = -EFAULT;
 +              goto out_unlock;
 +      }
 +
 +      if (card_res.count_modes == 0) {
 +              DRM_DEBUG("probing modes %dx%d\n", dev->mode_config.max_width, dev->mode_config.max_height);
 +              drm_crtc_probe_output_modes(dev, dev->mode_config.max_width, dev->mode_config.max_height);
 +              mode_count = 0;
 +              list_for_each_entry(output, &dev->mode_config.output_list, head) {
 +                      list_for_each(lh, &output->modes)
 +                              mode_count++;
 +              }
 +              list_for_each(lh, &dev->mode_config.usermode_list)
 +                      mode_count++;
 +      }
 +
 +      /* handle this in 4 parts */
 +      /* FBs */
 +      if (card_res.count_fbs >= fb_count) {
 +              copied = 0;
 +              list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
 +                      if (put_user(fb->id, &card_res.fb_id[copied++])) {
 +                              ret = -EFAULT;
 +                              goto done;
 +                      }
 +              }
 +      }
 +      card_res.count_fbs = fb_count;
 +
 +      /* CRTCs */
 +      if (card_res.count_crtcs >= crtc_count) {
 +              copied = 0;
 +              list_for_each_entry(crtc, &dev->mode_config.crtc_list, head){
 +                      DRM_DEBUG("CRTC ID is %d\n", crtc->id);
 +                      if (put_user(crtc->id, &card_res.crtc_id[copied++])) {
 +                              ret = -EFAULT;
 +                              goto done;
 +                      }
 +              }
 +      }
 +      card_res.count_crtcs = crtc_count;
 +
 +
 +      /* Outputs */
 +      if (card_res.count_outputs >= output_count) {
 +              copied = 0;
 +              list_for_each_entry(output, &dev->mode_config.output_list,
 +                                  head) {
 +                      DRM_DEBUG("OUTPUT ID is %d\n", output->id);
 +                      if (put_user(output->id, &card_res.output_id[copied++])) {
 +                              ret = -EFAULT;
 +                              goto done;
 +                      }
 +              }
 +      }
 +      card_res.count_outputs = output_count;
 +      
 +      /* Modes */
 +      if (card_res.count_modes >= mode_count) {
 +              copied = 0;
 +              list_for_each_entry(output, &dev->mode_config.output_list,
 +                                  head) {
 +                      list_for_each_entry(mode, &output->modes, head) {
 +                              drm_crtc_convert_to_umode(&u_mode, mode);
 +                              if (copy_to_user(&card_res.modes[copied++], &u_mode, sizeof(struct drm_mode_modeinfo))) {
 +                                      ret = -EFAULT;
 +                                      goto done;
 +                              }
 +                      }
 +              }
 +              /* add in user modes */
 +              list_for_each_entry(mode, &dev->mode_config.usermode_list, head) {
 +                      drm_crtc_convert_to_umode(&u_mode, mode);
 +                      if (copy_to_user(&card_res.modes[copied++], &u_mode, sizeof(struct drm_mode_modeinfo))) {
 +                              ret = -EFAULT;
 +                              goto done;
 +                      }
 +              }
 +      }
 +      card_res.count_modes = mode_count;
 +
 +done:
 +      DRM_DEBUG("Counted %d %d %d\n", card_res.count_crtcs,
 +                card_res.count_outputs,
 +                card_res.count_modes);
 +      
 +      if (copy_to_user(argp, &card_res, sizeof(card_res)))
 +              ret = -EFAULT;
 +
 +out_unlock:
 +      mutex_unlock(&dev->mode_config.mutex);
 +      return ret;
 +}
 +
 +/**
 + * drm_mode_getcrtc - get CRTC configuration
 + * @inode: inode from the ioctl
 + * @filp: file * from the ioctl
 + * @cmd: cmd from ioctl
 + * @arg: arg from ioctl
 + *
 + * LOCKING:
 + * Caller? (FIXME)
 + *
 + * Construct a CRTC configuration structure to return to the user.
 + *
 + * Called by the user via ioctl.
 + *
 + * RETURNS:
 + * Zero on success, errno on failure.
 + */
-       drm_file_t *priv = filp->private_data;
-       drm_device_t *dev = priv->head->dev;
-       struct drm_mode_crtc __user *argp = (void __user *)arg;
++int drm_mode_getcrtc(struct drm_device *dev,
++                   void *data, struct drm_file *file_priv)
 +{
- int drm_mode_getoutput(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg)
++      struct drm_mode_crtc __user *argp = (void __user *)data;
 +      struct drm_mode_crtc crtc_resp;
 +      struct drm_crtc *crtc;
 +      struct drm_output *output;
 +      int ocount;
 +      int ret = 0;
 +
 +      if (copy_from_user(&crtc_resp, argp, sizeof(crtc_resp)))
 +              return -EFAULT;
 +
 +      mutex_lock(&dev->mode_config.mutex);
 +      crtc = idr_find(&dev->mode_config.crtc_idr, crtc_resp.crtc_id);
 +      if (!crtc || (crtc->id != crtc_resp.crtc_id)) {
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +      crtc_resp.x = crtc->x;
 +      crtc_resp.y = crtc->y;
 +      crtc_resp.fb_id = 1;
 +
 +      crtc_resp.outputs = 0;
 +      if (crtc->enabled) {
 +
 +              crtc_resp.mode = crtc->mode.mode_id;
 +              ocount = 0;
 +              list_for_each_entry(output, &dev->mode_config.output_list, head) {
 +                      if (output->crtc == crtc)
 +                              crtc_resp.outputs |= 1 << (ocount++);
 +              }
 +      } else {
 +              crtc_resp.mode = 0;
 +      }
 +
 +      if (copy_to_user(argp, &crtc_resp, sizeof(crtc_resp)))
 +              ret = -EFAULT;
 +
 +out:
 +      mutex_unlock(&dev->mode_config.mutex);
 +      return ret;
 +}
 +
 +/**
 + * drm_mode_getoutput - get output configuration
 + * @inode: inode from the ioctl
 + * @filp: file * from the ioctl
 + * @cmd: cmd from ioctl
 + * @arg: arg from ioctl
 + *
 + * LOCKING:
 + * Caller? (FIXME)
 + *
 + * Construct a output configuration structure to return to the user.
 + *
 + * Called by the user via ioctl.
 + *
 + * RETURNS:
 + * Zero on success, errno on failure.
 + */
-       drm_file_t *priv = filp->private_data;
-       drm_device_t *dev = priv->head->dev;
-       struct drm_mode_get_output __user *argp = (void __user *)arg;
++int drm_mode_getoutput(struct drm_device *dev,
++                     void *data, struct drm_file *file_priv)
 +{
- int drm_mode_setcrtc(struct inode *inode, struct file *filp,
-                    unsigned int cmd, unsigned long arg)
++      struct drm_mode_get_output __user *argp = (void __user *)data;
 +      struct drm_mode_get_output out_resp;
 +      struct drm_output *output;
 +      struct drm_display_mode *mode;
 +      int mode_count = 0;
 +      int ret = 0;
 +      int copied = 0;
 +      int i;
 +
 +      if (copy_from_user(&out_resp, argp, sizeof(out_resp)))
 +              return -EFAULT; 
 +
 +      DRM_DEBUG("output id %d:\n", out_resp.output);
 +
 +      mutex_lock(&dev->mode_config.mutex);
 +      output= idr_find(&dev->mode_config.crtc_idr, out_resp.output);
 +      if (!output || (output->id != out_resp.output)) {
 +              ret = -EINVAL;
 +              goto out_unlock;
 +      }
 +
 +      list_for_each_entry(mode, &output->modes, head)
 +              mode_count++;
 +      
 +      for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++)
 +              if (output->user_mode_ids[i] != 0)
 +                      mode_count++;
 +
 +      strncpy(out_resp.name, output->name, DRM_OUTPUT_NAME_LEN);
 +      out_resp.name[DRM_OUTPUT_NAME_LEN-1] = 0;
 +
 +      out_resp.mm_width = output->mm_width;
 +      out_resp.mm_height = output->mm_height;
 +      out_resp.subpixel = output->subpixel_order;
 +      out_resp.connection = output->status;
 +      if (output->crtc)
 +              out_resp.crtc = output->crtc->id;
 +      else
 +              out_resp.crtc = 0;
 +
 +      if ((out_resp.count_modes >= mode_count) && mode_count) {
 +              copied = 0;
 +              list_for_each_entry(mode, &output->modes, head) {
 +                      if (put_user(mode->mode_id, &out_resp.modes[copied++])) {
 +                              ret = -EFAULT;
 +                              goto done;
 +                      }
 +              }
 +              for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++) {
 +                      if (output->user_mode_ids[i] != 0)
 +                              if (put_user(output->user_mode_ids[i], &out_resp.modes[copied++])) {
 +                                      ret = -EFAULT;
 +                                      goto done;
 +                              }
 +              }
 +                      
 +      }
 +      out_resp.count_modes = mode_count;
 +
 +done:
 +      if (copy_to_user(argp, &out_resp, sizeof(out_resp)))
 +              ret = -EFAULT;
 +
 +out_unlock:
 +      mutex_unlock(&dev->mode_config.mutex);
 +      return ret;
 +}
 +
 +/**
 + * drm_mode_setcrtc - set CRTC configuration
 + * @inode: inode from the ioctl
 + * @filp: file * from the ioctl
 + * @cmd: cmd from ioctl
 + * @arg: arg from ioctl
 + *
 + * LOCKING:
 + * Caller? (FIXME)
 + *
 + * Build a new CRTC configuration based on user request.
 + *
 + * Called by the user via ioctl.
 + *
 + * RETURNS:
 + * Zero on success, errno on failure.
 + */
-       drm_file_t *priv = filp->private_data;
-       drm_device_t *dev = priv->head->dev;
-       struct drm_mode_crtc __user *argp = (void __user *)arg;
++int drm_mode_setcrtc(struct drm_device *dev,
++                   void *data, struct drm_file *file_priv)
 +{
- int drm_mode_addfb(struct inode *inode, struct file *filp,
-                  unsigned int cmd, unsigned long arg)
++      struct drm_mode_crtc __user *argp = (void __user *)data;
 +      struct drm_mode_crtc crtc_req;
 +      struct drm_crtc *crtc;
 +      struct drm_output **output_set = NULL, *output;
 +      struct drm_display_mode *mode;
 +      struct drm_framebuffer *fb = NULL;
 +      int ret = 0;
 +      int i;
 +
 +      if (copy_from_user(&crtc_req, argp, sizeof(crtc_req)))
 +              return -EFAULT;
 +
 +      mutex_lock(&dev->mode_config.mutex);
 +      crtc = idr_find(&dev->mode_config.crtc_idr, crtc_req.crtc_id);
 +      if (!crtc || (crtc->id != crtc_req.crtc_id)) {
 +              DRM_DEBUG("Unknown CRTC ID %d\n", crtc_req.crtc_id);
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +      if (crtc_req.mode) {
 +              /* if we have a mode we need a framebuffer */
 +              if (crtc_req.fb_id) {
 +                      fb = idr_find(&dev->mode_config.crtc_idr, crtc_req.fb_id);
 +                      if (!fb || (fb->id != crtc_req.fb_id)) {
 +                              DRM_DEBUG("Unknown FB ID%d\n", crtc_req.fb_id);
 +                              ret = -EINVAL;
 +                              goto out;
 +                      }
 +              }
 +              mode = idr_find(&dev->mode_config.crtc_idr, crtc_req.mode);
 +              if (!mode || (mode->mode_id != crtc_req.mode)) {
 +                      struct drm_output *output;
 +                      
 +                      list_for_each_entry(output, 
 +                                          &dev->mode_config.output_list,
 +                                          head) {
 +                              list_for_each_entry(mode, &output->modes,
 +                                                  head) {
 +                                      drm_mode_debug_printmodeline(dev, 
 +                                                                   mode);
 +                              }
 +                      }
 +
 +                      DRM_DEBUG("Unknown mode id %d, %p\n", crtc_req.mode, mode);
 +                      ret = -EINVAL;
 +                      goto out;
 +              }
 +      } else
 +              mode = NULL;
 +
 +      if (crtc_req.count_outputs == 0 && mode) {
 +              DRM_DEBUG("Count outputs is 0 but mode set\n");
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +      if (crtc_req.count_outputs > 0 && !mode && !fb) {
 +              DRM_DEBUG("Count outputs is %d but no mode or fb set\n", crtc_req.count_outputs);
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +      if (crtc_req.count_outputs > 0) {
 +              u32 out_id;
 +              output_set = kmalloc(crtc_req.count_outputs *
 +                                   sizeof(struct drm_output *), GFP_KERNEL);
 +              if (!output_set) {
 +                      ret = -ENOMEM;
 +                      goto out;
 +              }
 +
 +              for (i = 0; i < crtc_req.count_outputs; i++) {
 +                      if (get_user(out_id, &crtc_req.set_outputs[i])) {
 +                              ret = -EFAULT;
 +                              goto out;
 +                      }
 +
 +                      output = idr_find(&dev->mode_config.crtc_idr, out_id);
 +                      if (!output || (out_id != output->id)) {
 +                              DRM_DEBUG("Output id %d unknown\n", out_id);
 +                              ret = -EINVAL;
 +                              goto out;
 +                      }
 +
 +                      output_set[i] = output;
 +              }
 +      }
 +              
 +      ret = drm_crtc_set_config(crtc, &crtc_req, mode, output_set, fb);
 +
 +out:
 +      mutex_unlock(&dev->mode_config.mutex);
 +      return ret;
 +}
 +
 +/**
 + * drm_mode_addfb - add an FB to the graphics configuration
 + * @inode: inode from the ioctl
 + * @filp: file * from the ioctl
 + * @cmd: cmd from ioctl
 + * @arg: arg from ioctl
 + *
 + * LOCKING:
 + * Takes mode config lock.
 + *
 + * Add a new FB to the specified CRTC, given a user request.
 + *
 + * Called by the user via ioctl.
 + *
 + * RETURNS:
 + * Zero on success, errno on failure.
 + */
-       struct drm_file *priv = filp->private_data;
-       struct drm_device *dev = priv->head->dev;
-       struct drm_mode_fb_cmd __user *argp = (void __user *)arg;
++int drm_mode_addfb(struct drm_device *dev,
++                 void *data, struct drm_file *file_priv)
 +{
-       list_add(&fb->filp_head, &priv->fbs);
++      struct drm_mode_fb_cmd __user *argp = (void __user *)data;
 +      struct drm_mode_fb_cmd r;
 +      struct drm_mode_config *config = &dev->mode_config;
 +      struct drm_framebuffer *fb;
 +      struct drm_buffer_object *bo;
 +      struct drm_crtc *crtc;
 +      int ret = 0;
 +
 +      if (copy_from_user(&r, argp, sizeof(r)))
 +              return -EFAULT;
 +
 +      if ((config->min_width > r.width) || (r.width > config->max_width)) {
 +              DRM_ERROR("mode new framebuffer width not within limits\n");
 +              return -EINVAL;
 +      }
 +      if ((config->min_height > r.height) || (r.height > config->max_height)) {
 +              DRM_ERROR("mode new framebuffer height not within limits\n");
 +              return -EINVAL;
 +      }
 +
 +      mutex_lock(&dev->mode_config.mutex);
 +      /* TODO check limits are okay */
 +      ret = drm_get_buffer_object(dev, &bo, r.handle);
 +      if (ret || !bo) {
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +      /* TODO check buffer is sufficently large */
 +      /* TODO setup destructor callback */
 +
 +      fb = drm_framebuffer_create(dev);
 +      if (!fb) {
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +      fb->width = r.width;
 +      fb->height = r.height;
 +      fb->pitch = r.pitch;
 +      fb->bits_per_pixel = r.bpp;
 +      fb->depth = r.depth;
 +      fb->offset = bo->offset;
 +      fb->bo = bo;
 +
 +      r.buffer_id = fb->id;
 +
- int drm_mode_rmfb(struct inode *inode, struct file *filp,
-                  unsigned int cmd, unsigned long arg)
++      list_add(&fb->filp_head, &file_priv->fbs);
 +
 +      if (copy_to_user(argp, &r, sizeof(r))) {
 +              ret = -EFAULT;
 +              goto out;
 +      }
 +              
 +      /* FIXME: bind the fb to the right crtc */
 +      list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 +              crtc->fb = fb;
 +              dev->driver->fb_probe(dev, crtc);
 +      }
 +
 +out:
 +      mutex_unlock(&dev->mode_config.mutex);
 +      return ret;
 +}
 +
 +/**
 + * drm_mode_rmfb - remove an FB from the configuration
 + * @inode: inode from the ioctl
 + * @filp: file * from the ioctl
 + * @cmd: cmd from ioctl
 + * @arg: arg from ioctl
 + *
 + * LOCKING:
 + * Takes mode config lock.
 + *
 + * Remove the FB specified by the user.
 + *
 + * Called by the user via ioctl.
 + *
 + * RETURNS:
 + * Zero on success, errno on failure.
 + */
-       drm_file_t *priv = filp->private_data;
-       drm_device_t *dev = priv->head->dev;
++int drm_mode_rmfb(struct drm_device *dev,
++                 void *data, struct drm_file *file_priv)
 +{
-       uint32_t id = arg;
 +      struct drm_framebuffer *fb = 0;
- int drm_mode_getfb(struct inode *inode, struct file *filp,
-                  unsigned int cmd, unsigned long arg)
++      uint32_t id = data;
 +      int ret = 0;
 +
 +      mutex_lock(&dev->mode_config.mutex);
 +      fb = idr_find(&dev->mode_config.crtc_idr, id);
 +      /* TODO check that we realy get a framebuffer back. */
 +      if (!fb || (id != fb->id)) {
 +              DRM_ERROR("mode invalid framebuffer id\n");
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +      dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb));
 +
 +      /* TODO check if we own the buffer */
 +      /* TODO release all crtc connected to the framebuffer */
 +      /* bind the fb to the crtc for now */
 +      /* TODO unhock the destructor from the buffer object */
 +
 +      drm_framebuffer_destroy(fb);
 +
 +out:
 +      mutex_unlock(&dev->mode_config.mutex);
 +      return ret;
 +}
 +
 +/**
 + * drm_mode_getfb - get FB info
 + * @inode: inode from the ioctl
 + * @filp: file * from the ioctl
 + * @cmd: cmd from ioctl
 + * @arg: arg from ioctl
 + *
 + * LOCKING:
 + * Caller? (FIXME)
 + *
 + * Lookup the FB given its ID and return info about it.
 + *
 + * Called by the user via ioctl.
 + *
 + * RETURNS:
 + * Zero on success, errno on failure.
 + */
-       drm_file_t *priv = filp->private_data;
-       drm_device_t *dev = priv->head->dev;    
-       struct drm_mode_fb_cmd __user *argp = (void __user *)arg;
++int drm_mode_getfb(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;
++      struct drm_mode_fb_cmd __user *argp = (void __user *)data;
 +      struct drm_mode_fb_cmd r;
 +      struct drm_framebuffer *fb;
 +      int ret = 0;
 +
 +      if (copy_from_user(&r, argp, sizeof(r)))
 +              return -EFAULT;
 +
 +      mutex_lock(&dev->mode_config.mutex);
 +      fb = idr_find(&dev->mode_config.crtc_idr, r.buffer_id);
 +      if (!fb || (r.buffer_id != fb->id)) {
 +              DRM_ERROR("invalid framebuffer id\n");
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +      r.height = fb->height;
 +      r.width = fb->width;
 +      r.depth = fb->depth;
 +      r.bpp = fb->bits_per_pixel;
 +      r.handle = fb->bo->base.hash.key;
 +      r.pitch = fb->pitch;
 +
 +      if (copy_to_user(argp, &r, sizeof(r)))
 +              ret = -EFAULT;
 +
 +out:
 +      mutex_unlock(&dev->mode_config.mutex);
 +      return ret;
 +}
 +
 +/**
 + * drm_fb_release - remove and free the FBs on this file
 + * @filp: file * from the ioctl
 + *
 + * LOCKING:
 + * Takes mode config lock.
 + *
 + * Destroy all the FBs associated with @filp.
 + *
 + * Called by the user via ioctl.
 + *
 + * RETURNS:
 + * Zero on success, errno on failure.
 + */
 +void drm_fb_release(struct file *filp)
 +{
- int drm_mode_addmode(struct inode *inode, struct file *filp,
-                    unsigned int cmd, unsigned long arg)
++      struct drm_file *priv = filp->private_data;
++      struct drm_device *dev = priv->head->dev;
 +      struct drm_framebuffer *fb, *tfb;
 +
 +      mutex_lock(&dev->mode_config.mutex);
 +      list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
 +              list_del(&fb->filp_head);
 +              dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb));
 +              drm_framebuffer_destroy(fb);
 +      }
 +      mutex_unlock(&dev->mode_config.mutex);
 +}
 +
 +/**
 + * drm_fb_newmode - adds a user defined mode
 + * @inode: inode from the ioctl
 + * @filp: file * from the ioctl
 + * @cmd: cmd from ioctl
 + * @arg: arg from ioctl
 + *
 + * Adds a user specified mode to the kernel.
 + *
 + * Called by the user via ioctl.
 + *
 + * RETURNS:
 + * writes new mode id into arg.
 + * Zero on success, errno on failure.
 + */
-       drm_file_t *priv = filp->private_data;
-       drm_device_t *dev = priv->head->dev;
-       struct drm_mode_modeinfo __user *argp = (void __user *)arg;
++int drm_mode_addmode(struct drm_device *dev,
++                   void *data, struct drm_file *file_priv)
 +{
- int drm_mode_rmmode(struct inode *inode, struct file *filp,
-                   unsigned int cmd, unsigned long arg)
++      struct drm_mode_modeinfo __user *argp = (void __user *)data;
 +      struct drm_mode_modeinfo new_mode;
 +      struct drm_display_mode *user_mode;
 +      int ret = 0;
 +
 +      if (copy_from_user(&new_mode, argp, sizeof(new_mode)))
 +              return -EFAULT;
 +
 +      mutex_lock(&dev->mode_config.mutex);
 +      user_mode = drm_mode_create(dev);
 +      if (!user_mode) {
 +              ret = -ENOMEM;
 +              goto out;
 +      }
 +
 +      drm_crtc_convert_umode(user_mode, &new_mode);
 +      user_mode->type |= DRM_MODE_TYPE_USERDEF;
 +
 +      user_mode->output_count = 0;
 +
 +      list_add(&user_mode->head, &dev->mode_config.usermode_list);
 +
 +      new_mode.id = user_mode->mode_id;
 +      if (copy_to_user(argp, &new_mode, sizeof(new_mode)))
 +              ret = -EFAULT;
 +
 +out:
 +      mutex_unlock(&dev->mode_config.mutex);
 +      return ret;
 +}
 +
 +/**
 + * drm_fb_rmmode - removes a user defined mode
 + * @inode: inode from the ioctl
 + * @filp: file * from the ioctl
 + * @cmd: cmd from ioctl
 + * @arg: arg from ioctl
 + *
 + * Remove the user defined mode specified by the user.
 + *
 + * Called by the user via ioctl
 + *
 + * RETURNS:
 + * Zero on success, errno on failure.
 + */
-       drm_file_t *priv = filp->private_data;
-       drm_device_t *dev = priv->head->dev;
-       uint32_t id = arg;
++int drm_mode_rmmode(struct drm_device *dev,
++                  void *data, struct drm_file *file_priv)
 +{
- int drm_mode_attachmode(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg)
++      uint32_t id = (uint32_t)data;
 +      struct drm_display_mode *mode, *t;
 +      int ret = -EINVAL;
 +
 +      mutex_lock(&dev->mode_config.mutex);    
 +      mode = idr_find(&dev->mode_config.crtc_idr, id);
 +      if (!mode || (id != mode->mode_id)) {
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +      if (!(mode->type & DRM_MODE_TYPE_USERDEF)) {
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +      if (mode->output_count) {
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +      list_for_each_entry(t, &dev->mode_config.usermode_list, head) {
 +              if (t == mode) {
 +                      list_del(&mode->head);
 +                      drm_mode_destroy(dev, mode);
 +                      ret = 0;
 +                      break;
 +              }
 +      }
 +
 +out:
 +      mutex_unlock(&dev->mode_config.mutex);
 +      return ret;
 +}
 +
 +/**
 + * drm_fb_attachmode - Attach a user mode to an output
 + * @inode: inode from the ioctl
 + * @filp: file * from the ioctl
 + * @cmd: cmd from ioctl
 + * @arg: arg from ioctl
 + *
 + * This attaches a user specified mode to an output.
 + * Called by the user via ioctl.
 + *
 + * RETURNS:
 + * Zero on success, errno on failure.
 + */
-       drm_file_t *priv = filp->private_data;
-       drm_device_t *dev = priv->head->dev;
-       struct drm_mode_mode_cmd __user *argp = (void __user *)arg;
++int drm_mode_attachmode(struct drm_device *dev,
++                      void *data, struct drm_file *file_priv)
 +{
- int drm_mode_detachmode(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg)
++      struct drm_mode_mode_cmd __user *argp = (void __user *)data;
 +      struct drm_mode_mode_cmd mode_cmd;
 +      struct drm_output *output;
 +      struct drm_display_mode *mode;
 +      int i, ret = 0;
 +
 +      if (copy_from_user(&mode_cmd, argp, sizeof(mode_cmd)))
 +              return -EFAULT;
 +
 +      mutex_lock(&dev->mode_config.mutex);
 +
 +      mode = idr_find(&dev->mode_config.crtc_idr, mode_cmd.mode_id);
 +      if (!mode || (mode->mode_id != mode_cmd.mode_id)) {
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +      output = idr_find(&dev->mode_config.crtc_idr, mode_cmd.output_id);
 +      if (!output || (output->id != mode_cmd.output_id)) {
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +      for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++) {
 +              if (output->user_mode_ids[i] == 0) {
 +                      output->user_mode_ids[i] = mode->mode_id;
 +                      mode->output_count++;
 +                      break;
 +              }
 +      }
 +
 +      if (i == DRM_OUTPUT_MAX_UMODES)
 +              ret = -ENOSPC;
 +
 +out:
 +      mutex_unlock(&dev->mode_config.mutex);
 +      return ret;
 +}
 +
 +
 +/**
 + * drm_fb_detachmode - Detach a user specified mode from an output
 + * @inode: inode from the ioctl
 + * @filp: file * from the ioctl
 + * @cmd: cmd from ioctl
 + * @arg: arg from ioctl
 + *
 + * Called by the user via ioctl.
 + *
 + * RETURNS:
 + * Zero on success, errno on failure.
 + */
-       drm_file_t *priv = filp->private_data;
-       drm_device_t *dev = priv->head->dev;
-       struct drm_mode_mode_cmd __user *argp = (void __user *)arg;
++int drm_mode_detachmode(struct drm_device *dev,
++                      void *data, struct drm_file *file_priv)
 +{
++      struct drm_mode_mode_cmd __user *argp = (void __user *)data;
 +      struct drm_mode_mode_cmd mode_cmd;
 +      struct drm_output *output;
 +      struct drm_display_mode *mode;
 +      int i, found = 0, ret = 0;
 +
 +      if (copy_from_user(&mode_cmd, argp, sizeof(mode_cmd)))
 +              return -EFAULT;
 +
 +      mutex_lock(&dev->mode_config.mutex);
 +
 +      mode = idr_find(&dev->mode_config.crtc_idr, mode_cmd.mode_id);
 +      if (!mode || (mode->mode_id != mode_cmd.mode_id)) {
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +      output = idr_find(&dev->mode_config.crtc_idr, mode_cmd.output_id);
 +      if (!output || (output->id != mode_cmd.output_id)) {
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
 +
 +      for (i = 0; i < DRM_OUTPUT_MAX_UMODES; i++) {
 +              if (output->user_mode_ids[i] == mode->mode_id) {
 +                      output->user_mode_ids[i] = 0;
 +                      mode->output_count--;
 +                      found = 1;
 +              }
 +      }
 +
 +      if (!found)
 +              ret = -EINVAL;
 +
 +out:         
 +      mutex_unlock(&dev->mode_config.mutex);
 +      return ret;
 +}
index 75db5b0,0000000..d97cd19
mode 100644,000000..100644
--- /dev/null
@@@ -1,556 -1,0 +1,556 @@@
- extern int drm_mode_getresources(struct inode *inode, struct file *filp,
-                                unsigned int cmd, unsigned long arg);
- extern int drm_mode_getcrtc(struct inode *inode, struct file *filp,
-                           unsigned int cmd, unsigned long arg);
- extern int drm_mode_getoutput(struct inode *inode, struct file *filp,
-                             unsigned int cmd, unsigned long arg);
- extern int drm_mode_setcrtc(struct inode *inode, struct file *filp,
-                           unsigned int cmd, unsigned long arg);
- extern int drm_mode_addfb(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
- extern int drm_mode_rmfb(struct inode *inode, struct file *filp,
-                        unsigned int cmd, unsigned long arg);
- extern int drm_mode_getfb(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
- extern int drm_mode_addmode(struct inode *inode, struct file *filp,
-                           unsigned int cmd, unsigned long arg);
- extern int drm_mode_rmmode(struct inode *inode, struct file *filp,
-                          unsigned int cmd, unsigned long arg);
- extern int drm_mode_attachmode(struct inode *inode, struct file *filp,
-                              unsigned int cmd, unsigned long arg);
- extern int drm_mode_detachmode(struct inode *inode, struct file *filp,
-                              unsigned int cmd, unsigned long arg);
 +/*
 + * Copyright Â© 2006 Keith Packard
 + * Copyright Â© 2007 Intel Corporation
 + *   Jesse Barnes <jesse.barnes@intel.com>
 + */
 +#ifndef __DRM_CRTC_H__
 +#define __DRM_CRTC_H__
 +
 +#include <linux/i2c.h>
 +#include <linux/spinlock.h>
 +#include <linux/types.h>
 +#include <linux/idr.h>
 +
 +#include <linux/fb.h>
 +
 +struct drm_device;
 +
 +/*
 + * Note on terminology:  here, for brevity and convenience, we refer to output
 + * control chips as 'CRTCs'.  They can control any type of output, VGA, LVDS,
 + * DVI, etc.  And 'screen' refers to the whole of the visible display, which
 + * may span multiple monitors (and therefore multiple CRTC and output
 + * structures).
 + */
 +
 +enum drm_mode_status {
 +    MODE_OK   = 0,    /* Mode OK */
 +    MODE_HSYNC,               /* hsync out of range */
 +    MODE_VSYNC,               /* vsync out of range */
 +    MODE_H_ILLEGAL,   /* mode has illegal horizontal timings */
 +    MODE_V_ILLEGAL,   /* mode has illegal horizontal timings */
 +    MODE_BAD_WIDTH,   /* requires an unsupported linepitch */
 +    MODE_NOMODE,      /* no mode with a maching name */
 +    MODE_NO_INTERLACE,        /* interlaced mode not supported */
 +    MODE_NO_DBLESCAN, /* doublescan mode not supported */
 +    MODE_NO_VSCAN,    /* multiscan mode not supported */
 +    MODE_MEM,         /* insufficient video memory */
 +    MODE_VIRTUAL_X,   /* mode width too large for specified virtual size */
 +    MODE_VIRTUAL_Y,   /* mode height too large for specified virtual size */
 +    MODE_MEM_VIRT,    /* insufficient video memory given virtual size */
 +    MODE_NOCLOCK,     /* no fixed clock available */
 +    MODE_CLOCK_HIGH,  /* clock required is too high */
 +    MODE_CLOCK_LOW,   /* clock required is too low */
 +    MODE_CLOCK_RANGE, /* clock/mode isn't in a ClockRange */
 +    MODE_BAD_HVALUE,  /* horizontal timing was out of range */
 +    MODE_BAD_VVALUE,  /* vertical timing was out of range */
 +    MODE_BAD_VSCAN,   /* VScan value out of range */
 +    MODE_HSYNC_NARROW,        /* horizontal sync too narrow */
 +    MODE_HSYNC_WIDE,  /* horizontal sync too wide */
 +    MODE_HBLANK_NARROW,       /* horizontal blanking too narrow */
 +    MODE_HBLANK_WIDE, /* horizontal blanking too wide */
 +    MODE_VSYNC_NARROW,        /* vertical sync too narrow */
 +    MODE_VSYNC_WIDE,  /* vertical sync too wide */
 +    MODE_VBLANK_NARROW,       /* vertical blanking too narrow */
 +    MODE_VBLANK_WIDE, /* vertical blanking too wide */
 +    MODE_PANEL,         /* exceeds panel dimensions */
 +    MODE_INTERLACE_WIDTH, /* width too large for interlaced mode */
 +    MODE_ONE_WIDTH,     /* only one width is supported */
 +    MODE_ONE_HEIGHT,    /* only one height is supported */
 +    MODE_ONE_SIZE,      /* only one resolution is supported */
 +    MODE_NO_REDUCED,    /* monitor doesn't accept reduced blanking */
 +    MODE_UNVERIFIED = -3, /* mode needs to reverified */
 +    MODE_BAD = -2,    /* unspecified reason */
 +    MODE_ERROR        = -1    /* error condition */
 +};
 +
 +#define DRM_MODE_TYPE_BUILTIN (1<<0)
 +#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN)
 +#define DRM_MODE_TYPE_CRTC_C  ((1<<2) | DRM_MODE_TYPE_BUILTIN)
 +#define DRM_MODE_TYPE_PREFERRED       (1<<3)
 +#define DRM_MODE_TYPE_DEFAULT (1<<4)
 +#define DRM_MODE_TYPE_USERDEF (1<<5)
 +#define DRM_MODE_TYPE_DRIVER  (1<<6)
 +
 +#define DRM_MODE_TYPE_CLOCK_CRTC_C (DRM_MODE_TYPE_CLOCK_C | \
 +                                  DRM_MODE_TYPE_CRTC_C)
 +
 +#define DRM_MODE(nm, t, c, hd, hss, hse, ht, hsk, vd, vss, vse, vt, vs, f) \
 +      .name = nm, .status = 0, .type = (t), .clock = (c), \
 +      .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \
 +      .htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \
 +      .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \
 +      .vscan = (vs), .flags = (f), .vrefresh = 0
 +
 +struct drm_display_mode {
 +      /* Header */
 +      struct list_head head;
 +      char name[DRM_DISPLAY_MODE_LEN];
 +      int mode_id;
 +      int output_count;
 +      enum drm_mode_status status;
 +      int type;
 +
 +      /* Proposed mode values */
 +      int clock;
 +      int hdisplay;
 +      int hsync_start;
 +      int hsync_end;
 +      int htotal;
 +      int hskew;
 +      int vdisplay;
 +      int vsync_start;
 +      int vsync_end;
 +      int vtotal;
 +      int vscan;
 +      unsigned int flags;
 +
 +      /* Actual mode we give to hw */
 +      int clock_index;
 +      int synth_clock;
 +      int crtc_hdisplay;
 +      int crtc_hblank_start;
 +      int crtc_hblank_end;
 +      int crtc_hsync_start;
 +      int crtc_hsync_end;
 +      int crtc_htotal;
 +      int crtc_hskew;
 +      int crtc_vdisplay;
 +      int crtc_vblank_start;
 +      int crtc_vblank_end;
 +      int crtc_vsync_start;
 +      int crtc_vsync_end;
 +      int crtc_vtotal;
 +      int crtc_hadjusted;
 +      int crtc_vadjusted;
 +
 +      /* Driver private mode info */
 +      int private_size;
 +      int *private;
 +      int private_flags;
 +
 +      int vrefresh;
 +      float hsync;
 +};
 +
 +/* Video mode flags */
 +#define V_PHSYNC      (1<<0)
 +#define V_NHSYNC      (1<<1)
 +#define V_PVSYNC      (1<<2)
 +#define V_NVSYNC      (1<<3)
 +#define V_INTERLACE   (1<<4)
 +#define V_DBLSCAN     (1<<5)
 +#define V_CSYNC               (1<<6)
 +#define V_PCSYNC      (1<<7)
 +#define V_NCSYNC      (1<<8)
 +#define V_HSKEW               (1<<9) /* hskew provided */
 +#define V_BCAST               (1<<10)
 +#define V_PIXMUX      (1<<11)
 +#define V_DBLCLK      (1<<12)
 +#define V_CLKDIV2     (1<<13)
 +
 +#define CRTC_INTERLACE_HALVE_V 0x1 /* halve V values for interlacing */
 +#define DPMSModeOn 0
 +#define DPMSModeStandby 1
 +#define DPMSModeSuspend 2
 +#define DPMSModeOff 3
 +
 +enum drm_output_status {
 +      output_status_connected,
 +      output_status_disconnected,
 +      output_status_unknown,
 +};
 +
 +enum subpixel_order {
 +      SubPixelUnknown = 0,
 +      SubPixelHorizontalRGB,
 +      SubPixelHorizontalBGR,
 +      SubPixelVerticalRGB,
 +      SubPixelVerticalBGR,
 +      SubPixelNone,
 +};
 +
 +/*
 + * Describes a given display (e.g. CRT or flat panel) and its limitations.
 + */
 +struct drm_display_info {
 +      char name[DRM_DISPLAY_INFO_LEN];
 +      /* Input info */
 +      bool serration_vsync;
 +      bool sync_on_green;
 +      bool composite_sync;
 +      bool separate_syncs;
 +      bool blank_to_black;
 +      unsigned char video_level;
 +      bool digital;
 +      /* Physical size */
 +        unsigned int width_mm;
 +      unsigned int height_mm;
 +
 +      /* Display parameters */
 +      unsigned char gamma; /* FIXME: storage format */
 +      bool gtf_supported;
 +      bool standard_color;
 +      enum {
 +              monochrome,
 +              rgb,
 +              other,
 +              unknown,
 +      } display_type;
 +      bool active_off_supported;
 +      bool suspend_supported;
 +      bool standby_supported;
 +
 +      /* Color info FIXME: storage format */
 +      unsigned short redx, redy;
 +      unsigned short greenx, greeny;
 +      unsigned short bluex, bluey;
 +      unsigned short whitex, whitey;
 +
 +      /* Clock limits FIXME: storage format */
 +      unsigned int min_vfreq, max_vfreq;
 +      unsigned int min_hfreq, max_hfreq;
 +      unsigned int pixel_clock;
 +
 +      /* White point indices FIXME: storage format */
 +      unsigned int wpx1, wpy1;
 +      unsigned int wpgamma1;
 +      unsigned int wpx2, wpy2;
 +      unsigned int wpgamma2;
 +
 +      /* Preferred mode (if any) */
 +      struct drm_display_mode *preferred_mode;
 +      char *raw_edid; /* if any */
 +};
 +
 +struct drm_framebuffer {
 +      struct drm_device *dev;
 +      struct list_head head;
 +      int id; /* idr assigned */
 +      unsigned int pitch;
 +      unsigned long offset;
 +      unsigned int width;
 +      unsigned int height;
 +      /* depth can be 15 or 16 */
 +      unsigned int depth;
 +      int bits_per_pixel;
 +      int flags;
 +      struct drm_buffer_object *bo;
 +      void *fbdev;
 +      u32 pseudo_palette[17];
 +      void *virtual_base;
 +      struct list_head filp_head;
 +};
 +struct drm_crtc;
 +struct drm_output;
 +
 +/**
 + * drm_crtc_funcs - control CRTCs for a given device
 + * @dpms: control display power levels
 + * @save: save CRTC state
 + * @resore: restore CRTC state
 + * @lock: lock the CRTC
 + * @unlock: unlock the CRTC
 + * @shadow_allocate: allocate shadow pixmap
 + * @shadow_create: create shadow pixmap for rotation support
 + * @shadow_destroy: free shadow pixmap
 + * @mode_fixup: fixup proposed mode
 + * @mode_set: set the desired mode on the CRTC
 + * @gamma_set: specify color ramp for CRTC
 + * @cleanup: cleanup driver private state prior to close
 + *
 + * The drm_crtc_funcs structure is the central CRTC management structure
 + * in the DRM.  Each CRTC controls one or more outputs (note that the name
 + * CRTC is simply historical, a CRTC may control LVDS, VGA, DVI, TV out, etc.
 + * outputs, not just CRTs).
 + *
 + * Each driver is responsible for filling out this structure at startup time,
 + * in addition to providing other modesetting features, like i2c and DDC
 + * bus accessors.
 + */
 +struct drm_crtc_funcs {
 +      /*
 +       * Control power levels on the CRTC.  If the mode passed in is
 +       * unsupported, the provider must use the next lowest power level.
 +       */
 +      void (*dpms)(struct drm_crtc *crtc, int mode);
 +
 +      /* JJJ:  Are these needed? */
 +      /* Save CRTC state */
 +      void (*save)(struct drm_crtc *crtc); /* suspend? */
 +      /* Restore CRTC state */
 +      void (*restore)(struct drm_crtc *crtc); /* resume? */
 +      bool (*lock)(struct drm_crtc *crtc);
 +      void (*unlock)(struct drm_crtc *crtc);
 +
 +      void (*prepare)(struct drm_crtc *crtc);
 +      void (*commit)(struct drm_crtc *crtc);
 +
 +      /* Provider can fixup or change mode timings before modeset occurs */
 +      bool (*mode_fixup)(struct drm_crtc *crtc,
 +                         struct drm_display_mode *mode,
 +                         struct drm_display_mode *adjusted_mode);
 +      /* Actually set the mode */
 +      void (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode,
 +                       struct drm_display_mode *adjusted_mode, int x, int y);
 +      /* Set gamma on the CRTC */
 +      void (*gamma_set)(struct drm_crtc *crtc, u16 r, u16 g, u16 b,
 +                        int regno);
 +      /* Driver cleanup routine */
 +      void (*cleanup)(struct drm_crtc *crtc);
 +};
 +
 +/**
 + * drm_crtc - central CRTC control structure
 + * @enabled: is this CRTC enabled?
 + * @x: x position on screen
 + * @y: y position on screen
 + * @desired_mode: new desired mode
 + * @desired_x: desired x for desired_mode
 + * @desired_y: desired y for desired_mode
 + * @funcs: CRTC control functions
 + * @driver_private: arbitrary driver data
 + *
 + * Each CRTC may have one or more outputs associated with it.  This structure
 + * allows the CRTC to be controlled.
 + */
 +struct drm_crtc {
 +      struct drm_device *dev;
 +      struct list_head head;
 +
 +      int id; /* idr assigned */
 +
 +      /* framebuffer the output is currently bound to */
 +      struct drm_framebuffer *fb;
 +
 +      bool enabled;
 +
 +      /* JJJ: are these needed? */
 +      bool cursor_in_range;
 +      bool cursor_shown;
 +
 +      struct drm_display_mode mode;
 +
 +      int x, y;
 +      struct drm_display_mode *desired_mode;
 +      int desired_x, desired_y;
 +      const struct drm_crtc_funcs *funcs;
 +      void *driver_private;
 +
 +      /* RRCrtcPtr randr_crtc? */
 +};
 +
 +extern struct drm_crtc *drm_crtc_create(struct drm_device *dev,
 +                                      const struct drm_crtc_funcs *funcs);
 +
 +/**
 + * drm_output_funcs - control outputs on a given device
 + * @init: setup this output
 + * @dpms: set power state (see drm_crtc_funcs above)
 + * @save: save output state
 + * @restore: restore output state
 + * @mode_valid: is this mode valid on the given output?
 + * @mode_fixup: try to fixup proposed mode for this output
 + * @mode_set: set this mode
 + * @detect: is this output active?
 + * @get_modes: get mode list for this output
 + * @set_property: property for this output may need update
 + * @cleanup: output is going away, cleanup
 + *
 + * Each CRTC may have one or more outputs attached to it.  The functions
 + * below allow the core DRM code to control outputs, enumerate available modes,
 + * etc.
 + */
 +struct drm_output_funcs {
 +      void (*init)(struct drm_output *output);
 +      void (*dpms)(struct drm_output *output, int mode);
 +      void (*save)(struct drm_output *output);
 +      void (*restore)(struct drm_output *output);
 +      int (*mode_valid)(struct drm_output *output,
 +                        struct drm_display_mode *mode);
 +      bool (*mode_fixup)(struct drm_output *output,
 +                         struct drm_display_mode *mode,
 +                         struct drm_display_mode *adjusted_mode);
 +      void (*prepare)(struct drm_output *output);
 +      void (*commit)(struct drm_output *output);
 +      void (*mode_set)(struct drm_output *output,
 +                       struct drm_display_mode *mode,
 +                       struct drm_display_mode *adjusted_mode);
 +      enum drm_output_status (*detect)(struct drm_output *output);
 +      int (*get_modes)(struct drm_output *output);
 +      /* JJJ: type checking for properties via property value type */
 +      bool (*set_property)(struct drm_output *output, int prop, void *val);
 +      void (*cleanup)(struct drm_output *output);
 +};
 +
 +#define DRM_OUTPUT_MAX_UMODES 16
 +#define DRM_OUTPUT_LEN 32
 +/**
 + * drm_output - central DRM output control structure
 + * @crtc: CRTC this output is currently connected to, NULL if none
 + * @possible_crtcs: bitmap of CRTCS this output could be attached to
 + * @possible_clones: bitmap of possible outputs this output could clone
 + * @interlace_allowed: can this output handle interlaced modes?
 + * @doublescan_allowed: can this output handle doublescan?
 + * @available_modes: modes available on this output (from get_modes() + user)
 + * @initial_x: initial x position for this output
 + * @initial_y: initial y position for this output
 + * @status: output connected?
 + * @subpixel_order: for this output
 + * @mm_width: displayable width of output in mm
 + * @mm_height: displayable height of output in mm
 + * @name: name of output (should be one of a few standard names)
 + * @funcs: output control functions
 + * @driver_private: private driver data
 + *
 + * Each output may be connected to one or more CRTCs, or may be clonable by
 + * another output if they can share a CRTC.  Each output also has a specific
 + * position in the broader display (referred to as a 'screen' though it could
 + * span multiple monitors).
 + */
 +struct drm_output {
 +      struct drm_device *dev;
 +      struct list_head head;
 +      struct drm_crtc *crtc;
 +      int id; /* idr assigned */
 +      unsigned long possible_crtcs;
 +      unsigned long possible_clones;
 +      bool interlace_allowed;
 +      bool doublescan_allowed;
 +      struct list_head modes; /* list of modes on this output */
 +
 +      /*
 +        OptionInfoPtr options;
 +        XF86ConfMonitorPtr conf_monitor;
 +       */
 +      int initial_x, initial_y;
 +      enum drm_output_status status;
 +
 +      /* these are modes added by probing with DDC or the BIOS */
 +      struct list_head probed_modes;
 +      
 +      /* xf86MonPtr MonInfo; */
 +      enum subpixel_order subpixel_order;
 +      int mm_width, mm_height;
 +      struct drm_display_info *monitor_info; /* if any */
 +      char name[DRM_OUTPUT_LEN];
 +      const struct drm_output_funcs *funcs;
 +      void *driver_private;
 +
 +      u32 user_mode_ids[DRM_OUTPUT_MAX_UMODES];
 +
 +};
 +
 +/**
 + * struct drm_mode_config_funcs - configure CRTCs for a given screen layout
 + * @resize: adjust CRTCs as necessary for the proposed layout
 + *
 + * Currently only a resize hook is available.  DRM will call back into the
 + * driver with a new screen width and height.  If the driver can't support
 + * the proposed size, it can return false.  Otherwise it should adjust
 + * the CRTC<->output mappings as needed and update its view of the screen.
 + */
 +struct drm_mode_config_funcs {
 +      bool (*resize)(struct drm_device *dev, int width, int height);
 +};
 +
 +/**
 + * drm_mode_config - Mode configuration control structure
 + *
 + */
 +struct drm_mode_config {
 +      struct mutex mutex; /* protects configuration and IDR */
 +      struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, output, modes - just makes life easier */
 +      /* this is limited to one for now */
 +      int num_fb;
 +      struct list_head fb_list;
 +      int num_output;
 +      struct list_head output_list;
 +
 +      /* int compat_output? */
 +      int num_crtc;
 +      struct list_head crtc_list;
 +
 +      struct list_head usermode_list;
 +      int min_width, min_height;
 +      int max_width, max_height;
 +      /* DamagePtr rotationDamage? */
 +      /* DGA stuff? */
 +      struct drm_mode_config_funcs *funcs;
 +      unsigned long fb_base;
 +};
 +
 +struct drm_output *drm_output_create(struct drm_device *dev,
 +                                   const struct drm_output_funcs *funcs,
 +                                   const char *name);
 +extern void drm_output_destroy(struct drm_output *output);
 +extern bool drm_output_rename(struct drm_output *output, const char *name);
 +extern void drm_fb_release(struct file *filp);
 +
 +extern int drm_add_edid_modes(struct drm_output *output,
 +                      struct i2c_adapter *adapter);
 +extern void drm_mode_probed_add(struct drm_output *output, struct drm_display_mode *mode);
 +extern void drm_mode_remove(struct drm_output *output, struct drm_display_mode *mode);
 +extern struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
 +                                                 struct drm_display_mode *mode);
 +extern void drm_mode_debug_printmodeline(struct drm_device *dev,
 +                                       struct drm_display_mode *mode);
 +extern void drm_mode_config_init(struct drm_device *dev);
 +extern void drm_mode_config_cleanup(struct drm_device *dev);
 +extern void drm_mode_set_name(struct drm_display_mode *mode);
 +extern bool drm_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode *mode2);
 +extern void drm_disable_unused_functions(struct drm_device *dev);
 +
 +extern struct drm_display_mode *drm_mode_create(struct drm_device *dev);
 +extern void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode);
 +extern void drm_mode_list_concat(struct list_head *head,
 +                               struct list_head *new);
 +extern void drm_mode_validate_size(struct drm_device *dev,
 +                                 struct list_head *mode_list,
 +                                 int maxX, int maxY, int maxPitch);
 +extern void drm_mode_prune_invalid(struct drm_device *dev,
 +                                 struct list_head *mode_list, bool verbose);
 +extern void drm_mode_sort(struct list_head *mode_list);
 +extern int drm_mode_vrefresh(struct drm_display_mode *mode);
 +extern void drm_mode_set_crtcinfo(struct drm_display_mode *p,
 +                                int adjust_flags);
 +extern void drm_mode_output_list_update(struct drm_output *output);
 +
 +extern struct drm_display_mode *drm_crtc_mode_create(struct drm_device *dev);
 +extern bool drm_initial_config(struct drm_device *dev, bool cangrow);
 +extern void drm_framebuffer_set_object(struct drm_device *dev,
 +                                     unsigned long handle);
 +extern struct drm_framebuffer *drm_framebuffer_create(struct drm_device *dev);
 +extern void drm_framebuffer_destroy(struct drm_framebuffer *fb);
 +extern int drmfb_probe(struct drm_device *dev, struct drm_crtc *crtc);
 +extern int drmfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
 +extern bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
 +                     int x, int y);
 +
 +/* IOCTLs */
++extern int drm_mode_getresources(struct drm_device *dev,
++                               void *data, struct drm_file *file_priv);
++
++extern int drm_mode_getcrtc(struct drm_device *dev,
++                          void *data, struct drm_file *file_priv);
++extern int drm_mode_getoutput(struct drm_device *dev,
++                            void *data, struct drm_file *file_priv);
++extern int drm_mode_setcrtc(struct drm_device *dev,
++                          void *data, struct drm_file *file_priv);
++extern int drm_mode_addfb(struct drm_device *dev,
++                        void *data, struct drm_file *file_priv);
++extern int drm_mode_rmfb(struct drm_device *dev,
++                       void *data, struct drm_file *file_priv);
++extern int drm_mode_getfb(struct drm_device *dev,
++                        void *data, struct drm_file *file_priv);
++extern int drm_mode_addmode(struct drm_device *dev,
++                          void *data, struct drm_file *file_priv);
++extern int drm_mode_rmmode(struct drm_device *dev,
++                         void *data, struct drm_file *file_priv);
++extern int drm_mode_attachmode(struct drm_device *dev,
++                             void *data, struct drm_file *file_priv);
++extern int drm_mode_detachmode(struct drm_device *dev,
++                             void *data, struct drm_file *file_priv);
 +
 +#endif /* __DRM_CRTC_H__ */
 +
  #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_MODE_GETRESOURCES)] = {drm_mode_getresources, DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_MODE_GETCRTC)] = {drm_mode_getcrtc, DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_MODE_GETOUTPUT)] = {drm_mode_getoutput, DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_MODE_SETCRTC)] = {drm_mode_setcrtc, DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_MODE_ADDFB)] = {drm_mode_addfb, DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_MODE_RMFB)] = {drm_mode_rmfb, DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_MODE_GETFB)] = {drm_mode_getfb, DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_MODE_ADDMODE)] = {drm_mode_addmode, DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_MODE_RMMODE)] = {drm_mode_rmmode, DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_MODE_ATTACHMODE)] = {drm_mode_attachmode, DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_IOCTL_MODE_DETACHMODE)] = {drm_mode_detachmode, DRM_MASTER|DRM_ROOT_ONLY},
+       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_MM_INIT, drm_mm_init_ioctl, 
++                                           DRM_AUTH ),
++      DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
++      DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_ROOT_ONLY),
++      DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_ROOT_ONLY),
++      DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETOUTPUT, drm_mode_getoutput, DRM_MASTER|DRM_ROOT_ONLY),
++      DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_ROOT_ONLY),
++      DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_ROOT_ONLY),
++      DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_ROOT_ONLY),
++      DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_ROOT_ONLY),
++      DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDMODE, drm_mode_addmode, DRM_MASTER|DRM_ROOT_ONLY),
++      DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMMODE, drm_mode_rmmode, DRM_MASTER|DRM_ROOT_ONLY),
++      DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode, DRM_MASTER|DRM_ROOT_ONLY),
++      DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode, DRM_MASTER|DRM_ROOT_ONLY),
+       //      DRM_IOCTL_DEF(DRM_IOCTL_BUFOBJ, drm_bo_ioctl, DRM_AUTH),
+       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_IOCTL_DEF(DRM_IOCTL_MM_TAKEDOWN, drm_mm_takedown_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_MM_LOCK, drm_mm_lock_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_MM_UNLOCK, drm_mm_unlock_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_FENCE_CREATE, drm_fence_create_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_IOCTL_FENCE_DESTROY, drm_fence_destroy_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_DESTROY, drm_bo_destroy_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_OP, drm_bo_op_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_SET_PIN, drm_bo_set_pin_ioctl, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY),
  };
  
  #define DRM_CORE_IOCTL_COUNT  ARRAY_SIZE( drm_ioctls )
index 0d06792,0000000..d7d3939
mode 100644,000000..100644
--- /dev/null
@@@ -1,467 -1,0 +1,467 @@@
- struct drm_display_mode *drm_mode_detailed(drm_device_t *dev,
 +/*
 + * Copyright (c) 2007 Intel Corporation
 + *   Jesse Barnes <jesse.barnes@intel.com>
 + *
 + * DDC probing routines (drm_ddc_read & drm_do_probe_ddc_edid) originally from
 + * FB layer.
 + *   Copyright (C) 2006 Dennis Munsie <dmunsie@cecropia.com>
 + */
 +#include <linux/i2c.h>
 +#include <linux/i2c-algo-bit.h>
 +#include "drmP.h"
 +#include "drm_edid.h"
 +
 +/* Valid EDID header has these bytes */
 +static u8 edid_header[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
 +
 +/**
 + * edid_valid - sanity check EDID data
 + * @edid: EDID data
 + *
 + * Sanity check the EDID block by looking at the header, the version number
 + * and the checksum.  Return 0 if the EDID doesn't check out, or 1 if it's
 + * valid.
 + */
 +static bool edid_valid(struct edid *edid)
 +{
 +      int i;
 +      u8 csum = 0;
 +      u8 *raw_edid = (u8 *)edid;
 +
 +      if (memcmp(edid->header, edid_header, sizeof(edid_header)))
 +              goto bad;
 +      if (edid->version != 1)
 +              goto bad;
 +      if (edid->revision <= 0 || edid->revision > 3)
 +              goto bad;
 +
 +      for (i = 0; i < EDID_LENGTH; i++)
 +              csum += raw_edid[i];
 +      if (csum)
 +              goto bad;
 +
 +      return 1;
 +
 +bad:
 +      return 0;
 +}
 +
 +/**
 + * drm_mode_std - convert standard mode info (width, height, refresh) into mode
 + * @t: standard timing params
 + *
 + * Take the standard timing params (in this case width, aspect, and refresh)
 + * and convert them into a real mode using CVT.
 + *
 + * Punts for now, but should eventually use the FB layer's CVT based mode
 + * generation code.
 + */
 +struct drm_display_mode *drm_mode_std(struct drm_device *dev,
 +                                    struct std_timing *t)
 +{
 +//    struct fb_videomode mode;
 +
 +//    fb_find_mode_cvt(&mode, 0, 0);
 +      /* JJJ:  convert to drm_display_mode */
 +      struct drm_display_mode *mode;
 +      int hsize = t->hsize * 8 + 248, vsize;
 +
 +      mode = drm_mode_create(dev);
 +      if (!mode)
 +              return NULL;
 +
 +      if (t->aspect_ratio == 0)
 +              vsize = (hsize * 10) / 16;
 +      else if (t->aspect_ratio == 1)
 +              vsize = (hsize * 3) / 4;
 +      else if (t->aspect_ratio == 2)
 +              vsize = (hsize * 4) / 5;
 +      else
 +              vsize = (hsize * 9) / 16;
 +
 +      drm_mode_set_name(mode);
 +
 +      return mode;
 +}
 +
 +/**
 + * drm_mode_detailed - create a new mode from an EDID detailed timing section
 + * @timing: EDID detailed timing info
 + * @preferred: is this a preferred mode?
 + *
 + * An EDID detailed timing block contains enough info for us to create and
 + * return a new struct drm_display_mode.  The @preferred flag will be set
 + * if this is the display's preferred timing, and we'll use it to indicate
 + * to the other layers that this mode is desired.
 + */
++struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
 +                                         struct detailed_timing *timing)
 +{
 +      struct drm_display_mode *mode;
 +      struct detailed_pixel_timing *pt = &timing->data.pixel_data;
 +
 +      if (pt->stereo) {
 +              printk(KERN_WARNING "stereo mode not supported\n");
 +              return NULL;
 +      }
 +      if (!pt->separate_sync) {
 +              printk(KERN_WARNING "integrated sync not supported\n");
 +              return NULL;
 +      }
 +
 +      mode = drm_mode_create(dev);
 +      if (!mode)
 +              return NULL;
 +
 +      mode->type = DRM_MODE_TYPE_DRIVER;
 +      mode->clock = timing->pixel_clock * 10;
 +
 +      mode->hdisplay = (pt->hactive_hi << 8) | pt->hactive_lo;
 +      mode->hsync_start = mode->hdisplay + ((pt->hsync_offset_hi << 8) |
 +                                            pt->hsync_offset_lo);
 +      mode->hsync_end = mode->hsync_start +
 +              ((pt->hsync_pulse_width_hi << 8) |
 +               pt->hsync_pulse_width_lo);
 +      mode->htotal = mode->hdisplay + ((pt->hblank_hi << 8) | pt->hblank_lo);
 +
 +      mode->vdisplay = (pt->vactive_hi << 8) | pt->vactive_lo;
 +      mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 8) |
 +                                            pt->vsync_offset_lo);
 +      mode->vsync_end = mode->vsync_start +
 +              ((pt->vsync_pulse_width_hi << 8) |
 +               pt->vsync_pulse_width_lo);
 +      mode->vtotal = mode->vdisplay + ((pt->vblank_hi << 8) | pt->vblank_lo);
 +
 +      drm_mode_set_name(mode);
 +
 +      if (pt->interlaced)
 +              mode->flags |= V_INTERLACE;
 +
 +      mode->flags |= pt->hsync_positive ? V_PHSYNC : V_NHSYNC;
 +      mode->flags |= pt->vsync_positive ? V_PVSYNC : V_NVSYNC;
 +
 +      return mode;
 +}
 +
 +/*
 + * Detailed mode info for the EDID "established modes" data to use.
 + */
 +static struct drm_display_mode edid_est_modes[] = {
 +      { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
 +                 968, 1056, 0, 600, 601, 605, 628, 0,
 +                 V_PHSYNC | V_PVSYNC) }, /* 800x600@60Hz */
 +      { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
 +                 896, 1024, 0, 600, 601, 603,  625, 0,
 +                 V_PHSYNC | V_PVSYNC) }, /* 800x600@56Hz */
 +      { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
 +                 720, 840, 0, 480, 481, 484, 500, 0,
 +                 V_NHSYNC | V_NVSYNC) }, /* 640x480@75Hz */
 +      { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
 +                 704,  832, 0, 480, 489, 491, 520, 0,
 +                 V_NHSYNC | V_NVSYNC) }, /* 640x480@72Hz */
 +      { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 30240, 640, 704,
 +                 768,  864, 0, 480, 483, 486, 525, 0,
 +                 V_NHSYNC | V_NVSYNC) }, /* 640x480@67Hz */
 +      { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25200, 640, 656,
 +                 752, 800, 0, 480, 490, 492, 525, 0,
 +                 V_NHSYNC | V_NVSYNC) }, /* 640x480@60Hz */
 +      { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 738,
 +                 846, 900, 0, 400, 421, 423,  449, 0,
 +                 V_NHSYNC | V_NVSYNC) }, /* 720x400@88Hz */
 +      { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 28320, 720, 738,
 +                 846,  900, 0, 400, 412, 414, 449, 0,
 +                 V_NHSYNC | V_PVSYNC) }, /* 720x400@70Hz */
 +      { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
 +                 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
 +                 V_PHSYNC | V_PVSYNC) }, /* 1280x1024@75Hz */
 +      { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78800, 1024, 1040,
 +                 1136, 1312, 0,  768, 769, 772, 800, 0,
 +                 V_PHSYNC | V_PVSYNC) }, /* 1024x768@75Hz */
 +      { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
 +                 1184, 1328, 0,  768, 771, 777, 806, 0,
 +                 V_NHSYNC | V_NVSYNC) }, /* 1024x768@70Hz */
 +      { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
 +                 1184, 1344, 0,  768, 771, 777, 806, 0,
 +                 V_NHSYNC | V_NVSYNC) }, /* 1024x768@60Hz */
 +      { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER,44900, 1024, 1032,
 +                 1208, 1264, 0, 768, 768, 776, 817, 0,
 +                 V_PHSYNC | V_PVSYNC | V_INTERLACE) }, /* 1024x768@43Hz */
 +      { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 57284, 832, 864,
 +                 928, 1152, 0, 624, 625, 628, 667, 0,
 +                 V_NHSYNC | V_NVSYNC) }, /* 832x624@75Hz */
 +      { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
 +                 896, 1056, 0, 600, 601, 604,  625, 0,
 +                 V_PHSYNC | V_PVSYNC) }, /* 800x600@75Hz */
 +      { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
 +                 976, 1040, 0, 600, 637, 643, 666, 0,
 +                 V_PHSYNC | V_PVSYNC) }, /* 800x600@72Hz */
 +      { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
 +                 1344, 1600, 0,  864, 865, 868, 900, 0,
 +                 V_PHSYNC | V_PVSYNC) }, /* 1152x864@75Hz */
 +};
 +
 +#define EDID_EST_TIMINGS 16
 +#define EDID_STD_TIMINGS 8
 +#define EDID_DETAILED_TIMINGS 4
 +
 +/**
 + * add_established_modes - get est. modes from EDID and add them
 + * @edid: EDID block to scan
 + *
 + * Each EDID block contains a bitmap of the supported "established modes" list
 + * (defined above).  Tease them out and add them to the global modes list.
 + */
 +static int add_established_modes(struct drm_output *output, struct edid *edid)
 +{
 +      struct drm_device *dev = output->dev;
 +      unsigned long est_bits = edid->established_timings.t1 |
 +              (edid->established_timings.t2 << 8) |
 +              ((edid->established_timings.mfg_rsvd & 0x80) << 9);
 +      int i, modes = 0;
 +
 +      for (i = 0; i <= EDID_EST_TIMINGS; i++)
 +              if (est_bits & (1<<i)) {
 +                      struct drm_display_mode *newmode;
 +                      newmode = drm_mode_duplicate(dev, &edid_est_modes[i]);
 +                      drm_mode_probed_add(output, newmode);
 +                      modes++;
 +              }
 +
 +      return modes;
 +}
 +
 +/**
 + * add_standard_modes - get std. modes from EDID and add them
 + * @edid: EDID block to scan
 + *
 + * Standard modes can be calculated using the CVT standard.  Grab them from
 + * @edid, calculate them, and add them to the list.
 + */
 +static int add_standard_modes(struct drm_output *output, struct edid *edid)
 +{
 +      struct drm_device *dev = output->dev;
 +      int i, modes = 0;
 +
 +      for (i = 0; i < EDID_STD_TIMINGS; i++) {
 +              struct std_timing *t = &edid->standard_timings[i];
 +              struct drm_display_mode *newmode;
 +
 +              /* If std timings bytes are 1, 1 it's empty */
 +              if (t->hsize == 1 && (t->aspect_ratio | t->vfreq) == 1)
 +                      continue;
 +
 +              newmode = drm_mode_std(dev, &edid->standard_timings[i]);
 +              drm_mode_probed_add(output, newmode);
 +              modes++;
 +      }
 +
 +      return modes;
 +}
 +
 +/**
 + * add_detailed_modes - get detailed mode info from EDID data
 + * @edid: EDID block to scan
 + *
 + * Some of the detailed timing sections may contain mode information.  Grab
 + * it and add it to the list.
 + */
 +static int add_detailed_info(struct drm_output *output, struct edid *edid)
 +{
 +      struct drm_device *dev = output->dev;
 +      int i, j, modes = 0;
 +
 +      for (i = 0; i < EDID_DETAILED_TIMINGS; i++) {
 +              struct detailed_timing *timing = &edid->detailed_timings[i];
 +              struct detailed_non_pixel *data = &timing->data.other_data;
 +              struct drm_display_mode *newmode;
 +
 +              /* EDID up to and including 1.2 may put monitor info here */
 +              if (edid->version == 1 && edid->revision < 3)
 +                      continue;
 +
 +              /* Detailed mode timing */
 +              if (timing->pixel_clock) {
 +                      newmode = drm_mode_detailed(dev, timing);
 +                      /* First detailed mode is preferred */
 +                      if (i == 0 && edid->preferred_timing)
 +                              newmode->type |= DRM_MODE_TYPE_PREFERRED;
 +                      drm_mode_probed_add(output, newmode);
 +                                   
 +                      modes++;
 +                      continue;
 +              }
 +
 +              /* Other timing or info */
 +              switch (data->type) {
 +              case EDID_DETAIL_MONITOR_SERIAL:
 +                      break;
 +              case EDID_DETAIL_MONITOR_STRING:
 +                      break;
 +              case EDID_DETAIL_MONITOR_RANGE:
 +                      /* Get monitor range data */
 +                      break;
 +              case EDID_DETAIL_MONITOR_NAME:
 +                      break;
 +              case EDID_DETAIL_MONITOR_CPDATA:
 +                      break;
 +              case EDID_DETAIL_STD_MODES:
 +                      /* Five modes per detailed section */
 +                      for (j = 0; j < 5; i++) {
 +                              struct std_timing *std;
 +                              struct drm_display_mode *newmode;
 +
 +                              std = &data->data.timings[j];
 +                              newmode = drm_mode_std(dev, std);
 +                              drm_mode_probed_add(output, newmode);
 +                              modes++;
 +                      }
 +                      break;
 +              default:
 +                      break;
 +              }
 +      }
 +
 +      return modes;
 +}
 +
 +#define DDC_ADDR 0x50
 +
 +static unsigned char *drm_do_probe_ddc_edid(struct i2c_adapter *adapter)
 +{
 +      unsigned char start = 0x0;
 +      unsigned char *buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
 +      struct i2c_msg msgs[] = {
 +              {
 +                      .addr   = DDC_ADDR,
 +                      .flags  = 0,
 +                      .len    = 1,
 +                      .buf    = &start,
 +              }, {
 +                      .addr   = DDC_ADDR,
 +                      .flags  = I2C_M_RD,
 +                      .len    = EDID_LENGTH,
 +                      .buf    = buf,
 +              }
 +      };
 +
 +      if (!buf) {
 +              dev_warn(&adapter->dev, "unable to allocate memory for EDID "
 +                       "block.\n");
 +              return NULL;
 +      }
 +
 +      if (i2c_transfer(adapter, msgs, 2) == 2)
 +              return buf;
 +
 +      dev_info(&adapter->dev, "unable to read EDID block.\n");
 +      kfree(buf);
 +      return NULL;
 +}
 +
 +static unsigned char *drm_ddc_read(struct i2c_adapter *adapter)
 +{
 +      struct i2c_algo_bit_data *algo_data = adapter->algo_data;
 +      unsigned char *edid = NULL;
 +      int i, j;
 +
 +      /*
 +       * Startup the bus:
 +       *   Set clock line high (but give it time to come up)
 +       *   Then set clock & data low
 +       */
 +      algo_data->setscl(algo_data->data, 1);
 +      udelay(550); /* startup delay */
 +      algo_data->setscl(algo_data->data, 0);
 +      algo_data->setsda(algo_data->data, 0);
 +
 +      for (i = 0; i < 3; i++) {
 +              /* For some old monitors we need the
 +               * following process to initialize/stop DDC
 +               */
 +              algo_data->setsda(algo_data->data, 0);
 +              msleep(13);
 +
 +              algo_data->setscl(algo_data->data, 1);
 +              for (j = 0; j < 5; j++) {
 +                      msleep(10);
 +                      if (algo_data->getscl(algo_data->data))
 +                              break;
 +              }
 +              if (j == 5)
 +                      continue;
 +
 +              algo_data->setsda(algo_data->data, 0);
 +              msleep(15);
 +              algo_data->setscl(algo_data->data, 0);
 +              msleep(15);
 +              algo_data->setsda(algo_data->data, 1);
 +              msleep(15);
 +
 +              /* Do the real work */
 +              edid = drm_do_probe_ddc_edid(adapter);
 +              algo_data->setsda(algo_data->data, 0);
 +              algo_data->setscl(algo_data->data, 0);
 +              msleep(15);
 +
 +              algo_data->setscl(algo_data->data, 1);
 +              for (j = 0; j < 10; j++) {
 +                      msleep(10);
 +                      if (algo_data->getscl(algo_data->data))
 +                              break;
 +              }
 +
 +              algo_data->setsda(algo_data->data, 1);
 +              msleep(15);
 +              algo_data->setscl(algo_data->data, 0);
 +              if (edid)
 +                      break;
 +      }
 +      /* Release the DDC lines when done or the Apple Cinema HD display
 +       * will switch off
 +       */
 +      algo_data->setsda(algo_data->data, 0);
 +      algo_data->setscl(algo_data->data, 0);
 +      algo_data->setscl(algo_data->data, 1);
 +
 +      return edid;
 +}
 +
 +/**
 + * drm_add_edid_modes - add modes from EDID data, if available
 + * @output: output we're probing
 + * @adapter: i2c adapter to use for DDC
 + *
 + * Poke the given output's i2c channel to grab EDID data if possible.  If we
 + * get any, add the specified modes to the output's mode list.
 + *
 + * Return number of modes added or 0 if we couldn't find any.
 + */
 +int drm_add_edid_modes(struct drm_output *output, struct i2c_adapter *adapter)
 +{
 +      struct edid *edid;
 +      int num_modes = 0;
 +
 +      edid = (struct edid *)drm_ddc_read(adapter);
 +      if (!edid) {
 +              dev_warn(&output->dev->pdev->dev, "%s: no EDID data\n",
 +                       output->name);
 +              goto out_err;
 +      }
 +
 +      if (!edid_valid(edid)) {
 +              dev_warn(&output->dev->pdev->dev, "%s: EDID invalid.\n",
 +                       output->name);
 +              goto out_err;
 +      }
 +
 +      num_modes += add_established_modes(output, edid);
 +      num_modes += add_standard_modes(output, edid);
 +      num_modes += add_detailed_info(output, edid);
 +
 +      return num_modes;
 +
 +out_err:
 +      kfree(edid);
 +      return 0;
 +}
 +EXPORT_SYMBOL(drm_add_edid_modes);
@@@ -487,10 -486,9 +487,10 @@@ int drm_release(struct inode *inode, st
        mutex_unlock(&dev->ctxlist_mutex);
  
        mutex_lock(&dev->struct_mutex);
 +      drm_fb_release(filp);
        drm_object_release(filp);
-       if (priv->remove_auth_on_close == 1) {
-               drm_file_t *temp;
+       if (file_priv->remove_auth_on_close == 1) {
+               struct drm_file *temp;
  
                list_for_each_entry(temp, &dev->filelist, lhead)
                        temp->authenticated = 0;
@@@ -428,15 -446,22 +446,21 @@@ struct drm_bo_driver 
  /*
   * buffer objects (drm_bo.c)
   */
- extern int drm_bo_init_mm(struct drm_device * dev, unsigned type,
-                         unsigned long p_offset, unsigned long p_size);
- extern int drm_buffer_object_create(struct drm_device *dev, unsigned long size,
-                                   drm_bo_type_t type, uint32_t mask,
-                                   uint32_t hint, uint32_t page_alignment,
-                                   unsigned long buffer_start,
-                                   drm_buffer_object_t ** buf_obj);
- extern int drm_bo_ioctl(DRM_IOCTL_ARGS);
- extern int drm_mm_init_ioctl(DRM_IOCTL_ARGS);
 -
+ extern int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int drm_bo_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int drm_bo_map_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int drm_bo_unmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int drm_bo_reference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int drm_bo_unreference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int drm_bo_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int drm_bo_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int drm_bo_op_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ int drm_bo_set_pin_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int drm_mm_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int drm_mm_takedown_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int drm_mm_lock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int drm_mm_unlock_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
  extern int drm_bo_driver_finish(struct drm_device *dev);
  extern int drm_bo_driver_init(struct drm_device *dev);
  extern int drm_bo_pci_offset(struct drm_device *dev,
                             unsigned long *bus_base,
                             unsigned long *bus_offset,
                             unsigned long *bus_size);
- extern int drm_mem_reg_is_pci(struct drm_device *dev, drm_bo_mem_reg_t * mem);
+ extern int drm_mem_reg_is_pci(struct drm_device *dev, struct drm_bo_mem_reg * mem);
  
- extern void drm_bo_usage_deref_locked(drm_buffer_object_t ** bo);
- extern int drm_fence_buffer_objects(drm_file_t * priv,
+ extern void drm_bo_usage_deref_locked(struct drm_buffer_object ** bo);
+ extern int drm_fence_buffer_objects(struct drm_file * priv,
                                    struct list_head *list,
                                    uint32_t fence_flags,
-                                   drm_fence_object_t * fence,
-                                   drm_fence_object_t ** used_fence);
- extern void drm_bo_add_to_lru(drm_buffer_object_t * bo);
- extern int drm_bo_wait(drm_buffer_object_t * bo, int lazy, int ignore_signals,
+                                   struct drm_fence_object * fence,
+                                   struct drm_fence_object ** used_fence);
+ extern void drm_bo_add_to_lru(struct drm_buffer_object * bo);
+ extern int drm_bo_wait(struct drm_buffer_object * bo, int lazy, int ignore_signals,
                       int no_wait);
- extern int drm_bo_mem_space(drm_buffer_object_t * bo,
-                           drm_bo_mem_reg_t * mem, int no_wait);
- extern int drm_bo_move_buffer(drm_buffer_object_t * bo, uint32_t new_mem_flags,
+ extern int drm_bo_mem_space(struct drm_buffer_object * bo,
+                           struct drm_bo_mem_reg * mem, int no_wait);
+ extern int drm_bo_move_buffer(struct drm_buffer_object * bo, uint32_t new_mem_flags,
                              int no_wait, int move_unfenced);
+ extern int drm_buffer_object_create(struct drm_device *dev, unsigned long size,
+                                   enum drm_bo_type type, uint64_t mask,
+                                   uint32_t hint, uint32_t page_alignment,
+                                   unsigned long buffer_start,
+                                   struct drm_buffer_object **bo);
+ extern int drm_bo_init_mm(struct drm_device *dev, unsigned type,
+                         unsigned long p_offset, unsigned long p_size);
  extern int drm_bo_clean_mm(struct drm_device *dev, unsigned mem_type);
+ extern int drm_bo_add_user_object(struct drm_file *file_priv,
+                                 struct drm_buffer_object *bo, int sharable);
+ extern void drm_bo_usage_deref_unlocked(struct drm_buffer_object **bo);
++extern int drm_bo_set_pin(struct drm_device *dev,
++                        struct drm_buffer_object *bo, int pin);
  
  /*
   * Buffer object memory move helpers.
@@@ -477,12 -512,13 +513,17 @@@ extern int drm_bo_move_accel_cleanup(st
                                     uint32_t fence_class,
                                     uint32_t fence_type,
                                     uint32_t fence_flags,
-                                    drm_bo_mem_reg_t * new_mem);
+                                    struct drm_bo_mem_reg * new_mem);
+ extern int drm_mem_reg_ioremap(struct drm_device *dev,
+                              struct drm_bo_mem_reg *mem, void **virtual);
+ extern void drm_mem_reg_iounmap(struct drm_device *dev,
+                               struct drm_bo_mem_reg *mem, void *virtual);
  
- extern int drm_mem_reg_ioremap(struct drm_device *dev, drm_bo_mem_reg_t * mem,
++extern int drm_mem_reg_ioremap(struct drm_device *dev, struct drm_bo_mem_reg * mem,
 +                             void **virtual);
- extern void drm_mem_reg_iounmap(struct drm_device *dev, drm_bo_mem_reg_t * mem,
++extern void drm_mem_reg_iounmap(struct drm_device *dev, struct drm_bo_mem_reg * mem,
 +                              void *virtual);
  #ifdef CONFIG_DEBUG_MUTEXES
  #define DRM_ASSERT_LOCKED(_mutex)                                     \
        BUG_ON(!mutex_is_locked(_mutex) ||                              \
Simple merge
@@@ -127,7 -123,7 +126,7 @@@ static void i915_emit_copy_blit(struct 
  {
        uint32_t cur_pages;
        uint32_t stride = PAGE_SIZE;
--      drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
        RING_LOCALS;
  
        if (!dev_priv)
@@@ -53,10 -52,10 +53,10 @@@ static struct drm_fence_driver i915_fen
  #endif
  #ifdef I915_HAVE_BUFFER
  
 -static uint32_t i915_mem_prios[] = {DRM_BO_MEM_PRIV0, DRM_BO_MEM_TT, DRM_BO_MEM_LOCAL};
 -static uint32_t i915_busy_prios[] = {DRM_BO_MEM_TT, DRM_BO_MEM_PRIV0, DRM_BO_MEM_LOCAL};
 +static uint32_t i915_mem_prios[] = {DRM_BO_MEM_VRAM, DRM_BO_MEM_PRIV0, DRM_BO_MEM_TT, DRM_BO_MEM_LOCAL};
 +static uint32_t i915_busy_prios[] = {DRM_BO_MEM_TT, DRM_BO_MEM_PRIV0, DRM_BO_MEM_VRAM, DRM_BO_MEM_LOCAL};
  
- static drm_bo_driver_t i915_bo_driver = {
+ static struct drm_bo_driver i915_bo_driver = {
        .mem_type_prio = i915_mem_prios,
        .mem_busy_prio = i915_busy_prios,
        .num_mem_type_prio = sizeof(i915_mem_prios)/sizeof(uint32_t),
   * Implements an intel sync flush operation.
   */
  
- static void i915_perform_flush(drm_device_t * dev)
+ static void i915_perform_flush(struct drm_device * dev)
  {
--      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       drm_fence_manager_t *fm = &dev->fm;
-       drm_fence_class_manager_t *fc = &fm->class[0];
-       drm_fence_driver_t *driver = dev->driver->fence_driver;
++      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+       struct drm_fence_manager *fm = &dev->fm;
+       struct drm_fence_class_manager *fc = &fm->class[0];
+       struct drm_fence_driver *driver = dev->driver->fence_driver;
        uint32_t flush_flags = 0;
        uint32_t flush_sequence = 0;
        uint32_t i_status;
@@@ -119,10 -119,10 +119,10 @@@ void i915_poke_flush(struct drm_device 
        write_unlock_irqrestore(&fm->lock, flags);
  }
  
- int i915_fence_emit_sequence(drm_device_t * dev, uint32_t class, uint32_t flags,
+ int i915_fence_emit_sequence(struct drm_device * dev, uint32_t class, uint32_t flags,
                             uint32_t * sequence, uint32_t * native_type)
  {
--      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
++      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
        if (!dev_priv)
                return -EINVAL;
  
index cdfb314,0000000..d2e1f95
mode 100644,000000..100644
--- /dev/null
@@@ -1,248 -1,0 +1,248 @@@
-       drm_device_t *dev = output->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
 +/*
 + * Copyright Â© 2006-2007 Intel Corporation
 + *
 + * Permission is hereby granted, free of charge, to any person obtaining a
 + * copy of this software and associated documentation files (the "Software"),
 + * to deal in the Software without restriction, including without limitation
 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 + * and/or sell copies of the Software, and to permit persons to whom the
 + * Software is furnished to do so, subject to the following conditions:
 + *
 + * The above copyright notice and this permission notice (including the next
 + * paragraph) shall be included in all copies or substantial portions of the
 + * Software.
 + *
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 + * DEALINGS IN THE SOFTWARE.
 + *
 + * Authors:
 + *    Eric Anholt <eric@anholt.net>
 + */
 +
 +#include <linux/i2c.h>
 +#include "drmP.h"
 +#include "drm.h"
 +#include "drm_crtc.h"
 +#include "intel_drv.h"
 +#include "i915_drm.h"
 +#include "i915_drv.h"
 +
 +static void intel_crt_dpms(struct drm_output *output, int mode)
 +{
-       drm_device_t *dev = output->dev;
++      struct drm_device *dev = output->dev;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      u32 temp;
 +      
 +      temp = I915_READ(ADPA);
 +      temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
 +      temp &= ~ADPA_DAC_ENABLE;
 +      
 +      switch(mode) {
 +      case DPMSModeOn:
 +              temp |= ADPA_DAC_ENABLE;
 +              break;
 +      case DPMSModeStandby:
 +              temp |= ADPA_DAC_ENABLE | ADPA_HSYNC_CNTL_DISABLE;
 +              break;
 +      case DPMSModeSuspend:
 +              temp |= ADPA_DAC_ENABLE | ADPA_VSYNC_CNTL_DISABLE;
 +              break;
 +      case DPMSModeOff:
 +              temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE;
 +              break;
 +      }
 +      
 +      I915_WRITE(ADPA, temp);
 +}
 +
 +static void intel_crt_save(struct drm_output *output)
 +{
 +      
 +}
 +
 +static void intel_crt_restore(struct drm_output *output)
 +{
 +
 +}
 +
 +static int intel_crt_mode_valid(struct drm_output *output,
 +                              struct drm_display_mode *mode)
 +{
 +      if (mode->flags & V_DBLSCAN)
 +              return MODE_NO_DBLESCAN;
 +
 +      if (mode->clock > 400000 || mode->clock < 25000)
 +              return MODE_CLOCK_RANGE;
 +
 +      return MODE_OK;
 +}
 +
 +static bool intel_crt_mode_fixup(struct drm_output *output,
 +                               struct drm_display_mode *mode,
 +                               struct drm_display_mode *adjusted_mode)
 +{
 +      return true;
 +}
 +
 +static void intel_crt_mode_set(struct drm_output *output,
 +                             struct drm_display_mode *mode,
 +                             struct drm_display_mode *adjusted_mode)
 +{
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_device *dev = output->dev;
 +      struct drm_crtc *crtc = output->crtc;
 +      struct intel_crtc *intel_crtc = crtc->driver_private;
-       drm_device_t *dev = output->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      int dpll_md_reg;
 +      u32 adpa, dpll_md;
 +
 +      if (intel_crtc->pipe == 0) 
 +              dpll_md_reg = DPLL_A_MD;
 +      else
 +              dpll_md_reg = DPLL_B_MD;
 +
 +      /*
 +       * Disable separate mode multiplier used when cloning SDVO to CRT
 +       * XXX this needs to be adjusted when we really are cloning
 +       */
 +      if (IS_I965G(dev)) {
 +              dpll_md = I915_READ(dpll_md_reg);
 +              I915_WRITE(dpll_md_reg,
 +                         dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
 +      }
 +      
 +      adpa = 0;
 +      if (adjusted_mode->flags & V_PHSYNC)
 +              adpa |= ADPA_HSYNC_ACTIVE_HIGH;
 +      if (adjusted_mode->flags & V_PVSYNC)
 +              adpa |= ADPA_VSYNC_ACTIVE_HIGH;
 +      
 +      if (intel_crtc->pipe == 0)
 +              adpa |= ADPA_PIPE_A_SELECT;
 +      else
 +              adpa |= ADPA_PIPE_B_SELECT;
 +      
 +      I915_WRITE(ADPA, adpa);
 +}
 +
 +/**
 + * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence.
 + *
 + * Only for I945G/GM.
 + *
 + * \return TRUE if CRT is connected.
 + * \return FALSE if CRT is disconnected.
 + */
 +static bool intel_crt_detect_hotplug(struct drm_output *output)
 +{
-       drm_device_t *dev = output->dev;
++      struct drm_device *dev = output->dev;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      u32 temp;
 +      unsigned long timeout = jiffies + msecs_to_jiffies(1000);
 +
 +      temp = I915_READ(PORT_HOTPLUG_EN);
 +
 +      I915_WRITE(PORT_HOTPLUG_EN,
 +                 temp | CRT_HOTPLUG_FORCE_DETECT | (1 << 5));
 +
 +      do {
 +              if (!(I915_READ(PORT_HOTPLUG_EN) & CRT_HOTPLUG_FORCE_DETECT))
 +                      break;
 +              msleep(1);
 +      } while (time_after(timeout, jiffies));
 +
 +      if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) ==
 +          CRT_HOTPLUG_MONITOR_COLOR)
 +              return true;
 +
 +      return false;
 +}
 +
 +static bool intel_crt_detect_ddc(struct drm_output *output)
 +{
 +      struct intel_output *intel_output = output->driver_private;
 +
 +      /* CRT should always be at 0, but check anyway */
 +      if (intel_output->type != INTEL_OUTPUT_ANALOG)
 +              return false;
 +      
 +      return intel_ddc_probe(output);
 +}
 +
 +static enum drm_output_status intel_crt_detect(struct drm_output *output)
 +{
- void intel_crt_init(drm_device_t *dev)
++      struct drm_device *dev = output->dev;
 +      
 +      if (IS_I945G(dev)| IS_I945GM(dev) || IS_I965G(dev)) {
 +              if (intel_crt_detect_hotplug(output))
 +                      return output_status_connected;
 +              else
 +                      return output_status_disconnected;
 +      }
 +
 +      if (intel_crt_detect_ddc(output))
 +              return output_status_connected;
 +
 +      /* TODO use load detect */
 +      return output_status_unknown;
 +}
 +
 +static void intel_crt_destroy(struct drm_output *output)
 +{
 +      struct intel_output *intel_output = output->driver_private;
 +
 +      intel_i2c_destroy(intel_output->ddc_bus);
 +      kfree(output->driver_private);
 +}
 +
 +static int intel_crt_get_modes(struct drm_output *output)
 +{
 +      return intel_ddc_get_modes(output);
 +}
 +
 +/*
 + * Routines for controlling stuff on the analog port
 + */
 +static const struct drm_output_funcs intel_crt_output_funcs = {
 +      .dpms = intel_crt_dpms,
 +      .save = intel_crt_save,
 +      .restore = intel_crt_restore,
 +      .mode_valid = intel_crt_mode_valid,
 +      .mode_fixup = intel_crt_mode_fixup,
 +      .prepare = intel_output_prepare,
 +      .mode_set = intel_crt_mode_set,
 +      .commit = intel_output_commit,
 +      .detect = intel_crt_detect,
 +      .get_modes = intel_crt_get_modes,
 +      .cleanup = intel_crt_destroy,
 +};
 +
++void intel_crt_init(struct drm_device *dev)
 +{
 +      struct drm_output *output;
 +      struct intel_output *intel_output;
 +
 +      output = drm_output_create(dev, &intel_crt_output_funcs, "VGA");
 +
 +      intel_output = kmalloc(sizeof(struct intel_output), GFP_KERNEL);
 +      if (!intel_output) {
 +              drm_output_destroy(output);
 +              return;
 +      }
 +      /* Set up the DDC bus. */
 +      intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A");
 +      if (!intel_output->ddc_bus) {
 +              dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
 +                         "failed.\n");
 +              return;
 +      }
 +
 +      intel_output->type = INTEL_OUTPUT_ANALOG;
 +      output->driver_private = intel_output;
 +      output->interlace_allowed = 0;
 +      output->doublescan_allowed = 0;
 +}
index 3fce094,0000000..3ff9f82
mode 100644,000000..100644
--- /dev/null
@@@ -1,1229 -1,0 +1,1229 @@@
-       drm_device_t *dev = crtc->dev;
 +/*
 + * Copyright Â© 2006-2007 Intel Corporation
 + *
 + * Permission is hereby granted, free of charge, to any person obtaining a
 + * copy of this software and associated documentation files (the "Software"),
 + * to deal in the Software without restriction, including without limitation
 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 + * and/or sell copies of the Software, and to permit persons to whom the
 + * Software is furnished to do so, subject to the following conditions:
 + *
 + * The above copyright notice and this permission notice (including the next
 + * paragraph) shall be included in all copies or substantial portions of the
 + * Software.
 + *
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 + * DEALINGS IN THE SOFTWARE.
 + *
 + * Authors:
 + *    Eric Anholt <eric@anholt.net>
 + */
 +
 +#include <linux/i2c.h>
 +#include "drmP.h"
 +#include "intel_drv.h"
 +#include "i915_drm.h"
 +#include "i915_drv.h"
 +
 +bool intel_pipe_has_type (struct drm_crtc *crtc, int type);
 +
 +typedef struct {
 +    /* given values */    
 +    int n;
 +    int m1, m2;
 +    int p1, p2;
 +    /* derived values */
 +    int       dot;
 +    int       vco;
 +    int       m;
 +    int       p;
 +} intel_clock_t;
 +
 +typedef struct {
 +    int       min, max;
 +} intel_range_t;
 +
 +typedef struct {
 +    int       dot_limit;
 +    int       p2_slow, p2_fast;
 +} intel_p2_t;
 +
 +#define INTEL_P2_NUM                2
 +
 +typedef struct {
 +    intel_range_t   dot, vco, n, m, m1, m2, p, p1;
 +    intel_p2_t            p2;
 +} intel_limit_t;
 +
 +#define I8XX_DOT_MIN            25000
 +#define I8XX_DOT_MAX           350000
 +#define I8XX_VCO_MIN           930000
 +#define I8XX_VCO_MAX          1400000
 +#define I8XX_N_MIN                  3
 +#define I8XX_N_MAX                 16
 +#define I8XX_M_MIN                 96
 +#define I8XX_M_MAX                140
 +#define I8XX_M1_MIN                18
 +#define I8XX_M1_MAX                26
 +#define I8XX_M2_MIN                 6
 +#define I8XX_M2_MAX                16
 +#define I8XX_P_MIN                  4
 +#define I8XX_P_MAX                128
 +#define I8XX_P1_MIN                 2
 +#define I8XX_P1_MAX                33
 +#define I8XX_P1_LVDS_MIN            1
 +#define I8XX_P1_LVDS_MAX            6
 +#define I8XX_P2_SLOW                4
 +#define I8XX_P2_FAST                2
 +#define I8XX_P2_LVDS_SLOW           14
 +#define I8XX_P2_LVDS_FAST           14 /* No fast option */
 +#define I8XX_P2_SLOW_LIMIT     165000
 +
 +#define I9XX_DOT_MIN            20000
 +#define I9XX_DOT_MAX           400000
 +#define I9XX_VCO_MIN          1400000
 +#define I9XX_VCO_MAX          2800000
 +#define I9XX_N_MIN                  3
 +#define I9XX_N_MAX                  8
 +#define I9XX_M_MIN                 70
 +#define I9XX_M_MAX                120
 +#define I9XX_M1_MIN                10
 +#define I9XX_M1_MAX                20
 +#define I9XX_M2_MIN                 5
 +#define I9XX_M2_MAX                 9
 +#define I9XX_P_SDVO_DAC_MIN         5
 +#define I9XX_P_SDVO_DAC_MAX        80
 +#define I9XX_P_LVDS_MIN                     7
 +#define I9XX_P_LVDS_MAX                    98
 +#define I9XX_P1_MIN                 1
 +#define I9XX_P1_MAX                 8
 +#define I9XX_P2_SDVO_DAC_SLOW              10
 +#define I9XX_P2_SDVO_DAC_FAST               5
 +#define I9XX_P2_SDVO_DAC_SLOW_LIMIT    200000
 +#define I9XX_P2_LVDS_SLOW                  14
 +#define I9XX_P2_LVDS_FAST                   7
 +#define I9XX_P2_LVDS_SLOW_LIMIT                112000
 +
 +#define INTEL_LIMIT_I8XX_DVO_DAC    0
 +#define INTEL_LIMIT_I8XX_LVDS     1
 +#define INTEL_LIMIT_I9XX_SDVO_DAC   2
 +#define INTEL_LIMIT_I9XX_LVDS     3
 +
 +static const intel_limit_t intel_limits[] = {
 +    { /* INTEL_LIMIT_I8XX_DVO_DAC */
 +        .dot = { .min = I8XX_DOT_MIN,         .max = I8XX_DOT_MAX },
 +        .vco = { .min = I8XX_VCO_MIN,         .max = I8XX_VCO_MAX },
 +        .n   = { .min = I8XX_N_MIN,           .max = I8XX_N_MAX },
 +        .m   = { .min = I8XX_M_MIN,           .max = I8XX_M_MAX },
 +        .m1  = { .min = I8XX_M1_MIN,          .max = I8XX_M1_MAX },
 +        .m2  = { .min = I8XX_M2_MIN,          .max = I8XX_M2_MAX },
 +        .p   = { .min = I8XX_P_MIN,           .max = I8XX_P_MAX },
 +        .p1  = { .min = I8XX_P1_MIN,          .max = I8XX_P1_MAX },
 +      .p2  = { .dot_limit = I8XX_P2_SLOW_LIMIT,
 +               .p2_slow = I8XX_P2_SLOW,       .p2_fast = I8XX_P2_FAST },
 +    },
 +    { /* INTEL_LIMIT_I8XX_LVDS */
 +        .dot = { .min = I8XX_DOT_MIN,         .max = I8XX_DOT_MAX },
 +        .vco = { .min = I8XX_VCO_MIN,         .max = I8XX_VCO_MAX },
 +        .n   = { .min = I8XX_N_MIN,           .max = I8XX_N_MAX },
 +        .m   = { .min = I8XX_M_MIN,           .max = I8XX_M_MAX },
 +        .m1  = { .min = I8XX_M1_MIN,          .max = I8XX_M1_MAX },
 +        .m2  = { .min = I8XX_M2_MIN,          .max = I8XX_M2_MAX },
 +        .p   = { .min = I8XX_P_MIN,           .max = I8XX_P_MAX },
 +        .p1  = { .min = I8XX_P1_LVDS_MIN,     .max = I8XX_P1_LVDS_MAX },
 +      .p2  = { .dot_limit = I8XX_P2_SLOW_LIMIT,
 +               .p2_slow = I8XX_P2_LVDS_SLOW,  .p2_fast = I8XX_P2_LVDS_FAST },
 +    },
 +    { /* INTEL_LIMIT_I9XX_SDVO_DAC */
 +        .dot = { .min = I9XX_DOT_MIN,         .max = I9XX_DOT_MAX },
 +        .vco = { .min = I9XX_VCO_MIN,         .max = I9XX_VCO_MAX },
 +        .n   = { .min = I9XX_N_MIN,           .max = I9XX_N_MAX },
 +        .m   = { .min = I9XX_M_MIN,           .max = I9XX_M_MAX },
 +        .m1  = { .min = I9XX_M1_MIN,          .max = I9XX_M1_MAX },
 +        .m2  = { .min = I9XX_M2_MIN,          .max = I9XX_M2_MAX },
 +        .p   = { .min = I9XX_P_SDVO_DAC_MIN,  .max = I9XX_P_SDVO_DAC_MAX },
 +        .p1  = { .min = I9XX_P1_MIN,          .max = I9XX_P1_MAX },
 +      .p2  = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
 +               .p2_slow = I9XX_P2_SDVO_DAC_SLOW,      .p2_fast = I9XX_P2_SDVO_DAC_FAST },
 +    },
 +    { /* INTEL_LIMIT_I9XX_LVDS */
 +        .dot = { .min = I9XX_DOT_MIN,         .max = I9XX_DOT_MAX },
 +        .vco = { .min = I9XX_VCO_MIN,         .max = I9XX_VCO_MAX },
 +        .n   = { .min = I9XX_N_MIN,           .max = I9XX_N_MAX },
 +        .m   = { .min = I9XX_M_MIN,           .max = I9XX_M_MAX },
 +        .m1  = { .min = I9XX_M1_MIN,          .max = I9XX_M1_MAX },
 +        .m2  = { .min = I9XX_M2_MIN,          .max = I9XX_M2_MAX },
 +        .p   = { .min = I9XX_P_LVDS_MIN,      .max = I9XX_P_LVDS_MAX },
 +        .p1  = { .min = I9XX_P1_MIN,          .max = I9XX_P1_MAX },
 +      /* The single-channel range is 25-112Mhz, and dual-channel
 +       * is 80-224Mhz.  Prefer single channel as much as possible.
 +       */
 +      .p2  = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
 +               .p2_slow = I9XX_P2_LVDS_SLOW,  .p2_fast = I9XX_P2_LVDS_FAST },
 +    },
 +};
 +
 +static const intel_limit_t *intel_limit(struct drm_crtc *crtc)
 +{
-       drm_device_t *dev = crtc->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_device *dev = crtc->dev;
 +      const intel_limit_t *limit;
 +      
 +      if (IS_I9XX(dev)) {
 +              if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
 +                      limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS];
 +              else
 +                      limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
 +      } else {
 +              if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
 +                      limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS];
 +              else
 +                      limit = &intel_limits[INTEL_LIMIT_I8XX_DVO_DAC];
 +      }
 +      return limit;
 +}
 +
 +/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
 +
 +static void i8xx_clock(int refclk, intel_clock_t *clock)
 +{
 +      clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
 +      clock->p = clock->p1 * clock->p2;
 +      clock->vco = refclk * clock->m / (clock->n + 2);
 +      clock->dot = clock->vco / clock->p;
 +}
 +
 +/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */
 +
 +static void i9xx_clock(int refclk, intel_clock_t *clock)
 +{
 +      clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
 +      clock->p = clock->p1 * clock->p2;
 +      clock->vco = refclk * clock->m / (clock->n + 2);
 +      clock->dot = clock->vco / clock->p;
 +}
 +
 +static void intel_clock(struct drm_device *dev, int refclk,
 +                      intel_clock_t *clock)
 +{
 +      if (IS_I9XX(dev))
 +              return i9xx_clock (refclk, clock);
 +      else
 +              return i8xx_clock (refclk, clock);
 +}
 +
 +/**
 + * Returns whether any output on the specified pipe is of the specified type
 + */
 +bool intel_pipe_has_type (struct drm_crtc *crtc, int type)
 +{
 +    struct drm_device *dev = crtc->dev;
 +    struct drm_mode_config *mode_config = &dev->mode_config;
 +    struct drm_output *l_entry;
 +
 +    list_for_each_entry(l_entry, &mode_config->output_list, head) {
 +          if (l_entry->crtc == crtc) {
 +                  struct intel_output *intel_output = l_entry->driver_private;
 +                  if (intel_output->type == type)
 +                          return true;
 +          }
 +    }
 +    return false;
 +}
 +
 +#define INTELPllInvalid(s)   { /* ErrorF (s) */; return false; }
 +/**
 + * Returns whether the given set of divisors are valid for a given refclk with
 + * the given outputs.
 + */
 +
 +static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock)
 +{
 +      const intel_limit_t *limit = intel_limit (crtc);
 +      
 +      if (clock->p1  < limit->p1.min  || limit->p1.max  < clock->p1)
 +              INTELPllInvalid ("p1 out of range\n");
 +      if (clock->p   < limit->p.min   || limit->p.max   < clock->p)
 +              INTELPllInvalid ("p out of range\n");
 +      if (clock->m2  < limit->m2.min  || limit->m2.max  < clock->m2)
 +              INTELPllInvalid ("m2 out of range\n");
 +      if (clock->m1  < limit->m1.min  || limit->m1.max  < clock->m1)
 +              INTELPllInvalid ("m1 out of range\n");
 +      if (clock->m1 <= clock->m2)
 +              INTELPllInvalid ("m1 <= m2\n");
 +      if (clock->m   < limit->m.min   || limit->m.max   < clock->m)
 +              INTELPllInvalid ("m out of range\n");
 +      if (clock->n   < limit->n.min   || limit->n.max   < clock->n)
 +              INTELPllInvalid ("n out of range\n");
 +      if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
 +              INTELPllInvalid ("vco out of range\n");
 +      /* XXX: We may need to be checking "Dot clock" depending on the multiplier,
 +       * output, etc., rather than just a single range.
 +       */
 +      if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
 +              INTELPllInvalid ("dot out of range\n");
 +      
 +      return true;
 +}
 +
 +/**
 + * Returns a set of divisors for the desired target clock with the given
 + * refclk, or FALSE.  The returned values represent the clock equation:
 + * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
 + */
 +static bool intel_find_best_PLL(struct drm_crtc *crtc, int target,
 +                              int refclk, intel_clock_t *best_clock)
 +{
- intel_set_vblank(drm_device_t *dev)
++      struct drm_device *dev = crtc->dev;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      intel_clock_t clock;
 +      const intel_limit_t *limit = intel_limit(crtc);
 +      int err = target;
 +
 +      if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
 +          (I915_READ(LVDS) & LVDS_PORT_EN) != 0) {
 +              /*
 +               * For LVDS, if the panel is on, just rely on its current
 +               * settings for dual-channel.  We haven't figured out how to
 +               * reliably set up different single/dual channel state, if we
 +               * even can.
 +               */
 +              if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
 +                  LVDS_CLKB_POWER_UP)
 +                      clock.p2 = limit->p2.p2_fast;
 +              else
 +                      clock.p2 = limit->p2.p2_slow;
 +      } else {
 +              if (target < limit->p2.dot_limit)
 +                      clock.p2 = limit->p2.p2_slow;
 +              else
 +                      clock.p2 = limit->p2.p2_fast;
 +      }
 +      
 +      memset (best_clock, 0, sizeof (*best_clock));
 +      
 +      for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
 +              for (clock.m2 = limit->m2.min; clock.m2 < clock.m1 &&
 +                           clock.m2 <= limit->m2.max; clock.m2++) {
 +                      for (clock.n = limit->n.min; clock.n <= limit->n.max;
 +                           clock.n++) {
 +                              for (clock.p1 = limit->p1.min;
 +                                   clock.p1 <= limit->p1.max; clock.p1++) {
 +                                      int this_err;
 +                                      
 +                                      intel_clock(dev, refclk, &clock);
 +                                      
 +                                      if (!intel_PLL_is_valid(crtc, &clock))
 +                                              continue;
 +                                      
 +                                      this_err = abs(clock.dot - target);
 +                                      if (this_err < err) {
 +                                              *best_clock = clock;
 +                                              err = this_err;
 +                                      }
 +                              }
 +                      }
 +              }
 +      }
 +
 +      return (err != target);
 +}
 +
 +void
-       drm_i915_private_t *dev_priv = dev->dev_private;
++intel_set_vblank(struct drm_device *dev)
 +{
- intel_wait_for_vblank(drm_device_t *dev)
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct drm_crtc *crtc;
 +      struct intel_crtc *intel_crtc;
 +      int vbl_pipe = 0;
 +
 +      list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 +              intel_crtc = crtc->driver_private;
 +
 +              if (crtc->enabled)
 +                      vbl_pipe |= (1<<intel_crtc->pipe);
 +      }
 +
 +      dev_priv->vblank_pipe = vbl_pipe;
 +      i915_enable_interrupt(dev);
 +}
 +void
-       drm_device_t *dev = crtc->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
++intel_wait_for_vblank(struct drm_device *dev)
 +{
 +      /* Wait for 20ms, i.e. one cycle at 50hz. */
 +      udelay(20000);
 +}
 +
 +void
 +intel_pipe_set_base(struct drm_crtc *crtc, int x, int y)
 +{
-               dev_priv->sarea_priv->pipeA_x = x;
-               dev_priv->sarea_priv->pipeA_y = y;
++      struct drm_device *dev = crtc->dev;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct intel_crtc *intel_crtc = crtc->driver_private;
 +      int pipe = intel_crtc->pipe;
 +      unsigned long Start, Offset;
 +      int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
 +      int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
 +
 +      Start = crtc->fb->offset;
 +      Offset = y * crtc->fb->pitch + x;
 +
 +      DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
 +      if (IS_I965G(dev)) {
 +              I915_WRITE(dspbase, Offset);
 +              I915_READ(dspbase);
 +              I915_WRITE(dspsurf, Start);
 +              I915_READ(dspsurf);
 +      } else {
 +              I915_WRITE(dspbase, Start + Offset);
 +              I915_READ(dspbase);
 +      }
 +      
 +
 +      if (!dev_priv->sarea_priv) 
 +              return;
 +              
 +      switch (pipe) {
 +      case 0:
-               dev_priv->sarea_priv->pipeB_x = x;
-               dev_priv->sarea_priv->pipeB_y = y;
++              dev_priv->sarea_priv->planeA_x = x;
++              dev_priv->sarea_priv->planeA_y = y;
 +              break;
 +      case 1:
-       drm_device_t *dev = crtc->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
++              dev_priv->sarea_priv->planeB_x = x;
++              dev_priv->sarea_priv->planeB_y = y;
 +              break;
 +      default:
 +              DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
 +              break;
 +      }
 +}
 +
 +/**
 + * Sets the power management mode of the pipe and plane.
 + *
 + * This code should probably grow support for turning the cursor off and back
 + * on appropriately at the same time as we're turning the pipe off/on.
 + */
 +static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
 +{
-               dev_priv->sarea_priv->pipeA_w = enabled ? crtc->mode.hdisplay : 0;
-               dev_priv->sarea_priv->pipeA_h = enabled ? crtc->mode.vdisplay : 0;
++      struct drm_device *dev = crtc->dev;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct intel_crtc *intel_crtc = crtc->driver_private;
 +      int pipe = intel_crtc->pipe;
 +      int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
 +      int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
 +      int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE;
 +      int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
 +      u32 temp;
 +      bool enabled;
 +
 +      /* XXX: When our outputs are all unaware of DPMS modes other than off
 +       * and on, we should map those modes to DPMSModeOff in the CRTC.
 +       */
 +      switch (mode) {
 +      case DPMSModeOn:
 +      case DPMSModeStandby:
 +      case DPMSModeSuspend:
 +              /* Enable the DPLL */
 +              temp = I915_READ(dpll_reg);
 +              if ((temp & DPLL_VCO_ENABLE) == 0) {
 +                      I915_WRITE(dpll_reg, temp);
 +                      I915_READ(dpll_reg);
 +                      /* Wait for the clocks to stabilize. */
 +                      udelay(150);
 +                      I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
 +                      I915_READ(dpll_reg);
 +                      /* Wait for the clocks to stabilize. */
 +                      udelay(150);
 +                      I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
 +                      I915_READ(dpll_reg);
 +                      /* Wait for the clocks to stabilize. */
 +                      udelay(150);
 +              }
 +              
 +              /* Enable the pipe */
 +              temp = I915_READ(pipeconf_reg);
 +              if ((temp & PIPEACONF_ENABLE) == 0)
 +                      I915_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
 +              
 +              /* Enable the plane */
 +              temp = I915_READ(dspcntr_reg);
 +              if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
 +                      I915_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
 +                      /* Flush the plane changes */
 +                      I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
 +              }
 +              
 +              intel_crtc_load_lut(crtc);
 +              
 +              /* Give the overlay scaler a chance to enable if it's on this pipe */
 +              //intel_crtc_dpms_video(crtc, TRUE); TODO
 +      break;
 +      case DPMSModeOff:
 +              /* Give the overlay scaler a chance to disable if it's on this pipe */
 +              //intel_crtc_dpms_video(crtc, FALSE); TODO
 +              
 +              /* Disable the VGA plane that we never use */
 +              I915_WRITE(VGACNTRL, VGA_DISP_DISABLE);
 +              
 +              /* Disable display plane */
 +              temp = I915_READ(dspcntr_reg);
 +              if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
 +                      I915_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
 +                      /* Flush the plane changes */
 +                      I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
 +                      I915_READ(dspbase_reg);
 +              }
 +              
 +              if (!IS_I9XX(dev)) {
 +                      /* Wait for vblank for the disable to take effect */
 +                      intel_wait_for_vblank(dev);
 +              }
 +              
 +              /* Next, disable display pipes */
 +              temp = I915_READ(pipeconf_reg);
 +              if ((temp & PIPEACONF_ENABLE) != 0) {
 +                      I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
 +                      I915_READ(pipeconf_reg);
 +              }
 +              
 +              /* Wait for vblank for the disable to take effect. */
 +              intel_wait_for_vblank(dev);
 +              
 +              temp = I915_READ(dpll_reg);
 +              if ((temp & DPLL_VCO_ENABLE) != 0) {
 +                      I915_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
 +                      I915_READ(dpll_reg);
 +              }
 +              
 +              /* Wait for the clocks to turn off. */
 +              udelay(150);
 +              break;
 +      }
 +      
 +
 +      if (!dev_priv->sarea_priv)
 +              return;
 +
 +      enabled = crtc->enabled && mode != DPMSModeOff;
 +      
 +      switch (pipe) {
 +      case 0:
-               dev_priv->sarea_priv->pipeB_w = enabled ? crtc->mode.hdisplay : 0;
-               dev_priv->sarea_priv->pipeB_h = enabled ? crtc->mode.vdisplay : 0;
++              dev_priv->sarea_priv->planeA_w = enabled ? crtc->mode.hdisplay : 0;
++              dev_priv->sarea_priv->planeA_h = enabled ? crtc->mode.vdisplay : 0;
 +              break;
 +      case 1:
- static int intel_get_core_clock_speed(drm_device_t *dev)
++              dev_priv->sarea_priv->planeB_w = enabled ? crtc->mode.hdisplay : 0;
++              dev_priv->sarea_priv->planeB_h = enabled ? crtc->mode.vdisplay : 0;
 +              break;
 +      default:
 +              DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
 +              break;
 +      }
 +}
 +
 +static bool intel_crtc_lock(struct drm_crtc *crtc)
 +{
 +   /* Sync the engine before mode switch */
 +//   i830WaitSync(crtc->scrn);
 +
 +#if 0 // TODO def XF86DRI
 +    return I830DRILock(crtc->scrn);
 +#else
 +    return FALSE;
 +#endif
 +}
 +
 +static void intel_crtc_unlock (struct drm_crtc *crtc)
 +{
 +#if 0 // TODO def XF86DRI
 +    I830DRIUnlock (crtc->scrn);
 +#endif
 +}
 +
 +static void intel_crtc_prepare (struct drm_crtc *crtc)
 +{
 +      crtc->funcs->dpms(crtc, DPMSModeOff);
 +}
 +
 +static void intel_crtc_commit (struct drm_crtc *crtc)
 +{
 +      crtc->funcs->dpms(crtc, DPMSModeOn);
 +}
 +
 +void intel_output_prepare (struct drm_output *output)
 +{
 +      /* lvds has its own version of prepare see intel_lvds_prepare */
 +      output->funcs->dpms(output, DPMSModeOff);
 +}
 +
 +void intel_output_commit (struct drm_output *output)
 +{
 +      /* lvds has its own version of commit see intel_lvds_commit */
 +      output->funcs->dpms(output, DPMSModeOn);
 +}
 +
 +static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
 +                                struct drm_display_mode *mode,
 +                                struct drm_display_mode *adjusted_mode)
 +{
 +      return true;
 +}
 +
 +
 +/** Returns the core display clock speed for i830 - i945 */
- static int intel_panel_fitter_pipe (drm_device_t *dev)
++static int intel_get_core_clock_speed(struct drm_device *dev)
 +{
 +
 +      /* Core clock values taken from the published datasheets.
 +       * The 830 may go up to 166 Mhz, which we should check.
 +       */
 +      if (IS_I945G(dev))
 +              return 400000;
 +      else if (IS_I915G(dev))
 +              return 333000;
 +      else if (IS_I945GM(dev) || IS_845G(dev))
 +              return 200000;
 +      else if (IS_I915GM(dev)) {
 +              u16 gcfgc = 0;
 +
 +              pci_read_config_word(dev->pdev, I915_GCFGC, &gcfgc);
 +              
 +              if (gcfgc & I915_LOW_FREQUENCY_ENABLE)
 +                      return 133000;
 +              else {
 +                      switch (gcfgc & I915_DISPLAY_CLOCK_MASK) {
 +                      case I915_DISPLAY_CLOCK_333_MHZ:
 +                              return 333000;
 +                      default:
 +                      case I915_DISPLAY_CLOCK_190_200_MHZ:
 +                              return 190000;
 +                      }
 +              }
 +      } else if (IS_I865G(dev))
 +              return 266000;
 +      else if (IS_I855(dev)) {
 +#if 0
 +              PCITAG bridge = pciTag(0, 0, 0); /* This is always the host bridge */
 +              u16 hpllcc = pciReadWord(bridge, I855_HPLLCC);
 +              
 +#endif
 +              u16 hpllcc = 0;
 +              /* Assume that the hardware is in the high speed state.  This
 +               * should be the default.
 +               */
 +              switch (hpllcc & I855_CLOCK_CONTROL_MASK) {
 +              case I855_CLOCK_133_200:
 +              case I855_CLOCK_100_200:
 +                      return 200000;
 +              case I855_CLOCK_166_250:
 +                      return 250000;
 +              case I855_CLOCK_100_133:
 +                      return 133000;
 +              }
 +      } else /* 852, 830 */
 +              return 133000;
 +      
 +      return 0; /* Silence gcc warning */
 +}
 +
 +
 +/**
 + * Return the pipe currently connected to the panel fitter,
 + * or -1 if the panel fitter is not present or not in use
 + */
-       drm_i915_private_t *dev_priv = dev->dev_private;
++static int intel_panel_fitter_pipe (struct drm_device *dev)
 +{
-       drm_device_t *dev = crtc->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      u32  pfit_control;
 +    
 +      /* i830 doesn't have a panel fitter */
 +      if (IS_I830(dev))
 +              return -1;
 +    
 +      pfit_control = I915_READ(PFIT_CONTROL);
 +    
 +      /* See if the panel fitter is in use */
 +      if ((pfit_control & PFIT_ENABLE) == 0)
 +              return -1;
 +      
 +      /* 965 can place panel fitter on either pipe */
 +      if (IS_I965G(dev))
 +              return (pfit_control >> 29) & 0x3;
 +      
 +      /* older chips can only use pipe 1 */
 +      return 1;
 +}
 +
 +static void intel_crtc_mode_set(struct drm_crtc *crtc,
 +                              struct drm_display_mode *mode,
 +                              struct drm_display_mode *adjusted_mode,
 +                              int x, int y)
 +{
-       drm_device_t *dev = crtc->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_device *dev = crtc->dev;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct intel_crtc *intel_crtc = crtc->driver_private;
 +      int pipe = intel_crtc->pipe;
 +      int fp_reg = (pipe == 0) ? FPA0 : FPB0;
 +      int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
 +      int dpll_md_reg = (intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
 +      int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
 +      int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
 +      int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
 +      int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
 +      int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
 +      int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
 +      int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
 +      int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
 +      int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
 +      int dspstride_reg = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
 +      int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
 +      int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
 +      int refclk;
 +      intel_clock_t clock;
 +      u32 dpll = 0, fp = 0, dspcntr, pipeconf;
 +      bool ok, is_sdvo = false, is_dvo = false;
 +      bool is_crt = false, is_lvds = false, is_tv = false;
 +      struct drm_mode_config *mode_config = &dev->mode_config;
 +      struct drm_output *output;
 +
 +      list_for_each_entry(output, &mode_config->output_list, head) {
 +              struct intel_output *intel_output = output->driver_private;
 +
 +              if (output->crtc != crtc)
 +                      continue;
 +
 +              switch (intel_output->type) {
 +              case INTEL_OUTPUT_LVDS:
 +                      is_lvds = TRUE;
 +                      break;
 +              case INTEL_OUTPUT_SDVO:
 +                      is_sdvo = TRUE;
 +                      break;
 +              case INTEL_OUTPUT_DVO:
 +                      is_dvo = TRUE;
 +                      break;
 +              case INTEL_OUTPUT_TVOUT:
 +                      is_tv = TRUE;
 +                      break;
 +              case INTEL_OUTPUT_ANALOG:
 +                      is_crt = TRUE;
 +                      break;
 +              }
 +      }
 +      
 +      if (IS_I9XX(dev)) {
 +              refclk = 96000;
 +      } else {
 +              refclk = 48000;
 +      }
 +
 +      ok = intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, &clock);
 +      if (!ok) {
 +              DRM_ERROR("Couldn't find PLL settings for mode!\n");
 +              return;
 +      }
 +
 +      fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
 +      
 +      dpll = DPLL_VGA_MODE_DIS;
 +      if (IS_I9XX(dev)) {
 +              if (is_lvds)
 +                      dpll |= DPLLB_MODE_LVDS;
 +              else
 +                      dpll |= DPLLB_MODE_DAC_SERIAL;
 +              if (is_sdvo) {
 +                      dpll |= DPLL_DVO_HIGH_SPEED;
 +                      if (IS_I945G(dev) || IS_I945GM(dev)) {
 +                              int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
 +                              dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
 +                      }
 +              }
 +              
 +              /* compute bitmask from p1 value */
 +              dpll |= (1 << (clock.p1 - 1)) << 16;
 +              switch (clock.p2) {
 +              case 5:
 +                      dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
 +                      break;
 +              case 7:
 +                      dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
 +                      break;
 +              case 10:
 +                      dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
 +                      break;
 +              case 14:
 +                      dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
 +                      break;
 +              }
 +              if (IS_I965G(dev))
 +                      dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
 +      } else {
 +              if (is_lvds) {
 +                      dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
 +              } else {
 +                      if (clock.p1 == 2)
 +                              dpll |= PLL_P1_DIVIDE_BY_TWO;
 +                      else
 +                              dpll |= (clock.p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT;
 +                      if (clock.p2 == 4)
 +                              dpll |= PLL_P2_DIVIDE_BY_4;
 +              }
 +      }
 +      
 +      if (is_tv) {
 +              /* XXX: just matching BIOS for now */
 +/*    dpll |= PLL_REF_INPUT_TVCLKINBC; */
 +              dpll |= 3;
 +      }
 +#if 0
 +      else if (is_lvds)
 +              dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
 +#endif
 +      else
 +              dpll |= PLL_REF_INPUT_DREFCLK;
 +      
 +      /* setup pipeconf */
 +      pipeconf = I915_READ(pipeconf_reg);
 +
 +      /* Set up the display plane register */
 +      dspcntr = DISPPLANE_GAMMA_ENABLE;
 +
 +      switch (crtc->fb->bits_per_pixel) {
 +      case 8:
 +              dspcntr |= DISPPLANE_8BPP;
 +              break;
 +      case 16:
 +              if (crtc->fb->depth == 15)
 +                      dspcntr |= DISPPLANE_15_16BPP;
 +              else
 +                      dspcntr |= DISPPLANE_16BPP;
 +              break;
 +      case 32:
 +              dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
 +              break;
 +      default:
 +              DRM_ERROR("Unknown color depth\n");
 +              return;
 +      }
 +      
 +
 +      if (pipe == 0)
 +              dspcntr |= DISPPLANE_SEL_PIPE_A;
 +      else
 +              dspcntr |= DISPPLANE_SEL_PIPE_B;
 +      
 +      if (pipe == 0 && !IS_I965G(dev)) {
 +              /* Enable pixel doubling when the dot clock is > 90% of the (display)
 +               * core speed.
 +               *
 +               * XXX: No double-wide on 915GM pipe B. Is that the only reason for the
 +               * pipe == 0 check?
 +               */
 +              if (mode->clock > intel_get_core_clock_speed(dev) * 9 / 10)
 +                      pipeconf |= PIPEACONF_DOUBLE_WIDE;
 +              else
 +                      pipeconf &= ~PIPEACONF_DOUBLE_WIDE;
 +      }
 +
 +      dspcntr |= DISPLAY_PLANE_ENABLE;
 +      pipeconf |= PIPEACONF_ENABLE;
 +      dpll |= DPLL_VCO_ENABLE;
 +
 +      
 +      /* Disable the panel fitter if it was on our pipe */
 +      if (intel_panel_fitter_pipe(dev) == pipe)
 +              I915_WRITE(PFIT_CONTROL, 0);
 +
 +      DRM_DEBUG("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
 +      drm_mode_debug_printmodeline(dev, mode);
 +      
 +#if 0
 +      if (!xf86ModesEqual(mode, adjusted_mode)) {
 +              xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 +                         "Adjusted mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
 +              xf86PrintModeline(pScrn->scrnIndex, mode);
 +      }
 +      i830PrintPll("chosen", &clock);
 +#endif
 +
 +      if (dpll & DPLL_VCO_ENABLE) {
 +              I915_WRITE(fp_reg, fp);
 +              I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
 +              I915_READ(dpll_reg);
 +              udelay(150);
 +      }
 +      
 +      /* The LVDS pin pair needs to be on before the DPLLs are enabled.
 +       * This is an exception to the general rule that mode_set doesn't turn
 +       * things on.
 +       */
 +      if (is_lvds) {
 +              u32 lvds = I915_READ(LVDS);
 +              
 +              lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT;
 +              /* Set the B0-B3 data pairs corresponding to whether we're going to
 +               * set the DPLLs for dual-channel mode or not.
 +               */
 +              if (clock.p2 == 7)
 +                      lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
 +              else
 +                      lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
 +              
 +              /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
 +               * appropriately here, but we need to look more thoroughly into how
 +               * panels behave in the two modes.
 +               */
 +              
 +              I915_WRITE(LVDS, lvds);
 +              I915_READ(LVDS);
 +      }
 +      
 +      I915_WRITE(fp_reg, fp);
 +      I915_WRITE(dpll_reg, dpll);
 +      I915_READ(dpll_reg);
 +      /* Wait for the clocks to stabilize. */
 +      udelay(150);
 +      
 +      if (IS_I965G(dev)) {
 +              int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
 +              I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) |
 +                         ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT));
 +      } else {
 +              /* write it again -- the BIOS does, after all */
 +              I915_WRITE(dpll_reg, dpll);
 +      }
 +      I915_READ(dpll_reg);
 +      /* Wait for the clocks to stabilize. */
 +      udelay(150);
 +      
 +      I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
 +                 ((adjusted_mode->crtc_htotal - 1) << 16));
 +      I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
 +                 ((adjusted_mode->crtc_hblank_end - 1) << 16));
 +      I915_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
 +                 ((adjusted_mode->crtc_hsync_end - 1) << 16));
 +      I915_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
 +                 ((adjusted_mode->crtc_vtotal - 1) << 16));
 +      I915_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
 +                 ((adjusted_mode->crtc_vblank_end - 1) << 16));
 +      I915_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
 +                 ((adjusted_mode->crtc_vsync_end - 1) << 16));
 +      I915_WRITE(dspstride_reg, crtc->fb->pitch);
 +      /* pipesrc and dspsize control the size that is scaled from, which should
 +       * always be the user's requested size.
 +       */
 +      I915_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
 +      I915_WRITE(dsppos_reg, 0);
 +      I915_WRITE(pipesrc_reg, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
 +      I915_WRITE(pipeconf_reg, pipeconf);
 +      I915_READ(pipeconf_reg);
 +      
 +      intel_wait_for_vblank(dev);
 +      
 +      I915_WRITE(dspcntr_reg, dspcntr);
 +      
 +      /* Flush the plane changes */
 +      intel_pipe_set_base(crtc, x, y);
 +      
 +      intel_set_vblank(dev);
 +
 +      intel_wait_for_vblank(dev);    
 +}
 +
 +/** Loads the palette/gamma unit for the CRTC with the prepared values */
 +void intel_crtc_load_lut(struct drm_crtc *crtc)
 +{
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_device *dev = crtc->dev;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct intel_crtc *intel_crtc = crtc->driver_private;
 +      int palreg = (intel_crtc->pipe == 0) ? PALETTE_A : PALETTE_B;
 +      int i;
 +
 +      /* The clocks have to be on to load the palette. */
 +      if (!crtc->enabled)
 +              return;
 +
 +      for (i = 0; i < 256; i++) {
 +              I915_WRITE(palreg + 4 * i,
 +                         (intel_crtc->lut_r[i] << 16) |
 +                         (intel_crtc->lut_g[i] << 8) |
 +                         intel_crtc->lut_b[i]);
 +      }
 +}
 +
 +/** Sets the color ramps on behalf of RandR */
 +static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
 +                               u16 blue, int regno)
 +{
 +      struct intel_crtc *intel_crtc = crtc->driver_private;
 +      
 +      intel_crtc->lut_r[regno] = red >> 8;
 +      intel_crtc->lut_g[regno] = green >> 8;
 +      intel_crtc->lut_b[regno] = blue >> 8;
 +}
 +
 +/* Returns the clock of the currently programmed mode of the given pipe. */
 +static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
 +{
- struct drm_display_mode *intel_crtc_mode_get(drm_device_t *dev,
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct intel_crtc *intel_crtc = crtc->driver_private;
 +      int pipe = intel_crtc->pipe;
 +      u32 dpll = I915_READ((pipe == 0) ? DPLL_A : DPLL_B);
 +      u32 fp;
 +      intel_clock_t clock;
 +
 +      if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
 +              fp = I915_READ((pipe == 0) ? FPA0 : FPB0);
 +      else
 +              fp = I915_READ((pipe == 0) ? FPA1 : FPB1);
 +
 +      clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
 +      clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
 +      clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
 +      if (IS_I9XX(dev)) {
 +              clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
 +                             DPLL_FPA01_P1_POST_DIV_SHIFT);
 +
 +              switch (dpll & DPLL_MODE_MASK) {
 +              case DPLLB_MODE_DAC_SERIAL:
 +                      clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ?
 +                              5 : 10;
 +                      break;
 +              case DPLLB_MODE_LVDS:
 +                      clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ?
 +                              7 : 14;
 +                      break;
 +              default:
 +                      DRM_DEBUG("Unknown DPLL mode %08x in programmed "
 +                                "mode\n", (int)(dpll & DPLL_MODE_MASK));
 +                      return 0;
 +              }
 +
 +              /* XXX: Handle the 100Mhz refclk */
 +              i9xx_clock(96000, &clock);
 +      } else {
 +              bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN);
 +
 +              if (is_lvds) {
 +                      clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
 +                                     DPLL_FPA01_P1_POST_DIV_SHIFT);
 +                      clock.p2 = 14;
 +
 +                      if ((dpll & PLL_REF_INPUT_MASK) ==
 +                          PLLB_REF_INPUT_SPREADSPECTRUMIN) {
 +                              /* XXX: might not be 66MHz */
 +                              i8xx_clock(66000, &clock);
 +                      } else
 +                              i8xx_clock(48000, &clock);              
 +              } else {
 +                      if (dpll & PLL_P1_DIVIDE_BY_TWO)
 +                              clock.p1 = 2;
 +                      else {
 +                              clock.p1 = ((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
 +                                          DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
 +                      }
 +                      if (dpll & PLL_P2_DIVIDE_BY_4)
 +                              clock.p2 = 4;
 +                      else
 +                              clock.p2 = 2;
 +
 +                      i8xx_clock(48000, &clock);
 +              }
 +      }
 +
 +      /* XXX: It would be nice to validate the clocks, but we can't reuse
 +       * i830PllIsValid() because it relies on the xf86_config output
 +       * configuration being accurate, which it isn't necessarily.
 +       */
 +
 +      return clock.dot;
 +}
 +
 +/** Returns the currently programmed mode of the given pipe. */
-       drm_i915_private_t *dev_priv = dev->dev_private;
++struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
 +                                           struct drm_crtc *crtc)
 +{
- void intel_crtc_init(drm_device_t *dev, int pipe)
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct intel_crtc *intel_crtc = crtc->driver_private;
 +      int pipe = intel_crtc->pipe;
 +      struct drm_display_mode *mode;
 +      int htot = I915_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B);
 +      int hsync = I915_READ((pipe == 0) ? HSYNC_A : HSYNC_B);
 +      int vtot = I915_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B);
 +      int vsync = I915_READ((pipe == 0) ? VSYNC_A : VSYNC_B);
 +
 +      mode = kzalloc(sizeof(*mode), GFP_KERNEL);
 +      if (!mode)
 +              return NULL;
 +
 +      mode->clock = intel_crtc_clock_get(dev, crtc);
 +      mode->hdisplay = (htot & 0xffff) + 1;
 +      mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
 +      mode->hsync_start = (hsync & 0xffff) + 1;
 +      mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1;
 +      mode->vdisplay = (vtot & 0xffff) + 1;
 +      mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
 +      mode->vsync_start = (vsync & 0xffff) + 1;
 +      mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
 +
 +      drm_mode_set_name(mode);
 +      drm_mode_set_crtcinfo(mode, 0);
 +
 +      return mode;
 +}
 +
 +static const struct drm_crtc_funcs intel_crtc_funcs = {
 +      .dpms = intel_crtc_dpms,
 +      .lock = intel_crtc_lock,
 +      .unlock = intel_crtc_unlock,
 +      .mode_fixup = intel_crtc_mode_fixup,
 +      .mode_set = intel_crtc_mode_set,
 +      .gamma_set = intel_crtc_gamma_set,
 +      .prepare = intel_crtc_prepare,
 +      .commit = intel_crtc_commit,
 +};
 +
 +
- struct drm_crtc *intel_get_crtc_from_pipe(drm_device_t *dev, int pipe)
++void intel_crtc_init(struct drm_device *dev, int pipe)
 +{
 +      struct drm_crtc *crtc;
 +      struct intel_crtc *intel_crtc;
 +      int i;
 +
 +      crtc = drm_crtc_create(dev, &intel_crtc_funcs);
 +      if (crtc == NULL)
 +              return;
 +
 +      intel_crtc = kzalloc(sizeof(struct intel_crtc), GFP_KERNEL);
 +      if (intel_crtc == NULL) {
 +              kfree(crtc);
 +              return;
 +      }
 +
 +      intel_crtc->pipe = pipe;
 +      for (i = 0; i < 256; i++) {
 +              intel_crtc->lut_r[i] = i;
 +              intel_crtc->lut_g[i] = i;
 +              intel_crtc->lut_b[i] = i;
 +      }
 +
 +      crtc->driver_private = intel_crtc;
 +}
 +
- int intel_output_clones(drm_device_t *dev, int type_mask)
++struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
 +{
 +      struct drm_crtc *crtc = NULL;
 +
 +      list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 +              struct intel_crtc *intel_crtc = crtc->driver_private;
 +              if (intel_crtc->pipe == pipe)
 +                      break;
 +      }
 +      return crtc;
 +}
 +
- static void intel_setup_outputs(drm_device_t *dev)
++int intel_output_clones(struct drm_device *dev, int type_mask)
 +{
 +      int index_mask = 0;
 +      struct drm_output *output;
 +      int entry = 0;
 +
 +        list_for_each_entry(output, &dev->mode_config.output_list, head) {
 +              struct intel_output *intel_output = output->driver_private;
 +              if (type_mask & (1 << intel_output->type))
 +                      index_mask |= (1 << entry);
 +              entry++;
 +      }
 +      return index_mask;
 +}
 +
 +
- void intel_modeset_init(drm_device_t *dev)
++static void intel_setup_outputs(struct drm_device *dev)
 +{
 +      struct drm_output *output;
 +
 +      intel_crt_init(dev);
 +
 +      /* Set up integrated LVDS */
 +      if (IS_MOBILE(dev) && !IS_I830(dev))
 +              intel_lvds_init(dev);
 +
 +      if (IS_I9XX(dev)) {
 +              intel_sdvo_init(dev, SDVOB);
 +              intel_sdvo_init(dev, SDVOC);
 +      }
 +
 +      list_for_each_entry(output, &dev->mode_config.output_list, head) {
 +              struct intel_output *intel_output = output->driver_private;
 +              int crtc_mask = 0, clone_mask = 0;
 +              
 +              /* valid crtcs */
 +              switch(intel_output->type) {
 +              case INTEL_OUTPUT_DVO:
 +              case INTEL_OUTPUT_SDVO:
 +                      crtc_mask = ((1 << 0)|
 +                                   (1 << 1));
 +                      clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
 +                                    (1 << INTEL_OUTPUT_DVO) |
 +                                    (1 << INTEL_OUTPUT_SDVO));
 +                      break;
 +              case INTEL_OUTPUT_ANALOG:
 +                      crtc_mask = ((1 << 0)|
 +                                   (1 << 1));
 +                      clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
 +                                    (1 << INTEL_OUTPUT_DVO) |
 +                                    (1 << INTEL_OUTPUT_SDVO));
 +                      break;
 +              case INTEL_OUTPUT_LVDS:
 +                      crtc_mask = (1 << 1);
 +                      clone_mask = (1 << INTEL_OUTPUT_LVDS);
 +                      break;
 +              case INTEL_OUTPUT_TVOUT:
 +                      crtc_mask = ((1 << 0) |
 +                                   (1 << 1));
 +                      clone_mask = (1 << INTEL_OUTPUT_TVOUT);
 +                      break;
 +              }
 +              output->possible_crtcs = crtc_mask;
 +              output->possible_clones = intel_output_clones(dev, clone_mask);
 +      }
 +}
 +
- void intel_modeset_cleanup(drm_device_t *dev)
++void intel_modeset_init(struct drm_device *dev)
 +{
 +      int num_pipe;
 +      int i;
 +
 +      drm_mode_config_init(dev);
 +
 +      dev->mode_config.min_width = 0;
 +      dev->mode_config.min_height = 0;
 +
 +      dev->mode_config.max_width = 4096;
 +      dev->mode_config.max_height = 4096;
 +
 +      if (IS_MOBILE(dev) || IS_I9XX(dev))
 +              num_pipe = 2;
 +      else
 +              num_pipe = 1;
 +      DRM_DEBUG("%d display pipe%s available.\n",
 +                num_pipe, num_pipe > 1 ? "s" : "");
 +
 +      for (i = 0; i < num_pipe; i++) {
 +              intel_crtc_init(dev, i);
 +      }
 +
 +      intel_setup_outputs(dev);
 +
 +      //drm_initial_config(dev, false);
 +}
 +
++void intel_modeset_cleanup(struct drm_device *dev)
 +{
 +      drm_mode_config_cleanup(dev);
 +}
index 0a03e37,0000000..7de4b92
mode 100644,000000..100644
--- /dev/null
@@@ -1,82 -1,0 +1,82 @@@
-       drm_device_t *drm_dev; /* for getting at dev. private (mmio etc.) */
 +/*
 + * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
 + * Copyright (c) 2007 Intel Corporation
 + *   Jesse Barnes <jesse.barnes@intel.com>
 + */
 +#ifndef __INTEL_DRV_H__
 +#define __INTEL_DRV_H__
 +
 +#include <linux/i2c.h>
 +#include <linux/i2c-id.h>
 +#include <linux/i2c-algo-bit.h>
 +#include "drm_crtc.h"
 +
 +/*
 + * Display related stuff
 + */
 +
 +/* store information about an Ixxx DVO */
 +/* The i830->i865 use multiple DVOs with multiple i2cs */
 +/* the i915, i945 have a single sDVO i2c bus - which is different */
 +#define MAX_OUTPUTS 6
 +
 +#define INTEL_I2C_BUS_DVO 1
 +#define INTEL_I2C_BUS_SDVO 2
 +
 +/* these are outputs from the chip - integrated only 
 +   external chips are via DVO or SDVO output */
 +#define INTEL_OUTPUT_UNUSED 0
 +#define INTEL_OUTPUT_ANALOG 1
 +#define INTEL_OUTPUT_DVO 2
 +#define INTEL_OUTPUT_SDVO 3
 +#define INTEL_OUTPUT_LVDS 4
 +#define INTEL_OUTPUT_TVOUT 5
 +
 +#define INTEL_DVO_CHIP_NONE 0
 +#define INTEL_DVO_CHIP_LVDS 1
 +#define INTEL_DVO_CHIP_TMDS 2
 +#define INTEL_DVO_CHIP_TVOUT 4
 +
 +struct intel_i2c_chan {
- struct intel_i2c_chan *intel_i2c_create(drm_device_t *dev, const u32 reg,
++      struct drm_device *drm_dev; /* for getting at dev. private (mmio etc.) */
 +      u32 reg; /* GPIO reg */
 +      struct i2c_adapter adapter;
 +      struct i2c_algo_bit_data algo;
 +        u8 slave_addr;
 +};
 +
 +struct intel_output {
 +      int type;
 +      struct intel_i2c_chan *i2c_bus; /* for control functions */
 +      struct intel_i2c_chan *ddc_bus; /* for DDC only stuff */
 +      bool load_detect_tmp;
 +      void *dev_priv;
 +};
 +
 +struct intel_crtc {
 +      int pipe;
 +      u8 lut_r[256], lut_g[256], lut_b[256];
 +};
 +
- extern void intel_crt_init(drm_device_t *dev);
- extern void intel_sdvo_init(drm_device_t *dev, int output_device);
- extern void intel_lvds_init(drm_device_t *dev);
++struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg,
 +                                      const char *name);
 +void intel_i2c_destroy(struct intel_i2c_chan *chan);
 +int intel_ddc_get_modes(struct drm_output *output);
 +extern bool intel_ddc_probe(struct drm_output *output);
 +
- extern struct drm_display_mode *intel_crtc_mode_get(drm_device_t *dev,
++extern void intel_crt_init(struct drm_device *dev);
++extern void intel_sdvo_init(struct drm_device *dev, int output_device);
++extern void intel_lvds_init(struct drm_device *dev);
 +
 +extern void intel_crtc_load_lut(struct drm_crtc *crtc);
 +extern void intel_output_prepare (struct drm_output *output);
 +extern void intel_output_commit (struct drm_output *output);
- extern void intel_wait_for_vblank(drm_device_t *dev);
- extern struct drm_crtc *intel_get_crtc_from_pipe(drm_device_t *dev, int pipe);
++extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
 +                                                  struct drm_crtc *crtc);
++extern void intel_wait_for_vblank(struct drm_device *dev);
++extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe);
 +
 +extern int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc);
 +extern int intelfb_remove(struct drm_device *dev, struct drm_crtc *crtc);
 +
 +#endif /* __INTEL_DRV_H__ */
index 3bfbcda,0000000..048295a
mode 100644,000000..100644
--- /dev/null
@@@ -1,629 -1,0 +1,636 @@@
-       drm_buffer_object_t *fbo = NULL;
 +/*
 + * Copyright Â© 2007 David Airlie
 + *
 + * Permission is hereby granted, free of charge, to any person obtaining a
 + * copy of this software and associated documentation files (the "Software"),
 + * to deal in the Software without restriction, including without limitation
 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 + * and/or sell copies of the Software, and to permit persons to whom the
 + * Software is furnished to do so, subject to the following conditions:
 + *
 + * The above copyright notice and this permission notice (including the next
 + * paragraph) shall be included in all copies or substantial portions of the
 + * Software.
 + *
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 + * DEALINGS IN THE SOFTWARE.
 + *
 + * Authors:
 + *     David Airlie
 + */
 +    /*
 +     *  Modularization
 +     */
 +
 +#include <linux/module.h>
 +#include <linux/kernel.h>
 +#include <linux/errno.h>
 +#include <linux/string.h>
 +#include <linux/mm.h>
 +#include <linux/tty.h>
 +#include <linux/slab.h>
 +#include <linux/delay.h>
 +#include <linux/fb.h>
 +#include <linux/init.h>
 +
 +#include "drmP.h"
 +#include "drm.h"
 +#include "drm_crtc.h"
 +#include "i915_drm.h"
 +#include "i915_drv.h"
 +
 +struct intelfb_par {
 +      struct drm_device *dev;
 +      struct drm_crtc *crtc;
 +};
 +
 +static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
 +                         unsigned blue, unsigned transp,
 +                         struct fb_info *info)
 +{
 +      struct intelfb_par *par = info->par;
 +      struct drm_framebuffer *fb = par->crtc->fb;
 +      struct drm_crtc *crtc = par->crtc;
 +
 +      if (regno > 255)
 +              return 1;
 +
 +      if (fb->depth == 8) {
 +              if (crtc->funcs->gamma_set)
 +                      crtc->funcs->gamma_set(crtc, red, green, blue, regno);
 +              return 0;
 +      }
 +
 +      if (regno < 16) {
 +              switch (fb->depth) {
 +              case 15:
 +                      fb->pseudo_palette[regno] = ((red & 0xf800) >>  1) |
 +                              ((green & 0xf800) >>  6) |
 +                              ((blue & 0xf800) >> 11);
 +                      break;
 +              case 16:
 +                      fb->pseudo_palette[regno] = (red & 0xf800) |
 +                              ((green & 0xfc00) >>  5) |
 +                              ((blue  & 0xf800) >> 11);
 +                      break;
 +              case 24:
 +              case 32:
 +                      fb->pseudo_palette[regno] = ((red & 0xff00) << 8) |
 +                              (green & 0xff00) |
 +                              ((blue  & 0xff00) >> 8);
 +                      break;
 +              }
 +      }
 +
 +      return 0;
 +}
 +
 +static int intelfb_check_var(struct fb_var_screeninfo *var,
 +                           struct fb_info *info)
 +{
 +        struct intelfb_par *par = info->par;
 +        struct drm_device *dev = par->dev;
 +      struct drm_framebuffer *fb = par->crtc->fb;
 +        struct drm_display_mode *drm_mode;
 +        struct drm_output *output;
 +        int depth;
 +
 +        if (!var->pixclock)
 +                return -EINVAL;
 +
 +        /* Need to resize the fb object !!! */
 +        if (var->xres > fb->width || var->yres > fb->height) {
 +                DRM_ERROR("Requested width/height is greater than current fb object %dx%d > %dx%d\n",var->xres,var->yres,fb->width,fb->height);
 +                DRM_ERROR("Need resizing code.\n");
 +                return -EINVAL;
 +        }
 +
 +        switch (var->bits_per_pixel) {
 +        case 16:
 +                depth = (var->green.length == 6) ? 16 : 15;
 +                break;
 +        case 32:
 +                depth = (var->transp.length > 0) ? 32 : 24;
 +                break;
 +        default:
 +                depth = var->bits_per_pixel;
 +                break;
 +        }
 +                
 +        switch (depth) {
 +        case 8:
 +                var->red.offset = 0;
 +                var->green.offset = 0;
 +                var->blue.offset = 0;
 +                var->red.length = 8;
 +                var->green.length = 8;
 +                var->blue.length = 8;
 +                var->transp.length = 0;
 +                var->transp.offset = 0;
 +                break;
 +        case 15:
 +                var->red.offset = 10;
 +                var->green.offset = 5;
 +                var->blue.offset = 0;
 +                var->red.length = 5;
 +                var->green.length = 5;
 +                var->blue.length = 5;
 +                var->transp.length = 1;
 +                var->transp.offset = 15;
 +                break;
 +        case 16:
 +                var->red.offset = 11;
 +                var->green.offset = 6;
 +                var->blue.offset = 0;
 +                var->red.length = 5;
 +                var->green.length = 6;
 +                var->blue.length = 5;
 +                var->transp.length = 0;
 +                var->transp.offset = 0;
 +                break;
 +        case 24:
 +                var->red.offset = 16;
 +                var->green.offset = 8;
 +                var->blue.offset = 0;
 +                var->red.length = 8;
 +                var->green.length = 8;
 +                var->blue.length = 8;
 +                var->transp.length = 0;
 +                var->transp.offset = 0;
 +                break;
 +        case 32:
 +                var->red.offset = 16;
 +                var->green.offset = 8;
 +                var->blue.offset = 0;
 +                var->red.length = 8;
 +                var->green.length = 8;
 +                var->blue.length = 8;
 +                var->transp.length = 8;
 +                var->transp.offset = 24;
 +                break;
 +        default:
 +                return -EINVAL; 
 +        }
 +
 +#if 0
 +        /* Here we walk the output mode list and look for modes. If we haven't
 +         * got it, then bail. Not very nice, so this is disabled.
 +         * In the set_par code, we create our mode based on the incoming
 +         * parameters. Nicer, but may not be desired by some.
 +         */
 +        list_for_each_entry(output, &dev->mode_config.output_list, head) {
 +                if (output->crtc == par->crtc)
 +                        break;
 +        }
 +    
 +        list_for_each_entry(drm_mode, &output->modes, head) {
 +                if (drm_mode->hdisplay == var->xres &&
 +                    drm_mode->vdisplay == var->yres &&
 +                    drm_mode->clock != 0)
 +                      break;
 +      }
 + 
 +        if (!drm_mode)
 +                return -EINVAL;
 +#endif
 +
 +      return 0;
 +}
 +
 +/* this will let fbcon do the mode init */
 +/* FIXME: take mode config lock? */
 +static int intelfb_set_par(struct fb_info *info)
 +{
 +      struct intelfb_par *par = info->par;
 +      struct drm_framebuffer *fb = par->crtc->fb;
 +      struct drm_device *dev = par->dev;
 +        struct drm_display_mode *drm_mode;
 +        struct fb_var_screeninfo *var = &info->var;
 +
 +        switch (var->bits_per_pixel) {
 +        case 16:
 +                fb->depth = (var->green.length == 6) ? 16 : 15;
 +                break;
 +        case 32:
 +                fb->depth = (var->transp.length > 0) ? 32 : 24;
 +                break;
 +        default:
 +                fb->depth = var->bits_per_pixel;
 +                break;
 +        }
 +
 +        fb->bits_per_pixel = var->bits_per_pixel;
 +
 +        info->fix.line_length = fb->pitch;
 +        info->fix.smem_len = info->fix.line_length * fb->height;
 +        info->fix.visual = (fb->depth == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
 +
 +        info->screen_size = info->fix.smem_len; /* ??? */
 +
 +        /* Should we walk the output's modelist or just create our own ???
 +         * For now, we create and destroy a mode based on the incoming 
 +         * parameters. But there's commented out code below which scans 
 +         * the output list too.
 +         */
 +#if 0
 +        list_for_each_entry(output, &dev->mode_config.output_list, head) {
 +                if (output->crtc == par->crtc)
 +                        break;
 +        }
 +    
 +        list_for_each_entry(drm_mode, &output->modes, head) {
 +                if (drm_mode->hdisplay == var->xres &&
 +                    drm_mode->vdisplay == var->yres &&
 +                    drm_mode->clock != 0)
 +                      break;
 +        }
 +#else
 +        drm_mode = drm_mode_create(dev);
 +        drm_mode->hdisplay = var->xres;
 +        drm_mode->hsync_start = drm_mode->hdisplay + var->right_margin;
 +        drm_mode->hsync_end = drm_mode->hsync_start + var->hsync_len;
 +        drm_mode->htotal = drm_mode->hsync_end + var->left_margin;
 +        drm_mode->vdisplay = var->yres;
 +        drm_mode->vsync_start = drm_mode->vdisplay + var->lower_margin;
 +        drm_mode->vsync_end = drm_mode->vsync_start + var->vsync_len;
 +        drm_mode->vtotal = drm_mode->vsync_end + var->upper_margin;
 +        drm_mode->clock = PICOS2KHZ(var->pixclock);
 +        drm_mode->vrefresh = drm_mode_vrefresh(drm_mode);
 +        drm_mode_set_name(drm_mode);
 +      drm_mode_set_crtcinfo(drm_mode, CRTC_INTERLACE_HALVE_V);
 +#endif
 +
 +        if (!drm_crtc_set_mode(par->crtc, drm_mode, 0, 0))
 +                return -EINVAL;
 +
 +        /* Have to destroy our created mode if we're not searching the mode
 +         * list for it.
 +         */
 +#if 1 
 +        drm_mode_destroy(dev, drm_mode);
 +#endif
 +
 +      return 0;
 +}
 +
 +#if 0
 +static void intelfb_copyarea(struct fb_info *info,
 +                           const struct fb_copyarea *region)
 +{
 +        struct intelfb_par *par = info->par;
 +      struct drm_device *dev = par->dev;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      u32 src_x1, src_y1, dst_x1, dst_y1, dst_x2, dst_y2, offset;
 +      u32 cmd, rop_depth_pitch, src_pitch;
 +      RING_LOCALS;
 +
 +      cmd = XY_SRC_COPY_BLT_CMD;
 +      src_x1 = region->sx;
 +      src_y1 = region->sy;
 +      dst_x1 = region->dx;
 +      dst_y1 = region->dy;
 +      dst_x2 = region->dx + region->width;
 +      dst_y2 = region->dy + region->height;
 +      offset = par->fb->offset;
 +      rop_depth_pitch = BLT_ROP_GXCOPY | par->fb->pitch;
 +      src_pitch = par->fb->pitch;
 +
 +      switch (par->fb->bits_per_pixel) {
 +      case 16:
 +              rop_depth_pitch |= BLT_DEPTH_16_565;
 +              break;
 +      case 32:
 +              rop_depth_pitch |= BLT_DEPTH_32;
 +              cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB;
 +              break;
 +      }
 +
 +      BEGIN_LP_RING(8);
 +      OUT_RING(cmd);
 +      OUT_RING(rop_depth_pitch);
 +      OUT_RING((dst_y1 << 16) | (dst_x1 & 0xffff));
 +      OUT_RING((dst_y2 << 16) | (dst_x2 & 0xffff));
 +      OUT_RING(offset);
 +      OUT_RING((src_y1 << 16) | (src_x1 & 0xffff));
 +      OUT_RING(src_pitch);
 +      OUT_RING(offset);
 +      ADVANCE_LP_RING();
 +}
 +
 +#define ROUND_UP_TO(x, y)     (((x) + (y) - 1) / (y) * (y))
 +#define ROUND_DOWN_TO(x, y)   ((x) / (y) * (y))
 +
 +void intelfb_imageblit(struct fb_info *info, const struct fb_image *image)
 +{
 +        struct intelfb_par *par = info->par;
 +      struct drm_device *dev = par->dev;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      u32 cmd, rop_pitch_depth, tmp;
 +      int nbytes, ndwords, pad;
 +      u32 dst_x1, dst_y1, dst_x2, dst_y2, offset, bg, fg;
 +      int dat, ix, iy, iw;
 +      int i, j;
 +      RING_LOCALS;
 +
 +      /* size in bytes of a padded scanline */
 +      nbytes = ROUND_UP_TO(image->width, 16) / 8;
 +
 +      /* Total bytes of padded scanline data to write out. */
 +      nbytes *= image->height;
 +
 +      /*
 +       * Check if the glyph data exceeds the immediate mode limit.
 +       * It would take a large font (1K pixels) to hit this limit.
 +       */
 +      if (nbytes > 128 || image->depth != 1)
 +              return cfb_imageblit(info, image);
 +
 +      /* Src data is packaged a dword (32-bit) at a time. */
 +      ndwords = ROUND_UP_TO(nbytes, 4) / 4;
 +
 +      /*
 +       * Ring has to be padded to a quad word. But because the command starts
 +         with 7 bytes, pad only if there is an even number of ndwords
 +       */
 +      pad = !(ndwords % 2);
 +
 +      DRM_DEBUG("imageblit %dx%dx%d to (%d,%d)\n", image->width,
 +                image->height, image->depth, image->dx, image->dy);
 +      DRM_DEBUG("nbytes: %d, ndwords: %d, pad: %d\n", nbytes, ndwords, pad);
 +
 +      tmp = (XY_MONO_SRC_COPY_IMM_BLT & 0xff) + ndwords;
 +      cmd = (XY_MONO_SRC_COPY_IMM_BLT & ~0xff) | tmp;
 +      offset = par->fb->offset;
 +      dst_x1 = image->dx;
 +      dst_y1 = image->dy;
 +      dst_x2 = image->dx + image->width;
 +      dst_y2 = image->dy + image->height;
 +      rop_pitch_depth = BLT_ROP_GXCOPY | par->fb->pitch;
 +
 +      switch (par->fb->bits_per_pixel) {
 +      case 8:
 +              rop_pitch_depth |= BLT_DEPTH_8;
 +              fg = image->fg_color;
 +              bg = image->bg_color;
 +              break;
 +      case 16:
 +              rop_pitch_depth |= BLT_DEPTH_16_565;
 +              fg = par->fb->pseudo_palette[image->fg_color];
 +              bg = par->fb->pseudo_palette[image->bg_color];
 +              break;
 +      case 32:
 +              rop_pitch_depth |= BLT_DEPTH_32;
 +              cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB;
 +              fg = par->fb->pseudo_palette[image->fg_color];
 +              bg = par->fb->pseudo_palette[image->bg_color];
 +              break;
 +      default:
 +              DRM_ERROR("unknown depth %d\n", par->fb->bits_per_pixel);
 +              break;
 +      }
 +      
 +      BEGIN_LP_RING(8 + ndwords);
 +      OUT_RING(cmd);
 +      OUT_RING(rop_pitch_depth);
 +      OUT_RING((dst_y1 << 16) | (dst_x1 & 0xffff));
 +      OUT_RING((dst_y2 << 16) | (dst_x2 & 0xffff));
 +      OUT_RING(offset);
 +      OUT_RING(bg);
 +      OUT_RING(fg);
 +      ix = iy = 0;
 +      iw = ROUND_UP_TO(image->width, 8) / 8;
 +      while (ndwords--) {
 +              dat = 0;
 +              for (j = 0; j < 2; ++j) {
 +                      for (i = 0; i < 2; ++i) {
 +                              if (ix != iw || i == 0)
 +                                      dat |= image->data[iy*iw + ix++] << (i+j*2)*8;
 +                      }
 +                      if (ix == iw && iy != (image->height - 1)) {
 +                              ix = 0;
 +                              ++iy;
 +                      }
 +              }
 +              OUT_RING(dat);
 +      }
 +      if (pad)
 +              OUT_RING(MI_NOOP);
 +      ADVANCE_LP_RING();
 +}
 +#endif
 +
 +static struct fb_ops intelfb_ops = {
 +      .owner = THIS_MODULE,
 +      //      .fb_open = intelfb_open,
 +      //      .fb_read = intelfb_read,
 +      //      .fb_write = intelfb_write,
 +      //      .fb_release = intelfb_release,
 +      //      .fb_ioctl = intelfb_ioctl,
 +      .fb_check_var = intelfb_check_var,
 +      .fb_set_par = intelfb_set_par,
 +      .fb_setcolreg = intelfb_setcolreg,
 +      .fb_fillrect = cfb_fillrect,
 +      .fb_copyarea = cfb_copyarea, //intelfb_copyarea,
 +      .fb_imageblit = cfb_imageblit, //intelfb_imageblit,
 +};
 +
 +int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc)
 +{
 +      struct fb_info *info;
 +      struct intelfb_par *par;
 +      struct device *device = &dev->pdev->dev; 
 +      struct drm_framebuffer *fb;
 +      struct drm_display_mode *mode = crtc->desired_mode;
-       ret = drm_buffer_object_create(dev, 
-                                      fb->width * fb->height * 4, 
++      struct drm_buffer_object *fbo = NULL;
 +      int ret;
 +
 +      info = framebuffer_alloc(sizeof(struct intelfb_par), device);
 +      if (!info){
 +              return -EINVAL;
 +      }
 +
 +      fb = drm_framebuffer_create(dev);
 +      if (!fb) {
 +              framebuffer_release(info);
 +              DRM_ERROR("failed to allocate fb.\n");
 +              return -EINVAL;
 +      }
 +      crtc->fb = fb;
 +
 +      fb->width = crtc->desired_mode->hdisplay;
 +      fb->height = crtc->desired_mode->vdisplay;
 +
 +      fb->bits_per_pixel = 32;
 +      fb->pitch = fb->width * ((fb->bits_per_pixel + 1) / 8);
 +      fb->depth = 24;
-                                      DRM_BO_FLAG_MEM_VRAM | /* FIXME! */
-                                      DRM_BO_FLAG_NO_MOVE,
++      ret = drm_buffer_object_create(dev, fb->width * fb->height * 4, 
 +                                     drm_bo_type_kernel,
 +                                     DRM_BO_FLAG_READ |
 +                                     DRM_BO_FLAG_WRITE |
++                                     DRM_BO_FLAG_MEM_VRAM,
 +                                     0, 0, 0,
 +                                     &fbo);
 +      if (ret || !fbo) {
 +              printk(KERN_ERR "failed to allocate framebuffer\n");
 +              drm_framebuffer_destroy(fb);
 +              framebuffer_release(info);
 +              return -EINVAL;
 +      }
++
++      ret = drm_bo_set_pin(dev, fbo, 1);
++      if (ret) {
++              printk(KERN_ERR "failed to pin framebuffer, aborting\n");
++              drm_framebuffer_destroy(fb);
++              framebuffer_release(info);
++              return -EINVAL;
++      }
++
 +      fb->offset = fbo->offset;
 +      fb->bo = fbo;
 +      printk("allocated %dx%d fb: 0x%08lx, bo %p\n", fb->width,
 +                     fb->height, fbo->offset, fbo);
 +
 +
 +      fb->fbdev = info;
 +              
 +      par = info->par;
 +
 +      par->dev = dev;
 +      par->crtc = crtc;
 +
 +      info->fbops = &intelfb_ops;
 +
 +      strcpy(info->fix.id, "intelfb");
 +      info->fix.type = FB_TYPE_PACKED_PIXELS;
 +      info->fix.visual = FB_VISUAL_TRUECOLOR;
 +      info->fix.type_aux = 0;
 +      info->fix.xpanstep = 8;
 +      info->fix.ypanstep = 1;
 +      info->fix.ywrapstep = 0;
 +      info->fix.accel = FB_ACCEL_I830;
 +      info->fix.type_aux = 0;
 +      info->fix.mmio_start = 0;
 +      info->fix.mmio_len = 0;
 +      info->fix.line_length = fb->pitch;
 +      info->fix.smem_start = fb->offset + dev->mode_config.fb_base;
 +      info->fix.smem_len = info->fix.line_length * fb->height;
 +
 +      info->flags = FBINFO_DEFAULT;
 +
 +      ret = drm_mem_reg_ioremap(dev, &fb->bo->mem, &fb->virtual_base);
 +      if (ret)
 +              DRM_ERROR("error mapping fb: %d\n", ret);
 +
 +      info->screen_base = fb->virtual_base;
 +      info->screen_size = info->fix.smem_len; /* FIXME */
 +      info->pseudo_palette = fb->pseudo_palette;
 +      info->var.xres_virtual = fb->width;
 +      info->var.yres_virtual = fb->height;
 +      info->var.bits_per_pixel = fb->bits_per_pixel;
 +      info->var.xoffset = 0;
 +      info->var.yoffset = 0;
 +      info->var.activate = FB_ACTIVATE_NOW;
 +      info->var.height = -1;
 +      info->var.width = -1;
 +      info->var.vmode = FB_VMODE_NONINTERLACED;
 +
 +        info->var.xres = mode->hdisplay;
 +        info->var.right_margin = mode->hsync_start - mode->hdisplay;
 +        info->var.hsync_len = mode->hsync_end - mode->hsync_start;
 +        info->var.left_margin = mode->htotal - mode->hsync_end;
 +        info->var.yres = mode->vdisplay;
 +        info->var.lower_margin = mode->vsync_start - mode->vdisplay;
 +        info->var.vsync_len = mode->vsync_end - mode->vsync_start;
 +      info->var.upper_margin = mode->vtotal - mode->vsync_end;
 +        info->var.pixclock = 10000000 / mode->htotal * 1000 /
 +              mode->vtotal * 100;
 +      /* avoid overflow */
 +      info->var.pixclock = info->var.pixclock * 1000 / mode->vrefresh;
 +
 +      info->pixmap.size = 64*1024;
 +      info->pixmap.buf_align = 8;
 +      info->pixmap.access_align = 32;
 +      info->pixmap.flags = FB_PIXMAP_SYSTEM;
 +      info->pixmap.scan_align = 1;
 +
 +      DRM_DEBUG("fb depth is %d\n", fb->depth);
 +      DRM_DEBUG("   pitch is %d\n", fb->pitch);
 +      switch(fb->depth) {
 +      case 8:
 +                info->var.red.offset = 0;
 +                info->var.green.offset = 0;
 +                info->var.blue.offset = 0;
 +                info->var.red.length = 8; /* 8bit DAC */
 +                info->var.green.length = 8;
 +                info->var.blue.length = 8;
 +                info->var.transp.offset = 0;
 +                info->var.transp.length = 0;
 +                break;
 +      case 15:
 +                info->var.red.offset = 10;
 +                info->var.green.offset = 5;
 +                info->var.blue.offset = 0;
 +                info->var.red.length = info->var.green.length =
 +                        info->var.blue.length = 5;
 +                info->var.transp.offset = 15;
 +                info->var.transp.length = 1;
 +                break;
 +      case 16:
 +                info->var.red.offset = 11;
 +                info->var.green.offset = 5;
 +                info->var.blue.offset = 0;
 +                info->var.red.length = 5;
 +                info->var.green.length = 6;
 +                info->var.blue.length = 5;
 +                info->var.transp.offset = 0;
 +              break;
 +      case 24:
 +                info->var.red.offset = 16;
 +                info->var.green.offset = 8;
 +                info->var.blue.offset = 0;
 +                info->var.red.length = info->var.green.length =
 +                        info->var.blue.length = 8;
 +                info->var.transp.offset = 0;
 +                info->var.transp.length = 0;
 +                break;
 +      case 32:
 +              info->var.red.offset = 16;
 +              info->var.green.offset = 8;
 +              info->var.blue.offset = 0;
 +              info->var.red.length = info->var.green.length =
 +                      info->var.blue.length = 8;
 +              info->var.transp.offset = 24;
 +              info->var.transp.length = 8;
 +              break;
 +      default:
 +              break;
 +      }
 +
 +      if (register_framebuffer(info) < 0)
 +              return -EINVAL;
 +
 +      printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
 +             info->fix.id);
 +      return 0;
 +}
 +EXPORT_SYMBOL(intelfb_probe);
 +
 +int intelfb_remove(struct drm_device *dev, struct drm_crtc *crtc)
 +{
 +      struct drm_framebuffer *fb = crtc->fb;
 +      struct fb_info *info = fb->fbdev;
 +      
 +      if (info) {
 +              unregister_framebuffer(info);
 +              framebuffer_release(info);
 +              drm_mem_reg_iounmap(dev, &fb->bo->mem, fb->virtual_base);
 +      }
 +      return 0;
 +}
 +EXPORT_SYMBOL(intelfb_remove);
 +MODULE_LICENSE("GPL");
index d4cf7ee,0000000..b512e59
mode 100644,000000..100644
--- /dev/null
@@@ -1,187 -1,0 +1,187 @@@
-       drm_i915_private_t *dev_priv = chan->drm_dev->dev_private;
 +/*
 + * Copyright Â© 2006-2007 Intel Corporation
 + *
 + * Permission is hereby granted, free of charge, to any person obtaining a
 + * copy of this software and associated documentation files (the "Software"),
 + * to deal in the Software without restriction, including without limitation
 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 + * and/or sell copies of the Software, and to permit persons to whom the
 + * Software is furnished to do so, subject to the following conditions:
 + *
 + * The above copyright notice and this permission notice (including the next
 + * paragraph) shall be included in all copies or substantial portions of the
 + * Software.
 + *
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 + * DEALINGS IN THE SOFTWARE.
 + *
 + * Authors:
 + *    Eric Anholt <eric@anholt.net>
 + */
 +/*
 + * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
 + *   Jesse Barnes <jesse.barnes@intel.com>
 + */
 +
 +#include <linux/i2c.h>
 +#include <linux/i2c-id.h>
 +#include <linux/i2c-algo-bit.h>
 +#include "drmP.h"
 +#include "drm.h"
 +#include "intel_drv.h"
 +#include "i915_drm.h"
 +#include "i915_drv.h"
 +
 +/*
 + * Intel GPIO access functions
 + */
 +
 +#define I2C_RISEFALL_TIME 20
 +
 +static int get_clock(void *data)
 +{
 +      struct intel_i2c_chan *chan = data;
-       drm_i915_private_t *dev_priv = chan->drm_dev->dev_private;
++      struct drm_i915_private *dev_priv = chan->drm_dev->dev_private;
 +      u32 val;
 +
 +      val = I915_READ(chan->reg);
 +      return ((val & GPIO_CLOCK_VAL_IN) != 0);
 +}
 +
 +static int get_data(void *data)
 +{
 +      struct intel_i2c_chan *chan = data;
-       drm_device_t *dev = chan->drm_dev;
-       drm_i915_private_t *dev_priv = chan->drm_dev->dev_private;
++      struct drm_i915_private *dev_priv = chan->drm_dev->dev_private;
 +      u32 val;
 +
 +      val = I915_READ(chan->reg);
 +      return ((val & GPIO_DATA_VAL_IN) != 0);
 +}
 +
 +static void set_clock(void *data, int state_high)
 +{
 +      struct intel_i2c_chan *chan = data;
-       drm_device_t *dev = chan->drm_dev;
-       drm_i915_private_t *dev_priv = chan->drm_dev->dev_private;
++      struct drm_device *dev = chan->drm_dev;
++      struct drm_i915_private *dev_priv = chan->drm_dev->dev_private;
 +      u32 reserved = 0, clock_bits;
 +
 +      /* On most chips, these bits must be preserved in software. */
 +      if (!IS_I830(dev) && !IS_845G(dev))
 +              reserved = I915_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
 +                                                 GPIO_CLOCK_PULLUP_DISABLE);
 +
 +      if (state_high)
 +              clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK;
 +      else
 +              clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK |
 +                      GPIO_CLOCK_VAL_MASK;
 +      I915_WRITE(chan->reg, reserved | clock_bits);
 +      udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */
 +}
 +
 +static void set_data(void *data, int state_high)
 +{
 +      struct intel_i2c_chan *chan = data;
- struct intel_i2c_chan *intel_i2c_create(drm_device_t *dev, const u32 reg,
++      struct drm_device *dev = chan->drm_dev;
++      struct drm_i915_private *dev_priv = chan->drm_dev->dev_private;
 +      u32 reserved = 0, data_bits;
 +
 +      /* On most chips, these bits must be preserved in software. */
 +      if (!IS_I830(dev) && !IS_845G(dev))
 +              reserved = I915_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
 +                                                 GPIO_CLOCK_PULLUP_DISABLE);
 +
 +      if (state_high)
 +              data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK;
 +      else
 +              data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK |
 +                      GPIO_DATA_VAL_MASK;
 +
 +      I915_WRITE(chan->reg, reserved | data_bits);
 +      udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */
 +}
 +
 +/**
 + * intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg
 + * @dev: DRM device
 + * @output: driver specific output device
 + * @reg: GPIO reg to use
 + * @name: name for this bus
 + *
 + * Creates and registers a new i2c bus with the Linux i2c layer, for use
 + * in output probing and control (e.g. DDC or SDVO control functions).
 + *
 + * Possible values for @reg include:
 + *   %GPIOA
 + *   %GPIOB
 + *   %GPIOC
 + *   %GPIOD
 + *   %GPIOE
 + *   %GPIOF
 + *   %GPIOG
 + *   %GPIOH
 + * see PRM for details on how these different busses are used.
 + */
++struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg,
 +                                      const char *name)
 +{
 +      struct intel_i2c_chan *chan;
 +
 +      chan = kzalloc(sizeof(struct intel_i2c_chan), GFP_KERNEL);
 +      if (!chan)
 +              goto out_free;
 +
 +      chan->drm_dev = dev;
 +      chan->reg = reg;
 +      snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name);
 +      chan->adapter.owner = THIS_MODULE;
 +      chan->adapter.id = I2C_HW_B_INTELFB;
 +      chan->adapter.algo_data = &chan->algo;
 +      chan->adapter.dev.parent = &dev->pdev->dev;
 +      chan->algo.setsda = set_data;
 +      chan->algo.setscl = set_clock;
 +      chan->algo.getsda = get_data;
 +      chan->algo.getscl = get_clock;
 +      chan->algo.udelay = 20;
 +      chan->algo.timeout = usecs_to_jiffies(2200);
 +      chan->algo.data = chan;
 +
 +      i2c_set_adapdata(&chan->adapter, chan);
 +
 +      if(i2c_bit_add_bus(&chan->adapter))
 +              goto out_free;
 +
 +      /* JJJ:  raise SCL and SDA? */
 +      set_data(chan, 1);
 +      set_clock(chan, 1);
 +      udelay(20);
 +
 +      return chan;
 +
 +out_free:
 +      kfree(chan);
 +      return NULL;
 +}
 +
 +/**
 + * intel_i2c_destroy - unregister and free i2c bus resources
 + * @output: channel to free
 + *
 + * Unregister the adapter from the i2c layer, then free the structure.
 + */
 +void intel_i2c_destroy(struct intel_i2c_chan *chan)
 +{
 +      if (!chan)
 +              return;
 +
 +      i2c_del_adapter(&chan->adapter);
 +      kfree(chan);
 +}
 +
 +      
 +      
index 942eb2a,0000000..4f15c13
mode 100644,000000..100644
--- /dev/null
@@@ -1,502 -1,0 +1,502 @@@
-       drm_i915_private_t *dev_priv = dev->dev_private;
 +/*
 + * Copyright Â© 2006-2007 Intel Corporation
 + * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
 + *
 + * Permission is hereby granted, free of charge, to any person obtaining a
 + * copy of this software and associated documentation files (the "Software"),
 + * to deal in the Software without restriction, including without limitation
 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 + * and/or sell copies of the Software, and to permit persons to whom the
 + * Software is furnished to do so, subject to the following conditions:
 + *
 + * The above copyright notice and this permission notice (including the next
 + * paragraph) shall be included in all copies or substantial portions of the
 + * Software.
 + *
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 + * DEALINGS IN THE SOFTWARE.
 + *
 + * Authors:
 + *    Eric Anholt <eric@anholt.net>
 + *      Dave Airlie <airlied@linux.ie>
 + *      Jesse Barnes <jesse.barnes@intel.com>
 + */
 +
 +#include <linux/i2c.h>
 +#include "drmP.h"
 +#include "drm.h"
 +#include "drm_crtc.h"
 +#include "drm_edid.h"
 +#include "intel_drv.h"
 +#include "i915_drm.h"
 +#include "i915_drv.h"
 +
 +/**
 + * Sets the backlight level.
 + *
 + * \param level backlight level, from 0 to intel_lvds_get_max_backlight().
 + */
 +static void intel_lvds_set_backlight(struct drm_device *dev, int level)
 +{
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      u32 blc_pwm_ctl;
 +
 +      blc_pwm_ctl = I915_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
 +      I915_WRITE(BLC_PWM_CTL, (blc_pwm_ctl |
 +                               (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
 +}
 +
 +/**
 + * Returns the maximum level of the backlight duty cycle field.
 + */
 +static u32 intel_lvds_get_max_backlight(struct drm_device *dev)
 +{
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +    
 +      return ((I915_READ(BLC_PWM_CTL) & BACKLIGHT_MODULATION_FREQ_MASK) >>
 +              BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
 +}
 +
 +/**
 + * Sets the power state for the panel.
 + */
 +static void intel_lvds_set_power(struct drm_device *dev, bool on)
 +{
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      u32 pp_status;
 +
 +      if (on) {
 +              I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) |
 +                         POWER_TARGET_ON);
 +              do {
 +                      pp_status = I915_READ(PP_STATUS);
 +              } while ((pp_status & PP_ON) == 0);
 +
 +              intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle);
 +      } else {
 +              intel_lvds_set_backlight(dev, 0);
 +
 +              I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) &
 +                         ~POWER_TARGET_ON);
 +              do {
 +                      pp_status = I915_READ(PP_STATUS);
 +              } while (pp_status & PP_ON);
 +      }
 +}
 +
 +static void intel_lvds_dpms(struct drm_output *output, int mode)
 +{
 +      struct drm_device *dev = output->dev;
 +
 +      if (mode == DPMSModeOn)
 +              intel_lvds_set_power(dev, true);
 +      else
 +              intel_lvds_set_power(dev, false);
 +
 +      /* XXX: We never power down the LVDS pairs. */
 +}
 +
 +static void intel_lvds_save(struct drm_output *output)
 +{
 +      struct drm_device *dev = output->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +
 +      dev_priv->savePP_ON = I915_READ(LVDSPP_ON);
 +      dev_priv->savePP_OFF = I915_READ(LVDSPP_OFF);
 +      dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
 +      dev_priv->savePP_CYCLE = I915_READ(PP_CYCLE);
 +      dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
 +      dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
 +                                     BACKLIGHT_DUTY_CYCLE_MASK);
 +
 +      /*
 +       * If the light is off at server startup, just make it full brightness
 +       */
 +      if (dev_priv->backlight_duty_cycle == 0)
 +              dev_priv->backlight_duty_cycle =
 +                      intel_lvds_get_max_backlight(dev);
 +}
 +
 +static void intel_lvds_restore(struct drm_output *output)
 +{
 +      struct drm_device *dev = output->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +
 +      I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
 +      I915_WRITE(LVDSPP_ON, dev_priv->savePP_ON);
 +      I915_WRITE(LVDSPP_OFF, dev_priv->savePP_OFF);
 +      I915_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE);
 +      I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
 +      if (dev_priv->savePP_CONTROL & POWER_TARGET_ON)
 +              intel_lvds_set_power(dev, true);
 +      else
 +              intel_lvds_set_power(dev, false);
 +}
 +
 +static int intel_lvds_mode_valid(struct drm_output *output,
 +                               struct drm_display_mode *mode)
 +{
 +      struct drm_device *dev = output->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode;
 +
 +      if (fixed_mode) {
 +              if (mode->hdisplay > fixed_mode->hdisplay)
 +                      return MODE_PANEL;
 +              if (mode->vdisplay > fixed_mode->vdisplay)
 +                      return MODE_PANEL;
 +      }
 +
 +      return MODE_OK;
 +}
 +
 +static bool intel_lvds_mode_fixup(struct drm_output *output,
 +                                struct drm_display_mode *mode,
 +                                struct drm_display_mode *adjusted_mode)
 +{
 +      struct drm_device *dev = output->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct intel_crtc *intel_crtc = output->crtc->driver_private;
 +      struct drm_output *tmp_output;
 +
 +      /* Should never happen!! */
 +      if (!IS_I965G(dev) && intel_crtc->pipe == 0) {
 +              printk(KERN_ERR "Can't support LVDS on pipe A\n");
 +              return false;
 +      }
 +
 +      /* Should never happen!! */
 +      list_for_each_entry(tmp_output, &dev->mode_config.output_list, head) {
 +              if (tmp_output != output && tmp_output->crtc == output->crtc) {
 +                      printk(KERN_ERR "Can't enable LVDS and another "
 +                             "output on the same pipe\n");
 +                      return false;
 +              }
 +      }
 +
 +      /*
 +       * If we have timings from the BIOS for the panel, put them in
 +       * to the adjusted mode.  The CRTC will be set up for this mode,
 +       * with the panel scaling set up to source from the H/VDisplay
 +       * of the original mode.
 +       */
 +      if (dev_priv->panel_fixed_mode != NULL) {
 +              adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay;
 +              adjusted_mode->hsync_start =
 +                      dev_priv->panel_fixed_mode->hsync_start;
 +              adjusted_mode->hsync_end =
 +                      dev_priv->panel_fixed_mode->hsync_end;
 +              adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal;
 +              adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay;
 +              adjusted_mode->vsync_start =
 +                      dev_priv->panel_fixed_mode->vsync_start;
 +              adjusted_mode->vsync_end =
 +                      dev_priv->panel_fixed_mode->vsync_end;
 +              adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal;
 +              adjusted_mode->clock = dev_priv->panel_fixed_mode->clock;
 +              drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
 +      }
 +
 +      /*
 +       * XXX: It would be nice to support lower refresh rates on the
 +       * panels to reduce power consumption, and perhaps match the
 +       * user's requested refresh rate.
 +       */
 +
 +      return true;
 +}
 +
 +static void intel_lvds_prepare(struct drm_output *output)
 +{
 +      struct drm_device *dev = output->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +
 +      dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
 +      dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
 +                                     BACKLIGHT_DUTY_CYCLE_MASK);
 +
 +      intel_lvds_set_power(dev, false);
 +}
 +
 +static void intel_lvds_commit( struct drm_output *output)
 +{
 +      struct drm_device *dev = output->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +
 +      if (dev_priv->backlight_duty_cycle == 0)
 +              dev_priv->backlight_duty_cycle =
 +                      intel_lvds_get_max_backlight(dev);
 +
 +      intel_lvds_set_power(dev, true);
 +}
 +
 +static void intel_lvds_mode_set(struct drm_output *output,
 +                              struct drm_display_mode *mode,
 +                              struct drm_display_mode *adjusted_mode)
 +{
 +      struct drm_device *dev = output->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct intel_crtc *intel_crtc = output->crtc->driver_private;
 +      u32 pfit_control;
 +
 +      /*
 +       * The LVDS pin pair will already have been turned on in the
 +       * intel_crtc_mode_set since it has a large impact on the DPLL
 +       * settings.
 +       */
 +
 +      /*
 +       * Enable automatic panel scaling so that non-native modes fill the
 +       * screen.  Should be enabled before the pipe is enabled, according to
 +       * register description and PRM.
 +       */
 +      pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
 +                      VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR);
 +
 +      if (!IS_I965G(dev)) {
 +              if (dev_priv->panel_wants_dither)
 +                      pfit_control |= PANEL_8TO6_DITHER_ENABLE;
 +      }
 +      else
 +              pfit_control |= intel_crtc->pipe << PFIT_PIPE_SHIFT;
 +
 +      I915_WRITE(PFIT_CONTROL, pfit_control);
 +}
 +
 +/**
 + * Detect the LVDS connection.
 + *
 + * This always returns OUTPUT_STATUS_CONNECTED.  This output should only have
 + * been set up if the LVDS was actually connected anyway.
 + */
 +static enum drm_output_status intel_lvds_detect(struct drm_output *output)
 +{
 +      return output_status_connected;
 +}
 +
 +/**
 + * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
 + */
 +static int intel_lvds_get_modes(struct drm_output *output)
 +{
 +      struct drm_device *dev = output->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      int ret = 0;
 +
 +      ret = intel_ddc_get_modes(output);
 +
 +      if (ret)
 +              return ret;
 +
 +      /* Didn't get an EDID */
 +      if (!output->monitor_info) {
 +              struct drm_display_info *dspinfo;
 +              dspinfo = kzalloc(sizeof(*output->monitor_info), GFP_KERNEL);
 +              if (!dspinfo)
 +                      goto out;
 +
 +              /* Set wide sync ranges so we get all modes
 +               * handed to valid_mode for checking
 +               */
 +              dspinfo->min_vfreq = 0;
 +              dspinfo->max_vfreq = 200;
 +              dspinfo->min_hfreq = 0;
 +              dspinfo->max_hfreq = 200;
 +              output->monitor_info = dspinfo;
 +      }
 +
 +out:
 +      if (dev_priv->panel_fixed_mode != NULL) {
 +              struct drm_display_mode *mode =
 +                      drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
 +              drm_mode_probed_add(output, mode);
 +              return 1;
 +      }
 +
 +      return 0;
 +}
 +
 +/**
 + * intel_lvds_destroy - unregister and free LVDS structures
 + * @output: output to free
 + *
 + * Unregister the DDC bus for this output then free the driver private
 + * structure.
 + */
 +static void intel_lvds_destroy(struct drm_output *output)
 +{
 +      struct intel_output *intel_output = output->driver_private;
 +
 +      intel_i2c_destroy(intel_output->ddc_bus);
 +      kfree(output->driver_private);
 +}
 +
 +static const struct drm_output_funcs intel_lvds_output_funcs = {
 +      .dpms = intel_lvds_dpms,
 +      .save = intel_lvds_save,
 +      .restore = intel_lvds_restore,
 +      .mode_valid = intel_lvds_mode_valid,
 +      .mode_fixup = intel_lvds_mode_fixup,
 +      .prepare = intel_lvds_prepare,
 +      .mode_set = intel_lvds_mode_set,
 +      .commit = intel_lvds_commit,
 +      .detect = intel_lvds_detect,
 +      .get_modes = intel_lvds_get_modes,
 +      .cleanup = intel_lvds_destroy
 +};
 +
 +/**
 + * intel_lvds_init - setup LVDS outputs on this device
 + * @dev: drm device
 + *
 + * Create the output, register the LVDS DDC bus, and try to figure out what
 + * modes we can display on the LVDS panel (if present).
 + */
 +void intel_lvds_init(struct drm_device *dev)
 +{
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct drm_output *output;
 +      struct intel_output *intel_output;
 +      struct drm_display_mode *scan; /* *modes, *bios_mode; */
 +      struct drm_crtc *crtc;
 +      u32 lvds;
 +      int pipe;
 +
 +      output = drm_output_create(dev, &intel_lvds_output_funcs, "LVDS");
 +      if (!output)
 +              return;
 +
 +      intel_output = kmalloc(sizeof(struct intel_output), GFP_KERNEL);
 +      if (!intel_output) {
 +              drm_output_destroy(output);
 +              return;
 +      }
 +
 +      intel_output->type = INTEL_OUTPUT_LVDS;
 +      output->driver_private = intel_output;
 +      output->subpixel_order = SubPixelHorizontalRGB;
 +      output->interlace_allowed = FALSE;
 +      output->doublescan_allowed = FALSE;
 +
 +      /* Set up the DDC bus. */
 +      intel_output->ddc_bus = intel_i2c_create(dev, GPIOC, "LVDSDDC_C");
 +      if (!intel_output->ddc_bus) {
 +              dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
 +                         "failed.\n");
 +              return;
 +      }
 +
 +      /*
 +       * Attempt to get the fixed panel mode from DDC.  Assume that the
 +       * preferred mode is the right one.
 +       */
 +      intel_ddc_get_modes(output);
 +
 +      list_for_each_entry(scan, &output->probed_modes, head) {
 +              if (scan->type & DRM_MODE_TYPE_PREFERRED) {
 +                      dev_priv->panel_fixed_mode = 
 +                              drm_mode_duplicate(dev, scan);
 +                      goto out; /* FIXME: check for quirks */
 +              }
 +      }
 +
 +      /*
 +       * If we didn't get EDID, try checking if the panel is already turned
 +       * on.  If so, assume that whatever is currently programmed is the
 +       * correct mode.
 +       */
 +      lvds = I915_READ(LVDS);
 +      pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
 +      crtc = intel_get_crtc_from_pipe(dev, pipe);
 +              
 +      if (crtc && (lvds & LVDS_PORT_EN)) {
 +              dev_priv->panel_fixed_mode = intel_crtc_mode_get(dev, crtc);
 +              if (dev_priv->panel_fixed_mode) {
 +                      dev_priv->panel_fixed_mode->type |=
 +                              DRM_MODE_TYPE_PREFERRED;
 +                      goto out; /* FIXME: check for quirks */
 +              }
 +      }
 +
 +      /* If we still don't have a mode after all that, give up. */
 +      if (!dev_priv->panel_fixed_mode)
 +              goto failed;
 +
 +      /* FIXME: probe the BIOS for modes and check for LVDS quirks */
 +#if 0
 +      /* Get the LVDS fixed mode out of the BIOS.  We should support LVDS
 +       * with the BIOS being unavailable or broken, but lack the
 +       * configuration options for now.
 +       */
 +      bios_mode = intel_bios_get_panel_mode(pScrn);
 +      if (bios_mode != NULL) {
 +              if (dev_priv->panel_fixed_mode != NULL) {
 +                      if (dev_priv->debug_modes &&
 +                          !xf86ModesEqual(dev_priv->panel_fixed_mode,
 +                                          bios_mode))
 +                      {
 +                              xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 +                                         "BIOS panel mode data doesn't match probed data, "
 +                                         "continuing with probed.\n");
 +                              xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIOS mode:\n");
 +                              xf86PrintModeline(pScrn->scrnIndex, bios_mode);
 +                              xf86DrvMsg(pScrn->scrnIndex, X_INFO, "probed mode:\n");
 +                              xf86PrintModeline(pScrn->scrnIndex, dev_priv->panel_fixed_mode);
 +                              xfree(bios_mode->name);
 +                              xfree(bios_mode);
 +                      }
 +              }  else {
 +                      dev_priv->panel_fixed_mode = bios_mode;
 +              }
 +      } else {
 +              xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 +                         "Couldn't detect panel mode.  Disabling panel\n");
 +              goto disable_exit;
 +      }
 +
 +      /*
 +       * Blacklist machines with BIOSes that list an LVDS panel without
 +       * actually having one.
 +       */
 +      if (dev_priv->PciInfo->chipType == PCI_CHIP_I945_GM) {
 +              /* aopen mini pc */
 +              if (dev_priv->PciInfo->subsysVendor == 0xa0a0)
 +                      goto disable_exit;
 +
 +              if ((dev_priv->PciInfo->subsysVendor == 0x8086) &&
 +                  (dev_priv->PciInfo->subsysCard == 0x7270)) {
 +                      /* It's a Mac Mini or Macbook Pro.
 +                       *
 +                       * Apple hardware is out to get us.  The macbook pro
 +                       * has a real LVDS panel, but the mac mini does not,
 +                       * and they have the same device IDs.  We'll
 +                       * distinguish by panel size, on the assumption
 +                       * that Apple isn't about to make any machines with an
 +                       * 800x600 display.
 +                       */
 +
 +                      if (dev_priv->panel_fixed_mode != NULL &&
 +                          dev_priv->panel_fixed_mode->HDisplay == 800 &&
 +                          dev_priv->panel_fixed_mode->VDisplay == 600)
 +                      {
 +                              xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 +                                         "Suspected Mac Mini, ignoring the LVDS\n");
 +                              goto disable_exit;
 +                      }
 +              }
 +      }
 +
 +#endif
 +
 +out:
 +      return;
 +
 +failed:
 +        DRM_DEBUG("No LVDS modes found, disabling.\n");
 +      drm_output_destroy(output); /* calls intel_lvds_destroy above */
 +}
index 196298f,0000000..11f3a0a
mode 100644,000000..100644
--- /dev/null
@@@ -1,1084 -1,0 +1,1084 @@@
-       drm_device_t *dev = output->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
 +/*
 + * Copyright Â© 2006-2007 Intel Corporation
 + *
 + * Permission is hereby granted, free of charge, to any person obtaining a
 + * copy of this software and associated documentation files (the "Software"),
 + * to deal in the Software without restriction, including without limitation
 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 + * and/or sell copies of the Software, and to permit persons to whom the
 + * Software is furnished to do so, subject to the following conditions:
 + *
 + * The above copyright notice and this permission notice (including the next
 + * paragraph) shall be included in all copies or substantial portions of the
 + * Software.
 + *
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 + * DEALINGS IN THE SOFTWARE.
 + *
 + * Authors:
 + *    Eric Anholt <eric@anholt.net>
 + */
 +/*
 + * Copyright 2006 Dave Airlie <airlied@linux.ie>
 + *   Jesse Barnes <jesse.barnes@intel.com>
 + */
 +
 +#include <linux/i2c.h>
 +#include <linux/delay.h>
 +#include "drmP.h"
 +#include "drm.h"
 +#include "drm_crtc.h"
 +#include "intel_drv.h"
 +#include "i915_drm.h"
 +#include "i915_drv.h"
 +#include "intel_sdvo_regs.h"
 +
 +struct intel_sdvo_priv {
 +      struct intel_i2c_chan *i2c_bus;
 +      int slaveaddr;
 +      int output_device;
 +
 +      u16 active_outputs;
 +
 +      struct intel_sdvo_caps caps;
 +      int pixel_clock_min, pixel_clock_max;
 +
 +      int save_sdvo_mult;
 +      u16 save_active_outputs;
 +      struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
 +      struct intel_sdvo_dtd save_output_dtd[16];
 +      u32 save_SDVOX;
 +};
 +
 +/**
 + * Writes the SDVOB or SDVOC with the given value, but always writes both
 + * SDVOB and SDVOC to work around apparent hardware issues (according to
 + * comments in the BIOS).
 + */
 +static void intel_sdvo_write_sdvox(struct drm_output *output, u32 val)
 +{
-       drm_device_t *dev = output->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_device *dev = output->dev;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct intel_output *intel_output = output->driver_private;
 +      struct intel_sdvo_priv   *sdvo_priv = intel_output->dev_priv;
 +      u32 bval = val, cval = val;
 +      int i;
 +
 +      if (sdvo_priv->output_device == SDVOB)
 +              cval = I915_READ(SDVOC);
 +      else
 +              bval = I915_READ(SDVOB);
 +      /*
 +       * Write the registers twice for luck. Sometimes,
 +       * writing them only once doesn't appear to 'stick'.
 +       * The BIOS does this too. Yay, magic
 +       */
 +      for (i = 0; i < 2; i++)
 +      {
 +              I915_WRITE(SDVOB, bval);
 +              I915_READ(SDVOB);
 +              I915_WRITE(SDVOC, cval);
 +              I915_READ(SDVOC);
 +      }
 +}
 +
 +static bool intel_sdvo_read_byte(struct drm_output *output, u8 addr,
 +                               u8 *ch)
 +{
 +      struct intel_output *intel_output = output->driver_private;
 +      struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
 +      u8 out_buf[2];
 +      u8 buf[2];
 +      int ret;
 +
 +      struct i2c_msg msgs[] = {
 +              { 
 +                      .addr = sdvo_priv->i2c_bus->slave_addr,
 +                      .flags = 0,
 +                      .len = 1,
 +                      .buf = out_buf,
 +              }, 
 +              {
 +                      .addr = sdvo_priv->i2c_bus->slave_addr,
 +                      .flags = I2C_M_RD,
 +                      .len = 1,
 +                      .buf = buf,
 +              }
 +      };
 +
 +      out_buf[0] = addr;
 +      out_buf[1] = 0;
 +
 +      if ((ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2)) == 2)
 +      {
 +//            DRM_DEBUG("got back from addr %02X = %02x\n", out_buf[0], buf[0]); 
 +              *ch = buf[0];
 +              return true;
 +      }
 +
 +      DRM_DEBUG("i2c transfer returned %d\n", ret);
 +      return false;
 +}
 +
 +
 +static bool intel_sdvo_read_byte_quiet(struct drm_output *output, int addr,
 +                                     u8 *ch)
 +{
 +      return true;
 +
 +}
 +
 +static bool intel_sdvo_write_byte(struct drm_output *output, int addr,
 +                                u8 ch)
 +{
 +      struct intel_output *intel_output = output->driver_private;
 +      u8 out_buf[2];
 +      struct i2c_msg msgs[] = {
 +              { 
 +                      .addr = intel_output->i2c_bus->slave_addr,
 +                      .flags = 0,
 +                      .len = 2,
 +                      .buf = out_buf,
 +              }
 +      };
 +
 +      out_buf[0] = addr;
 +      out_buf[1] = ch;
 +
 +      if (i2c_transfer(&intel_output->i2c_bus->adapter, msgs, 1) == 1)
 +      {
 +              return true;
 +      }
 +      return false;
 +}
 +
 +#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd}
 +/** Mapping of command numbers to names, for debug output */
 +const static struct _sdvo_cmd_name {
 +    u8 cmd;
 +    char *name;
 +} sdvo_cmd_names[] = {
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_RESOLUTION_SUPPORT),
 +    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),
 +};
 +
 +#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
 +#define SDVO_PRIV(output)   ((struct intel_sdvo_priv *) (output)->dev_priv)
 +
 +static void intel_sdvo_write_cmd(struct drm_output *output, u8 cmd,
 +                               void *args, int args_len)
 +{
 +      struct intel_output *intel_output = output->driver_private;
 +      struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
 +      int i;
 +
 +        if (1) {
 +                DRM_DEBUG("%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
 +                for (i = 0; i < args_len; i++)
 +                        DRM_DEBUG("%02X ", ((u8 *)args)[i]);
 +                for (; i < 8; i++)
 +                        DRM_DEBUG("   ");
 +                for (i = 0; i < sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]); i++) {
 +                        if (cmd == sdvo_cmd_names[i].cmd) {
 +                                DRM_DEBUG("(%s)", sdvo_cmd_names[i].name);
 +                                break;
 +                        }
 +                }
 +                if (i == sizeof(sdvo_cmd_names)/ sizeof(sdvo_cmd_names[0]))
 +                        DRM_DEBUG("(%02X)",cmd);
 +                DRM_DEBUG("\n");
 +        }
 +                        
 +      for (i = 0; i < args_len; i++) {
 +              intel_sdvo_write_byte(output, SDVO_I2C_ARG_0 - i, ((u8*)args)[i]);
 +      }
 +
 +      intel_sdvo_write_byte(output, SDVO_I2C_OPCODE, cmd);
 +}
 +
 +static const char *cmd_status_names[] = {
 +      "Power on",
 +      "Success",
 +      "Not supported",
 +      "Invalid arg",
 +      "Pending",
 +      "Target not specified",
 +      "Scaling not supported"
 +};
 +
 +static u8 intel_sdvo_read_response(struct drm_output *output, void *response,
 +                                 int response_len)
 +{
 +      struct intel_output *intel_output = output->driver_private;
 +      struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
 +      int i;
 +      u8 status;
 +      u8 retry = 50;
 +
 +      while (retry--) {
 +              /* Read the command response */
 +              for (i = 0; i < response_len; i++) {
 +                      intel_sdvo_read_byte(output, SDVO_I2C_RETURN_0 + i,
 +                                   &((u8 *)response)[i]);
 +              }
 +
 +              /* read the return status */
 +              intel_sdvo_read_byte(output, SDVO_I2C_CMD_STATUS, &status);
 +
 +              if (1) {
 +                      DRM_DEBUG("%s: R: ", SDVO_NAME(sdvo_priv));
 +                              for (i = 0; i < response_len; i++)
 +                              DRM_DEBUG("%02X ", ((u8 *)response)[i]);
 +                      for (; i < 8; i++)
 +                              DRM_DEBUG("   ");
 +                      if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
 +                              DRM_DEBUG("(%s)", cmd_status_names[status]);
 +                      else
 +                              DRM_DEBUG("(??? %d)", status);
 +                      DRM_DEBUG("\n");
 +              }
 +
 +              if (status != SDVO_CMD_STATUS_PENDING)
 +                      return status;
 +
 +              mdelay(50);
 +      }
 +
 +      return status;
 +}
 +
 +int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
 +{
 +      if (mode->clock >= 100000)
 +              return 1;
 +      else if (mode->clock >= 50000)
 +              return 2;
 +      else
 +              return 4;
 +}
 +
 +/**
 + * Don't check status code from this as it switches the bus back to the
 + * SDVO chips which defeats the purpose of doing a bus switch in the first
 + * place.
 + */
 +void intel_sdvo_set_control_bus_switch(struct drm_output *output, u8 target)
 +{
 +      intel_sdvo_write_cmd(output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, &target, 1);
 +}
 +
 +static bool intel_sdvo_set_target_input(struct drm_output *output, bool target_0, bool target_1)
 +{
 +      struct intel_sdvo_set_target_input_args targets = {0};
 +      u8 status;
 +
 +      if (target_0 && target_1)
 +              return SDVO_CMD_STATUS_NOTSUPP;
 +
 +      if (target_1)
 +              targets.target_1 = 1;
 +
 +      intel_sdvo_write_cmd(output, SDVO_CMD_SET_TARGET_INPUT, &targets,
 +                           sizeof(targets));
 +
 +      status = intel_sdvo_read_response(output, NULL, 0);
 +
 +      return (status == SDVO_CMD_STATUS_SUCCESS);
 +}
 +
 +/**
 + * Return whether each input is trained.
 + *
 + * This function is making an assumption about the layout of the response,
 + * which should be checked against the docs.
 + */
 +static bool intel_sdvo_get_trained_inputs(struct drm_output *output, bool *input_1, bool *input_2)
 +{
 +      struct intel_sdvo_get_trained_inputs_response response;
 +      u8 status;
 +
 +      intel_sdvo_write_cmd(output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
 +      status = intel_sdvo_read_response(output, &response, sizeof(response));
 +      if (status != SDVO_CMD_STATUS_SUCCESS)
 +              return false;
 +
 +      *input_1 = response.input0_trained;
 +      *input_2 = response.input1_trained;
 +      return true;
 +}
 +
 +static bool intel_sdvo_get_active_outputs(struct drm_output *output,
 +                                        u16 *outputs)
 +{
 +      u8 status;
 +
 +      intel_sdvo_write_cmd(output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
 +      status = intel_sdvo_read_response(output, outputs, sizeof(*outputs));
 +
 +      return (status == SDVO_CMD_STATUS_SUCCESS);
 +}
 +
 +static bool intel_sdvo_set_active_outputs(struct drm_output *output,
 +                                        u16 outputs)
 +{
 +      u8 status;
 +
 +      intel_sdvo_write_cmd(output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
 +                           sizeof(outputs));
 +      status = intel_sdvo_read_response(output, NULL, 0);
 +      return (status == SDVO_CMD_STATUS_SUCCESS);
 +}
 +
 +static bool intel_sdvo_set_encoder_power_state(struct drm_output *output,
 +                                             int mode)
 +{
 +      u8 status, state = SDVO_ENCODER_STATE_ON;
 +
 +      switch (mode) {
 +      case DPMSModeOn:
 +              state = SDVO_ENCODER_STATE_ON;
 +              break;
 +      case DPMSModeStandby:
 +              state = SDVO_ENCODER_STATE_STANDBY;
 +              break;
 +      case DPMSModeSuspend:
 +              state = SDVO_ENCODER_STATE_SUSPEND;
 +              break;
 +      case DPMSModeOff:
 +              state = SDVO_ENCODER_STATE_OFF;
 +              break;
 +      }
 +      
 +      intel_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
 +                           sizeof(state));
 +      status = intel_sdvo_read_response(output, NULL, 0);
 +
 +      return (status == SDVO_CMD_STATUS_SUCCESS);
 +}
 +
 +static bool intel_sdvo_get_input_pixel_clock_range(struct drm_output *output,
 +                                                 int *clock_min,
 +                                                 int *clock_max)
 +{
 +      struct intel_sdvo_pixel_clock_range clocks;
 +      u8 status;
 +
 +      intel_sdvo_write_cmd(output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
 +                           NULL, 0);
 +
 +      status = intel_sdvo_read_response(output, &clocks, sizeof(clocks));
 +
 +      if (status != SDVO_CMD_STATUS_SUCCESS)
 +              return false;
 +
 +      /* Convert the values from units of 10 kHz to kHz. */
 +      *clock_min = clocks.min * 10;
 +      *clock_max = clocks.max * 10;
 +
 +      return true;
 +}
 +
 +static bool intel_sdvo_set_target_output(struct drm_output *output,
 +                                       u16 outputs)
 +{
 +      u8 status;
 +
 +      intel_sdvo_write_cmd(output, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
 +                           sizeof(outputs));
 +
 +      status = intel_sdvo_read_response(output, NULL, 0);
 +      return (status == SDVO_CMD_STATUS_SUCCESS);
 +}
 +
 +static bool intel_sdvo_get_timing(struct drm_output *output, u8 cmd,
 +                                struct intel_sdvo_dtd *dtd)
 +{
 +      u8 status;
 +
 +      intel_sdvo_write_cmd(output, cmd, NULL, 0);
 +      status = intel_sdvo_read_response(output, &dtd->part1,
 +                                        sizeof(dtd->part1));
 +      if (status != SDVO_CMD_STATUS_SUCCESS)
 +              return false;
 +
 +      intel_sdvo_write_cmd(output, cmd + 1, NULL, 0);
 +      status = intel_sdvo_read_response(output, &dtd->part2,
 +                                        sizeof(dtd->part2));
 +      if (status != SDVO_CMD_STATUS_SUCCESS)
 +              return false;
 +
 +      return true;
 +}
 +
 +static bool intel_sdvo_get_input_timing(struct drm_output *output,
 +                                       struct intel_sdvo_dtd *dtd)
 +{
 +      return intel_sdvo_get_timing(output,
 +                                   SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
 +}
 +
 +static bool intel_sdvo_get_output_timing(struct drm_output *output,
 +                                       struct intel_sdvo_dtd *dtd)
 +{
 +      return intel_sdvo_get_timing(output,
 +                                   SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd);
 +}
 +
 +static bool intel_sdvo_set_timing(struct drm_output *output, u8 cmd,
 +                                struct intel_sdvo_dtd *dtd)
 +{
 +      u8 status;
 +
 +      intel_sdvo_write_cmd(output, cmd, &dtd->part1, sizeof(dtd->part1));
 +      status = intel_sdvo_read_response(output, NULL, 0);
 +      if (status != SDVO_CMD_STATUS_SUCCESS)
 +              return false;
 +
 +      intel_sdvo_write_cmd(output, cmd + 1, &dtd->part2, sizeof(dtd->part2));
 +      status = intel_sdvo_read_response(output, NULL, 0);
 +      if (status != SDVO_CMD_STATUS_SUCCESS)
 +              return false;
 +
 +      return true;
 +}
 +
 +static bool intel_sdvo_set_input_timing(struct drm_output *output,
 +                                       struct intel_sdvo_dtd *dtd)
 +{
 +      return intel_sdvo_set_timing(output,
 +                                   SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);
 +}
 +
 +static bool intel_sdvo_set_output_timing(struct drm_output *output,
 +                                       struct intel_sdvo_dtd *dtd)
 +{
 +      return intel_sdvo_set_timing(output,
 +                                   SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
 +}
 +
 +#if 0
 +static bool intel_sdvo_get_preferred_input_timing(struct drm_output *output,
 +                                                struct intel_sdvo_dtd *dtd)
 +{
 +      struct intel_output *intel_output = output->driver_private;
 +      struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
 +      u8 status;
 +
 +      intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
 +                           NULL, 0);
 +
 +      status = intel_sdvo_read_response(output, &dtd->part1,
 +                                        sizeof(dtd->part1));
 +      if (status != SDVO_CMD_STATUS_SUCCESS)
 +              return false;
 +
 +      intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
 +                           NULL, 0);
 +      status = intel_sdvo_read_response(output, &dtd->part2,
 +                                        sizeof(dtd->part2));
 +      if (status != SDVO_CMD_STATUS_SUCCESS)
 +              return false;
 +
 +      return true;
 +}
 +#endif
 +
 +static int intel_sdvo_get_clock_rate_mult(struct drm_output *output)
 +{
 +      u8 response, status;
 +
 +      intel_sdvo_write_cmd(output, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
 +      status = intel_sdvo_read_response(output, &response, 1);
 +
 +      if (status != SDVO_CMD_STATUS_SUCCESS) {
 +              DRM_DEBUG("Couldn't get SDVO clock rate multiplier\n");
 +              return SDVO_CLOCK_RATE_MULT_1X;
 +      } else {
 +              DRM_DEBUG("Current clock rate multiplier: %d\n", response);
 +      }
 +
 +      return response;
 +}
 +
 +static bool intel_sdvo_set_clock_rate_mult(struct drm_output *output, u8 val)
 +{
 +      u8 status;
 +
 +      intel_sdvo_write_cmd(output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
 +      status = intel_sdvo_read_response(output, NULL, 0);
 +      if (status != SDVO_CMD_STATUS_SUCCESS)
 +              return false;
 +
 +      return true;
 +}
 +
 +static bool intel_sdvo_mode_fixup(struct drm_output *output,
 +                                struct drm_display_mode *mode,
 +                                struct drm_display_mode *adjusted_mode)
 +{
 +      /* Make the CRTC code factor in the SDVO pixel multiplier.  The SDVO
 +       * device will be told of the multiplier during mode_set.
 +       */
 +      adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode);
 +      return true;
 +}
 +
 +static void intel_sdvo_mode_set(struct drm_output *output,
 +                              struct drm_display_mode *mode,
 +                              struct drm_display_mode *adjusted_mode)
 +{
-       drm_device_t *dev = output->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_device *dev = output->dev;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct drm_crtc *crtc = output->crtc;
 +      struct intel_crtc *intel_crtc = crtc->driver_private;
 +      struct intel_output *intel_output = output->driver_private;
 +      struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
 +      u16 width, height;
 +      u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
 +      u16 h_sync_offset, v_sync_offset;
 +      u32 sdvox;
 +      struct intel_sdvo_dtd output_dtd;
 +      int sdvo_pixel_multiply;
 +
 +      if (!mode)
 +              return;
 +
 +      width = mode->crtc_hdisplay;
 +      height = mode->crtc_vdisplay;
 +
 +      /* do some mode translations */
 +      h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start;
 +      h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
 +
 +      v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start;
 +      v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
 +
 +      h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
 +      v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
 +
 +      output_dtd.part1.clock = mode->clock / 10;
 +      output_dtd.part1.h_active = width & 0xff;
 +      output_dtd.part1.h_blank = h_blank_len & 0xff;
 +      output_dtd.part1.h_high = (((width >> 8) & 0xf) << 4) |
 +              ((h_blank_len >> 8) & 0xf);
 +      output_dtd.part1.v_active = height & 0xff;
 +      output_dtd.part1.v_blank = v_blank_len & 0xff;
 +      output_dtd.part1.v_high = (((height >> 8) & 0xf) << 4) |
 +              ((v_blank_len >> 8) & 0xf);
 +      
 +      output_dtd.part2.h_sync_off = h_sync_offset;
 +      output_dtd.part2.h_sync_width = h_sync_len & 0xff;
 +      output_dtd.part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
 +              (v_sync_len & 0xf);
 +      output_dtd.part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) |
 +              ((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) |
 +              ((v_sync_len & 0x30) >> 4);
 +      
 +      output_dtd.part2.dtd_flags = 0x18;
 +      if (mode->flags & V_PHSYNC)
 +              output_dtd.part2.dtd_flags |= 0x2;
 +      if (mode->flags & V_PVSYNC)
 +              output_dtd.part2.dtd_flags |= 0x4;
 +
 +      output_dtd.part2.sdvo_flags = 0;
 +      output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0;
 +      output_dtd.part2.reserved = 0;
 +
 +      /* Set the output timing to the screen */
 +      intel_sdvo_set_target_output(output, sdvo_priv->active_outputs);
 +      intel_sdvo_set_output_timing(output, &output_dtd);
 +
 +      /* Set the input timing to the screen. Assume always input 0. */
 +      intel_sdvo_set_target_input(output, true, false);
 +
 +      /* We would like to use i830_sdvo_create_preferred_input_timing() to
 +       * provide the device with a timing it can support, if it supports that
 +       * feature.  However, presumably we would need to adjust the CRTC to
 +       * output the preferred timing, and we don't support that currently.
 +       */
 +#if 0
 +      success = intel_sdvo_create_preferred_input_timing(output, clock,
 +                                                         width, height);
 +      if (success) {
 +              struct intel_sdvo_dtd *input_dtd;
 +              
 +              intel_sdvo_get_preferred_input_timing(output, &input_dtd);
 +              intel_sdvo_set_input_timing(output, &input_dtd);
 +      }
 +#else
 +      intel_sdvo_set_input_timing(output, &output_dtd);
 +#endif        
 +
 +      switch (intel_sdvo_get_pixel_multiplier(mode)) {
 +      case 1:
 +              intel_sdvo_set_clock_rate_mult(output,
 +                                             SDVO_CLOCK_RATE_MULT_1X);
 +              break;
 +      case 2:
 +              intel_sdvo_set_clock_rate_mult(output,
 +                                             SDVO_CLOCK_RATE_MULT_2X);
 +              break;
 +      case 4:
 +              intel_sdvo_set_clock_rate_mult(output,
 +                                             SDVO_CLOCK_RATE_MULT_4X);
 +              break;
 +      }       
 +
 +      /* Set the SDVO control regs. */
 +        if (0/*IS_I965GM(dev)*/) {
 +                sdvox = SDVO_BORDER_ENABLE;
 +        } else {
 +                sdvox = I915_READ(sdvo_priv->output_device);
 +                switch (sdvo_priv->output_device) {
 +                case SDVOB:
 +                        sdvox &= SDVOB_PRESERVE_MASK;
 +                        break;
 +                case SDVOC:
 +                        sdvox &= SDVOC_PRESERVE_MASK;
 +                        break;
 +                }
 +                sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
 +        }
 +      if (intel_crtc->pipe == 1)
 +              sdvox |= SDVO_PIPE_B_SELECT;
 +
 +      sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode);
 +      if (IS_I965G(dev)) {
 +              /* done in crtc_mode_set as the dpll_md reg must be written 
 +                 early */
 +      } else if (IS_I945G(dev) || IS_I945GM(dev)) {
 +              /* done in crtc_mode_set as it lives inside the 
 +                 dpll register */
 +      } else {
 +              sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
 +      }
 +
 +      intel_sdvo_write_sdvox(output, sdvox);
 +}
 +
 +static void intel_sdvo_dpms(struct drm_output *output, int mode)
 +{
-       drm_device_t *dev = output->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_device *dev = output->dev;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct intel_output *intel_output = output->driver_private;
 +      struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
 +      u32 temp;
 +
 +      if (mode != DPMSModeOn) {
 +              intel_sdvo_set_active_outputs(output, 0);
 +              if (0)
 +                      intel_sdvo_set_encoder_power_state(output, mode);
 +
 +              if (mode == DPMSModeOff) {
 +                      temp = I915_READ(sdvo_priv->output_device);
 +                      if ((temp & SDVO_ENABLE) != 0) {
 +                              intel_sdvo_write_sdvox(output, temp & ~SDVO_ENABLE);
 +                      }
 +              }
 +      } else {
 +              bool input1, input2;
 +              int i;
 +              u8 status;
 +              
 +              temp = I915_READ(sdvo_priv->output_device);
 +              if ((temp & SDVO_ENABLE) == 0)
 +                      intel_sdvo_write_sdvox(output, temp | SDVO_ENABLE);
 +              for (i = 0; i < 2; i++)
 +                intel_wait_for_vblank(dev);
 +              
 +              status = intel_sdvo_get_trained_inputs(output, &input1,
 +                                                     &input2);
 +
 +              
 +              /* Warn if the device reported failure to sync. */
 +              if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
 +                      DRM_ERROR("First %s output reported failure to sync\n",
 +                                 SDVO_NAME(sdvo_priv));
 +              }
 +              
 +              if (0)
 +                      intel_sdvo_set_encoder_power_state(output, mode);
 +              intel_sdvo_set_active_outputs(output, sdvo_priv->active_outputs);
 +      }       
 +      return;
 +}
 +
 +static void intel_sdvo_save(struct drm_output *output)
 +{
-       drm_device_t *dev = output->dev;
-       drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_device *dev = output->dev;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct intel_output *intel_output = output->driver_private;
 +      struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
 +      int o;
 +
 +      sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(output);
 +      intel_sdvo_get_active_outputs(output, &sdvo_priv->save_active_outputs);
 +
 +      if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
 +              intel_sdvo_set_target_input(output, true, false);
 +              intel_sdvo_get_input_timing(output,
 +                                          &sdvo_priv->save_input_dtd_1);
 +      }
 +
 +      if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
 +              intel_sdvo_set_target_input(output, false, true);
 +              intel_sdvo_get_input_timing(output,
 +                                          &sdvo_priv->save_input_dtd_2);
 +      }
 +
 +      for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
 +      {
 +              u16  this_output = (1 << o);
 +              if (sdvo_priv->caps.output_flags & this_output)
 +              {
 +                      intel_sdvo_set_target_output(output, this_output);
 +                      intel_sdvo_get_output_timing(output,
 +                                                   &sdvo_priv->save_output_dtd[o]);
 +              }
 +      }
 +
 +      sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device);
 +}
 +
 +static void intel_sdvo_restore(struct drm_output *output)
 +{
- void intel_sdvo_init(drm_device_t *dev, int output_device)
++      struct drm_device *dev = output->dev;
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct intel_output *intel_output = output->driver_private;
 +      struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
 +      int o;
 +      int i;
 +      bool input1, input2;
 +      u8 status;
 +
 +      intel_sdvo_set_active_outputs(output, 0);
 +
 +      for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
 +      {
 +              u16  this_output = (1 << o);
 +              if (sdvo_priv->caps.output_flags & this_output) {
 +                      intel_sdvo_set_target_output(output, this_output);
 +                      intel_sdvo_set_output_timing(output, &sdvo_priv->save_output_dtd[o]);
 +              }
 +      }
 +
 +      if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
 +              intel_sdvo_set_target_input(output, true, false);
 +              intel_sdvo_set_input_timing(output, &sdvo_priv->save_input_dtd_1);
 +      }
 +
 +      if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
 +              intel_sdvo_set_target_input(output, false, true);
 +              intel_sdvo_set_input_timing(output, &sdvo_priv->save_input_dtd_2);
 +      }
 +      
 +      intel_sdvo_set_clock_rate_mult(output, sdvo_priv->save_sdvo_mult);
 +      
 +      I915_WRITE(sdvo_priv->output_device, sdvo_priv->save_SDVOX);
 +      
 +      if (sdvo_priv->save_SDVOX & SDVO_ENABLE)
 +      {
 +              for (i = 0; i < 2; i++)
 +                      intel_wait_for_vblank(dev);
 +              status = intel_sdvo_get_trained_inputs(output, &input1, &input2);
 +              if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
 +                      DRM_DEBUG("First %s output reported failure to sync\n",
 +                                 SDVO_NAME(sdvo_priv));
 +      }
 +      
 +      intel_sdvo_set_active_outputs(output, sdvo_priv->save_active_outputs);
 +}
 +
 +static int intel_sdvo_mode_valid(struct drm_output *output,
 +                               struct drm_display_mode *mode)
 +{
 +      struct intel_output *intel_output = output->driver_private;
 +      struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
 +
 +      if (mode->flags & V_DBLSCAN)
 +              return MODE_NO_DBLESCAN;
 +
 +      if (sdvo_priv->pixel_clock_min > mode->clock)
 +              return MODE_CLOCK_HIGH;
 +
 +      if (sdvo_priv->pixel_clock_max < mode->clock)
 +              return MODE_CLOCK_LOW;
 +
 +      return MODE_OK;
 +}
 +
 +static bool intel_sdvo_get_capabilities(struct drm_output *output, struct intel_sdvo_caps *caps)
 +{
 +      u8 status;
 +
 +      intel_sdvo_write_cmd(output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
 +      status = intel_sdvo_read_response(output, caps, sizeof(*caps));
 +      if (status != SDVO_CMD_STATUS_SUCCESS)
 +              return false;
 +
 +      return true;
 +}
 +
 +
 +static void intel_sdvo_dump_cmd(struct drm_output *output, int opcode)
 +{
 +
 +
 +}
 +
 +static void intel_sdvo_dump_device(struct drm_output *output)
 +{
 +
 +}
 +
 +void intel_sdvo_dump(void)
 +{
 +
 +}
 +
 +
 +static enum drm_output_status intel_sdvo_detect(struct drm_output *output)
 +{
 +      u8 response[2];
 +      u8 status;
 +
 +      intel_sdvo_write_cmd(output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
 +      status = intel_sdvo_read_response(output, &response, 2);
 +
 +      DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]);
 +      if ((response[0] != 0) || (response[1] != 0))
 +              return output_status_connected;
 +      else
 +              return output_status_disconnected;
 +}
 +
 +static int intel_sdvo_get_modes(struct drm_output *output)
 +{
 +      /* set the bus switch and get the modes */
 +      intel_sdvo_set_control_bus_switch(output, SDVO_CONTROL_BUS_DDC2);
 +      intel_ddc_get_modes(output);
 +
 +      if (list_empty(&output->probed_modes))
 +              return 0;
 +      return 1;
 +#if 0
 +      /* Mac mini hack.  On this device, I get DDC through the analog, which
 +       * load-detects as disconnected.  I fail to DDC through the SDVO DDC,
 +       * but it does load-detect as connected.  So, just steal the DDC bits 
 +       * from analog when we fail at finding it the right way.
 +       */
 +      /* TODO */
 +      return NULL;
 +
 +      return NULL;
 +#endif
 +}
 +
 +static void intel_sdvo_destroy(struct drm_output *output)
 +{
 +      struct intel_output *intel_output = output->driver_private;
 +
 +      if (intel_output->i2c_bus)
 +              intel_i2c_destroy(intel_output->i2c_bus);
 +
 +      if (intel_output) {
 +              kfree(intel_output);
 +              output->driver_private = NULL;
 +      }
 +}
 +
 +static const struct drm_output_funcs intel_sdvo_output_funcs = {
 +      .dpms = intel_sdvo_dpms,
 +      .save = intel_sdvo_save,
 +      .restore = intel_sdvo_restore,
 +      .mode_valid = intel_sdvo_mode_valid,
 +      .mode_fixup = intel_sdvo_mode_fixup,
 +      .prepare = intel_output_prepare,
 +      .mode_set = intel_sdvo_mode_set,
 +      .commit = intel_output_commit,
 +      .detect = intel_sdvo_detect,
 +      .get_modes = intel_sdvo_get_modes,
 +      .cleanup = intel_sdvo_destroy
 +};
 +
++void intel_sdvo_init(struct drm_device *dev, int output_device)
 +{
 +      struct drm_output *output;
 +      struct intel_output *intel_output;
 +      struct intel_sdvo_priv *sdvo_priv;
 +      struct intel_i2c_chan *i2cbus = NULL;
 +      u8 ch[0x40];
 +      int i;
 +      char name[DRM_OUTPUT_LEN];
 +      char *name_prefix;
 +      char *name_suffix;
 +      
 +
 +      output = drm_output_create(dev, &intel_sdvo_output_funcs, NULL);
 +      if (!output)
 +              return;
 +
 +      intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
 +      if (!intel_output) {
 +              drm_output_destroy(output);
 +              return;
 +      }
 +
 +      sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1);
 +      intel_output->type = INTEL_OUTPUT_SDVO;
 +      output->driver_private = intel_output;
 +      output->interlace_allowed = 0;
 +      output->doublescan_allowed = 0;
 +
 +      /* setup the DDC bus. */
 +      if (output_device == SDVOB)
 +              i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
 +      else
 +              i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
 +
 +      if (i2cbus == NULL) {
 +              drm_output_destroy(output);
 +              return;
 +      }
 +
 +      sdvo_priv->i2c_bus = i2cbus;
 +
 +      if (output_device == SDVOB) {
 +              name_suffix = "-1";
 +              sdvo_priv->i2c_bus->slave_addr = 0x38;
 +      } else {
 +              name_suffix = "-2";
 +              sdvo_priv->i2c_bus->slave_addr = 0x39;
 +      }
 +
 +      sdvo_priv->output_device = output_device;
 +      intel_output->i2c_bus = i2cbus;
 +      intel_output->dev_priv = sdvo_priv;
 +
 +
 +      /* Read the regs to test if we can talk to the device */
 +      for (i = 0; i < 0x40; i++) {
 +              if (!intel_sdvo_read_byte(output, i, &ch[i])) {
 +                      DRM_DEBUG("No SDVO device found on SDVO%c\n",
 +                                output_device == SDVOB ? 'B' : 'C');
 +                      drm_output_destroy(output);
 +                      return;
 +              }
 +      }
 +
 +      intel_sdvo_get_capabilities(output, &sdvo_priv->caps);
 +
 +      memset(&sdvo_priv->active_outputs, 0, sizeof(sdvo_priv->active_outputs));
 +
 +      /* TODO, CVBS, SVID, YPRPB & SCART outputs. */
 +      if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
 +      {
 +              sdvo_priv->active_outputs = SDVO_OUTPUT_RGB0;
 +              output->subpixel_order = SubPixelHorizontalRGB;
 +              name_prefix="RGB";
 +      }
 +      else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1)
 +      {
 +              sdvo_priv->active_outputs = SDVO_OUTPUT_RGB1;
 +              output->subpixel_order = SubPixelHorizontalRGB;
 +              name_prefix="RGB";
 +      }
 +      else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
 +      {
 +              sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS0;
 +              output->subpixel_order = SubPixelHorizontalRGB;
 +              name_prefix="TMDS";
 +      }
 +      else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS1)
 +      {
 +              sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS1;
 +              output->subpixel_order = SubPixelHorizontalRGB;
 +              name_prefix="TMDS";
 +      }
 +      else
 +      {
 +              unsigned char bytes[2];
 +              
 +              memcpy (bytes, &sdvo_priv->caps.output_flags, 2);
 +              DRM_DEBUG("%s: No active RGB or TMDS outputs (0x%02x%02x)\n",
 +                        SDVO_NAME(sdvo_priv),
 +                        bytes[0], bytes[1]);
 +              drm_output_destroy(output);
 +              return;
 +      }
 +      strcpy (name, name_prefix);
 +      strcat (name, name_suffix);
 +      if (!drm_output_rename(output, name))
 +      {
 +              drm_output_destroy(output);
 +              return;
 +      }
 +              
 +
 +      /* Set the input timing to the screen. Assume always input 0. */
 +      intel_sdvo_set_target_input(output, true, false);
 +      
 +      intel_sdvo_get_input_pixel_clock_range(output,
 +                                             &sdvo_priv->pixel_clock_min,
 +                                             &sdvo_priv->pixel_clock_max);
 +
 +
 +      DRM_DEBUG("%s device VID/DID: %02X:%02X.%02X, "
 +                "clock range %dMHz - %dMHz, "
 +                "input 1: %c, input 2: %c, "
 +                "output 1: %c, output 2: %c\n",
 +                SDVO_NAME(sdvo_priv),
 +                sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id,
 +                sdvo_priv->caps.device_rev_id,
 +                sdvo_priv->pixel_clock_min / 1000,
 +                sdvo_priv->pixel_clock_max / 1000,
 +                (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
 +                (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
 +                /* check currently supported outputs */
 +                sdvo_priv->caps.output_flags & 
 +                      (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N',
 +                sdvo_priv->caps.output_flags & 
 +                      (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
 +
 +      intel_output->ddc_bus = i2cbus; 
 +}
@@@ -282,14 -257,13 +257,14 @@@ enum drm_map_flags 
        _DRM_KERNEL = 0x08,          /**< kernel requires access */
        _DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */
        _DRM_CONTAINS_LOCK = 0x20,   /**< SHM page that contains lock */
 -      _DRM_REMOVABLE = 0x40        /**< Removable mapping */
 +      _DRM_REMOVABLE = 0x40,       /**< Removable mapping */
 +        _DRM_DRIVER = 0x80           /**< Driver will take care of it */
- } drm_map_flags_t;
+ };
  
typedef struct drm_ctx_priv_map {
+ struct drm_ctx_priv_map {
        unsigned int ctx_id;     /**< Context requesting private mapping */
        void *handle;            /**< Handle of map */
- } drm_ctx_priv_map_t;
+ };
  
  /**
   * DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls
@@@ -863,119 -882,19 +883,112 @@@ struct drm_bo_set_pin_arg 
  
  #define DRM_BO_MEM_TYPES 8 /* For now. */
  
- typedef union drm_mm_init_arg{
-       struct {
-               enum {
-                       mm_init,
-                       mm_takedown,
-                       mm_query,
-                       mm_lock,
-                       mm_unlock
-               } op;
-               drm_u64_t p_offset;
-               drm_u64_t p_size;
-               unsigned mem_type;
-               unsigned expand_pad[8]; /*Future expansion */
-       } req;
-       struct {
-               drm_handle_t mm_sarea;
-               unsigned expand_pad[8]; /*Future expansion */
-       } rep;
- } drm_mm_init_arg_t;
+ struct drm_mm_type_arg {
+       unsigned int mem_type;
+ };
+ struct drm_mm_init_arg {
+       unsigned int magic;
+       unsigned int major;
+       unsigned int minor;
+       unsigned int mem_type;
+       uint64_t p_offset;
+       uint64_t p_size;
+ };
  
 +/*
 + * Drm mode setting
 + */
 +#define DRM_DISPLAY_INFO_LEN 32
 +#define DRM_OUTPUT_NAME_LEN 32
 +#define DRM_DISPLAY_MODE_LEN 32
 +
 +struct drm_mode_modeinfo {
 +
 +      unsigned int id;
 +
 +      unsigned int clock;
 +      unsigned short hdisplay, hsync_start, hsync_end, htotal, hskew;
 +      unsigned short vdisplay, vsync_start, vsync_end, vtotal, vscan;
 +
 +      unsigned int vrefresh; /* vertical refresh * 1000 */
 +
 +      unsigned int flags;
 +
 +      char name[DRM_DISPLAY_MODE_LEN];
 +};
 +
 +struct drm_mode_card_res {
 +
 +      int count_fbs;
 +      unsigned int __user *fb_id;
 +
 +      int count_crtcs;
 +      unsigned int __user *crtc_id;
 +
 +      int count_outputs;
 +      unsigned int __user *output_id;
 +
 +      int count_modes;
 +        struct drm_mode_modeinfo __user *modes;
 +
 +};
 +
 +struct drm_mode_crtc {
 +      unsigned int crtc_id; /**< Id */
 +      unsigned int fb_id; /**< Id of framebuffer */
 +
 +      int x, y; /**< Position on the frameuffer */
 +
 +      unsigned int mode; /**< Current mode used */
 +
 +      int count_outputs;
 +      unsigned int outputs; /**< Outputs that are connected */
 +
 +      int count_possibles;
 +      unsigned int possibles; /**< Outputs that can be connected */
 +
 +      unsigned int __user *set_outputs; /**< Outputs to be connected */
 +
 +      int gamma_size;
 +
 +};
 +
 +struct drm_mode_get_output {
 +
 +      unsigned int output; /**< Id */
 +      unsigned int crtc; /**< Id of crtc */
 +      unsigned char name[DRM_OUTPUT_NAME_LEN];
 +
 +      unsigned int connection;
 +      unsigned int mm_width, mm_height; /**< HxW in millimeters */
 +      unsigned int subpixel;
 +
 +      int count_crtcs;
 +      unsigned int crtcs; /**< possible crtc to connect to */
 +
 +      int count_clones;
 +      unsigned int clones; /**< list of clones */
 +
 +      int count_modes;
 +      unsigned int __user *modes; /**< list of modes it supports */
 +
 +};
 +
 +struct drm_mode_fb_cmd {
 +        unsigned int buffer_id;
 +        unsigned int width, height;
 +        unsigned int pitch;
 +        unsigned int bpp;
 +        unsigned int handle;
 +      unsigned int depth;
 +};
 +
 +struct drm_mode_mode_cmd {
 +      unsigned int output_id;
 +      unsigned int mode_id;
 +};
 +
  /**
   * \name Ioctls Definitions
   */
  
  #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_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_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_DESTROY         DRM_IOWR(0xc5, 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_DESTROY            DRM_IOWR(0xce, struct drm_bo_handle_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_OP                 DRM_IOWR(0xd3, struct drm_bo_op_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_SET_PIN          DRM_IOWR(0xd6, struct drm_bo_set_pin_arg)
  
 +#define DRM_IOCTL_MODE_GETRESOURCES     DRM_IOWR(0xA0, struct drm_mode_card_res)
 +#define DRM_IOCTL_MODE_GETCRTC          DRM_IOWR(0xA1, struct drm_mode_crtc)
 +#define DRM_IOCTL_MODE_GETOUTPUT        DRM_IOWR(0xA2, struct drm_mode_get_output)
 +#define DRM_IOCTL_MODE_SETCRTC          DRM_IOWR(0xA3, struct drm_mode_crtc)
 +#define DRM_IOCTL_MODE_ADDFB            DRM_IOWR(0xA4, struct drm_mode_fb_cmd)
 +#define DRM_IOCTL_MODE_RMFB             DRM_IOWR(0xA5, unsigned int)
 +#define DRM_IOCTL_MODE_GETFB            DRM_IOWR(0xA6, struct drm_mode_fb_cmd)
 +
 +#define DRM_IOCTL_MODE_ADDMODE         DRM_IOWR(0xA7, struct drm_mode_modeinfo)
 +#define DRM_IOCTL_MODE_RMMODE          DRM_IOWR(0xA8, unsigned int)
 +#define DRM_IOCTL_MODE_ATTACHMODE      DRM_IOWR(0xA9, struct drm_mode_mode_cmd)
 +#define DRM_IOCTL_MODE_DETACHMODE      DRM_IOWR(0xAA, struct drm_mode_mode_cmd)
  /*@}*/
  
  /**
   * the head pointer changes, so that EBUSY only happens if the ring
   * actually stalls for (eg) 3 seconds.
   */
- int i915_wait_ring(drm_device_t * dev, int n, const char *caller)
+ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
  {
--      drm_i915_private_t *dev_priv = dev->dev_private;
--      drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
++      struct drm_i915_private *dev_priv = dev->dev_private;
++      struct drm_i915_ring_buffer *ring = &(dev_priv->ring);
        u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
        int i;
  
                DRM_UDELAY(1);
        }
  
-       return DRM_ERR(EBUSY);
+       return -EBUSY;
  }
  
- void i915_kernel_lost_context(drm_device_t * dev)
+ void i915_kernel_lost_context(struct drm_device * dev)
  {
--      drm_i915_private_t *dev_priv = dev->dev_private;
--      drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
++      struct drm_i915_private *dev_priv = dev->dev_private;
++      struct drm_i915_ring_buffer *ring = &(dev_priv->ring);
  
        ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
        ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
                dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;
  }
  
- int i915_dma_cleanup(drm_device_t * dev)
 -static int i915_dma_cleanup(struct drm_device * dev)
++int i915_dma_cleanup(struct drm_device * dev)
  {
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
++      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
 +
        /* Make sure interrupts are disabled here because the uninstall ioctl
         * may not have been called from userspace and after dev_private
         * is freed, it's too late.
        return 0;
  }
  
- static int i915_initialize(drm_device_t * dev,
-                          drm_i915_private_t * dev_priv,
-                          drm_i915_init_t * init)
+ static int i915_initialize(struct drm_device * dev,
 -                         drm_i915_private_t * dev_priv,
 -                         drm_i915_init_t * init)
++                         struct drm_i915_private * dev_priv,
++                         struct drm_i915_init * init)
  {
--      memset(dev_priv, 0, sizeof(drm_i915_private_t));
++      memset(dev_priv, 0, sizeof(struct drm_i915_private));
  
        dev_priv->sarea = drm_getsarea(dev);
        if (!dev_priv->sarea) {
        return 0;
  }
  
- static int i915_dma_resume(drm_device_t * dev)
+ static int i915_dma_resume(struct drm_device * dev)
  {
--      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
++      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
  
        DRM_DEBUG("%s\n", __FUNCTION__);
  
        return 0;
  }
  
- static int i915_dma_init(DRM_IOCTL_ARGS)
+ static int i915_dma_init(struct drm_device *dev, void *data,
+                        struct drm_file *file_priv)
  {
-       DRM_DEVICE;
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       drm_i915_init_t init;
 -      drm_i915_private_t *dev_priv;
 -      drm_i915_init_t *init = data;
++      struct drm_i915_private *dev_priv;
++      struct drm_i915_init *init = data;
        int retcode = 0;
  
-       DRM_COPY_FROM_USER_IOCTL(init, (drm_i915_init_t __user *) data,
-                                sizeof(init));
-       switch (init.func) {
+       switch (init->func) {
        case I915_INIT_DMA:
-               retcode = i915_initialize(dev, dev_priv, &init);
 -              dev_priv = drm_alloc(sizeof(drm_i915_private_t),
++              dev_priv = drm_alloc(sizeof(struct drm_i915_private),
+                                    DRM_MEM_DRIVER);
+               if (dev_priv == NULL)
+                       return -ENOMEM;
+               retcode = i915_initialize(dev, dev_priv, init);
                break;
        case I915_CLEANUP_DMA:
                retcode = i915_dma_cleanup(dev);
@@@ -259,9 -355,10 +324,10 @@@ static int validate_cmd(int cmd
        return ret;
  }
  
- static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords)
+ static int i915_emit_cmds(struct drm_device * dev, int __user * buffer,
+                         int dwords)
  {
--      drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
        int i;
        RING_LOCALS;
  
        return 0;
  }
  
- static int i915_emit_box(drm_device_t * dev,
-                        drm_clip_rect_t __user * boxes,
+ static int i915_emit_box(struct drm_device * dev,
+                        struct drm_clip_rect __user * boxes,
                         int i, int DR1, int DR4)
  {
--      drm_i915_private_t *dev_priv = dev->dev_private;
-       drm_clip_rect_t box;
++      struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_clip_rect box;
        RING_LOCALS;
  
        if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) {
   * emit.  For now, do it in both places:
   */
  
- void i915_emit_breadcrumb(drm_device_t *dev)
+ void i915_emit_breadcrumb(struct drm_device *dev)
  {
--      drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
        RING_LOCALS;
  
        if (++dev_priv->counter > BREADCRUMB_MASK) {
  }
  
  
- int i915_emit_mi_flush(drm_device_t *dev, uint32_t flush)
+ int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush)
  {
--      drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t flush_cmd = CMD_MI_FLUSH;
        RING_LOCALS;
  
  }
  
  
- static int i915_dispatch_cmdbuffer(drm_device_t * dev,
-                                  drm_i915_cmdbuffer_t * cmd)
+ static int i915_dispatch_cmdbuffer(struct drm_device * dev,
 -                                 drm_i915_cmdbuffer_t * cmd)
++                                 struct drm_i915_cmdbuffer * cmd)
  {
  #ifdef I915_HAVE_FENCE
--      drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
  #endif
        int nbox = cmd->num_cliprects;
        int i = 0, count, ret;
        return 0;
  }
  
- static int i915_dispatch_batchbuffer(drm_device_t * dev,
+ static int i915_dispatch_batchbuffer(struct drm_device * dev,
                                     drm_i915_batchbuffer_t * batch)
  {
--      drm_i915_private_t *dev_priv = dev->dev_private;
-       drm_clip_rect_t __user *boxes = batch->cliprects;
++      struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_clip_rect __user *boxes = batch->cliprects;
        int nbox = batch->num_cliprects;
        int i = 0, count;
        RING_LOCALS;
        return 0;
  }
  
- static void i915_do_dispatch_flip(drm_device_t * dev, int pipe, int sync)
+ static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync)
  {
--      drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
        u32 num_pages, current_page, next_page, dspbase;
-       int shift = 2 * pipe, x, y;
+       int shift = 2 * plane, x, y;
        RING_LOCALS;
  
        /* Calculate display base offset */
        dev_priv->sarea_priv->pf_current_page |= next_page << shift;
  }
  
- void i915_dispatch_flip(drm_device_t * dev, int pipes, int sync)
+ void i915_dispatch_flip(struct drm_device * dev, int planes, int sync)
  {
--      drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
        int i;
  
-       DRM_DEBUG("%s: pipes=0x%x pfCurrentPage=%d\n",
+       DRM_DEBUG("%s: planes=0x%x pfCurrentPage=%d\n",
                  __FUNCTION__,
-                 pipes, dev_priv->sarea_priv->pf_current_page);
+                 planes, dev_priv->sarea_priv->pf_current_page);
  
        i915_emit_mi_flush(dev, MI_READ_FLUSH | MI_EXE_FLUSH);
  
  #endif
  }
  
- static int i915_quiescent(drm_device_t * dev)
+ static int i915_quiescent(struct drm_device * dev)
  {
--      drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
  
        i915_kernel_lost_context(dev);
        return i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);
@@@ -560,13 -663,13 +632,13 @@@ static int i915_flush_ioctl(struct drm_
        return i915_quiescent(dev);
  }
  
- static int i915_batchbuffer(DRM_IOCTL_ARGS)
+ static int i915_batchbuffer(struct drm_device *dev, void *data,
+                           struct drm_file *file_priv)
  {
-       DRM_DEVICE;
--      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
++      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
        drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
            dev_priv->sarea_priv;
-       drm_i915_batchbuffer_t batch;
+       drm_i915_batchbuffer_t *batch = data;
        int ret;
  
        if (!dev_priv->allow_batchbuffer) {
        return ret;
  }
  
- static int i915_cmdbuffer(DRM_IOCTL_ARGS)
+ static int i915_cmdbuffer(struct drm_device *dev, void *data,
+                         struct drm_file *file_priv)
  {
-       DRM_DEVICE;
--      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
--      drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
++      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
++      struct drm_i915_sarea *sarea_priv = (struct drm_i915_sarea *)
            dev_priv->sarea_priv;
-       drm_i915_cmdbuffer_t cmdbuf;
 -      drm_i915_cmdbuffer_t *cmdbuf = data;
++      struct drm_i915_cmdbuffer *cmdbuf = data;
        int ret;
  
-       DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_i915_cmdbuffer_t __user *) data,
-                                sizeof(cmdbuf));
        DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
-                 cmdbuf.buf, cmdbuf.sz, cmdbuf.num_cliprects);
+                 cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects);
  
-       LOCK_TEST_WITH_RETURN(dev, filp);
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
  
-       if (cmdbuf.num_cliprects &&
-           DRM_VERIFYAREA_READ(cmdbuf.cliprects,
-                               cmdbuf.num_cliprects *
-                               sizeof(drm_clip_rect_t))) {
+       if (cmdbuf->num_cliprects &&
+           DRM_VERIFYAREA_READ(cmdbuf->cliprects,
+                               cmdbuf->num_cliprects *
+                               sizeof(struct drm_clip_rect))) {
                DRM_ERROR("Fault accessing cliprects\n");
-               return DRM_ERR(EFAULT);
+               return -EFAULT;
        }
  
-       ret = i915_dispatch_cmdbuffer(dev, &cmdbuf);
+       ret = i915_dispatch_cmdbuffer(dev, cmdbuf);
        if (ret) {
                DRM_ERROR("i915_dispatch_cmdbuffer failed\n");
                return ret;
        return 0;
  }
  
- static int i915_do_cleanup_pageflip(drm_device_t * dev)
 -static int i915_do_cleanup_pageflip(struct drm_device * dev)
++int i915_do_cleanup_pageflip(struct drm_device * dev)
  {
--      drm_i915_private_t *dev_priv = dev->dev_private;
-       int i, pipes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
++      struct drm_i915_private *dev_priv = dev->dev_private;
+       int i, planes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
  
        DRM_DEBUG("%s\n", __FUNCTION__);
  
        return 0;
  }
  
- static int i915_flip_bufs(DRM_IOCTL_ARGS)
+ static int i915_flip_bufs(struct drm_device *dev, void *data, struct drm_file *file_priv)
  {
-       DRM_DEVICE;
-       drm_i915_flip_t param;
 -      drm_i915_flip_t *param = data;
++      struct drm_i915_flip *param = data;
  
        DRM_DEBUG("%s\n", __FUNCTION__);
  
  }
  
  
- static int i915_getparam(DRM_IOCTL_ARGS)
+ static int i915_getparam(struct drm_device *dev, void *data,
+                        struct drm_file *file_priv)
  {
-       DRM_DEVICE;
--      drm_i915_private_t *dev_priv = dev->dev_private;
-       drm_i915_getparam_t param;
 -      drm_i915_getparam_t *param = data;
++      struct drm_i915_private *dev_priv = dev->dev_private;
++      struct drm_i915_getparam *param = data;
        int value;
  
        if (!dev_priv) {
        return 0;
  }
  
- static int i915_setparam(DRM_IOCTL_ARGS)
+ static int i915_setparam(struct drm_device *dev, void *data,
+                        struct drm_file *file_priv)
  {
-       DRM_DEVICE;
--      drm_i915_private_t *dev_priv = dev->dev_private;
-       drm_i915_setparam_t param;
++      struct drm_i915_private *dev_priv = dev->dev_private;
+       drm_i915_setparam_t *param = data;
  
        if (!dev_priv) {
                DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
@@@ -754,35 -841,36 +810,36 @@@ drm_i915_mmio_entry_t mmio_table[] = 
  
  static int mmio_table_size = sizeof(mmio_table)/sizeof(drm_i915_mmio_entry_t);
  
- static int i915_mmio(DRM_IOCTL_ARGS)
+ static int i915_mmio(struct drm_device *dev, void *data,
+                    struct drm_file *file_priv)
  {
-       char buf[32];
-       DRM_DEVICE;
-       drm_i915_private_t *dev_priv = dev->dev_private;
+       uint32_t buf[8];
 -      drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
        drm_i915_mmio_entry_t *e;        
-       drm_i915_mmio_t mmio;
+       drm_i915_mmio_t *mmio = data;
        void __iomem *base;
+       int i;
        if (!dev_priv) {
                DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
-               return DRM_ERR(EINVAL);
+               return -EINVAL;
        }
-       DRM_COPY_FROM_USER_IOCTL(mmio, (drm_i915_mmio_t __user *) data,
-                                sizeof(mmio));
  
-       if (mmio.reg >= mmio_table_size)
-               return DRM_ERR(EINVAL);
+       if (mmio->reg >= mmio_table_size)
+               return -EINVAL;
  
-       e = &mmio_table[mmio.reg];
+       e = &mmio_table[mmio->reg];
        base = (u8 *) dev_priv->mmio_map->handle + e->offset;
  
-         switch (mmio.read_write) {
+       switch (mmio->read_write) {
                case I915_MMIO_READ:
                        if (!(e->flag & I915_MMIO_MAY_READ))
-                               return DRM_ERR(EINVAL);
-                       memcpy_fromio(buf, base, e->size);
-                       if (DRM_COPY_TO_USER(mmio.data, buf, e->size)) {
+                               return -EINVAL;
+                       for (i = 0; i < e->size / 4; i++)
+                               buf[i] = I915_READ(e->offset + i * 4);
+                       if (DRM_COPY_TO_USER(mmio->data, buf, e->size)) {
                                DRM_ERROR("DRM_COPY_TO_USER failed\n");
-                               return DRM_ERR(EFAULT);
+                               return -EFAULT;
                        }
                        break;
  
        return 0;
  }
  
- static int i915_set_status_page(DRM_IOCTL_ARGS)
+ static int i915_set_status_page(struct drm_device *dev, void *data,
+                               struct drm_file *file_priv)
  {
-       DRM_DEVICE;
--      drm_i915_private_t *dev_priv = dev->dev_private;
-       drm_i915_hws_addr_t hws;
++      struct drm_i915_private *dev_priv = dev->dev_private;
+       drm_i915_hws_addr_t *hws = data;
  
        if (!dev_priv) {
                DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
        return 0;
  }
  
- drm_ioctl_desc_t i915_ioctls[] = {
-       [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
-       [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] = { i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
-       [DRM_IOCTL_NR(DRM_I915_SET_VBLANK_PIPE)] = { i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
-       [DRM_IOCTL_NR(DRM_I915_GET_VBLANK_PIPE)] = { i915_vblank_pipe_get, DRM_AUTH },
-       [DRM_IOCTL_NR(DRM_I915_VBLANK_SWAP)] = {i915_vblank_swap, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_I915_MMIO)] = {i915_mmio, DRM_AUTH},
-       [DRM_IOCTL_NR(DRM_I915_HWS_ADDR)] = {i915_set_status_page, DRM_AUTH},
 -int i915_driver_load(struct drm_device *dev, unsigned long flags)
 -{
 -      /* i915 has 4 more counters */
 -      dev->counters += 4;
 -      dev->types[6] = _DRM_STAT_IRQ;
 -      dev->types[7] = _DRM_STAT_PRIMARY;
 -      dev->types[8] = _DRM_STAT_SECONDARY;
 -      dev->types[9] = _DRM_STAT_DMA;
 -
 -      return 0;
 -}
 -
 -void i915_driver_lastclose(struct drm_device * dev)
 -{
 -      if (dev->dev_private) {
 -              drm_i915_private_t *dev_priv = dev->dev_private;
 -              i915_do_cleanup_pageflip(dev);
 -              i915_mem_takedown(&(dev_priv->agp_heap));
 -      }
 -      i915_dma_cleanup(dev);
 -}
 -
 -void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
 -{
 -      if (dev->dev_private) {
 -              drm_i915_private_t *dev_priv = dev->dev_private;
 -              i915_mem_release(dev, file_priv, dev_priv->agp_heap);
 -      }
 -}
 -
+ struct drm_ioctl_desc i915_ioctls[] = {
+       DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_I915_FLIP, i915_flip_bufs, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_I915_GETPARAM, i915_getparam, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_I915_ALLOC, i915_mem_alloc, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_I915_FREE, i915_mem_free, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+       DRM_IOCTL_DEF(DRM_I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_I915_DESTROY_HEAP,  i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ),
+       DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE,  i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ),
+       DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE,  i915_vblank_pipe_get, DRM_AUTH ),
+       DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_I915_MMIO, i915_mmio, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH),
  };
  
  int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
@@@ -39,7 -39,7 +39,7 @@@
                                 * of chars for next/prev indices */
  #define I915_LOG_MIN_TEX_REGION_SIZE 14
  
--typedef struct _drm_i915_init {
++typedef struct drm_i915_init {
        enum {
                I915_INIT_DMA = 0x01,
                I915_CLEANUP_DMA = 0x02,
@@@ -63,8 -63,8 +63,8 @@@
        unsigned int chipset;
  } drm_i915_init_t;
  
--typedef struct _drm_i915_sarea {
-       drm_tex_region_t texList[I915_NR_TEX_REGIONS + 1];
++typedef struct drm_i915_sarea {
+       struct drm_tex_region texList[I915_NR_TEX_REGIONS + 1];
        int last_upload;        /* last time texture was uploaded */
        int last_enqueue;       /* last time a buffer was enqueued */
        int last_dispatch;      /* age of the most recently dispatched buffer */
@@@ -188,7 -188,7 +188,7 @@@ typedef struct drm_i915_flip 
  /* Allow drivers to submit batchbuffers directly to hardware, relying
   * on the security mechanisms provided by hardware.
   */
--typedef struct _drm_i915_batchbuffer {
++typedef struct drm_i915_batchbuffer {
        int start;              /* agp offset */
        int used;               /* nr bytes in use */
        int DR1;                /* hw flags for GFX_OP_DRAWRECT_INFO */
  /* As above, but pass a pointer to userspace buffer which can be
   * validated by the kernel prior to sending to hardware.
   */
--typedef struct _drm_i915_cmdbuffer {
++typedef struct drm_i915_cmdbuffer {
        char __user *buf;       /* pointer to userspace command buffer */
        int sz;                 /* nr bytes in buf */
        int DR1;                /* hw flags for GFX_OP_DRAWRECT_INFO */
   *      - Support vertical blank on secondary display pipe
   * 1.8: New ioctl for ARB_Occlusion_Query
   * 1.9: Usable page flipping and triple buffering
+  * 1.10: Plane/pipe disentangling
   */
  #define DRIVER_MAJOR          1
- #define DRIVER_MINOR          9
- #define DRIVER_PATCHLEVEL     0
- #if defined(__linux__)
- #define I915_HAVE_FENCE
- #define I915_HAVE_BUFFER
+ #if defined(I915_HAVE_FENCE) && defined(I915_HAVE_BUFFER)
+ #define DRIVER_MINOR          10
+ #else
+ #define DRIVER_MINOR          6
  #endif
+ #define DRIVER_PATCHLEVEL     0
  
--typedef struct _drm_i915_ring_buffer {
++struct drm_i915_ring_buffer {
        int tail_mask;
        unsigned long Start;
        unsigned long End;
        int tail;
        int space;
        drm_local_map_t map;
--} drm_i915_ring_buffer_t;
++};
  
  struct mem_block {
        struct mem_block *next;
        struct mem_block *prev;
        int start;
        int size;
-       DRMFILE filp;           /* 0: free, -1: heap, other: real files */
+       struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */
  };
  
--typedef struct _drm_i915_vbl_swap {
++struct drm_i915_vbl_swap {
        struct list_head head;
        drm_drawable_t drw_id;
-       unsigned int pipe;
+       unsigned int plane;
        unsigned int sequence;
        int flip;
--} drm_i915_vbl_swap_t;
++};
  
--typedef struct drm_i915_private {
-       drm_buffer_object_t *ring_buffer;
++struct drm_i915_private {
++      struct drm_buffer_object *ring_buffer;
        drm_local_map_t *sarea;
        drm_local_map_t *mmio_map;
  
 -      drm_i915_sarea_t *sarea_priv;
 -      drm_i915_ring_buffer_t ring;
 +      unsigned long mmiobase;
 +      unsigned long mmiolen;
 +
-       drm_i915_sarea_t *sarea_priv;
-       drm_i915_ring_buffer_t ring;
++      struct drm_i915_sarea *sarea_priv;
++      struct drm_i915_ring_buffer ring;
  
--      drm_dma_handle_t *status_page_dmah;
++      struct drm_dma_handle *status_page_dmah;
        void *hw_status_page;
        dma_addr_t dma_status_page;
        uint32_t counter;
  #ifdef I915_HAVE_BUFFER
        void *agp_iomap;
  #endif
-       spinlock_t swaps_lock;
-       drm_i915_vbl_swap_t vbl_swaps;
+       DRM_SPINTYPE swaps_lock;
 -      drm_i915_vbl_swap_t vbl_swaps;
++      struct drm_i915_vbl_swap vbl_swaps;
        unsigned int swaps_pending;
 -} drm_i915_private_t;
 +
 +      /* LVDS info */
 +      int backlight_duty_cycle;  /* restore backlight to this value */
 +      bool panel_wants_dither;
 +      struct drm_display_mode *panel_fixed_mode;
 +
 +      /* Register state */
 +      u32 saveDSPACNTR;
 +      u32 saveDSPBCNTR;
 +      u32 savePIPEACONF;
 +      u32 savePIPEBCONF;
 +      u32 savePIPEASRC;
 +      u32 savePIPEBSRC;
 +      u32 saveFPA0;
 +      u32 saveFPA1;
 +      u32 saveDPLL_A;
 +      u32 saveDPLL_A_MD;
 +      u32 saveHTOTAL_A;
 +      u32 saveHBLANK_A;
 +      u32 saveHSYNC_A;
 +      u32 saveVTOTAL_A;
 +      u32 saveVBLANK_A;
 +      u32 saveVSYNC_A;
 +      u32 saveDSPASTRIDE;
 +      u32 saveDSPASIZE;
 +      u32 saveDSPAPOS;
 +      u32 saveDSPABASE;
 +      u32 saveDSPASURF;
 +      u32 saveFPB0;
 +      u32 saveFPB1;
 +      u32 saveDPLL_B;
 +      u32 saveDPLL_B_MD;
 +      u32 saveHTOTAL_B;
 +      u32 saveHBLANK_B;
 +      u32 saveHSYNC_B;
 +      u32 saveVTOTAL_B;
 +      u32 saveVBLANK_B;
 +      u32 saveVSYNC_B;
 +      u32 saveDSPBSTRIDE;
 +      u32 saveDSPBSIZE;
 +      u32 saveDSPBPOS;
 +      u32 saveDSPBBASE;
 +      u32 saveDSPBSURF;
 +      u32 saveVCLK_DIVISOR_VGA0;
 +      u32 saveVCLK_DIVISOR_VGA1;
 +      u32 saveVCLK_POST_DIV;
 +      u32 saveVGACNTRL;
 +      u32 saveADPA;
 +      u32 saveLVDS;
 +      u32 saveDVOA;
 +      u32 saveDVOB;
 +      u32 saveDVOC;
 +      u32 savePP_ON;
 +      u32 savePP_OFF;
 +      u32 savePP_CONTROL;
 +      u32 savePP_CYCLE;
 +      u32 savePFIT_CONTROL;
 +      u32 savePaletteA[256];
 +      u32 savePaletteB[256];
 +      u32 saveSWF[17];
 +      u32 saveBLC_PWM_CTL;
- } drm_i915_private_t;
++};
  
  enum intel_chip_family {
        CHIP_I8XX = 0x01,
@@@ -210,46 -150,54 +215,59 @@@ extern struct drm_ioctl_desc i915_ioctl
  extern int i915_max_ioctl;
  
                                /* i915_dma.c */
- extern void i915_kernel_lost_context(drm_device_t * dev);
+ extern void i915_kernel_lost_context(struct drm_device * dev);
  extern int i915_driver_load(struct drm_device *, unsigned long flags);
- extern int i915_driver_unload(drm_device_t *dev);
- extern void i915_driver_lastclose(drm_device_t * dev);
- extern void i915_driver_preclose(drm_device_t * dev, DRMFILE filp);
- extern int i915_driver_device_is_agp(drm_device_t * dev);
++extern int i915_driver_unload(struct drm_device *dev);
+ extern void i915_driver_lastclose(struct drm_device * dev);
+ extern void i915_driver_preclose(struct drm_device *dev,
+                                struct drm_file *file_priv);
+ extern int i915_driver_device_is_agp(struct drm_device * dev);
  extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
                              unsigned long arg);
- extern void i915_emit_breadcrumb(drm_device_t *dev);
- extern void i915_dispatch_flip(drm_device_t * dev, int pipes, int sync);
- extern int i915_emit_mi_flush(drm_device_t *dev, uint32_t flush);
- extern int i915_dma_cleanup(drm_device_t * dev);
+ extern void i915_emit_breadcrumb(struct drm_device *dev);
+ extern void i915_dispatch_flip(struct drm_device * dev, int pipes, int sync);
+ extern int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush);
+ extern int i915_driver_firstopen(struct drm_device *dev);
++extern int i915_do_cleanup_pageflip(struct drm_device *dev);
++extern int i915_dma_cleanup(struct drm_device *dev);
  
  /* i915_irq.c */
- extern int i915_irq_emit(DRM_IOCTL_ARGS);
- extern int i915_irq_wait(DRM_IOCTL_ARGS);
- extern void i915_driver_wait_next_vblank(drm_device_t *dev, int pipe);
- extern int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence);
- extern int i915_driver_vblank_wait2(drm_device_t *dev, unsigned int *sequence);
+ 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 void i915_driver_wait_next_vblank(struct drm_device *dev, int pipe);
+ 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 void 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_user_irq_on(drm_i915_private_t *dev_priv);
- extern void i915_user_irq_off(drm_i915_private_t *dev_priv);
- extern void i915_enable_interrupt (drm_device_t *dev);
- extern int i915_vblank_swap(DRM_IOCTL_ARGS);
+ extern void i915_driver_irq_preinstall(struct drm_device * dev);
+ extern void 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 void i915_user_irq_on(struct drm_i915_private *dev_priv);
++extern void i915_user_irq_off(struct drm_i915_private *dev_priv);
++extern void i915_enable_interrupt (struct drm_device *dev);
+ extern int i915_vblank_swap(struct drm_device *dev, void *data,
+                           struct drm_file *file_priv);
  
  /* 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 */
  
@@@ -276,12 -224,6 +294,12 @@@ extern int i915_move(struct drm_buffer_
  
  #endif
  
- extern void intel_modeset_init(drm_device_t *dev);
- extern void intel_modeset_cleanup(drm_device_t *dev);
 +
 +/* modesetting */
++extern void intel_modeset_init(struct drm_device *dev);
++extern void intel_modeset_cleanup(struct drm_device *dev);
 +
 +
  #define I915_READ(reg)          DRM_READ32(dev_priv->mmio_map, (reg))
  #define I915_WRITE(reg,val)     DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
  #define I915_READ16(reg)      DRM_READ16(dev_priv->mmio_map, (reg))
        I915_WRITE(LP_RING + RING_TAIL, outring);                       \
  } while(0)
  
- extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller);
 +#define MI_NOOP       (0x00 << 23)
 +
+ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
  
 +/*
 + * The Bridge device's PCI config space has information about the
 + * fb aperture size and the amount of pre-reserved memory.
 + */
 +#define INTEL_GMCH_CTRL               0x52
 +#define INTEL_GMCH_ENABLED    0x4
 +#define INTEL_GMCH_MEM_MASK   0x1
 +#define INTEL_GMCH_MEM_64M    0x1
 +#define INTEL_GMCH_MEM_128M   0
 +
 +#define INTEL_855_GMCH_GMS_MASK               (0x7 << 4)
 +#define INTEL_855_GMCH_GMS_DISABLED   (0x0 << 4)
 +#define INTEL_855_GMCH_GMS_STOLEN_1M  (0x1 << 4)
 +#define INTEL_855_GMCH_GMS_STOLEN_4M  (0x2 << 4)
 +#define INTEL_855_GMCH_GMS_STOLEN_8M  (0x3 << 4)
 +#define INTEL_855_GMCH_GMS_STOLEN_16M (0x4 << 4)
 +#define INTEL_855_GMCH_GMS_STOLEN_32M (0x5 << 4)
 +
 +#define INTEL_915G_GMCH_GMS_STOLEN_48M        (0x6 << 4)
 +#define INTEL_915G_GMCH_GMS_STOLEN_64M        (0x7 << 4)
 +
  #define GFX_OP_USER_INTERRUPT                 ((0<<29)|(2<<23))
  #define GFX_OP_BREAKPOINT_INTERRUPT   ((0<<29)|(1<<23))
  #define CMD_REPORT_HEAD                       (7<<23)
  #define BB1_UNPROTECTED       (0<<0)
  #define BB2_END_ADDR_MASK     (~0x7)
  
 +#define I915REG_HWS_PGA               0x02080
++
+ /* Interrupt bits:
+  */
+ #define USER_INT_FLAG    (1<<1)
+ #define VSYNC_PIPEB_FLAG (1<<5)
+ #define VSYNC_PIPEA_FLAG (1<<7)
+ #define HWB_OOM_FLAG     (1<<13) /* binner out of memory */
  #define I915REG_HWSTAM                0x02098
  #define I915REG_INT_IDENTITY_R        0x020a4
  #define I915REG_INT_MASK_R    0x020a8
index fd102b3,0000000..065afcd
mode 100644,000000..100644
--- /dev/null
@@@ -1,322 -1,0 +1,329 @@@
- int i915_driver_load(drm_device_t *dev, unsigned long flags)
 +/*
 + * Copyright (c) 2007 Intel Corporation
 + *   Jesse Barnes <jesse.barnes@intel.com>
 + *
 + * Copyright Â© 2002, 2003 David Dawes <dawes@xfree86.org>
 + *                   2004 Sylvain Meyer
 + *
 + * GPL/BSD dual license
 + */
 +#include "drmP.h"
 +#include "drm.h"
 +#include "drm_sarea.h"
 +#include "i915_drm.h"
 +#include "i915_drv.h"
 +
 +/**
 + * i915_probe_agp - get AGP bootup configuration
 + * @pdev: PCI device
 + * @aperture_size: returns AGP aperture configured size
 + * @preallocated_size: returns size of BIOS preallocated AGP space
 + *
 + * Since Intel integrated graphics are UMA, the BIOS has to set aside
 + * some RAM for the framebuffer at early boot.  This code figures out
 + * how much was set aside so we can use it for our own purposes.
 + */
 +int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size,
 +                 unsigned long *preallocated_size)
 +{
 +      struct pci_dev *bridge_dev;
 +      u16 tmp = 0;
 +      unsigned long overhead;
 +
 +      bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
 +      if (!bridge_dev) {
 +              DRM_ERROR("bridge device not found\n");
 +              return -1;
 +      }
 +
 +      /* Get the fb aperture size and "stolen" memory amount. */
 +      pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp);
 +      pci_dev_put(bridge_dev);
 +
 +      *aperture_size = 1024 * 1024;
 +      *preallocated_size = 1024 * 1024;
 +
 +      switch (pdev->device) {
 +      case PCI_DEVICE_ID_INTEL_82830_CGC:
 +      case PCI_DEVICE_ID_INTEL_82845G_IG:
 +      case PCI_DEVICE_ID_INTEL_82855GM_IG:
 +      case PCI_DEVICE_ID_INTEL_82865_IG:
 +              if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M)
 +                      *aperture_size *= 64;
 +              else
 +                      *aperture_size *= 128;
 +              break;
 +      default:
 +              /* 9xx supports large sizes, just look at the length */
 +              *aperture_size = pci_resource_len(pdev, 2);
 +              break;
 +      }
 +
 +      /*
 +       * Some of the preallocated space is taken by the GTT
 +       * and popup.  GTT is 1K per MB of aperture size, and popup is 4K.
 +       */
 +      overhead = (*aperture_size / 1024) + 4096;
 +      switch (tmp & INTEL_855_GMCH_GMS_MASK) {
 +      case INTEL_855_GMCH_GMS_STOLEN_1M:
 +              break; /* 1M already */
 +      case INTEL_855_GMCH_GMS_STOLEN_4M:
 +              *preallocated_size *= 4;
 +              break;
 +      case INTEL_855_GMCH_GMS_STOLEN_8M:
 +              *preallocated_size *= 8;
 +              break;
 +      case INTEL_855_GMCH_GMS_STOLEN_16M:
 +              *preallocated_size *= 16;
 +              break;
 +      case INTEL_855_GMCH_GMS_STOLEN_32M:
 +              *preallocated_size *= 32;
 +              break;
 +      case INTEL_915G_GMCH_GMS_STOLEN_48M:
 +              *preallocated_size *= 48;
 +              break;
 +      case INTEL_915G_GMCH_GMS_STOLEN_64M:
 +              *preallocated_size *= 64;
 +              break;
 +      case INTEL_855_GMCH_GMS_DISABLED:
 +              DRM_ERROR("video memory is disabled\n");
 +              return -1;
 +      default:
 +              DRM_ERROR("unexpected GMCH_GMS value: 0x%02x\n",
 +                      tmp & INTEL_855_GMCH_GMS_MASK);
 +              return -1;
 +      }
 +      *preallocated_size -= overhead;
 +
 +      return 0;
 +}
 +
 +/**
 + * i915_driver_load - setup chip and create an initial config
 + * @dev: DRM device
 + * @flags: startup flags
 + *
 + * The driver load routine has to do several things:
 + *   - drive output discovery via intel_modeset_init()
 + *   - initialize the memory manager
 + *   - allocate initial config memory
 + *   - setup the DRM framebuffer with the allocated memory
 + */
-       drm_i915_private_t *dev_priv;
++int i915_driver_load(struct drm_device *dev, unsigned long flags)
 +{
-       dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER);
++      struct drm_i915_private *dev_priv;
 +      unsigned long agp_size, prealloc_size;
 +      unsigned long sareapage;
 +      int size, ret;
 +
-               return DRM_ERR(ENOMEM);
++      dev_priv = drm_alloc(sizeof(struct drm_i915_private), DRM_MEM_DRIVER);
 +      if (dev_priv == NULL)
-       memset(dev_priv, 0, sizeof(drm_i915_private_t));
++              return -ENOMEM;
 +
-         dev_priv->sarea_priv = dev_priv->sarea->handle + sizeof(drm_sarea_t);
++      memset(dev_priv, 0, sizeof(struct drm_i915_private));
 +      dev->dev_private = (void *)dev_priv;
 +//    dev_priv->flags = flags;
 +
 +      /* i915 has 4 more counters */
 +      dev->counters += 4;
 +      dev->types[6] = _DRM_STAT_IRQ;
 +      dev->types[7] = _DRM_STAT_PRIMARY;
 +      dev->types[8] = _DRM_STAT_SECONDARY;
 +      dev->types[9] = _DRM_STAT_DMA;
 +
 +      if (IS_I9XX(dev)) {
 +              dev_priv->mmiobase = drm_get_resource_start(dev, 0);
 +              dev_priv->mmiolen = drm_get_resource_len(dev, 0);
 +              dev->mode_config.fb_base =
 +                      drm_get_resource_start(dev, 2) & 0xff000000;
 +      } else if (drm_get_resource_start(dev, 1)) {
 +              dev_priv->mmiobase = drm_get_resource_start(dev, 1);
 +              dev_priv->mmiolen = drm_get_resource_len(dev, 1);
 +              dev->mode_config.fb_base =
 +                      drm_get_resource_start(dev, 0) & 0xff000000;
 +      } else {
 +              DRM_ERROR("Unable to find MMIO registers\n");
 +              return -ENODEV;
 +      }
 +
 +      DRM_DEBUG("fb_base: 0x%08lx\n", dev->mode_config.fb_base);
 +
 +      ret = drm_addmap(dev, dev_priv->mmiobase, dev_priv->mmiolen,
 +                       _DRM_REGISTERS, _DRM_READ_ONLY|_DRM_DRIVER, &dev_priv->mmio_map);
 +      if (ret != 0) {
 +              DRM_ERROR("Cannot add mapping for MMIO registers\n");
 +              return ret;
 +      }
 +
 +      /* prebuild the SAREA */
 +      sareapage = max(SAREA_MAX, PAGE_SIZE);
 +      ret = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK|_DRM_DRIVER,
 +                       &dev_priv->sarea);
 +      if (ret) {
 +              DRM_ERROR("SAREA setup failed\n");
 +              return ret;
 +      }
 +
 +      init_waitqueue_head(&dev->lock.lock_queue);
 +
 +      /* FIXME: assume sarea_priv is right after SAREA */
-                                      DRM_BO_FLAG_NO_EVICT,
-                                      DRM_BO_HINT_DONT_FENCE, 0x1, 0,
++        dev_priv->sarea_priv = dev_priv->sarea->handle + sizeof(struct drm_sarea);
 +
 +      /*
 +       * Initialize the memory manager for local and AGP space
 +       */
 +      drm_bo_driver_init(dev);
 +
 +      i915_probe_agp(dev->pdev, &agp_size, &prealloc_size);
 +      DRM_DEBUG("setting up %ld bytes of VRAM space\n", prealloc_size);
 +      drm_bo_init_mm(dev, DRM_BO_MEM_VRAM, 0, prealloc_size >> PAGE_SHIFT);
 +
 +      I915_WRITE(LP_RING + RING_LEN, 0);
 +      I915_WRITE(LP_RING + RING_HEAD, 0);
 +      I915_WRITE(LP_RING + RING_TAIL, 0);
 +
 +      size = PRIMARY_RINGBUFFER_SIZE;
 +      ret = drm_buffer_object_create(dev, size, drm_bo_type_kernel,
 +                                     DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
 +                                     DRM_BO_FLAG_MEM_VRAM |
-                       return DRM_ERR(ENOMEM);
++                                     DRM_BO_HINT_DONT_FENCE, 0, 0x1, 0,
 +                                     &dev_priv->ring_buffer);
 +      if (ret < 0) {
 +              DRM_ERROR("Unable to allocate ring buffer\n");
 +              return -EINVAL;
 +      }
 +
++      ret = drm_bo_set_pin(dev, dev_priv->ring_buffer, 1);
++      if (ret < 0) {
++              DRM_ERROR("Unable to pin ring buffer\n");
++              return -EINVAL;
++      }
++
 +      /* remap the buffer object properly */
 +      dev_priv->ring.Start = dev_priv->ring_buffer->offset;
 +      dev_priv->ring.End = dev_priv->ring.Start + size;
 +      dev_priv->ring.Size = size;
 +      dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
 +
 +      /* FIXME: need wrapper with PCI mem checks */
 +      ret = drm_mem_reg_ioremap(dev, &dev_priv->ring_buffer->mem,
 +                                (void **) &dev_priv->ring.virtual_start);
 +      if (ret)
 +              DRM_ERROR("error mapping ring buffer: %d\n", ret);
 +
 +      DRM_DEBUG("ring start %08lX, %p, %08lX\n", dev_priv->ring.Start,
 +                dev_priv->ring.virtual_start, dev_priv->ring.Size);
 +
 +      dev_priv->sarea_priv->pf_current_page = 0;
 +
 +      memset((void *)(dev_priv->ring.virtual_start), 0, dev_priv->ring.Size);
 +
 +      I915_WRITE(LP_RING + RING_START, dev_priv->ring.Start);
 +      I915_WRITE(LP_RING + RING_LEN,
 +                 ((dev_priv->ring.Size - 4096) & RING_NR_PAGES) |
 +                 (RING_NO_REPORT | RING_VALID));
 +
 +      /* We are using separate values as placeholders for mechanisms for
 +       * private backbuffer/depthbuffer usage.
 +       */
 +      dev_priv->use_mi_batchbuffer_start = 0;
 +
 +      /* Allow hardware batchbuffers unless told otherwise.
 +       */
 +      dev_priv->allow_batchbuffer = 1;
 +
 +      /* Program Hardware Status Page */
 +      if (!IS_G33(dev)) {
 +              dev_priv->status_page_dmah = 
 +                      drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
 +
 +              if (!dev_priv->status_page_dmah) {
 +                      dev->dev_private = (void *)dev_priv;
 +                      i915_dma_cleanup(dev);
 +                      DRM_ERROR("Can not allocate hardware status page\n");
- int i915_driver_unload(drm_device_t *dev)
++                      return -ENOMEM;
 +              }
 +              dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
 +              dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
 +
 +              memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
 +
 +              I915_WRITE(I915REG_HWS_PGA, dev_priv->dma_status_page);
 +      }
 +      DRM_DEBUG("Enabled hardware status page\n");
 +
 +      intel_modeset_init(dev);
 +      drm_initial_config(dev, false);
 +
 +      return 0;
 +}
 +
-       drm_i915_private_t *dev_priv = dev->dev_private;
++int i915_driver_unload(struct drm_device *dev)
 +{
- void i915_driver_lastclose(drm_device_t * dev)
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +
 +      if (dev_priv->ring.virtual_start) {
 +              drm_core_ioremapfree(&dev_priv->ring.map, dev);
 +      }
 +
 +      if (dev_priv->status_page_dmah) {
 +              drm_pci_free(dev, dev_priv->status_page_dmah);
 +              dev_priv->status_page_dmah = NULL;
 +              dev_priv->hw_status_page = NULL;
 +              dev_priv->dma_status_page = 0;
 +              /* Need to rewrite hardware status page */
 +              I915_WRITE(I915REG_HWS_PGA, 0x1ffff000);
 +      }
 +
 +      if (dev_priv->status_gfx_addr) {
 +              dev_priv->status_gfx_addr = 0;
 +              drm_core_ioremapfree(&dev_priv->hws_map, dev);
 +              I915_WRITE(I915REG_HWS_PGA, 0x1ffff000);
 +      }
 +
 +      I915_WRITE(LP_RING + RING_LEN, 0);
 +
 +      intel_modeset_cleanup(dev);
 +
 +      drm_mem_reg_iounmap(dev, &dev_priv->ring_buffer->mem,
 +                          dev_priv->ring.virtual_start);
 +
 +      DRM_DEBUG("usage is %d\n", atomic_read(&dev_priv->ring_buffer->usage));
 +      mutex_lock(&dev->struct_mutex);
 +      drm_bo_usage_deref_locked(&dev_priv->ring_buffer);
 +      mutex_unlock(&dev->struct_mutex);
 +
 +      if (drm_bo_clean_mm(dev, DRM_BO_MEM_VRAM)) {
 +              DRM_ERROR("Memory manager type 3 not clean. "
 +                        "Delaying takedown\n");
 +      }
 +
 +      drm_bo_driver_finish(dev);
 +
 +        DRM_DEBUG("%p, %p\n", dev_priv->mmio_map, dev_priv->sarea);
 +        drm_rmmap(dev, dev_priv->mmio_map);
 +        drm_rmmap(dev, dev_priv->sarea);
 +
 +      drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
 +
 +      dev->dev_private = NULL;
 +      return 0;
 +}
 +
-       drm_i915_private_t *dev_priv = dev->dev_private;
++void i915_driver_lastclose(struct drm_device *dev)
 +{
- void i915_driver_preclose(drm_device_t * dev, DRMFILE filp)
++      struct drm_i915_private *dev_priv = dev->dev_private;
++
++      i915_do_cleanup_pageflip(dev);
 +      
 +      i915_mem_takedown(&(dev_priv->agp_heap));
 +
 +      i915_dma_cleanup(dev);
 +}
 +
-       drm_i915_private_t *dev_priv = dev->dev_private;
++void i915_driver_preclose(struct drm_device *dev, struct drm_file *filp)
 +{
++      struct drm_i915_private *dev_priv = dev->dev_private;
 +      i915_mem_release(dev, filp, dev_priv->agp_heap);
 +}
 +
  #define MAX_NOPID ((u32)~0)
  
  /**
 -      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+  * i915_get_pipe - return the the pipe associated with a given plane
+  * @dev: DRM device
+  * @plane: plane to look for
+  *
+  * We need to get the pipe associated with a given plane to correctly perform
+  * vblank driven swapping, and they may not always be equal.  So look up the
+  * pipe associated with @plane here.
+  */
+ static int
+ i915_get_pipe(struct drm_device *dev, int plane)
+ {
++      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+       u32 dspcntr;
+       dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR);
+       return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0;
+ }
+ /**
   * Emit a synchronous flip.
   *
   * This function must be called with the drawable spinlock held.
   */
  static void
- i915_dispatch_vsync_flip(drm_device_t *dev, drm_drawable_info_t *drw, int pipe)
+ i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw,
+                        int plane)
  {
--      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
--      drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
++      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
++      struct drm_i915_sarea *sarea_priv = dev_priv->sarea_priv;
        u16 x1, y1, x2, y2;
-       int pf_pipes = 1 << pipe;
+       int pf_planes = 1 << plane;
  
-       /* If the window is visible on the other pipe, we have to flip on that
-        * pipe as well.
+       DRM_SPINLOCK_ASSERT(&dev->drw_lock);
+       /* If the window is visible on the other plane, we have to flip on that
+        * plane as well.
         */
-       if (pipe == 1) {
-               x1 = sarea_priv->pipeA_x;
-               y1 = sarea_priv->pipeA_y;
-               x2 = x1 + sarea_priv->pipeA_w;
-               y2 = y1 + sarea_priv->pipeA_h;
+       if (plane == 1) {
+               x1 = sarea_priv->planeA_x;
+               y1 = sarea_priv->planeA_y;
+               x2 = x1 + sarea_priv->planeA_w;
+               y2 = y1 + sarea_priv->planeA_h;
        } else {
-               x1 = sarea_priv->pipeB_x;
-               y1 = sarea_priv->pipeB_y;
-               x2 = x1 + sarea_priv->pipeB_w;
-               y2 = y1 + sarea_priv->pipeB_h;
+               x1 = sarea_priv->planeB_x;
+               y1 = sarea_priv->planeB_y;
+               x2 = x1 + sarea_priv->planeB_w;
+               y2 = y1 + sarea_priv->planeB_h;
        }
  
        if (x2 > 0 && y2 > 0) {
   *
   * 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 drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
        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) };
-       drm_drawable_info_t *drw;
-       drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       struct drm_drawable_info *drw;
 -      drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
++      struct drm_i915_sarea *sarea_priv = dev_priv->sarea_priv;
        u32 cpp = dev_priv->cpp,  offsets[3];
        u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
                                XY_SRC_COPY_BLT_WRITE_ALPHA |
  
        /* Find buffer swaps scheduled for this vertical blank */
        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);
++              struct drm_i915_vbl_swap *vbl_swap =
++                      list_entry(list, struct drm_i915_vbl_swap, head);
+               int pipe = 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))
                        continue;
  
                list_del(list);
                }
  
                list_for_each(hit, &hits) {
--                      drm_i915_vbl_swap_t *swap_cmp =
--                              list_entry(hit, drm_i915_vbl_swap_t, head);
-                       drm_drawable_info_t *drw_cmp =
++                      struct drm_i915_vbl_swap *swap_cmp =
++                              list_entry(hit, struct drm_i915_vbl_swap, head);
+                       struct drm_drawable_info *drw_cmp =
                                drm_get_drawable_info(dev, swap_cmp->drw_id);
  
                        if (drw_cmp &&
                        lower[0] = lower[1] = sarea_priv->height;
  
                list_for_each(hit, &hits) {
--                      drm_i915_vbl_swap_t *swap_hit =
--                              list_entry(hit, drm_i915_vbl_swap_t, head);
-                       drm_clip_rect_t *rect;
-                       int num_rects, pipe, front, back;
++                      struct drm_i915_vbl_swap *swap_hit =
++                              list_entry(hit, struct drm_i915_vbl_swap, head);
+                       struct drm_clip_rect *rect;
+                       int num_rects, plane, front, back;
                        unsigned short top, bottom;
  
                        drw = drm_get_drawable_info(dev, swap_hit->drw_id);
                }
        }
  
-       spin_unlock_irqrestore(&dev->drw_lock, irqflags);
+       DRM_SPINUNLOCK(&dev->drw_lock);
  
        list_for_each_safe(hit, tmp, &hits) {
--              drm_i915_vbl_swap_t *swap_hit =
--                      list_entry(hit, drm_i915_vbl_swap_t, head);
++              struct drm_i915_vbl_swap *swap_hit =
++                      list_entry(hit, struct drm_i915_vbl_swap, head);
  
                list_del(hit);
  
  
  irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
  {
-       drm_device_t *dev = (drm_device_t *) arg;
-       drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+       struct drm_device *dev = (struct drm_device *) arg;
 -      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
++      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
        u16 temp;
        u32 pipea_stats, pipeb_stats;
  
        return IRQ_HANDLED;
  }
  
- int i915_emit_irq(drm_device_t * dev)
+ int i915_emit_irq(struct drm_device * dev)
  {
        
--      drm_i915_private_t *dev_priv = dev->dev_private;
++      struct drm_i915_private *dev_priv = dev->dev_private;
        RING_LOCALS;
  
        i915_kernel_lost_context(dev);
  
  }
  
--void i915_user_irq_on(drm_i915_private_t *dev_priv)
++void i915_user_irq_on(struct drm_i915_private *dev_priv)
  {
-       spin_lock(&dev_priv->user_irq_lock);
+       DRM_SPINLOCK(&dev_priv->user_irq_lock);
        if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1)){
                dev_priv->irq_enable_reg |= USER_INT_FLAG;
                I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
  
  }
                
--void i915_user_irq_off(drm_i915_private_t *dev_priv)
++void i915_user_irq_off(struct drm_i915_private *dev_priv)
  {
-       spin_lock(&dev_priv->user_irq_lock);
+       DRM_SPINLOCK(&dev_priv->user_irq_lock);
        if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
                //              dev_priv->irq_enable_reg &= ~USER_INT_FLAG;
                //              I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
  }
                
  
- static int i915_wait_irq(drm_device_t * dev, int irq_nr)
+ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
  {
--      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
++      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
        int ret = 0;
  
        DRM_DEBUG("%s irq_nr=%d breadcrumb=%d\n", __FUNCTION__, irq_nr,
        return ret;
  }
  
- static int i915_driver_vblank_do_wait(drm_device_t *dev, unsigned int *sequence,
+ 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;
++      struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned int cur_vblank;
        int ret = 0;
  
        return ret;
  }
  
- void i915_driver_wait_next_vblank(drm_device_t *dev, int pipe)
++void i915_driver_wait_next_vblank(struct drm_device *dev, int pipe)
 +{
 +      unsigned int seq;
 +
 +      seq = pipe ? atomic_read(&dev->vbl_received2) + 1 :
 +              atomic_read(&dev->vbl_received) + 1;
 +
 +      if (!pipe)
 +              i915_driver_vblank_do_wait(dev, &seq, &dev->vbl_received);
 +      else
 +              i915_driver_vblank_do_wait(dev, &seq, &dev->vbl_received2);
 +}
 +
- int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
+ int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
  {
        return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received);
  }
@@@ -456,14 -471,13 +484,13 @@@ int i915_driver_vblank_wait2(struct drm
  
  /* 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;
++      struct drm_i915_private *dev_priv = dev->dev_private;
++      struct drm_i915_irq_emit *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__);
  
  /* Doesn't need the hardware lock.
   */
- int i915_irq_wait(DRM_IOCTL_ARGS)
+ int i915_irq_wait(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_wait_t irqwait;
 -      drm_i915_irq_wait_t *irqwait = data;
++      struct drm_i915_private *dev_priv = dev->dev_private;
++      struct drm_i915_irq_wait *irqwait = data;
  
        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);
  }
  
- void i915_enable_interrupt (drm_device_t *dev)
 -static void i915_enable_interrupt (struct drm_device *dev)
++void i915_enable_interrupt (struct drm_device *dev)
  {
--      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
++      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
        
        dev_priv->irq_enable_reg = USER_INT_FLAG; 
        if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
  
  /* Set the vblank monitor pipe
   */
- int i915_vblank_pipe_set(DRM_IOCTL_ARGS)
+ int i915_vblank_pipe_set(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_pipe_t pipe;
 -      drm_i915_vblank_pipe_t *pipe = data;
++      struct drm_i915_private *dev_priv = dev->dev_private;
++      struct drm_i915_vblank_pipe *pipe = data;
  
        if (!dev_priv) {
                DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
        return 0;
  }
  
- int i915_vblank_pipe_get(DRM_IOCTL_ARGS)
+ int i915_vblank_pipe_get(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_pipe_t pipe;
 -      drm_i915_vblank_pipe_t *pipe = data;
++      struct drm_i915_private *dev_priv = dev->dev_private;
++      struct drm_i915_vblank_pipe *pipe = data;
        u16 flag;
  
        if (!dev_priv) {
  /**
   * 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;
++      struct drm_i915_private *dev_priv = dev->dev_private;
++      struct drm_i915_vblank_swap *swap = data;
++      struct drm_i915_vbl_swap *vbl_swap;
+       unsigned int pipe, seqtype, curseq, plane;
        unsigned long irqflags;
        struct list_head *list;
  
                }
        }
  
-       spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
+       DRM_SPINLOCK_IRQSAVE(&dev_priv->swaps_lock, irqflags);
  
        list_for_each(list, &dev_priv->vbl_swaps.head) {
--              vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head);
++              vbl_swap = list_entry(list, struct drm_i915_vbl_swap, head);
  
-               if (vbl_swap->drw_id == swap.drawable &&
-                   vbl_swap->pipe == pipe &&
-                   vbl_swap->sequence == swap.sequence) {
-                       vbl_swap->flip = (swap.seqtype & _DRM_VBLANK_FLIP);
-                       spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
+               if (vbl_swap->drw_id == swap->drawable &&
+                   vbl_swap->plane == plane &&
+                   vbl_swap->sequence == swap->sequence) {
+                       vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP);
+                       DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->swaps_lock, irqflags);
                        DRM_DEBUG("Already scheduled\n");
                        return 0;
                }
  
  /* drm_dma.h hooks
  */
- void i915_driver_irq_preinstall(drm_device_t * dev)
+ void i915_driver_irq_preinstall(struct drm_device * dev)
  {
--      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
++      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
  
        I915_WRITE16(I915REG_HWSTAM, 0xeffe);
        I915_WRITE16(I915REG_INT_MASK_R, 0x0);
        I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
  }
  
- void i915_driver_irq_postinstall(drm_device_t * dev)
+ void i915_driver_irq_postinstall(struct drm_device * dev)
  {
--      drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
++      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
  
-       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;
  
        I915_WRITE(I915REG_INSTPM, ( 1 << 5) | ( 1 << 21));
  }
  
- 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;
++      struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
        u16 temp;
        if (!dev_priv)
                return;
   * block to allocate, and the ring is drained prior to allocations --
   * in other words allocation is expensive.
   */
- static void mark_block(drm_device_t * dev, struct mem_block *p, int in_use)
+ static void mark_block(struct drm_device * dev, struct mem_block *p, int in_use)
  {
--      drm_i915_private_t *dev_priv = dev->dev_private;
--      drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
-       drm_tex_region_t *list;
++      struct drm_i915_private *dev_priv = dev->dev_private;
++      struct drm_i915_sarea *sarea_priv = dev_priv->sarea_priv;
+       struct drm_tex_region *list;
        unsigned shift, nr;
        unsigned start;
        unsigned end;
@@@ -255,7 -256,7 +256,7 @@@ void i915_mem_takedown(struct mem_bloc
        *heap = NULL;
  }
  
--static struct mem_block **get_heap(drm_i915_private_t * dev_priv, int region)
++static struct mem_block **get_heap(struct drm_i915_private * dev_priv, int region)
  {
        switch (region) {
        case I915_MEM_REGION_AGP:
  
  /* IOCTL HANDLERS */
  
- int i915_mem_alloc(DRM_IOCTL_ARGS)
+ int i915_mem_alloc(struct drm_device *dev, void *data,
+                  struct drm_file *file_priv)
  {
-       DRM_DEVICE;
--      drm_i915_private_t *dev_priv = dev->dev_private;
-       drm_i915_mem_alloc_t alloc;
 -      drm_i915_mem_alloc_t *alloc = data;
++      struct drm_i915_private *dev_priv = dev->dev_private;
++      struct drm_i915_mem_alloc *alloc = data;
        struct mem_block *block, **heap;
  
        if (!dev_priv) {
        return 0;
  }
  
- int i915_mem_free(DRM_IOCTL_ARGS)
+ int i915_mem_free(struct drm_device *dev, void *data,
+                 struct drm_file *file_priv)
  {
-       DRM_DEVICE;
--      drm_i915_private_t *dev_priv = dev->dev_private;
-       drm_i915_mem_free_t memfree;
 -      drm_i915_mem_free_t *memfree = data;
++      struct drm_i915_private *dev_priv = dev->dev_private;
++      struct drm_i915_mem_free *memfree = data;
        struct mem_block *block, **heap;
  
        if (!dev_priv) {
        return 0;
  }
  
- int i915_mem_init_heap(DRM_IOCTL_ARGS)
+ int i915_mem_init_heap(struct drm_device *dev, void *data,
+                      struct drm_file *file_priv)
  {
-       DRM_DEVICE;
--      drm_i915_private_t *dev_priv = dev->dev_private;
-       drm_i915_mem_init_heap_t initheap;
 -      drm_i915_mem_init_heap_t *initheap = data;
++      struct drm_i915_private *dev_priv = dev->dev_private;
++      struct drm_i915_mem_init_heap *initheap = data;
        struct mem_block **heap;
  
        if (!dev_priv) {
  
        if (*heap) {
                DRM_ERROR("heap already initialized?");
-               return DRM_ERR(EFAULT);
+               return -EFAULT;
        }
  
-       return init_heap(heap, initheap.start, initheap.size);
+       return init_heap(heap, initheap->start, initheap->size);
  }
  
- int i915_mem_destroy_heap( DRM_IOCTL_ARGS )
+ int i915_mem_destroy_heap( struct drm_device *dev, void *data,
+                          struct drm_file *file_priv )
  {
-       DRM_DEVICE;
--      drm_i915_private_t *dev_priv = dev->dev_private;
-       drm_i915_mem_destroy_heap_t destroyheap;
 -      drm_i915_mem_destroy_heap_t *destroyheap = data;
++      struct drm_i915_private *dev_priv = dev->dev_private;
++      struct drm_i915_mem_destroy_heap *destroyheap = data;
        struct mem_block **heap;
  
        if ( !dev_priv ) {