rpms/kernel/devel alsa-tell-user-that-stream-to-be-rewound-is-suspended.patch, NONE, 1.1.2.2 drm-intel-next.patch, 1.4.6.3, 1.4.6.4 drm-intel-pm.patch, NONE, 1.4.2.2 drm-page-flip.patch, NONE, 1.2.6.2 drm-r600-kms.patch, NONE, 1.1.2.2 drm-vga-arb.patch, NONE, 1.5.2.2 hid-ignore-all-recent-imon-devices.patch, NONE, 1.1.2.2 linux-2.6-alsa-improve-hda-powerdown.patch, NONE, 1.1.6.2 linux-2.6-bluetooth-autosuspend.diff, NONE, 1.1.6.2 linux-2.6-defaults-aspm.patch, NONE, 1.1.6.2 linux-2.6-dell-laptop-rfkill-fix.patch, NONE, 1.1.6.2 linux-2.6-driver-level-usb-autosuspend.diff, NONE, 1.1.6.2 linux-2.6-fix-usb-serial-autosuspend.diff, NONE, 1.2.6.2 linux-2.6-ksm-kvm.patch, NONE, 1.2.6.2 linux-2.6-ksm.patch, NONE, 1.2.6.2 linux-2.6-ppc-perfctr-oops-fix.patch, NONE, 1.2.2.2 linux-2.6-qcserial-autosuspend.diff, NONE, 1.1.6.2 linux-2.6-usb-uvc-autosuspend.diff, NONE, 1.1.6.2 linux-2.6-vga-arb.patch, NONE, 1.6.2.2 linux-2.6.30-hush-rom-warning.patch, NONE, 1.2.2.2 linux-2.6.30-no-pcspkr-modalias.patch, NONE, 1.1.6.2 patch-2.6.31-rc5-git3.bz2.sign, NONE, 1.1.2.2 patch-2.6.31-rc5.bz2.sign, NONE, 1.1.6.2 revert-ftrace-powerpc-snafu.patch, NONE, 1.1.2.2 .cvsignore, 1.1014.2.21, 1.1014.2.22 Makefile.config, 1.70, 1.70.6.1 TODO, 1.54.6.8, 1.54.6.9 config-debug, 1.23.6.3, 1.23.6.4 config-generic, 1.238.6.31, 1.238.6.32 config-i686-PAE, 1.1.18.1, 1.1.18.2 config-nodebug, 1.31.6.4, 1.31.6.5 config-powerpc-generic, 1.33.6.8, 1.33.6.9 config-powerpc32-generic, 1.30.6.2, 1.30.6.3 config-powerpc64, 1.27.6.3, 1.27.6.4 config-s390x, 1.11.6.3, 1.11.6.4 config-x86-generic, 1.68.6.14, 1.68.6.15 config-x86_64-generic, 1.68.2.13, 1.68.2.14 drm-nouveau.patch, 1.8.6.13, 1.8.6.14 kernel.spec, 1.1294.2.43, 1.1294.2.44 linux-2.6-pci-cacheline-sizing.patch, 1.1.2.2, 1.1.2.3 linux-2.6.31-lirc.patch, 1.2.2.2, 1.2.2.3 sources, 1.976.2.22, 1.976.2.23 upstream, 1.888.2.21, 1.888.2.22 config-i586, 1.6, NONE drm-modesetting-radeon.patch, 1.54.6.9, NONE drm-next.patch, 1.6.6.7, NONE linux-2.6-cpufreq-ppc-suspend-clusterfuck.patch, 1.1.2.2, NONE patch-2.6.31-rc3.bz2.sign, 1.1.2.2, NONE

myoung myoung at fedoraproject.org
Wed Aug 5 23:00:24 UTC 2009


Author: myoung

Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv27452

Modified Files:
      Tag: private-myoung-dom0-branch
	.cvsignore Makefile.config TODO config-debug config-generic 
	config-i686-PAE config-nodebug config-powerpc-generic 
	config-powerpc32-generic config-powerpc64 config-s390x 
	config-x86-generic config-x86_64-generic drm-nouveau.patch 
	kernel.spec linux-2.6-pci-cacheline-sizing.patch 
	linux-2.6.31-lirc.patch sources upstream 
Added Files:
      Tag: private-myoung-dom0-branch
	alsa-tell-user-that-stream-to-be-rewound-is-suspended.patch 
	drm-intel-next.patch drm-intel-pm.patch drm-page-flip.patch 
	drm-r600-kms.patch drm-vga-arb.patch 
	hid-ignore-all-recent-imon-devices.patch 
	linux-2.6-alsa-improve-hda-powerdown.patch 
	linux-2.6-bluetooth-autosuspend.diff 
	linux-2.6-defaults-aspm.patch 
	linux-2.6-dell-laptop-rfkill-fix.patch 
	linux-2.6-driver-level-usb-autosuspend.diff 
	linux-2.6-fix-usb-serial-autosuspend.diff 
	linux-2.6-ksm-kvm.patch linux-2.6-ksm.patch 
	linux-2.6-ppc-perfctr-oops-fix.patch 
	linux-2.6-qcserial-autosuspend.diff 
	linux-2.6-usb-uvc-autosuspend.diff linux-2.6-vga-arb.patch 
	linux-2.6.30-hush-rom-warning.patch 
	linux-2.6.30-no-pcspkr-modalias.patch 
	patch-2.6.31-rc5-git3.bz2.sign patch-2.6.31-rc5.bz2.sign 
	revert-ftrace-powerpc-snafu.patch 
Removed Files:
      Tag: private-myoung-dom0-branch
	config-i586 drm-modesetting-radeon.patch drm-next.patch 
	linux-2.6-cpufreq-ppc-suspend-clusterfuck.patch 
	patch-2.6.31-rc3.bz2.sign 
Log Message:
update pvops to current rawhide


alsa-tell-user-that-stream-to-be-rewound-is-suspended.patch:
 pcm_native.c |   13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

--- NEW FILE alsa-tell-user-that-stream-to-be-rewound-is-suspended.patch ---
>From 7402d155b5ba6551241cdde9724c2c49dd6cc7ea Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak at v3.sk>
Date: Sun, 2 Aug 2009 17:41:28 +0200
Subject: [PATCH] Tell user that stream to be rewound is suspended

Return STRPIPE instead of EBADF when userspace attempts to rewind
of forward a stream that was suspended in meanwhile, so that it
can be recovered by snd_pcm_recover().

This was causing Pulseaudio to unload the ALSA sink module under a race
condition when it attempted to rewind the stream right after resume from
suspend, before writing to the stream which would cause it to revive the
stream otherwise. Tested to work with Pulseaudio patched to attempt to
snd_pcm_recover() upon receiving an error from snd_pcm_rewind().

Signed-off-by: Lubomir Rintel <lkundrak at v3.sk>
---
 sound/core/pcm_native.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index ac2150e..d89c816 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2208,6 +2208,9 @@ static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *subst
 	case SNDRV_PCM_STATE_XRUN:
 		ret = -EPIPE;
 		goto __end;
+	case SNDRV_PCM_STATE_SUSPENDED:
+		ret = -ESTRPIPE;
+		goto __end;
 	default:
 		ret = -EBADFD;
 		goto __end;
@@ -2253,6 +2256,9 @@ static snd_pcm_sframes_t snd_pcm_capture_rewind(struct snd_pcm_substream *substr
 	case SNDRV_PCM_STATE_XRUN:
 		ret = -EPIPE;
 		goto __end;
+	case SNDRV_PCM_STATE_SUSPENDED:
+		ret = -ESTRPIPE;
+		goto __end;
 	default:
 		ret = -EBADFD;
 		goto __end;
@@ -2299,6 +2305,9 @@ static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *subs
 	case SNDRV_PCM_STATE_XRUN:
 		ret = -EPIPE;
 		goto __end;
+	case SNDRV_PCM_STATE_SUSPENDED:
+		ret = -ESTRPIPE;
+		goto __end;
 	default:
 		ret = -EBADFD;
 		goto __end;
@@ -2345,6 +2354,9 @@ static snd_pcm_sframes_t snd_pcm_capture_forward(struct snd_pcm_substream *subst
 	case SNDRV_PCM_STATE_XRUN:
 		ret = -EPIPE;
 		goto __end;
+	case SNDRV_PCM_STATE_SUSPENDED:
+		ret = -ESTRPIPE;
+		goto __end;
 	default:
 		ret = -EBADFD;
 		goto __end;
-- 
1.6.2.5


drm-intel-next.patch:
 i915_drv.h         |    3 
 i915_gem_debugfs.c |    2 
 i915_irq.c         |  232 +++++++++++-----
 i915_reg.h         |   45 +++
 intel_bios.c       |   40 ++
 intel_bios.h       |   45 +++
 intel_crt.c        |   12 
 intel_display.c    |  759 +++++++++++++++++++++++++++++++++++------------------
 intel_dp.c         |  216 +++++++++++++--
 intel_drv.h        |    3 
 intel_hdmi.c       |   64 ----
 intel_lvds.c       |   12 
 intel_sdvo.c       |  254 ++++++++++++-----
 intel_tv.c         |   22 +
 14 files changed, 1202 insertions(+), 507 deletions(-)

View full diff with command:
/usr/bin/cvs -n -f diff -kk -u -p -N -r 1.4.6.3 -r 1.4.6.4 drm-intel-next.patchIndex: drm-intel-next.patch
===================================================================
RCS file: drm-intel-next.patch
diff -N drm-intel-next.patch
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ drm-intel-next.patch	5 Aug 2009 23:00:10 -0000	1.4.6.4
@@ -0,0 +1,2555 @@
+diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
+index d087528..5f3a259 100644
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -219,6 +219,7 @@ typedef struct drm_i915_private {
+ 	unsigned int lvds_vbt:1;
+ 	unsigned int int_crt_support:1;
+ 	unsigned int lvds_use_ssc:1;
++	unsigned int edp_support:1;
+ 	int lvds_ssc_freq;
+ 
+ 	struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
+@@ -229,6 +230,7 @@ typedef struct drm_i915_private {
+ 
+ 	spinlock_t error_lock;
+ 	struct drm_i915_error_state *first_error;
++	struct work_struct error_work;
+ 
+ 	/* Register state */
+ 	u8 saveLBB;
+@@ -888,6 +890,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
+ 						      IS_I915GM(dev)))
+ #define SUPPORTS_INTEGRATED_HDMI(dev)	(IS_G4X(dev) || IS_IGDNG(dev))
+ #define SUPPORTS_INTEGRATED_DP(dev)	(IS_G4X(dev) || IS_IGDNG(dev))
++#define SUPPORTS_EDP(dev)		(IS_IGDNG_M(dev))
+ #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev))
+ /* dsparb controlled by hw only */
+ #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev))
+diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_gem_debugfs.c
+index 9a44bfc..cb3b974 100644
+--- a/drivers/gpu/drm/i915/i915_gem_debugfs.c
++++ b/drivers/gpu/drm/i915/i915_gem_debugfs.c
+@@ -343,6 +343,8 @@ static int i915_error_state(struct seq_file *m, void *unused)
+ 
+ 	error = dev_priv->first_error;
+ 
++	seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec,
++		   error->time.tv_usec);
+ 	seq_printf(m, "EIR: 0x%08x\n", error->eir);
+ 	seq_printf(m, "  PGTBL_ER: 0x%08x\n", error->pgtbl_er);
+ 	seq_printf(m, "  INSTPM: 0x%08x\n", error->instpm);
+diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
+index 7ba23a6..f340b3f 100644
+--- a/drivers/gpu/drm/i915/i915_irq.c
++++ b/drivers/gpu/drm/i915/i915_irq.c
+@@ -290,6 +290,35 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
+ 	return ret;
+ }
+ 
++/**
++ * i915_error_work_func - do process context error handling work
++ * @work: work struct
++ *
++ * Fire an error uevent so userspace can see that a hang or error
++ * was detected.
++ */
++static void i915_error_work_func(struct work_struct *work)
++{
++	drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
++						    error_work);
++	struct drm_device *dev = dev_priv->dev;
++	char *event_string = "ERROR=1";
++	char *envp[] = { event_string, NULL };
++
++	DRM_DEBUG("generating error event\n");
++
++	kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, envp);
++}
++
++/**
++ * i915_capture_error_state - capture an error record for later analysis
++ * @dev: drm device
++ *
++ * Should be called when an error is detected (either a hang or an error
++ * interrupt) to capture error state from the time of the error.  Fills
++ * out a structure which becomes available in debugfs for user level tools
++ * to pick up.
++ */
+ static void i915_capture_error_state(struct drm_device *dev)
+ {
+ 	struct drm_i915_private *dev_priv = dev->dev_private;
+@@ -325,12 +354,137 @@ static void i915_capture_error_state(struct drm_device *dev)
+ 		error->acthd = I915_READ(ACTHD_I965);
+ 	}
+ 
++	do_gettimeofday(&error->time);
++
+ 	dev_priv->first_error = error;
+ 
+ out:
+ 	spin_unlock_irqrestore(&dev_priv->error_lock, flags);
+ }
+ 
++/**
++ * i915_handle_error - handle an error interrupt
++ * @dev: drm device
++ *
++ * Do some basic checking of regsiter state at error interrupt time and
++ * dump it to the syslog.  Also call i915_capture_error_state() to make
++ * sure we get a record and make it available in debugfs.  Fire a uevent
++ * so userspace knows something bad happened (should trigger collection
++ * of a ring dump etc.).
++ */
++static void i915_handle_error(struct drm_device *dev)
++{
++	struct drm_i915_private *dev_priv = dev->dev_private;
++	u32 eir = I915_READ(EIR);
++	u32 pipea_stats = I915_READ(PIPEASTAT);
++	u32 pipeb_stats = I915_READ(PIPEBSTAT);
++
++	i915_capture_error_state(dev);
++
++	printk(KERN_ERR "render error detected, EIR: 0x%08x\n",
++	       eir);
++
++	if (IS_G4X(dev)) {
++		if (eir & (GM45_ERROR_MEM_PRIV | GM45_ERROR_CP_PRIV)) {
++			u32 ipeir = I915_READ(IPEIR_I965);
++
++			printk(KERN_ERR "  IPEIR: 0x%08x\n",
++			       I915_READ(IPEIR_I965));
++			printk(KERN_ERR "  IPEHR: 0x%08x\n",
++			       I915_READ(IPEHR_I965));
++			printk(KERN_ERR "  INSTDONE: 0x%08x\n",
++			       I915_READ(INSTDONE_I965));
++			printk(KERN_ERR "  INSTPS: 0x%08x\n",
++			       I915_READ(INSTPS));
++			printk(KERN_ERR "  INSTDONE1: 0x%08x\n",
++			       I915_READ(INSTDONE1));
++			printk(KERN_ERR "  ACTHD: 0x%08x\n",
++			       I915_READ(ACTHD_I965));
++			I915_WRITE(IPEIR_I965, ipeir);
++			(void)I915_READ(IPEIR_I965);
++		}
++		if (eir & GM45_ERROR_PAGE_TABLE) {
++			u32 pgtbl_err = I915_READ(PGTBL_ER);
++			printk(KERN_ERR "page table error\n");
++			printk(KERN_ERR "  PGTBL_ER: 0x%08x\n",
++			       pgtbl_err);
++			I915_WRITE(PGTBL_ER, pgtbl_err);
++			(void)I915_READ(PGTBL_ER);
++		}
++	}
++
++	if (IS_I9XX(dev)) {
++		if (eir & I915_ERROR_PAGE_TABLE) {
++			u32 pgtbl_err = I915_READ(PGTBL_ER);
++			printk(KERN_ERR "page table error\n");
++			printk(KERN_ERR "  PGTBL_ER: 0x%08x\n",
++			       pgtbl_err);
++			I915_WRITE(PGTBL_ER, pgtbl_err);
++			(void)I915_READ(PGTBL_ER);
++		}
++	}
++
++	if (eir & I915_ERROR_MEMORY_REFRESH) {
++		printk(KERN_ERR "memory refresh error\n");
++		printk(KERN_ERR "PIPEASTAT: 0x%08x\n",
++		       pipea_stats);
++		printk(KERN_ERR "PIPEBSTAT: 0x%08x\n",
++		       pipeb_stats);
++		/* pipestat has already been acked */
++	}
++	if (eir & I915_ERROR_INSTRUCTION) {
++		printk(KERN_ERR "instruction error\n");
++		printk(KERN_ERR "  INSTPM: 0x%08x\n",
++		       I915_READ(INSTPM));
++		if (!IS_I965G(dev)) {
++			u32 ipeir = I915_READ(IPEIR);
++
++			printk(KERN_ERR "  IPEIR: 0x%08x\n",
++			       I915_READ(IPEIR));
++			printk(KERN_ERR "  IPEHR: 0x%08x\n",
++			       I915_READ(IPEHR));
++			printk(KERN_ERR "  INSTDONE: 0x%08x\n",
++			       I915_READ(INSTDONE));
++			printk(KERN_ERR "  ACTHD: 0x%08x\n",
++			       I915_READ(ACTHD));
++			I915_WRITE(IPEIR, ipeir);
++			(void)I915_READ(IPEIR);
++		} else {
++			u32 ipeir = I915_READ(IPEIR_I965);
++
++			printk(KERN_ERR "  IPEIR: 0x%08x\n",
++			       I915_READ(IPEIR_I965));
++			printk(KERN_ERR "  IPEHR: 0x%08x\n",
++			       I915_READ(IPEHR_I965));
++			printk(KERN_ERR "  INSTDONE: 0x%08x\n",
++			       I915_READ(INSTDONE_I965));
++			printk(KERN_ERR "  INSTPS: 0x%08x\n",
++			       I915_READ(INSTPS));
++			printk(KERN_ERR "  INSTDONE1: 0x%08x\n",
++			       I915_READ(INSTDONE1));
[...2162 lines suppressed...]
++		sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0;
++		encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
++		connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
++		sdvo_priv->is_tv = true;
++		intel_output->needs_tv_clock = true;
++	} else if (flags & SDVO_OUTPUT_RGB0) {
++
++		sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
++		encoder->encoder_type = DRM_MODE_ENCODER_DAC;
++		connector->connector_type = DRM_MODE_CONNECTOR_VGA;
++	} else if (flags & SDVO_OUTPUT_RGB1) {
++
++		sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
++		encoder->encoder_type = DRM_MODE_ENCODER_DAC;
++		connector->connector_type = DRM_MODE_CONNECTOR_VGA;
++	} else if (flags & SDVO_OUTPUT_LVDS0) {
++
++		sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0;
++		encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
++		connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
++		sdvo_priv->is_lvds = true;
++	} else if (flags & SDVO_OUTPUT_LVDS1) {
++
++		sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1;
++		encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
++		connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
++		sdvo_priv->is_lvds = true;
++	} else {
++
++		unsigned char bytes[2];
++
++		sdvo_priv->controlled_output = 0;
++		memcpy(bytes, &sdvo_priv->caps.output_flags, 2);
++		DRM_DEBUG_KMS(I915_SDVO,
++				"%s: Unknown SDVO output type (0x%02x%02x)\n",
++				  SDVO_NAME(sdvo_priv),
++				  bytes[0], bytes[1]);
++		ret = false;
++	}
++
++	if (ret && registered)
++		ret = drm_sysfs_connector_add(connector) == 0 ? true : false;
++
++
++	return ret;
++
++}
++
+ bool intel_sdvo_init(struct drm_device *dev, int output_device)
+ {
+ 	struct drm_connector *connector;
+ 	struct intel_output *intel_output;
+ 	struct intel_sdvo_priv *sdvo_priv;
+ 
+-	int connector_type;
+ 	u8 ch[0x40];
+ 	int i;
+-	int encoder_type;
+ 
+ 	intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
+ 	if (!intel_output) {
+@@ -1925,88 +2075,28 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
+ 	intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo;
+ 
+ 	/* In defaut case sdvo lvds is false */
+-	sdvo_priv->is_lvds = false;
+ 	intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
+ 
+-	if (sdvo_priv->caps.output_flags &
+-	    (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) {
+-		if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
+-			sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS0;
+-		else
+-			sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1;
+-
+-		encoder_type = DRM_MODE_ENCODER_TMDS;
+-		connector_type = DRM_MODE_CONNECTOR_DVID;
+-
+-		if (intel_sdvo_get_supp_encode(intel_output,
+-					       &sdvo_priv->encode) &&
+-		    intel_sdvo_get_digital_encoding_mode(intel_output) &&
+-		    sdvo_priv->is_hdmi) {
+-			/* enable hdmi encoding mode if supported */
+-			intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI);
+-			intel_sdvo_set_colorimetry(intel_output,
+-						   SDVO_COLORIMETRY_RGB256);
+-			connector_type = DRM_MODE_CONNECTOR_HDMIA;
+-		}
+-	}
+-	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_SVID0)
+-	{
+-		sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0;
+-		encoder_type = DRM_MODE_ENCODER_TVDAC;
+-		connector_type = DRM_MODE_CONNECTOR_SVIDEO;
+-		sdvo_priv->is_tv = true;
+-		intel_output->needs_tv_clock = true;
+-	}
+-	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
+-	{
+-		sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
+-		encoder_type = DRM_MODE_ENCODER_DAC;
+-		connector_type = DRM_MODE_CONNECTOR_VGA;
+-	}
+-	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1)
+-	{
+-		sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
+-		encoder_type = DRM_MODE_ENCODER_DAC;
+-		connector_type = DRM_MODE_CONNECTOR_VGA;
+-	}
+-	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS0)
+-	{
+-		sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0;
+-		encoder_type = DRM_MODE_ENCODER_LVDS;
+-		connector_type = DRM_MODE_CONNECTOR_LVDS;
+-		sdvo_priv->is_lvds = true;
+-	}
+-	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS1)
+-	{
+-		sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1;
+-		encoder_type = DRM_MODE_ENCODER_LVDS;
+-		connector_type = DRM_MODE_CONNECTOR_LVDS;
+-		sdvo_priv->is_lvds = true;
+-	}
+-	else
+-	{
+-		unsigned char bytes[2];
+-
+-		sdvo_priv->controlled_output = 0;
+-		memcpy (bytes, &sdvo_priv->caps.output_flags, 2);
+-		DRM_DEBUG_KMS(I915_SDVO,
+-				"%s: Unknown SDVO output type (0x%02x%02x)\n",
+-				  SDVO_NAME(sdvo_priv),
+-				  bytes[0], bytes[1]);
+-		encoder_type = DRM_MODE_ENCODER_NONE;
+-		connector_type = DRM_MODE_CONNECTOR_Unknown;
++	if (intel_sdvo_output_setup(intel_output,
++				    sdvo_priv->caps.output_flags) != true) {
++		DRM_DEBUG("SDVO output failed to setup on SDVO%c\n",
++			  output_device == SDVOB ? 'B' : 'C');
+ 		goto err_i2c;
+ 	}
+ 
++
+ 	connector = &intel_output->base;
+ 	drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,
+-			   connector_type);
++			   connector->connector_type);
++
+ 	drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs);
+ 	connector->interlace_allowed = 0;
+ 	connector->doublescan_allowed = 0;
+ 	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+ 
+-	drm_encoder_init(dev, &intel_output->enc, &intel_sdvo_enc_funcs, encoder_type);
++	drm_encoder_init(dev, &intel_output->enc,
++			&intel_sdvo_enc_funcs, intel_output->enc.encoder_type);
++
+ 	drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs);
+ 
+ 	drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
+diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
+index a43c98e..da4ab4d 100644
+--- a/drivers/gpu/drm/i915/intel_tv.c
++++ b/drivers/gpu/drm/i915/intel_tv.c
+@@ -1490,6 +1490,27 @@ static struct input_res {
+ 	{"1920x1080", 1920, 1080},
+ };
+ 
++/*
++ * Chose preferred mode  according to line number of TV format
++ */
++static void
++intel_tv_chose_preferred_modes(struct drm_connector *connector,
++			       struct drm_display_mode *mode_ptr)
++{
++	struct intel_output *intel_output = to_intel_output(connector);
++	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
++
++	if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
++		mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
++	else if (tv_mode->nbr_end > 480) {
++		if (tv_mode->progressive == true && tv_mode->nbr_end < 720) {
++			if (mode_ptr->vdisplay == 720)
++				mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
++		} else if (mode_ptr->vdisplay == 1080)
++				mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
++	}
++}
++
+ /**
+  * Stub get_modes function.
+  *
+@@ -1544,6 +1565,7 @@ intel_tv_get_modes(struct drm_connector *connector)
+ 		mode_ptr->clock = (int) tmp;
+ 
+ 		mode_ptr->type = DRM_MODE_TYPE_DRIVER;
++		intel_tv_chose_preferred_modes(connector, mode_ptr);
+ 		drm_mode_probed_add(connector, mode_ptr);
+ 		count++;
+ 	}

drm-intel-pm.patch:
 i915_drv.c      |   15 +
 i915_drv.h      |   14 +
 i915_gem.c      |    8 
 i915_reg.h      |   22 ++
 intel_display.c |  484 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
 intel_drv.h     |    4 
 6 files changed, 512 insertions(+), 35 deletions(-)

--- NEW FILE drm-intel-pm.patch ---
diff -up linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_drv.c.jx linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_drv.c
--- linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_drv.c.jx	2009-08-03 14:00:43.000000000 -0400
+++ linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_drv.c	2009-08-03 14:01:07.000000000 -0400
@@ -43,6 +43,21 @@ module_param_named(modeset, i915_modeset
 unsigned int i915_fbpercrtc = 0;
 module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);
 
+unsigned int i915_powersave = 1;
+module_param_named(powersave, i915_powersave, int, 0400);
+
+unsigned int i915_lvdsclock = 1;
+module_param_named(lvdsclock, i915_lvdsclock, int, 0400);
+
+unsigned int i915_lvdsscale = 85;
+module_param_named(lvdsscale, i915_lvdsscale, int, 0400);
+
+unsigned int i915_displayclock = 1;
+module_param_named(displayclock, i915_displayclock, int, 0600);
+
+unsigned int i915_renderclock = 0;
+module_param_named(renderclock, i915_renderclock, int, 0600);
+
 static struct drm_driver driver;
 
 static struct pci_device_id pciidlist[] = {
diff -up linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_drv.h.jx linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_drv.h
--- linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_drv.h.jx	2009-08-03 14:00:44.000000000 -0400
+++ linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_drv.h	2009-08-03 14:01:07.000000000 -0400
@@ -438,6 +438,12 @@ typedef struct drm_i915_private {
 		struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT];
 	} mm;
 	struct sdvo_device_mapping sdvo_mappings[2];
+
+	/* Reclocking support */
+	struct work_struct idle_work;
+	struct timer_list idle_timer;
+	bool busy;
+	u16 orig_clock;
 } drm_i915_private_t;
 
 /** driver private structure attached to each drm_gem_object */
@@ -567,6 +573,11 @@ enum intel_chip_family {
 extern struct drm_ioctl_desc i915_ioctls[];
 extern int i915_max_ioctl;
 extern unsigned int i915_fbpercrtc;
+extern unsigned int i915_powersave;
+extern unsigned int i915_lvdsclock;
+extern unsigned int i915_lvdsscale;
+extern unsigned int i915_displayclock;
+extern unsigned int i915_renderclock;
 
 extern int i915_master_create(struct drm_device *dev, struct drm_master *master);
 extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master);
@@ -895,6 +906,9 @@ extern int i915_wait_ring(struct drm_dev
 /* dsparb controlled by hw only */
 #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev))
 
+#define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IGDNG(dev))
+#define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IGDNG(dev))
+
 #define PRIMARY_RINGBUFFER_SIZE         (128*1024)
 
 #endif
diff -up linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_gem.c.jx linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_gem.c
--- linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_gem.c.jx	2009-08-03 14:00:43.000000000 -0400
+++ linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_gem.c	2009-08-03 14:01:07.000000000 -0400
@@ -29,6 +29,7 @@
 #include "drm.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
+#include "intel_drv.h"
 #include <linux/swap.h>
 #include <linux/pci.h>
 
@@ -980,6 +981,7 @@ i915_gem_set_domain_ioctl(struct drm_dev
 {
 	struct drm_i915_gem_set_domain *args = data;
 	struct drm_gem_object *obj;
+	struct drm_i915_gem_object *obj_priv;
 	uint32_t read_domains = args->read_domains;
 	uint32_t write_domain = args->write_domain;
 	int ret;
@@ -1003,8 +1005,12 @@ i915_gem_set_domain_ioctl(struct drm_dev
 	obj = drm_gem_object_lookup(dev, file_priv, args->handle);
 	if (obj == NULL)
 		return -EBADF;
+	obj_priv = obj->driver_private;
 
 	mutex_lock(&dev->struct_mutex);
+
+	intel_mark_busy(dev, obj);
+
 #if WATCH_BUF
 	DRM_INFO("set_domain_ioctl %p(%zd), %08x %08x\n",
 		 obj, obj->size, read_domains, write_domain);
@@ -2761,6 +2767,8 @@ i915_gem_object_set_to_gpu_domain(struct
 	BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU);
 	BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU);
 
+	intel_mark_busy(dev, obj);
+
 #if WATCH_BUF
 	DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n",
 		 __func__, obj,
diff -up linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_reg.h.jx linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_reg.h
--- linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_reg.h.jx	2009-08-03 14:00:44.000000000 -0400
+++ linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_reg.h	2009-08-03 14:01:07.000000000 -0400
@@ -55,7 +55,7 @@
 /* PCI config space */
 
 #define HPLLCC	0xc0 /* 855 only */
-#define   GC_CLOCK_CONTROL_MASK		(3 << 0)
+#define   GC_CLOCK_CONTROL_MASK		(0xf << 0)
 #define   GC_CLOCK_133_200		(0 << 0)
 #define   GC_CLOCK_100_200		(1 << 0)
 #define   GC_CLOCK_100_133		(2 << 0)
@@ -65,6 +65,25 @@
 #define   GC_DISPLAY_CLOCK_190_200_MHZ	(0 << 4)
 #define   GC_DISPLAY_CLOCK_333_MHZ	(4 << 4)
 #define   GC_DISPLAY_CLOCK_MASK		(7 << 4)
+#define   GM45_GC_RENDER_CLOCK_MASK	(0xf << 0)
+#define   GM45_GC_RENDER_CLOCK_266_MHZ	(8 << 0)
+#define   GM45_GC_RENDER_CLOCK_320_MHZ	(9 << 0)
+#define   GM45_GC_RENDER_CLOCK_400_MHZ	(0xb << 0)
+#define   GM45_GC_RENDER_CLOCK_533_MHZ	(0xc << 0)
+#define   I965_GC_RENDER_CLOCK_MASK	(0xf << 0)
+#define   I965_GC_RENDER_CLOCK_267_MHZ	(2 << 0)
+#define   I965_GC_RENDER_CLOCK_333_MHZ	(3 << 0)
+#define   I965_GC_RENDER_CLOCK_444_MHZ	(4 << 0)
+#define   I965_GC_RENDER_CLOCK_533_MHZ	(5 << 0)
+#define   I945_GC_RENDER_CLOCK_MASK	(7 << 0)
+#define   I945_GC_RENDER_CLOCK_166_MHZ	(0 << 0)
+#define   I945_GC_RENDER_CLOCK_200_MHZ	(1 << 0)
+#define   I945_GC_RENDER_CLOCK_250_MHZ	(3 << 0)
+#define   I945_GC_RENDER_CLOCK_400_MHZ	(5 << 0)
+#define   I915_GC_RENDER_CLOCK_MASK	(7 << 0)
+#define   I915_GC_RENDER_CLOCK_166_MHZ	(0 << 0)
+#define   I915_GC_RENDER_CLOCK_200_MHZ	(1 << 0)
+#define   I915_GC_RENDER_CLOCK_333_MHZ	(4 << 0)
 #define LBB	0xf4
 
 /* VGA stuff */
@@ -1586,6 +1605,7 @@
 #define   PIPECONF_PROGRESSIVE	(0 << 21)
 #define   PIPECONF_INTERLACE_W_FIELD_INDICATION	(6 << 21)
 #define   PIPECONF_INTERLACE_FIELD_0_ONLY		(7 << 21)
+#define   PIPECONF_CXSR_DOWNCLOCK	(1<<16)
 #define PIPEASTAT		0x70024
 #define   PIPE_FIFO_UNDERRUN_STATUS		(1UL<<31)
 #define   PIPE_CRC_ERROR_ENABLE			(1UL<<29)
diff -up linux-2.6.30.noarch/drivers/gpu/drm/i915/intel_display.c.jx linux-2.6.30.noarch/drivers/gpu/drm/i915/intel_display.c
--- linux-2.6.30.noarch/drivers/gpu/drm/i915/intel_display.c.jx	2009-08-03 14:00:44.000000000 -0400
+++ linux-2.6.30.noarch/drivers/gpu/drm/i915/intel_display.c	2009-08-03 14:11:56.000000000 -0400
@@ -38,6 +38,7 @@
 
 bool intel_pipe_has_type (struct drm_crtc *crtc, int type);
 static void intel_update_watermarks(struct drm_device *dev);
+static void intel_increase_pllclock(struct drm_crtc *crtc, int schedule);
 
 typedef struct {
     /* given values */
@@ -67,6 +68,8 @@ struct intel_limit {
     intel_p2_t	    p2;
     bool (* find_pll)(const intel_limit_t *, struct drm_crtc *,
 		      int, int, intel_clock_t *);
+    bool (* find_reduced_pll)(const intel_limit_t *, struct drm_crtc *,
+			      int, int, intel_clock_t *);
 };
 
 #define I8XX_DOT_MIN		  25000
@@ -192,7 +195,7 @@ struct intel_limit {
 #define G4X_P2_SINGLE_CHANNEL_LVDS_LIMIT          0
 
 /*The parameter is for DUAL_CHANNEL_LVDS on G4x platform*/
-#define G4X_DOT_DUAL_CHANNEL_LVDS_MIN           80000
+#define G4X_DOT_DUAL_CHANNEL_LVDS_MIN           10000
 #define G4X_DOT_DUAL_CHANNEL_LVDS_MAX           224000
 #define G4X_N_DUAL_CHANNEL_LVDS_MIN             1
 #define G4X_N_DUAL_CHANNEL_LVDS_MAX             3
@@ -261,6 +264,9 @@ static bool
 intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 		    int target, int refclk, intel_clock_t *best_clock);
 static bool
+intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
+			    int target, int refclk, intel_clock_t *best_clock);
+static bool
 intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 			int target, int refclk, intel_clock_t *best_clock);
 static bool
@@ -286,6 +292,7 @@ static const intel_limit_t intel_limits_
 	.p2  = { .dot_limit = I8XX_P2_SLOW_LIMIT,
 		 .p2_slow = I8XX_P2_SLOW,	.p2_fast = I8XX_P2_FAST },
 	.find_pll = intel_find_best_PLL,
+	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 
 static const intel_limit_t intel_limits_i8xx_lvds = {
@@ -300,6 +307,7 @@ static const intel_limit_t intel_limits_
 	.p2  = { .dot_limit = I8XX_P2_SLOW_LIMIT,
 		 .p2_slow = I8XX_P2_LVDS_SLOW,	.p2_fast = I8XX_P2_LVDS_FAST },
 	.find_pll = intel_find_best_PLL,
+	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 	
 static const intel_limit_t intel_limits_i9xx_sdvo = {
@@ -314,6 +322,7 @@ static const intel_limit_t intel_limits_
 	.p2  = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
 		 .p2_slow = I9XX_P2_SDVO_DAC_SLOW,	.p2_fast = I9XX_P2_SDVO_DAC_FAST },
 	.find_pll = intel_find_best_PLL,
+	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 
 static const intel_limit_t intel_limits_i9xx_lvds = {
@@ -331,6 +340,7 @@ static const intel_limit_t intel_limits_
 	.p2  = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
 		 .p2_slow = I9XX_P2_LVDS_SLOW,	.p2_fast = I9XX_P2_LVDS_FAST },
 	.find_pll = intel_find_best_PLL,
+	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 
     /* below parameter and function is for G4X Chipset Family*/
@@ -348,6 +358,7 @@ static const intel_limit_t intel_limits_
 		 .p2_fast = G4X_P2_SDVO_FAST
 	},
 	.find_pll = intel_g4x_find_best_PLL,
+	.find_reduced_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_hdmi = {
@@ -364,6 +375,7 @@ static const intel_limit_t intel_limits_
 		 .p2_fast = G4X_P2_HDMI_DAC_FAST
 	},
 	.find_pll = intel_g4x_find_best_PLL,
+	.find_reduced_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_single_channel_lvds = {
@@ -388,6 +400,7 @@ static const intel_limit_t intel_limits_
 		 .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST
 	},
 	.find_pll = intel_g4x_find_best_PLL,
+	.find_reduced_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
@@ -412,6 +425,7 @@ static const intel_limit_t intel_limits_
 		 .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST
 	},
 	.find_pll = intel_g4x_find_best_PLL,
+	.find_reduced_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_display_port = {
@@ -449,6 +463,7 @@ static const intel_limit_t intel_limits_
 	.p2  = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
 		 .p2_slow = I9XX_P2_SDVO_DAC_SLOW,	.p2_fast = I9XX_P2_SDVO_DAC_FAST },
 	.find_pll = intel_find_best_PLL,
+	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 
 static const intel_limit_t intel_limits_igd_lvds = {
@@ -464,6 +479,7 @@ static const intel_limit_t intel_limits_
 	.p2  = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
 		 .p2_slow = I9XX_P2_LVDS_SLOW,	.p2_fast = I9XX_P2_LVDS_SLOW },
 	.find_pll = intel_find_best_PLL,
+	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 
 static const intel_limit_t intel_limits_igdng_sdvo = {
@@ -688,15 +704,16 @@ intel_find_best_PLL(const intel_limit_t 
 
 	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 <= limit->m2.max; clock.m2++) {
-			/* m1 is always 0 in IGD */
-			if (clock.m2 >= clock.m1 && !IS_IGD(dev))
-				break;
-			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++) {
+	for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
+		for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
+		     clock.m1++) {
+			for (clock.m2 = limit->m2.min;
+			     clock.m2 <= limit->m2.max; clock.m2++) {
+				/* m1 is always 0 in IGD */
+				if (clock.m2 >= clock.m1 && !IS_IGD(dev))
+					break;
+				for (clock.n = limit->n.min;
+				     clock.n <= limit->n.max; clock.n++) {
 					int this_err;
 
 					intel_clock(dev, refclk, &clock);
@@ -717,6 +734,46 @@ intel_find_best_PLL(const intel_limit_t 
 	return (err != target);
 }
 
+
+static bool
+intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
+			    int target, int refclk, intel_clock_t *best_clock)
+
+{
+	struct drm_device *dev = crtc->dev;
+	intel_clock_t clock;
+	int err = target;
+	bool found = false;
+
+	memcpy(&clock, best_clock, sizeof(intel_clock_t));
+
+	for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
+		for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) {
+			/* m1 is always 0 in IGD */
+			if (clock.m2 >= clock.m1 && !IS_IGD(dev))
+				break;
+			for (clock.n = limit->n.min; clock.n <= limit->n.max;
+			     clock.n++) {
+				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;
+					found = true;
+				}
+			}
+		}
+	}
+
+	return found;
+}
+
 static bool
 intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 			int target, int refclk, intel_clock_t *best_clock)
@@ -747,7 +804,7 @@ intel_g4x_find_best_PLL(const intel_limi
 	max_n = limit->n.max;
 	/* based on hardware requriment prefer smaller n to precision */
 	for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
-		/* based on hardware requirment prefere larger m1,m2, p1 */
+		/* based on hardware requirment prefere larger m1,m2, */
 		for (clock.m1 = limit->m1.max;
 		     clock.m1 >= limit->m1.min; clock.m1--) {
 			for (clock.m2 = limit->m2.max;
@@ -757,8 +814,8 @@ intel_g4x_find_best_PLL(const intel_limi
 					int this_err;
 
 					intel_clock(dev, refclk, &clock);
-					if (!intel_PLL_is_valid(crtc, &clock))
-						continue;
+//					if (!intel_PLL_is_valid(crtc, &clock))
+//						continue;
 					this_err = abs(clock.dot - target) ;
 					if (this_err < err_most) {
 						*best_clock = clock;
@@ -832,15 +889,14 @@ intel_igdng_find_best_PLL(const intel_li
 
 	memset(best_clock, 0, sizeof(*best_clock));
 	max_n = limit->n.max;
-	/* based on hardware requriment prefer smaller n to precision */
-	for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
-		/* based on hardware requirment prefere larger m1,m2, p1 */
-		for (clock.m1 = limit->m1.max;
-		     clock.m1 >= limit->m1.min; clock.m1--) {
-			for (clock.m2 = limit->m2.max;
-			     clock.m2 >= limit->m2.min; clock.m2--) {
-				for (clock.p1 = limit->p1.max;
-				     clock.p1 >= limit->p1.min; clock.p1--) {
+	for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
+		/* based on hardware requriment prefer smaller n to precision */
+		for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
+			/* based on hardware requirment prefere larger m1,m2 */
+			for (clock.m1 = limit->m1.max;
+			     clock.m1 >= limit->m1.min; clock.m1--) {
+				for (clock.m2 = limit->m2.max;
+				     clock.m2 >= limit->m2.min; clock.m2--) {
 					int this_err;
 
 					intel_clock(dev, refclk, &clock);
@@ -1029,6 +1085,7 @@ intel_pipe_set_base(struct drm_crtc *crt
 		intel_wait_for_vblank(dev);
 		i915_gem_object_unpin(intel_fb->obj);
 	}
+	intel_increase_pllclock(crtc, true);
 
 	if (!dev->primary->master)
 		return 0;
@@ -2036,6 +2093,18 @@ static int intel_get_fifo_size(struct dr
 	return size;
 }
 
+static void g4x_update_wm(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 fw_blc_self = I915_READ(FW_BLC_SELF);
+
+	if (i915_powersave)
+		fw_blc_self |= FW_BLC_SELF_EN;
+	else
+		fw_blc_self &= ~FW_BLC_SELF_EN;
+	I915_WRITE(FW_BLC_SELF, fw_blc_self);
+}
+
 static void i965_update_wm(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2087,7 +2156,7 @@ static void i9xx_update_wm(struct drm_de
 	cwm = 2;
 
 	/* Calc sr entries for one plane configs */
-	if (sr_hdisplay && (!planea_clock || !planeb_clock)) {
+	if (HAS_FW_BLC(dev) && sr_hdisplay && (!planea_clock || !planeb_clock)) {
 		/* self-refresh has much higher latency */
 		const static int sr_latency_ns = 6000;
 
@@ -2102,8 +2171,7 @@ static void i9xx_update_wm(struct drm_de
 		srwm = total_size - sr_entries;
 		if (srwm < 0)
 			srwm = 1;
-		if (IS_I9XX(dev))
-			I915_WRITE(FW_BLC_SELF, (srwm & 0x3f));
+		I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f));
 	}
 
 	DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n",
@@ -2177,9 +2245,6 @@ static void intel_update_watermarks(stru
 	unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0;
 	int enabled = 0, pixel_size = 0;
 
-	if (DSPARB_HWCONTROL(dev))
-		return;
-
 	/* Get the clock config from both planes */
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		intel_crtc = to_intel_crtc(crtc);
@@ -2212,7 +2277,9 @@ static void intel_update_watermarks(stru
 	else if (IS_IGD(dev))
 		igd_disable_cxsr(dev);
 
-	if (IS_I965G(dev))
+	if (IS_G4X(dev))
+		g4x_update_wm(dev);
+	else if (IS_I965G(dev))
 		i965_update_wm(dev);
 	else if (IS_I9XX(dev) || IS_MOBILE(dev))
 		i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay,
@@ -2246,9 +2313,9 @@ static int intel_crtc_mode_set(struct dr
 	int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
 	int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
 	int refclk, num_outputs = 0;
-	intel_clock_t clock;
-	u32 dpll = 0, fp = 0, dspcntr, pipeconf;
-	bool ok, is_sdvo = false, is_dvo = false;
+	intel_clock_t clock, reduced_clock;
+	u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf;
+	bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false;
 	bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
 	bool is_edp = false;
 	struct drm_mode_config *mode_config = &dev->mode_config;
@@ -2331,6 +2398,14 @@ static int intel_crtc_mode_set(struct dr
 		return -EINVAL;
 	}
 
+	if (limit->find_reduced_pll && is_lvds) {
+		memcpy(&reduced_clock, &clock, sizeof(intel_clock_t));
+		has_reduced_clock = limit->find_reduced_pll(limit, crtc,
+							    (adjusted_mode->clock*i915_lvdsscale/100),
+							    refclk,
+							    &reduced_clock);
+	}
+
 	/* SDVO TV has fixed PLL values depend on its clock range,
 	   this mirrors vbios setting. */
 	if (is_sdvo && is_tv) {
@@ -2376,10 +2451,17 @@ static int intel_crtc_mode_set(struct dr
 				  link_bw, &m_n);
 	}
 
-	if (IS_IGD(dev))
+	if (IS_IGD(dev)) {
 		fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
-	else
+		if (has_reduced_clock)
+			fp2 = (1 << reduced_clock.n) << 16 |
+				reduced_clock.m1 << 8 | reduced_clock.m2;
+	} else {
 		fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
+		if (has_reduced_clock)
+			fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
+				reduced_clock.m2;
+	}
 
 	if (!IS_IGDNG(dev))
 		dpll = DPLL_VGA_MODE_DIS;
@@ -2408,6 +2490,8 @@ static int intel_crtc_mode_set(struct dr
 			/* also FPA1 */
 			if (IS_IGDNG(dev))
 				dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
+			if (IS_G4X(dev) && has_reduced_clock)
+				dpll |= (1 << (reduced_clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
 		}
 		switch (clock.p2) {
 		case 5:
@@ -2534,9 +2618,25 @@ static int intel_crtc_mode_set(struct dr
 	}
 	if (is_dp)
 		intel_dp_set_m_n(crtc, mode, adjusted_mode);
+	
 
 	if (!is_edp) {
 		I915_WRITE(fp_reg, fp);
+		if (has_reduced_clock && i915_powersave && i915_lvdsclock) {
+			I915_WRITE(fp_reg + 4, fp2);
+			intel_crtc->lowfreq_avail = true;
+			if (HAS_PIPE_CXSR(dev)) {
+				DRM_DEBUG("enabling CxSR downclocking\n");
+				pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
+			}
+		} else {
+			I915_WRITE(fp_reg + 4, fp);
+			intel_crtc->lowfreq_avail = false;
+			if (HAS_PIPE_CXSR(dev)) {
+				DRM_DEBUG("disabling CxSR downclocking\n");
+				pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK;
+			}
+		}
 		I915_WRITE(dpll_reg, dpll);
 		I915_READ(dpll_reg);
 		/* Wait for the clocks to stabilize. */
@@ -2748,6 +2848,8 @@ fail_locked:
 	return ret;
 }
 
+#define CRTC_IDLE_TIMEOUT 1000 /* ms */
+
 static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
 {
 	struct drm_device *dev = crtc->dev;
@@ -2757,6 +2859,12 @@ static int intel_crtc_cursor_move(struct
 	uint32_t temp = 0;
 	uint32_t adder;
 
+	if (!intel_crtc->busy)
+		intel_increase_pllclock(crtc, true);
+	intel_crtc->busy = true;
+	mod_timer(&intel_crtc->idle_timer, jiffies +
+		  msecs_to_jiffies(CRTC_IDLE_TIMEOUT));
+
 	if (x < 0) {
 		temp |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
 		x = -x;
@@ -3054,6 +3162,286 @@ struct drm_display_mode *intel_crtc_mode
 	return mode;
 }
 
+#define GPU_IDLE_TIMEOUT 500 /* ms */
+
+/* When this timer fires, we've been idle for awhile */
+static void intel_gpu_idle_timer(unsigned long arg)
+{
+	struct drm_device *dev = (struct drm_device *)arg;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+
+	DRM_DEBUG("idle timer fired, downclocking\n");
+
+	dev_priv->busy = false;
+
+	schedule_work(&dev_priv->idle_work);
+}
+
+void intel_increase_renderclock(struct drm_device *dev, int schedule)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+
+	if (!i915_renderclock)
+		return;
+
+	if (IS_G4X(dev) || IS_I9XX(dev)) {
+		/* Up to maximum... */
+		pci_write_config_word(dev->pdev, GCFGC, dev_priv->orig_clock);
+	} else if (IS_I85X(dev)) {
+		pci_write_config_word(dev->pdev, HPLLCC, dev_priv->orig_clock);
+	}
+	DRM_DEBUG("increasing render clock frequency\n");
+
+	if (!schedule)
+		return;
+
+	/* Schedule downclock */
+	mod_timer(&dev_priv->idle_timer, jiffies +
+		  msecs_to_jiffies(GPU_IDLE_TIMEOUT));
+}
+
+void intel_decrease_renderclock(struct drm_device *dev)
+{
+	if (!i915_renderclock)
+		return;
+
+	if (IS_G4X(dev)) {
+		u16 gcfgc;
+
+		/* Adjust render clock... */
+		pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
+
+		/* Down to minimum... */
+		gcfgc &= ~GM45_GC_RENDER_CLOCK_MASK;
+		gcfgc |= GM45_GC_RENDER_CLOCK_266_MHZ;
+
+		pci_write_config_word(dev->pdev, GCFGC, gcfgc);
+	} else if (IS_I965G(dev)) {
+		u16 gcfgc;
+
+		/* Adjust render clock... */
+		pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
+
+		/* Down to minimum... */
+		gcfgc &= ~I965_GC_RENDER_CLOCK_MASK;
+		gcfgc |= I965_GC_RENDER_CLOCK_267_MHZ;
+
+		pci_write_config_word(dev->pdev, GCFGC, gcfgc);
+	} else if (IS_I945G(dev) || IS_I945GM(dev)) {
+		u16 gcfgc;
+
+		/* Adjust render clock... */
+		pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
+
+		/* Down to minimum... */
+		gcfgc &= ~I945_GC_RENDER_CLOCK_MASK;
+		gcfgc |= I945_GC_RENDER_CLOCK_166_MHZ;
+
+		pci_write_config_word(dev->pdev, GCFGC, gcfgc);
+	} else if (IS_I915G(dev) || IS_I915GM(dev)) {
+		u16 gcfgc;
+
+		/* Adjust render clock... */
+		pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
+
+		/* Down to minimum... */
+		gcfgc &= ~I915_GC_RENDER_CLOCK_MASK;
+		gcfgc |= I915_GC_RENDER_CLOCK_166_MHZ;
+
+		pci_write_config_word(dev->pdev, GCFGC, gcfgc);
+	} else if (IS_I85X(dev)) {
+		u16 hpllcc;
+
+		/* Adjust render clock... */
+		pci_read_config_word(dev->pdev, HPLLCC, &hpllcc);
+
+		/* Up to maximum... */
+		hpllcc &= ~GC_CLOCK_CONTROL_MASK;
+		hpllcc |= GC_CLOCK_133_200;
+
+		pci_write_config_word(dev->pdev, HPLLCC, hpllcc);
+	}
+	DRM_DEBUG("decreasing render clock frequency\n");
+}
+
+/* Note that no increase function is needed for this - increase_renderclock()
+ *  will also rewrite these bits
+ */
+void intel_decrease_displayclock(struct drm_device *dev)
+{
+	if (!i915_displayclock)
+		return;
+
+	if (IS_I945G(dev) || IS_I945GM(dev) || IS_I915G(dev) ||
+	    IS_I915GM(dev)) {
+		u16 gcfgc;
+
+		/* Adjust render clock... */
+		pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
+
+		/* Down to minimum... */
+		gcfgc &= ~0xf0;
+		gcfgc |= 0x80;
+
+		pci_write_config_word(dev->pdev, GCFGC, gcfgc);
+	}
+}
+
+static void intel_crtc_idle_timer(unsigned long arg)
+{
+	struct intel_crtc *intel_crtc = (struct intel_crtc *)arg;
+	struct drm_crtc *crtc = &intel_crtc->base;
+	drm_i915_private_t *dev_priv = crtc->dev->dev_private;
+
+	DRM_DEBUG("idle timer fired, downclocking\n");
+
+	intel_crtc->busy = false;
+
+	schedule_work(&dev_priv->idle_work);
+}
+
+static void intel_increase_pllclock(struct drm_crtc *crtc, int schedule)
+{
+	struct drm_device *dev = crtc->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
+	int dpll = I915_READ(dpll_reg);
+
+	if (!i915_lvdsclock)
+		return;
+
+	if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) {
+		DRM_DEBUG("upclocking LVDS\n");
+
+		I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16));
+		I915_WRITE(dpll_reg, dpll & ~DISPLAY_RATE_SELECT_FPA1);
+		dpll = I915_READ(dpll_reg);
+		intel_wait_for_vblank(dev);
+		dpll = I915_READ(dpll_reg);
+		if (dpll & DISPLAY_RATE_SELECT_FPA1)
+			DRM_DEBUG("failed to upclock LVDS!\n");
+		I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3);
+	}
+
+	if (!schedule)
+		return;
+
+	/* Schedule downclock */
+	mod_timer(&intel_crtc->idle_timer, jiffies +
+		  msecs_to_jiffies(CRTC_IDLE_TIMEOUT));
+}
+
+static void intel_decrease_pllclock(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
+	int dpll = I915_READ(dpll_reg);
+
+	if (!i915_lvdsclock)
+		return;
+
+	/*
+	 * Since this is called by a timer, we should never get here in
+	 * the manual case.
+	 */
+	if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) {
+		DRM_DEBUG("downclocking LVDS\n");
+		I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16));
+
+		dpll |= DISPLAY_RATE_SELECT_FPA1;
+		I915_WRITE(dpll_reg, dpll);
+		dpll = I915_READ(dpll_reg);
+		intel_wait_for_vblank(dev);
+		dpll = I915_READ(dpll_reg);
+		if (!(dpll & DISPLAY_RATE_SELECT_FPA1))
+			DRM_DEBUG("failed to downclock LVDS!\n");
+		I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3);
+	}
+
+}
+
+/**
+ * intel_idle_update - adjust clocks for idleness
+ * @work: work struct
+ *
+ * Either the GPU or display (or both) went idle.  Check the busy status
+ * here and adjust the CRTC and GPU clocks as necessary.
+ */
+static void intel_idle_update(struct work_struct *work)
+{
+	drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
+						    idle_work);
+	struct drm_device *dev = dev_priv->dev;
+	struct drm_crtc *crtc;
+	struct intel_crtc *intel_crtc;
+
+	if (!i915_powersave)
+		return;
+
+	mutex_lock(&dev->struct_mutex);
+
+	/* GPU isn't processing, downclock it. */
+	if (!dev_priv->busy) {
+		intel_decrease_renderclock(dev);
+		intel_decrease_displayclock(dev);
+	}
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		/* Skip inactive CRTCs */
+		if (!crtc->fb)
+			continue;
+
+		intel_crtc = to_intel_crtc(crtc);
+		if (!intel_crtc->busy)
+			intel_decrease_pllclock(crtc);
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+}
+
+/**
+ * intel_mark_busy - mark the GPU and possibly the display busy
+ * @dev: drm device
+ * @obj: object we're operating on
+ *
+ * Callers can use this function to indicate that the GPU is busy processing
+ * commands.  If @obj matches one of the CRTC objects (i.e. it's a scanout
+ * buffer), we'll also mark the display as busy, so we know to increase its
+ * clock frequency.
+ */
+void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc = NULL;
+	struct intel_framebuffer *intel_fb;
+	struct intel_crtc *intel_crtc;
+
+	dev_priv->busy = true;
+	intel_increase_renderclock(dev, true);
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		if (!crtc->fb)
+			continue;
+
+		intel_crtc = to_intel_crtc(crtc);
+		intel_fb = to_intel_framebuffer(crtc->fb);
+		if (intel_fb->obj == obj) {
+			if (!intel_crtc->busy)
+				intel_increase_pllclock(crtc, true);
+			intel_crtc->busy = true;
+			mod_timer(&intel_crtc->idle_timer, jiffies +
+				  msecs_to_jiffies(CRTC_IDLE_TIMEOUT));
+		}
+	}
+
+
+}
+
 static void intel_crtc_destroy(struct drm_crtc *crtc)
 {
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -3110,6 +3498,10 @@ static void intel_crtc_init(struct drm_d
 	intel_crtc->mode_set.crtc = &intel_crtc->base;
 	intel_crtc->mode_set.connectors = (struct drm_connector **)(intel_crtc + 1);
 	intel_crtc->mode_set.num_connectors = 0;
+	intel_crtc->busy = false;
+
+	setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer,
+		    (unsigned long)intel_crtc);
 
 	if (i915_fbpercrtc) {
 
@@ -3399,6 +3791,7 @@ static const struct drm_mode_config_func
 
 void intel_modeset_init(struct drm_device *dev)
 {
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	int num_pipe;
 	int i;
 
@@ -3433,15 +3826,38 @@ void intel_modeset_init(struct drm_devic
 	DRM_DEBUG("%d display pipe%s available.\n",
 		  num_pipe, num_pipe > 1 ? "s" : "");
 
+	if (IS_I85X(dev))
+		pci_read_config_word(dev->pdev, HPLLCC, &dev_priv->orig_clock);
+	else if (IS_I9XX(dev) || IS_G4X(dev))
+		pci_read_config_word(dev->pdev, GCFGC, &dev_priv->orig_clock);
+
 	for (i = 0; i < num_pipe; i++) {
 		intel_crtc_init(dev, i);
 	}
 
 	intel_setup_outputs(dev);
+
+	INIT_WORK(&dev_priv->idle_work, intel_idle_update);
+	setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer,
+		    (unsigned long)dev);
 }
 
 void intel_modeset_cleanup(struct drm_device *dev)
 {
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* Clean up up/down clocking */
+	if (!HAS_PIPE_CXSR(dev)) {
+		u32 dpll_b = I915_READ(DPLL_B);
+
+		del_timer_sync(&dev_priv->idle_timer);
+		dpll_b &= ~DISPLAY_RATE_SELECT_FPA1;
+		I915_WRITE(DPLL_B, dpll_b);
+		POSTING_READ(DPLL_B);
+		intel_wait_for_vblank(dev);
+	}
+
+	intel_increase_renderclock(dev, false);
 	drm_mode_config_cleanup(dev);
 }
 
diff -up linux-2.6.30.noarch/drivers/gpu/drm/i915/intel_drv.h.jx linux-2.6.30.noarch/drivers/gpu/drm/i915/intel_drv.h
--- linux-2.6.30.noarch/drivers/gpu/drm/i915/intel_drv.h.jx	2009-08-03 14:00:44.000000000 -0400
+++ linux-2.6.30.noarch/drivers/gpu/drm/i915/intel_drv.h	2009-08-03 14:01:07.000000000 -0400
@@ -99,6 +99,9 @@ struct intel_crtc {
 	struct intel_framebuffer *fbdev_fb;
 	/* a mode_set for fbdev users on this crtc */
 	struct drm_mode_set mode_set;
+	bool busy; /* is scanout buffer being updated frequently? */
+	struct timer_list idle_timer;
+	bool lowfreq_avail;
 };
 
 #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
@@ -117,6 +120,7 @@ extern void intel_hdmi_init(struct drm_d
 extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
 extern void intel_dvo_init(struct drm_device *dev);
 extern void intel_tv_init(struct drm_device *dev);
+extern void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj);
 extern void intel_lvds_init(struct drm_device *dev);
 extern void intel_dp_init(struct drm_device *dev, int dp_reg);
 void

drm-page-flip.patch:
 b/drivers/gpu/drm/drm_crtc.c                          |  169 +++++++++++++++++-
 b/drivers/gpu/drm/drm_crtc_helper.c                   |   12 +
 b/drivers/gpu/drm/drm_drv.c                           |    1 
 b/drivers/gpu/drm/drm_fops.c                          |   68 +++++++
 b/drivers/gpu/drm/drm_irq.c                           |   43 ++++
 b/drivers/gpu/drm/i915/i915_drv.c                     |    1 
 b/drivers/gpu/drm/i915/intel_display.c                |   24 +-
 b/drivers/gpu/drm/radeon/atombios_crtc.c              |    1 
 b/drivers/gpu/drm/radeon/radeon_display.c             |    3 
 b/include/drm/drm.h                                   |   25 ++
 b/include/drm/drmP.h                                  |   32 +++
 b/include/drm/drm_crtc.h                              |   27 ++
 b/include/drm/drm_crtc_helper.h                       |    4 
 b/include/drm/drm_mode.h                              |   17 +
 linux-2.6.30.i686/drivers/gpu/drm/nouveau/nv04_crtc.c |    2 
 linux-2.6.30.i686/drivers/gpu/drm/nouveau/nv50_crtc.c |    2 
 16 files changed, 415 insertions(+), 16 deletions(-)

--- NEW FILE drm-page-flip.patch ---
>From 2c6289cd75e125745e38dc563fa33301d05923a0 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Kristian=20H=C3=B8gsberg?= <krh at hinata.local>
Date: Mon, 13 Jul 2009 09:07:19 -0400
Subject: [PATCH] Add modesetting pageflip ioctl and corresponding drm event
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

This patch adds a vblank synced pageflip ioctl for to the modesetting
family of ioctls.  The ioctl takes a crtc and an fb and schedules a
pageflip to the new fb at the next coming vertical blank event.  This
feature lets userspace implement tear-free updating of the screen contents
with hw-guaranteed low latency page flipping.

The ioctl is asynchronous in that it returns immediately and then later
notifies the client by making an event available for reading on the drm fd.
This lets applications add the drm fd to their main loop and handle other
tasks while waiting for the flip to happen.  The event includes the time
of the flip, the frame counter and a 64 bit opaque token provided by
user space in the ioctl.

Based on work and suggestions from
	Jesse Barnes <jbarnes at virtuousgeek.org>,
	Jakob Bornecrantz <wallbraker at gmail.com>,
	Chris Wilson <chris at chris-wilson.co.uk>

Signed-off-by: Kristian Høgsberg <krh at redhat.com>
Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>
---
 drivers/gpu/drm/drm_crtc.c              |  169 ++++++++++++++++++++++++++++++-
 drivers/gpu/drm/drm_crtc_helper.c       |   12 ++
 drivers/gpu/drm/drm_drv.c               |    1 +
 drivers/gpu/drm/drm_fops.c              |   68 ++++++++++++-
 drivers/gpu/drm/drm_irq.c               |   43 ++++++++
 drivers/gpu/drm/i915/i915_drv.c         |    1 +
 drivers/gpu/drm/i915/intel_display.c    |   24 +++--
 drivers/gpu/drm/radeon/atombios_crtc.c  |    1 -
 drivers/gpu/drm/radeon/radeon_display.c |    3 +-
 include/drm/drm.h                       |   25 +++++
 include/drm/drmP.h                      |   32 ++++++
 include/drm/drm_crtc.h                  |   27 +++++
 include/drm/drm_crtc_helper.h           |    4 +
 include/drm/drm_mode.h                  |   16 +++
 14 files changed, 413 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 8fab789..32212e6 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -34,6 +34,8 @@
 #include "drmP.h"
 #include "drm_crtc.h"
 
+#undef set_base
+
 struct drm_prop_enum_list {
 	int type;
 	char *name;
@@ -342,6 +344,34 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
 EXPORT_SYMBOL(drm_framebuffer_cleanup);
 
 /**
+ * drm_crtc_async_flip - do a set_base call from a work queue
+ * @work: work struct
+ *
+ * Called when a set_base call is queued by the page flip code.  This
+ * allows the flip ioctl itself to return immediately and allow userspace
+ * to continue working.
+ */
+static void drm_crtc_async_flip(struct work_struct *work)
+{
+	struct drm_crtc *crtc = container_of(work, struct drm_crtc, async_flip);
+	struct drm_device *dev = crtc->dev;
+	struct drm_pending_flip *pending;
+
+	BUG_ON(crtc->pending_flip == NULL);
+
+	mutex_lock(&dev->struct_mutex);
+	crtc->funcs->set_base(crtc, 0, 0, NULL);
+
+	pending = crtc->pending_flip;
+	crtc->pending_flip = NULL;
+
+	pending->frame = drm_vblank_count(dev, crtc->pipe);
+	list_add_tail(&pending->link, &dev->flip_list);
+
+	mutex_unlock(&dev->struct_mutex);
+}
+
+/**
  * drm_crtc_init - Initialise a new CRTC object
  * @dev: DRM device
  * @crtc: CRTC object to init
@@ -352,17 +382,19 @@ EXPORT_SYMBOL(drm_framebuffer_cleanup);
  *
  * Inits a new object created as base part of an driver crtc object.
  */
-void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
+void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, int pipe,
 		   const struct drm_crtc_funcs *funcs)
 {
 	crtc->dev = dev;
 	crtc->funcs = funcs;
+	crtc->pipe = pipe;
 
 	mutex_lock(&dev->mode_config.mutex);
 	drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
 
 	list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
 	dev->mode_config.num_crtc++;
+	INIT_WORK(&crtc->async_flip, drm_crtc_async_flip);
 	mutex_unlock(&dev->mode_config.mutex);
 }
 EXPORT_SYMBOL(drm_crtc_init);
@@ -381,6 +413,9 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
 
+	mutex_lock(&dev->mode_config.mutex);
+	flush_work(&crtc->async_flip);
+
 	if (crtc->gamma_store) {
 		kfree(crtc->gamma_store);
 		crtc->gamma_store = NULL;
@@ -388,6 +423,7 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)
 
 	drm_mode_object_put(dev, &crtc->base);
 	list_del(&crtc->head);
+	mutex_unlock(&dev->mode_config.mutex);
 	dev->mode_config.num_crtc--;
 }
 EXPORT_SYMBOL(drm_crtc_cleanup);
@@ -2452,3 +2488,134 @@ out:
 	mutex_unlock(&dev->mode_config.mutex);
 	return ret;
 }
+
+/**
+ * drm_mode_page_flip_ioctl - page flip ioctl
+ * @dev: DRM device
+ * @data: ioctl args
+ * @file_priv: file private data
+ *
+ * The page flip ioctl replaces the current front buffer with a new
+ * one, using the CRTC's set_base function, which should just update
+ * the front buffer base pointer.  It's up to set_base to make
+ * sure the update doesn't result in tearing (on some hardware the
+ * base register is double buffered, so this is easy).
+ *
+ * Note that this covers just the simple case of flipping the front
+ * buffer immediately.  Interval handling and interlaced modes have to
+ * be handled by userspace, or with new ioctls.
+ */
+int drm_mode_page_flip_ioctl(struct drm_device *dev, void *data,
+			     struct drm_file *file_priv)
+{
+	struct drm_pending_flip *pending;
+	struct drm_mode_page_flip *flip_data = data;
+	struct drm_mode_object *drm_obj, *fb_obj;
+	struct drm_crtc *crtc;
+	int ret = 0;
+
+	if (!(drm_core_check_feature(dev, DRIVER_MODESET)))
+		return -ENODEV;
+
+	/*
+	 * Reject unknown flags so future userspace knows what we (don't)
+	 * support
+	 */
+	if (flip_data->flags & (~DRM_MODE_PAGE_FLIP_FLAGS_MASK)) {
+		DRM_DEBUG("bad page flip flags\n");
+		return -EINVAL;
+	}
+
+	pending = kzalloc(sizeof *pending, GFP_KERNEL);
+	if (pending == NULL)
+		return -ENOMEM;
+
+	mutex_lock(&dev->struct_mutex);
+
+	fb_obj = drm_mode_object_find(dev, flip_data->fb_id,
+				      DRM_MODE_OBJECT_FB);
+	if (!fb_obj) {
+		DRM_DEBUG("unknown fb %d\n", flip_data->fb_id);
+		ret = -ENOENT;
+		goto out_unlock;
+	}
+
+	drm_obj = drm_mode_object_find(dev, flip_data->crtc_id,
+				       DRM_MODE_OBJECT_CRTC);
+	if (!drm_obj) {
+		DRM_DEBUG("unknown crtc %d\n", flip_data->crtc_id);
+		ret = -ENOENT;
+		goto out_unlock;
+	}
+	crtc = obj_to_crtc(drm_obj);
+	if (!crtc->enabled) {
+		DRM_DEBUG("crtc %d not enabled\n", flip_data->crtc_id);
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	if (crtc->fb->funcs->unpin == NULL) {
+		DRM_DEBUG("fb for crtc %d does not support delayed unpin\n",
+			  flip_data->crtc_id);
+		ret = -ENODEV;
+		goto out_unlock;
+	}
+
+	pending->crtc = crtc;
+	pending->old_fb = crtc->fb;
+	pending->pipe = crtc->pipe;
+	pending->event.base.type = DRM_EVENT_MODE_PAGE_FLIP;
+	pending->event.base.length = sizeof pending->event;
+	pending->event.user_data = flip_data->user_data;
+	pending->pending_event.event = &pending->event.base;
+	pending->pending_event.file_priv = file_priv;
+	pending->pending_event.destroy =
+		(void (*) (struct drm_pending_event *)) kfree;
+
+	/* Get vblank ref for completion handling */
+	ret = drm_vblank_get(dev, crtc->pipe);
+	if (ret) {
+		DRM_DEBUG("failed to take vblank ref\n");
+		goto out_unlock;
+	}
+
+	/*
+	 * The set_base call will change the domain on the new fb,
+	 * which will force the rendering to finish and block the
+	 * ioctl.  We need to do this last part from a work queue, to
+	 * avoid blocking userspace here.
+	 */
+	crtc->fb = obj_to_fb(fb_obj);
+
+	if (crtc->pending_flip != NULL) {
+	    struct drm_pending_flip *old_flip;
+
+	    /* We have an outstanding flip request for this crtc/pipe.
+	     * In order to satisfy the user we can either queue the requests
+	     * and apply them on sequential vblanks, or we can drop old
+	     * requests.
+	     *
+	     * Here we choose to discard the previous request for
+	     * simplicity. Note that since we have not yet applied the
+	     * previous flip, we need to preserve the original (i.e. still
+	     * current) fb.
+	     */
+
+	    old_flip = crtc->pending_flip;
+	    pending->old_fb = old_flip->old_fb;
+	    old_flip->old_fb = NULL;
+	    drm_finish_pending_flip (dev, old_flip, 0);
+	} else
+	    schedule_work(&crtc->async_flip);
+	crtc->pending_flip = pending;
+
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+
+out_unlock:
+	mutex_unlock(&dev->struct_mutex);
+	kfree(pending);
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 3da9cfa..5a26bab 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -868,8 +868,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 		old_fb = set->crtc->fb;
 		if (set->crtc->fb != set->fb)
 			set->crtc->fb = set->fb;
+		mutex_lock(&dev->struct_mutex);
 		ret = crtc_funcs->mode_set_base(set->crtc,
 						set->x, set->y, old_fb);
+		mutex_unlock(&dev->struct_mutex);
 		if (ret != 0)
 		    goto fail_set_mode;
 	}
@@ -1095,3 +1097,13 @@ int drm_helper_resume_force_mode(struct drm_device *dev)
 	return 0;
 }
 EXPORT_SYMBOL(drm_helper_resume_force_mode);
+
+int
+drm_crtc_helper_set_base(struct drm_crtc *crtc, int x, int y,
+			 struct drm_framebuffer *old_fb)
+{
+	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+
+	return crtc_funcs->mode_set_base(crtc, x, y, old_fb);
+}
+EXPORT_SYMBOL(drm_crtc_helper_set_base);
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index b39d7bf..c66c993 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -145,6 +145,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
 };
 
 #define DRM_CORE_IOCTL_COUNT	ARRAY_SIZE( drm_ioctls )
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 251bc0e..dcd9c66 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -257,6 +257,8 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
 
 	INIT_LIST_HEAD(&priv->lhead);
 	INIT_LIST_HEAD(&priv->fbs);
+	INIT_LIST_HEAD(&priv->event_list);
+	init_waitqueue_head(&priv->event_wait);
 
 	if (dev->driver->driver_features & DRIVER_GEM)
 		drm_gem_open(dev, priv);
@@ -429,6 +431,9 @@ int drm_release(struct inode *inode, struct file *filp)
 {
 	struct drm_file *file_priv = filp->private_data;
 	struct drm_device *dev = file_priv->minor->dev;
+	struct drm_pending_flip *f, *ft;
+	struct drm_pending_event *e, *et;
+
 	int retcode = 0;
 
 	lock_kernel();
@@ -451,6 +456,19 @@ int drm_release(struct inode *inode, struct file *filp)
 	if (file_priv->minor->master)
 		drm_master_release(dev, filp);
 
+	mutex_lock(&dev->struct_mutex);
+
+	/* Remove pending flips */
+	list_for_each_entry_safe(f, ft, &dev->flip_list, link)
+		if (f->pending_event.file_priv == file_priv)
+			drm_finish_pending_flip(dev, f, 0);
+
+	/* Remove unconsumed events */
+	list_for_each_entry_safe(e, et, &file_priv->event_list, link)
+		e->destroy(e);
+
+	mutex_unlock(&dev->struct_mutex);
+
 	if (dev->driver->driver_features & DRIVER_GEM)
 		drm_gem_release(dev, file_priv);
 
@@ -544,9 +562,55 @@ int drm_release(struct inode *inode, struct file *filp)
 }
 EXPORT_SYMBOL(drm_release);
 
-/** No-op. */
+ssize_t drm_read(struct file *filp, char __user *buffer,
+		 size_t count, loff_t *offset)
+{
+	struct drm_file *file_priv = filp->private_data;
+	struct drm_device *dev = file_priv->minor->dev;
+	struct drm_pending_event *event;
+	ssize_t total, ret;
+
+	ret = wait_event_interruptible(file_priv->event_wait,
+				       !list_empty(&file_priv->event_list));
+	if (ret < 0)
+		return ret;
+
+	total = 0;
+	while (!list_empty(&file_priv->event_list)) {
+		mutex_lock(&dev->struct_mutex);
+		event = list_first_entry(&file_priv->event_list,
+					 struct drm_pending_event, link);
+		if (total + event->event->length > count) {
+			mutex_unlock(&dev->struct_mutex);
+			break;
+		}
+		list_del(&event->link);
+		mutex_unlock(&dev->struct_mutex);
+
+		if (copy_to_user(buffer + total,
+				 event->event, event->event->length)) {
+			total = -EFAULT;
+			break;
+		}
+
+		total += event->event->length;
+		event->destroy(event);
+	}
+
+	return total;
+}
+EXPORT_SYMBOL(drm_read);
+
 unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait)
 {
-	return 0;
+	struct drm_file *file_priv = filp->private_data;
+	unsigned int mask = 0;
+
+	poll_wait(filp, &file_priv->event_wait, wait);
+
+	if (!list_empty(&file_priv->event_list))
+		mask |= POLLIN | POLLRDNORM;
+
+	return mask;
 }
 EXPORT_SYMBOL(drm_poll);
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index b4a3dbc..c7a17f6 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -34,6 +34,7 @@
  */
 
 #include "drmP.h"
+#include "drm_crtc_helper.h"
 
 #include <linux/interrupt.h>	/* For task queue support */
 
@@ -71,6 +72,44 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
 	return 0;
 }
 
+#define vblank_passed(a,b) ((long)(a - b) > 0)
+
+void drm_finish_pending_flip(struct drm_device *dev,
+			     struct drm_pending_flip *f, u32 frame)
+{
+	struct timeval now;
+
+	f->event.frame = frame;
+	do_gettimeofday(&now);
+	f->event.tv_sec = now.tv_sec;
+	f->event.tv_usec = now.tv_usec;	
+	drm_vblank_put(dev, f->pipe);
+	list_del_init(&f->link);
+	list_add_tail(&f->pending_event.link,
+		      &f->pending_event.file_priv->event_list);
+	if (f->old_fb)
+	    f->old_fb->funcs->unpin(f->old_fb);
+	wake_up_interruptible(&f->pending_event.file_priv->event_wait);
+}
+
+static void drm_flip_work_func(struct work_struct *work)
+{
+	struct drm_device *dev =
+		container_of(work, struct drm_device, flip_work);
+	struct drm_pending_flip *f, *t;
+	u32 frame;
+
+	mutex_lock(&dev->struct_mutex);
+
+	list_for_each_entry_safe(f, t, &dev->flip_list, link) {
+		frame = drm_vblank_count(dev, f->pipe);
+		if (vblank_passed(frame, f->frame))
+			drm_finish_pending_flip(dev, f, frame);
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+}
+
 static void vblank_disable_fn(unsigned long arg)
 {
 	struct drm_device *dev = (struct drm_device *)arg;
@@ -161,6 +200,8 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
 		atomic_set(&dev->vblank_refcount[i], 0);
 	}
 
+	INIT_LIST_HEAD(&dev->flip_list);
+	INIT_WORK(&dev->flip_work, drm_flip_work_func);
 	dev->vblank_disable_allowed = 0;
 
 	return 0;
@@ -626,5 +667,7 @@ void drm_handle_vblank(struct drm_device *dev, int crtc)
 {
 	atomic_inc(&dev->_vblank_count[crtc]);
 	DRM_WAKEUP(&dev->vbl_queue[crtc]);
+	schedule_work(&dev->flip_work);
 }
 EXPORT_SYMBOL(drm_handle_vblank);
+
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index fc4b68a..322b0f2 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -203,6 +203,7 @@ static struct drm_driver driver = {
 		 .mmap = drm_gem_mmap,
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
+		 .read = drm_read,
 #ifdef CONFIG_COMPAT
 		 .compat_ioctl = i915_compat_ioctl,
 #endif
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 508838e..697c31a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -863,6 +863,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 	u32 dspcntr, alignment;
 	int ret;
 
+	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
+
 	/* no fb bound */
 	if (!crtc->fb) {
 		DRM_DEBUG("No FB bound\n");
@@ -898,17 +900,14 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 		BUG();
 	}
 
-	mutex_lock(&dev->struct_mutex);
 	ret = i915_gem_object_pin(obj, alignment);
 	if (ret != 0) {
-		mutex_unlock(&dev->struct_mutex);
 		return ret;
 	}
 
 	ret = i915_gem_object_set_to_gtt_domain(obj, 1);
 	if (ret != 0) {
 		i915_gem_object_unpin(obj);
-		mutex_unlock(&dev->struct_mutex);
 		return ret;
 	}
 
@@ -944,7 +943,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 	default:
 		DRM_ERROR("Unknown color depth\n");
 		i915_gem_object_unpin(obj);
-		mutex_unlock(&dev->struct_mutex);
 		return -EINVAL;
 	}
 	if (IS_I965G(dev)) {
@@ -972,13 +970,11 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 		I915_READ(dspbase);
 	}
 
-	intel_wait_for_vblank(dev);
-
 	if (old_fb) {
 		intel_fb = to_intel_framebuffer(old_fb);
+		intel_wait_for_vblank(dev);
 		i915_gem_object_unpin(intel_fb->obj);
 	}
-	mutex_unlock(&dev->struct_mutex);
 
 	if (!dev->primary->master)
 		return 0;
@@ -2364,7 +2360,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 	I915_WRITE(dspcntr_reg, dspcntr);
 
 	/* Flush the plane changes */
+	mutex_lock(&dev->struct_mutex);
 	ret = intel_pipe_set_base(crtc, x, y, old_fb);
+	mutex_unlock(&dev->struct_mutex);
 
 	intel_update_watermarks(dev);
 
@@ -2840,6 +2838,7 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
 	.gamma_set = intel_crtc_gamma_set,
 	.set_config = drm_crtc_helper_set_config,
 	.destroy = intel_crtc_destroy,
+	.set_base = drm_crtc_helper_set_base,
 };
 
 
@@ -2852,7 +2851,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
 	if (intel_crtc == NULL)
 		return;
 
-	drm_crtc_init(dev, &intel_crtc->base, &intel_crtc_funcs);
+	drm_crtc_init(dev, &intel_crtc->base, pipe, &intel_crtc_funcs);
 
 	drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256);
 	intel_crtc->pipe = pipe;
@@ -3071,9 +3070,18 @@ static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb,
 	return drm_gem_handle_create(file_priv, object, handle);
 }
 
+static void intel_user_framebuffer_unpin(struct drm_framebuffer *fb)
+{
+	struct intel_framebuffer *intel_fb;
+
+	intel_fb = to_intel_framebuffer(fb);
+	i915_gem_object_unpin(intel_fb->obj);
+}
+
 static const struct drm_framebuffer_funcs intel_fb_funcs = {
 	.destroy = intel_user_framebuffer_destroy,
 	.create_handle = intel_user_framebuffer_create_handle,
+	.unpin = intel_user_framebuffer_unpin
 };
 
 int intel_framebuffer_create(struct drm_device *dev,
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index c0080cc..501209d 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -535,7 +535,6 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
 	.dpms = atombios_crtc_dpms,
 	.mode_fixup = atombios_crtc_mode_fixup,
 	.mode_set = atombios_crtc_mode_set,
-	.mode_set_base = atombios_crtc_set_base,
 	.prepare = atombios_crtc_prepare,
 	.commit = atombios_crtc_commit,
 };
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 3efcf1a..372ba35 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -171,6 +171,7 @@ static const struct drm_crtc_funcs radeon_crtc_funcs = {
 	.gamma_set = radeon_crtc_gamma_set,
 	.set_config = drm_crtc_helper_set_config,
 	.destroy = radeon_crtc_destroy,
+	.set_base = radeon_crtc_set_base,
 };
 
 static void radeon_crtc_init(struct drm_device *dev, int index)
@@ -183,7 +184,7 @@ static void radeon_crtc_init(struct drm_device *dev, int index)
 	if (radeon_crtc == NULL)
 		return;
 
-	drm_crtc_init(dev, &radeon_crtc->base, &radeon_crtc_funcs);
+	drm_crtc_init(dev, &radeon_crtc->base, index, &radeon_crtc_funcs);
 
 	drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256);
 	radeon_crtc->crtc_id = index;
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 7cb50bd..1920323 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -686,6 +686,7 @@ struct drm_gem_open {
 #define DRM_IOCTL_MODE_GETFB		DRM_IOWR(0xAD, struct drm_mode_fb_cmd)
 #define DRM_IOCTL_MODE_ADDFB		DRM_IOWR(0xAE, struct drm_mode_fb_cmd)
 #define DRM_IOCTL_MODE_RMFB		DRM_IOWR(0xAF, unsigned int)
+#define DRM_IOCTL_MODE_PAGE_FLIP	DRM_IOW( 0xB0, struct drm_mode_page_flip)
 
 /**
  * Device specific ioctls should only be in their respective headers
@@ -698,6 +699,30 @@ struct drm_gem_open {
 #define DRM_COMMAND_BASE                0x40
 #define DRM_COMMAND_END			0xA0
 
+/**
+ * Header for events written back to userspace on the drm fd.  The
+ * type defines the type of event, the length specifies the total
+ * length of the event (including the header), and user_data is
+ * typically a 64 bit value passed with the ioctl that triggered the
+ * event.  A read on the drm fd will always only return complete
+ * events, that is, if for example the read buffer is 100 bytes, and
+ * there are two 64 byte events pending, only one will be returned.
+ */
+struct drm_event {
+	__u32 type;
+	__u32 length;
+};
+
+#define DRM_EVENT_MODE_PAGE_FLIP 0x01
+
+struct drm_event_page_flip {
+	struct drm_event base;
+	__u64 user_data;
+	__u32 tv_sec;
+	__u32 tv_usec;
+	__u32 frame;
+};
+
 /* typedef area */
 #ifndef __KERNEL__
 typedef struct drm_clip_rect drm_clip_rect_t;
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 45b67d9..4ff43ab 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -402,6 +402,14 @@ struct drm_buf_entry {
 	struct drm_freelist freelist;
 };
 
+/* Event queued up for userspace to read */
+struct drm_pending_event {
+	struct drm_event *event;
+	struct list_head link;
+	struct drm_file *file_priv;
+	void (*destroy) (struct drm_pending_event *event);
+};
+
 /** File private data */
 struct drm_file {
 	int authenticated;
@@ -425,6 +433,9 @@ struct drm_file {
 	struct drm_master *master; /* master this node is currently associated with
 				      N.B. not always minor->master */
 	struct list_head fbs;
+
+	wait_queue_head_t event_wait;
+	struct list_head event_list;
 };
 
 /** Wait queue */
@@ -873,6 +884,16 @@ struct drm_minor {
 	struct drm_mode_group mode_group;
 };
 
+struct drm_pending_flip {
+	struct drm_pending_event pending_event;
+	struct drm_framebuffer *old_fb;
+	struct drm_crtc *crtc;
+	u32 frame;
+	int pipe;
+	struct list_head link;
+	struct drm_event_page_flip event;
+};
+
 /**
  * DRM device structure. This structure represent a complete card that
  * may contain multiple heads.
@@ -972,6 +993,13 @@ struct drm_device {
 
 	u32 max_vblank_count;           /**< size of vblank counter register */
 
+	struct work_struct flip_work;
+
+	/**
+	 * List of objects waiting on flip completion
+	 */
+	struct list_head flip_list;
+
 	/*@} */
 	cycles_t ctx_start;
 	cycles_t lck_start;
@@ -1108,6 +1136,8 @@ extern int drm_lastclose(struct drm_device *dev);
 extern int drm_open(struct inode *inode, struct file *filp);
 extern int drm_stub_open(struct inode *inode, struct file *filp);
 extern int drm_fasync(int fd, struct file *filp, int on);
+extern ssize_t drm_read(struct file *filp, char __user *buffer,
+			size_t count, loff_t *offset);
 extern int drm_release(struct inode *inode, struct file *filp);
 
 				/* Mapping support (drm_vm.h) */
@@ -1274,6 +1304,8 @@ extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc);
 extern void drm_vblank_post_modeset(struct drm_device *dev, int crtc);
 extern int drm_modeset_ctl(struct drm_device *dev, void *data,
 			   struct drm_file *file_priv);
+extern void drm_finish_pending_flip(struct drm_device *dev,
+				   struct drm_pending_flip *f, u32 frame);
 
 				/* AGP/GART support (drm_agpsupport.h) */
 extern struct drm_agp_head *drm_agp_init(struct drm_device *dev);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 7300fb8..0b5dc47 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -238,6 +238,12 @@ struct drm_display_info {
 };
 
 struct drm_framebuffer_funcs {
+	/*
+	 * Unpin the old fb after setting a mode.  Must be called
+	 * after the old framebuffer is no longer visible, ie, after
+	 * the next vblank, typically.
+	 */
+	void (*unpin)(struct drm_framebuffer *fb);
 	void (*destroy)(struct drm_framebuffer *framebuffer);
 	int (*create_handle)(struct drm_framebuffer *fb,
 			     struct drm_file *file_priv,
@@ -288,6 +294,7 @@ struct drm_property {
 struct drm_crtc;
 struct drm_connector;
 struct drm_encoder;
+struct drm_pending_flip;
 
 /**
  * drm_crtc_funcs - control CRTCs for a given device
@@ -331,17 +338,29 @@ struct drm_crtc_funcs {
 	void (*destroy)(struct drm_crtc *crtc);
 
 	int (*set_config)(struct drm_mode_set *set);
+
+	/*
+	 * Move the crtc on the current fb to the given position.
+	 * This function is optional.  If old_fb is provided, the
+	 * function will wait for vblank and unpin it.  If old_fb is
+	 * NULL, nothing is unpinned and the caller must call
+	 * mode_unpin_fb to release the old framebuffer.
+	 */
+	int (*set_base)(struct drm_crtc *crtc, int x, int y,
+			struct drm_framebuffer *old_fb);
 };
 
 /**
  * drm_crtc - central CRTC control structure
  * @enabled: is this CRTC enabled?
+ * @pipe: pipe number (as seen by DRM vblank functions)
  * @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
+ * @async_work: work queue for async set base calls
  *
  * Each CRTC may have one or more connectors associated with it.  This structure
  * allows the CRTC to be controlled.
@@ -359,6 +378,7 @@ struct drm_crtc {
 
 	struct drm_display_mode mode;
 
+	int pipe;
 	int x, y;
 	struct drm_display_mode *desired_mode;
 	int desired_x, desired_y;
@@ -368,6 +388,10 @@ struct drm_crtc {
 	uint32_t gamma_size;
 	uint16_t *gamma_store;
 
+	/* Allow async set_pipe_base calls for flipping */
+	struct work_struct async_flip;
+	struct drm_pending_flip *pending_flip;
+
 	/* if you are using the helper */
 	void *helper_private;
 };
@@ -589,6 +613,7 @@ struct drm_mode_config {
 
 extern void drm_crtc_init(struct drm_device *dev,
 			  struct drm_crtc *crtc,
+			  int pipe,
 			  const struct drm_crtc_funcs *funcs);
 extern void drm_crtc_cleanup(struct drm_crtc *crtc);
 
@@ -736,4 +761,6 @@ extern int drm_mode_gamma_get_ioctl(struct drm_device *dev,
 extern int drm_mode_gamma_set_ioctl(struct drm_device *dev,
 				    void *data, struct drm_file *file_priv);
 extern bool drm_detect_hdmi_monitor(struct edid *edid);
+extern int drm_mode_page_flip_ioctl(struct drm_device *dev, void *data,
+				    struct drm_file *file_priv);
 #endif /* __DRM_CRTC_H__ */
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index 6769ff6..dd10566 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -123,4 +123,8 @@ static inline void drm_connector_helper_add(struct drm_connector *connector,
 }
 
 extern int drm_helper_resume_force_mode(struct drm_device *dev);
+
+extern int drm_crtc_helper_set_base(struct drm_crtc *crtc, int x, int y,
+				    struct drm_framebuffer *old_fb);
+
 #endif
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index ae304cc..464b779 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -265,4 +265,20 @@ struct drm_mode_crtc_lut {
 	__u64 blue;
 };
 
+#define DRM_MODE_PAGE_FLIP_WAIT		(1<<0) /* block on previous page flip */
+#define DRM_MODE_PAGE_FLIP_FLAGS_MASK	(DRM_MODE_PAGE_FLIP_WAIT)
+
+struct drm_mode_page_flip {
+	/** Handle of new front buffer */
+	__u32 fb_id;
+	__u32 crtc_id;
+
+	/* 64 bit cookie returned to userspace in the page flip event. */
+	__u64 user_data;
+	/**
+	 * page flip flags (wait on flip only for now)
+	 */
+	__u32 flags;
+};
+
 #endif
-- 
1.6.3.3

diff -up linux-2.6.30.i686/drivers/gpu/drm/nouveau/nv04_crtc.c~ linux-2.6.30.i686/drivers/gpu/drm/nouveau/nv04_crtc.c
--- linux-2.6.30.i686/drivers/gpu/drm/nouveau/nv04_crtc.c~	2009-07-24 19:38:36.000000000 -0400
+++ linux-2.6.30.i686/drivers/gpu/drm/nouveau/nv04_crtc.c	2009-07-26 18:06:06.000000000 -0400
@@ -1014,7 +1014,7 @@ nv04_crtc_create(struct drm_device *dev,
 	nv_crtc->mode_set.connectors = (struct drm_connector **)(nv_crtc + 1);
 	nv_crtc->mode_set.num_connectors = 0;
 
-	drm_crtc_init(dev, &nv_crtc->base, &nv04_crtc_funcs);
+	drm_crtc_init(dev, &nv_crtc->base, crtc_num, &nv04_crtc_funcs);
 	drm_crtc_helper_add(&nv_crtc->base, &nv04_crtc_helper_funcs);
 	drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256);
 
diff -up linux-2.6.30.i686/drivers/gpu/drm/nouveau/nv50_crtc.c~ linux-2.6.30.i686/drivers/gpu/drm/nouveau/nv50_crtc.c
--- linux-2.6.30.i686/drivers/gpu/drm/nouveau/nv50_crtc.c~	2009-07-24 19:38:36.000000000 -0400
+++ linux-2.6.30.i686/drivers/gpu/drm/nouveau/nv50_crtc.c	2009-07-26 18:06:23.000000000 -0400
@@ -796,7 +796,7 @@ nv50_crtc_create(struct drm_device *dev,
 	crtc->mode_set.connectors = (struct drm_connector **)(crtc + 1);
 	crtc->mode_set.num_connectors = 0;
 
-	drm_crtc_init(dev, &crtc->base, &nv50_crtc_funcs);
+	drm_crtc_init(dev, &crtc->base, index, &nv50_crtc_funcs);
 	drm_crtc_helper_add(&crtc->base, &nv50_crtc_helper_funcs);
 	drm_mode_crtc_set_gamma_size(&crtc->base, 256);
 

drm-r600-kms.patch:
 b/drivers/gpu/drm/radeon/Makefile        |    2 
 b/drivers/gpu/drm/radeon/atombios_crtc.c |    1 
 b/drivers/gpu/drm/radeon/avivod.h        |   60 +
 b/drivers/gpu/drm/radeon/r100.c          |   69 +
 b/drivers/gpu/drm/radeon/r300.c          |    2 
 b/drivers/gpu/drm/radeon/r600.c          | 1243 +++++++++++++++++++++++++++++--
 b/drivers/gpu/drm/radeon/r600d.h         |  349 ++++++++
 b/drivers/gpu/drm/radeon/radeon.h        |   51 +
 b/drivers/gpu/drm/radeon/radeon_asic.h   |  137 +++
 b/drivers/gpu/drm/radeon/radeon_clocks.c |   10 
 b/drivers/gpu/drm/radeon/radeon_device.c |  338 ++++----
 b/drivers/gpu/drm/radeon/radeon_drv.h    |    1 
 b/drivers/gpu/drm/radeon/radeon_ring.c   |   63 -
 b/drivers/gpu/drm/radeon/radeon_share.h  |   66 +
 b/drivers/gpu/drm/radeon/radeon_ttm.c    |    6 
 b/drivers/gpu/drm/radeon/rs400.c         |    2 
 b/drivers/gpu/drm/radeon/rv770.c         |  980 ++++++++++++++++++++++--
 b/drivers/gpu/drm/radeon/rv770d.h        |  341 ++++++++
 drivers/gpu/drm/radeon/r300.h            |   36 
 drivers/gpu/drm/radeon/rs780.c           |  102 --
 20 files changed, 3364 insertions(+), 495 deletions(-)

--- NEW FILE drm-r600-kms.patch ---
>From 6599b4a047d80cd7b8715b5ad74e0735e6d4b941 Mon Sep 17 00:00:00 2001
From: Jerome Glisse <jglisse at redhat.com>
Date: Fri, 24 Jul 2009 19:42:23 +0200
Subject: [PATCH] radeon: add basic KMS support for r6xx & r7xx chipset.

This only provide a kms drm fb device for this hw and allow X
to run with no acceleration.
---
 drivers/gpu/drm/radeon/Makefile        |    2 +-
 drivers/gpu/drm/radeon/atombios_crtc.c |    1 +
 drivers/gpu/drm/radeon/avivod.h        |   60 ++
 drivers/gpu/drm/radeon/r100.c          |   69 ++
 drivers/gpu/drm/radeon/r300.c          |    2 +-
 drivers/gpu/drm/radeon/r300.h          |   36 -
 drivers/gpu/drm/radeon/r600.c          | 1243 ++++++++++++++++++++++++++++++--
 drivers/gpu/drm/radeon/r600d.h         |  349 +++++++++
 drivers/gpu/drm/radeon/radeon.h        |   51 ++-
 drivers/gpu/drm/radeon/radeon_asic.h   |  137 ++++-
 drivers/gpu/drm/radeon/radeon_clocks.c |   10 +-
 drivers/gpu/drm/radeon/radeon_device.c |  338 +++++----
 drivers/gpu/drm/radeon/radeon_drv.h    |    1 +
 drivers/gpu/drm/radeon/radeon_ring.c   |   63 +--
 drivers/gpu/drm/radeon/radeon_share.h  |   66 ++
 drivers/gpu/drm/radeon/radeon_ttm.c    |    6 +-
 drivers/gpu/drm/radeon/rs400.c         |    2 +-
 drivers/gpu/drm/radeon/rs780.c         |  102 ---
 drivers/gpu/drm/radeon/rv770.c         |  980 +++++++++++++++++++++++--
 drivers/gpu/drm/radeon/rv770d.h        |  340 +++++++++
 20 files changed, 3364 insertions(+), 494 deletions(-)
 create mode 100644 drivers/gpu/drm/radeon/avivod.h
 delete mode 100644 drivers/gpu/drm/radeon/r300.h
 create mode 100644 drivers/gpu/drm/radeon/r600d.h
 delete mode 100644 drivers/gpu/drm/radeon/rs780.c
 create mode 100644 drivers/gpu/drm/radeon/rv770d.h

diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index 013d380..7384cad 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -13,7 +13,7 @@ radeon-$(CONFIG_DRM_RADEON_KMS) += radeon_device.o radeon_kms.o \
 	radeon_encoders.o radeon_display.o radeon_cursor.o radeon_i2c.o \
 	radeon_clocks.o radeon_fb.o radeon_gem.o radeon_ring.o radeon_irq_kms.o \
 	radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \
-	rs400.o rs600.o rs690.o rv515.o r520.o r600.o rs780.o rv770.o \
+	rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o \
 	radeon_test.o
 
 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 74d034f..629d7c8 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -370,6 +370,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
 					pll_flags |= RADEON_PLL_USE_REF_DIV;
 			}
 			radeon_encoder = to_radeon_encoder(encoder);
+			break;
 		}
 	}
 
diff --git a/drivers/gpu/drm/radeon/avivod.h b/drivers/gpu/drm/radeon/avivod.h
new file mode 100644
index 0000000..d4e6e6e
--- /dev/null
+++ b/drivers/gpu/drm/radeon/avivod.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2009 Advanced Micro Devices, Inc.
+ * Copyright 2009 Red Hat Inc.
+ *
+ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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: Dave Airlie
+ *          Alex Deucher
+ *          Jerome Glisse
+ */
+#ifndef AVIVOD_H
+#define AVIVOD_H
+
+
+#define	D1CRTC_CONTROL					0x6080
+#define		CRTC_EN						(1 << 0)
+#define	D1CRTC_UPDATE_LOCK				0x60E8
+#define	D1GRPH_PRIMARY_SURFACE_ADDRESS			0x6110
+#define	D1GRPH_SECONDARY_SURFACE_ADDRESS		0x6118
+
+#define	D2CRTC_CONTROL					0x6880
+#define	D2CRTC_UPDATE_LOCK				0x68E8
+#define	D2GRPH_PRIMARY_SURFACE_ADDRESS			0x6910
+#define	D2GRPH_SECONDARY_SURFACE_ADDRESS		0x6918
+
+#define	D1VGA_CONTROL					0x0330
+#define		DVGA_CONTROL_MODE_ENABLE			(1 << 0)
+#define		DVGA_CONTROL_TIMING_SELECT			(1 << 8)
+#define		DVGA_CONTROL_SYNC_POLARITY_SELECT		(1 << 9)
+#define		DVGA_CONTROL_OVERSCAN_TIMING_SELECT		(1 << 10)
+#define		DVGA_CONTROL_OVERSCAN_COLOR_EN			(1 << 16)
+#define		DVGA_CONTROL_ROTATE				(1 << 24)
+#define D2VGA_CONTROL					0x0338
+
+#define	VGA_HDP_CONTROL					0x328
+#define		VGA_MEM_PAGE_SELECT_EN				(1 << 0)
+#define		VGA_MEMORY_DISABLE				(1 << 4)
+#define		VGA_RBBM_LOCK_DISABLE				(1 << 8)
+#define		VGA_SOFT_RESET					(1 << 16)
+#define	VGA_MEMORY_BASE_ADDRESS				0x0310
+#define	VGA_RENDER_CONTROL				0x0300
+#define		VGA_VSTATUS_CNTL_MASK				0x00030000
+
+#endif
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index f1ba8ff..59ef4f9 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -644,6 +644,12 @@ int r100_cp_reset(struct radeon_device *rdev)
 	return -1;
 }
 
+void r100_cp_commit(struct radeon_device *rdev)
+{
+	WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr);
+	(void)RREG32(RADEON_CP_RB_WPTR);
+}
+
 
 /*
  * CS functions
@@ -2278,3 +2284,66 @@ void r100_bandwidth_update(struct radeon_device *rdev)
 			  (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL));
 	}
 }
+
+void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
+{
+	radeon_ring_write(rdev, PACKET0(RADEON_CP_IB_BASE, 1));
+	radeon_ring_write(rdev, ib->gpu_addr);
+	radeon_ring_write(rdev, ib->length_dw);
+}
+
+int r100_ib_test(struct radeon_device *rdev)
+{
+	struct radeon_ib *ib;
+	uint32_t scratch;
+	uint32_t tmp = 0;
+	unsigned i;
+	int r;
+
+	r = radeon_scratch_get(rdev, &scratch);
+	if (r) {
+		DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r);
+		return r;
+	}
+	WREG32(scratch, 0xCAFEDEAD);
+	r = radeon_ib_get(rdev, &ib);
+	if (r) {
+		return r;
+	}
+	ib->ptr[0] = PACKET0(scratch, 0);
+	ib->ptr[1] = 0xDEADBEEF;
+	ib->ptr[2] = PACKET2(0);
+	ib->ptr[3] = PACKET2(0);
+	ib->ptr[4] = PACKET2(0);
+	ib->ptr[5] = PACKET2(0);
+	ib->ptr[6] = PACKET2(0);
+	ib->ptr[7] = PACKET2(0);
+	ib->length_dw = 8;
+	r = radeon_ib_schedule(rdev, ib);
+	if (r) {
+		radeon_scratch_free(rdev, scratch);
+		radeon_ib_free(rdev, &ib);
+		return r;
+	}
+	r = radeon_fence_wait(ib->fence, false);
+	if (r) {
+		return r;
+	}
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		tmp = RREG32(scratch);
+		if (tmp == 0xDEADBEEF) {
+			break;
+		}
+		DRM_UDELAY(1);
+	}
[...4102 lines suppressed...]
+#define	MC_VM_AGP_TOP					0x2028
+#define	MC_VM_AGP_BOT					0x202C
+#define	MC_VM_AGP_BASE					0x2030
+#define	MC_VM_FB_LOCATION				0x2024
+#define	MC_VM_MB_L1_TLB0_CNTL				0x2234
+#define	MC_VM_MB_L1_TLB1_CNTL				0x2238
+#define	MC_VM_MB_L1_TLB2_CNTL				0x223C
+#define	MC_VM_MB_L1_TLB3_CNTL				0x2240
+#define		ENABLE_L1_TLB					(1 << 0)
+#define		ENABLE_L1_FRAGMENT_PROCESSING			(1 << 1)
+#define		SYSTEM_ACCESS_MODE_PA_ONLY			(0 << 3)
+#define		SYSTEM_ACCESS_MODE_USE_SYS_MAP			(1 << 3)
+#define		SYSTEM_ACCESS_MODE_IN_SYS			(2 << 3)
+#define		SYSTEM_ACCESS_MODE_NOT_IN_SYS			(3 << 3)
+#define		SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU	(0 << 5)
+#define		EFFECTIVE_L1_TLB_SIZE(x)			((x)<<15)
+#define		EFFECTIVE_L1_QUEUE_SIZE(x)			((x)<<18)
+#define	MC_VM_MD_L1_TLB0_CNTL				0x2654
+#define	MC_VM_MD_L1_TLB1_CNTL				0x2658
+#define	MC_VM_MD_L1_TLB2_CNTL				0x265C
+#define	MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR		0x203C
+#define	MC_VM_SYSTEM_APERTURE_HIGH_ADDR			0x2038
+#define	MC_VM_SYSTEM_APERTURE_LOW_ADDR			0x2034
+
+#define	PA_CL_ENHANCE					0x8A14
+#define		CLIP_VTX_REORDER_ENA				(1 << 0)
+#define		NUM_CLIP_SEQ(x)					((x) << 1)
+#define PA_SC_AA_CONFIG					0x28C04
+#define PA_SC_CLIPRECT_RULE				0x2820C
+#define	PA_SC_EDGERULE					0x28230
+#define	PA_SC_FIFO_SIZE					0x8BCC
+#define		SC_PRIM_FIFO_SIZE(x)				((x) << 0)
+#define		SC_HIZ_TILE_FIFO_SIZE(x)			((x) << 12)
+#define	PA_SC_FORCE_EOV_MAX_CNTS			0x8B24
+#define		FORCE_EOV_MAX_CLK_CNT(x)			((x)<<0)
+#define		FORCE_EOV_MAX_REZ_CNT(x)			((x)<<16)
+#define PA_SC_LINE_STIPPLE				0x28A0C
+#define	PA_SC_LINE_STIPPLE_STATE			0x8B10
+#define PA_SC_MODE_CNTL					0x28A4C
+#define	PA_SC_MULTI_CHIP_CNTL				0x8B20
+#define		SC_EARLYZ_TILE_FIFO_SIZE(x)			((x) << 20)
+
+#define	SCRATCH_REG0					0x8500
+#define	SCRATCH_REG1					0x8504
+#define	SCRATCH_REG2					0x8508
+#define	SCRATCH_REG3					0x850C
+#define	SCRATCH_REG4					0x8510
+#define	SCRATCH_REG5					0x8514
+#define	SCRATCH_REG6					0x8518
+#define	SCRATCH_REG7					0x851C
+#define	SCRATCH_UMSK					0x8540
+#define	SCRATCH_ADDR					0x8544
+
+#define	SMX_DC_CTL0					0xA020
+#define		USE_HASH_FUNCTION				(1 << 0)
+#define		CACHE_DEPTH(x)					((x) << 1)
+#define		FLUSH_ALL_ON_EVENT				(1 << 10)
+#define		STALL_ON_EVENT					(1 << 11)
+#define	SMX_EVENT_CTL					0xA02C
+#define		ES_FLUSH_CTL(x)					((x) << 0)
+#define		GS_FLUSH_CTL(x)					((x) << 3)
+#define		ACK_FLUSH_CTL(x)				((x) << 6)
+#define		SYNC_FLUSH_CTL					(1 << 8)
+
+#define	SPI_CONFIG_CNTL					0x9100
+#define		GPR_WRITE_PRIORITY(x)				((x) << 0)
+#define		DISABLE_INTERP_1				(1 << 5)
+#define	SPI_CONFIG_CNTL_1				0x913C
+#define		VTX_DONE_DELAY(x)				((x) << 0)
+#define		INTERP_ONE_PRIM_PER_ROW				(1 << 4)
+#define	SPI_INPUT_Z					0x286D8
+#define	SPI_PS_IN_CONTROL_0				0x286CC
+#define		NUM_INTERP(x)					((x)<<0)
+#define		POSITION_ENA					(1<<8)
+#define		POSITION_CENTROID				(1<<9)
+#define		POSITION_ADDR(x)				((x)<<10)
+#define		PARAM_GEN(x)					((x)<<15)
+#define		PARAM_GEN_ADDR(x)				((x)<<19)
+#define		BARYC_SAMPLE_CNTL(x)				((x)<<26)
+#define		PERSP_GRADIENT_ENA				(1<<28)
+#define		LINEAR_GRADIENT_ENA				(1<<29)
+#define		POSITION_SAMPLE					(1<<30)
+#define		BARYC_AT_SAMPLE_ENA				(1<<31)
+
+#define	SQ_CONFIG					0x8C00
+#define		VC_ENABLE					(1 << 0)
+#define		EXPORT_SRC_C					(1 << 1)
+#define		DX9_CONSTS					(1 << 2)
+#define		ALU_INST_PREFER_VECTOR				(1 << 3)
+#define		DX10_CLAMP					(1 << 4)
+#define		CLAUSE_SEQ_PRIO(x)				((x) << 8)
+#define		PS_PRIO(x)					((x) << 24)
+#define		VS_PRIO(x)					((x) << 26)
+#define		GS_PRIO(x)					((x) << 28)
+#define	SQ_DYN_GPR_SIZE_SIMD_AB_0			0x8DB0
+#define		SIMDA_RING0(x)					((x)<<0)
+#define		SIMDA_RING1(x)					((x)<<8)
+#define		SIMDB_RING0(x)					((x)<<16)
+#define		SIMDB_RING1(x)					((x)<<24)
+#define	SQ_DYN_GPR_SIZE_SIMD_AB_1			0x8DB4
+#define	SQ_DYN_GPR_SIZE_SIMD_AB_2			0x8DB8
+#define	SQ_DYN_GPR_SIZE_SIMD_AB_3			0x8DBC
+#define	SQ_DYN_GPR_SIZE_SIMD_AB_4			0x8DC0
+#define	SQ_DYN_GPR_SIZE_SIMD_AB_5			0x8DC4
+#define	SQ_DYN_GPR_SIZE_SIMD_AB_6			0x8DC8
+#define	SQ_DYN_GPR_SIZE_SIMD_AB_7			0x8DCC
+#define		ES_PRIO(x)					((x) << 30)
+#define	SQ_GPR_RESOURCE_MGMT_1				0x8C04
+#define		NUM_PS_GPRS(x)					((x) << 0)
+#define		NUM_VS_GPRS(x)					((x) << 16)
+#define		DYN_GPR_ENABLE					(1 << 27)
+#define		NUM_CLAUSE_TEMP_GPRS(x)				((x) << 28)
+#define	SQ_GPR_RESOURCE_MGMT_2				0x8C08
+#define		NUM_GS_GPRS(x)					((x) << 0)
+#define		NUM_ES_GPRS(x)					((x) << 16)
+#define	SQ_MS_FIFO_SIZES				0x8CF0
+#define		CACHE_FIFO_SIZE(x)				((x) << 0)
+#define		FETCH_FIFO_HIWATER(x)				((x) << 8)
+#define		DONE_FIFO_HIWATER(x)				((x) << 16)
+#define		ALU_UPDATE_FIFO_HIWATER(x)			((x) << 24)
+#define	SQ_STACK_RESOURCE_MGMT_1			0x8C10
+#define		NUM_PS_STACK_ENTRIES(x)				((x) << 0)
+#define		NUM_VS_STACK_ENTRIES(x)				((x) << 16)
+#define	SQ_STACK_RESOURCE_MGMT_2			0x8C14
+#define		NUM_GS_STACK_ENTRIES(x)				((x) << 0)
+#define		NUM_ES_STACK_ENTRIES(x)				((x) << 16)
+#define	SQ_THREAD_RESOURCE_MGMT				0x8C0C
+#define		NUM_PS_THREADS(x)				((x) << 0)
+#define		NUM_VS_THREADS(x)				((x) << 8)
+#define		NUM_GS_THREADS(x)				((x) << 16)
+#define		NUM_ES_THREADS(x)				((x) << 24)
+
+#define	SX_DEBUG_1					0x9058
+#define		ENABLE_NEW_SMX_ADDRESS				(1 << 16)
+#define	SX_EXPORT_BUFFER_SIZES				0x900C
+#define		COLOR_BUFFER_SIZE(x)				((x) << 0)
+#define		POSITION_BUFFER_SIZE(x)				((x) << 8)
+#define		SMX_BUFFER_SIZE(x)				((x) << 16)
+#define	SX_MISC						0x28350
+
+#define	TA_CNTL_AUX					0x9508
+#define		DISABLE_CUBE_WRAP				(1 << 0)
+#define		DISABLE_CUBE_ANISO				(1 << 1)
+#define		SYNC_GRADIENT					(1 << 24)
+#define		SYNC_WALKER					(1 << 25)
+#define		SYNC_ALIGNER					(1 << 26)
+#define		BILINEAR_PRECISION_6_BIT			(0 << 31)
+#define		BILINEAR_PRECISION_8_BIT			(1 << 31)
+
+#define	TCP_CNTL					0x9610
+
+#define	VGT_CACHE_INVALIDATION				0x88C4
+#define		CACHE_INVALIDATION(x)				((x)<<0)
+#define			VC_ONLY						0
+#define			TC_ONLY						1
+#define			VC_AND_TC					2
+#define		AUTO_INVLD_EN(x)				((x) << 6)
+#define			NO_AUTO						0
+#define			ES_AUTO						1
+#define			GS_AUTO						2
+#define			ES_AND_GS_AUTO					3
+#define	VGT_ES_PER_GS					0x88CC
+#define	VGT_GS_PER_ES					0x88C8
+#define	VGT_GS_PER_VS					0x88E8
+#define	VGT_GS_VERTEX_REUSE				0x88D4
+#define	VGT_NUM_INSTANCES				0x8974
+#define	VGT_OUT_DEALLOC_CNTL				0x28C5C
+#define		DEALLOC_DIST_MASK				0x0000007F
+#define	VGT_STRMOUT_EN					0x28AB0
+#define	VGT_VERTEX_REUSE_BLOCK_CNTL			0x28C58
+#define		VTX_REUSE_DEPTH_MASK				0x000000FF
+
+#define VM_CONTEXT0_CNTL				0x1410
+#define		ENABLE_CONTEXT					(1 << 0)
+#define		PAGE_TABLE_DEPTH(x)				(((x) & 3) << 1)
+#define		RANGE_PROTECTION_FAULT_ENABLE_DEFAULT		(1 << 4)
+#define	VM_CONTEXT0_PAGE_TABLE_BASE_ADDR		0x153C
+#define	VM_CONTEXT0_PAGE_TABLE_END_ADDR			0x157C
+#define	VM_CONTEXT0_PAGE_TABLE_START_ADDR		0x155C
+#define VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR	0x1518
+#define VM_L2_CNTL					0x1400
+#define		ENABLE_L2_CACHE					(1 << 0)
+#define		ENABLE_L2_FRAGMENT_PROCESSING			(1 << 1)
+#define		ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE		(1 << 9)
+#define		EFFECTIVE_L2_QUEUE_SIZE(x)			(((x) & 7) << 14)
+#define VM_L2_CNTL2					0x1404
+#define		INVALIDATE_ALL_L1_TLBS				(1 << 0)
+#define		INVALIDATE_L2_CACHE				(1 << 1)
+#define VM_L2_CNTL3					0x1408
+#define		BANK_SELECT(x)					((x) << 0)
+#define		CACHE_UPDATE_MODE(x)				((x) << 6)
+#define	VM_L2_STATUS					0x140C
+#define		L2_BUSY						(1 << 0)
+
+#define	WAIT_UNTIL					0x8040
+
+#endif
-- 
1.6.2.5


drm-vga-arb.patch:
 drivers/gpu/drm/drm_irq.c              |   27 +++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_dma.c        |   20 ++++++++++++++++++++
 drivers/gpu/drm/i915/i915_drv.h        |    1 +
 drivers/gpu/drm/i915/i915_reg.h        |    1 +
 drivers/gpu/drm/i915/intel_display.c   |   23 +++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h       |    1 +
 drivers/gpu/drm/radeon/r100.c          |   14 ++++++++++++++
 drivers/gpu/drm/radeon/radeon.h        |    2 ++
 drivers/gpu/drm/radeon/radeon_asic.h   |    9 +++++++++
 drivers/gpu/drm/radeon/radeon_device.c |   19 +++++++++++++++++++
 include/drm/drmP.h                     |    3 +++
 11 files changed, 120 insertions(+)

--- NEW FILE drm-vga-arb.patch ---
diff -up linux-2.6.30.noarch/drivers/gpu/drm/drm_irq.c.arb linux-2.6.30.noarch/drivers/gpu/drm/drm_irq.c
--- linux-2.6.30.noarch/drivers/gpu/drm/drm_irq.c.arb	2009-08-05 10:14:24.000000000 +1000
+++ linux-2.6.30.noarch/drivers/gpu/drm/drm_irq.c	2009-08-05 10:15:15.000000000 +1000
@@ -38,6 +38,7 @@
 
 #include <linux/interrupt.h>	/* For task queue support */
 
+#include <linux/vgaarb.h>
 /**
  * Get interrupt from bus id.
  *
@@ -212,6 +213,26 @@ err:
 }
 EXPORT_SYMBOL(drm_vblank_init);
 
+static void drm_irq_vgaarb_nokms(void *cookie, bool state)
+{
+	struct drm_device *dev = cookie;
+
+	if (dev->driver->vgaarb_irq) {
+		dev->driver->vgaarb_irq(dev, state);
+		return;
+	}
+
+	if (!dev->irq_enabled)
+		return;
+
+	if (state)
+		dev->driver->irq_uninstall(dev);
+	else {
+		dev->driver->irq_preinstall(dev);
+		dev->driver->irq_postinstall(dev);
+	}
+}
+
 /**
  * Install IRQ handler.
  *
@@ -272,6 +293,9 @@ int drm_irq_install(struct drm_device *d
 		return ret;
 	}
 
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		vga_client_register(dev->pdev, (void *)dev, drm_irq_vgaarb_nokms, NULL);
+
 	/* After installing handler */
 	ret = dev->driver->irq_postinstall(dev);
 	if (ret < 0) {
@@ -320,6 +344,9 @@ int drm_irq_uninstall(struct drm_device 
 
 	DRM_DEBUG("irq=%d\n", dev->pdev->irq);
 
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		vga_client_register(dev->pdev, NULL, NULL, NULL);
+
 	dev->driver->irq_uninstall(dev);
 
 	free_irq(dev->pdev->irq, dev);
diff -up linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_dma.c.arb linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_dma.c
--- linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_dma.c.arb	2009-08-05 07:03:48.000000000 +1000
+++ linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_dma.c	2009-08-05 10:15:15.000000000 +1000
@@ -33,6 +33,7 @@
 #include "i915_drm.h"
 #include "i915_drv.h"
 
+#include <linux/vgaarb.h>
 #define I915_DRV	"i915_drv"
 
 /* Really want an OS-independent resettable timer.  Would like to have
@@ -984,6 +985,19 @@ static int i915_probe_agp(struct drm_dev
 	return 0;
 }
 
+/* true = enable decode, false = disable decoder */
+static unsigned int i915_vga_set_decode(void *cookie, bool state)
+{
+	struct drm_device *dev = cookie;
+
+	intel_modeset_vga_set_state(dev, state);
+	if (state)
+		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
+		       VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+	else
+		return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+}
+
 static int i915_load_modeset_init(struct drm_device *dev,
 				  unsigned long prealloc_size,
 				  unsigned long agp_size)
@@ -1029,6 +1043,11 @@ static int i915_load_modeset_init(struct
 	if (ret)
 		DRM_INFO("failed to find VBIOS tables\n");
 
+	/* if we have > 1 VGA cards, then disable the radeon VGA resources */
+	ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode);
+	if (ret)
+		goto destroy_ringbuffer;
+
 	ret = drm_irq_install(dev);
 	if (ret)
 		goto destroy_ringbuffer;
@@ -1278,6 +1297,7 @@ int i915_driver_unload(struct drm_device
 
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
 		drm_irq_uninstall(dev);
+		vga_client_register(dev->pdev, NULL, NULL, NULL);
 	}
 
 	if (dev->pdev->msi_enabled)
diff -up linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_drv.h.arb linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_drv.h
--- linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_drv.h.arb	2009-08-05 10:14:24.000000000 +1000
+++ linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_drv.h	2009-08-05 10:15:15.000000000 +1000
@@ -760,6 +760,7 @@ static inline void opregion_enable_asle(
 /* modesetting */
 extern void intel_modeset_init(struct drm_device *dev);
 extern void intel_modeset_cleanup(struct drm_device *dev);
+extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
 
 /**
  * Lock test for when it's just for synchronization of ring access.
diff -up linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_reg.h.arb linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_reg.h
--- linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_reg.h.arb	2009-08-05 10:14:24.000000000 +1000
+++ linux-2.6.30.noarch/drivers/gpu/drm/i915/i915_reg.h	2009-08-05 10:15:15.000000000 +1000
@@ -30,6 +30,7 @@
  * fb aperture size and the amount of pre-reserved memory.
  */
 #define INTEL_GMCH_CTRL		0x52
+#define INTEL_GMCH_VGA_DISABLE  (1 << 1)
 #define INTEL_GMCH_ENABLED	0x4
 #define INTEL_GMCH_MEM_MASK	0x1
 #define INTEL_GMCH_MEM_64M	0x1
diff -up linux-2.6.30.noarch/drivers/gpu/drm/i915/intel_display.c.arb linux-2.6.30.noarch/drivers/gpu/drm/i915/intel_display.c
--- linux-2.6.30.noarch/drivers/gpu/drm/i915/intel_display.c.arb	2009-08-05 10:14:24.000000000 +1000
+++ linux-2.6.30.noarch/drivers/gpu/drm/i915/intel_display.c	2009-08-05 10:15:15.000000000 +1000
@@ -3871,3 +3871,26 @@ struct drm_encoder *intel_best_encoder(s
 
 	return &intel_output->enc;
 }
+
+/*
+ * set vga decode state - true == enable VGA decode
+ */
+int intel_modeset_vga_set_state(struct drm_device *dev, bool state)
+{
+	struct pci_dev *bridge_dev;
+	u16 gmch_ctrl;
+
+	bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
+	if (!bridge_dev) {
+		DRM_ERROR("Can't disable VGA, no bridge\n");
+		return -1;
+	}
+
+	pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &gmch_ctrl);
+	if (state)
+		gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE;
+	else
+		gmch_ctrl |= INTEL_GMCH_VGA_DISABLE;
+	pci_write_config_word(bridge_dev, INTEL_GMCH_CTRL, gmch_ctrl);
+	return 0;
+}
diff -up linux-2.6.30.noarch/drivers/gpu/drm/i915/intel_drv.h.arb linux-2.6.30.noarch/drivers/gpu/drm/i915/intel_drv.h
--- linux-2.6.30.noarch/drivers/gpu/drm/i915/intel_drv.h.arb	2009-08-05 10:14:24.000000000 +1000
+++ linux-2.6.30.noarch/drivers/gpu/drm/i915/intel_drv.h	2009-08-05 10:15:15.000000000 +1000
@@ -161,4 +161,5 @@ extern int intel_framebuffer_create(stru
 				    struct drm_mode_fb_cmd *mode_cmd,
 				    struct drm_framebuffer **fb,
 				    struct drm_gem_object *obj);
+
 #endif /* __INTEL_DRV_H__ */
diff -up linux-2.6.30.noarch/drivers/gpu/drm/radeon/r100.c.arb linux-2.6.30.noarch/drivers/gpu/drm/radeon/r100.c
--- linux-2.6.30.noarch/drivers/gpu/drm/radeon/r100.c.arb	2009-08-05 10:14:23.000000000 +1000
+++ linux-2.6.30.noarch/drivers/gpu/drm/radeon/r100.c	2009-08-05 10:15:15.000000000 +1000
@@ -1497,6 +1497,20 @@ void r100_vram_init_sizes(struct radeon_
 		rdev->mc.real_vram_size = rdev->mc.aper_size;
 }
 
+void r100_vga_set_state(struct radeon_device *rdev, bool state)
+{
+	uint32_t temp;
+
+	temp = RREG32(RADEON_CONFIG_CNTL);
+	if (state == false) {
+		temp &= ~(1<<8);
+		temp |= (1<<9);
+	} else {
+		temp &= ~(1<<9);
+	}
+	WREG32(RADEON_CONFIG_CNTL, temp);
+}
+
 void r100_vram_info(struct radeon_device *rdev)
 {
 	r100_vram_get_type(rdev);
diff -up linux-2.6.30.noarch/drivers/gpu/drm/radeon/radeon_asic.h.arb linux-2.6.30.noarch/drivers/gpu/drm/radeon/radeon_asic.h
--- linux-2.6.30.noarch/drivers/gpu/drm/radeon/radeon_asic.h.arb	2009-08-05 10:14:24.000000000 +1000
+++ linux-2.6.30.noarch/drivers/gpu/drm/radeon/radeon_asic.h	2009-08-05 10:15:15.000000000 +1000
@@ -46,6 +46,7 @@ uint32_t r100_mm_rreg(struct radeon_devi
 void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 void r100_errata(struct radeon_device *rdev);
 void r100_vram_info(struct radeon_device *rdev);
+void r100_vga_set_state(struct radeon_device *rdev, bool state);
 int r100_gpu_reset(struct radeon_device *rdev);
 int r100_mc_init(struct radeon_device *rdev);
 void r100_mc_fini(struct radeon_device *rdev);
@@ -84,6 +85,7 @@ static struct radeon_asic r100_asic = {
 	.init = &r100_init,
 	.errata = &r100_errata,
 	.vram_info = &r100_vram_info,
+	.vga_set_state = &r100_vga_set_state,
 	.gpu_reset = &r100_gpu_reset,
 	.mc_init = &r100_mc_init,
 	.mc_fini = &r100_mc_fini,
@@ -147,6 +149,7 @@ static struct radeon_asic r300_asic = {
 	.init = &r300_init,
 	.errata = &r300_errata,
 	.vram_info = &r300_vram_info,
+	.vga_set_state = &r100_vga_set_state,
 	.gpu_reset = &r300_gpu_reset,
 	.mc_init = &r300_mc_init,
 	.mc_fini = &r300_mc_fini,
@@ -190,6 +193,7 @@ static struct radeon_asic r420_asic = {
 	.init = &r300_init,
 	.errata = &r420_errata,
 	.vram_info = &r420_vram_info,
+	.vga_set_state = &r100_vga_set_state,
 	.gpu_reset = &r300_gpu_reset,
 	.mc_init = &r420_mc_init,
 	.mc_fini = &r420_mc_fini,
@@ -240,6 +244,7 @@ static struct radeon_asic rs400_asic = {
 	.init = &r300_init,
 	.errata = &rs400_errata,
 	.vram_info = &rs400_vram_info,
+	.vga_set_state = &r100_vga_set_state,
 	.gpu_reset = &r300_gpu_reset,
 	.mc_init = &rs400_mc_init,
 	.mc_fini = &rs400_mc_fini,
@@ -292,6 +297,7 @@ static struct radeon_asic rs600_asic = {
 	.init = &r300_init,
 	.errata = &rs600_errata,
 	.vram_info = &rs600_vram_info,
+	.vga_set_state = &r100_vga_set_state,
 	.gpu_reset = &r300_gpu_reset,
 	.mc_init = &rs600_mc_init,
 	.mc_fini = &rs600_mc_fini,
@@ -337,6 +343,7 @@ static struct radeon_asic rs690_asic = {
 	.init = &r300_init,
 	.errata = &rs690_errata,
 	.vram_info = &rs690_vram_info,
+	.vga_set_state = &r100_vga_set_state,
 	.gpu_reset = &r300_gpu_reset,
 	.mc_init = &rs690_mc_init,
 	.mc_fini = &rs690_mc_fini,
@@ -389,6 +396,7 @@ static struct radeon_asic rv515_asic = {
 	.init = &rv515_init,
 	.errata = &rv515_errata,
 	.vram_info = &rv515_vram_info,
+	.vga_set_state = &r100_vga_set_state,
 	.gpu_reset = &rv515_gpu_reset,
 	.mc_init = &rv515_mc_init,
 	.mc_fini = &rv515_mc_fini,
@@ -432,6 +440,7 @@ static struct radeon_asic r520_asic = {
 	.init = &rv515_init,
 	.errata = &r520_errata,
 	.vram_info = &r520_vram_info,
+	.vga_set_state = &r100_vga_set_state,
 	.gpu_reset = &rv515_gpu_reset,
 	.mc_init = &r520_mc_init,
 	.mc_fini = &r520_mc_fini,
diff -up linux-2.6.30.noarch/drivers/gpu/drm/radeon/radeon_device.c.arb linux-2.6.30.noarch/drivers/gpu/drm/radeon/radeon_device.c
--- linux-2.6.30.noarch/drivers/gpu/drm/radeon/radeon_device.c.arb	2009-08-05 10:14:24.000000000 +1000
+++ linux-2.6.30.noarch/drivers/gpu/drm/radeon/radeon_device.c	2009-08-05 10:15:29.000000000 +1000
@@ -29,6 +29,7 @@
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/radeon_drm.h>
+#include <linux/vgaarb.h>
 #include "radeon_reg.h"
 #include "radeon.h"
 #include "radeon_asic.h"
@@ -475,7 +476,18 @@ void radeon_combios_fini(struct radeon_d
 int radeon_modeset_init(struct radeon_device *rdev);
 void radeon_modeset_fini(struct radeon_device *rdev);
 
+/* if we get transitioned to only one device, tak VGA back */
+static unsigned int radeon_vga_set_decode(void *cookie, bool state)
+{
+	struct radeon_device *rdev = cookie;
 
+	radeon_vga_set_state(rdev, state);
+	if (state)
+		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
+		       VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+	else
+		return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+}
 /*
  * Radeon device.
  */
@@ -566,6 +578,12 @@ int radeon_device_init(struct radeon_dev
 		/* Initialize surface registers */
 		radeon_surface_init(rdev);
 
+		/* if we have > 1 VGA cards, then disable the radeon VGA resources */
+		ret = vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
+		if (ret) {
+			return -EINVAL;
+		}
+
 		/* TODO: disable VGA need to use VGA request */
 		/* BIOS*/
 		if (!radeon_get_bios(rdev)) {
@@ -700,6 +718,7 @@ void radeon_device_fini(struct radeon_de
 		radeon_agp_fini(rdev);
 #endif
 		radeon_irq_kms_fini(rdev);
+		vga_client_register(rdev->pdev, NULL, NULL, NULL);
 		radeon_fence_driver_fini(rdev);
 		radeon_clocks_fini(rdev);
 		radeon_object_fini(rdev);
diff -up linux-2.6.30.noarch/drivers/gpu/drm/radeon/radeon.h.arb linux-2.6.30.noarch/drivers/gpu/drm/radeon/radeon.h
--- linux-2.6.30.noarch/drivers/gpu/drm/radeon/radeon.h.arb	2009-08-05 10:14:24.000000000 +1000
+++ linux-2.6.30.noarch/drivers/gpu/drm/radeon/radeon.h	2009-08-05 10:15:15.000000000 +1000
@@ -579,6 +579,7 @@ struct radeon_asic {
 	int (*suspend)(struct radeon_device *rdev);
 	void (*errata)(struct radeon_device *rdev);
 	void (*vram_info)(struct radeon_device *rdev);
+	void (*vga_set_state)(struct radeon_device *rdev, bool state);
 	int (*gpu_reset)(struct radeon_device *rdev);
 	int (*mc_init)(struct radeon_device *rdev);
 	void (*mc_fini)(struct radeon_device *rdev);
@@ -879,6 +880,7 @@ static inline void radeon_ring_write(str
 #define radeon_cs_parse(p) rdev->asic->cs_parse((p))
 #define radeon_errata(rdev) (rdev)->asic->errata((rdev))
 #define radeon_vram_info(rdev) (rdev)->asic->vram_info((rdev))
+#define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state))
 #define radeon_gpu_reset(rdev) (rdev)->asic->gpu_reset((rdev))
 #define radeon_mc_init(rdev) (rdev)->asic->mc_init((rdev))
 #define radeon_mc_fini(rdev) (rdev)->asic->mc_fini((rdev))
diff -up linux-2.6.30.noarch/include/drm/drmP.h.arb linux-2.6.30.noarch/include/drm/drmP.h
--- linux-2.6.30.noarch/include/drm/drmP.h.arb	2009-08-05 10:14:24.000000000 +1000
+++ linux-2.6.30.noarch/include/drm/drmP.h	2009-08-05 10:15:15.000000000 +1000
@@ -797,6 +797,9 @@ struct drm_driver {
 	int (*gem_init_object) (struct drm_gem_object *obj);
 	void (*gem_free_object) (struct drm_gem_object *obj);
 
+	/* vga arb irq handler */
+	void (*vgaarb_irq)(struct drm_device *dev, bool state);
+
 	/* Driver private ops for this object */
 	struct vm_operations_struct *gem_vm_ops;
 

hid-ignore-all-recent-imon-devices.patch:
 hid-core.c |   10 +++++-----
 hid-ids.h  |    7 ++-----
 2 files changed, 7 insertions(+), 10 deletions(-)

--- NEW FILE hid-ignore-all-recent-imon-devices.patch ---
[PATCH] hid: ignore all recent SoundGraph iMON devices

After some inspection of the Windows iMON driver, several additional
device IDs were added to the lirc_imon driver. At least a few of these
have been seen in the wild, and require manual quirking to keep the
usbhid driver from binding to them. Rather than list out every single
device, ignore the entire device ID range, 0x0034 - 0x0046. Some of
these may not advertise themselves as HID devices, but no harm done to
such devices anyway.

Signed-off-by: Jarod Wilson <jarod at redhat.com>

---
 drivers/hid/hid-core.c |   10 +++++-----
 drivers/hid/hid-ids.h  |    7 ++-----
 2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 5eb10c2..18bf803 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1623,11 +1623,6 @@ static const struct hid_device_id hid_ignore_list[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD4) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) },
@@ -1694,6 +1689,11 @@ static bool hid_ignore(struct hid_device *hdev)
 				hdev->product <= USB_DEVICE_ID_LOGITECH_HARMONY_LAST)
 			return true;
 		break;
+	case USB_VENDOR_ID_SOUNDGRAPH:
+		if (hdev->product >= USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST &&
+		    hdev->product <= USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST)
+			return true;
+		break;
 	}
 
 	if (hdev->type == HID_TYPE_USBMOUSE &&
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 6301010..989a3ba 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -376,11 +376,8 @@
 #define USB_DEVICE_ID_SONY_PS3_CONTROLLER	0x0268
 
 #define USB_VENDOR_ID_SOUNDGRAPH	0x15c2
-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD	0x0038
-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2	0x0036
-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3	0x0034
-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD4	0x0044
-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5	0x0045
+#define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST	0x0034
+#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST	0x0046
 
 #define USB_VENDOR_ID_SUN		0x0430
 #define USB_DEVICE_ID_RARITAN_KVM_DONGLE	0xcdab

linux-2.6-alsa-improve-hda-powerdown.patch:
 hda_codec.c      |    9 +++++++--
 patch_sigmatel.c |   14 ++++++++++++++
 2 files changed, 21 insertions(+), 2 deletions(-)

--- NEW FILE linux-2.6-alsa-improve-hda-powerdown.patch ---
From: Takashi Iwai <tiwai at suse.de>
Date: Wed, 22 Jul 2009 10:39:24 +0000 (+0200)
Subject: ALSA: hda - Reduce click noise at power-saving
X-Git-Url: http://kernel.ubuntu.com/git?p=dtchen%2Fubuntu-karmic.git;a=commitdiff_plain;h=d6c571bdc08f1958f70c71eb11677066729e8505

ALSA: hda - Reduce click noise at power-saving

Add some tricks to reduce the click noise at powering down to D3
in the power saving mode on STAC/IDT codecs.
The key seems to be to reset PINs before the power-down, and some
delay before entering D3.  The needed delay is significantly long,
but I don't know why.

Signed-off-by: Takashi Iwai <tiwai at suse.de>
Signed-off-by: Daniel T Chen <seven.steps at gmail.com>
---

diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 88480c0..4d72e50 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -2356,9 +2356,14 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
 	hda_nid_t nid;
 	int i;
 
-	snd_hda_codec_write(codec, fg, 0, AC_VERB_SET_POWER_STATE,
+	/* this delay seems necessary to avoid click noise at power-down */
+	if (power_state == AC_PWRST_D3)
+		msleep(100);
+	snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
 			    power_state);
-	msleep(10); /* partial workaround for "azx_get_response timeout" */
+	/* partial workaround for "azx_get_response timeout" */
+	if (power_state == AC_PWRST_D0)
+		msleep(10);
 
 	nid = codec->start_nid;
 	for (i = 0; i < codec->num_nodes; i++, nid++) {
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index da7f9f6..3637b31 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -4746,6 +4746,20 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
 static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
 {
 	struct sigmatel_spec *spec = codec->spec;
+	int i;
+	hda_nid_t nid;
+
+	/* reset each pin before powering down DAC/ADC to avoid click noise */
+	nid = codec->start_nid;
+	for (i = 0; i < codec->num_nodes; i++, nid++) {
+		unsigned int wcaps = get_wcaps(codec, nid);
+		unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >>
+			AC_WCAP_TYPE_SHIFT;
+		if (wid_type == AC_WID_PIN)
+			snd_hda_codec_read(codec, nid, 0,
+				AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
+	}
+
 	if (spec->eapd_mask)
 		stac_gpio_set(codec, spec->gpio_mask,
 				spec->gpio_dir, spec->gpio_data &

linux-2.6-bluetooth-autosuspend.diff:
 btusb.c |  185 +++++++++++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 143 insertions(+), 42 deletions(-)

--- NEW FILE linux-2.6-bluetooth-autosuspend.diff ---
commit 7ed6456e2717d641a287bf6a83c1bf80395d312c
Author: Matthew Garrett <mjg at redhat.com>
Date:   Sat Jul 18 23:19:10 2009 +0100

    Add support for bluetooth autosuspend

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index e70c57e..2f4b4c6 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -145,6 +145,7 @@ static struct usb_device_id blacklist_table[] = {
 #define BTUSB_INTR_RUNNING	0
 #define BTUSB_BULK_RUNNING	1
 #define BTUSB_ISOC_RUNNING	2
+#define BTUSB_SUSPENDING	3
 
 struct btusb_data {
 	struct hci_dev       *hdev;
@@ -157,11 +158,13 @@ struct btusb_data {
 	unsigned long flags;
 
 	struct work_struct work;
+	struct work_struct waker;
 
 	struct usb_anchor tx_anchor;
 	struct usb_anchor intr_anchor;
 	struct usb_anchor bulk_anchor;
 	struct usb_anchor isoc_anchor;
+	struct usb_anchor deferred;
 
 	struct usb_endpoint_descriptor *intr_ep;
 	struct usb_endpoint_descriptor *bulk_tx_ep;
@@ -174,6 +177,7 @@ struct btusb_data {
 	unsigned int sco_num;
 	int isoc_altsetting;
 	int suspend_count;
+	int did_iso_resume:1;
 };
 
 static void btusb_intr_complete(struct urb *urb)
@@ -202,6 +206,10 @@ static void btusb_intr_complete(struct urb *urb)
 	if (!test_bit(BTUSB_INTR_RUNNING, &data->flags))
 		return;
 
+	if (test_bit(BTUSB_SUSPENDING, &data->flags))
+		return;
+
+	usb_mark_last_busy(data->udev);
 	usb_anchor_urb(urb, &data->intr_anchor);
 
 	err = usb_submit_urb(urb, GFP_ATOMIC);
@@ -285,6 +293,9 @@ static void btusb_bulk_complete(struct urb *urb)
 	if (!test_bit(BTUSB_BULK_RUNNING, &data->flags))
 		return;
 
+	if (test_bit(BTUSB_SUSPENDING, &data->flags))
+		return;
+
 	usb_anchor_urb(urb, &data->bulk_anchor);
 
 	err = usb_submit_urb(urb, GFP_ATOMIC);
@@ -320,6 +331,7 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
 		return -ENOMEM;
 	}
 
+	usb_mark_last_busy(data->udev);
 	pipe = usb_rcvbulkpipe(data->udev, data->bulk_rx_ep->bEndpointAddress);
 
 	usb_fill_bulk_urb(urb, data->udev, pipe,
@@ -327,6 +339,7 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
 
 	urb->transfer_flags |= URB_FREE_BUFFER;
 
+	usb_mark_last_busy(data->udev);
 	usb_anchor_urb(urb, &data->bulk_anchor);
 
 	err = usb_submit_urb(urb, mem_flags);
@@ -375,6 +388,9 @@ static void btusb_isoc_complete(struct urb *urb)
 	if (!test_bit(BTUSB_ISOC_RUNNING, &data->flags))
 		return;
 
+	if (test_bit(BTUSB_SUSPENDING, &data->flags))
+		return;
+
 	usb_anchor_urb(urb, &data->isoc_anchor);
 
 	err = usb_submit_urb(urb, GFP_ATOMIC);
@@ -490,6 +506,12 @@ static int btusb_open(struct hci_dev *hdev)
 
 	BT_DBG("%s", hdev->name);
 
+	err = usb_autopm_get_interface(data->intf);
+	if (err < 0)
+		return err;
+	data->intf->needs_remote_wakeup = 1;
+	usb_autopm_put_interface(data->intf);
+
 	if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
 		return 0;
 
@@ -517,9 +539,17 @@ failed:
 	return err;
 }
 
+static void btusb_stop_traffic(struct btusb_data *data)
+{
+	usb_kill_anchored_urbs(&data->intr_anchor);
+	usb_kill_anchored_urbs(&data->bulk_anchor);
+	usb_kill_anchored_urbs(&data->isoc_anchor);
+}
+
 static int btusb_close(struct hci_dev *hdev)
 {
 	struct btusb_data *data = hdev->driver_data;
+	int err;
 
 	BT_DBG("%s", hdev->name);
 
@@ -529,13 +559,15 @@ static int btusb_close(struct hci_dev *hdev)
 	cancel_work_sync(&data->work);
 
 	clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
-	usb_kill_anchored_urbs(&data->isoc_anchor);
-
 	clear_bit(BTUSB_BULK_RUNNING, &data->flags);
-	usb_kill_anchored_urbs(&data->bulk_anchor);
-
 	clear_bit(BTUSB_INTR_RUNNING, &data->flags);
-	usb_kill_anchored_urbs(&data->intr_anchor);
+	btusb_stop_traffic(data);
+
+	err = usb_autopm_get_interface(data->intf);
+	if (!err) {
+		data->intf->needs_remote_wakeup = 0;
+		usb_autopm_put_interface(data->intf);
+	}
 
 	return 0;
 }
@@ -558,7 +590,7 @@ static int btusb_send_frame(struct sk_buff *skb)
 	struct usb_ctrlrequest *dr;
 	struct urb *urb;
 	unsigned int pipe;
-	int err;
+	int err, susp;
 
 	BT_DBG("%s", hdev->name);
 
@@ -567,6 +599,7 @@ static int btusb_send_frame(struct sk_buff *skb)
 
 	switch (bt_cb(skb)->pkt_type) {
 	case HCI_COMMAND_PKT:
+		BT_DBG("HCI_COMMAND_PKT");
 		urb = usb_alloc_urb(0, GFP_ATOMIC);
 		if (!urb)
 			return -ENOMEM;
@@ -592,6 +625,7 @@ static int btusb_send_frame(struct sk_buff *skb)
 		break;
 
 	case HCI_ACLDATA_PKT:
+		BT_DBG("HCI_ACLDATA_PKT");
 		if (!data->bulk_tx_ep || hdev->conn_hash.acl_num < 1)
 			return -ENODEV;
 
@@ -609,6 +643,7 @@ static int btusb_send_frame(struct sk_buff *skb)
 		break;
 
 	case HCI_SCODATA_PKT:
+		BT_DBG("HCI_SCODATA_PKT");
 		if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1)
 			return -ENODEV;
 
@@ -639,17 +674,22 @@ static int btusb_send_frame(struct sk_buff *skb)
 		return -EILSEQ;
 	}
 
+	spin_lock(&data->lock);
+	susp = test_bit(BTUSB_SUSPENDING, &data->flags);
 	usb_anchor_urb(urb, &data->tx_anchor);
-
-	err = usb_submit_urb(urb, GFP_ATOMIC);
-	if (err < 0) {
-		BT_ERR("%s urb %p submission failed", hdev->name, urb);
-		kfree(urb->setup_packet);
-		usb_unanchor_urb(urb);
+	if (susp) {
+		schedule_work(&data->waker);
+		err = 0;
+	} else {
+		err = usb_submit_urb(urb, GFP_ATOMIC);
+		if (err < 0) {
+			BT_ERR("%s urb %p submission failed", hdev->name, urb);
+			kfree(urb->setup_packet);
+			usb_unanchor_urb(urb);
+		}
+		usb_free_urb(urb);
 	}
-
-	usb_free_urb(urb);
-
+	spin_unlock(&data->lock);
 	return err;
 }
 
@@ -742,9 +782,26 @@ static void btusb_work(struct work_struct *work)
 		usb_kill_anchored_urbs(&data->isoc_anchor);
 
 		__set_isoc_interface(hdev, 0);
+		if (data->did_iso_resume) {
+			data->did_iso_resume = 0;
+			usb_autopm_put_interface(data->isoc);
+		}
 	}
 }
 
+static void btusb_waker(struct work_struct *work)
+{
+	struct btusb_data *data = container_of(work, struct btusb_data, waker);
+	int err;
+
+	BUG_ON(data == NULL);
+	BT_DBG("about to resume");
+	BUG_ON(data->intf == NULL);
+	err = usb_autopm_get_interface(data->intf);
+	if (!err)
+		usb_autopm_put_interface(data->intf);
+}
+
 static int btusb_probe(struct usb_interface *intf,
 				const struct usb_device_id *id)
 {
@@ -814,11 +871,13 @@ static int btusb_probe(struct usb_interface *intf,
 	spin_lock_init(&data->lock);
 
 	INIT_WORK(&data->work, btusb_work);
+	INIT_WORK(&data->waker, btusb_waker);
 
 	init_usb_anchor(&data->tx_anchor);
 	init_usb_anchor(&data->intr_anchor);
 	init_usb_anchor(&data->bulk_anchor);
 	init_usb_anchor(&data->isoc_anchor);
+	init_usb_anchor(&data->deferred);
 
 	hdev = hci_alloc_dev();
 	if (!hdev) {
@@ -908,6 +967,7 @@ static int btusb_probe(struct usb_interface *intf,
 	}
 
 	usb_set_intfdata(intf, data);
+	usb_device_autosuspend_enable(data->udev);
 
 	return 0;
 }
@@ -947,60 +1007,100 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
 {
 	struct btusb_data *data = usb_get_intfdata(intf);
 
-	BT_DBG("intf %p", intf);
+	BT_DBG("%s called\n", __func__);
 
 	if (data->suspend_count++)
 		return 0;
 
-	cancel_work_sync(&data->work);
+	spin_lock_irq(&data->lock);
+	if (interface_to_usbdev(intf)->auto_pm &&
+		!usb_anchor_empty(&data->tx_anchor)) {
+		spin_unlock_irq(&data->lock);
+		return -EBUSY;
+	}
+
+	set_bit(BTUSB_SUSPENDING, &data->flags);
+	spin_unlock_irq(&data->lock);
 
+	cancel_work_sync(&data->work);
+	btusb_stop_traffic(data);
 	usb_kill_anchored_urbs(&data->tx_anchor);
+	return 0;
+}
 
-	usb_kill_anchored_urbs(&data->isoc_anchor);
-	usb_kill_anchored_urbs(&data->bulk_anchor);
-	usb_kill_anchored_urbs(&data->intr_anchor);
+static int play_deferred(struct btusb_data *data)
+{
+	struct urb *urb;
+	int err = 0;
 
-	return 0;
+	while ((urb = usb_get_from_anchor(&data->tx_anchor))) {
+		err = usb_submit_urb(urb, GFP_ATOMIC);
+		if (err < 0)
+			break;
+	}
+
+	usb_scuttle_anchored_urbs(&data->tx_anchor);
+	return err;
 }
 
+
 static int btusb_resume(struct usb_interface *intf)
 {
 	struct btusb_data *data = usb_get_intfdata(intf);
 	struct hci_dev *hdev = data->hdev;
-	int err;
-
-	BT_DBG("intf %p", intf);
+	int ret = 0;
 
 	if (--data->suspend_count)
 		return 0;
 
-	if (!test_bit(HCI_RUNNING, &hdev->flags))
-		return 0;
+	if (test_bit(HCI_RUNNING, &hdev->flags)) {
+		spin_lock_irq(&data->lock);
+		ret = play_deferred(data);
+		clear_bit(BTUSB_SUSPENDING, &data->flags);
+		spin_unlock_irq(&data->lock);
 
-	if (test_bit(BTUSB_INTR_RUNNING, &data->flags)) {
-		err = btusb_submit_intr_urb(hdev, GFP_NOIO);
-		if (err < 0) {
-			clear_bit(BTUSB_INTR_RUNNING, &data->flags);
-			return err;
+		if (ret < 0) {
+			clear_bit(HCI_RUNNING, &hdev->flags);
+			return ret;
 		}
+
+		ret = btusb_submit_intr_urb(hdev, GFP_NOIO);
+		if (ret < 0) {
+			clear_bit(HCI_RUNNING, &hdev->flags);
+			return ret;
+		}
+	} else {
+		spin_lock_irq(&data->lock);
+		clear_bit(BTUSB_SUSPENDING, &data->flags);
+		spin_unlock_irq(&data->lock);
 	}
 
-	if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
-		err = btusb_submit_bulk_urb(hdev, GFP_NOIO);
-		if (err < 0) {
+	if (hdev->conn_hash.acl_num > 0) {
+		ret = btusb_submit_bulk_urb(hdev, GFP_NOIO);
+		if (ret < 0) {
 			clear_bit(BTUSB_BULK_RUNNING, &data->flags);
-			return err;
-		} else
-			btusb_submit_bulk_urb(hdev, GFP_NOIO);
+			return ret;
+		} else {
+			ret = btusb_submit_bulk_urb(hdev, GFP_NOIO);
+			if (ret < 0) {
+				clear_bit(BTUSB_BULK_RUNNING, &data->flags);
+				usb_kill_anchored_urbs(&data->bulk_anchor);
+				return ret;
+			}
+		}
 	}
 
-	if (test_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
-		if (btusb_submit_isoc_urb(hdev, GFP_NOIO) < 0)
-			clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
-		else
-			btusb_submit_isoc_urb(hdev, GFP_NOIO);
+	if (data->isoc) {
+		if (test_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
+			ret = btusb_submit_isoc_urb(hdev, GFP_NOIO);
+			if (ret < 0)
+				clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+			else
+				btusb_submit_isoc_urb(hdev, GFP_NOIO);
+		}
 	}
 
+	schedule_work(&data->work);
 	return 0;
 }
 
@@ -1011,6 +1111,7 @@ static struct usb_driver btusb_driver = {
 	.suspend	= btusb_suspend,
 	.resume		= btusb_resume,
 	.id_table	= btusb_table,
+	.supports_autosuspend = 1,
 };
 
 static int __init btusb_init(void)

linux-2.6-defaults-aspm.patch:
 aspm.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE linux-2.6-defaults-aspm.patch ---
diff -up linux-2.6.30.noarch/drivers/pci/pcie/aspm.c.mjg linux-2.6.30.noarch/drivers/pci/pcie/aspm.c
--- linux-2.6.30.noarch/drivers/pci/pcie/aspm.c.mjg	2009-07-16 22:01:11.000000000 +0100
+++ linux-2.6.30.noarch/drivers/pci/pcie/aspm.c	2009-07-16 22:01:30.000000000 +0100
@@ -65,7 +65,7 @@ static LIST_HEAD(link_list);
 #define POLICY_DEFAULT 0	/* BIOS default setting */
 #define POLICY_PERFORMANCE 1	/* high performance */
 #define POLICY_POWERSAVE 2	/* high power saving */
-static int aspm_policy;
+static int aspm_policy = POLICY_POWERSAVE;
 static const char *policy_str[] = {
 	[POLICY_DEFAULT] = "default",
 	[POLICY_PERFORMANCE] = "performance",

linux-2.6-dell-laptop-rfkill-fix.patch:
 b/drivers/input/input.c              |   91 +++++++++++++++++++++++++++----
 b/drivers/platform/x86/dell-laptop.c |  100 +++++++++++++++++++++++++++++++++++
 b/include/linux/input.h              |    5 +
 drivers/platform/x86/dell-laptop.c   |    5 -
 4 files changed, 185 insertions(+), 16 deletions(-)

--- NEW FILE linux-2.6-dell-laptop-rfkill-fix.patch ---
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 7c237e6..80f1e48 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -88,19 +88,26 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz)
  */
 static void input_pass_event(struct input_dev *dev,
 			     unsigned int type, unsigned int code, int value)
-{
-	struct input_handle *handle;
+
+{	struct input_handle *handle;
 
 	rcu_read_lock();
 
 	handle = rcu_dereference(dev->grab);
-	if (handle)
+	if (handle) {
 		handle->handler->event(handle, type, code, value);
-	else
-		list_for_each_entry_rcu(handle, &dev->h_list, d_node)
-			if (handle->open)
-				handle->handler->event(handle,
-							type, code, value);
+		goto out;
+	}
+
+	handle = rcu_dereference(dev->filter);
+	if (handle && handle->handler->filter(handle, type, code, value))
+		goto out;
+
+	list_for_each_entry_rcu(handle, &dev->h_list, d_node)
+		if (handle->open)
+			handle->handler->event(handle,
+					       type, code, value);
+out:
 	rcu_read_unlock();
 }
 
@@ -375,12 +382,15 @@ int input_grab_device(struct input_handle *handle)
 }
 EXPORT_SYMBOL(input_grab_device);
 
-static void __input_release_device(struct input_handle *handle)
+static void __input_release_device(struct input_handle *handle, bool filter)
 {
 	struct input_dev *dev = handle->dev;
 
-	if (dev->grab == handle) {
-		rcu_assign_pointer(dev->grab, NULL);
+	if (handle == (filter ? dev->filter : dev->grab)) {
+		if (filter)
+			rcu_assign_pointer(dev->filter, NULL);
+		else
+			rcu_assign_pointer(dev->grab, NULL);
 		/* Make sure input_pass_event() notices that grab is gone */
 		synchronize_rcu();
 
@@ -404,12 +414,65 @@ void input_release_device(struct input_handle *handle)
 	struct input_dev *dev = handle->dev;
 
 	mutex_lock(&dev->mutex);
-	__input_release_device(handle);
+	__input_release_device(handle, false);
 	mutex_unlock(&dev->mutex);
 }
 EXPORT_SYMBOL(input_release_device);
 
 /**
+ * input_filter_device - allow input events to be filtered from higher layers
+ * @handle: input handle that wants to filter the device
+ *
+ * When a device is filtered by an input handle all events generated by
+ * the device are to this handle. If the filter function returns true then
+ * the event is discarded rather than being passed to any other input handles,
+ * otherwise it is passed to them as normal. Grabs will be handled before
+ * filters, so a grabbed device will not deliver events to a filter function.
+ */
+int input_filter_device(struct input_handle *handle)
+{
+	struct input_dev *dev = handle->dev;
+	int retval;
+
+	retval = mutex_lock_interruptible(&dev->mutex);
+	if (retval)
+		return retval;
+
+	if (dev->filter) {
+		retval = -EBUSY;
+		goto out;
+	}
+
+	rcu_assign_pointer(dev->filter, handle);
+	synchronize_rcu();
+
+ out:
+	mutex_unlock(&dev->mutex);
+	return retval;
+}
+EXPORT_SYMBOL(input_filter_device);
+
+/**
+ * input_unfilter_device - removes a filter from a device
+ * @handle: input handle that owns the device
+ *
+ * Removes the filter from a device so that other input handles can
+ * start receiving unfiltered input events. Upon release all handlers
+ * attached to the device have their start() method called so they
+ * have a change to synchronize device state with the rest of the
+ * system.
+ */
+void input_unfilter_device(struct input_handle *handle)
+{
+	struct input_dev *dev = handle->dev;
+
+	mutex_lock(&dev->mutex);
+	__input_release_device(handle, true);
+	mutex_unlock(&dev->mutex);
+}
+EXPORT_SYMBOL(input_unfilter_device);
+
+/**
  * input_open_device - open input device
  * @handle: handle through which device is being accessed
  *
@@ -482,7 +545,9 @@ void input_close_device(struct input_handle *handle)
 
 	mutex_lock(&dev->mutex);
 
-	__input_release_device(handle);
+	/* Release both grabs and filters */
+	__input_release_device(handle, false);
+	__input_release_device(handle, true);
 
 	if (!--dev->users && dev->close)
 		dev->close(dev);
diff --git a/include/linux/input.h b/include/linux/input.h
index 8b3bc3e..e28f116 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -1118,6 +1118,7 @@ struct input_dev {
 	int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
 
 	struct input_handle *grab;
+	struct input_handle *filter;
 
 	spinlock_t event_lock;
 	struct mutex mutex;
@@ -1218,6 +1219,7 @@ struct input_handler {
 	void *private;
 
 	void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
+	bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
 	int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
 	void (*disconnect)(struct input_handle *handle);
 	void (*start)(struct input_handle *handle);
@@ -1295,6 +1297,9 @@ void input_unregister_handle(struct input_handle *);
 int input_grab_device(struct input_handle *);
 void input_release_device(struct input_handle *);
 
+int input_filter_device(struct input_handle *);
+void input_unfilter_device(struct input_handle *);
+
 int input_open_device(struct input_handle *);
 void input_close_device(struct input_handle *);
 
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index 74909c4..71a4149 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -22,6 +22,7 @@
 #include <linux/rfkill.h>
 #include <linux/power_supply.h>
 #include <linux/acpi.h>
+#include <linux/input.h>
 #include "../../firmware/dcdbas.h"
 
 #define BRIGHTNESS_TOKEN 0x7d
@@ -206,6 +207,16 @@ static const struct rfkill_ops dell_rfkill_ops = {
 	.query = dell_rfkill_query,
 };
 
+static void dell_rfkill_update(void)
+{
+	if (wifi_rfkill)
+		dell_rfkill_query(wifi_rfkill, (void *)1);
+	if (bluetooth_rfkill)
+		dell_rfkill_query(bluetooth_rfkill, (void *)2);
+	if (wwan_rfkill)
+		dell_rfkill_query(wwan_rfkill, (void *)3);
+}
+
 static int dell_setup_rfkill(void)
 {
 	struct calling_interface_buffer buffer;
@@ -310,6 +321,90 @@ static struct backlight_ops dell_ops = {
 	.update_status  = dell_send_intensity,
 };
 
+static const struct input_device_id dell_input_ids[] = {
+	{
+		.bustype = 0x11,
+		.vendor = 0x01,
+		.product = 0x01,
+		.version = 0xab41,
+		.flags = INPUT_DEVICE_ID_MATCH_BUS |
+			 INPUT_DEVICE_ID_MATCH_VENDOR |
+			 INPUT_DEVICE_ID_MATCH_PRODUCT |
+			 INPUT_DEVICE_ID_MATCH_VERSION
+	},
+	{ },
+};
+
+static bool dell_input_filter(struct input_handle *handle, unsigned int type,
+			     unsigned int code, int value)
+{
+	if (type == EV_KEY && code == KEY_WLAN && value == 1) {
+		dell_rfkill_update();
+		return 1;
+	}
+
+	return 0;
+}
+
+static void dell_input_event(struct input_handle *handle, unsigned int type,
+			     unsigned int code, int value)
+{
+}
+
+static int dell_input_connect(struct input_handler *handler,
+			      struct input_dev *dev,
+			      const struct input_device_id *id)
+{
+	struct input_handle *handle;
+	int error;
+
+	handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
+	if (!handle)
+		return -ENOMEM;
+
+	handle->dev = dev;
+	handle->handler = handler;
+	handle->name = "dell-laptop";
+
+	error = input_register_handle(handle);
+	if (error)
+		goto err_free_handle;
+
+	error = input_open_device(handle);
+	if (error)
+		goto err_unregister_handle;
+
+	error = input_filter_device(handle);
+	if (error)
+		goto err_close_handle;
+
+	return 0;
+
+err_close_handle:
+	input_close_device(handle);
+err_unregister_handle:
+	input_unregister_handle(handle);
+err_free_handle:
+	kfree(handle);
+	return error;
+}
+
+static void dell_input_disconnect(struct input_handle *handle)
+{
+	input_close_device(handle);
+	input_unregister_handle(handle);
+	kfree(handle);
+}
+
+static struct input_handler dell_input_handler = {
+	.name = "dell-laptop",
+	.filter = dell_input_filter,
+	.event = dell_input_event,
+	.connect = dell_input_connect,
+	.disconnect = dell_input_disconnect,
+	.id_table = dell_input_ids,
+};
+
 static int __init dell_init(void)
 {
 	struct calling_interface_buffer buffer;
@@ -333,6 +428,10 @@ static int __init dell_init(void)
 		goto out;
 	}
 
+	if (input_register_handler(&dell_input_handler))
+		printk(KERN_INFO
+		       "dell-laptop: Could not register input filter\n");
+
 #ifdef CONFIG_ACPI
 	/* In the event of an ACPI backlight being available, don't
 	 * register the platform controller.
@@ -388,6 +487,7 @@ static void __exit dell_exit(void)
 		rfkill_unregister(bluetooth_rfkill);
 	if (wwan_rfkill)
 		rfkill_unregister(wwan_rfkill);
+	input_unregister_handler(&dell_input_handler);
 }
 
 module_init(dell_init);
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index 71a4149..e559fa1 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -198,8 +198,8 @@ static void dell_rfkill_query(struct rfkill *rfkill, void *data)
 	dell_send_request(&buffer, 17, 11);
 	status = buffer.output[1];
 
-	if (status & BIT(bit))
-		rfkill_set_hw_state(rfkill, !!(status & BIT(16)));
+	rfkill_set_sw_state(rfkill, !!(status & BIT(bit)));
+	rfkill_set_hw_state(rfkill, !(status & BIT(16)));
 }
 
 static const struct rfkill_ops dell_rfkill_ops = {
-- 
1.6.3.3


linux-2.6-driver-level-usb-autosuspend.diff:
 drivers/usb/core/driver.c |   15 +++++++++++++++
 include/linux/usb.h       |    4 ++++
 2 files changed, 19 insertions(+)

--- NEW FILE linux-2.6-driver-level-usb-autosuspend.diff ---
commit 0f592e33934bf6108e33e34f00b425f98ee833ef
Author: Matthew Garrett <mjg at redhat.com>
Date:   Wed Jul 8 19:04:23 2009 +0100

    usb: Allow drivers to enable USB autosuspend on a per-device basis
    
    USB autosuspend is currently only enabled by default for hubs. On other
    hardware the decision is made by userspace. This is unnecessary in cases
    where we know that the hardware supports autosuspend, so this patch adds
    a function to allow drivers to enable it at probe time.
    
    Signed-off-by: Matthew Garrett <mjg at redhat.com>

diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 69e5773..6e81caa 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1560,6 +1560,21 @@ void usb_autopm_put_interface_async(struct usb_interface *intf)
 EXPORT_SYMBOL_GPL(usb_autopm_put_interface_async);
 
 /**
+ * usb_device_autosuspend_enable - enable autosuspend on a device
+ * @udev: the usb_device to be autosuspended
+ *
+ * This routine should be called by an interface driver when it knows that
+ * the device in question supports USB autosuspend.
+ *
+ */
+void usb_device_autosuspend_enable(struct usb_device *udev)
+{
+	udev->autosuspend_disabled = 0;
+	udev->autoresume_disabled = 0;
+}
+EXPORT_SYMBOL_GPL(usb_device_autosuspend_enable);
+
+/**
  * usb_autopm_get_interface - increment a USB interface's PM-usage counter
  * @intf: the usb_interface whose counter should be incremented
  *
diff --git a/include/linux/usb.h b/include/linux/usb.h
index b1e3c2f..61bddbe 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -543,6 +543,7 @@ extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id);
 
 /* USB autosuspend and autoresume */
 #ifdef CONFIG_USB_SUSPEND
+extern void usb_device_autosuspend_enable(struct usb_device *udev);
 extern int usb_autopm_set_interface(struct usb_interface *intf);
 extern int usb_autopm_get_interface(struct usb_interface *intf);
 extern void usb_autopm_put_interface(struct usb_interface *intf);
@@ -568,6 +569,9 @@ static inline void usb_mark_last_busy(struct usb_device *udev)
 
 #else
 
+static inline void usb_device_autosuspend_enable(struct usb_device *udev)
+{ }
+
 static inline int usb_autopm_set_interface(struct usb_interface *intf)
 { return 0; }
 

linux-2.6-fix-usb-serial-autosuspend.diff:
 usb-serial.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

--- NEW FILE linux-2.6-fix-usb-serial-autosuspend.diff ---
commit 3b8e1210f0a558145ba87eddb20f7b104676d6f6
Author: Oliber Neukum <oliver at neukum.org>
Date:   Sat Jul 18 07:19:04 2009 +0200

    usb: fix counter logic in opening serial converters
    
    the usage counter must be increased only after autoresumption

diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 99188c9..3d1a756 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -216,16 +216,15 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
 		goto bailout_port_put;
 	}
 
-	++port->port.count;
-
 	/* set up our port structure making the tty driver
 	 * remember our port object, and us it */
 	tty->driver_data = port;
 	tty_port_tty_set(&port->port, tty);
 
 	/* If the console is attached, the device is already open */
-	if (port->port.count == 1 && !port->console) {
+	if (!port->port.count && !port->console) {
 		first = 1;
+
 		/* lock this module before we call it
 		 * this may fail, which means we must bail out,
 		 * safe because we are called with BKL held */
@@ -242,6 +241,8 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
 		if (retval)
 			goto bailout_module_put;
 
+		++port->port.count;
+
 		/* only call the device specific open if this
 		 * is the first time the port is opened */
 		retval = serial->type->open(tty, port, filp);
@@ -249,6 +250,8 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
 			goto bailout_interface_put;
 		mutex_unlock(&serial->disc_mutex);
 		set_bit(ASYNCB_INITIALIZED, &port->port.flags);
+	} else {
+		++port->port.count;
 	}
 	mutex_unlock(&port->mutex);
 	/* Now do the correct tty layer semantics */

linux-2.6-ksm-kvm.patch:
 arch/x86/include/asm/kvm_host.h |    1 
 arch/x86/kvm/mmu.c              |   89 ++++++++++++++++++++++++++++++++--------
 arch/x86/kvm/paging_tmpl.h      |   15 +++++-
 virt/kvm/kvm_main.c             |   14 ++++++
 4 files changed, 100 insertions(+), 19 deletions(-)

--- NEW FILE linux-2.6-ksm-kvm.patch ---
When using mmu notifiers, we are allowed to remove the page count
reference tooken by get_user_pages to a specific page that is mapped
inside the shadow page tables.

This is needed so we can balance the pagecount against mapcount
checking.

(Right now kvm increase the pagecount and does not increase the
mapcount when mapping page into shadow page table entry,
so when comparing pagecount against mapcount, you have no
reliable result.)

add SPTE_HOST_WRITEABLE flag notify that the host physical page we are
pointing to from the spte is write protected, and therefore we cant
change its access to be write unless we run get_user_pages(write = 1).

(this is needed for change_pte support in kvm)

support for change_pte mmu notifiers is needed for kvm if it want ksm to
directly map pages into its shadow page tables.

Signed-off-by: Izik Eidus <ieidus at redhat.com>
Signed-off-by: Justin M. Forbes <jforbes at redhat.com>
---
--- linux-2.6.30.x86_64/arch/x86/include/asm/kvm_host.h	2009-07-23 14:58:56.000000000 -0500
+++ linux-2.6.30.x86_64-ksm/arch/x86/include/asm/kvm_host.h	2009-07-23 15:00:04.000000000 -0500
@@ -796,5 +796,6 @@ asmlinkage void kvm_handle_fault_on_rebo
 int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
 int kvm_age_hva(struct kvm *kvm, unsigned long hva);
 int cpuid_maxphyaddr(struct kvm_vcpu *vcpu);
+void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
 
 #endif /* _ASM_X86_KVM_HOST_H */
--- linux-2.6.30.x86_64/arch/x86/kvm/mmu.c	2009-07-23 14:58:56.000000000 -0500
+++ linux-2.6.30.x86_64-ksm/arch/x86/kvm/mmu.c	2009-07-23 15:00:04.000000000 -0500
@@ -139,6 +139,8 @@ module_param(oos_shadow, bool, 0644);
 #define ACC_USER_MASK    PT_USER_MASK
 #define ACC_ALL          (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK)
 
+#define SPTE_HOST_WRITEABLE (1ULL << PT_FIRST_AVAIL_BITS_SHIFT)
+
 #define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
 
 struct kvm_rmap_desc {
@@ -254,6 +256,11 @@ static pfn_t spte_to_pfn(u64 pte)
 	return (pte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT;
 }
 
+static pte_t ptep_val(pte_t *ptep)
+{
+	return *ptep;
+}
+
 static gfn_t pse36_gfn_delta(u32 gpte)
 {
 	int shift = 32 - PT32_DIR_PSE36_SHIFT - PAGE_SHIFT;
@@ -566,9 +573,7 @@ static void rmap_remove(struct kvm *kvm,
 	if (*spte & shadow_accessed_mask)
 		kvm_set_pfn_accessed(pfn);
 	if (is_writeble_pte(*spte))
-		kvm_release_pfn_dirty(pfn);
-	else
-		kvm_release_pfn_clean(pfn);
+		kvm_set_pfn_dirty(pfn);
 	rmapp = gfn_to_rmap(kvm, sp->gfns[spte - sp->spt], is_large_pte(*spte));
 	if (!*rmapp) {
 		printk(KERN_ERR "rmap_remove: %p %llx 0->BUG\n", spte, *spte);
@@ -677,7 +682,8 @@ static int rmap_write_protect(struct kvm
 	return write_protected;
 }
 
-static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp)
+static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp,
+			   unsigned long data)
 {
 	u64 *spte;
 	int need_tlb_flush = 0;
@@ -692,8 +698,48 @@ static int kvm_unmap_rmapp(struct kvm *k
 	return need_tlb_flush;
 }
 
+static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp,
+			     unsigned long data)
+{
+	int need_flush = 0;
+	u64 *spte, new_spte;
+	pte_t *ptep = (pte_t *)data;
+	pfn_t new_pfn;
+
+	new_pfn = pte_pfn(ptep_val(ptep));
+	spte = rmap_next(kvm, rmapp, NULL);
+	while (spte) {
+		BUG_ON(!is_shadow_present_pte(*spte));
+		rmap_printk("kvm_set_pte_rmapp: spte %p %llx\n", spte, *spte);
+		need_flush = 1;
+		if (pte_write(ptep_val(ptep))) {
+			rmap_remove(kvm, spte);
+			set_shadow_pte(spte, shadow_trap_nonpresent_pte);
+			spte = rmap_next(kvm, rmapp, NULL);
+		} else {
+			new_spte = *spte &~ (PT64_BASE_ADDR_MASK);
+			new_spte |= new_pfn << PAGE_SHIFT;
+
+			if (!pte_write(ptep_val(ptep))) {
+				new_spte &= ~PT_WRITABLE_MASK;
+				new_spte &= ~SPTE_HOST_WRITEABLE;
+				if (is_writeble_pte(*spte))
+					kvm_set_pfn_dirty(spte_to_pfn(*spte));
+			}
+			set_shadow_pte(spte, new_spte);
+			spte = rmap_next(kvm, rmapp, spte);
+		}
+	}
+	if (need_flush)
+		kvm_flush_remote_tlbs(kvm);
+
+	return 0;
+}
+
 static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
-			  int (*handler)(struct kvm *kvm, unsigned long *rmapp))
+			  unsigned long data,
+			  int (*handler)(struct kvm *kvm, unsigned long *rmapp,
+					 unsigned long data))
 {
 	int i;
 	int retval = 0;
@@ -714,11 +760,13 @@ static int kvm_handle_hva(struct kvm *kv
 		end = start + (memslot->npages << PAGE_SHIFT);
 		if (hva >= start && hva < end) {
 			gfn_t gfn_offset = (hva - start) >> PAGE_SHIFT;
-			retval |= handler(kvm, &memslot->rmap[gfn_offset]);
+			retval |= handler(kvm, &memslot->rmap[gfn_offset],
+					  data);
 			retval |= handler(kvm,
 					  &memslot->lpage_info[
 						  gfn_offset /
-						  KVM_PAGES_PER_HPAGE].rmap_pde);
+						  KVM_PAGES_PER_HPAGE].rmap_pde,
+						  data);
 		}
 	}
 
@@ -727,10 +775,16 @@ static int kvm_handle_hva(struct kvm *kv
 
 int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
 {
-	return kvm_handle_hva(kvm, hva, kvm_unmap_rmapp);
+	return kvm_handle_hva(kvm, hva, 0, kvm_unmap_rmapp);
+}
+
+void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte)
+{
+	kvm_handle_hva(kvm, hva, (unsigned long)&pte, kvm_set_pte_rmapp);
 }
 
-static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp)
+static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
+			 unsigned long data)
 {
 	u64 *spte;
 	int young = 0;
@@ -756,7 +810,7 @@ static int kvm_age_rmapp(struct kvm *kvm
 
 int kvm_age_hva(struct kvm *kvm, unsigned long hva)
 {
-	return kvm_handle_hva(kvm, hva, kvm_age_rmapp);
+	return kvm_handle_hva(kvm, hva, 0, kvm_age_rmapp);
 }
 
 #ifdef MMU_DEBUG
@@ -1665,7 +1719,7 @@ static int set_spte(struct kvm_vcpu *vcp
 		    unsigned pte_access, int user_fault,
 		    int write_fault, int dirty, int largepage,
 		    gfn_t gfn, pfn_t pfn, bool speculative,
-		    bool can_unsync)
+		    bool can_unsync, bool reset_host_protection)
 {
 	u64 spte;
 	int ret = 0;
@@ -1723,6 +1777,8 @@ static int set_spte(struct kvm_vcpu *vcp
 				spte &= ~PT_WRITABLE_MASK;
 		}
 	}
+	if (reset_host_protection)
+		spte |= SPTE_HOST_WRITEABLE;
 
 	if (pte_access & ACC_WRITE_MASK)
 		mark_page_dirty(vcpu->kvm, gfn);
@@ -1736,7 +1792,8 @@ static void mmu_set_spte(struct kvm_vcpu
 			 unsigned pt_access, unsigned pte_access,
 			 int user_fault, int write_fault, int dirty,
 			 int *ptwrite, int largepage, gfn_t gfn,
-			 pfn_t pfn, bool speculative)
+			 pfn_t pfn, bool speculative,
+             bool reset_host_protection)
 {
 	int was_rmapped = 0;
 	int was_writeble = is_writeble_pte(*shadow_pte);
@@ -1765,7 +1822,8 @@ static void mmu_set_spte(struct kvm_vcpu
 			was_rmapped = 1;
 	}
 	if (set_spte(vcpu, shadow_pte, pte_access, user_fault, write_fault,
-		      dirty, largepage, gfn, pfn, speculative, true)) {
+		      dirty, largepage, gfn, pfn, speculative, true,
+              reset_host_protection)) {
 		if (write_fault)
 			*ptwrite = 1;
 		kvm_x86_ops->tlb_flush(vcpu);
@@ -1782,8 +1840,7 @@ static void mmu_set_spte(struct kvm_vcpu
 	page_header_update_slot(vcpu->kvm, shadow_pte, gfn);
 	if (!was_rmapped) {
 		rmap_add(vcpu, shadow_pte, gfn, largepage);
-		if (!is_rmap_pte(*shadow_pte))
-			kvm_release_pfn_clean(pfn);
+		kvm_release_pfn_clean(pfn);
 	} else {
 		if (was_writeble)
 			kvm_release_pfn_dirty(pfn);
@@ -1813,7 +1870,7 @@ static int __direct_map(struct kvm_vcpu 
 		    || (largepage && iterator.level == PT_DIRECTORY_LEVEL)) {
 			mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, ACC_ALL,
 				     0, write, 1, &pt_write,
-				     largepage, gfn, pfn, false);
+				     largepage, gfn, pfn, false, true);
 			++vcpu->stat.pf_fixed;
 			break;
 		}
--- linux-2.6.30.x86_64/arch/x86/kvm/paging_tmpl.h	2009-07-23 14:58:56.000000000 -0500
+++ linux-2.6.30.x86_64-ksm/arch/x86/kvm/paging_tmpl.h	2009-07-23 15:01:49.000000000 -0500
@@ -266,9 +266,13 @@ static void FNAME(update_pte)(struct kvm
 	if (mmu_notifier_retry(vcpu, vcpu->arch.update_pte.mmu_seq))
 		return;
 	kvm_get_pfn(pfn);
+    /*
+     * we call mmu_set_spte() with reset_host_protection = true beacuse that
+     * vcpu->arch.update_pte.pfn was fetched from get_user_pages(write = 1).
+     */ 
 	mmu_set_spte(vcpu, spte, page->role.access, pte_access, 0, 0,
 		     gpte & PT_DIRTY_MASK, NULL, largepage,
-		     gpte_to_gfn(gpte), pfn, true);
+		     gpte_to_gfn(gpte), pfn, true, true);
 }
 
 /*
@@ -302,7 +306,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu
 				     user_fault, write_fault,
 				     gw->ptes[gw->level-1] & PT_DIRTY_MASK,
 				     ptwrite, largepage,
-				     gw->gfn, pfn, false);
+				     gw->gfn, pfn, false, true);
 			break;
 		}
 
@@ -552,6 +556,7 @@ static void FNAME(prefetch_page)(struct 
 static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
 {
 	int i, offset, nr_present;
+        bool reset_host_protection = 1;
 
 	offset = nr_present = 0;
 
@@ -589,9 +594,13 @@ static int FNAME(sync_page)(struct kvm_v
 
 		nr_present++;
 		pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte);
+        if (!(sp->spt[i] & SPTE_HOST_WRITEABLE)) {
+            pte_access &= ~PT_WRITABLE_MASK;
+                         reset_host_protection = 0;
+                } else { reset_host_protection = 1; }
 		set_spte(vcpu, &sp->spt[i], pte_access, 0, 0,
 			 is_dirty_pte(gpte), 0, gfn,
-			 spte_to_pfn(sp->spt[i]), true, false);
+			 spte_to_pfn(sp->spt[i]), true, false, reset_host_protection);
 	}
 
 	return !nr_present;
--- linux-2.6.30.x86_64/virt/kvm/kvm_main.c	2009-07-23 14:58:58.000000000 -0500
+++ linux-2.6.30.x86_64-ksm/virt/kvm/kvm_main.c	2009-07-23 15:00:04.000000000 -0500
@@ -859,6 +859,19 @@ static void kvm_mmu_notifier_invalidate_
 
 }
 
+static void kvm_mmu_notifier_change_pte(struct mmu_notifier *mn,
+					struct mm_struct *mm,
+					unsigned long address,
+					pte_t pte)
+{
+	struct kvm *kvm = mmu_notifier_to_kvm(mn);
+
+	spin_lock(&kvm->mmu_lock);
+	kvm->mmu_notifier_seq++;
+	kvm_set_spte_hva(kvm, address, pte);
+	spin_unlock(&kvm->mmu_lock);
+}
+
 static void kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
 						    struct mm_struct *mm,
 						    unsigned long start,
@@ -938,6 +951,7 @@ static const struct mmu_notifier_ops kvm
 	.invalidate_range_start	= kvm_mmu_notifier_invalidate_range_start,
 	.invalidate_range_end	= kvm_mmu_notifier_invalidate_range_end,
 	.clear_flush_young	= kvm_mmu_notifier_clear_flush_young,
+	.change_pte		= kvm_mmu_notifier_change_pte,
 	.release		= kvm_mmu_notifier_release,
 };
 #endif /* CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER */

linux-2.6-ksm.patch:
 b/arch/alpha/include/asm/mman.h     |    3 
 b/arch/mips/include/asm/mman.h      |    3 
 b/arch/parisc/include/asm/mman.h    |    3 
 b/arch/xtensa/include/asm/mman.h    |    3 
 b/fs/proc/page.c                    |    5 
 b/include/asm-generic/mman-common.h |    5 
 b/include/linux/ksm.h               |   50 +
 b/include/linux/mm.h                |    1 
 b/include/linux/mmu_notifier.h      |   34 
 b/include/linux/rmap.h              |    6 
 b/include/linux/sched.h             |    7 
 b/kernel/fork.c                     |    8 
 b/mm/Kconfig                        |   11 
 b/mm/Makefile                       |    1 
 b/mm/ksm.c                          |   56 +
 b/mm/madvise.c                      |   41 
 b/mm/memory.c                       |    9 
 b/mm/mmu_notifier.c                 |   22 
 b/mm/mremap.c                       |   14 
 b/mm/rmap.c                         |   23 
 include/linux/ksm.h                 |   29 
 mm/ksm.c                            | 1506 +++++++++++++++++++++++++++++++++++-
 mm/madvise.c                        |   16 
 mm/memory.c                         |    7 
 24 files changed, 1780 insertions(+), 83 deletions(-)

--- NEW FILE linux-2.6-ksm.patch ---
From: Izik Eidus <ieidus at redhat.com>
Subject: [PATCH 01/10] ksm: add mmu_notifier set_pte_at_notify()
Date: 	Fri, 17 Jul 2009 20:30:41 +0300

The set_pte_at_notify() macro allows setting a pte in the shadow page
table directly, instead of flushing the shadow page table entry and then
getting vmexit to set it.  It uses a new change_pte() callback to do so.

set_pte_at_notify() is an optimization for kvm, and other users of
mmu_notifiers, for COW pages.  It is useful for kvm when ksm is used,
because it allows kvm not to have to receive vmexit and only then map
the ksm page into the shadow page table, but instead map it directly
at the same time as Linux maps the page into the host page table.

Users of mmu_notifiers who don't implement new mmu_notifier_change_pte()
callback will just receive the mmu_notifier_invalidate_page() callback.

Signed-off-by: Izik Eidus <ieidus at redhat.com>
Signed-off-by: Chris Wright <chrisw at redhat.com>
Signed-off-by: Hugh Dickins <hugh.dickins at tiscali.co.uk>
---
 include/linux/mmu_notifier.h |   34 ++++++++++++++++++++++++++++++++++
 mm/memory.c                  |    9 +++++++--
 mm/mmu_notifier.c            |   20 ++++++++++++++++++++
 3 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h
index b77486d..4e02ee2 100644
--- a/include/linux/mmu_notifier.h
+++ b/include/linux/mmu_notifier.h
@@ -62,6 +62,15 @@ struct mmu_notifier_ops {
 				 unsigned long address);
 
 	/*
+	 * change_pte is called in cases that pte mapping to page is changed:
+	 * for example, when ksm remaps pte to point to a new shared page.
+	 */
+	void (*change_pte)(struct mmu_notifier *mn,
+			   struct mm_struct *mm,
+			   unsigned long address,
+			   pte_t pte);
+
+	/*
 	 * Before this is invoked any secondary MMU is still ok to
 	 * read/write to the page previously pointed to by the Linux
 	 * pte because the page hasn't been freed yet and it won't be
@@ -154,6 +163,8 @@ extern void __mmu_notifier_mm_destroy(struct mm_struct *mm);
 extern void __mmu_notifier_release(struct mm_struct *mm);
 extern int __mmu_notifier_clear_flush_young(struct mm_struct *mm,
 					  unsigned long address);
+extern void __mmu_notifier_change_pte(struct mm_struct *mm,
+				      unsigned long address, pte_t pte);
 extern void __mmu_notifier_invalidate_page(struct mm_struct *mm,
 					  unsigned long address);
 extern void __mmu_notifier_invalidate_range_start(struct mm_struct *mm,
@@ -175,6 +186,13 @@ static inline int mmu_notifier_clear_flush_young(struct mm_struct *mm,
 	return 0;
 }
 
+static inline void mmu_notifier_change_pte(struct mm_struct *mm,
+					   unsigned long address, pte_t pte)
+{
+	if (mm_has_notifiers(mm))
+		__mmu_notifier_change_pte(mm, address, pte);
+}
+
 static inline void mmu_notifier_invalidate_page(struct mm_struct *mm,
 					  unsigned long address)
 {
@@ -236,6 +254,16 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm)
 	__young;							\
 })
 
+#define set_pte_at_notify(__mm, __address, __ptep, __pte)		\
+({									\
+	struct mm_struct *___mm = __mm;					\
+	unsigned long ___address = __address;				\
+	pte_t ___pte = __pte;						\
+									\
+	set_pte_at(___mm, ___address, __ptep, ___pte);			\
+	mmu_notifier_change_pte(___mm, ___address, ___pte);		\
+})
+
 #else /* CONFIG_MMU_NOTIFIER */
 
 static inline void mmu_notifier_release(struct mm_struct *mm)
@@ -248,6 +276,11 @@ static inline int mmu_notifier_clear_flush_young(struct mm_struct *mm,
 	return 0;
 }
 
+static inline void mmu_notifier_change_pte(struct mm_struct *mm,
+					   unsigned long address, pte_t pte)
+{
+}
+
 static inline void mmu_notifier_invalidate_page(struct mm_struct *mm,
 					  unsigned long address)
 {
@@ -273,6 +306,7 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm)
 
 #define ptep_clear_flush_young_notify ptep_clear_flush_young
 #define ptep_clear_flush_notify ptep_clear_flush
+#define set_pte_at_notify set_pte_at
 
 #endif /* CONFIG_MMU_NOTIFIER */
 
diff --git a/mm/memory.c b/mm/memory.c
index 6521619..8159a62 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2113,9 +2113,14 @@ gotten:
 		 * seen in the presence of one thread doing SMC and another
 		 * thread doing COW.
 		 */
-		ptep_clear_flush_notify(vma, address, page_table);
+		ptep_clear_flush(vma, address, page_table);
 		page_add_new_anon_rmap(new_page, vma, address);
-		set_pte_at(mm, address, page_table, entry);
+		/*
+		 * We call the notify macro here because, when using secondary
+		 * mmu page tables (such as kvm shadow page tables), we want the
+		 * new page to be mapped directly into the secondary page table.
+		 */
+		set_pte_at_notify(mm, address, page_table, entry);
 		update_mmu_cache(vma, address, entry);
 		if (old_page) {
 			/*
diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c
index 5f4ef02..7e33f2c 100644
--- a/mm/mmu_notifier.c
+++ b/mm/mmu_notifier.c
@@ -99,6 +99,26 @@ int __mmu_notifier_clear_flush_young(struct mm_struct *mm,
 	return young;
 }
 
+void __mmu_notifier_change_pte(struct mm_struct *mm, unsigned long address,
+			       pte_t pte)
+{
+	struct mmu_notifier *mn;
+	struct hlist_node *n;
+
+	rcu_read_lock();
+	hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) {
+		if (mn->ops->change_pte)
+			mn->ops->change_pte(mn, mm, address, pte);
+		/*
+		 * Some drivers don't have change_pte,
+		 * so we must call invalidate_page in that case.
+		 */
+		else if (mn->ops->invalidate_page)
+			mn->ops->invalidate_page(mn, mm, address);
+	}
+	rcu_read_unlock();
+}
+
 void __mmu_notifier_invalidate_page(struct mm_struct *mm,
 					  unsigned long address)
 {
-- 
1.5.6.5

--

From: Izik Eidus <ieidus at redhat.com>
Subject: [PATCH 02/10] ksm: first tidy up madvise_vma()
Date: 	Fri, 17 Jul 2009 20:30:42 +0300

madvise.c has several levels of switch statements, what to do in which?
Move MADV_DOFORK code down from madvise_vma() to madvise_behavior(), so
madvise_vma() can be a simple router, to madvise_behavior() by default.

vma->vm_flags is an unsigned long so use the same type for new_flags.
Add missing comment lines to describe MADV_DONTFORK and MADV_DOFORK.

Signed-off-by: Hugh Dickins <hugh.dickins at tiscali.co.uk>
Signed-off-by: Chris Wright <chrisw at redhat.com>
Signed-off-by: Izik Eidus <ieidus at redhat.com>
---
 mm/madvise.c |   39 +++++++++++++--------------------------
 1 files changed, 13 insertions(+), 26 deletions(-)

diff --git a/mm/madvise.c b/mm/madvise.c
index 76eb419..66c3126 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -41,7 +41,7 @@ static long madvise_behavior(struct vm_area_struct * vma,
 	struct mm_struct * mm = vma->vm_mm;
 	int error = 0;
 	pgoff_t pgoff;
-	int new_flags = vma->vm_flags;
+	unsigned long new_flags = vma->vm_flags;
 
 	switch (behavior) {
 	case MADV_NORMAL:
@@ -57,6 +57,10 @@ static long madvise_behavior(struct vm_area_struct * vma,
 		new_flags |= VM_DONTCOPY;
 		break;
 	case MADV_DOFORK:
+		if (vma->vm_flags & VM_IO) {
[...2246 lines suppressed...]
+	unsigned long nr_pages;
+
+	err = strict_strtoul(buf, 10, &nr_pages);
+	if (err)
+		return -EINVAL;
+
+	ksm_max_kernel_pages = nr_pages;
+
+	return count;
+}
+
+static ssize_t max_kernel_pages_show(struct kobject *kobj,
+				     struct kobj_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%lu\n", ksm_max_kernel_pages);
+}
+KSM_ATTR(max_kernel_pages);
+
+static struct attribute *ksm_attrs[] = {
+	&sleep_millisecs_attr.attr,
+	&pages_to_scan_attr.attr,
+	&run_attr.attr,
+	&pages_shared_attr.attr,
+	&kernel_pages_allocated_attr.attr,
+	&max_kernel_pages_attr.attr,
+	NULL,
+};
+
+static struct attribute_group ksm_attr_group = {
+	.attrs = ksm_attrs,
+	.name = "ksm",
+};
+
+static int __init ksm_init(void)
+{
+	struct task_struct *ksm_thread;
+	int err;
+
+	err = ksm_slab_init();
+	if (err)
+		goto out;
+
+	err = mm_slots_hash_init();
+	if (err)
+		goto out_free1;
+
+	ksm_thread = kthread_run(ksm_scan_thread, NULL, "ksmd");
+	if (IS_ERR(ksm_thread)) {
+		printk(KERN_ERR "ksm: creating kthread failed\n");
+		err = PTR_ERR(ksm_thread);
+		goto out_free2;
+	}
+
+	err = sysfs_create_group(mm_kobj, &ksm_attr_group);
+	if (err) {
+		printk(KERN_ERR "ksm: register sysfs failed\n");
+		goto out_free3;
+	}
+
+	return 0;
+
+out_free3:
+	kthread_stop(ksm_thread);
+out_free2:
+	mm_slots_hash_free();
+out_free1:
+	ksm_slab_free();
+out:
+	return err;
 }
+module_init(ksm_init)
-- 
1.5.6.5

--
From: Izik Eidus <ieidus at redhat.com>
Subject: [PATCH 08/10] ksm: prevent mremap move poisoning
Date: 	Fri, 17 Jul 2009 20:30:48 +0300

KSM's scan allows for user pages to be COWed or unmapped at any time,
without requiring any notification.  But its stable tree does assume
that when it finds a KSM page where it placed a KSM page, then it is
the same KSM page that it placed there.

mremap move could break that assumption: if an area containing a KSM
page was unmapped, then an area containing a different KSM page was
moved with mremap into the place of the original, before KSM's scan
came around to notice.  That could then poison a node of the stable
tree, so that memcmps would "lie" and upset the ordering of the tree.

Probably noone will ever need mremap move on a VM_MERGEABLE area;
except that prohibiting it would make trouble for schemes in which we
try making everything VM_MERGEABLE e.g. for testing: an mremap which
normally works would then fail mysteriously.

There's no need to go to any trouble, such as re-sorting KSM's list of
rmap_items to match the new layout: simply unmerge the area to COW all
its KSM pages before moving, but leave VM_MERGEABLE on so that they're
remerged later.

Signed-off-by: Hugh Dickins <hugh.dickins at tiscali.co.uk>
Signed-off-by: Chris Wright <chrisw at redhat.com>
Signed-off-by: Izik Eidus <ieidus at redhat.com>
---
 mm/mremap.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/mm/mremap.c b/mm/mremap.c
index a39b7b9..93addde 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -11,6 +11,7 @@
 #include <linux/hugetlb.h>
 #include <linux/slab.h>
 #include <linux/shm.h>
+#include <linux/ksm.h>
 #include <linux/mman.h>
 #include <linux/swap.h>
 #include <linux/capability.h>
@@ -182,6 +183,17 @@ static unsigned long move_vma(struct vm_area_struct *vma,
 	if (mm->map_count >= sysctl_max_map_count - 3)
 		return -ENOMEM;
 
+	/*
+	 * Advise KSM to break any KSM pages in the area to be moved:
+	 * it would be confusing if they were to turn up at the new
+	 * location, where they happen to coincide with different KSM
+	 * pages recently unmapped.  But leave vma->vm_flags as it was,
+	 * so KSM can come around to merge on vma and new_vma afterwards.
+	 */
+	if (ksm_madvise(vma, old_addr, old_addr + old_len,
+						MADV_UNMERGEABLE, &vm_flags))
+		return -ENOMEM;
+
 	new_pgoff = vma->vm_pgoff + ((old_addr - vma->vm_start) >> PAGE_SHIFT);
 	new_vma = copy_vma(&vma, new_addr, new_len, new_pgoff);
 	if (!new_vma)
-- 
1.5.6.5

--
From: Izik Eidus <ieidus at redhat.com>
Subject: [PATCH 09/10] ksm: change copyright message
Date: 	Fri, 17 Jul 2009 20:30:49 +0300

Adding Hugh Dickins into the authors list.

Signed-off-by: Izik Eidus <ieidus at redhat.com>
---
 mm/ksm.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/mm/ksm.c b/mm/ksm.c
index a0fbdb2..75d7802 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -4,11 +4,12 @@
  * This code enables dynamic sharing of identical pages found in different
  * memory areas, even if they are not shared by fork()
  *
- * Copyright (C) 2008 Red Hat, Inc.
+ * Copyright (C) 2008-2009 Red Hat, Inc.
  * Authors:
  *	Izik Eidus
  *	Andrea Arcangeli
  *	Chris Wright
+ *	Hugh Dickins
  *
  * This work is licensed under the terms of the GNU GPL, version 2.
  */
-- 
1.5.6.5

--
From: Izik Eidus <ieidus at redhat.com>
Subject: [PATCH 10/10] ksm: change ksm nice level to be 5
Date: 	Fri, 17 Jul 2009 20:30:50 +0300

ksm should try not to disturb other tasks as much as possible.

Signed-off-by: Izik Eidus <ieidus at redhat.com>
---
 mm/ksm.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/mm/ksm.c b/mm/ksm.c
index 75d7802..4afe345 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1270,7 +1270,7 @@ static void ksm_do_scan(unsigned int scan_npages)
 
 static int ksm_scan_thread(void *nothing)
 {
-	set_user_nice(current, 0);
+	set_user_nice(current, 5);
 
 	while (!kthread_should_stop()) {
 		if (ksm_run & KSM_RUN_MERGE) {
-- 
1.5.6.5

linux-2.6-ppc-perfctr-oops-fix.patch:
 mpc7450-pmu.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- NEW FILE linux-2.6-ppc-perfctr-oops-fix.patch ---
diff --git a/arch/powerpc/kernel/mpc7450-pmu.c b/arch/powerpc/kernel/mpc7450-pmu.c
index 75ff47f..ea383c1 100644
--- a/arch/powerpc/kernel/mpc7450-pmu.c
+++ b/arch/powerpc/kernel/mpc7450-pmu.c
@@ -408,7 +408,8 @@ struct power_pmu mpc7450_pmu = {
 
 static int init_mpc7450_pmu(void)
 {
-	if (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc/7450"))
+	if (cur_cpu_spec->oprofile_cpu_type &&
+	    strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc/7450"))
 		return -ENODEV;
 
 	return register_power_pmu(&mpc7450_pmu);

linux-2.6-qcserial-autosuspend.diff:
 qcserial.c |    2 ++
 1 file changed, 2 insertions(+)

--- NEW FILE linux-2.6-qcserial-autosuspend.diff ---
commit b2bcfa17349e5a6a01170b5269ee261dbd762a0c
Author: Matthew Garrett <mjg at redhat.com>
Date:   Sat Jul 18 14:43:36 2009 +0100

    usb: enable autosuspend by default on qcserial
    
    All qcserial hardware supports autosuspend properly. Enable it by default.
    
    Signed-off-by: Matthew Garrett <mjg at redhat.com>

diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 7528b8d..959a176 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -74,6 +74,8 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 	ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
 	dbg("This Interface = %d", ifnum);
 
+	usb_device_autosuspend_enable(serial->dev);
+
 	switch (nintf) {
 	case 1:
 		/* QDL mode */

linux-2.6-usb-uvc-autosuspend.diff:
 uvc_driver.c |    2 ++
 1 file changed, 2 insertions(+)

--- NEW FILE linux-2.6-usb-uvc-autosuspend.diff ---
commit 9d4c919bcfa794c054cc33155c7e3c53ac2c5684
Author: Matthew Garrett <mjg at redhat.com>
Date:   Sun Jul 19 02:24:49 2009 +0100

    Enable autosuspend on UVC by default

diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 89927b7..8de516b 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1647,6 +1647,8 @@ static int uvc_probe(struct usb_interface *intf,
 			"supported.\n", ret);
 	}
 
+	usb_device_autosuspend_enable(udev);
+
 	uvc_trace(UVC_TRACE_PROBE, "UVC device initialized.\n");
 	return 0;
 

linux-2.6-vga-arb.patch:
 drivers/gpu/Makefile     |    2 
 drivers/gpu/vga/Kconfig  |   10 
 drivers/gpu/vga/Makefile |    1 
 drivers/gpu/vga/vgaarb.c | 1195 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/pci/pci.c        |   44 +
 drivers/video/Kconfig    |    2 
 include/linux/pci.h      |    2 
 include/linux/vgaarb.h   |  196 +++++++
 8 files changed, 1450 insertions(+), 2 deletions(-)

--- NEW FILE linux-2.6-vga-arb.patch ---
>From a00c47b3e783fe9ebb871071d2472387451d9225 Mon Sep 17 00:00:00 2001
From: Tiago Vignatti <tiago.vignatti at nokia.com>
Date: Tue, 14 Jul 2009 15:57:29 +0300
Subject: [PATCH] vga: implements VGA arbitration on Linux

changes since last patch:
fix up so the arb doesn't turn off vga decodes
on hw until first used. This worksaround an
X.org problem with older X servers which fail
at detecting boot device if doesn't have the VGA
bit enabled. Newer pciacccess + X server fix this.
add default processing
use hex for the target API to match the output API
balance pci get/put
use the decodes count for userspace to get card
count also if a gpu disables decodes move it to
the next card

Signed-off-by: Tiago Vignatti <tiago.vignatti at nokia.com>
---
 drivers/gpu/Makefile     |    2 +-
 drivers/gpu/vga/Kconfig  |   10 +
 drivers/gpu/vga/Makefile |    1 +
 drivers/gpu/vga/vgaarb.c | 1195 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/pci/pci.c        |   44 ++
 drivers/video/Kconfig    |    2 +
 include/linux/pci.h      |    2 +
 include/linux/vgaarb.h   |  195 ++++++++
 8 files changed, 1450 insertions(+), 1 deletions(-)
 create mode 100644 drivers/gpu/vga/Kconfig
 create mode 100644 drivers/gpu/vga/Makefile
 create mode 100644 drivers/gpu/vga/vgaarb.c
 create mode 100644 include/linux/vgaarb.h

diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index de566cf..30879df 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -1 +1 @@
-obj-y			+= drm/
+obj-y			+= drm/ vga/
diff --git a/drivers/gpu/vga/Kconfig b/drivers/gpu/vga/Kconfig
new file mode 100644
index 0000000..790e675
--- /dev/null
+++ b/drivers/gpu/vga/Kconfig
@@ -0,0 +1,10 @@
+config VGA_ARB
+	bool "VGA Arbitration" if EMBEDDED
+	default y
+	depends on PCI
+	help
+	  Some "legacy" VGA devices implemented on PCI typically have the same
+	  hard-decoded addresses as they did on ISA. When multiple PCI devices
+	  are accessed at same time they need some kind of coordination. Please
+	  see Documentation/vgaarbiter.txt for more details. Select this to
+	  enable VGA arbiter.
diff --git a/drivers/gpu/vga/Makefile b/drivers/gpu/vga/Makefile
new file mode 100644
index 0000000..7cc8c1e
--- /dev/null
+++ b/drivers/gpu/vga/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VGA_ARB)  += vgaarb.o
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
new file mode 100644
index 0000000..08ba44d
--- /dev/null
+++ b/drivers/gpu/vga/vgaarb.c
@@ -0,0 +1,1195 @@
+/*
+ * vgaarb.c
+ *
+ * (C) Copyright 2005 Benjamin Herrenschmidt <benh at kernel.crashing.org>
+ * (C) Copyright 2007 Paulo R. Zanoni <przanoni at gmail.com>
+ * (C) Copyright 2007, 2009 Tiago Vignatti <vignatti at freedesktop.org>
+ *
+ * Implements the VGA arbitration. For details refer to
+ * Documentation/vgaarbiter.txt
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+
+#include <linux/uaccess.h>
+
+#include <linux/vgaarb.h>
+
+static void vga_arbiter_notify_clients(void);
+/*
+ * We keep a list of all vga devices in the system to speed
+ * up the various operations of the arbiter
+ */
+struct vga_device {
+	struct list_head list;
+	struct pci_dev *pdev;
+	unsigned int decodes;	/* what does it decodes */
+	unsigned int owns;	/* what does it owns */
+	unsigned int locks;	/* what does it locks */
+	unsigned int io_lock_cnt;	/* legacy IO lock count */
+	unsigned int mem_lock_cnt;	/* legacy MEM lock count */
+	unsigned int io_norm_cnt;	/* normal IO count */
+	unsigned int mem_norm_cnt;	/* normal MEM count */
+
+	/* allow IRQ enable/disable hook */
+	void *cookie;
+	void (*irq_set_state)(void *cookie, bool enable);
+	unsigned int (*set_vga_decode)(void *cookie, bool decode);
+};
+
+static LIST_HEAD(vga_list);
+static int vga_count, vga_decode_count;
+static bool vga_arbiter_used;
+static DEFINE_SPINLOCK(vga_lock);
+static DECLARE_WAIT_QUEUE_HEAD(vga_wait_queue);
+
+
+static const char *vga_iostate_to_str(unsigned int iostate)
+{
+	/* Ignore VGA_RSRC_IO and VGA_RSRC_MEM */
+	iostate &= VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM;
+	switch (iostate) {
+	case VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM:
+		return "io+mem";
+	case VGA_RSRC_LEGACY_IO:
+		return "io";
+	case VGA_RSRC_LEGACY_MEM:
+		return "mem";
+	}
+	return "none";
+}
+
+static int vga_str_to_iostate(char *buf, int str_size, int *io_state)
+{
+	/* we could in theory hand out locks on IO and mem
+	 * separately to userspace but it can cause deadlocks */
+	if (strncmp(buf, "none", 4) == 0) {
+		*io_state = VGA_RSRC_NONE;
+		return 1;
+	}
+
+	/* XXX We're not chekcing the str_size! */
+	if (strncmp(buf, "io+mem", 6) == 0)
+		goto both;
+	else if (strncmp(buf, "io", 2) == 0)
+		goto both;
+	else if (strncmp(buf, "mem", 3) == 0)
+		goto both;
+	return 0;
+both:
+	*io_state = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM;
+	return 1;
+}
+
+#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE
+/* this is only used a cookie - it should not be dereferenced */
+static struct pci_dev *vga_default;
+#endif
+
+static void vga_arb_device_card_gone(struct pci_dev *pdev);
+
+/* Find somebody in our list */
+static struct vga_device *vgadev_find(struct pci_dev *pdev)
+{
+	struct vga_device *vgadev;
+
+	list_for_each_entry(vgadev, &vga_list, list)
+		if (pdev == vgadev->pdev)
+			return vgadev;
+	return NULL;
+}
+
+/* Returns the default VGA device (vgacon's babe) */
+#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE
+struct pci_dev *vga_default_device(void)
+{
+	return vga_default;
+}
+#endif
+
+static inline void vga_irq_set_state(struct vga_device *vgadev, bool state)
+{
+	if (vgadev->irq_set_state)
+		vgadev->irq_set_state(vgadev->cookie, state);
+}
+
+
+/* If we don't ever use VGA arb we should avoid
+   turning off anything anywhere due to old X servers getting
+   confused about the boot device not being VGA */
+static void vga_check_first_use(void)
+{
+	/* we should inform all GPUs in the system that
+	 * VGA arb has occured and to try and disable resources
+	 * if they can */
+	if (!vga_arbiter_used) {
+		vga_arbiter_used = true;
+		vga_arbiter_notify_clients();
+	}
+}
+
+static struct vga_device *__vga_tryget(struct vga_device *vgadev,
+				       unsigned int rsrc)
+{
+	unsigned int wants, legacy_wants, match;
+	struct vga_device *conflict;
+	unsigned int pci_bits;
+	/* Account for "normal" resources to lock. If we decode the legacy,
+	 * counterpart, we need to request it as well
+	 */
+	if ((rsrc & VGA_RSRC_NORMAL_IO) &&
+	    (vgadev->decodes & VGA_RSRC_LEGACY_IO))
+		rsrc |= VGA_RSRC_LEGACY_IO;
+	if ((rsrc & VGA_RSRC_NORMAL_MEM) &&
+	    (vgadev->decodes & VGA_RSRC_LEGACY_MEM))
+		rsrc |= VGA_RSRC_LEGACY_MEM;
+
+	pr_devel("%s: %d\n", __func__, rsrc);
+	pr_devel("%s: owns: %d\n", __func__, vgadev->owns);
+
+	/* Check what resources we need to acquire */
+	wants = rsrc & ~vgadev->owns;
+
+	/* We already own everything, just mark locked & bye bye */
+	if (wants == 0)
+		goto lock_them;
+
+	/* We don't need to request a legacy resource, we just enable
+	 * appropriate decoding and go
+	 */
+	legacy_wants = wants & VGA_RSRC_LEGACY_MASK;
+	if (legacy_wants == 0)
+		goto enable_them;
+
+	/* Ok, we don't, let's find out how we need to kick off */
+	list_for_each_entry(conflict, &vga_list, list) {
+		unsigned int lwants = legacy_wants;
+		unsigned int change_bridge = 0;
+
+		/* Don't conflict with myself */
+		if (vgadev == conflict)
+			continue;
+
+		/* Check if the architecture allows a conflict between those
+		 * 2 devices or if they are on separate domains
+		 */
+		if (!vga_conflicts(vgadev->pdev, conflict->pdev))
+			continue;
+
+		/* We have a possible conflict. before we go further, we must
+		 * check if we sit on the same bus as the conflicting device.
+		 * if we don't, then we must tie both IO and MEM resources
+		 * together since there is only a single bit controlling
+		 * VGA forwarding on P2P bridges
+		 */
+		if (vgadev->pdev->bus != conflict->pdev->bus) {
+			change_bridge = 1;
+			lwants = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM;
+		}
+
+		/* Check if the guy has a lock on the resource. If he does,
+		 * return the conflicting entry
+		 */
+		if (conflict->locks & lwants)
+			return conflict;
+
+		/* Ok, now check if he owns the resource we want. We don't need
+		 * to check "decodes" since it should be impossible to own
+		 * own legacy resources you don't decode unless I have a bug
+		 * in this code...
+		 */
+		WARN_ON(conflict->owns & ~conflict->decodes);
+		match = lwants & conflict->owns;
+		if (!match)
+			continue;
+
+		/* looks like he doesn't have a lock, we can steal
+		 * them from him
+		 */
+		vga_irq_set_state(conflict, false);
+
+		pci_bits = 0;
+		if (lwants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM))
+			pci_bits |= PCI_COMMAND_MEMORY;
+		if (lwants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO))
+			pci_bits |= PCI_COMMAND_IO;
+
+		pci_set_vga_state(conflict->pdev, false, pci_bits,
+				  change_bridge);
+		conflict->owns &= ~lwants;
+		/* If he also owned non-legacy, that is no longer the case */
+		if (lwants & VGA_RSRC_LEGACY_MEM)
+			conflict->owns &= ~VGA_RSRC_NORMAL_MEM;
+		if (lwants & VGA_RSRC_LEGACY_IO)
+			conflict->owns &= ~VGA_RSRC_NORMAL_IO;
+	}
+
+enable_them:
+	/* ok dude, we got it, everybody conflicting has been disabled, let's
+	 * enable us. Make sure we don't mark a bit in "owns" that we don't
+	 * also have in "decodes". We can lock resources we don't decode but
+	 * not own them.
+	 */
+	pci_bits = 0;
+	if (wants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM))
+		pci_bits |= PCI_COMMAND_MEMORY;
+	if (wants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO))
+		pci_bits |= PCI_COMMAND_IO;
+	pci_set_vga_state(vgadev->pdev, true, pci_bits, !!(wants & VGA_RSRC_LEGACY_MASK));
+
+	vga_irq_set_state(vgadev, true);
+	vgadev->owns |= (wants & vgadev->decodes);
+lock_them:
+	vgadev->locks |= (rsrc & VGA_RSRC_LEGACY_MASK);
+	if (rsrc & VGA_RSRC_LEGACY_IO)
+		vgadev->io_lock_cnt++;
+	if (rsrc & VGA_RSRC_LEGACY_MEM)
+		vgadev->mem_lock_cnt++;
+	if (rsrc & VGA_RSRC_NORMAL_IO)
+		vgadev->io_norm_cnt++;
+	if (rsrc & VGA_RSRC_NORMAL_MEM)
+		vgadev->mem_norm_cnt++;
+
+	return NULL;
+}
+
+static void __vga_put(struct vga_device *vgadev, unsigned int rsrc)
+{
+	unsigned int old_locks = vgadev->locks;
+
+	pr_devel("%s\n", __func__);
+
+	/* Update our counters, and account for equivalent legacy resources
+	 * if we decode them
+	 */
+	if ((rsrc & VGA_RSRC_NORMAL_IO) && vgadev->io_norm_cnt > 0) {
+		vgadev->io_norm_cnt--;
+		if (vgadev->decodes & VGA_RSRC_LEGACY_IO)
+			rsrc |= VGA_RSRC_LEGACY_IO;
+	}
+	if ((rsrc & VGA_RSRC_NORMAL_MEM) && vgadev->mem_norm_cnt > 0) {
+		vgadev->mem_norm_cnt--;
+		if (vgadev->decodes & VGA_RSRC_LEGACY_MEM)
+			rsrc |= VGA_RSRC_LEGACY_MEM;
+	}
+	if ((rsrc & VGA_RSRC_LEGACY_IO) && vgadev->io_lock_cnt > 0)
+		vgadev->io_lock_cnt--;
+	if ((rsrc & VGA_RSRC_LEGACY_MEM) && vgadev->mem_lock_cnt > 0)
+		vgadev->mem_lock_cnt--;
+
+	/* Just clear lock bits, we do lazy operations so we don't really
+	 * have to bother about anything else at this point
+	 */
+	if (vgadev->io_lock_cnt == 0)
+		vgadev->locks &= ~VGA_RSRC_LEGACY_IO;
+	if (vgadev->mem_lock_cnt == 0)
+		vgadev->locks &= ~VGA_RSRC_LEGACY_MEM;
+
+	/* Kick the wait queue in case somebody was waiting if we actually
+	 * released something
+	 */
+	if (old_locks != vgadev->locks)
+		wake_up_all(&vga_wait_queue);
+}
+
+int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible)
+{
+	struct vga_device *vgadev, *conflict;
+	unsigned long flags;
+	wait_queue_t wait;
+	int rc = 0;
+
+	vga_check_first_use();
+	/* The one who calls us should check for this, but lets be sure... */
+	if (pdev == NULL)
+		pdev = vga_default_device();
+	if (pdev == NULL)
+		return 0;
+
+	for (;;) {
+		spin_lock_irqsave(&vga_lock, flags);
+		vgadev = vgadev_find(pdev);
+		if (vgadev == NULL) {
+			spin_unlock_irqrestore(&vga_lock, flags);
+			rc = -ENODEV;
+			break;
+		}
+		conflict = __vga_tryget(vgadev, rsrc);
+		spin_unlock_irqrestore(&vga_lock, flags);
+		if (conflict == NULL)
+			break;
+
+
+		/* We have a conflict, we wait until somebody kicks the
+		 * work queue. Currently we have one work queue that we
+		 * kick each time some resources are released, but it would
+		 * be fairly easy to have a per device one so that we only
+		 * need to attach to the conflicting device
+		 */
+		init_waitqueue_entry(&wait, current);
+		add_wait_queue(&vga_wait_queue, &wait);
+		set_current_state(interruptible ?
+				  TASK_INTERRUPTIBLE :
+				  TASK_UNINTERRUPTIBLE);
+		if (signal_pending(current)) {
+			rc = -EINTR;
+			break;
+		}
+		schedule();
+		remove_wait_queue(&vga_wait_queue, &wait);
+		set_current_state(TASK_RUNNING);
+	}
+	return rc;
+}
+EXPORT_SYMBOL(vga_get);
+
+int vga_tryget(struct pci_dev *pdev, unsigned int rsrc)
+{
+	struct vga_device *vgadev;
+	unsigned long flags;
+	int rc = 0;
+
+	vga_check_first_use();
+
+	/* The one who calls us should check for this, but lets be sure... */
+	if (pdev == NULL)
+		pdev = vga_default_device();
+	if (pdev == NULL)
+		return 0;
+	spin_lock_irqsave(&vga_lock, flags);
+	vgadev = vgadev_find(pdev);
+	if (vgadev == NULL) {
+		rc = -ENODEV;
+		goto bail;
+	}
+	if (__vga_tryget(vgadev, rsrc))
+		rc = -EBUSY;
+bail:
+	spin_unlock_irqrestore(&vga_lock, flags);
+	return rc;
+}
+EXPORT_SYMBOL(vga_tryget);
+
+void vga_put(struct pci_dev *pdev, unsigned int rsrc)
+{
+	struct vga_device *vgadev;
+	unsigned long flags;
+
+	/* The one who calls us should check for this, but lets be sure... */
+	if (pdev == NULL)
+		pdev = vga_default_device();
+	if (pdev == NULL)
+		return;
+	spin_lock_irqsave(&vga_lock, flags);
+	vgadev = vgadev_find(pdev);
+	if (vgadev == NULL)
+		goto bail;
+	__vga_put(vgadev, rsrc);
+bail:
+	spin_unlock_irqrestore(&vga_lock, flags);
+}
+EXPORT_SYMBOL(vga_put);
+
+/*
+ * Currently, we assume that the "initial" setup of the system is
+ * not sane, that is we come up with conflicting devices and let
+ * the arbiter's client decides if devices decodes or not legacy
+ * things.
+ */
+static void vga_arbiter_add_pci_device(struct pci_dev *pdev)
+{
+	struct vga_device *vgadev;
+	unsigned long flags;
+	struct pci_bus *bus;
+	struct pci_dev *bridge;
+	u16 cmd;
+
+	/* Only deal with VGA class devices */
+	if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+		return;
+
+	/* Allocate structure */
+	vgadev = kmalloc(sizeof(struct vga_device), GFP_KERNEL);
+	if (vgadev == NULL) {
+		pr_err("vgaarb: failed to allocate pci device\n");
+		/* What to do on allocation failure ? For now, let's
+		 * just do nothing, I'm not sure there is anything saner
+		 * to be done
+		 */
+		return;
+	}
+
+	memset(vgadev, 0, sizeof(*vgadev));
+
+	/* Take lock & check for duplicates */
+	spin_lock_irqsave(&vga_lock, flags);
+	if (vgadev_find(pdev) != NULL) {
+		BUG_ON(1);
+		goto fail;
+	}
+	vgadev->pdev = pdev;
+
+	/* By default, assume we decode everything */
+	vgadev->decodes = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
+			  VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+
+	/* by default mark it as decoding */
+	vga_decode_count++;
+	/* Mark that we "own" resources based on our enables, we will
+	 * clear that below if the bridge isn't forwarding
+	 */
+	pci_read_config_word(pdev, PCI_COMMAND, &cmd);
+	if (cmd & PCI_COMMAND_IO)
+		vgadev->owns |= VGA_RSRC_LEGACY_IO;
+	if (cmd & PCI_COMMAND_MEMORY)
+		vgadev->owns |= VGA_RSRC_LEGACY_MEM;
+
+	/* Check if VGA cycles can get down to us */
+	bus = pdev->bus;
+	while (bus) {
+		bridge = bus->self;
+		if (bridge) {
+			u16 l;
+			pci_read_config_word(bridge, PCI_BRIDGE_CONTROL,
+					     &l);
+			if (!(l & PCI_BRIDGE_CTL_VGA)) {
+				vgadev->owns = 0;
+				break;
+			}
+		}
+		bus = bus->parent;
+	}
+
+	/* Deal with VGA default device. Use first enabled one
+	 * by default if arch doesn't have it's own hook
+	 */
+#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE
+	if (vga_default == NULL &&
+	    ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK))
+		vga_default = pci_dev_get(pdev);
+#endif
+
+	/* Add to the list */
+	list_add(&vgadev->list, &vga_list);
+	vga_count++;
+	pr_info("vgaarb: device added: PCI:%s,decodes=%s,owns=%s,locks=%s\n",
+		pci_name(pdev),
+		vga_iostate_to_str(vgadev->decodes),
+		vga_iostate_to_str(vgadev->owns),
+		vga_iostate_to_str(vgadev->locks));
+
+	spin_unlock_irqrestore(&vga_lock, flags);
+	return;
+fail:
+	spin_unlock_irqrestore(&vga_lock, flags);
+	kfree(vgadev);
+}
+
+static void vga_arbiter_del_pci_device(struct pci_dev *pdev)
+{
+	struct vga_device *vgadev;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vga_lock, flags);
+	vgadev = vgadev_find(pdev);
+	if (vgadev == NULL)
+		goto bail;
+
+	if (vga_default == pdev) {
+		pci_dev_put(vga_default);
+		vga_default = NULL;
+	}
+
+	if (vgadev->decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM))
+		vga_decode_count--;
+
+	/* Remove entry from list */
+	list_del(&vgadev->list);
+	vga_count--;
+	/* Notify userland driver that the device is gone so it discards
+	 * it's copies of the pci_dev pointer
+	 */
+	vga_arb_device_card_gone(pdev);
+
+	/* Wake up all possible waiters */
+	wake_up_all(&vga_wait_queue);
+bail:
+	spin_unlock_irqrestore(&vga_lock, flags);
+	kfree(vgadev);
+}
+
+/* this is called with the lock */
+static inline void vga_update_device_decodes(struct vga_device *vgadev,
+					     int new_decodes)
+{
+	int old_decodes;
+	struct vga_device *new_vgadev, *conflict;
+
+	old_decodes = vgadev->decodes;
+	vgadev->decodes = new_decodes;
+
+	pr_info("vgaarb: device changed decodes: PCI:%s,olddecodes=%s,decodes=%s\n",
+		pci_name(vgadev->pdev),
+		vga_iostate_to_str(old_decodes),
+		vga_iostate_to_str(vgadev->decodes));
+
+	/* if we own the decodes we should move them along to
+	   another card */
+	if ((vgadev->owns & new_decodes) && (vga_count > 1)) {
+		vgadev->owns &= new_decodes;
+		list_for_each_entry(new_vgadev, &vga_list, list) {
+			if ((new_vgadev != vgadev) &&
+			    (new_vgadev->decodes & VGA_RSRC_LEGACY_MASK)) {
+				conflict = __vga_tryget(new_vgadev, VGA_RSRC_LEGACY_MASK);
+				if (!conflict)
+					__vga_put(new_vgadev, VGA_RSRC_LEGACY_MASK);
+				break;
+			}
+		}
+	}
+
+	/* change decodes counter */
+	if (old_decodes != new_decodes) {
+		if (new_decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM))
+			vga_decode_count++;
+		else
+			vga_decode_count--;
+	}
+}
+
+void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace)
+{
+	struct vga_device *vgadev;
+	unsigned long flags;
+
+	decodes &= VGA_RSRC_LEGACY_MASK;
+
+	spin_lock_irqsave(&vga_lock, flags);
+	vgadev = vgadev_find(pdev);
+	if (vgadev == NULL)
+		goto bail;
+
+	/* don't let userspace futz with kernel driver decodes */
+	if (userspace && vgadev->set_vga_decode)
+		goto bail;
+
+	/* update the device decodes + counter */
+	vga_update_device_decodes(vgadev, decodes);
+
+	/* XXX if somebody is going from "doesn't decode" to "decodes" state
+	 * here, additional care must be taken as we may have pending owner
+	 * ship of non-legacy region ...
+	 */
+bail:
+	spin_unlock_irqrestore(&vga_lock, flags);
+}
+
+void vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes)
+{
+	__vga_set_legacy_decoding(pdev, decodes, false);
+}
+EXPORT_SYMBOL(vga_set_legacy_decoding);
+
+/* return number of active VGA devices */
+/* call with NULL to unregister */
+int vga_client_register(struct pci_dev *pdev, void *cookie,
+			void (*irq_set_state)(void *cookie, bool state),
+			unsigned int (*set_vga_decode)(void *cookie, bool decode))
+{
+	int ret = -1;
+	struct vga_device *vgadev;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vga_lock, flags);
+	vgadev = vgadev_find(pdev);
+	if (!vgadev)
+		goto bail;
+
+	vgadev->irq_set_state = irq_set_state;
+	vgadev->set_vga_decode = set_vga_decode;
+	vgadev->cookie = cookie;
+	ret = 0;
+
+bail:
+	spin_unlock_irqrestore(&vga_lock, flags);
+	return ret;
+
+}
+EXPORT_SYMBOL(vga_client_register);
+
+/*
+ * Char driver implementation
+ *
+ * Semantics is:
+ *
+ *  open       : open user instance of the arbitrer. by default, it's
+ *                attached to the default VGA device of the system.
+ *
+ *  close      : close user instance, release locks
+ *
+ *  read       : return a string indicating the status of the target.
+ *                an IO state string is of the form {io,mem,io+mem,none},
+ *                mc and ic are respectively mem and io lock counts (for
+ *                debugging/diagnostic only). "decodes" indicate what the
+ *                card currently decodes, "owns" indicates what is currently
+ *                enabled on it, and "locks" indicates what is locked by this
+ *                card. If the card is unplugged, we get "invalid" then for
+ *                card_ID and an -ENODEV error is returned for any command
+ *                until a new card is targeted
+ *
+ *   "<card_ID>,decodes=<io_state>,owns=<io_state>,locks=<io_state> (ic,mc)"
+ *
+ * write       : write a command to the arbiter. List of commands is:
+ *
+ *   target <card_ID>   : switch target to card <card_ID> (see below)
+ *   lock <io_state>    : acquires locks on target ("none" is invalid io_state)
+ *   trylock <io_state> : non-blocking acquire locks on target
+ *   unlock <io_state>  : release locks on target
+ *   unlock all         : release all locks on target held by this user
+ *   decodes <io_state> : set the legacy decoding attributes for the card
+ *
+ * poll         : event if something change on any card (not just the target)
+ *
+ * card_ID is of the form "PCI:domain:bus:dev.fn". It can be set to "default"
+ * to go back to the system default card (TODO: not implemented yet).
+ * Currently, only PCI is supported as a prefix, but the userland API may
+ * support other bus types in the future, even if the current kernel
+ * implementation doesn't.
+ *
+ * Note about locks:
+ *
+ * The driver keeps track of which user has what locks on which card. It
+ * supports stacking, like the kernel one. This complexifies the implementation
+ * a bit, but makes the arbiter more tolerant to userspace problems and able
+ * to properly cleanup in all cases when a process dies.
+ * Currently, a max of 16 cards simultaneously can have locks issued from
+ * userspace for a given user (file descriptor instance) of the arbiter.
+ *
+ * If the device is hot-unplugged, there is a hook inside the module to notify
+ * they being added/removed in the system and automatically added/removed in
+ * the arbiter.
+ */
+
+#define MAX_USER_CARDS         16
+#define PCI_INVALID_CARD       ((struct pci_dev *)-1UL)
+
+/*
+ * Each user has an array of these, tracking which cards have locks
+ */
+struct vga_arb_user_card {
+	struct pci_dev *pdev;
+	unsigned int mem_cnt;
+	unsigned int io_cnt;
+};
+
+struct vga_arb_private {
+	struct list_head list;
+	struct pci_dev *target;
+	struct vga_arb_user_card cards[MAX_USER_CARDS];
+	spinlock_t lock;
+};
+
+static LIST_HEAD(vga_user_list);
+static DEFINE_SPINLOCK(vga_user_lock);
+
+
+/*
+ * This function gets a string in the format: "PCI:domain:bus:dev.fn" and
+ * returns the respective values. If the string is not in this format,
+ * it returns 0.
+ */
+static int vga_pci_str_to_vars(char *buf, int count, unsigned int *domain,
+			       unsigned int *bus, unsigned int *devfn)
+{
+	int n;
+	unsigned int slot, func;
+
+
+	n = sscanf(buf, "PCI:%x:%x:%x.%x", domain, bus, &slot, &func);
+	if (n != 4)
+		return 0;
+
+	*devfn = PCI_DEVFN(slot, func);
+
+	return 1;
+}
+
+static ssize_t vga_arb_read(struct file *file, char __user * buf,
+			    size_t count, loff_t *ppos)
+{
+	struct vga_arb_private *priv = file->private_data;
+	struct vga_device *vgadev;
+	struct pci_dev *pdev;
+	unsigned long flags;
+	size_t len;
+	int rc;
+	char *lbuf;
+
+	lbuf = kmalloc(1024, GFP_KERNEL);
+	if (lbuf == NULL)
+		return -ENOMEM;
+
+	/* Shields against vga_arb_device_card_gone (pci_dev going
+	 * away), and allows access to vga list
+	 */
+	spin_lock_irqsave(&vga_lock, flags);
+
+	/* If we are targetting the default, use it */
+	pdev = priv->target;
+	if (pdev == NULL || pdev == PCI_INVALID_CARD) {
+		spin_unlock_irqrestore(&vga_lock, flags);
+		len = sprintf(lbuf, "invalid");
+		goto done;
+	}
+
+	/* Find card vgadev structure */
+	vgadev = vgadev_find(pdev);
+	if (vgadev == NULL) {
+		/* Wow, it's not in the list, that shouldn't happen,
+		 * let's fix us up and return invalid card
+		 */
+		if (pdev == priv->target)
+			vga_arb_device_card_gone(pdev);
+		spin_unlock_irqrestore(&vga_lock, flags);
+		len = sprintf(lbuf, "invalid");
+		goto done;
+	}
+
+	/* Fill the buffer with infos */
+	len = snprintf(lbuf, 1024,
+		       "count:%d,PCI:%s,decodes=%s,owns=%s,locks=%s(%d:%d)\n",
+		       vga_decode_count, pci_name(pdev),
+		       vga_iostate_to_str(vgadev->decodes),
+		       vga_iostate_to_str(vgadev->owns),
+		       vga_iostate_to_str(vgadev->locks),
+		       vgadev->io_lock_cnt, vgadev->mem_lock_cnt);
+
+	spin_unlock_irqrestore(&vga_lock, flags);
+done:
+
+	/* Copy that to user */
+	if (len > count)
+		len = count;
+	rc = copy_to_user(buf, lbuf, len);
+	kfree(lbuf);
+	if (rc)
+		return -EFAULT;
+	return len;
+}
+
+/*
+ * TODO: To avoid parsing inside kernel and to improve the speed we may
+ * consider use ioctl here
+ */
+static ssize_t vga_arb_write(struct file *file, const char __user * buf,
+			     size_t count, loff_t *ppos)
+{
+	struct vga_arb_private *priv = file->private_data;
+	struct vga_arb_user_card *uc = NULL;
+	struct pci_dev *pdev;
+
+	unsigned int io_state;
+
+	char *kbuf, *curr_pos;
+	size_t remaining = count;
+
+	int ret_val;
+	int i;
+
+
+	kbuf = kmalloc(count + 1, GFP_KERNEL);
+	if (!kbuf)
+		return -ENOMEM;
+
+	if (copy_from_user(kbuf, buf, count)) {
+		kfree(kbuf);
+		return -EFAULT;
+	}
+	curr_pos = kbuf;
+	kbuf[count] = '\0';	/* Just to make sure... */
+
+	if (strncmp(curr_pos, "lock ", 5) == 0) {
+		curr_pos += 5;
+		remaining -= 5;
+
+		pr_devel("client 0x%X called 'lock'\n", (int)priv);
+
+		if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) {
+			ret_val = -EPROTO;
+			goto done;
+		}
+		if (io_state == VGA_RSRC_NONE) {
+			ret_val = -EPROTO;
+			goto done;
+		}
+
+		pdev = priv->target;
+		if (priv->target == NULL) {
+			ret_val = -ENODEV;
+			goto done;
+		}
+
+		vga_get_uninterruptible(pdev, io_state);
+
+		/* Update the client's locks lists... */
+		for (i = 0; i < MAX_USER_CARDS; i++) {
+			if (priv->cards[i].pdev == pdev) {
+				if (io_state & VGA_RSRC_LEGACY_IO)
+					priv->cards[i].io_cnt++;
+				if (io_state & VGA_RSRC_LEGACY_MEM)
+					priv->cards[i].mem_cnt++;
+				break;
+			}
+		}
+
+		ret_val = count;
+		goto done;
+	} else if (strncmp(curr_pos, "unlock ", 7) == 0) {
+		curr_pos += 7;
+		remaining -= 7;
+
+		pr_devel("client 0x%X called 'unlock'\n", (int)priv);
+
+		if (strncmp(curr_pos, "all", 3) == 0)
+			io_state = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM;
+		else {
+			if (!vga_str_to_iostate
+			    (curr_pos, remaining, &io_state)) {
+				ret_val = -EPROTO;
+				goto done;
+			}
+			/* TODO: Add this?
+			   if (io_state == VGA_RSRC_NONE) {
+			   ret_val = -EPROTO;
+			   goto done;
+			   }
+			  */
+		}
+
+		pdev = priv->target;
+		if (priv->target == NULL) {
+			ret_val = -ENODEV;
+			goto done;
+		}
+		for (i = 0; i < MAX_USER_CARDS; i++) {
+			if (priv->cards[i].pdev == pdev)
+				uc = &priv->cards[i];
+		}
+
+		if (!uc)
+			return -EINVAL;
+
+		if (io_state & VGA_RSRC_LEGACY_IO && uc->io_cnt == 0)
+			return -EINVAL;
+
+		if (io_state & VGA_RSRC_LEGACY_MEM && uc->mem_cnt == 0)
+			return -EINVAL;
+
+		vga_put(pdev, io_state);
+
+		if (io_state & VGA_RSRC_LEGACY_IO)
+			uc->io_cnt--;
+		if (io_state & VGA_RSRC_LEGACY_MEM)
+			uc->mem_cnt--;
+
+		ret_val = count;
+		goto done;
+	} else if (strncmp(curr_pos, "trylock ", 8) == 0) {
+		curr_pos += 8;
+		remaining -= 8;
+
+		pr_devel("client 0x%X called 'trylock'\n", (int)priv);
+
+		if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) {
+			ret_val = -EPROTO;
+			goto done;
+		}
+		/* TODO: Add this?
+		   if (io_state == VGA_RSRC_NONE) {
+		   ret_val = -EPROTO;
+		   goto done;
+		   }
+		 */
+
+		pdev = priv->target;
+		if (priv->target == NULL) {
+			ret_val = -ENODEV;
+			goto done;
+		}
+
+		if (vga_tryget(pdev, io_state)) {
+			/* Update the client's locks lists... */
+			for (i = 0; i < MAX_USER_CARDS; i++) {
+				if (priv->cards[i].pdev == pdev) {
+					if (io_state & VGA_RSRC_LEGACY_IO)
+						priv->cards[i].io_cnt++;
+					if (io_state & VGA_RSRC_LEGACY_MEM)
+						priv->cards[i].mem_cnt++;
+					break;
+				}
+			}
+			ret_val = count;
+			goto done;
+		} else {
+			ret_val = -EBUSY;
+			goto done;
+		}
+
+	} else if (strncmp(curr_pos, "target ", 7) == 0) {
+		unsigned int domain, bus, devfn;
+		struct vga_device *vgadev;
+
+		curr_pos += 7;
+		remaining -= 7;
+		pr_devel("client 0x%X called 'target'\n", (int)priv);
+		/* if target is default */
+		if (!strncmp(buf, "default", 7))
+			pdev = pci_dev_get(vga_default_device());
+		else {
+			if (!vga_pci_str_to_vars(curr_pos, remaining,
+						 &domain, &bus, &devfn)) {
+				ret_val = -EPROTO;
+				goto done;
+			}
+
+			pdev = pci_get_bus_and_slot(bus, devfn);
+			if (!pdev) {
+				pr_info("vgaarb: invalid PCI address!\n");
+				ret_val = -ENODEV;
+				goto done;
+			}
+		}
+
+		vgadev = vgadev_find(pdev);
+		if (vgadev == NULL) {
+			pr_info("vgaarb: this pci device is not a vga device\n");
+			pci_dev_put(pdev);
+			ret_val = -ENODEV;
+			goto done;
+		}
+
+		priv->target = pdev;
+		for (i = 0; i < MAX_USER_CARDS; i++) {
+			if (priv->cards[i].pdev == pdev)
+				break;
+			if (priv->cards[i].pdev == NULL) {
+				priv->cards[i].pdev = pdev;
+				priv->cards[i].io_cnt = 0;
+				priv->cards[i].mem_cnt = 0;
+				break;
+			}
+		}
+		if (i == MAX_USER_CARDS) {
+			pr_err("vgaarb: maximum user cards number reached!\n");
+			pci_dev_put(pdev);
+			/* XXX: which value to return? */
+			ret_val =  -ENOMEM;
+			goto done;
+		}
+
+		ret_val = count;
+		pci_dev_put(pdev);
+		goto done;
+
+
+	} else if (strncmp(curr_pos, "decodes ", 8) == 0) {
+		curr_pos += 8;
+		remaining -= 8;
+		pr_devel("vgaarb: client 0x%X called 'decodes'\n", (int)priv);
+
+		if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) {
+			ret_val = -EPROTO;
+			goto done;
+		}
+		pdev = priv->target;
+		if (priv->target == NULL) {
+			ret_val = -ENODEV;
+			goto done;
+		}
+
+		__vga_set_legacy_decoding(pdev, io_state, true);
+		ret_val = count;
+		goto done;
+	}
+	/* If we got here, the message written is not part of the protocol! */
+	kfree(kbuf);
+	return -EPROTO;
+
+done:
+	kfree(kbuf);
+	return ret_val;
+}
+
+static unsigned int vga_arb_fpoll(struct file *file, poll_table * wait)
+{
+	struct vga_arb_private *priv = file->private_data;
+
+	pr_devel("%s\n", __func__);
+
+	if (priv == NULL)
+		return -ENODEV;
+	poll_wait(file, &vga_wait_queue, wait);
+	return POLLIN;
+}
+
+static int vga_arb_open(struct inode *inode, struct file *file)
+{
+	struct vga_arb_private *priv;
+	unsigned long flags;
+
+	pr_devel("%s\n", __func__);
+
+	priv = kmalloc(sizeof(struct vga_arb_private), GFP_KERNEL);
+	if (priv == NULL)
+		return -ENOMEM;
+	memset(priv, 0, sizeof(*priv));
+	spin_lock_init(&priv->lock);
+	file->private_data = priv;
+
+	spin_lock_irqsave(&vga_user_lock, flags);
+	list_add(&priv->list, &vga_user_list);
+	spin_unlock_irqrestore(&vga_user_lock, flags);
+
+	/* Set the client' lists of locks */
+	priv->target = vga_default_device(); /* Maybe this is still null! */
+	priv->cards[0].pdev = priv->target;
+	priv->cards[0].io_cnt = 0;
+	priv->cards[0].mem_cnt = 0;
+
+
+	return 0;
+}
+
+static int vga_arb_release(struct inode *inode, struct file *file)
+{
+	struct vga_arb_private *priv = file->private_data;
+	struct vga_arb_user_card *uc;
+	unsigned long flags;
+	int i;
+
+	pr_devel("%s\n", __func__);
+
+	if (priv == NULL)
+		return -ENODEV;
+
+	spin_lock_irqsave(&vga_user_lock, flags);
+	list_del(&priv->list);
+	for (i = 0; i < MAX_USER_CARDS; i++) {
+		uc = &priv->cards[i];
+		if (uc->pdev == NULL)
+			continue;
+		pr_devel("uc->io_cnt == %d, uc->mem_cnt == %d\n",
+			 uc->io_cnt, uc->mem_cnt);
+		while (uc->io_cnt--)
+			vga_put(uc->pdev, VGA_RSRC_LEGACY_IO);
+		while (uc->mem_cnt--)
+			vga_put(uc->pdev, VGA_RSRC_LEGACY_MEM);
+	}
+	spin_unlock_irqrestore(&vga_user_lock, flags);
+
+	kfree(priv);
+
+	return 0;
+}
+
+static void vga_arb_device_card_gone(struct pci_dev *pdev)
+{
+}
+
+/*
+ * callback any registered clients to let them know we have a
+ * change in VGA cards
+ */
+static void vga_arbiter_notify_clients(void)
+{
+	struct vga_device *vgadev;
+	unsigned long flags;
+	uint32_t new_decodes;
+	bool new_state;
+
+	if (!vga_arbiter_used)
+		return;
+
+	spin_lock_irqsave(&vga_lock, flags);
+	list_for_each_entry(vgadev, &vga_list, list) {
+		if (vga_count > 1)
+			new_state = false;
+		else
+			new_state = true;
+		if (vgadev->set_vga_decode) {
+			new_decodes = vgadev->set_vga_decode(vgadev->cookie, new_state);
+			vga_update_device_decodes(vgadev, new_decodes);
+		}
+	}
+	spin_unlock_irqrestore(&vga_lock, flags);
+}
+
+static int pci_notify(struct notifier_block *nb, unsigned long action,
+		      void *data)
+{
+	struct device *dev = data;
+	struct pci_dev *pdev = to_pci_dev(dev);
+
+	pr_devel("%s\n", __func__);
+
+	/* For now we're only intereted in devices added and removed. I didn't
+	 * test this thing here, so someone needs to double check for the
+	 * cases of hotplugable vga cards. */
+	if (action == BUS_NOTIFY_ADD_DEVICE)
+		vga_arbiter_add_pci_device(pdev);
+	else if (action == BUS_NOTIFY_DEL_DEVICE)
+		vga_arbiter_del_pci_device(pdev);
+
+	vga_arbiter_notify_clients();
+	return 0;
+}
+
+static struct notifier_block pci_notifier = {
+	.notifier_call = pci_notify,
+};
+
+static const struct file_operations vga_arb_device_fops = {
+	.read = vga_arb_read,
+	.write = vga_arb_write,
+	.poll = vga_arb_fpoll,
+	.open = vga_arb_open,
+	.release = vga_arb_release,
+};
+
+static struct miscdevice vga_arb_device = {
+	MISC_DYNAMIC_MINOR, "vga_arbiter", &vga_arb_device_fops
+};
+
+static int __init vga_arb_device_init(void)
+{
+	int rc;
+	struct pci_dev *pdev;
+
+	rc = misc_register(&vga_arb_device);
+	if (rc < 0)
+		pr_err("vgaarb: error %d registering device\n", rc);
+
+	bus_register_notifier(&pci_bus_type, &pci_notifier);
+
+	/* We add all pci devices satisfying vga class in the arbiter by
+	 * default */
+	pdev = NULL;
+	while ((pdev =
+		pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+			       PCI_ANY_ID, pdev)) != NULL)
+		vga_arbiter_add_pci_device(pdev);
+
+	pr_info("vgaarb: loaded\n");
+	return rc;
+}
+subsys_initcall(vga_arb_device_init);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index dbd0f94..d837606 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2502,6 +2502,50 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
 	return 0;
 }
 
+/**
+ * pci_set_vga_state - set VGA decode state on device and parents if requested
+ * @dev the PCI device
+ * @decode - true = enable decoding, false = disable decoding
+ * @command_bits PCI_COMMAND_IO and/or PCI_COMMAND_MEMORY
+ * @change_bridge - traverse ancestors and change bridges
+ */
+int pci_set_vga_state(struct pci_dev *dev, bool decode,
+		      unsigned int command_bits, bool change_bridge)
+{
+	struct pci_bus *bus;
+	struct pci_dev *bridge;
+	u16 cmd;
+
+	WARN_ON(command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY));
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	if (decode == true)
+		cmd |= command_bits;
+	else
+		cmd &= ~command_bits;
+	pci_write_config_word(dev, PCI_COMMAND, cmd);
+
+	if (change_bridge == false)
+		return 0;
+
+	bus = dev->bus;
+	while (bus) {
+		bridge = bus->self;
+		if (bridge) {
+			pci_read_config_word(bridge, PCI_BRIDGE_CONTROL,
+					     &cmd);
+			if (decode == true)
+				cmd |= PCI_BRIDGE_CTL_VGA;
+			else
+				cmd &= ~PCI_BRIDGE_CTL_VGA;
+			pci_write_config_word(bridge, PCI_BRIDGE_CONTROL,
+					      cmd);
+		}
+		bus = bus->parent;
+	}
+	return 0;
+}
+
 #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE
 static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0};
 spinlock_t resource_alignment_lock = SPIN_LOCK_UNLOCKED;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 8afcf08..f4ed145 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -7,6 +7,8 @@ menu "Graphics support"
 
 source "drivers/char/agp/Kconfig"
 
+source "drivers/gpu/vga/Kconfig"
+
 source "drivers/gpu/drm/Kconfig"
 
 config VGASTATE
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 115fb7b..7ba6eba 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -805,6 +805,8 @@ int pci_cfg_space_size_ext(struct pci_dev *dev);
 int pci_cfg_space_size(struct pci_dev *dev);
 unsigned char pci_bus_max_busnr(struct pci_bus *bus);
 
+int pci_set_vga_state(struct pci_dev *pdev, bool decode,
+		      unsigned int command_bits, bool change_bridge);
 /* kmem_cache style wrapper around pci_alloc_consistent() */
 
 #include <linux/dmapool.h>
diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h
new file mode 100644
index 0000000..68229ce
--- /dev/null
+++ b/include/linux/vgaarb.h
@@ -0,0 +1,195 @@
+/*
+ * vgaarb.c
+ *
+ * (C) Copyright 2005 Benjamin Herrenschmidt <benh at kernel.crashing.org>
+ * (C) Copyright 2007 Paulo R. Zanoni <przanoni at gmail.com>
+ * (C) Copyright 2007, 2009 Tiago Vignatti <vignatti at freedesktop.org>
+ */
+
+#ifndef LINUX_VGA_H
+
+#include <asm/vga.h>
+
+/* Legacy VGA regions */
+#define VGA_RSRC_NONE	       0x00
+#define VGA_RSRC_LEGACY_IO     0x01
+#define VGA_RSRC_LEGACY_MEM    0x02
+#define VGA_RSRC_LEGACY_MASK   (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM)
+/* Non-legacy access */
+#define VGA_RSRC_NORMAL_IO     0x04
+#define VGA_RSRC_NORMAL_MEM    0x08
+
+/* Passing that instead of a pci_dev to use the system "default"
+ * device, that is the one used by vgacon. Archs will probably
+ * have to provide their own vga_default_device();
+ */
+#define VGA_DEFAULT_DEVICE     (NULL)
+
+/* For use by clients */
+
+/**
+ *     vga_set_legacy_decoding
+ *
+ *     @pdev: pci device of the VGA card
+ *     @decodes: bit mask of what legacy regions the card decodes
+ *
+ *     Indicates to the arbiter if the card decodes legacy VGA IOs,
+ *     legacy VGA Memory, both, or none. All cards default to both,
+ *     the card driver (fbdev for example) should tell the arbiter
+ *     if it has disabled legacy decoding, so the card can be left
+ *     out of the arbitration process (and can be safe to take
+ *     interrupts at any time.
+ */
+extern void vga_set_legacy_decoding(struct pci_dev *pdev,
+									unsigned int decodes);
+
+/**
+ *     vga_get         - acquire & locks VGA resources
+ *
+ *     pdev: pci device of the VGA card or NULL for the system default
+ *     rsrc: bit mask of resources to acquire and lock
+ *     interruptible: blocking should be interruptible by signals ?
+ *
+ *     This function acquires VGA resources for the given
+ *     card and mark those resources locked. If the resource requested
+ *     are "normal" (and not legacy) resources, the arbiter will first check
+ *     wether the card is doing legacy decoding for that type of resource. If
+ *     yes, the lock is "converted" into a legacy resource lock.
+ *     The arbiter will first look for all VGA cards that might conflict
+ *     and disable their IOs and/or Memory access, inlcuding VGA forwarding
+ *     on P2P bridges if necessary, so that the requested resources can
+ *     be used. Then, the card is marked as locking these resources and
+ *     the IO and/or Memory accesse are enabled on the card (including
+ *     VGA forwarding on parent P2P bridges if any).
+ *     This function will block if some conflicting card is already locking
+ *     one of the required resources (or any resource on a different bus
+ *     segment, since P2P bridges don't differenciate VGA memory and IO
+ *     afaik). You can indicate wether this blocking should be interruptible
+ *     by a signal (for userland interface) or not.
+ *     Must not be called at interrupt time or in atomic context.
+ *     If the card already owns the resources, the function succeeds.
+ *     Nested calls are supported (a per-resource counter is maintained)
+ */
+
+extern int vga_get(struct pci_dev *pdev, unsigned int rsrc,
+											int interruptible);
+
+/**
+ *     vga_get_interruptible
+ *
+ *     Shortcut to vga_get
+ */
+
+static inline int vga_get_interruptible(struct pci_dev *pdev,
+										unsigned int rsrc)
+{
+       return vga_get(pdev, rsrc, 1);
+}
+
+/**
+ *     vga_get_interruptible
+ *
+ *     Shortcut to vga_get
+ */
+
+static inline int vga_get_uninterruptible(struct pci_dev *pdev,
+											unsigned int rsrc)
+{
+       return vga_get(pdev, rsrc, 0);
+}
+
+/**
+ *     vga_tryget      - try to acquire & lock legacy VGA resources
+ *
+ *     @pdev: pci devivce of VGA card or NULL for system default
+ *     @rsrc: bit mask of resources to acquire and lock
+ *
+ *     This function performs the same operation as vga_get(), but
+ *     will return an error (-EBUSY) instead of blocking if the resources
+ *     are already locked by another card. It can be called in any context
+ */
+
+extern int vga_tryget(struct pci_dev *pdev, unsigned int rsrc);
+
+/**
+ *     vga_put         - release lock on legacy VGA resources
+ *
+ *     @pdev: pci device of VGA card or NULL for system default
+ *     @rsrc: but mask of resource to release
+ *
+ *     This function releases resources previously locked by vga_get()
+ *     or vga_tryget(). The resources aren't disabled right away, so
+ *     that a subsequence vga_get() on the same card will succeed
+ *     immediately. Resources have a counter, so locks are only
+ *     released if the counter reaches 0.
+ */
+
+extern void vga_put(struct pci_dev *pdev, unsigned int rsrc);
+
+
+/**
+ *     vga_default_device
+ *
+ *     This can be defined by the platform. The default implementation
+ *     is rather dumb and will probably only work properly on single
+ *     vga card setups and/or x86 platforms.
+ *
+ *     If your VGA default device is not PCI, you'll have to return
+ *     NULL here. In this case, I assume it will not conflict with
+ *     any PCI card. If this is not true, I'll have to define two archs
+ *     hooks for enabling/disabling the VGA default device if that is
+ *     possible. This may be a problem with real _ISA_ VGA cards, in
+ *     addition to a PCI one. I don't know at this point how to deal
+ *     with that card. Can theirs IOs be disabled at all ? If not, then
+ *     I suppose it's a matter of having the proper arch hook telling
+ *     us about it, so we basically never allow anybody to succeed a
+ *     vga_get()...
+ */
+
+#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE
+extern struct pci_dev *vga_default_device(void);
+#endif
+
+/**
+ *     vga_conflicts
+ *
+ *     Architectures should define this if they have several
+ *     independant PCI domains that can afford concurrent VGA
+ *     decoding
+ */
+
+#ifndef __ARCH_HAS_VGA_CONFLICT
+static inline int vga_conflicts(struct pci_dev *p1, struct pci_dev *p2)
+{
+       return 1;
+}
+#endif
+
+/*
+ * Register a client with the VGA arbitration logic
+ * return value: number of VGA devices in system.
+ *
+ * Clients have two callback mechanisms they can use.
+ * irq enable/disable callback -
+ *    If a client can't disable its GPUs VGA resources, then we
+ *    need to be able to ask it to turn off its irqs when we
+ *    turn off its mem and io decoding.
+ * set_vga_decode
+ *    If a client can disable its GPU VGA resource, it will
+ *    get a callback from this to set the encode/decode state
+ *
+ * Clients with disable abilities should check the return value
+ * of this function and if the VGA device count is > 1, should
+ * disable VGA decoding resources.
+ *
+ * Rationale: we cannot disable VGA decode resources unconditionally
+ * some single GPU laptops seem to require ACPI or BIOS access to the
+ * VGA registers to control things like backlights etc.
+ * Hopefully newer multi-GPU laptops do something saner, and desktops
+ * won't have any special ACPI for this.
+ */
+int vga_client_register(struct pci_dev *pdev, void *cookie,
+			void (*irq_set_state)(void *cookie, bool state),
+			unsigned int (*set_vga_decode)(void *cookie, bool state));
+
+#endif /* LINUX_VGA_H */
-- 
1.5.4.1


linux-2.6.30-hush-rom-warning.patch:
 setup-res.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

--- NEW FILE linux-2.6.30-hush-rom-warning.patch ---
diff -up linux-2.6.30.noarch/drivers/pci/setup-res.c.jx linux-2.6.30.noarch/drivers/pci/setup-res.c
--- linux-2.6.30.noarch/drivers/pci/setup-res.c.jx	2009-07-27 17:56:13.000000000 -0400
+++ linux-2.6.30.noarch/drivers/pci/setup-res.c	2009-07-27 17:58:25.000000000 -0400
@@ -101,6 +101,7 @@ int pci_claim_resource(struct pci_dev *d
 	struct resource *res = &dev->resource[resource];
 	struct resource *root;
 	int err;
+	const char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge";
 
 	root = pci_find_parent_resource(dev, res);
 
@@ -108,8 +109,13 @@ int pci_claim_resource(struct pci_dev *d
 	if (root != NULL)
 		err = request_resource(root, res);
 
-	if (err) {
-		const char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge";
+	if (err && resource == 6) {
+		dev_info(&dev->dev, "BAR %d: %s of %s %pR\n",
+			resource,
+			root ? "address space collision on" :
+				"no parent found for",
+			dtype, res);
+	} else if (err) {
 		dev_err(&dev->dev, "BAR %d: %s of %s %pR\n",
 			resource,
 			root ? "address space collision on" :

linux-2.6.30-no-pcspkr-modalias.patch:
 pcspkr.c |    1 -
 1 file changed, 1 deletion(-)

--- NEW FILE linux-2.6.30-no-pcspkr-modalias.patch ---
diff -up linux-2.6.30.noarch/drivers/input/misc/pcspkr.c.jx linux-2.6.30.noarch/drivers/input/misc/pcspkr.c
--- linux-2.6.30.noarch/drivers/input/misc/pcspkr.c.jx	2009-07-28 16:54:44.000000000 -0400
+++ linux-2.6.30.noarch/drivers/input/misc/pcspkr.c	2009-07-28 16:59:36.000000000 -0400
@@ -23,7 +23,6 @@
 MODULE_AUTHOR("Vojtech Pavlik <vojtech at ucw.cz>");
 MODULE_DESCRIPTION("PC Speaker beeper driver");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:pcspkr");
 
 #if defined(CONFIG_MIPS) || defined(CONFIG_X86)
 /* Use the global PIT lock ! */


--- NEW FILE patch-2.6.31-rc5-git3.bz2.sign ---
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: See http://www.kernel.org/signature.html for info

iD8DBQBKeMweyGugalF9Dw4RAp18AJ9Ch7DQJA5GwevbuXDXattxayrJMACfSDOb
t3+OUGZ1dQ2Y8+z9QDVk2zM=
=HbQm
-----END PGP SIGNATURE-----


--- NEW FILE patch-2.6.31-rc5.bz2.sign ---
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: See http://www.kernel.org/signature.html for info

iD8DBQBKc5FayGugalF9Dw4RAhV0AJwOz4HlfA1WCi74lPIuro8pDNPrzgCgh/ag
vf8aBky58al8AnVRvhpNaIs=
=vgyD
-----END PGP SIGNATURE-----

revert-ftrace-powerpc-snafu.patch:
 recordmcount.pl |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE revert-ftrace-powerpc-snafu.patch ---
commit 4e7fea66de82caf76bf11213150b629562cca74b
Author: Dave Airlie <airlied at ppcg5.localdomain>
Date:   Wed Aug 5 17:07:10 2009 +1000

    Revert "ftrace: Fix the conditional that updates $ref_func"
    
    This reverts commit fc4c73554c9d93b3e495f2f7acae1323b0d5db84.

diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index d29baa2..d99b343 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -414,7 +414,7 @@ while (<IN>) {
 	    $offset = hex $1;
 	} else {
 	    # if we already have a function, and this is weak, skip it
-	    if (!defined($ref_func) && !defined($weak{$text})) {
+	    if (!defined($ref_func) || !defined($weak{$text})) {
 		$ref_func = $text;
 		$offset = hex $1;
 	    }


Index: .cvsignore
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/.cvsignore,v
retrieving revision 1.1014.2.21
retrieving revision 1.1014.2.22
diff -u -p -r1.1014.2.21 -r1.1014.2.22
--- .cvsignore	15 Jul 2009 20:58:03 -0000	1.1014.2.21
+++ .cvsignore	5 Aug 2009 23:00:08 -0000	1.1014.2.22
@@ -5,4 +5,5 @@ kernel-2.6.*.config
 temp-*
 kernel-2.6.30
 linux-2.6.30.tar.bz2
-patch-2.6.31-rc3.bz2
+patch-2.6.31-rc5.bz2
+patch-2.6.31-rc5-git3.bz2


Index: Makefile.config
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/Makefile.config,v
retrieving revision 1.70
retrieving revision 1.70.6.1
diff -u -p -r1.70 -r1.70.6.1
--- Makefile.config	5 Feb 2009 21:11:18 -0000	1.70
+++ Makefile.config	5 Aug 2009 23:00:08 -0000	1.70.6.1
@@ -5,7 +5,7 @@
 CFG		= kernel-$(VERSION)
 
 CONFIGFILES	= \
-	$(CFG)-i586.config $(CFG)-i586-debug.config \
+	$(CFG)-i686.config $(CFG)-i686-debug.config \
 	$(CFG)-i686-PAE.config $(CFG)-i686-PAEdebug.config \
 	$(CFG)-x86_64.config $(CFG)-x86_64-debug.config \
 	$(CFG)-s390x.config $(CFG)-arm.config \
@@ -68,10 +68,10 @@ kernel-$(VERSION)-i686-PAE.config: confi
 kernel-$(VERSION)-i686-PAEdebug.config: config-i686-PAE temp-x86-debug-generic
 	perl merge.pl $^ i386 > $@
 
-kernel-$(VERSION)-i586.config: config-i586 temp-x86-generic
+kernel-$(VERSION)-i686.config: /dev/null temp-x86-generic
 	perl merge.pl $^ i386 > $@
 
-kernel-$(VERSION)-i586-debug.config: config-i586 temp-x86-debug-generic
+kernel-$(VERSION)-i686-debug.config: /dev/null temp-x86-debug-generic
 	perl merge.pl $^ i386 > $@
 
 kernel-$(VERSION)-x86_64.config: /dev/null temp-x86_64-generic


Index: TODO
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/TODO,v
retrieving revision 1.54.6.8
retrieving revision 1.54.6.9
diff -u -p -r1.54.6.8 -r1.54.6.9
--- TODO	27 Jun 2009 11:05:09 -0000	1.54.6.8
+++ TODO	5 Aug 2009 23:00:08 -0000	1.54.6.9
@@ -59,8 +59,11 @@
 * linux-2.6-execshield.patch
 	Not interesting to upstream.
 
-* linux-2.6.29-lirc.patch
 * linux-2.6-sysrq-c.patch
+* linux-2.6.31-lirc.patch
+* lirc_streamzap-buffer-rework.patch
+* hdpvr-ir-enable.patch
+* hid-ignore-all-recent-imon-devices.patch
 	jarod working on upstreaming
 
 * linux-2.6-silence-acpi-blacklist.patch
@@ -81,3 +84,6 @@
 * linux-2.6-kmemleak-improvements.patch
 	will go upstream for .31
 
+* linux-2.6-vga-arb.patch
+* drm-vga-arb.patch
+	will go upstream for .32


Index: config-debug
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/config-debug,v
retrieving revision 1.23.6.3
retrieving revision 1.23.6.4
diff -u -p -r1.23.6.3 -r1.23.6.4
--- config-debug	3 Jul 2009 18:54:45 -0000	1.23.6.3
+++ config-debug	5 Aug 2009 23:00:08 -0000	1.23.6.4
@@ -50,4 +50,3 @@ CONFIG_DEBUG_NOTIFIERS=y
 CONFIG_DMA_API_DEBUG=y
 
 CONFIG_MMIOTRACE=y
-


Index: config-generic
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/config-generic,v
retrieving revision 1.238.6.31
retrieving revision 1.238.6.32
diff -u -p -r1.238.6.31 -r1.238.6.32
--- config-generic	15 Jul 2009 21:32:22 -0000	1.238.6.31
+++ config-generic	5 Aug 2009 23:00:08 -0000	1.238.6.32
@@ -16,7 +16,6 @@ CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 
 CONFIG_BUILD_DOCSRC=y
-CONFIG_DYNAMIC_DEBUG=y
 
 #
 # General setup
@@ -97,7 +96,6 @@ CONFIG_ISA=y
 # CONFIG_EISA is not set
 # CONFIG_MCA is not set
 # CONFIG_SCx200 is not set
-# CONFIG_DEBUG_KOBJECT is not set
 
 #
 # PCMCIA/CardBus support
@@ -2177,7 +2175,8 @@ CONFIG_HW_RANDOM_TIMERIOMEM=m
 # CONFIG_RTC_DEBUG is not set
 # CONFIG_GEN_RTC is not set
 CONFIG_RTC_CLASS=y
-# CONFIG_RTC_HCTOSYS is not set
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
 CONFIG_RTC_INTF_SYSFS=y
 CONFIG_RTC_INTF_PROC=y
 CONFIG_RTC_INTF_DEV=y
@@ -2246,6 +2245,7 @@ CONFIG_DRM_I915_KMS=y
 CONFIG_DRM_VIA=m
 # CONFIG_DRM_NOUVEAU is not set
 # CONFIG_DRM_NOUVEAU_KMS is not set
+# CONFIG_DRM_NOUVEAU_BACKLIGHT is not set
 
 #
 # PCMCIA character devices
@@ -2777,6 +2777,7 @@ CONFIG_LOGITECH_FF=y
 CONFIG_LOGIRUMBLEPAD2_FF=y
 CONFIG_PANTHERLORD_FF=y
 CONFIG_THRUSTMASTER_FF=y
+CONFIG_HID_WACOM=y
 CONFIG_ZEROPLUS_FF=y
 CONFIG_USB_HIDDEV=y
 CONFIG_USB_IDMOUSE=m
@@ -2811,6 +2812,8 @@ CONFIG_USB_GSPCA_OV519=m
 CONFIG_USB_GSPCA_OV534=m
 CONFIG_USB_GSPCA_PAC207=m
 CONFIG_USB_GSPCA_PAC7311=m
+CONFIG_USB_GSPCA_SN9C20X=m
+CONFIG_USB_GSPCA_SN9C20X_EVDEV=y
 CONFIG_USB_GSPCA_SONIXB=m
 CONFIG_USB_GSPCA_SONIXJ=m
 CONFIG_USB_GSPCA_SPCA500=m
@@ -2867,6 +2870,7 @@ CONFIG_USB_NET_CDC_SUBSET=m
 CONFIG_USB_NET_CDC_EEM=m
 CONFIG_USB_NET_ZAURUS=m
 CONFIG_USB_NET_INT51X1=m
+CONFIG_USB_CDC_PHONET=m
 
 #
 # USB Host-to-Host Cables
@@ -3353,22 +3357,6 @@ CONFIG_KGDB_SERIAL_CONSOLE=y
 CONFIG_KGDB_TESTS=y
 # CONFIG_KGDB_TESTS_ON_BOOT is not set
 
-# These debug options are deliberatly left on.
-# They aren't that much of a performance impact, and the value
-# from getting out-of-tree modules fixed is worth the trade-off.
-CONFIG_DEBUG_HIGHMEM=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_BOOT_PRINTK_DELAY=y
-CONFIG_DEBUG_SLAB_LEAK=y
-CONFIG_DEBUG_LIST=y
-CONFIG_DEBUG_SHIRQ=y
-CONFIG_DEBUG_DEVRES=y
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
-
-CONFIG_DEBUG_RODATA_TEST=y
-CONFIG_DEBUG_NX_TEST=m
-CONFIG_DEBUG_BOOT_PARAMS=y
-
 #
 # Security options
 #
@@ -3517,12 +3505,9 @@ CONFIG_PROC_PID_CPUSET=y
 
 CONFIG_RELAY=y
 # CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_MUST_CHECK=y
 
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
-CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
 
 CONFIG_KEXEC=y
 
@@ -3775,6 +3760,7 @@ CONFIG_POWER_SUPPLY=m
 # CONFIG_POWER_SUPPLY_DEBUG is not set
 CONFIG_APM_POWER=m
 # CONFIG_BATTERY_DS2760 is not set
+# CONFIG_BATTERY_DS2782 is not set
 CONFIG_BATTERY_PMU=m
 CONFIG_BATTERY_BQ27x00=m
 CONFIG_BATTERY_MAX17040=m
@@ -4013,6 +3999,7 @@ CONFIG_STRIP_ASM_SYMS=y
 
 # CONFIG_RCU_FANOUT_EXACT is not set
 
+CONFIG_KSM=y
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
 CONFIG_FSNOTIFY=y
@@ -4032,9 +4019,33 @@ CONFIG_PPS=m
 # CONFIG_RDC_17F3101X is not set
 # CONFIG_FB_UDL is not set
 
+# DEBUG options that don't get enabled/disabled with 'make debug/release'
+#
+# Kmemleak still produces a lot of false positives.
 # CONFIG_DEBUG_KMEMLEAK is not set
-
 #
+# This generates a huge amount of dmesg spew
+# CONFIG_DEBUG_KOBJECT is not set
+#
+#
+# These debug options are deliberatly left on (even in 'make release' kernels).
+# They aren't that much of a performance impact, and the value
+# from getting useful bug-reports makes it worth leaving them on.
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_HIGHMEM=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+CONFIG_BOOT_PRINTK_DELAY=y
+CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DEBUG_DEVRES=y
+CONFIG_DEBUG_RODATA_TEST=y
+CONFIG_DEBUG_NX_TEST=m
+CONFIG_DEBUG_BOOT_PARAMS=y
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+
 # added for xen pvops patch
 #
 CONFIG_XEN_DOM0=y


Index: config-i686-PAE
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/config-i686-PAE,v
retrieving revision 1.1.18.1
retrieving revision 1.1.18.2
diff -u -p -r1.1.18.1 -r1.1.18.2
--- config-i686-PAE	27 Jun 2009 11:05:10 -0000	1.1.18.1
+++ config-i686-PAE	5 Aug 2009 23:00:09 -0000	1.1.18.2
@@ -1,5 +1,3 @@
-CONFIG_M686=y
-# CONFIG_NOHIGHMEM is not set
 # CONFIG_HIGHMEM4G is not set
 CONFIG_HIGHMEM64G=y
 


Index: config-nodebug
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/config-nodebug,v
retrieving revision 1.31.6.4
retrieving revision 1.31.6.5
diff -u -p -r1.31.6.4 -r1.31.6.5
--- config-nodebug	3 Jul 2009 18:54:45 -0000	1.31.6.4
+++ config-nodebug	5 Aug 2009 23:00:09 -0000	1.31.6.5
@@ -49,4 +49,3 @@ CONFIG_DEBUG_NOTIFIERS=y
 CONFIG_DMA_API_DEBUG=y
 
 CONFIG_MMIOTRACE=y
-


Index: config-powerpc-generic
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/config-powerpc-generic,v
retrieving revision 1.33.6.8
retrieving revision 1.33.6.9
diff -u -p -r1.33.6.8 -r1.33.6.9
--- config-powerpc-generic	10 Jul 2009 19:04:29 -0000	1.33.6.8
+++ config-powerpc-generic	5 Aug 2009 23:00:09 -0000	1.33.6.9
@@ -312,7 +312,7 @@ CONFIG_USB_FHCI_HCD=m
 
 # CONFIG_DRM_RADEON_KMS is not set
 
-CONFIG_AMIGAONE=y
+# CONFIG_AMIGAONE is not set
 
 CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
 


Index: config-powerpc32-generic
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/config-powerpc32-generic,v
retrieving revision 1.30.6.2
retrieving revision 1.30.6.3
diff -u -p -r1.30.6.2 -r1.30.6.3
--- config-powerpc32-generic	27 Jun 2009 11:05:10 -0000	1.30.6.2
+++ config-powerpc32-generic	5 Aug 2009 23:00:09 -0000	1.30.6.3
@@ -187,3 +187,5 @@ CONFIG_USB_GPIO_VBUS=m
 CONFIG_RCU_FANOUT=32
 
 CONFIG_PERF_COUNTERS=y
+CONFIG_EVENT_PROFILE=y
+


Index: config-powerpc64
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/config-powerpc64,v
retrieving revision 1.27.6.3
retrieving revision 1.27.6.4
diff -u -p -r1.27.6.3 -r1.27.6.4
--- config-powerpc64	27 Jun 2009 11:05:10 -0000	1.27.6.3
+++ config-powerpc64	5 Aug 2009 23:00:09 -0000	1.27.6.4
@@ -185,3 +185,4 @@ CONFIG_RELOCATABLE=y
 CONFIG_RCU_FANOUT=64
 
 CONFIG_PERF_COUNTERS=y
+CONFIG_EVENT_PROFILE=y


Index: config-s390x
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/config-s390x,v
retrieving revision 1.11.6.3
retrieving revision 1.11.6.4
diff -u -p -r1.11.6.3 -r1.11.6.4
--- config-s390x	27 Jun 2009 11:05:10 -0000	1.11.6.3
+++ config-s390x	5 Aug 2009 23:00:09 -0000	1.11.6.4
@@ -228,3 +228,5 @@ CONFIG_HIBERNATION=y
 CONFIG_PM_STD_PARTITION="/dev/jokes"
 
 CONFIG_PERF_COUNTERS=y
+CONFIG_EVENT_PROFILE=y
+


Index: config-x86-generic
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/config-x86-generic,v
retrieving revision 1.68.6.14
retrieving revision 1.68.6.15
diff -u -p -r1.68.6.14 -r1.68.6.15
--- config-x86-generic	10 Jul 2009 19:04:29 -0000	1.68.6.14
+++ config-x86-generic	5 Aug 2009 23:00:09 -0000	1.68.6.15
@@ -26,7 +26,7 @@ CONFIG_X86_BIGSMP=y
 # CONFIG_M586 is not set
 # CONFIG_M586TSC is not set
 # CONFIG_M586MMX is not set
-# CONFIG_M686 is not set
+CONFIG_M686=y
 # CONFIG_MPENTIUMII is not set
 # CONFIG_MPENTIUMIII is not set
 # CONFIG_MPENTIUMM is not set
@@ -75,7 +75,11 @@ CONFIG_X86_CPU_DEBUG=m
 CONFIG_EDD=m
 # CONFIG_EDD_OFF is not set
 # CONFIG_NUMA is not set
+# CONFIG_NOHIGHMEM is not set
+CONFIG_HIGHMEM4G=y
+# CONFIG_HIGHMEM64G is not set
 CONFIG_HIGHMEM=y
+
 CONFIG_HIGHPTE=n
 # CONFIG_MATH_EMULATION is not set
 CONFIG_MTRR=y
@@ -468,6 +472,7 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_IOMMU_STRESS is not set
 
 CONFIG_PERF_COUNTERS=y
+CONFIG_EVENT_PROFILE=y
 
 # CONFIG_X86_OLD_MCE is not set
 CONFIG_X86_MCE_INTEL=y


Index: config-x86_64-generic
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/config-x86_64-generic,v
retrieving revision 1.68.2.13
retrieving revision 1.68.2.14
diff -u -p -r1.68.2.13 -r1.68.2.14
--- config-x86_64-generic	10 Jul 2009 19:04:29 -0000	1.68.2.13
+++ config-x86_64-generic	5 Aug 2009 23:00:10 -0000	1.68.2.14
@@ -377,5 +377,6 @@ CONFIG_RCU_FANOUT=64
 # CONFIG_IOMMU_STRESS is not set
 
 CONFIG_PERF_COUNTERS=y
+CONFIG_EVENT_PROFILE=y
 
 # CONFIG_X86_MCE_INJECT is not set

drm-nouveau.patch:
 drivers/gpu/drm/Kconfig                     |   30 
 drivers/gpu/drm/Makefile                    |    1 
 drivers/gpu/drm/drm_bufs.c                  |   28 
 drivers/gpu/drm/nouveau/Makefile            |   27 
 drivers/gpu/drm/nouveau/nouveau_backlight.c |  155 
 drivers/gpu/drm/nouveau/nouveau_bios.c      | 5056 ++++++
 drivers/gpu/drm/nouveau/nouveau_bios.h      |  227 
 drivers/gpu/drm/nouveau/nouveau_bo.c        |  557 
 drivers/gpu/drm/nouveau/nouveau_calc.c      |  622 
 drivers/gpu/drm/nouveau/nouveau_connector.c |  595 
 drivers/gpu/drm/nouveau/nouveau_connector.h |   52 
 drivers/gpu/drm/nouveau/nouveau_crtc.h      |   88 
 drivers/gpu/drm/nouveau/nouveau_display.c   |  115 
 drivers/gpu/drm/nouveau/nouveau_dma.c       |  143 
 drivers/gpu/drm/nouveau/nouveau_dma.h       |  144 
 drivers/gpu/drm/nouveau/nouveau_drv.c       |  369 
 drivers/gpu/drm/nouveau/nouveau_drv.h       | 1131 +
 drivers/gpu/drm/nouveau/nouveau_encoder.h   |   49 
 drivers/gpu/drm/nouveau/nouveau_fb.h        |   43 
 drivers/gpu/drm/nouveau/nouveau_fbcon.c     | 1027 +
 drivers/gpu/drm/nouveau/nouveau_fbcon.h     |   49 
 drivers/gpu/drm/nouveau/nouveau_fence.c     |  261 
 drivers/gpu/drm/nouveau/nouveau_fifo.c      |  683 
 drivers/gpu/drm/nouveau/nouveau_gem.c       |  751 
 drivers/gpu/drm/nouveau/nouveau_hw.c        | 1018 +
 drivers/gpu/drm/nouveau/nouveau_hw.h        |  431 
 drivers/gpu/drm/nouveau/nouveau_i2c.c       |  246 
 drivers/gpu/drm/nouveau/nouveau_i2c.h       |   45 
 drivers/gpu/drm/nouveau/nouveau_ioc32.c     |   72 
 drivers/gpu/drm/nouveau/nouveau_irq.c       |  674 
 drivers/gpu/drm/nouveau/nouveau_mem.c       |  567 
 drivers/gpu/drm/nouveau/nouveau_notifier.c  |  192 
 drivers/gpu/drm/nouveau/nouveau_object.c    | 1276 +
 drivers/gpu/drm/nouveau/nouveau_reg.h       |  834 +
 drivers/gpu/drm/nouveau/nouveau_sgdma.c     |  317 
 drivers/gpu/drm/nouveau/nouveau_state.c     |  825 +
 drivers/gpu/drm/nouveau/nouveau_swmthd.h    |   33 
 drivers/gpu/drm/nouveau/nouveau_ttm.c       |  116 
 drivers/gpu/drm/nouveau/nv04_crtc.c         | 1143 +
 drivers/gpu/drm/nouveau/nv04_cursor.c       |   70 
 drivers/gpu/drm/nouveau/nv04_display.c      |  250 
 drivers/gpu/drm/nouveau/nv04_fb.c           |   21 
 drivers/gpu/drm/nouveau/nv04_fbcon.c        |  291 
 drivers/gpu/drm/nouveau/nv04_fifo.c         |  146 
 drivers/gpu/drm/nouveau/nv04_graph.c        |  586 
 drivers/gpu/drm/nouveau/nv04_instmem.c      |  192 
 drivers/gpu/drm/nouveau/nv04_mc.c           |   20 
 drivers/gpu/drm/nouveau/nv04_output.c       |  797 +
 drivers/gpu/drm/nouveau/nv04_timer.c        |   51 
 drivers/gpu/drm/nouveau/nv10_fb.c           |   24 
 drivers/gpu/drm/nouveau/nv10_fifo.c         |  177 
 drivers/gpu/drm/nouveau/nv10_graph.c        |  945 +
 drivers/gpu/drm/nouveau/nv20_graph.c        |  958 +
 drivers/gpu/drm/nouveau/nv40_fb.c           |   62 
 drivers/gpu/drm/nouveau/nv40_fifo.c         |  222 
 drivers/gpu/drm/nouveau/nv40_graph.c        | 2203 ++
 drivers/gpu/drm/nouveau/nv40_mc.c           |   38 
 drivers/gpu/drm/nouveau/nv50_crtc.c         |  811 +
 drivers/gpu/drm/nouveau/nv50_cursor.c       |  153 
 drivers/gpu/drm/nouveau/nv50_dac.c          |  284 
 drivers/gpu/drm/nouveau/nv50_display.c      |  849 +
 drivers/gpu/drm/nouveau/nv50_display.h      |   46 
 drivers/gpu/drm/nouveau/nv50_evo.h          |  113 
 drivers/gpu/drm/nouveau/nv50_fbcon.c        |  256 
 drivers/gpu/drm/nouveau/nv50_fifo.c         |  475 
 drivers/gpu/drm/nouveau/nv50_graph.c        |  437 
 drivers/gpu/drm/nouveau/nv50_grctx.h        |22284 ++++++++++++++++++++++++++++
 drivers/gpu/drm/nouveau/nv50_instmem.c      |  499 
 drivers/gpu/drm/nouveau/nv50_mc.c           |   40 
 drivers/gpu/drm/nouveau/nv50_sor.c          |  264 
 drivers/gpu/drm/nouveau/nvreg.h             |  503 
 drivers/gpu/drm/ttm/ttm_bo.c                |    4 
 include/drm/Kbuild                          |    1 
 include/drm/drmP.h                          |    2 
 include/drm/nouveau_drm.h                   |  214 
 75 files changed, 54259 insertions(+), 21 deletions(-)

View full diff with command:
/usr/bin/cvs -n -f diff -kk -u -p -N -r 1.8.6.13 -r 1.8.6.14 drm-nouveau.patchIndex: drm-nouveau.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/drm-nouveau.patch,v
retrieving revision 1.8.6.13
retrieving revision 1.8.6.14
diff -u -p -r1.8.6.13 -r1.8.6.14
--- drm-nouveau.patch	15 Jul 2009 20:58:03 -0000	1.8.6.13
+++ drm-nouveau.patch	5 Aug 2009 23:00:12 -0000	1.8.6.14
@@ -1,8 +1,8 @@
 diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
-index 39b393d..3339338 100644
+index 39b393d..5ea10e5 100644
 --- a/drivers/gpu/drm/Kconfig
 +++ b/drivers/gpu/drm/Kconfig
-@@ -143,3 +143,22 @@ config DRM_SAVAGE
+@@ -143,3 +143,33 @@ config DRM_SAVAGE
  	help
  	  Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister
  	  chipset. If M is selected the module will be called savage.
@@ -14,6 +14,9 @@ index 39b393d..3339338 100644
 +	select FB_CFB_FILLRECT
 +	select FB_CFB_COPYAREA
 +	select FB_CFB_IMAGEBLIT
++	select FB
++	select FRAMEBUFFER_CONSOLE if !EMBEDDED
++	select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT
 +	help
 +	  Choose this option for open-source nVidia support.
 +
@@ -25,6 +28,14 @@ index 39b393d..3339338 100644
 +	and you have a new enough userspace to support this. Running old
 +	userspaces with this enabled will cause pain.
 +
++config DRM_NOUVEAU_BACKLIGHT
++	bool "Support for backlight control"
++	depends on DRM_NOUVEAU
++	default y
++	help
++	  Say Y here if you want to control the backlight of your display
++	  (e.g. a laptop panel).
++
 diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
 index fe23f29..4c6a38d 100644
 --- a/drivers/gpu/drm/Makefile
@@ -94,10 +105,10 @@ index 6246e3f..436e2fe 100644
  		if (map->type == _DRM_REGISTERS)
 diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
 new file mode 100644
-index 0000000..f5d93b5
+index 0000000..a04127f
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/Makefile
-@@ -0,0 +1,26 @@
+@@ -0,0 +1,27 @@
 +#
 +# Makefile for the drm device driver.  This driver provides support for the
 +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
@@ -108,7 +119,7 @@ index 0000000..f5d93b5
 +             nouveau_sgdma.o nouveau_dma.o \
 +             nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \
 +             nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \
-+	     nouveau_display.o nouveau_fbcon.o nouveau_backlight.o \
++	     nouveau_display.o nouveau_connector.o nouveau_fbcon.o \
 +             nv04_timer.o \
 +             nv04_mc.o nv40_mc.o nv50_mc.o \
 +             nv04_fb.o nv10_fb.o nv40_fb.o \
@@ -116,20 +127,21 @@ index 0000000..f5d93b5
 +             nv04_graph.o nv10_graph.o nv20_graph.o \
 +             nv40_graph.o nv50_graph.o \
 +             nv04_instmem.o nv50_instmem.o \
-+             nv50_crtc.o nv50_dac.o nv50_sor.o nv50_connector.o \
++             nv50_crtc.o nv50_dac.o nv50_sor.o \
 +             nv50_cursor.o nv50_display.o nv50_fbcon.o \
 +             nv04_display.o nv04_output.o nv04_crtc.o nv04_cursor.o \
-+	     nv04_fbcon.o
++             nv04_fbcon.o
 +
 +nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
++nouveau-$(CONFIG_DRM_NOUVEAU_BACKLIGHT) += nouveau_backlight.o
 +
 +obj-$(CONFIG_DRM_NOUVEAU)+= nouveau.o
 diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c
 new file mode 100644
-index 0000000..395639b
+index 0000000..20564f8
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
-@@ -0,0 +1,154 @@
+@@ -0,0 +1,155 @@
 +/*
 + * Copyright (C) 2009 Red Hat <mjg at redhat.com>
 + *
@@ -172,7 +184,8 @@ index 0000000..395639b
 +static int nv40_get_intensity(struct backlight_device *bd)
 +{
 +	struct drm_device *dev = bl_get_data(bd);
-+	int val = (nv_rd32(NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK) >> 16;
++	int val = (nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK)
++									>> 16;
 +
 +	return val;
 +}
@@ -181,9 +194,9 @@ index 0000000..395639b
 +{
 +	struct drm_device *dev = bl_get_data(bd);
 +	int val = bd->props.brightness;
-+	int reg = nv_rd32(NV40_PMC_BACKLIGHT);
++	int reg = nv_rd32(dev, NV40_PMC_BACKLIGHT);
 +
-+	nv_wr32(NV40_PMC_BACKLIGHT,
++	nv_wr32(dev, NV40_PMC_BACKLIGHT,
 +		 (val << 16) | (reg & ~NV40_PMC_BACKLIGHT_MASK));
 +
 +	return 0;
@@ -199,7 +212,7 @@ index 0000000..395639b
 +{
 +	struct drm_device *dev = bl_get_data(bd);
 +
-+	return nv_rd32(NV50_PDISPLAY_BACKLIGHT);
++	return nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT);
 +}
 +
 +static int nv50_set_intensity(struct backlight_device *bd)
@@ -207,8 +220,8 @@ index 0000000..395639b
 +	struct drm_device *dev = bl_get_data(bd);
 +	int val = bd->props.brightness;
 +
-+	nv_wr32(NV50_PDISPLAY_BACKLIGHT, val | NV50_PDISPLAY_BACKLIGHT_ENABLE);
-+
++	nv_wr32(dev, NV50_PDISPLAY_SOR_BACKLIGHT,
++		val | NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE);
 +	return 0;
 +}
 +
@@ -223,7 +236,7 @@ index 0000000..395639b
 +	struct drm_nouveau_private *dev_priv = dev->dev_private;
 +	struct backlight_device *bd;
 +
-+	if (!(nv_rd32(NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK))
++	if (!(nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK))
 +		return 0;
 +
 +	bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev,
@@ -244,7 +257,7 @@ index 0000000..395639b
 +	struct drm_nouveau_private *dev_priv = dev->dev_private;
 +	struct backlight_device *bd;
 +
-+	if (!nv_rd32(NV50_PDISPLAY_BACKLIGHT))
++	if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT))
 +		return 0;
 +
 +	bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev,
@@ -265,13 +278,13 @@ index 0000000..395639b
 +
 +	switch (dev_priv->card_type) {
 +	case NV_40:
-+	case NV_44:
 +		return nouveau_nv40_backlight_init(dev);
-+		break;
 +	case NV_50:
 +		return nouveau_nv50_backlight_init(dev);
++	default:
 +		break;
 +	}
++
 +	return 0;
 +}
 +
@@ -286,10 +299,10 @@ index 0000000..395639b
 +}
 diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
 new file mode 100644
-index 0000000..f719eb4
+index 0000000..defc0c8
 --- /dev/null
 +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
-@@ -0,0 +1,4861 @@
+@@ -0,0 +1,5056 @@
 +/*
 + * Copyright 2005-2006 Erik Waling
 + * Copyright 2006 Stephane Marchesin
@@ -396,17 +409,17 @@ index 0000000..f719eb4
 +		  save_pci_nv_20 & ~NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED);
 +
 +	/* bail if no rom signature */
-+	if (nv_rd08(NV_PROM_OFFSET) != 0x55 ||
-+	    nv_rd08(NV_PROM_OFFSET + 1) != 0xaa)
++	if (nv_rd08(dev, NV_PROM_OFFSET) != 0x55 ||
++	    nv_rd08(dev, NV_PROM_OFFSET + 1) != 0xaa)
 +		goto out;
 +
 +	/* additional check (see note below) - read PCI record header */
-+	pcir_ptr = nv_rd08(NV_PROM_OFFSET + 0x18) |
-+		   nv_rd08(NV_PROM_OFFSET + 0x19) << 8;
-+	if (nv_rd08(NV_PROM_OFFSET + pcir_ptr) != 'P' ||
-+	    nv_rd08(NV_PROM_OFFSET + pcir_ptr + 1) != 'C' ||
-+	    nv_rd08(NV_PROM_OFFSET + pcir_ptr + 2) != 'I' ||
-+	    nv_rd08(NV_PROM_OFFSET + pcir_ptr + 3) != 'R')
++	pcir_ptr = nv_rd08(dev, NV_PROM_OFFSET + 0x18) |
++		   nv_rd08(dev, NV_PROM_OFFSET + 0x19) << 8;
[...16454 lines suppressed...]
 +
-+#define NOUVEAU_DRM_HEADER_PATCHLEVEL 14
++#define NOUVEAU_DRM_HEADER_PATCHLEVEL 15
 +
 +struct drm_nouveau_channel_alloc {
 +	uint32_t     fb_ctxdma_handle;
@@ -54133,8 +54610,7 @@ index 0000000..dc6a194
 +	int          channel;
 +
 +	/* Notifier memory */
-+	drm_handle_t notifier;
-+	int          notifier_size;
++	uint32_t     notifier_handle;
 +
 +	/* DRM-enforced subchannel assignments */
 +	struct {
@@ -54142,15 +54618,6 @@ index 0000000..dc6a194
 +		uint32_t grclass;
 +	} subchan[8];
 +	uint32_t nr_subchan;
-+
-+/* !MM_ENABLED ONLY */
-+	uint32_t     put_base;
-+	/* FIFO control regs */
-+	drm_handle_t ctrl;
-+	int          ctrl_size;
-+	/* DMA command buffer */
-+	drm_handle_t cmdbuf;
-+	int          cmdbuf_size;
 +};
 +
 +struct drm_nouveau_channel_free {
@@ -54163,14 +54630,10 @@ index 0000000..dc6a194
 +	int      class;
 +};
 +
-+#define NOUVEAU_MEM_ACCESS_RO	1
-+#define NOUVEAU_MEM_ACCESS_WO	2
-+#define NOUVEAU_MEM_ACCESS_RW	3
 +struct drm_nouveau_notifierobj_alloc {
-+	int      channel;
++	uint32_t channel;
 +	uint32_t handle;
-+	int      count;
-+
++	uint32_t size;
 +	uint32_t offset;
 +};
 +
@@ -54179,52 +54642,6 @@ index 0000000..dc6a194
 +	uint32_t handle;
 +};
 +
-+/* This is needed to avoid a race condition.
-+ * Otherwise you may be writing in the fetch area.
-+ * Is this large enough, as it's only 32 bytes, and the maximum fetch size is 256 bytes?
-+ */
-+#define NOUVEAU_DMA_SKIPS 8
-+
-+#define NOUVEAU_MEM_FB			0x00000001
-+#define NOUVEAU_MEM_AGP			0x00000002
-+#define NOUVEAU_MEM_FB_ACCEPTABLE	0x00000004
-+#define NOUVEAU_MEM_AGP_ACCEPTABLE	0x00000008
-+#define NOUVEAU_MEM_PCI			0x00000010
-+#define NOUVEAU_MEM_PCI_ACCEPTABLE	0x00000020
-+#define NOUVEAU_MEM_PINNED		0x00000040
-+#define NOUVEAU_MEM_USER_BACKED		0x00000080
-+#define NOUVEAU_MEM_MAPPED		0x00000100
-+#define NOUVEAU_MEM_TILE		0x00000200
-+#define NOUVEAU_MEM_TILE_ZETA		0x00000400
-+#define NOUVEAU_MEM_INSTANCE		0x01000000 /* internal */
-+#define NOUVEAU_MEM_NOTIFIER            0x02000000 /* internal */
-+#define NOUVEAU_MEM_NOVM		0x04000000 /* internal */
-+#define NOUVEAU_MEM_USER		0x08000000 /* internal */
-+#define NOUVEAU_MEM_INTERNAL (NOUVEAU_MEM_INSTANCE | \
-+			      NOUVEAU_MEM_NOTIFIER | \
-+			      NOUVEAU_MEM_NOVM | \
-+			      NOUVEAU_MEM_USER)
-+
-+struct drm_nouveau_mem_alloc {
-+	int flags;
-+	int alignment;
-+	uint64_t size;	// in bytes
-+	uint64_t offset;
-+	drm_handle_t map_handle;
-+};
-+
-+struct drm_nouveau_mem_free {
-+	uint64_t offset;
-+	int flags;
-+};
-+
-+struct drm_nouveau_mem_tile {
-+	uint64_t offset;
-+	uint64_t delta;
-+	uint64_t size;
-+	int flags;
-+};
-+
 +/* FIXME : maybe unify {GET,SET}PARAMs */
 +#define NOUVEAU_GETPARAM_PCI_VENDOR      3
 +#define NOUVEAU_GETPARAM_PCI_DEVICE      4
@@ -54235,15 +54652,12 @@ index 0000000..dc6a194
 +#define NOUVEAU_GETPARAM_AGP_SIZE        9
 +#define NOUVEAU_GETPARAM_PCI_PHYSICAL    10
 +#define NOUVEAU_GETPARAM_CHIPSET_ID      11
-+#define NOUVEAU_GETPARAM_MM_ENABLED      12
-+#define NOUVEAU_GETPARAM_VM_VRAM_BASE    13
++#define NOUVEAU_GETPARAM_VM_VRAM_BASE    12
 +struct drm_nouveau_getparam {
 +	uint64_t param;
 +	uint64_t value;
 +};
 +
-+#define NOUVEAU_SETPARAM_CMDBUF_LOCATION 1
-+#define NOUVEAU_SETPARAM_CMDBUF_SIZE     2
 +struct drm_nouveau_setparam {
 +	uint64_t param;
 +	uint64_t value;
@@ -54327,8 +54741,12 @@ index 0000000..dc6a194
 +	uint32_t handle;
 +};
 +
++#define NOUVEAU_GEM_CPU_PREP_NOWAIT                                  0x00000001
++#define NOUVEAU_GEM_CPU_PREP_NOBLOCK                                 0x00000002
++#define NOUVEAU_GEM_CPU_PREP_WRITE                                   0x00000004
 +struct drm_nouveau_gem_cpu_prep {
 +	uint32_t handle;
++	uint32_t flags;
 +};
 +
 +struct drm_nouveau_gem_cpu_fini {
@@ -54337,38 +54755,19 @@ index 0000000..dc6a194
 +
 +struct drm_nouveau_gem_tile {
 +	uint32_t handle;
-+	uint32_t delta;
++	uint32_t offset;
 +	uint32_t size;
-+	uint32_t flags;
-+};
-+
-+enum nouveau_card_type {
-+	NV_UNKNOWN =0,
-+	NV_04      =4,
-+	NV_05      =5,
-+	NV_10      =10,
-+	NV_11      =11,
-+	NV_17      =17,
-+	NV_20      =20,
-+	NV_30      =30,
-+	NV_40      =40,
-+	NV_44      =44,
-+	NV_50      =50,
-+	NV_LAST    =0xffff,
++	uint32_t tile_mode;
++	uint32_t tile_flags;
 +};
 +
 +enum nouveau_bus_type {
-+	NV_AGP     =0,
-+	NV_PCI     =1,
-+	NV_PCIE    =2,
++	NV_AGP     = 0,
++	NV_PCI     = 1,
++	NV_PCIE    = 2,
 +};
 +
-+#define NOUVEAU_MAX_SAREA_CLIPRECTS 16
-+
 +struct drm_nouveau_sarea {
-+	/* the cliprects */
-+	struct drm_clip_rect boxes[NOUVEAU_MAX_SAREA_CLIPRECTS];
-+	unsigned int nbox;
 +};
 +
 +#define DRM_NOUVEAU_CARD_INIT          0x00
@@ -54379,19 +54778,13 @@ index 0000000..dc6a194
 +#define DRM_NOUVEAU_GROBJ_ALLOC        0x05
 +#define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC  0x06
 +#define DRM_NOUVEAU_GPUOBJ_FREE        0x07
-+#define DRM_NOUVEAU_MEM_ALLOC          0x08
-+#define DRM_NOUVEAU_MEM_FREE           0x09
-+#define DRM_NOUVEAU_MEM_TILE           0x0a
-+#define DRM_NOUVEAU_SUSPEND            0x0b
-+#define DRM_NOUVEAU_RESUME             0x0c
 +#define DRM_NOUVEAU_GEM_NEW            0x40
 +#define DRM_NOUVEAU_GEM_PUSHBUF        0x41
 +#define DRM_NOUVEAU_GEM_PUSHBUF_CALL   0x42
-+#define DRM_NOUVEAU_GEM_PIN            0x43
-+#define DRM_NOUVEAU_GEM_UNPIN          0x44
++#define DRM_NOUVEAU_GEM_PIN            0x43 /* !KMS only */
++#define DRM_NOUVEAU_GEM_UNPIN          0x44 /* !KMS only */
 +#define DRM_NOUVEAU_GEM_CPU_PREP       0x45
 +#define DRM_NOUVEAU_GEM_CPU_FINI       0x46
-+#define DRM_NOUVEAU_GEM_TILE           0x47
-+#define DRM_NOUVEAU_GEM_INFO           0x48
++#define DRM_NOUVEAU_GEM_INFO           0x47
 +
 +#endif /* __NOUVEAU_DRM_H__ */


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.1294.2.43
retrieving revision 1.1294.2.44
diff -u -p -r1.1294.2.43 -r1.1294.2.44
--- kernel.spec	15 Jul 2009 22:20:03 -0000	1.1294.2.43
+++ kernel.spec	5 Aug 2009 23:00:15 -0000	1.1294.2.44
@@ -1,9 +1,12 @@
+# We have to override the new %%install behavior because, well... the kernel is special.
+%global __spec_install_pre %{___build_pre}
+
 Summary: The Linux kernel
 
 # For a stable, released kernel, released_kernel should be 1. For rawhide
 # and/or a kernel built from an rc or git snapshot, released_kernel should
 # be 0.
-%define released_kernel 0
+%global released_kernel 0
 
 # Versions of various parts
 
@@ -57,9 +60,9 @@ Summary: The Linux kernel
 # The next upstream release sublevel (base_sublevel+1)
 %define upstream_sublevel %(echo $((%{base_sublevel} + 1)))
 # The rc snapshot level
-%define rcrev 3
+%define rcrev 5
 # The git snapshot level
-%define gitrev 0
+%define gitrev 3
 # Set rpm version accordingly
 %define rpmversion 2.6.%{upstream_sublevel}
 %endif
@@ -98,6 +101,8 @@ Summary: The Linux kernel
 %define with_bootwrapper %{?_without_bootwrapper: 0} %{?!_without_bootwrapper: 1}
 # Want to build a the vsdo directories installed
 %define with_vdso_install %{?_without_vdso_install: 0} %{?!_without_vdso_install: 1}
+# dracut initrd-generic
+%define with_dracut       %{?_without_dracut:       0} %{?!_without_dracut:       1}
 
 # Build the kernel-doc package, but don't fail the build if it botches.
 # Here "true" means "continue" and "false" means "fail the build".
@@ -196,9 +201,8 @@ Summary: The Linux kernel
 %endif
 %define debuginfodir /usr/lib/debug
 
-# We only build -PAE for 686 as of Fedora 11.
+# kernel-PAE is only built on i686.
 %ifarch i686
-%define with_up 0
 %define with_pae 1
 %else
 %define with_pae 0
@@ -218,7 +222,7 @@ Summary: The Linux kernel
 %define with_debug 0
 %endif
 
-%define all_x86 i386 i586 i686
+%define all_x86 i386 i686
 
 %if %{with_vdso_install}
 # These arches install vdso/ directories.
@@ -250,12 +254,6 @@ Summary: The Linux kernel
 %define with_perf 0
 %endif
 
-# no need to build headers again for these arches,
-# they can just use i586 and ppc64 headers
-%ifarch i686 ppc64iseries
-%define with_headers 0
-%endif
-
 # don't build noarch kernels or headers (duh)
 %ifarch noarch
 %define with_up 0
@@ -375,7 +373,7 @@ Summary: The Linux kernel
 
 # We don't build a kernel on i386; we only do kernel-headers there,
 # and we no longer build for 31bit S390. Same for 32bit sparc and arm.
-%define nobuildarches i386 i586 ppc ppc64 ia64 sparc sparc64 390 s390x alpha alphaev56 %{arm}
+%define nobuildarches i386 ppc ppc64 ia64 sparc sparc64 390 s390x alpha alphaev56 %{arm}
 
 %ifarch %nobuildarches
 %define with_up 0
@@ -444,7 +442,7 @@ Summary: The Linux kernel
 Provides: kernel = %{rpmversion}-%{pkg_release}\
 Provides: kernel-%{_target_cpu} = %{rpmversion}-%{pkg_release}%{?1:.%{1}}\
 Provides: kernel-drm = 4.3.0\
-Provides: kernel-drm-nouveau = 14\
+Provides: kernel-drm-nouveau = 15\
 Provides: kernel-modeset = 1\
 Provides: kernel-uname-r = %{KVERREL}%{?1:.%{1}}\
 Requires(pre): %{kernel_prereq}\
@@ -491,7 +489,11 @@ BuildRequires: xmlto
 BuildRequires: sparse >= 0.4.1
 %endif
 %if %{with_perftool}
-BuildRequires: elfutils-libelf-devel zlib-devel
+BuildRequires: elfutils-libelf-devel zlib-devel binutils-devel
+%endif
+%if %{with_dracut}
+BuildRequires: dracut-kernel >= 0.7
+BuildRequires: dracut-generic >= 0.7
 %endif
 BuildConflicts: rhbuildsys(DiskFree) < 500Mb
 
@@ -521,8 +523,7 @@ Source23: config-generic
 Source24: config-rhel-generic
 
 Source30: config-x86-generic
-Source31: config-i586
-Source32: config-i686-PAE
+Source31: config-i686-PAE
 
 Source40: config-x86_64-generic
 
@@ -588,6 +589,8 @@ Patch05: linux-2.6-makefile-after_link.p
 
 %if !%{nopatches}
 
+# revert powerpc breakage
+Patch08: revert-ftrace-powerpc-snafu.patch
 # revert upstream patches we get via other methods
 Patch09: linux-2.6-upstream-reverts.patch
 # Git trees.
@@ -608,6 +611,7 @@ Patch141: linux-2.6-ps3-storage-alias.pa
 Patch143: linux-2.6-g5-therm-shutdown.patch
 Patch144: linux-2.6-vio-modalias.patch
 Patch147: linux-2.6-imac-transparent-bridge.patch
+Patch148: linux-2.6-ppc-perfctr-oops-fix.patch
 
 Patch150: linux-2.6.29-sparc-IOC_TYPECHECK.patch
 
@@ -617,25 +621,35 @@ Patch250: linux-2.6-debug-sizeof-structs
 Patch260: linux-2.6-debug-nmi-timeout.patch
 Patch270: linux-2.6-debug-taint-vm.patch
 Patch280: linux-2.6-debug-spinlock-taint.patch
+Patch300: linux-2.6-driver-level-usb-autosuspend.diff
+Patch301: linux-2.6-fix-usb-serial-autosuspend.diff
+Patch302: linux-2.6-qcserial-autosuspend.diff
+Patch303: linux-2.6-bluetooth-autosuspend.diff
+Patch304: linux-2.6-usb-uvc-autosuspend.diff
 Patch340: linux-2.6-debug-vm-would-have-oomkilled.patch
 Patch360: linux-2.6-debug-always-inline-kzalloc.patch
 Patch380: linux-2.6-defaults-pci_no_msi.patch
 Patch381: linux-2.6-pciehp-update.patch
 Patch382: linux-2.6-defaults-pciehp.patch
+Patch383: linux-2.6-defaults-aspm.patch
 Patch390: linux-2.6-defaults-acpi-video.patch
 Patch391: linux-2.6-acpi-video-dos.patch
 Patch450: linux-2.6-input-kill-stupid-messages.patch
 Patch451: linux-2.6-input-fix-toshiba-hotkeys.patch
+Patch452: linux-2.6.30-no-pcspkr-modalias.patch
 
 Patch460: linux-2.6-serial-460800.patch
 
 Patch510: linux-2.6-silence-noise.patch
+Patch520: linux-2.6.30-hush-rom-warning.patch
 Patch530: linux-2.6-silence-fbcon-logo.patch
 Patch570: linux-2.6-selinux-mprotect-checks.patch
 Patch580: linux-2.6-sparc-selinux-mprotect-checks.patch
 
 Patch600: linux-2.6-defaults-alsa-hda-beep-off.patch
+Patch601: linux-2.6-alsa-improve-hda-powerdown.patch
 Patch610: hda_intel-prealloc-4mb-dmabuffer.patch
+Patch611: alsa-tell-user-that-stream-to-be-rewound-is-suspended.patch
 
 Patch670: linux-2.6-ata-quirk.patch
 
@@ -646,19 +660,28 @@ Patch800: linux-2.6-crash-driver.patch
 
 Patch900: linux-2.6-pci-cacheline-sizing.patch
 
-Patch1000: linux-2.6-cpufreq-ppc-suspend-clusterfuck.patch
-
 Patch1515: linux-2.6.31-lirc.patch
 Patch1516: lirc_streamzap-buffer-rework.patch
 Patch1517: hdpvr-ir-enable.patch
+Patch1518: hid-ignore-all-recent-imon-devices.patch
+
+Patch1550: linux-2.6-ksm.patch
+Patch1551: linux-2.6-ksm-kvm.patch
 
 # nouveau + drm fixes
-Patch1811: drm-next.patch
-Patch1812: drm-modesetting-radeon.patch
 Patch1813: drm-radeon-pm.patch
 Patch1814: drm-nouveau.patch
 Patch1818: drm-i915-resume-force-mode.patch
 Patch1819: drm-intel-big-hammer.patch
+Patch1821: drm-page-flip.patch
+# anholt's tree as of 2009-08-03
+Patch1824: drm-intel-next.patch
+Patch1825: drm-intel-pm.patch
+Patch1826: drm-r600-kms.patch
+
+# vga arb
+Patch1900: linux-2.6-vga-arb.patch
+Patch1901: drm-vga-arb.patch
 
 # kludge to make ich9 e1000 work
 Patch2000: linux-2.6-e1000-ich9.patch
@@ -685,6 +708,7 @@ Patch3050: linux-2.6-nfsd4-proots.patch
 Patch11010: via-hwmon-temp-sensor.patch
 
 # patches headed upstream
+Patch12010: linux-2.6-dell-laptop-rfkill-fix.patch
 
 Patch19997: xen.pvops.pre.patch
 Patch19998: xen.pvops.patch
@@ -1091,6 +1115,7 @@ ApplyOptionalPatch linux-2.6-compile-fix
 # revert patches from upstream that conflict or that we get via other means
 ApplyOptionalPatch linux-2.6-upstream-reverts.patch -R
 
+ApplyPatch revert-ftrace-powerpc-snafu.patch
 #ApplyPatch git-cpufreq.patch
 #ApplyPatch git-bluetooth.patch
 
@@ -1108,6 +1133,7 @@ ApplyPatch sched-introduce-SCHED_RESET_O
 # Architecture patches
 # x86(-64)
 ApplyPatch via-hwmon-temp-sensor.patch
+ApplyPatch linux-2.6-dell-laptop-rfkill-fix.patch
 
 #
 # PowerPC
@@ -1123,6 +1149,8 @@ ApplyPatch linux-2.6-g5-therm-shutdown.p
 ApplyPatch linux-2.6-vio-modalias.patch
 # Work around PCIe bridge setup on iSight
 ApplyPatch linux-2.6-imac-transparent-bridge.patch
+# Fix oops in 7450 perfctr
+ApplyPatch linux-2.6-ppc-perfctr-oops-fix.patch
 
 #
 # SPARC64
@@ -1144,10 +1172,17 @@ ApplyPatch linux-2.6-execshield.patch
 
 # btrfs
 
+# eCryptfs
+
 # NFSv4
 ApplyPatch linux-2.6-nfsd4-proots.patch
 
 # USB
+ApplyPatch linux-2.6-driver-level-usb-autosuspend.diff
+ApplyPatch linux-2.6-fix-usb-serial-autosuspend.diff
+ApplyPatch linux-2.6-qcserial-autosuspend.diff
+ApplyPatch linux-2.6-bluetooth-autosuspend.diff
+ApplyPatch linux-2.6-usb-uvc-autosuspend.diff
 
 # ACPI
 ApplyPatch linux-2.6-defaults-acpi-video.patch
@@ -1170,6 +1205,8 @@ ApplyPatch linux-2.6-defaults-pci_no_msi
 #ApplyPatch linux-2.6-pciehp-update.patch
 # default to enabling passively listening for hotplug events
 #ApplyPatch linux-2.6-defaults-pciehp.patch
+# enable ASPM by default on hardware we expect to work
+ApplyPatch linux-2.6-defaults-aspm.patch
 
 #
 # SCSI Bits.
@@ -1178,7 +1215,9 @@ ApplyPatch linux-2.6-defaults-pci_no_msi
 # ALSA
 # squelch hda_beep by default
 ApplyPatch linux-2.6-defaults-alsa-hda-beep-off.patch
+ApplyPatch linux-2.6-alsa-improve-hda-powerdown.patch
 ApplyPatch hda_intel-prealloc-4mb-dmabuffer.patch
+ApplyPatch alsa-tell-user-that-stream-to-be-rewound-is-suspended.patch
 
 # Networking
 
@@ -1189,11 +1228,14 @@ ApplyPatch linux-2.6-input-kill-stupid-m
 # Get away from having to poll Toshibas
 #ApplyPatch linux-2.6-input-fix-toshiba-hotkeys.patch
 
+ApplyPatch linux-2.6.30-no-pcspkr-modalias.patch
+
 # Allow to use 480600 baud on 16C950 UARTs
 ApplyPatch linux-2.6-serial-460800.patch
 
 # Silence some useless messages that still get printed with 'quiet'
 ApplyPatch linux-2.6-silence-noise.patch
+ApplyPatch linux-2.6.30-hush-rom-warning.patch
 
 # Make fbcon not show the penguins with 'quiet'
 ApplyPatch linux-2.6-silence-fbcon-logo.patch
@@ -1221,25 +1263,37 @@ ApplyPatch linux-2.6-crash-driver.patch
 # Determine cacheline sizes in a generic manner.
 ApplyPatch linux-2.6-pci-cacheline-sizing.patch
 
-ApplyPatch linux-2.6-cpufreq-ppc-suspend-clusterfuck.patch
-
 # http://www.lirc.org/
 ApplyPatch linux-2.6.31-lirc.patch
 # should be a short-lived patch, hopefully fixing bz#508952 w/o breaking anything else...
 ApplyPatch lirc_streamzap-buffer-rework.patch
 # enable IR receiver on Hauppauge HD PVR (v4l-dvb merge pending)
 ApplyPatch hdpvr-ir-enable.patch
+# tell usbhid to ignore all imon devices (sent upstream 2009.07.31)
+ApplyPatch hid-ignore-all-recent-imon-devices.patch
+
+# Add kernel KSM support
+ApplyPatch linux-2.6-ksm.patch
+# Optimize KVM for KSM support
+ApplyPatch linux-2.6-ksm-kvm.patch
 
 ApplyPatch linux-2.6-e1000-ich9.patch
 
 # Nouveau DRM + drm fixes
-#ApplyPatch drm-next.patch
-#ApplyPatch drm-modesetting-radeon.patch
+ApplyPatch drm-r600-kms.patch
+
 ApplyPatch drm-nouveau.patch
 # pm broken on my thinkpad t60p - airlied
 #ApplyPatch drm-radeon-pm.patch
 ApplyPatch drm-i915-resume-force-mode.patch
 ApplyPatch drm-intel-big-hammer.patch
+ApplyPatch drm-page-flip.patch
+ApplyPatch drm-intel-next.patch
+ApplyPatch drm-intel-pm.patch
+
+# VGA arb + drm
+ApplyPatch linux-2.6-vga-arb.patch
+ApplyPatch drm-vga-arb.patch
 
 # linux1394 git patches
 #ApplyPatch linux-2.6-firewire-git-update.patch
@@ -1627,7 +1681,7 @@ ls $man9dir | grep -q '' || > $man9dir/B
 mkdir -p $RPM_BUILD_ROOT/usr/sbin
 cat <<EOF >>$RPM_BUILD_ROOT/usr/sbin/perf
 #!/bin/bash
-exec /usr/libexec/perf-`uname -r`
+exec /usr/libexec/perf-\$(uname -r)
 EOF
 chmod 755 $RPM_BUILD_ROOT/usr/sbin/perf
 mkdir -p $RPM_BUILD_ROOT%{_datadir}/doc/perf
@@ -1665,6 +1719,27 @@ make INSTALL_FW_PATH=$RPM_BUILD_ROOT/lib
 make DESTDIR=$RPM_BUILD_ROOT bootwrapper_install WRAPPER_OBJDIR=%{_libdir}/kernel-wrapper WRAPPER_DTSDIR=%{_libdir}/kernel-wrapper/dts
 %endif
 
+%if %{with_dracut}
+%if !%{with_firmware}
+# dracut needs the firmware files
+    make INSTALL_FW_PATH=$RPM_BUILD_ROOT/lib/firmware firmware_install
+%endif
+    for i in $RPM_BUILD_ROOT/lib/modules/*; do
+	[ -d $i ] || continue
+	KernelVer=${i##$RPM_BUILD_ROOT/lib/modules/}
+        depmod -b $RPM_BUILD_ROOT $KernelVer
+    	dracut  --strip \
+	    --fwdir $RPM_BUILD_ROOT/lib/firmware:/lib/firmware \
+            -k $i $RPM_BUILD_ROOT/boot/initrd-generic-${KernelVer}.img $KernelVer
+	rm -fr $i/modules.dep
+    done
+%if !%{with_firmware}
+# remove the firmware files, if ! with_firmware
+    rm -fr $RPM_BUILD_ROOT/lib/firmware 
+%endif
+%endif
+
+
 ###
 ### clean
 ###
@@ -1836,6 +1911,9 @@ fi
 %endif\
 /lib/modules/%{KVERREL}%{?2:.%{2}}/modules.*\
 %ghost /boot/initrd-%{KVERREL}%{?2:.%{2}}.img\
+%if %{with_dracut}\
+/boot/initrd-generic-%{KVERREL}%{?2:.%{2}}.img\
+%endif\
 %{expand:%%files %{?2:%{2}-}devel}\
 %defattr(-,root,root)\
 %dir /usr/src/kernels\
@@ -1875,6 +1953,197 @@ fi
 # and build.
 
 %changelog
+* Wed Aug 05 2009 Dave Airlie <airlied at redhat.com> 2.6.31.0.132.rc5.git3
+- revert-ftrace-powerpc-snafu.patch - fix ppc build
+
+* Wed Aug 05 2009 Ben Skeggs <bskeggs at redhat.com>
+- nouveau: respect nomodeset
+
+* Wed Aug 05 2009 Chuck Ebbert <cebbert at redhat.com>
+- Fix /usr/sbin/perf script. (#515494)
+
+* Wed Aug 05 2009 Dave Jones <davej at redhat.com>
+- Fix shift in pci cacheline size printk.
+
+* Wed Aug 05 2009 Dave Airlie <airlied at redhat.com> 2.6.31.0.128.rc5.git3
+- 2.6.31-rc5-git3
+- drop cpufreq + set memory fixes
+
+* Wed Aug 05 2009 Dave Airlie <airlied at redhat.com>
+- Add Jeromes initial r600 kms work.
+- rebase arb patch
+
+* Tue Aug 04 2009 Kyle McMartin <kyle at redhat.com>
+- alsa-tell-user-that-stream-to-be-rewound-is-suspended.patch: apply patch
+  destined for 2.6.32, requested by Lennart.
+
+* Tue Aug 04 2009 Ben Skeggs <bskeggs at redhat.com>
+- nouveau: more code share between nv50/<nv50 kms, bug fixes
+
+* Tue Aug 04 2009 Dave Airlie <airlied at redhat.com>
+- update VGA arb patches again
+
+* Mon Aug 03 2009 Adam Jackson <ajax at redhat.com>
+- Update intel drm from anholt's tree
+- Rebase drm-intel-pm.patch to match
+- Drop gen3 fb hack, merged
+- Drop previous watermark setup change
+
+* Mon Aug 03 2009 Dave Jones <davej at redhat.com> 2.6.31-0.122.rc5.git2
+- 2.6.31-rc5-git2
+
+* Mon Aug 03 2009 Adam Jackson <ajax at redhat.com>
+- (Attempt to) fix watermark setup on Intel 9xx parts.
+
+* Mon Aug 03 2009 Jarod Wilson <jarod at redhat.com>
+- make usbhid driver ignore all recent SoundGraph iMON devices, so the
+  lirc_imon driver can grab them instead
+
+* Mon Aug 03 2009 Dave Airlie <airlied at redhat.com>
+- update VGA arb patches
+
+* Sat Aug 01 2009 David Woodhouse <David.Woodhouse at intel.com> 2.6.31-0.118.rc5
+- Fix boot failures on ppc32 (#514010, #505071)
+
+* Fri Jul 31 2009 Kyle McMartin <kyle at redhat.com> 2.6.31-0.117.rc5
+- Linux 2.6.31-rc5
+
+* Fri Jul 31 2009 Matthew Garrett <mjg at redhat.com>
+- linux-2.6-dell-laptop-rfkill-fix.patch: Fix up Dell rfkill
+
+* Fri Jul 31 2009 Ben Skeggs <bskeggs at redhat.com>
+- nouveau: build against 2.6.31-rc4-git6, fix script parsing on some G8x chips
+
+* Thu Jul 30 2009 Chuck Ebbert <cebbert at redhat.com>
+- Linux 2.6.31-rc4-git6
+  New config item: CONFIG_BATTERY_DS2782 is not set
+- Add last-minute set_memory_wc() fix from LKML.
+
+* Thu Jul 30 2009 Matthew Garrett <mjg at redhat.com>
+- drm-intel-pm.patch: Don't reclock external outputs. Increase the reduced
+   clock slightly to avoid upsetting some hardware. Disable renderclock
+   adjustment for the moment - it's breaking on some hardware.
+
+* Thu Jul 30 2009 Ben Skeggs <bskeggs at redhat.com>
+- nouveau: another DCB 1.5 entry, G80 corruption fixes, small <G80 KMS fix
+
+* Thu Jul 30 2009 Dave Airlie <airlied at redhat.com> 
+- fix VGA ARB + kms
+
+* Wed Jul 29 2009 Dave Jones <davej at redhat.com>
+- Add support for dracut. (Harald Hoyer)
+
+* Wed Jul 29 2009 Ben Skeggs <bskeggs at redhat.com>
+- drm-nouveau.patch: nv50/nva0 tiled scanout fixes, nv40 kms fixes
+
+* Wed Jul 29 2009 Chuck Ebbert <cebbert at redhat.com>
+- Linux 2.6.31-rc4-git3
+- Drop linux-2.6-ecryptfs-overflow-fixes.patch, merged upstream now.
+
+* Wed Jul 29 2009 Dave Airlie <airlied at redhat.com>
+- update VGA arb patches
+
+* Tue Jul 28 2009 Adam Jackson <ajax at redhat.com>
+- Remove the pcspkr modalias.  If you're still living in 1994, load it
+  by hand.
+
+* Tue Jul 28 2009 Eric Sandeen <sandeen at redhat.com> 2.6.31-0.102.rc4.git2
+- Fix eCryptfs overflow issues (CVE-2009-2406, CVE-2009-2407)
+
+* Tue Jul 28 2009 Kyle McMartin <kyle at redhat.com> 2.6.31-0.101.rc4.git2
+- 2.6.31-rc4-git2
+- rebase linux-2.6-fix-usb-serial-autosuspend.diff
+- config changes:
+ - USB_GSPCA_SN9C20X=m (_EVDEV=y)
+
+* Tue Jul 28 2009 Ben Skeggs <bskeggs at redhat.com>
+- drm-nouveau.patch: cleanup userspace API, various bugfixes.
+  Looks worse than it is, register macros got cleaned up, which
+  touches pretty much everywhere..
+
+* Mon Jul 27 2009 Adam Jackson <ajax at redhat.com>
+- Warn quieter about not finding PCI bus parents for ROM BARs, they're
+  not usually needed and there's nothing you can do about it anyway.
+
+* Mon Jul 27 2009 Matthew Garrett <mjg at redhat.com>
+- linux-2.6-alsa-improve-hda-powerdown.patch - attempt to reduce audio glitches
+   caused by HDA powerdown
+- disable CONFIG_DEBUG_KOBJECT again for now, since it produces huge dmesg spew
+
+* Mon Jul 27 2009 Dave Airlie <airlied at redhat.com>
+- update vga arb code
+
+* Mon Jul 27 2009 Matthew Garrett <mjg at redhat.com>
+- drm-intel-pm.patch - Add runtime PM for Intel graphics
+
+* Fri Jul 24 2009 Kristian Høgsberg <krh at redhat.com>
+- Add drm-page-flip.patch to support vsynced page flipping on intel
+  chipsets.
+- Really add patch.
+- Fix patch to not break nouveau.
+
+* Fri Jul 24 2009 Chuck Ebbert <cebbert at redhat.com>
+- Enable CONFIG_DEBUG_KOBJECT in debug kernels. (#513606)
+
+* Thu Jul 23 2009 Kyle McMartin <kyle at redhat.com>
+- perf BuildRequires binutils-devel now.
+
+* Thu Jul 23 2009 Justin M. Forbes <jforbes at redhat.com>
+- Add KSM support
+
+* Thu Jul 23 2009 Kyle McMartin <kyle at redhat.com> 2.6.31-0.87.rc4
+- Linux 2.6.31-rc4
+- config changes:
+ - USB_CDC_PHONET=m [all]
+ - EVENT_PROFILE=y [i386, x86_64, powerpc, s390]
+
+* Wed Jul 22 2009 Tom "spot" Callaway <tcallawa at redhat.com>
+- We have to override the new %%install behavior because, well... the kernel is special.
+
+* Wed Jul 22 2009 Dave Jones <davej at redhat.com>
+- 2.6.31-rc3-git5
+
+* Wed Jul 22 2009 Ben Skeggs <bskeggs at redhat.com> 2.6.31-0.82.rc3.git4
+- Enable KMS for nouveau
+
+* Wed Jul 22 2009 Ben Skeggs <bskeggs at redhat.com>
+- Update nouveau from upstream (initial suspend/resume + misc bugfixes)
+
+* Mon Jul 20 2009 Adam Jackson <ajax at redhat.com>
+- Disable VGA arbiter patches for a moment
+
+* Mon Jul 20 2009 Adam Jackson <ajax at redhat.com>
+- Revive 4k framebuffers for intel gen3
+
+* Mon Jul 20 2009 Dave Jones <davej at redhat.com> 2.6.31-0.78.rc3.git4
+- Enable CONFIG_RTC_HCTOSYS (#489494)
+
+* Mon Jul 20 2009 Dave Jones <davej at redhat.com> 2.6.31-0.77.rc3.git4
+- Don't build 586 kernels any more.
+
+* Sun Jul 19 2009 Dave Jones <davej at redhat.com> 2.6.31-0.75.rc3.git4
+- build a 'full' package on i686 (Bill Nottingham)
+
+* Sun Jul 19 2009 Dave Jones <davej at redhat.com> 2.6.31-0.74.rc3.git4
+- 2.6.31-rc3-git4
+
+* Sat Jul 18 2009 Matthew Garrett <mjg at redhat.com>
+- linux-2.6-driver-level-usb-autosuspend.diff - allow drivers to enable autopm
+- linux-2.6-fix-usb-serial-autosuspend.diff - fix generic usb-serial autopm
+- linux-2.6-qcserial-autosuspend.diff - enable autopm by default on qcserial
+- linux-2.6-bluetooth-autosuspend.diff - enable autopm by default on btusb
+- linux-2.6-usb-uvc-autosuspend.diff - enable autopm by default on uvc
+
+* Thu Jul 16 2009 Chuck Ebbert <cebbert at redhat.com>
+- 2.6.31-rc3-git3
+
+* Thu Jul 16 2009 Matthew Garrett <mjg at redhat.com>
+- linux-2.6-defaults-aspm.patch - default ASPM to on for PCIe >= 1.1 hardware
+
+* Thu Jul 16 2009 Dave Airlie <airlied at redhat.com> 2.6.31-0.69.rc3
+- linux-2.6-vga-arb.patch - add VGA arbiter.
+- drm-vga-arb.patch - add VGA arbiter support to drm
+
 * Wed Jul 15 2009 Michael Young <m.a.young at durham.ac.uk>
 - update pvops patch x2
 
@@ -2672,3 +2941,4 @@ fi
 # rpm-change-log-uses-utc: t
 # End:
 ###
+

linux-2.6-pci-cacheline-sizing.patch:
 common.c |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)

Index: linux-2.6-pci-cacheline-sizing.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-pci-cacheline-sizing.patch,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -p -r1.1.2.2 -r1.1.2.3
--- linux-2.6-pci-cacheline-sizing.patch	27 Jun 2009 11:05:15 -0000	1.1.2.2
+++ linux-2.6-pci-cacheline-sizing.patch	5 Aug 2009 23:00:16 -0000	1.1.2.3
@@ -30,7 +30,7 @@ index 2202b62..f371fe8 100644
 +	if (c->x86_clflush_size > 0) {
 +		pci_cache_line_size = c->x86_clflush_size >> 2;
 +		printk(KERN_DEBUG "PCI: pci_cache_line_size set to %d bytes\n",
-+			pci_cache_line_size >> 2);
++			pci_cache_line_size << 2);
 +	} else {
 +		pci_cache_line_size = 32 >> 2;
 +		printk(KERN_DEBUG "PCI: Unknown cacheline size. Setting to 32 bytes\n");

linux-2.6.31-lirc.patch:
 MAINTAINERS                           |    9 
 drivers/input/Kconfig                 |    2 
 drivers/input/Makefile                |    2 
 drivers/input/lirc/Kconfig            |  112 +
 drivers/input/lirc/Makefile           |   20 
 drivers/input/lirc/lirc.h             |  100 +
 drivers/input/lirc/lirc_bt829.c       |  383 ++++++
 drivers/input/lirc/lirc_dev.c         |  851 ++++++++++++++
 drivers/input/lirc/lirc_dev.h         |  184 +++
 drivers/input/lirc/lirc_i2c.c         |  537 ++++++++
 drivers/input/lirc/lirc_igorplugusb.c |  556 +++++++++
 drivers/input/lirc/lirc_imon.c        | 2062 ++++++++++++++++++++++++++++++++++
 drivers/input/lirc/lirc_it87.c        |  986 ++++++++++++++++
 drivers/input/lirc/lirc_it87.h        |  116 +
 drivers/input/lirc/lirc_ite8709.c     |  539 ++++++++
 drivers/input/lirc/lirc_mceusb.c      | 1223 ++++++++++++++++++++
 drivers/input/lirc/lirc_parallel.c    |  709 +++++++++++
 drivers/input/lirc/lirc_parallel.h    |   26 
 drivers/input/lirc/lirc_sasem.c       |  931 +++++++++++++++
 drivers/input/lirc/lirc_serial.c      | 1316 +++++++++++++++++++++
 drivers/input/lirc/lirc_sir.c         | 1294 +++++++++++++++++++++
 drivers/input/lirc/lirc_streamzap.c   |  777 ++++++++++++
 drivers/input/lirc/lirc_ttusbir.c     |  397 ++++++
 drivers/input/lirc/lirc_zilog.c       | 1374 ++++++++++++++++++++++
 24 files changed, 14506 insertions(+)

Index: linux-2.6.31-lirc.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6.31-lirc.patch,v
retrieving revision 1.2.2.2
retrieving revision 1.2.2.3
diff -u -p -r1.2.2.2 -r1.2.2.3
--- linux-2.6.31-lirc.patch	9 Jul 2009 22:53:02 -0000	1.2.2.2
+++ linux-2.6.31-lirc.patch	5 Aug 2009 23:00:17 -0000	1.2.2.3
@@ -51,8 +51,8 @@ index 381190c..fc79bdf 100644
 +S:	Maintained
 +
  LINUX SECURITY MODULE (LSM) FRAMEWORK
- P:	Chris Wright
- M:	chrisw at sous-sol.org
+ M:	Chris Wright <chrisw at sous-sol.org>
+ L:	linux-security-module at vger.kernel.org
 diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
 index cd50c00..442f94f 100644
 --- a/drivers/input/Kconfig


Index: sources
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/sources,v
retrieving revision 1.976.2.22
retrieving revision 1.976.2.23
diff -u -p -r1.976.2.22 -r1.976.2.23
--- sources	15 Jul 2009 20:58:07 -0000	1.976.2.22
+++ sources	5 Aug 2009 23:00:18 -0000	1.976.2.23
@@ -1,2 +1,3 @@
 7a80058a6382e5108cdb5554d1609615  linux-2.6.30.tar.bz2
-39a1c949531faa70e147d0aa5be6c6ec  patch-2.6.31-rc3.bz2
+09d608a6f10801d34097d0e127e36d5b  patch-2.6.31-rc5.bz2
+6bc3320216b43bd8ce98e5f0565b485f  patch-2.6.31-rc5-git3.bz2


Index: upstream
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/upstream,v
retrieving revision 1.888.2.21
retrieving revision 1.888.2.22
diff -u -p -r1.888.2.21 -r1.888.2.22
--- upstream	15 Jul 2009 20:58:07 -0000	1.888.2.21
+++ upstream	5 Aug 2009 23:00:18 -0000	1.888.2.22
@@ -1,3 +1,3 @@
 linux-2.6.30.tar.bz2
-patch-2.6.31-rc3.bz2
-
+patch-2.6.31-rc5.bz2
+patch-2.6.31-rc5-git3.bz2


--- config-i586 DELETED ---


--- drm-modesetting-radeon.patch DELETED ---


--- drm-next.patch DELETED ---


--- linux-2.6-cpufreq-ppc-suspend-clusterfuck.patch DELETED ---


--- patch-2.6.31-rc3.bz2.sign DELETED ---




More information about the fedora-extras-commits mailing list