Skip to contentSkip to conversation

gma500: ioctl first pass

PATCH In review Alan Cox 4 participants 9 messages Apr 13, 2011 Staging

lore
Share & tools
lore

Alan Cox

author
#0 lore raw

PATCH 1/5 gma500: ioctl first pass

Go through the remaining ioctls and check they make sense

---

 drivers/staging/gma500/psb_drv.c |   61 -----------------------
 drivers/staging/gma500/psb_gtt.c |  103 --------------------------------------
 drivers/staging/gma500/psb_gtt.h |   11 ----
 3 files changed, 1 insertions(+), 174 deletions(-)
drivers/staging/gma500/psb_drv.c +1 -60
index 05c31b9..df50553 100644
@@ -73,10 +73,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
 		DRM_IO(DRM_PSB_KMS_OFF + DRM_COMMAND_BASE)
 #define DRM_IOCTL_PSB_KMS_ON	\
 		DRM_IO(DRM_PSB_KMS_ON + DRM_COMMAND_BASE)
-#define DRM_IOCTL_PSB_VT_LEAVE	\
-		DRM_IO(DRM_PSB_VT_LEAVE + DRM_COMMAND_BASE)
-#define DRM_IOCTL_PSB_VT_ENTER	\
-		DRM_IO(DRM_PSB_VT_ENTER + DRM_COMMAND_BASE)
 #define DRM_IOCTL_PSB_SIZES	\
 		DRM_IOR(DRM_PSB_SIZES + DRM_COMMAND_BASE, \
 			struct drm_psb_sizes_arg)
@@ -96,15 +92,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
 #define DRM_IOCTL_PSB_REGISTER_RW	\
 		DRM_IOWR(DRM_PSB_REGISTER_RW + DRM_COMMAND_BASE, \
 			 struct drm_psb_register_rw_arg)
-#define DRM_IOCTL_PSB_GTT_MAP	\
-		DRM_IOWR(DRM_PSB_GTT_MAP + DRM_COMMAND_BASE, \
-			 struct psb_gtt_mapping_arg)
-#define DRM_IOCTL_PSB_GTT_UNMAP	\
-		DRM_IOW(DRM_PSB_GTT_UNMAP + DRM_COMMAND_BASE, \
-			struct psb_gtt_mapping_arg)
-#define DRM_IOCTL_PSB_UPDATE_GUARD	\
-		DRM_IOWR(DRM_PSB_UPDATE_GUARD + DRM_COMMAND_BASE, \
-			 uint32_t)
 #define DRM_IOCTL_PSB_DPST	\
 		DRM_IOWR(DRM_PSB_DPST + DRM_COMMAND_BASE, \
 			 uint32_t)
@@ -118,13 +105,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
 		DRM_IOWR(DRM_PSB_GET_PIPE_FROM_CRTC_ID + DRM_COMMAND_BASE, \
 			 struct drm_psb_get_pipe_from_crtc_id_arg)
 
-#define DRM_IOCTL_PSB_KMS_OFF	  DRM_IO(DRM_PSB_KMS_OFF + DRM_COMMAND_BASE)
-#define DRM_IOCTL_PSB_KMS_ON	  DRM_IO(DRM_PSB_KMS_ON + DRM_COMMAND_BASE)
-
-static int psb_vt_leave_ioctl(struct drm_device *dev, void *data,
-			      struct drm_file *file_priv);
-static int psb_vt_enter_ioctl(struct drm_device *dev, void *data,
-			      struct drm_file *file_priv);
 static int psb_sizes_ioctl(struct drm_device *dev, void *data,
 			   struct drm_file *file_priv);
 static int psb_dc_state_ioctl(struct drm_device *dev, void * data,
@@ -153,11 +133,6 @@ static struct drm_ioctl_desc psb_ioctls[] = {
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_KMS_ON,
 			psbfb_kms_on_ioctl,
 			DRM_ROOT_ONLY),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_VT_LEAVE, psb_vt_leave_ioctl,
-		      DRM_ROOT_ONLY),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_VT_ENTER,
-			psb_vt_enter_ioctl,
-			DRM_ROOT_ONLY),
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_SIZES, psb_sizes_ioctl, DRM_AUTH),
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_DC_STATE, psb_dc_state_ioctl, DRM_AUTH),
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_ADB, psb_adb_ioctl, DRM_AUTH),
@@ -167,12 +142,6 @@ static struct drm_ioctl_desc psb_ioctls[] = {
 		      DRM_AUTH),
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_REGISTER_RW, psb_register_rw_ioctl,
 		      DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GTT_MAP,
-			psb_gtt_map_meminfo_ioctl,
-			DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GTT_UNMAP,
-			psb_gtt_unmap_meminfo_ioctl,
-			DRM_AUTH),
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST, psb_dpst_ioctl, DRM_AUTH),
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GAMMA, psb_gamma_ioctl, DRM_AUTH),
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH),
@@ -495,7 +464,6 @@ static int psb_do_init(struct drm_device *dev)
 	psb_spank(dev_priv);
 
 	/* mmu_gatt ?? */
-	printk(KERN_INFO "TWOD base %08lX\n", (u32) pg->gatt_start);
       	PSB_WSGX32(pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE);
 
 	return 0;
@@ -721,18 +689,6 @@ int psb_driver_device_is_agp(struct drm_device *dev)
 }
 
 
-static int psb_vt_leave_ioctl(struct drm_device *dev, void *data,
-			      struct drm_file *file_priv)
-{
-	return 0;
-}
-
-static int psb_vt_enter_ioctl(struct drm_device *dev, void *data,
-			      struct drm_file *file_priv)
-{
-	return 0;
-}
-
 static int psb_sizes_ioctl(struct drm_device *dev, void *data,
 			   struct drm_file *file_priv)
 {
@@ -840,7 +796,7 @@ static int psb_dpst_ioctl(struct drm_device *dev, void *data,
 	uint32_t reg;
 
 	if (!gma_power_begin(dev, 0))
-		return 0;
+		return -EIO;
 
 	reg = PSB_RVDC32(PIPEASRC);
 
@@ -1368,28 +1324,13 @@ static unsigned int psb_poll(struct file *filp,
 	return POLLIN | POLLRDNORM;
 }
 
-/* Not sure what we will need yet - in the PVR driver this disappears into
-   a tangle of abstracted handlers and per process crap */
-
-struct psb_priv {
-	int dummy;
-};
-
 static int psb_driver_open(struct drm_device *dev, struct drm_file *priv)
 {
-	struct psb_priv *psb = kzalloc(sizeof(struct psb_priv), GFP_KERNEL);
-	if (psb == NULL)
-		return -ENOMEM;
-	priv->driver_priv = psb;
-	DRM_DEBUG("\n");
-	/*return PVRSRVOpen(dev, priv);*/
 	return 0;
 }
 
 static void psb_driver_close(struct drm_device *dev, struct drm_file *priv)
 {
-	kfree(priv->driver_priv);
-	priv->driver_priv = NULL;
 }
 
 static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd,
drivers/staging/gma500/psb_gtt.c +0 -103

106 lines not on this page · raw message

drivers/staging/gma500/psb_gtt.h +0 -11
index 8a0ef77..5ddc3ae 100644
@@ -87,15 +87,4 @@ extern int psb_gtt_unmap_meminfo_ioctl(struct drm_device *dev, void *data,
 extern int psb_gtt_mm_init(struct psb_gtt *pg);
 extern void psb_gtt_mm_takedown(void);
 
-extern int psb_gtt_map_pvr_memory(struct drm_device *dev,
-                                                                  unsigned int hHandle,
-                                                                  unsigned int ui32TaskId,
-                                                                  dma_addr_t *pPages,
-                                                                  unsigned int ui32PagesNum,
-                                                                  unsigned int *ui32Offset);
-
-extern int psb_gtt_unmap_pvr_memory(struct drm_device *dev,
-                                                                        unsigned int hHandle,
-                                                                        unsigned int ui32TaskId);
-
 #endif
author
#1 lore raw

PATCH 2/5 gma500: prepare to do some actual memory management

---

 drivers/staging/gma500/psb_drv.c |    8 ++------
 1 files changed, 2 insertions(+), 6 deletions(-)
drivers/staging/gma500/psb_drv.c +2 -6
index df50553..d87e00d 100644
@@ -1425,12 +1425,8 @@ static struct drm_driver driver = {
 	.lastclose = psb_lastclose,
 	.open = psb_driver_open,
 	.postclose = psb_driver_close,
-#if 0	/* ACFIXME */
-	.get_map_ofs = drm_core_get_map_ofs,
-	.get_reg_ofs = drm_core_get_reg_ofs,
-	.proc_init = psb_proc_init,
-	.proc_cleanup = psb_proc_cleanup,
-#endif
+	.reclaim_buffers = drm_core_reclaim_buffers,
+
 	.preclose = psb_driver_preclose,
 	.fops = {
 		 .owner = THIS_MODULE,
author
#2 lore raw

PATCH 3/5 gma500: backlight warning

In reply to Alan Cox

The current bl code checks for backlight types and warns if they are not properly set. Set ours to avoid the warning spew

(This one alone is probably 2.6.39 candidate)

---

 drivers/staging/gma500/psb_bl.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/staging/gma500/psb_bl.c +1 -0
index 57b9a5e..5dffc71 100644
@@ -194,6 +194,7 @@ int psb_backlight_init(struct drm_device *dev)
 	struct backlight_properties props;
 	memset(&props, 0, sizeof(struct backlight_properties));
 	props.max_brightness = 100;
+	props.type = BACKLIGHT_PLATFORM;
 
 	psb_backlight_device = backlight_device_register("psb-bl", NULL,
 						(void *)dev, &psb_ops, &props);
#3 lore raw

Re: [PATCH 3/5] gma500: backlight warning

drivers/staging/gma500/psb_bl.c int psb_backlight_init(struct drm_device *dev) · line 197

Quoted 2 lines · Alan Cox
drivers/staging/gma500/psb_bl.c +1 -0
 	props.max_brightness = 100;
+	props.type = BACKLIGHT_PLATFORM;

No, this should be BACKLIGHT_RAW - it's hitting the control registers directly rather than going via a platform interface.

Signature · 1 line
Matthew Garrett | [email protected]
#4 lore raw

Re: [PATCH 3/5] gma500: backlight warning

Quoted 6 lines · On Wed, 13 Apr 2011 14:17:14 +0100 Matthew Garrett <[email protected]> wrote:

drivers/staging/gma500/psb_bl.c int psb_backlight_init(struct drm_device *dev) · line 197

Quoted 2 lines · Alan Cox
drivers/staging/gma500/psb_bl.c +1 -0
 	props.max_brightness = 100;
+	props.type = BACKLIGHT_PLATFORM;

No, this should be BACKLIGHT_RAW - it's hitting the control registers directly rather than going via a platform interface.

Ah ok - I figured it *was* the platform backlight. I'll send Greg a new version of that changeset.

Alan

#5 lore raw

Re: [PATCH 3/5] gma500: backlight warning

Quoted 4 lines · Alan Cox
Quoted 1 line · On Wed, 13 Apr 2011 14:17:14 +0100 Matthew Garrett <[email protected]> wrote:

On Wed, Apr 13, 2011 at 10:36:19AM +0100, Alan Cox wrote:

Quoted 8 lines
Quoted 5 lines

drivers/staging/gma500/psb_bl.c int psb_backlight_init(struct drm_device *dev) · line 197

Quoted 2 lines
drivers/staging/gma500/psb_bl.c +1 -0
 	props.max_brightness = 100;
+	props.type = BACKLIGHT_PLATFORM;

No, this should be BACKLIGHT_RAW - it's hitting the control registers directly rather than going via a platform interface.

Ah ok - I figured it *was* the platform backlight. I'll send Greg a new version of that changeset.

Platform is intended for cases where the platform (ie, the specific instance of a GMA500-based system) provides its own mechanism, rather than falling through to the raw register access. The idea is that platform interfaces may keep track of other platform-level policy such as ALS. Opregion potentially mitigates these problems, but I've still seen some cases where the distinction matters.

Signature · 1 line
Matthew Garrett | [email protected]
author
#6 lore raw

PATCH 4/5 gma500: Add a gtt allocator

In reply to Alan Cox

At the moment we don't do any page backing for the GTT so only the stolen area pages will actually work. That is fine for our initial framebuffer and a bit of testing but will need resolution (including alternate mmap methods and the like for s/g areas) eventually.

Rather than use some of the overcomplex stuff in the DRM we use the existing Linux resource allocators to hand out framebuffers and the like. This also has the nice result that /proc/iomem shows the allocations.

---

 drivers/staging/gma500/psb_drv.h |   16 +++-
 drivers/staging/gma500/psb_fb.c  |   32 +++++---
 drivers/staging/gma500/psb_fb.h  |   13 +--
 drivers/staging/gma500/psb_gtt.c |  155 ++++++++++++++++++++++++++++++++++++++
 drivers/staging/gma500/psb_gtt.h |   30 ++++++-
 5 files changed, 217 insertions(+), 29 deletions(-)
drivers/staging/gma500/psb_drv.h +14 -2
index c3609e0..7a0506a 100644
@@ -21,6 +21,7 @@
 #define _PSB_DRV_H_
 
 #include <linux/version.h>
+#include <linux/kref.h>
 
 #include <drm/drmP.h>
 #include "drm_global.h"
@@ -228,6 +229,7 @@ struct psb_intel_opregion {
 	int enabled;
 };
 
+
 struct drm_psb_private {
 	struct drm_device *dev;
 
@@ -235,19 +237,29 @@ struct drm_psb_private {
 
 	struct psb_gtt *pg;
 
-	/*GTT Memory manager*/
+	/* GTT Memory manager */
 	struct psb_gtt_mm *gtt_mm;
 	struct page *scratch_page;
 
+	struct mutex gtt_mutex;
+	struct resource *gtt_mem;	/* Our PCI resource */
+	struct gtt_range *gtt_handles[GTT_MAX];
+
+	struct gtt_range *fb;		/* System frame buffer */
+
 	struct psb_mmu_driver *mmu;
 	struct psb_mmu_pd *pf_pd;
 
+	/*
+	 * Register base
+	 */
+
 	uint8_t *sgx_reg;
 	uint8_t *vdc_reg;
 	uint32_t gatt_free_offset;
 
 	/*
-	 *Fencing / irq.
+	 * Fencing / irq.
 	 */
 
 	uint32_t vdc_irq_mask;
drivers/staging/gma500/psb_fb.c +20 -12
index 665096f..06715e8 100644
@@ -256,15 +256,15 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 	DRM_DEBUG("vm_pgoff 0x%lx, screen base %p vram_addr %p\n",
 				vma->vm_pgoff, fb_screen_base, pg->vram_addr);
 
-	/*if using stolen memory, */
-	if (fb_screen_base == pg->vram_addr) {
+        /* FIXME: ultimately this needs to become 'if entirely stolen memory' */
+	if (1 || fb_screen_base == pg->vram_addr) {
 		vma->vm_ops = &psbfb_vm_ops;
 		vma->vm_private_data = (void *)psbfb;
 		vma->vm_flags |= VM_RESERVED | VM_IO |
 						VM_MIXEDMAP | VM_DONTEXPAND;
 	} else {
-	/*using IMG meminfo, can I use pvrmmap to map it?*/
-
+	        /* GTT memory backed by kernel/user pages, needs a different
+	           approach ? */
 	}
 
 	return 0;
@@ -328,7 +328,7 @@ static struct drm_framebuffer *psb_framebuffer_create
 
 	drm_helper_mode_fill_fb_struct(&fb->base, r);
 
-	fb->bo = mm_private;
+	fb->mem = mm_private;
 
 	return &fb->base;
 
@@ -464,8 +464,6 @@ static int psbfb_create(struct psb_fbdev *fbdev,
 	struct psb_framebuffer *psbfb;
 	struct drm_mode_fb_cmd mode_cmd;
 	struct device *device = &dev->pdev->dev;
-
-	struct ttm_buffer_object *fbo = NULL;
 	int size, aligned_size;
 	int ret;
 
@@ -480,8 +478,14 @@ static int psbfb_create(struct psb_fbdev *fbdev,
 	size = mode_cmd.pitch * mode_cmd.height;
 	aligned_size = ALIGN(size, PAGE_SIZE);
 
+	/* Allocate the framebuffer in the GTT */
+	/* FIXME: this cannot live in dev_priv once we go multi head */
+	dev_priv->fb = psb_gtt_alloc_range(dev, aligned_size, "fb");
+	if (dev_priv->fb == NULL)
+	        return -ENOMEM;
+
 	mutex_lock(&dev->struct_mutex);
-	fb = psb_framebuffer_create(dev, &mode_cmd, fbo);
+	fb = psb_framebuffer_create(dev, &mode_cmd, dev_priv->fb);
 	if (!fb) {
 		DRM_ERROR("failed to allocate fb.\n");
 		ret = -ENOMEM;
@@ -510,7 +514,11 @@ static int psbfb_create(struct psb_fbdev *fbdev,
 	info->fbops = &psbfb_ops;
 	info->fix.smem_start = dev->mode_config.fb_base;
 	info->fix.smem_len = size;
-	info->screen_base = (char *)pg->vram_addr;
+
+	/* Accessed via stolen memory directly, This only works for stolem
+	   memory however. Need to address this once we start using gtt
+	   pages we allocate */
+	info->screen_base = (char *)pg->vram_addr + dev_priv->fb->offset;
 	info->screen_size = size;
 	memset(info->screen_base, 0, size);
 
@@ -540,6 +548,8 @@ out_err0:
 	fb->funcs->destroy(fb);
 out_err1:
 	mutex_unlock(&dev->struct_mutex);
+	psb_gtt_free_range(dev, dev_priv->fb);
+	dev_priv->fb = NULL;
 	return ret;
 }
 
@@ -586,15 +596,14 @@ int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)
 
 	if (fbdev->psb_fb_helper.fbdev) {
 		info = fbdev->psb_fb_helper.fbdev;
+		psb_gtt_free_range(dev, psbfb->mem);
 		unregister_framebuffer(info);
 		iounmap(info->screen_base);
 		framebuffer_release(info);
 	}
 
 	drm_fb_helper_fini(&fbdev->psb_fb_helper);
-
 	drm_framebuffer_cleanup(&psbfb->base);
-
 	return 0;
 }
 
@@ -652,7 +661,6 @@ int psbfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
 		return 0;
 
 	info = psbfb->fbdev;
-	psbfb->pvrBO = NULL;
 
 	if (info)
 		framebuffer_release(info);
drivers/staging/gma500/psb_fb.h +3 -10
index b4fab92..b943a9f 100644
@@ -28,16 +28,11 @@
 
 #include "psb_drv.h"
 
-/*IMG Headers*/
-/*#include "servicesint.h"*/
-
 struct psb_framebuffer {
 	struct drm_framebuffer base;
 	struct address_space *addr_space;
-	struct ttm_buffer_object *bo;
-	struct fb_info * fbdev;
-	/* struct ttm_bo_kmap_obj kmap; */
-	void *pvrBO;	/* FIXME: sort this out */
+	struct fb_info *fbdev;
+	struct gtt_range *mem;
 	void * hKernelMemInfo;
 	uint32_t size;
 	uint32_t offset;
@@ -45,15 +40,13 @@ struct psb_framebuffer {
 
 struct psb_fbdev {
 	struct drm_fb_helper psb_fb_helper;
-	struct psb_framebuffer * pfb;
+	struct psb_framebuffer *pfb;
 };
 
 
 #define to_psb_fb(x) container_of(x, struct psb_framebuffer, base)
 
-
 extern int psb_intel_connector_clones(struct drm_device *dev, int type_mask);
 
-
 #endif
 
drivers/staging/gma500/psb_gtt.c +154 -1

165 lines not on this page · raw message

drivers/staging/gma500/psb_gtt.h +26 -4
index 5ddc3ae..010ef70 100644
@@ -80,11 +80,33 @@ extern int psb_gtt_map_meminfo(struct drm_device *dev,
 				uint32_t *offset);
 extern int psb_gtt_unmap_meminfo(struct drm_device *dev,
 				 void * hKernelMemInfo);
-extern int psb_gtt_map_meminfo_ioctl(struct drm_device *dev, void *data,
-				     struct drm_file *file_priv);
-extern int psb_gtt_unmap_meminfo_ioctl(struct drm_device *dev, void *data,
-				       struct drm_file *file_priv);
 extern int psb_gtt_mm_init(struct psb_gtt *pg);
 extern void psb_gtt_mm_takedown(void);
 
+/* Each gtt_range describes an allocation in the GTT area */
+struct gtt_range {
+	struct resource resource;
+	u32 offset;
+	int handle;
+	struct kref kref;
+};
+
+/* Most GTT handles we allow allocation of - for now five is fine: we need
+   - Two framebuffers
+   - Maybe an upload area
+   - One cursor (eventually)
+   - One fence page (possibly)
+*/
+
+#define	GTT_MAX		5
+
+extern int psb_gtt_alloc_handle(struct drm_device *dev, struct gtt_range *gt);
+extern int psb_gtt_release_handle(struct drm_device *dev, struct gtt_range *gt);
+extern struct gtt_range *psb_gtt_lookup_handle(struct drm_device *dev,
+							int handle);
+extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
+							const char *name);
+extern void psb_gtt_kref_put(struct gtt_range *gt);
+extern void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt);
+
 #endif
#7 lore raw

Re: [PATCH 4/5] gma500: Add a gtt allocator

Quoted 32 lines · Alan Cox

At the moment we don't do any page backing for the GTT so only the stolen area pages will actually work. That is fine for our initial framebuffer and a bit of testing but will need resolution (including alternate mmap methods and the like for s/g areas) eventually.

Rather than use some of the overcomplex stuff in the DRM we use the existing Linux resource allocators to hand out framebuffers and the like. This also has the nice result that /proc/iomem shows the allocations.

---

 drivers/staging/gma500/psb_drv.h |   16 +++-
 drivers/staging/gma500/psb_fb.c  |   32 +++++---
 drivers/staging/gma500/psb_fb.h  |   13 +--
 drivers/staging/gma500/psb_gtt.c |  155 ++++++++++++++++++++++++++++++++++++++
 drivers/staging/gma500/psb_gtt.h |   30 ++++++-
 5 files changed, 217 insertions(+), 29 deletions(-)
drivers/staging/gma500/psb_drv.h +1 -0
index c3609e0..7a0506a 100644
@@ -21,6 +21,7 @@
 #define _PSB_DRV_H_
 
 #include <linux/version.h>
+#include <linux/kref.h>
 
 #include <drm/drmP.h>
 #include "drm_global.h"

drivers/staging/gma500/psb_drv.h struct psb_intel_opregion { · line 232

Quoted 4 lines
drivers/staging/gma500/psb_drv.h +1 -0
@@ -228,6 +229,7 @@ struct psb_intel_opregion {
 	int enabled;
 };
 
+

Gratuitous newline?

Thierry

author
#8 lore raw

PATCH 5/5 gma500: Tidy up the allocations

In reply to Alan Cox

Now we can do allocations we need to shuffle the fb resource into the fb so we can one day have multiple frame buffer objects.

---

 drivers/staging/gma500/psb_drv.h |    2 --
 drivers/staging/gma500/psb_fb.c  |   13 ++++++-------
 2 files changed, 6 insertions(+), 9 deletions(-)
drivers/staging/gma500/psb_drv.h +0 -2
index 7a0506a..9da6a33 100644
@@ -245,8 +245,6 @@ struct drm_psb_private {
 	struct resource *gtt_mem;	/* Our PCI resource */
 	struct gtt_range *gtt_handles[GTT_MAX];
 
-	struct gtt_range *fb;		/* System frame buffer */
-
 	struct psb_mmu_driver *mmu;
 	struct psb_mmu_pd *pf_pd;
 
drivers/staging/gma500/psb_fb.c +6 -7
index 06715e8..0bad4e0 100644
@@ -466,6 +466,7 @@ static int psbfb_create(struct psb_fbdev *fbdev,
 	struct device *device = &dev->pdev->dev;
 	int size, aligned_size;
 	int ret;
+	struct gtt_range *backing;
 
 	mode_cmd.width = sizes->surface_width;
 	mode_cmd.height = sizes->surface_height;
@@ -479,13 +480,12 @@ static int psbfb_create(struct psb_fbdev *fbdev,
 	aligned_size = ALIGN(size, PAGE_SIZE);
 
 	/* Allocate the framebuffer in the GTT */
-	/* FIXME: this cannot live in dev_priv once we go multi head */
-	dev_priv->fb = psb_gtt_alloc_range(dev, aligned_size, "fb");
-	if (dev_priv->fb == NULL)
+	backing = psb_gtt_alloc_range(dev, aligned_size, "fb");
+	if (backing == NULL)
 	        return -ENOMEM;
 
 	mutex_lock(&dev->struct_mutex);
-	fb = psb_framebuffer_create(dev, &mode_cmd, dev_priv->fb);
+	fb = psb_framebuffer_create(dev, &mode_cmd, backing);
 	if (!fb) {
 		DRM_ERROR("failed to allocate fb.\n");
 		ret = -ENOMEM;
@@ -518,7 +518,7 @@ static int psbfb_create(struct psb_fbdev *fbdev,
 	/* Accessed via stolen memory directly, This only works for stolem
 	   memory however. Need to address this once we start using gtt
 	   pages we allocate */
-	info->screen_base = (char *)pg->vram_addr + dev_priv->fb->offset;
+	info->screen_base = (char *)pg->vram_addr + backing->offset;
 	info->screen_size = size;
 	memset(info->screen_base, 0, size);
 
@@ -548,8 +548,7 @@ out_err0:
 	fb->funcs->destroy(fb);
 out_err1:
 	mutex_unlock(&dev->struct_mutex);
-	psb_gtt_free_range(dev, dev_priv->fb);
-	dev_priv->fb = NULL;
+	psb_gtt_free_range(dev, backing);
 	return ret;
 }