diff options
-rw-r--r-- | drivers/mtd/nand/Kconfig | 2 | ||||
-rw-r--r-- | 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 f24408d92688..d5d4d767b643 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -211,7 +211,7 @@ config MTD_NAND_SHARPSL | |||
211 | 211 | ||
212 | config MTD_NAND_CS553X | 212 | config MTD_NAND_CS553X |
213 | tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)" | 213 | tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)" |
214 | depends on MTD_NAND && X86_PC && PCI | 214 | depends on MTD_NAND && (X86_PC || X86_GENERICARCH) |
215 | help | 215 | help |
216 | The CS553x companion chips for the AMD Geode processor | 216 | The CS553x companion chips for the AMD Geode processor |
217 | include NAND flash controllers with built-in hardware ECC | 217 | 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 1e0348ae325f..e0a1d386e581 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c | |||
@@ -31,6 +31,10 @@ | |||
31 | 31 | ||
32 | #define NR_CS553X_CONTROLLERS 4 | 32 | #define NR_CS553X_CONTROLLERS 4 |
33 | 33 | ||
34 | #define MSR_DIVIL_GLD_CAP 0x51400000 /* DIVIL capabilitiies */ | ||
35 | #define CAP_CS5535 0x2df000ULL | ||
36 | #define CAP_CS5536 0x5df500ULL | ||
37 | |||
34 | /* NAND Timing MSRs */ | 38 | /* NAND Timing MSRs */ |
35 | #define MSR_NANDF_DATA 0x5140001b /* NAND Flash Data Timing MSR */ | 39 | #define MSR_NANDF_DATA 0x5140001b /* NAND Flash Data Timing MSR */ |
36 | #define MSR_NANDF_CTL 0x5140001c /* NAND Flash Control Timing */ | 40 | #define MSR_NANDF_CTL 0x5140001c /* NAND Flash Control Timing */ |
@@ -252,17 +256,40 @@ out: | |||
252 | return err; | 256 | return err; |
253 | } | 257 | } |
254 | 258 | ||
259 | static int is_geode(void) | ||
260 | { | ||
261 | /* These are the CPUs which will have a CS553[56] companion chip */ | ||
262 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && | ||
263 | boot_cpu_data.x86 == 5 && | ||
264 | boot_cpu_data.x86_model == 10) | ||
265 | return 1; /* Geode LX */ | ||
266 | |||
267 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_NSC || | ||
268 | boot_cpu_data.x86_vendor == X86_VENDOR_CYRIX) && | ||
269 | boot_cpu_data.x86 == 5 && | ||
270 | boot_cpu_data.x86_model == 5) | ||
271 | return 1; /* Geode GX (née GX2) */ | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
255 | static int __init cs553x_init(void) | 276 | static int __init cs553x_init(void) |
256 | { | 277 | { |
257 | int err = -ENXIO; | 278 | int err = -ENXIO; |
258 | int i; | 279 | int i; |
259 | uint64_t val; | 280 | uint64_t val; |
260 | 281 | ||
261 | /* Check whether we actually have a CS5535 or CS5536 */ | 282 | /* If the CPU isn't a Geode GX or LX, abort */ |
262 | if (!pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, NULL) && | 283 | if (!is_geode()) |
263 | !pci_find_device(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA, NULL)) | 284 | return -ENXIO; |
285 | |||
286 | /* If it doesn't have the CS553[56], abort */ | ||
287 | rdmsrl(MSR_DIVIL_GLD_CAP, val); | ||
288 | val &= ~0xFFULL; | ||
289 | if (val != CAP_CS5535 && val != CAP_CS5536) | ||
264 | return -ENXIO; | 290 | return -ENXIO; |
265 | 291 | ||
292 | /* If it doesn't have the NAND controller enabled, abort */ | ||
266 | rdmsrl(MSR_DIVIL_BALL_OPTS, val); | 293 | rdmsrl(MSR_DIVIL_BALL_OPTS, val); |
267 | if (val & 1) { | 294 | if (val & 1) { |
268 | printk(KERN_INFO "CS553x NAND controller: Flash I/O not enabled in MSR_DIVIL_BALL_OPTS.\n"); | 295 | printk(KERN_INFO "CS553x NAND controller: Flash I/O not enabled in MSR_DIVIL_BALL_OPTS.\n"); |