Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/agpgart

* master.kernel.org:/pub/scm/linux/kernel/git/davej/agpgart:
  [AGPGART] VIA and SiS AGP chipsets are x86-only
  [AGPGART] agp-amd64: section mismatches with HOTPLUG=n
  [AGPGART] Fix up misprogrammed bridges with incorrect AGPv2 rates.
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index c603bf2..a9f9c48 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -86,7 +86,7 @@
 
 config AGP_SIS
 	tristate "SiS chipset support"
-	depends on AGP
+	depends on AGP && X86
 	help
 	  This option gives you AGP support for the GLX component of
 	  X on Silicon Integrated Systems [SiS] chipsets.
@@ -103,7 +103,7 @@
 
 config AGP_VIA
 	tristate "VIA chipset support"
-	depends on AGP
+	depends on AGP && X86
 	help
 	  This option gives you AGP support for the GLX component of
 	  X on VIA MVP3/Apollo Pro chipsets.
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 5ff457b..883a36a 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -419,6 +419,31 @@
 		*requested_mode &= ~AGP2_RESERVED_MASK;
 	}
 
+	/*
+	 * Some dumb bridges are programmed to disobey the AGP2 spec.
+	 * This is likely a BIOS misprogramming rather than poweron default, or
+	 * it would be a lot more common.
+	 * https://bugs.freedesktop.org/show_bug.cgi?id=8816
+	 * AGPv2 spec 6.1.9 states:
+	 *   The RATE field indicates the data transfer rates supported by this
+	 *   device. A.G.P. devices must report all that apply.
+	 * Fix them up as best we can.
+	 */
+	switch (*bridge_agpstat & 7) {
+	case 4:
+		*bridge_agpstat |= (AGPSTAT2_2X | AGPSTAT2_1X);
+		printk(KERN_INFO PFX "BIOS bug. AGP bridge claims to only support x4 rate"
+			"Fixing up support for x2 & x1\n");
+		break;
+	case 2:
+		*bridge_agpstat |= AGPSTAT2_1X;
+		printk(KERN_INFO PFX "BIOS bug. AGP bridge claims to only support x2 rate"
+			"Fixing up support for x1\n");
+		break;
+	default:
+		break;
+	}
+
 	/* Check the speed bits make sense. Only one should be set. */
 	tmp = *requested_mode & 7;
 	switch (tmp) {