aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-mmp/aspenite.c5
-rw-r--r--arch/arm/mach-pxa/cm-x300.c5
-rw-r--r--arch/arm/mach-pxa/colibri-pxa3xx.c5
-rw-r--r--arch/arm/mach-pxa/littleton.c5
-rw-r--r--arch/arm/mach-pxa/mxm8x10.c9
-rw-r--r--arch/arm/mach-pxa/raumfeld.c5
-rw-r--r--arch/arm/mach-pxa/zylonite.c5
-rw-r--r--arch/arm/plat-pxa/include/plat/pxa3xx_nand.h20
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c173
9 files changed, 164 insertions, 68 deletions
diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index 06b5fa853c93..c4996f3dba3b 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -167,8 +167,9 @@ static struct mtd_partition aspenite_nand_partitions[] = {
167 167
168static struct pxa3xx_nand_platform_data aspenite_nand_info = { 168static struct pxa3xx_nand_platform_data aspenite_nand_info = {
169 .enable_arbiter = 1, 169 .enable_arbiter = 1,
170 .parts = aspenite_nand_partitions, 170 .num_cs = 1,
171 .nr_parts = ARRAY_SIZE(aspenite_nand_partitions), 171 .parts[0] = aspenite_nand_partitions,
172 .nr_parts[0] = ARRAY_SIZE(aspenite_nand_partitions),
172}; 173};
173 174
174static struct i2c_board_info aspenite_i2c_info[] __initdata = { 175static struct i2c_board_info aspenite_i2c_info[] __initdata = {
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
index b6a51340270b..eac3846ce42c 100644
--- a/arch/arm/mach-pxa/cm-x300.c
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -424,8 +424,9 @@ static struct mtd_partition cm_x300_nand_partitions[] = {
424static struct pxa3xx_nand_platform_data cm_x300_nand_info = { 424static struct pxa3xx_nand_platform_data cm_x300_nand_info = {
425 .enable_arbiter = 1, 425 .enable_arbiter = 1,
426 .keep_config = 1, 426 .keep_config = 1,
427 .parts = cm_x300_nand_partitions, 427 .num_cs = 1,
428 .nr_parts = ARRAY_SIZE(cm_x300_nand_partitions), 428 .parts[0] = cm_x300_nand_partitions,
429 .nr_parts[0] = ARRAY_SIZE(cm_x300_nand_partitions),
429}; 430};
430 431
431static void __init cm_x300_init_nand(void) 432static void __init cm_x300_init_nand(void)
diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c
index 3f9be419959d..2b8ca0de8a3d 100644
--- a/arch/arm/mach-pxa/colibri-pxa3xx.c
+++ b/arch/arm/mach-pxa/colibri-pxa3xx.c
@@ -139,8 +139,9 @@ static struct mtd_partition colibri_nand_partitions[] = {
139static struct pxa3xx_nand_platform_data colibri_nand_info = { 139static struct pxa3xx_nand_platform_data colibri_nand_info = {
140 .enable_arbiter = 1, 140 .enable_arbiter = 1,
141 .keep_config = 1, 141 .keep_config = 1,
142 .parts = colibri_nand_partitions, 142 .num_cs = 1,
143 .nr_parts = ARRAY_SIZE(colibri_nand_partitions), 143 .parts[0] = colibri_nand_partitions,
144 .nr_parts[0] = ARRAY_SIZE(colibri_nand_partitions),
144}; 145};
145 146
146void __init colibri_pxa3xx_init_nand(void) 147void __init colibri_pxa3xx_init_nand(void)
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
index 8f97e15e86e5..cd9fda3c9e65 100644
--- a/arch/arm/mach-pxa/littleton.c
+++ b/arch/arm/mach-pxa/littleton.c
@@ -325,8 +325,9 @@ static struct mtd_partition littleton_nand_partitions[] = {
325 325
326static struct pxa3xx_nand_platform_data littleton_nand_info = { 326static struct pxa3xx_nand_platform_data littleton_nand_info = {
327 .enable_arbiter = 1, 327 .enable_arbiter = 1,
328 .parts = littleton_nand_partitions, 328 .num_cs = 1,
329 .nr_parts = ARRAY_SIZE(littleton_nand_partitions), 329 .parts[0] = littleton_nand_partitions,
330 .nr_parts[0] = ARRAY_SIZE(littleton_nand_partitions),
330}; 331};
331 332
332static void __init littleton_init_nand(void) 333static void __init littleton_init_nand(void)
diff --git a/arch/arm/mach-pxa/mxm8x10.c b/arch/arm/mach-pxa/mxm8x10.c
index b5a8fd3fce04..90928d6e1a5b 100644
--- a/arch/arm/mach-pxa/mxm8x10.c
+++ b/arch/arm/mach-pxa/mxm8x10.c
@@ -389,10 +389,11 @@ static struct mtd_partition mxm_8x10_nand_partitions[] = {
389}; 389};
390 390
391static struct pxa3xx_nand_platform_data mxm_8x10_nand_info = { 391static struct pxa3xx_nand_platform_data mxm_8x10_nand_info = {
392 .enable_arbiter = 1, 392 .enable_arbiter = 1,
393 .keep_config = 1, 393 .keep_config = 1,
394 .parts = mxm_8x10_nand_partitions, 394 .num_cs = 1,
395 .nr_parts = ARRAY_SIZE(mxm_8x10_nand_partitions) 395 .parts[0] = mxm_8x10_nand_partitions,
396 .nr_parts[0] = ARRAY_SIZE(mxm_8x10_nand_partitions)
396}; 397};
397 398
398static void __init mxm_8x10_nand_init(void) 399static void __init mxm_8x10_nand_init(void)
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c
index bbcd90562ebe..6a2f353de39a 100644
--- a/arch/arm/mach-pxa/raumfeld.c
+++ b/arch/arm/mach-pxa/raumfeld.c
@@ -346,8 +346,9 @@ static struct mtd_partition raumfeld_nand_partitions[] = {
346static struct pxa3xx_nand_platform_data raumfeld_nand_info = { 346static struct pxa3xx_nand_platform_data raumfeld_nand_info = {
347 .enable_arbiter = 1, 347 .enable_arbiter = 1,
348 .keep_config = 1, 348 .keep_config = 1,
349 .parts = raumfeld_nand_partitions, 349 .num_cs = 1,
350 .nr_parts = ARRAY_SIZE(raumfeld_nand_partitions), 350 .parts[0] = raumfeld_nand_partitions,
351 .nr_parts[0] = ARRAY_SIZE(raumfeld_nand_partitions),
351}; 352};
352 353
353/** 354/**
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index 15ec66b3471a..90fbf879c019 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -366,8 +366,9 @@ static struct mtd_partition zylonite_nand_partitions[] = {
366 366
367static struct pxa3xx_nand_platform_data zylonite_nand_info = { 367static struct pxa3xx_nand_platform_data zylonite_nand_info = {
368 .enable_arbiter = 1, 368 .enable_arbiter = 1,
369 .parts = zylonite_nand_partitions, 369 .num_cs = 1,
370 .nr_parts = ARRAY_SIZE(zylonite_nand_partitions), 370 .parts[0] = zylonite_nand_partitions,
371 .nr_parts[0] = ARRAY_SIZE(zylonite_nand_partitions),
371}; 372};
372 373
373static void __init zylonite_init_nand(void) 374static void __init zylonite_init_nand(void)
diff --git a/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h b/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
index 442301fe48b4..c42f39f20195 100644
--- a/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
+++ b/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
@@ -41,6 +41,19 @@ struct pxa3xx_nand_flash {
41 struct pxa3xx_nand_timing *timing; /* NAND Flash timing */ 41 struct pxa3xx_nand_timing *timing; /* NAND Flash timing */
42}; 42};
43 43
44/*
45 * Current pxa3xx_nand controller has two chip select which
46 * both be workable.
47 *
48 * Notice should be taken that:
49 * When you want to use this feature, you should not enable the
50 * keep configuration feature, for two chip select could be
51 * attached with different nand chip. The different page size
52 * and timing requirement make the keep configuration impossible.
53 */
54
55/* The max num of chip select current support */
56#define NUM_CHIP_SELECT (2)
44struct pxa3xx_nand_platform_data { 57struct pxa3xx_nand_platform_data {
45 58
46 /* the data flash bus is shared between the Static Memory 59 /* the data flash bus is shared between the Static Memory
@@ -52,8 +65,11 @@ struct pxa3xx_nand_platform_data {
52 /* allow platform code to keep OBM/bootloader defined NFC config */ 65 /* allow platform code to keep OBM/bootloader defined NFC config */
53 int keep_config; 66 int keep_config;
54 67
55 const struct mtd_partition *parts; 68 /* indicate how many chip selects will be used */
56 unsigned int nr_parts; 69 int num_cs;
70
71 const struct mtd_partition *parts[NUM_CHIP_SELECT];
72 unsigned int nr_parts[NUM_CHIP_SELECT];
57 73
58 const struct pxa3xx_nand_flash * flash; 74 const struct pxa3xx_nand_flash * flash;
59 size_t num_flash; 75 size_t num_flash;
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 97b689499119..9eb7f879969e 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -130,6 +130,7 @@ struct pxa3xx_nand_host {
130 /* page size of attached chip */ 130 /* page size of attached chip */
131 unsigned int page_size; 131 unsigned int page_size;
132 int use_ecc; 132 int use_ecc;
133 int cs;
133 134
134 /* calculated from pxa3xx_nand_flash data */ 135 /* calculated from pxa3xx_nand_flash data */
135 unsigned int col_addr_cycles; 136 unsigned int col_addr_cycles;
@@ -165,9 +166,10 @@ struct pxa3xx_nand_info {
165 struct pxa_dma_desc *data_desc; 166 struct pxa_dma_desc *data_desc;
166 dma_addr_t data_desc_addr; 167 dma_addr_t data_desc_addr;
167 168
168 struct pxa3xx_nand_host *host; 169 struct pxa3xx_nand_host *host[NUM_CHIP_SELECT];
169 unsigned int state; 170 unsigned int state;
170 171
172 int cs;
171 int use_ecc; /* use HW ECC ? */ 173 int use_ecc; /* use HW ECC ? */
172 int use_dma; /* use DMA ? */ 174 int use_dma; /* use DMA ? */
173 int is_ready; 175 int is_ready;
@@ -226,7 +228,7 @@ static struct pxa3xx_nand_flash builtin_flash_types[] = {
226/* Define a default flash type setting serve as flash detecting only */ 228/* Define a default flash type setting serve as flash detecting only */
227#define DEFAULT_FLASH_TYPE (&builtin_flash_types[0]) 229#define DEFAULT_FLASH_TYPE (&builtin_flash_types[0])
228 230
229const char *mtd_names[] = {"pxa3xx_nand-0", NULL}; 231const char *mtd_names[] = {"pxa3xx_nand-0", "pxa3xx_nand-1", NULL};
230 232
231#define NDTR0_tCH(c) (min((c), 7) << 19) 233#define NDTR0_tCH(c) (min((c), 7) << 19)
232#define NDTR0_tCS(c) (min((c), 7) << 16) 234#define NDTR0_tCS(c) (min((c), 7) << 16)
@@ -268,7 +270,7 @@ static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host,
268 270
269static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info) 271static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info)
270{ 272{
271 struct pxa3xx_nand_host *host = info->host; 273 struct pxa3xx_nand_host *host = info->host[info->cs];
272 int oob_enable = host->reg_ndcr & NDCR_SPARE_EN; 274 int oob_enable = host->reg_ndcr & NDCR_SPARE_EN;
273 275
274 info->data_size = host->page_size; 276 info->data_size = host->page_size;
@@ -295,7 +297,7 @@ static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info)
295 */ 297 */
296static void pxa3xx_nand_start(struct pxa3xx_nand_info *info) 298static void pxa3xx_nand_start(struct pxa3xx_nand_info *info)
297{ 299{
298 struct pxa3xx_nand_host *host = info->host; 300 struct pxa3xx_nand_host *host = info->host[info->cs];
299 uint32_t ndcr; 301 uint32_t ndcr;
300 302
301 ndcr = host->reg_ndcr; 303 ndcr = host->reg_ndcr;
@@ -420,6 +422,15 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
420{ 422{
421 struct pxa3xx_nand_info *info = devid; 423 struct pxa3xx_nand_info *info = devid;
422 unsigned int status, is_completed = 0; 424 unsigned int status, is_completed = 0;
425 unsigned int ready, cmd_done;
426
427 if (info->cs == 0) {
428 ready = NDSR_FLASH_RDY;
429 cmd_done = NDSR_CS0_CMDD;
430 } else {
431 ready = NDSR_RDY;
432 cmd_done = NDSR_CS1_CMDD;
433 }
423 434
424 status = nand_readl(info, NDSR); 435 status = nand_readl(info, NDSR);
425 436
@@ -441,11 +452,11 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
441 handle_data_pio(info); 452 handle_data_pio(info);
442 } 453 }
443 } 454 }
444 if (status & NDSR_CS0_CMDD) { 455 if (status & cmd_done) {
445 info->state = STATE_CMD_DONE; 456 info->state = STATE_CMD_DONE;
446 is_completed = 1; 457 is_completed = 1;
447 } 458 }
448 if (status & NDSR_FLASH_RDY) { 459 if (status & ready) {
449 info->is_ready = 1; 460 info->is_ready = 1;
450 info->state = STATE_READY; 461 info->state = STATE_READY;
451 } 462 }
@@ -480,9 +491,11 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
480{ 491{
481 uint16_t cmd; 492 uint16_t cmd;
482 int addr_cycle, exec_cmd; 493 int addr_cycle, exec_cmd;
483 struct pxa3xx_nand_host *host = info->host; 494 struct pxa3xx_nand_host *host;
484 struct mtd_info *mtd = host->mtd; 495 struct mtd_info *mtd;
485 496
497 host = info->host[info->cs];
498 mtd = host->mtd;
486 addr_cycle = 0; 499 addr_cycle = 0;
487 exec_cmd = 1; 500 exec_cmd = 1;
488 501
@@ -492,8 +505,11 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
492 info->oob_size = 0; 505 info->oob_size = 0;
493 info->use_ecc = 0; 506 info->use_ecc = 0;
494 info->is_ready = 0; 507 info->is_ready = 0;
495 info->ndcb0 = 0;
496 info->retcode = ERR_NONE; 508 info->retcode = ERR_NONE;
509 if (info->cs != 0)
510 info->ndcb0 = NDCB0_CSEL;
511 else
512 info->ndcb0 = 0;
497 513
498 switch (command) { 514 switch (command) {
499 case NAND_CMD_READ0: 515 case NAND_CMD_READ0:
@@ -637,6 +653,17 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
637 if (host->reg_ndcr & NDCR_DWIDTH_M) 653 if (host->reg_ndcr & NDCR_DWIDTH_M)
638 column /= 2; 654 column /= 2;
639 655
656 /*
657 * There may be different NAND chip hooked to
658 * different chip select, so check whether
659 * chip select has been changed, if yes, reset the timing
660 */
661 if (info->cs != host->cs) {
662 info->cs = host->cs;
663 nand_writel(info, NDTR0CS0, host->ndtr0cs0);
664 nand_writel(info, NDTR1CS0, host->ndtr1cs0);
665 }
666
640 info->state = STATE_PREPARED; 667 info->state = STATE_PREPARED;
641 exec_cmd = prepare_command_pool(info, command, column, page_addr); 668 exec_cmd = prepare_command_pool(info, command, column, page_addr);
642 if (exec_cmd) { 669 if (exec_cmd) {
@@ -778,7 +805,7 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
778{ 805{
779 struct platform_device *pdev = info->pdev; 806 struct platform_device *pdev = info->pdev;
780 struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data; 807 struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data;
781 struct pxa3xx_nand_host *host = info->host; 808 struct pxa3xx_nand_host *host = info->host[info->cs];
782 uint32_t ndcr = 0x0; /* enable all interrupts */ 809 uint32_t ndcr = 0x0; /* enable all interrupts */
783 810
784 if (f->page_size != 2048 && f->page_size != 512) { 811 if (f->page_size != 2048 && f->page_size != 512) {
@@ -822,7 +849,11 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
822 849
823static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) 850static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
824{ 851{
825 struct pxa3xx_nand_host *host = info->host; 852 /*
853 * We set 0 by hard coding here, for we don't support keep_config
854 * when there is more than one chip attached to the controller
855 */
856 struct pxa3xx_nand_host *host = info->host[0];
826 uint32_t ndcr = nand_readl(info, NDCR); 857 uint32_t ndcr = nand_readl(info, NDCR);
827 858
828 if (ndcr & NDCR_PAGE_SZ) { 859 if (ndcr & NDCR_PAGE_SZ) {
@@ -884,9 +915,9 @@ static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
884 915
885static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info) 916static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info)
886{ 917{
887 struct mtd_info *mtd = info->host->mtd; 918 struct mtd_info *mtd;
888 int ret; 919 int ret;
889 920 mtd = info->host[info->cs]->mtd;
890 /* use the common timing to make a try */ 921 /* use the common timing to make a try */
891 ret = pxa3xx_nand_config_flash(info, &builtin_flash_types[0]); 922 ret = pxa3xx_nand_config_flash(info, &builtin_flash_types[0]);
892 if (ret) 923 if (ret)
@@ -917,7 +948,8 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
917 948
918 ret = pxa3xx_nand_sensing(info); 949 ret = pxa3xx_nand_sensing(info);
919 if (ret) { 950 if (ret) {
920 dev_info(&info->pdev->dev, "There is no nand chip on cs 0!\n"); 951 dev_info(&info->pdev->dev, "There is no chip on cs %d!\n",
952 info->cs);
921 953
922 return ret; 954 return ret;
923 } 955 }
@@ -996,41 +1028,47 @@ KEEP_CONFIG:
996 1028
997static int alloc_nand_resource(struct platform_device *pdev) 1029static int alloc_nand_resource(struct platform_device *pdev)
998{ 1030{
1031 struct pxa3xx_nand_platform_data *pdata;
999 struct pxa3xx_nand_info *info; 1032 struct pxa3xx_nand_info *info;
1000 struct pxa3xx_nand_host *host; 1033 struct pxa3xx_nand_host *host;
1001 struct nand_chip *chip; 1034 struct nand_chip *chip;
1002 struct mtd_info *mtd; 1035 struct mtd_info *mtd;
1003 struct resource *r; 1036 struct resource *r;
1004 int ret, irq; 1037 int ret, irq, cs;
1005 1038
1006 info = kzalloc(sizeof(*info) + sizeof(*mtd) + sizeof(*host), 1039 pdata = pdev->dev.platform_data;
1007 GFP_KERNEL); 1040 info = kzalloc(sizeof(*info) + (sizeof(*mtd) +
1041 sizeof(*host)) * pdata->num_cs, GFP_KERNEL);
1008 if (!info) { 1042 if (!info) {
1009 dev_err(&pdev->dev, "failed to allocate memory\n"); 1043 dev_err(&pdev->dev, "failed to allocate memory\n");
1010 return -ENOMEM; 1044 return -ENOMEM;
1011 } 1045 }
1012 1046
1013 mtd = (struct mtd_info *)(&info[1]);
1014 chip = (struct nand_chip *)(&mtd[1]);
1015 host = (struct pxa3xx_nand_host *)chip;
1016 info->pdev = pdev; 1047 info->pdev = pdev;
1017 info->host = host; 1048 for (cs = 0; cs < pdata->num_cs; cs++) {
1018 host->mtd = mtd; 1049 mtd = (struct mtd_info *)((unsigned int)&info[1] +
1019 host->info_data = info; 1050 (sizeof(*mtd) + sizeof(*host)) * cs);
1020 mtd->priv = host; 1051 chip = (struct nand_chip *)(&mtd[1]);
1021 mtd->owner = THIS_MODULE; 1052 host = (struct pxa3xx_nand_host *)chip;
1022 1053 info->host[cs] = host;
1023 chip->ecc.read_page = pxa3xx_nand_read_page_hwecc; 1054 host->mtd = mtd;
1024 chip->ecc.write_page = pxa3xx_nand_write_page_hwecc; 1055 host->cs = cs;
1025 chip->controller = &info->controller; 1056 host->info_data = info;
1026 chip->waitfunc = pxa3xx_nand_waitfunc; 1057 mtd->priv = host;
1027 chip->select_chip = pxa3xx_nand_select_chip; 1058 mtd->owner = THIS_MODULE;
1028 chip->cmdfunc = pxa3xx_nand_cmdfunc; 1059
1029 chip->read_word = pxa3xx_nand_read_word; 1060 chip->ecc.read_page = pxa3xx_nand_read_page_hwecc;
1030 chip->read_byte = pxa3xx_nand_read_byte; 1061 chip->ecc.write_page = pxa3xx_nand_write_page_hwecc;
1031 chip->read_buf = pxa3xx_nand_read_buf; 1062 chip->controller = &info->controller;
1032 chip->write_buf = pxa3xx_nand_write_buf; 1063 chip->waitfunc = pxa3xx_nand_waitfunc;
1033 chip->verify_buf = pxa3xx_nand_verify_buf; 1064 chip->select_chip = pxa3xx_nand_select_chip;
1065 chip->cmdfunc = pxa3xx_nand_cmdfunc;
1066 chip->read_word = pxa3xx_nand_read_word;
1067 chip->read_byte = pxa3xx_nand_read_byte;
1068 chip->read_buf = pxa3xx_nand_read_buf;
1069 chip->write_buf = pxa3xx_nand_write_buf;
1070 chip->verify_buf = pxa3xx_nand_verify_buf;
1071 }
1034 1072
1035 spin_lock_init(&chip->controller->lock); 1073 spin_lock_init(&chip->controller->lock);
1036 init_waitqueue_head(&chip->controller->wq); 1074 init_waitqueue_head(&chip->controller->wq);
@@ -1128,12 +1166,14 @@ fail_free_mtd:
1128static int pxa3xx_nand_remove(struct platform_device *pdev) 1166static int pxa3xx_nand_remove(struct platform_device *pdev)
1129{ 1167{
1130 struct pxa3xx_nand_info *info = platform_get_drvdata(pdev); 1168 struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
1169 struct pxa3xx_nand_platform_data *pdata;
1131 struct resource *r; 1170 struct resource *r;
1132 int irq; 1171 int irq, cs;
1133 1172
1134 if (!info) 1173 if (!info)
1135 return 0; 1174 return 0;
1136 1175
1176 pdata = pdev->dev.platform_data;
1137 platform_set_drvdata(pdev, NULL); 1177 platform_set_drvdata(pdev, NULL);
1138 1178
1139 irq = platform_get_irq(pdev, 0); 1179 irq = platform_get_irq(pdev, 0);
@@ -1153,7 +1193,8 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
1153 clk_disable(info->clk); 1193 clk_disable(info->clk);
1154 clk_put(info->clk); 1194 clk_put(info->clk);
1155 1195
1156 nand_release(info->host->mtd); 1196 for (cs = 0; cs < pdata->num_cs; cs++)
1197 nand_release(info->host[cs]->mtd);
1157 kfree(info); 1198 kfree(info);
1158 return 0; 1199 return 0;
1159} 1200}
@@ -1162,7 +1203,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
1162{ 1203{
1163 struct pxa3xx_nand_platform_data *pdata; 1204 struct pxa3xx_nand_platform_data *pdata;
1164 struct pxa3xx_nand_info *info; 1205 struct pxa3xx_nand_info *info;
1165 int ret; 1206 int ret, cs, probe_success;
1166 1207
1167 pdata = pdev->dev.platform_data; 1208 pdata = pdev->dev.platform_data;
1168 if (!pdata) { 1209 if (!pdata) {
@@ -1177,41 +1218,69 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
1177 } 1218 }
1178 1219
1179 info = platform_get_drvdata(pdev); 1220 info = platform_get_drvdata(pdev);
1180 if (pxa3xx_nand_scan(info->host->mtd)) { 1221 probe_success = 0;
1181 dev_err(&pdev->dev, "failed to scan nand\n"); 1222 for (cs = 0; cs < pdata->num_cs; cs++) {
1223 info->cs = cs;
1224 ret = pxa3xx_nand_scan(info->host[cs]->mtd);
1225 if (ret) {
1226 dev_warn(&pdev->dev, "failed to scan nand at cs %d\n",
1227 cs);
1228 continue;
1229 }
1230
1231 ret = mtd_device_parse_register(info->host[cs]->mtd, NULL, 0,
1232 pdata->parts[cs], pdata->nr_parts[cs]);
1233 if (!ret)
1234 probe_success = 1;
1235 }
1236
1237 if (!probe_success) {
1182 pxa3xx_nand_remove(pdev); 1238 pxa3xx_nand_remove(pdev);
1183 return -ENODEV; 1239 return -ENODEV;
1184 } 1240 }
1185 1241
1186 return mtd_device_parse_register(info->host->mtd, NULL, 0, 1242 return 0;
1187 pdata->parts, pdata->nr_parts);
1188} 1243}
1189 1244
1190#ifdef CONFIG_PM 1245#ifdef CONFIG_PM
1191static int pxa3xx_nand_suspend(struct platform_device *pdev, pm_message_t state) 1246static int pxa3xx_nand_suspend(struct platform_device *pdev, pm_message_t state)
1192{ 1247{
1193 struct pxa3xx_nand_info *info = platform_get_drvdata(pdev); 1248 struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
1194 struct mtd_info *mtd = info->mtd; 1249 struct pxa3xx_nand_platform_data *pdata;
1250 struct mtd_info *mtd;
1251 int cs;
1195 1252
1253 pdata = pdev->dev.platform_data;
1196 if (info->state) { 1254 if (info->state) {
1197 dev_err(&pdev->dev, "driver busy, state = %d\n", info->state); 1255 dev_err(&pdev->dev, "driver busy, state = %d\n", info->state);
1198 return -EAGAIN; 1256 return -EAGAIN;
1199 } 1257 }
1200 1258
1201 mtd->suspend(mtd); 1259 for (cs = 0; cs < pdata->num_cs; cs++) {
1260 mtd = info->host[cs]->mtd;
1261 mtd->suspend(mtd);
1262 }
1263
1202 return 0; 1264 return 0;
1203} 1265}
1204 1266
1205static int pxa3xx_nand_resume(struct platform_device *pdev) 1267static int pxa3xx_nand_resume(struct platform_device *pdev)
1206{ 1268{
1207 struct pxa3xx_nand_info *info = platform_get_drvdata(pdev); 1269 struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
1208 struct mtd_info *mtd = info->mtd; 1270 struct pxa3xx_nand_platform_data *pdata;
1271 struct mtd_info *mtd;
1272 int cs;
1209 1273
1274 pdata = pdev->dev.platform_data;
1210 /* We don't want to handle interrupt without calling mtd routine */ 1275 /* We don't want to handle interrupt without calling mtd routine */
1211 disable_int(info, NDCR_INT_MASK); 1276 disable_int(info, NDCR_INT_MASK);
1212 1277
1213 nand_writel(info, NDTR0CS0, info->host->ndtr0cs0); 1278 /*
1214 nand_writel(info, NDTR1CS0, info->host->ndtr1cs0); 1279 * Directly set the chip select to a invalid value,
1280 * then the driver would reset the timing according
1281 * to current chip select at the beginning of cmdfunc
1282 */
1283 info->cs = 0xff;
1215 1284
1216 /* 1285 /*
1217 * As the spec says, the NDSR would be updated to 0x1800 when 1286 * As the spec says, the NDSR would be updated to 0x1800 when
@@ -1220,7 +1289,11 @@ static int pxa3xx_nand_resume(struct platform_device *pdev)
1220 * all status before resume 1289 * all status before resume
1221 */ 1290 */
1222 nand_writel(info, NDSR, NDSR_MASK); 1291 nand_writel(info, NDSR, NDSR_MASK);
1223 mtd->resume(mtd); 1292 for (cs = 0; cs < pdata->num_cs; cs++) {
1293 mtd = info->host[cs]->mtd;
1294 mtd->resume(mtd);
1295 }
1296
1224 return 0; 1297 return 0;
1225} 1298}
1226#else 1299#else