[MTD] Remove PCI dependency for Geode CS553[56] NAND controller.

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Thu May 25 21:59:02 EDT 2006


Commit:     e4d222ff18bca6322f032088a21e9c4a4c038b85
Parent:     89291a9d5b70778e49e2563247c6c7e3efac9b14
Author:     David Woodhouse <dwmw2 at infradead.org>
AuthorDate: Fri May 26 02:06:27 2006 +0100
Commit:     David Woodhouse <dwmw2 at infradead.org>
CommitDate: Fri May 26 02:06:27 2006 +0100

    [MTD] Remove PCI dependency for Geode CS553[56] NAND controller.
    
    PCI is faked on these devices by SMM traps. Don't depend on that --
    check for the chipset directly instead.
    
    Signed-off-by: David Woodhouse <dwmw2 at infradead.org>

 drivers/mtd/nand/Kconfig       |    2 +-
 drivers/mtd/nand/cs553x_nand.c |   33 ++++++++++++++++++++++++++++++---
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index f24408d..d5d4d76 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -211,7 +211,7 @@ config MTD_NAND_SHARPSL
 
 config MTD_NAND_CS553X
 	tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)"
-	depends on MTD_NAND && X86_PC && PCI
+	depends on MTD_NAND && (X86_PC || X86_GENERICARCH)
 	help
 	  The CS553x companion chips for the AMD Geode processor
 	  include NAND flash controllers with built-in hardware ECC
diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c
index 1e0348a..e0a1d38 100644
--- a/drivers/mtd/nand/cs553x_nand.c
+++ b/drivers/mtd/nand/cs553x_nand.c
@@ -31,6 +31,10 @@ #include <asm/io.h>
 
 #define NR_CS553X_CONTROLLERS	4
 
+#define MSR_DIVIL_GLD_CAP	0x51400000	/* DIVIL capabilitiies */
+#define CAP_CS5535		0x2df000ULL
+#define CAP_CS5536		0x5df500ULL
+
 /* NAND Timing MSRs */
 #define MSR_NANDF_DATA		0x5140001b	/* NAND Flash Data Timing MSR */
 #define MSR_NANDF_CTL		0x5140001c	/* NAND Flash Control Timing */
@@ -252,17 +256,40 @@ out:
 	return err;
 }
 
+static int is_geode(void)
+{
+	/* These are the CPUs which will have a CS553[56] companion chip */
+	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
+	    boot_cpu_data.x86 == 5 &&
+	    boot_cpu_data.x86_model == 10)
+		return 1; /* Geode LX */
+
+	if ((boot_cpu_data.x86_vendor == X86_VENDOR_NSC ||
+	     boot_cpu_data.x86_vendor == X86_VENDOR_CYRIX) &&
+	    boot_cpu_data.x86 == 5 &&
+	    boot_cpu_data.x86_model == 5)
+		return 1; /* Geode GX (née GX2) */
+
+	return 0;
+}
+
 static int __init cs553x_init(void)
 {
 	int err = -ENXIO;
 	int i;
 	uint64_t val;
 
-	/* Check whether we actually have a CS5535 or CS5536 */
-	if (!pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, NULL) &&
-	    !pci_find_device(PCI_VENDOR_ID_NS,  PCI_DEVICE_ID_NS_CS5535_ISA, NULL))
+	/* If the CPU isn't a Geode GX or LX, abort */
+	if (!is_geode())
+		return -ENXIO;
+
+	/* If it doesn't have the CS553[56], abort */
+	rdmsrl(MSR_DIVIL_GLD_CAP, val);
+	val &= ~0xFFULL;
+	if (val != CAP_CS5535 && val != CAP_CS5536)
 		return -ENXIO;
 
+	/* If it doesn't have the NAND controller enabled, abort */
 	rdmsrl(MSR_DIVIL_BALL_OPTS, val);
 	if (val & 1) {
 		printk(KERN_INFO "CS553x NAND controller: Flash I/O not enabled in MSR_DIVIL_BALL_OPTS.\n");



More information about the linux-mtd-cvs mailing list