diff options
| -rw-r--r-- | drivers/mtd/nand/cs553x_nand.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c index 19e1594421a4..8dab69657b19 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c | |||
| @@ -13,9 +13,12 @@ | |||
| 13 | * Overview: | 13 | * Overview: |
| 14 | * This is a device driver for the NAND flash controller found on | 14 | * This is a device driver for the NAND flash controller found on |
| 15 | * the AMD CS5535/CS5536 companion chipsets for the Geode processor. | 15 | * the AMD CS5535/CS5536 companion chipsets for the Geode processor. |
| 16 | * mtd-id for command line partitioning is cs553x_nand_cs[0-3] | ||
| 17 | * where 0-3 reflects the chip select for NAND. | ||
| 16 | * | 18 | * |
| 17 | */ | 19 | */ |
| 18 | 20 | ||
| 21 | #include <linux/kernel.h> | ||
| 19 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 20 | #include <linux/init.h> | 23 | #include <linux/init.h> |
| 21 | #include <linux/module.h> | 24 | #include <linux/module.h> |
| @@ -244,6 +247,8 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) | |||
| 244 | goto out_ior; | 247 | goto out_ior; |
| 245 | } | 248 | } |
| 246 | 249 | ||
| 250 | new_mtd->name = kasprintf(GFP_KERNEL, "cs553x_nand_cs%d", cs); | ||
| 251 | |||
| 247 | cs553x_mtd[cs] = new_mtd; | 252 | cs553x_mtd[cs] = new_mtd; |
| 248 | goto out; | 253 | goto out; |
| 249 | 254 | ||
| @@ -272,12 +277,21 @@ static int is_geode(void) | |||
| 272 | return 0; | 277 | return 0; |
| 273 | } | 278 | } |
| 274 | 279 | ||
| 280 | |||
| 281 | #ifdef CONFIG_MTD_PARTITIONS | ||
| 282 | const char *part_probes[] = { "cmdlinepart", NULL }; | ||
| 283 | #endif | ||
| 284 | |||
| 285 | |||
| 275 | static int __init cs553x_init(void) | 286 | static int __init cs553x_init(void) |
| 276 | { | 287 | { |
| 277 | int err = -ENXIO; | 288 | int err = -ENXIO; |
| 278 | int i; | 289 | int i; |
| 279 | uint64_t val; | 290 | uint64_t val; |
| 280 | 291 | ||
| 292 | int mtd_parts_nb = 0; | ||
| 293 | struct mtd_partition *mtd_parts = NULL; | ||
| 294 | |||
| 281 | /* If the CPU isn't a Geode GX or LX, abort */ | 295 | /* If the CPU isn't a Geode GX or LX, abort */ |
| 282 | if (!is_geode()) | 296 | if (!is_geode()) |
| 283 | return -ENXIO; | 297 | return -ENXIO; |
| @@ -290,7 +304,7 @@ static int __init cs553x_init(void) | |||
| 290 | 304 | ||
| 291 | /* If it doesn't have the NAND controller enabled, abort */ | 305 | /* If it doesn't have the NAND controller enabled, abort */ |
| 292 | rdmsrl(MSR_DIVIL_BALL_OPTS, val); | 306 | rdmsrl(MSR_DIVIL_BALL_OPTS, val); |
| 293 | if (val & 1) { | 307 | if (val & PIN_OPT_IDE) { |
| 294 | printk(KERN_INFO "CS553x NAND controller: Flash I/O not enabled in MSR_DIVIL_BALL_OPTS.\n"); | 308 | printk(KERN_INFO "CS553x NAND controller: Flash I/O not enabled in MSR_DIVIL_BALL_OPTS.\n"); |
| 295 | return -ENXIO; | 309 | return -ENXIO; |
| 296 | } | 310 | } |
| @@ -306,9 +320,19 @@ static int __init cs553x_init(void) | |||
| 306 | do mtdconcat etc. if we want to. */ | 320 | do mtdconcat etc. if we want to. */ |
| 307 | for (i = 0; i < NR_CS553X_CONTROLLERS; i++) { | 321 | for (i = 0; i < NR_CS553X_CONTROLLERS; i++) { |
| 308 | if (cs553x_mtd[i]) { | 322 | if (cs553x_mtd[i]) { |
| 309 | add_mtd_device(cs553x_mtd[i]); | ||
| 310 | 323 | ||
| 311 | /* If any devices registered, return success. Else the last error. */ | 324 | /* If any devices registered, return success. Else the last error. */ |
| 325 | #ifdef CONFIG_MTD_PARTITIONS | ||
| 326 | mtd_parts_nb = parse_mtd_partitions(cs553x_mtd[i], part_probes, &mtd_parts, 0); | ||
| 327 | if (mtd_parts_nb > 0) { | ||
| 328 | printk(KERN_NOTICE "Using command line partition definition\n"); | ||
| 329 | add_mtd_partitions(cs553x_mtd[i], mtd_parts, mtd_parts_nb); | ||
| 330 | } else { | ||
| 331 | add_mtd_device(cs553x_mtd[i]); | ||
| 332 | } | ||
| 333 | #else | ||
| 334 | add_mtd_device(cs553x_mtd[i]); | ||
| 335 | #endif | ||
| 312 | err = 0; | 336 | err = 0; |
| 313 | } | 337 | } |
| 314 | } | 338 | } |
| @@ -328,13 +352,14 @@ static void __exit cs553x_cleanup(void) | |||
| 328 | void __iomem *mmio_base; | 352 | void __iomem *mmio_base; |
| 329 | 353 | ||
| 330 | if (!mtd) | 354 | if (!mtd) |
| 331 | break; | 355 | continue; |
| 332 | 356 | ||
| 333 | this = cs553x_mtd[i]->priv; | 357 | this = cs553x_mtd[i]->priv; |
| 334 | mmio_base = this->IO_ADDR_R; | 358 | mmio_base = this->IO_ADDR_R; |
| 335 | 359 | ||
| 336 | /* Release resources, unregister device */ | 360 | /* Release resources, unregister device */ |
| 337 | nand_release(cs553x_mtd[i]); | 361 | nand_release(cs553x_mtd[i]); |
| 362 | kfree(cs553x_mtd[i]->name); | ||
| 338 | cs553x_mtd[i] = NULL; | 363 | cs553x_mtd[i] = NULL; |
| 339 | 364 | ||
| 340 | /* unmap physical address */ | 365 | /* unmap physical address */ |
