diff options
author | Mart Raudsepp <mart.raudsepp@artecdesign.ee> | 2008-02-09 03:16:36 -0500 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2008-02-09 03:21:31 -0500 |
commit | 641f43669fa28ca795ac4e9b3ec78643a007ee20 (patch) | |
tree | a01db6175241c36d1da14d021200fd53a5806313 | |
parent | b1d0e4f535e10775cffde922208b49629169aeaa (diff) |
[MTD] [NAND] cs553x_nand: command line partitioning support
Implements kernel command line partitioning support for the CS5535/CS5536 chipsets driver.
For that the following is done:
* cs553x_cleanup(): try the cleanup for all chip selects to not leak memory
* Assign a unique name for each chip select to be separately addressable in the command line mtd-id portion(s)
* Use the already defined PIN_OPT_IDE constant where appropriate for readability
* Include command line partitioning support when CONFIG_MTD_PARTS is set
Signed-off-by: Mart Raudsepp <mart.raudsepp@artecdesign.ee>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
-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 */ |