aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMart Raudsepp <mart.raudsepp@artecdesign.ee>2008-02-09 03:16:36 -0500
committerDavid Woodhouse <dwmw2@infradead.org>2008-02-09 03:21:31 -0500
commit641f43669fa28ca795ac4e9b3ec78643a007ee20 (patch)
treea01db6175241c36d1da14d021200fd53a5806313 /drivers
parentb1d0e4f535e10775cffde922208b49629169aeaa (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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/nand/cs553x_nand.c31
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
282const char *part_probes[] = { "cmdlinepart", NULL };
283#endif
284
285
275static int __init cs553x_init(void) 286static 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 */