diff options
author | Lei Wen <leiwen@marvell.com> | 2011-07-14 23:44:32 -0400 |
---|---|---|
committer | Artem Bityutskiy <artem.bityutskiy@intel.com> | 2011-09-11 08:02:15 -0400 |
commit | d456882b41b84eba5e729cf78757b8ed95572362 (patch) | |
tree | 8e460f17e0ec736ea8e94340c2080dd7f271d0df | |
parent | da675b4ef20bb460f185e0aca4afeb8c3e7e4477 (diff) |
mtd: pxa3xx_nand: sperate each chip individual info
For support two chip select, we seperate chip specific info in this
patch.
Signed-off-by: Lei Wen <leiwen@marvell.com>
-rw-r--r-- | drivers/mtd/nand/pxa3xx_nand.c | 292 |
1 files changed, 160 insertions, 132 deletions
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index e55d7f8df978..97b689499119 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -110,6 +110,7 @@ enum { | |||
110 | 110 | ||
111 | enum { | 111 | enum { |
112 | STATE_IDLE = 0, | 112 | STATE_IDLE = 0, |
113 | STATE_PREPARED, | ||
113 | STATE_CMD_HANDLE, | 114 | STATE_CMD_HANDLE, |
114 | STATE_DMA_READING, | 115 | STATE_DMA_READING, |
115 | STATE_DMA_WRITING, | 116 | STATE_DMA_WRITING, |
@@ -120,21 +121,39 @@ enum { | |||
120 | STATE_READY, | 121 | STATE_READY, |
121 | }; | 122 | }; |
122 | 123 | ||
123 | struct pxa3xx_nand_info { | 124 | struct pxa3xx_nand_host { |
124 | struct nand_chip nand_chip; | 125 | struct nand_chip chip; |
126 | struct pxa3xx_nand_cmdset *cmdset; | ||
127 | struct mtd_info *mtd; | ||
128 | void *info_data; | ||
129 | |||
130 | /* page size of attached chip */ | ||
131 | unsigned int page_size; | ||
132 | int use_ecc; | ||
125 | 133 | ||
134 | /* calculated from pxa3xx_nand_flash data */ | ||
135 | unsigned int col_addr_cycles; | ||
136 | unsigned int row_addr_cycles; | ||
137 | size_t read_id_bytes; | ||
138 | |||
139 | /* cached register value */ | ||
140 | uint32_t reg_ndcr; | ||
141 | uint32_t ndtr0cs0; | ||
142 | uint32_t ndtr1cs0; | ||
143 | }; | ||
144 | |||
145 | struct pxa3xx_nand_info { | ||
126 | struct nand_hw_control controller; | 146 | struct nand_hw_control controller; |
127 | struct platform_device *pdev; | 147 | struct platform_device *pdev; |
128 | struct pxa3xx_nand_cmdset *cmdset; | ||
129 | 148 | ||
130 | struct clk *clk; | 149 | struct clk *clk; |
131 | void __iomem *mmio_base; | 150 | void __iomem *mmio_base; |
132 | unsigned long mmio_phys; | 151 | unsigned long mmio_phys; |
152 | struct completion cmd_complete; | ||
133 | 153 | ||
134 | unsigned int buf_start; | 154 | unsigned int buf_start; |
135 | unsigned int buf_count; | 155 | unsigned int buf_count; |
136 | 156 | ||
137 | struct mtd_info *mtd; | ||
138 | /* DMA information */ | 157 | /* DMA information */ |
139 | int drcmr_dat; | 158 | int drcmr_dat; |
140 | int drcmr_cmd; | 159 | int drcmr_cmd; |
@@ -142,18 +161,11 @@ struct pxa3xx_nand_info { | |||
142 | unsigned char *data_buff; | 161 | unsigned char *data_buff; |
143 | unsigned char *oob_buff; | 162 | unsigned char *oob_buff; |
144 | dma_addr_t data_buff_phys; | 163 | dma_addr_t data_buff_phys; |
145 | size_t data_buff_size; | ||
146 | int data_dma_ch; | 164 | int data_dma_ch; |
147 | struct pxa_dma_desc *data_desc; | 165 | struct pxa_dma_desc *data_desc; |
148 | dma_addr_t data_desc_addr; | 166 | dma_addr_t data_desc_addr; |
149 | 167 | ||
150 | uint32_t reg_ndcr; | 168 | struct pxa3xx_nand_host *host; |
151 | |||
152 | /* saved column/page_addr during CMD_SEQIN */ | ||
153 | int seqin_column; | ||
154 | int seqin_page_addr; | ||
155 | |||
156 | /* relate to the command */ | ||
157 | unsigned int state; | 169 | unsigned int state; |
158 | 170 | ||
159 | int use_ecc; /* use HW ECC ? */ | 171 | int use_ecc; /* use HW ECC ? */ |
@@ -162,24 +174,13 @@ struct pxa3xx_nand_info { | |||
162 | 174 | ||
163 | unsigned int page_size; /* page size of attached chip */ | 175 | unsigned int page_size; /* page size of attached chip */ |
164 | unsigned int data_size; /* data size in FIFO */ | 176 | unsigned int data_size; /* data size in FIFO */ |
177 | unsigned int oob_size; | ||
165 | int retcode; | 178 | int retcode; |
166 | struct completion cmd_complete; | ||
167 | 179 | ||
168 | /* generated NDCBx register values */ | 180 | /* generated NDCBx register values */ |
169 | uint32_t ndcb0; | 181 | uint32_t ndcb0; |
170 | uint32_t ndcb1; | 182 | uint32_t ndcb1; |
171 | uint32_t ndcb2; | 183 | uint32_t ndcb2; |
172 | |||
173 | /* timing calcuted from setting */ | ||
174 | uint32_t ndtr0cs0; | ||
175 | uint32_t ndtr1cs0; | ||
176 | |||
177 | /* calculated from pxa3xx_nand_flash data */ | ||
178 | size_t oob_size; | ||
179 | size_t read_id_bytes; | ||
180 | |||
181 | unsigned int col_addr_cycles; | ||
182 | unsigned int row_addr_cycles; | ||
183 | }; | 184 | }; |
184 | 185 | ||
185 | static int use_dma = 1; | 186 | static int use_dma = 1; |
@@ -241,9 +242,10 @@ const char *mtd_names[] = {"pxa3xx_nand-0", NULL}; | |||
241 | /* convert nano-seconds to nand flash controller clock cycles */ | 242 | /* convert nano-seconds to nand flash controller clock cycles */ |
242 | #define ns2cycle(ns, clk) (int)((ns) * (clk / 1000000) / 1000) | 243 | #define ns2cycle(ns, clk) (int)((ns) * (clk / 1000000) / 1000) |
243 | 244 | ||
244 | static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info, | 245 | static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host, |
245 | const struct pxa3xx_nand_timing *t) | 246 | const struct pxa3xx_nand_timing *t) |
246 | { | 247 | { |
248 | struct pxa3xx_nand_info *info = host->info_data; | ||
247 | unsigned long nand_clk = clk_get_rate(info->clk); | 249 | unsigned long nand_clk = clk_get_rate(info->clk); |
248 | uint32_t ndtr0, ndtr1; | 250 | uint32_t ndtr0, ndtr1; |
249 | 251 | ||
@@ -258,23 +260,24 @@ static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info, | |||
258 | NDTR1_tWHR(ns2cycle(t->tWHR, nand_clk)) | | 260 | NDTR1_tWHR(ns2cycle(t->tWHR, nand_clk)) | |
259 | NDTR1_tAR(ns2cycle(t->tAR, nand_clk)); | 261 | NDTR1_tAR(ns2cycle(t->tAR, nand_clk)); |
260 | 262 | ||
261 | info->ndtr0cs0 = ndtr0; | 263 | host->ndtr0cs0 = ndtr0; |
262 | info->ndtr1cs0 = ndtr1; | 264 | host->ndtr1cs0 = ndtr1; |
263 | nand_writel(info, NDTR0CS0, ndtr0); | 265 | nand_writel(info, NDTR0CS0, ndtr0); |
264 | nand_writel(info, NDTR1CS0, ndtr1); | 266 | nand_writel(info, NDTR1CS0, ndtr1); |
265 | } | 267 | } |
266 | 268 | ||
267 | static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info) | 269 | static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info) |
268 | { | 270 | { |
269 | int oob_enable = info->reg_ndcr & NDCR_SPARE_EN; | 271 | struct pxa3xx_nand_host *host = info->host; |
272 | int oob_enable = host->reg_ndcr & NDCR_SPARE_EN; | ||
270 | 273 | ||
271 | info->data_size = info->page_size; | 274 | info->data_size = host->page_size; |
272 | if (!oob_enable) { | 275 | if (!oob_enable) { |
273 | info->oob_size = 0; | 276 | info->oob_size = 0; |
274 | return; | 277 | return; |
275 | } | 278 | } |
276 | 279 | ||
277 | switch (info->page_size) { | 280 | switch (host->page_size) { |
278 | case 2048: | 281 | case 2048: |
279 | info->oob_size = (info->use_ecc) ? 40 : 64; | 282 | info->oob_size = (info->use_ecc) ? 40 : 64; |
280 | break; | 283 | break; |
@@ -292,9 +295,10 @@ static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info) | |||
292 | */ | 295 | */ |
293 | static void pxa3xx_nand_start(struct pxa3xx_nand_info *info) | 296 | static void pxa3xx_nand_start(struct pxa3xx_nand_info *info) |
294 | { | 297 | { |
298 | struct pxa3xx_nand_host *host = info->host; | ||
295 | uint32_t ndcr; | 299 | uint32_t ndcr; |
296 | 300 | ||
297 | ndcr = info->reg_ndcr; | 301 | ndcr = host->reg_ndcr; |
298 | ndcr |= info->use_ecc ? NDCR_ECC_EN : 0; | 302 | ndcr |= info->use_ecc ? NDCR_ECC_EN : 0; |
299 | ndcr |= info->use_dma ? NDCR_DMA_EN : 0; | 303 | ndcr |= info->use_dma ? NDCR_DMA_EN : 0; |
300 | ndcr |= NDCR_ND_RUN; | 304 | ndcr |= NDCR_ND_RUN; |
@@ -463,12 +467,6 @@ NORMAL_IRQ_EXIT: | |||
463 | return IRQ_HANDLED; | 467 | return IRQ_HANDLED; |
464 | } | 468 | } |
465 | 469 | ||
466 | static int pxa3xx_nand_dev_ready(struct mtd_info *mtd) | ||
467 | { | ||
468 | struct pxa3xx_nand_info *info = mtd->priv; | ||
469 | return (nand_readl(info, NDSR) & NDSR_RDY) ? 1 : 0; | ||
470 | } | ||
471 | |||
472 | static inline int is_buf_blank(uint8_t *buf, size_t len) | 470 | static inline int is_buf_blank(uint8_t *buf, size_t len) |
473 | { | 471 | { |
474 | for (; len > 0; len--) | 472 | for (; len > 0; len--) |
@@ -481,10 +479,10 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command, | |||
481 | uint16_t column, int page_addr) | 479 | uint16_t column, int page_addr) |
482 | { | 480 | { |
483 | uint16_t cmd; | 481 | uint16_t cmd; |
484 | int addr_cycle, exec_cmd, ndcb0; | 482 | int addr_cycle, exec_cmd; |
485 | struct mtd_info *mtd = info->mtd; | 483 | struct pxa3xx_nand_host *host = info->host; |
484 | struct mtd_info *mtd = host->mtd; | ||
486 | 485 | ||
487 | ndcb0 = 0; | ||
488 | addr_cycle = 0; | 486 | addr_cycle = 0; |
489 | exec_cmd = 1; | 487 | exec_cmd = 1; |
490 | 488 | ||
@@ -494,6 +492,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command, | |||
494 | info->oob_size = 0; | 492 | info->oob_size = 0; |
495 | info->use_ecc = 0; | 493 | info->use_ecc = 0; |
496 | info->is_ready = 0; | 494 | info->is_ready = 0; |
495 | info->ndcb0 = 0; | ||
497 | info->retcode = ERR_NONE; | 496 | info->retcode = ERR_NONE; |
498 | 497 | ||
499 | switch (command) { | 498 | switch (command) { |
@@ -512,20 +511,19 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command, | |||
512 | break; | 511 | break; |
513 | } | 512 | } |
514 | 513 | ||
515 | info->ndcb0 = ndcb0; | 514 | addr_cycle = NDCB0_ADDR_CYC(host->row_addr_cycles |
516 | addr_cycle = NDCB0_ADDR_CYC(info->row_addr_cycles | 515 | + host->col_addr_cycles); |
517 | + info->col_addr_cycles); | ||
518 | 516 | ||
519 | switch (command) { | 517 | switch (command) { |
520 | case NAND_CMD_READOOB: | 518 | case NAND_CMD_READOOB: |
521 | case NAND_CMD_READ0: | 519 | case NAND_CMD_READ0: |
522 | cmd = info->cmdset->read1; | 520 | cmd = host->cmdset->read1; |
523 | if (command == NAND_CMD_READOOB) | 521 | if (command == NAND_CMD_READOOB) |
524 | info->buf_start = mtd->writesize + column; | 522 | info->buf_start = mtd->writesize + column; |
525 | else | 523 | else |
526 | info->buf_start = column; | 524 | info->buf_start = column; |
527 | 525 | ||
528 | if (unlikely(info->page_size < PAGE_CHUNK_SIZE)) | 526 | if (unlikely(host->page_size < PAGE_CHUNK_SIZE)) |
529 | info->ndcb0 |= NDCB0_CMD_TYPE(0) | 527 | info->ndcb0 |= NDCB0_CMD_TYPE(0) |
530 | | addr_cycle | 528 | | addr_cycle |
531 | | (cmd & NDCB0_CMD1_MASK); | 529 | | (cmd & NDCB0_CMD1_MASK); |
@@ -537,7 +535,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command, | |||
537 | 535 | ||
538 | case NAND_CMD_SEQIN: | 536 | case NAND_CMD_SEQIN: |
539 | /* small page addr setting */ | 537 | /* small page addr setting */ |
540 | if (unlikely(info->page_size < PAGE_CHUNK_SIZE)) { | 538 | if (unlikely(host->page_size < PAGE_CHUNK_SIZE)) { |
541 | info->ndcb1 = ((page_addr & 0xFFFFFF) << 8) | 539 | info->ndcb1 = ((page_addr & 0xFFFFFF) << 8) |
542 | | (column & 0xFF); | 540 | | (column & 0xFF); |
543 | 541 | ||
@@ -564,7 +562,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command, | |||
564 | break; | 562 | break; |
565 | } | 563 | } |
566 | 564 | ||
567 | cmd = info->cmdset->program; | 565 | cmd = host->cmdset->program; |
568 | info->ndcb0 |= NDCB0_CMD_TYPE(0x1) | 566 | info->ndcb0 |= NDCB0_CMD_TYPE(0x1) |
569 | | NDCB0_AUTO_RS | 567 | | NDCB0_AUTO_RS |
570 | | NDCB0_ST_ROW_EN | 568 | | NDCB0_ST_ROW_EN |
@@ -574,8 +572,8 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command, | |||
574 | break; | 572 | break; |
575 | 573 | ||
576 | case NAND_CMD_READID: | 574 | case NAND_CMD_READID: |
577 | cmd = info->cmdset->read_id; | 575 | cmd = host->cmdset->read_id; |
578 | info->buf_count = info->read_id_bytes; | 576 | info->buf_count = host->read_id_bytes; |
579 | info->ndcb0 |= NDCB0_CMD_TYPE(3) | 577 | info->ndcb0 |= NDCB0_CMD_TYPE(3) |
580 | | NDCB0_ADDR_CYC(1) | 578 | | NDCB0_ADDR_CYC(1) |
581 | | cmd; | 579 | | cmd; |
@@ -583,7 +581,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command, | |||
583 | info->data_size = 8; | 581 | info->data_size = 8; |
584 | break; | 582 | break; |
585 | case NAND_CMD_STATUS: | 583 | case NAND_CMD_STATUS: |
586 | cmd = info->cmdset->read_status; | 584 | cmd = host->cmdset->read_status; |
587 | info->buf_count = 1; | 585 | info->buf_count = 1; |
588 | info->ndcb0 |= NDCB0_CMD_TYPE(4) | 586 | info->ndcb0 |= NDCB0_CMD_TYPE(4) |
589 | | NDCB0_ADDR_CYC(1) | 587 | | NDCB0_ADDR_CYC(1) |
@@ -593,7 +591,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command, | |||
593 | break; | 591 | break; |
594 | 592 | ||
595 | case NAND_CMD_ERASE1: | 593 | case NAND_CMD_ERASE1: |
596 | cmd = info->cmdset->erase; | 594 | cmd = host->cmdset->erase; |
597 | info->ndcb0 |= NDCB0_CMD_TYPE(2) | 595 | info->ndcb0 |= NDCB0_CMD_TYPE(2) |
598 | | NDCB0_AUTO_RS | 596 | | NDCB0_AUTO_RS |
599 | | NDCB0_ADDR_CYC(3) | 597 | | NDCB0_ADDR_CYC(3) |
@@ -604,7 +602,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command, | |||
604 | 602 | ||
605 | break; | 603 | break; |
606 | case NAND_CMD_RESET: | 604 | case NAND_CMD_RESET: |
607 | cmd = info->cmdset->reset; | 605 | cmd = host->cmdset->reset; |
608 | info->ndcb0 |= NDCB0_CMD_TYPE(5) | 606 | info->ndcb0 |= NDCB0_CMD_TYPE(5) |
609 | | cmd; | 607 | | cmd; |
610 | 608 | ||
@@ -627,7 +625,8 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command, | |||
627 | static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command, | 625 | static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command, |
628 | int column, int page_addr) | 626 | int column, int page_addr) |
629 | { | 627 | { |
630 | struct pxa3xx_nand_info *info = mtd->priv; | 628 | struct pxa3xx_nand_host *host = mtd->priv; |
629 | struct pxa3xx_nand_info *info = host->info_data; | ||
631 | int ret, exec_cmd; | 630 | int ret, exec_cmd; |
632 | 631 | ||
633 | /* | 632 | /* |
@@ -635,9 +634,10 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command, | |||
635 | * "byte" address into a "word" address appropriate | 634 | * "byte" address into a "word" address appropriate |
636 | * for indexing a word-oriented device | 635 | * for indexing a word-oriented device |
637 | */ | 636 | */ |
638 | if (info->reg_ndcr & NDCR_DWIDTH_M) | 637 | if (host->reg_ndcr & NDCR_DWIDTH_M) |
639 | column /= 2; | 638 | column /= 2; |
640 | 639 | ||
640 | info->state = STATE_PREPARED; | ||
641 | exec_cmd = prepare_command_pool(info, command, column, page_addr); | 641 | exec_cmd = prepare_command_pool(info, command, column, page_addr); |
642 | if (exec_cmd) { | 642 | if (exec_cmd) { |
643 | init_completion(&info->cmd_complete); | 643 | init_completion(&info->cmd_complete); |
@@ -650,8 +650,8 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command, | |||
650 | /* Stop State Machine for next command cycle */ | 650 | /* Stop State Machine for next command cycle */ |
651 | pxa3xx_nand_stop(info); | 651 | pxa3xx_nand_stop(info); |
652 | } | 652 | } |
653 | info->state = STATE_IDLE; | ||
654 | } | 653 | } |
654 | info->state = STATE_IDLE; | ||
655 | } | 655 | } |
656 | 656 | ||
657 | static void pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd, | 657 | static void pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd, |
@@ -664,7 +664,8 @@ static void pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd, | |||
664 | static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, | 664 | static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, |
665 | struct nand_chip *chip, uint8_t *buf, int page) | 665 | struct nand_chip *chip, uint8_t *buf, int page) |
666 | { | 666 | { |
667 | struct pxa3xx_nand_info *info = mtd->priv; | 667 | struct pxa3xx_nand_host *host = mtd->priv; |
668 | struct pxa3xx_nand_info *info = host->info_data; | ||
668 | 669 | ||
669 | chip->read_buf(mtd, buf, mtd->writesize); | 670 | chip->read_buf(mtd, buf, mtd->writesize); |
670 | chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); | 671 | chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); |
@@ -695,7 +696,8 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, | |||
695 | 696 | ||
696 | static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd) | 697 | static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd) |
697 | { | 698 | { |
698 | struct pxa3xx_nand_info *info = mtd->priv; | 699 | struct pxa3xx_nand_host *host = mtd->priv; |
700 | struct pxa3xx_nand_info *info = host->info_data; | ||
699 | char retval = 0xFF; | 701 | char retval = 0xFF; |
700 | 702 | ||
701 | if (info->buf_start < info->buf_count) | 703 | if (info->buf_start < info->buf_count) |
@@ -707,7 +709,8 @@ static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd) | |||
707 | 709 | ||
708 | static u16 pxa3xx_nand_read_word(struct mtd_info *mtd) | 710 | static u16 pxa3xx_nand_read_word(struct mtd_info *mtd) |
709 | { | 711 | { |
710 | struct pxa3xx_nand_info *info = mtd->priv; | 712 | struct pxa3xx_nand_host *host = mtd->priv; |
713 | struct pxa3xx_nand_info *info = host->info_data; | ||
711 | u16 retval = 0xFFFF; | 714 | u16 retval = 0xFFFF; |
712 | 715 | ||
713 | if (!(info->buf_start & 0x01) && info->buf_start < info->buf_count) { | 716 | if (!(info->buf_start & 0x01) && info->buf_start < info->buf_count) { |
@@ -719,7 +722,8 @@ static u16 pxa3xx_nand_read_word(struct mtd_info *mtd) | |||
719 | 722 | ||
720 | static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | 723 | static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
721 | { | 724 | { |
722 | struct pxa3xx_nand_info *info = mtd->priv; | 725 | struct pxa3xx_nand_host *host = mtd->priv; |
726 | struct pxa3xx_nand_info *info = host->info_data; | ||
723 | int real_len = min_t(size_t, len, info->buf_count - info->buf_start); | 727 | int real_len = min_t(size_t, len, info->buf_count - info->buf_start); |
724 | 728 | ||
725 | memcpy(buf, info->data_buff + info->buf_start, real_len); | 729 | memcpy(buf, info->data_buff + info->buf_start, real_len); |
@@ -729,7 +733,8 @@ static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |||
729 | static void pxa3xx_nand_write_buf(struct mtd_info *mtd, | 733 | static void pxa3xx_nand_write_buf(struct mtd_info *mtd, |
730 | const uint8_t *buf, int len) | 734 | const uint8_t *buf, int len) |
731 | { | 735 | { |
732 | struct pxa3xx_nand_info *info = mtd->priv; | 736 | struct pxa3xx_nand_host *host = mtd->priv; |
737 | struct pxa3xx_nand_info *info = host->info_data; | ||
733 | int real_len = min_t(size_t, len, info->buf_count - info->buf_start); | 738 | int real_len = min_t(size_t, len, info->buf_count - info->buf_start); |
734 | 739 | ||
735 | memcpy(info->data_buff + info->buf_start, buf, real_len); | 740 | memcpy(info->data_buff + info->buf_start, buf, real_len); |
@@ -749,7 +754,8 @@ static void pxa3xx_nand_select_chip(struct mtd_info *mtd, int chip) | |||
749 | 754 | ||
750 | static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) | 755 | static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) |
751 | { | 756 | { |
752 | struct pxa3xx_nand_info *info = mtd->priv; | 757 | struct pxa3xx_nand_host *host = mtd->priv; |
758 | struct pxa3xx_nand_info *info = host->info_data; | ||
753 | 759 | ||
754 | /* pxa3xx_nand_send_command has waited for command complete */ | 760 | /* pxa3xx_nand_send_command has waited for command complete */ |
755 | if (this->state == FL_WRITING || this->state == FL_ERASING) { | 761 | if (this->state == FL_WRITING || this->state == FL_ERASING) { |
@@ -772,6 +778,7 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, | |||
772 | { | 778 | { |
773 | struct platform_device *pdev = info->pdev; | 779 | struct platform_device *pdev = info->pdev; |
774 | struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data; | 780 | struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data; |
781 | struct pxa3xx_nand_host *host = info->host; | ||
775 | uint32_t ndcr = 0x0; /* enable all interrupts */ | 782 | uint32_t ndcr = 0x0; /* enable all interrupts */ |
776 | 783 | ||
777 | if (f->page_size != 2048 && f->page_size != 512) { | 784 | if (f->page_size != 2048 && f->page_size != 512) { |
@@ -785,45 +792,52 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, | |||
785 | } | 792 | } |
786 | 793 | ||
787 | /* calculate flash information */ | 794 | /* calculate flash information */ |
788 | info->cmdset = &default_cmdset; | 795 | host->cmdset = &default_cmdset; |
789 | info->page_size = f->page_size; | 796 | host->page_size = f->page_size; |
790 | info->read_id_bytes = (f->page_size == 2048) ? 4 : 2; | 797 | host->read_id_bytes = (f->page_size == 2048) ? 4 : 2; |
791 | 798 | ||
792 | /* calculate addressing information */ | 799 | /* calculate addressing information */ |
793 | info->col_addr_cycles = (f->page_size == 2048) ? 2 : 1; | 800 | host->col_addr_cycles = (f->page_size == 2048) ? 2 : 1; |
794 | 801 | ||
795 | if (f->num_blocks * f->page_per_block > 65536) | 802 | if (f->num_blocks * f->page_per_block > 65536) |
796 | info->row_addr_cycles = 3; | 803 | host->row_addr_cycles = 3; |
797 | else | 804 | else |
798 | info->row_addr_cycles = 2; | 805 | host->row_addr_cycles = 2; |
799 | 806 | ||
800 | ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; | 807 | ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; |
801 | ndcr |= (info->col_addr_cycles == 2) ? NDCR_RA_START : 0; | 808 | ndcr |= (host->col_addr_cycles == 2) ? NDCR_RA_START : 0; |
802 | ndcr |= (f->page_per_block == 64) ? NDCR_PG_PER_BLK : 0; | 809 | ndcr |= (f->page_per_block == 64) ? NDCR_PG_PER_BLK : 0; |
803 | ndcr |= (f->page_size == 2048) ? NDCR_PAGE_SZ : 0; | 810 | ndcr |= (f->page_size == 2048) ? NDCR_PAGE_SZ : 0; |
804 | ndcr |= (f->flash_width == 16) ? NDCR_DWIDTH_M : 0; | 811 | ndcr |= (f->flash_width == 16) ? NDCR_DWIDTH_M : 0; |
805 | ndcr |= (f->dfc_width == 16) ? NDCR_DWIDTH_C : 0; | 812 | ndcr |= (f->dfc_width == 16) ? NDCR_DWIDTH_C : 0; |
806 | 813 | ||
807 | ndcr |= NDCR_RD_ID_CNT(info->read_id_bytes); | 814 | ndcr |= NDCR_RD_ID_CNT(host->read_id_bytes); |
808 | ndcr |= NDCR_SPARE_EN; /* enable spare by default */ | 815 | ndcr |= NDCR_SPARE_EN; /* enable spare by default */ |
809 | 816 | ||
810 | info->reg_ndcr = ndcr; | 817 | host->reg_ndcr = ndcr; |
811 | 818 | ||
812 | pxa3xx_nand_set_timing(info, f->timing); | 819 | pxa3xx_nand_set_timing(host, f->timing); |
813 | return 0; | 820 | return 0; |
814 | } | 821 | } |
815 | 822 | ||
816 | static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) | 823 | static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) |
817 | { | 824 | { |
825 | struct pxa3xx_nand_host *host = info->host; | ||
818 | uint32_t ndcr = nand_readl(info, NDCR); | 826 | uint32_t ndcr = nand_readl(info, NDCR); |
819 | info->page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512; | ||
820 | /* set info fields needed to read id */ | ||
821 | info->read_id_bytes = (info->page_size == 2048) ? 4 : 2; | ||
822 | info->reg_ndcr = ndcr & ~NDCR_INT_MASK; | ||
823 | info->cmdset = &default_cmdset; | ||
824 | 827 | ||
825 | info->ndtr0cs0 = nand_readl(info, NDTR0CS0); | 828 | if (ndcr & NDCR_PAGE_SZ) { |
826 | info->ndtr1cs0 = nand_readl(info, NDTR1CS0); | 829 | host->page_size = 2048; |
830 | host->read_id_bytes = 4; | ||
831 | } else { | ||
832 | host->page_size = 512; | ||
833 | host->read_id_bytes = 2; | ||
834 | } | ||
835 | |||
836 | host->reg_ndcr = ndcr & ~NDCR_INT_MASK; | ||
837 | host->cmdset = &default_cmdset; | ||
838 | |||
839 | host->ndtr0cs0 = nand_readl(info, NDTR0CS0); | ||
840 | host->ndtr1cs0 = nand_readl(info, NDTR1CS0); | ||
827 | 841 | ||
828 | return 0; | 842 | return 0; |
829 | } | 843 | } |
@@ -853,7 +867,6 @@ static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info) | |||
853 | return -ENOMEM; | 867 | return -ENOMEM; |
854 | } | 868 | } |
855 | 869 | ||
856 | info->data_buff_size = MAX_BUFF_SIZE; | ||
857 | info->data_desc = (void *)info->data_buff + data_desc_offset; | 870 | info->data_desc = (void *)info->data_buff + data_desc_offset; |
858 | info->data_desc_addr = info->data_buff_phys + data_desc_offset; | 871 | info->data_desc_addr = info->data_buff_phys + data_desc_offset; |
859 | 872 | ||
@@ -861,7 +874,7 @@ static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info) | |||
861 | pxa3xx_nand_data_dma_irq, info); | 874 | pxa3xx_nand_data_dma_irq, info); |
862 | if (info->data_dma_ch < 0) { | 875 | if (info->data_dma_ch < 0) { |
863 | dev_err(&pdev->dev, "failed to request data dma\n"); | 876 | dev_err(&pdev->dev, "failed to request data dma\n"); |
864 | dma_free_coherent(&pdev->dev, info->data_buff_size, | 877 | dma_free_coherent(&pdev->dev, MAX_BUFF_SIZE, |
865 | info->data_buff, info->data_buff_phys); | 878 | info->data_buff, info->data_buff_phys); |
866 | return info->data_dma_ch; | 879 | return info->data_dma_ch; |
867 | } | 880 | } |
@@ -871,21 +884,25 @@ static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info) | |||
871 | 884 | ||
872 | static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info) | 885 | static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info) |
873 | { | 886 | { |
874 | struct mtd_info *mtd = info->mtd; | 887 | struct mtd_info *mtd = info->host->mtd; |
875 | struct nand_chip *chip = mtd->priv; | 888 | int ret; |
876 | 889 | ||
877 | /* use the common timing to make a try */ | 890 | /* use the common timing to make a try */ |
878 | pxa3xx_nand_config_flash(info, &builtin_flash_types[0]); | 891 | ret = pxa3xx_nand_config_flash(info, &builtin_flash_types[0]); |
879 | chip->cmdfunc(mtd, NAND_CMD_RESET, 0, 0); | 892 | if (ret) |
893 | return ret; | ||
894 | |||
895 | pxa3xx_nand_cmdfunc(mtd, NAND_CMD_RESET, 0, 0); | ||
880 | if (info->is_ready) | 896 | if (info->is_ready) |
881 | return 1; | ||
882 | else | ||
883 | return 0; | 897 | return 0; |
898 | |||
899 | return -ENODEV; | ||
884 | } | 900 | } |
885 | 901 | ||
886 | static int pxa3xx_nand_scan(struct mtd_info *mtd) | 902 | static int pxa3xx_nand_scan(struct mtd_info *mtd) |
887 | { | 903 | { |
888 | struct pxa3xx_nand_info *info = mtd->priv; | 904 | struct pxa3xx_nand_host *host = mtd->priv; |
905 | struct pxa3xx_nand_info *info = host->info_data; | ||
889 | struct platform_device *pdev = info->pdev; | 906 | struct platform_device *pdev = info->pdev; |
890 | struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data; | 907 | struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data; |
891 | struct nand_flash_dev pxa3xx_flash_ids[2], *def = NULL; | 908 | struct nand_flash_dev pxa3xx_flash_ids[2], *def = NULL; |
@@ -899,12 +916,10 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) | |||
899 | goto KEEP_CONFIG; | 916 | goto KEEP_CONFIG; |
900 | 917 | ||
901 | ret = pxa3xx_nand_sensing(info); | 918 | ret = pxa3xx_nand_sensing(info); |
902 | if (!ret) { | 919 | if (ret) { |
903 | kfree(mtd); | ||
904 | info->mtd = NULL; | ||
905 | dev_info(&info->pdev->dev, "There is no nand chip on cs 0!\n"); | 920 | dev_info(&info->pdev->dev, "There is no nand chip on cs 0!\n"); |
906 | 921 | ||
907 | return -EINVAL; | 922 | return ret; |
908 | } | 923 | } |
909 | 924 | ||
910 | chip->cmdfunc(mtd, NAND_CMD_READID, 0, 0); | 925 | chip->cmdfunc(mtd, NAND_CMD_READID, 0, 0); |
@@ -912,8 +927,6 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) | |||
912 | if (id != 0) | 927 | if (id != 0) |
913 | dev_info(&info->pdev->dev, "Detect a flash id %x\n", id); | 928 | dev_info(&info->pdev->dev, "Detect a flash id %x\n", id); |
914 | else { | 929 | else { |
915 | kfree(mtd); | ||
916 | info->mtd = NULL; | ||
917 | dev_warn(&info->pdev->dev, | 930 | dev_warn(&info->pdev->dev, |
918 | "Read out ID 0, potential timing set wrong!!\n"); | 931 | "Read out ID 0, potential timing set wrong!!\n"); |
919 | 932 | ||
@@ -933,14 +946,17 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) | |||
933 | } | 946 | } |
934 | 947 | ||
935 | if (i >= (ARRAY_SIZE(builtin_flash_types) + pdata->num_flash - 1)) { | 948 | if (i >= (ARRAY_SIZE(builtin_flash_types) + pdata->num_flash - 1)) { |
936 | kfree(mtd); | ||
937 | info->mtd = NULL; | ||
938 | dev_err(&info->pdev->dev, "ERROR!! flash not defined!!!\n"); | 949 | dev_err(&info->pdev->dev, "ERROR!! flash not defined!!!\n"); |
939 | 950 | ||
940 | return -EINVAL; | 951 | return -EINVAL; |
941 | } | 952 | } |
942 | 953 | ||
943 | pxa3xx_nand_config_flash(info, f); | 954 | ret = pxa3xx_nand_config_flash(info, f); |
955 | if (ret) { | ||
956 | dev_err(&info->pdev->dev, "ERROR! Configure failed\n"); | ||
957 | return ret; | ||
958 | } | ||
959 | |||
944 | pxa3xx_flash_ids[0].name = f->name; | 960 | pxa3xx_flash_ids[0].name = f->name; |
945 | pxa3xx_flash_ids[0].id = (f->chip_id >> 8) & 0xffff; | 961 | pxa3xx_flash_ids[0].id = (f->chip_id >> 8) & 0xffff; |
946 | pxa3xx_flash_ids[0].pagesize = f->page_size; | 962 | pxa3xx_flash_ids[0].pagesize = f->page_size; |
@@ -952,47 +968,56 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) | |||
952 | pxa3xx_flash_ids[1].name = NULL; | 968 | pxa3xx_flash_ids[1].name = NULL; |
953 | def = pxa3xx_flash_ids; | 969 | def = pxa3xx_flash_ids; |
954 | KEEP_CONFIG: | 970 | KEEP_CONFIG: |
971 | chip->ecc.mode = NAND_ECC_HW; | ||
972 | chip->ecc.size = host->page_size; | ||
973 | |||
974 | chip->options = NAND_NO_AUTOINCR; | ||
975 | chip->options |= NAND_NO_READRDY; | ||
976 | if (host->reg_ndcr & NDCR_DWIDTH_M) | ||
977 | chip->options |= NAND_BUSWIDTH_16; | ||
978 | |||
955 | if (nand_scan_ident(mtd, 1, def)) | 979 | if (nand_scan_ident(mtd, 1, def)) |
956 | return -ENODEV; | 980 | return -ENODEV; |
957 | /* calculate addressing information */ | 981 | /* calculate addressing information */ |
958 | info->col_addr_cycles = (mtd->writesize >= 2048) ? 2 : 1; | 982 | if (mtd->writesize >= 2048) |
983 | host->col_addr_cycles = 2; | ||
984 | else | ||
985 | host->col_addr_cycles = 1; | ||
986 | |||
959 | info->oob_buff = info->data_buff + mtd->writesize; | 987 | info->oob_buff = info->data_buff + mtd->writesize; |
960 | if ((mtd->size >> chip->page_shift) > 65536) | 988 | if ((mtd->size >> chip->page_shift) > 65536) |
961 | info->row_addr_cycles = 3; | 989 | host->row_addr_cycles = 3; |
962 | else | 990 | else |
963 | info->row_addr_cycles = 2; | 991 | host->row_addr_cycles = 2; |
964 | mtd->name = mtd_names[0]; | ||
965 | chip->ecc.mode = NAND_ECC_HW; | ||
966 | chip->ecc.size = info->page_size; | ||
967 | |||
968 | chip->options = (info->reg_ndcr & NDCR_DWIDTH_M) ? NAND_BUSWIDTH_16 : 0; | ||
969 | chip->options |= NAND_NO_AUTOINCR; | ||
970 | chip->options |= NAND_NO_READRDY; | ||
971 | 992 | ||
993 | mtd->name = mtd_names[0]; | ||
972 | return nand_scan_tail(mtd); | 994 | return nand_scan_tail(mtd); |
973 | } | 995 | } |
974 | 996 | ||
975 | static | 997 | static int alloc_nand_resource(struct platform_device *pdev) |
976 | struct pxa3xx_nand_info *alloc_nand_resource(struct platform_device *pdev) | ||
977 | { | 998 | { |
978 | struct pxa3xx_nand_info *info; | 999 | struct pxa3xx_nand_info *info; |
1000 | struct pxa3xx_nand_host *host; | ||
979 | struct nand_chip *chip; | 1001 | struct nand_chip *chip; |
980 | struct mtd_info *mtd; | 1002 | struct mtd_info *mtd; |
981 | struct resource *r; | 1003 | struct resource *r; |
982 | int ret, irq; | 1004 | int ret, irq; |
983 | 1005 | ||
984 | mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct pxa3xx_nand_info), | 1006 | info = kzalloc(sizeof(*info) + sizeof(*mtd) + sizeof(*host), |
985 | GFP_KERNEL); | 1007 | GFP_KERNEL); |
986 | if (!mtd) { | 1008 | if (!info) { |
987 | dev_err(&pdev->dev, "failed to allocate memory\n"); | 1009 | dev_err(&pdev->dev, "failed to allocate memory\n"); |
988 | return NULL; | 1010 | return -ENOMEM; |
989 | } | 1011 | } |
990 | 1012 | ||
991 | info = (struct pxa3xx_nand_info *)(&mtd[1]); | 1013 | mtd = (struct mtd_info *)(&info[1]); |
992 | chip = (struct nand_chip *)(&mtd[1]); | 1014 | chip = (struct nand_chip *)(&mtd[1]); |
1015 | host = (struct pxa3xx_nand_host *)chip; | ||
993 | info->pdev = pdev; | 1016 | info->pdev = pdev; |
994 | info->mtd = mtd; | 1017 | info->host = host; |
995 | mtd->priv = info; | 1018 | host->mtd = mtd; |
1019 | host->info_data = info; | ||
1020 | mtd->priv = host; | ||
996 | mtd->owner = THIS_MODULE; | 1021 | mtd->owner = THIS_MODULE; |
997 | 1022 | ||
998 | chip->ecc.read_page = pxa3xx_nand_read_page_hwecc; | 1023 | chip->ecc.read_page = pxa3xx_nand_read_page_hwecc; |
@@ -1000,7 +1025,6 @@ struct pxa3xx_nand_info *alloc_nand_resource(struct platform_device *pdev) | |||
1000 | chip->controller = &info->controller; | 1025 | chip->controller = &info->controller; |
1001 | chip->waitfunc = pxa3xx_nand_waitfunc; | 1026 | chip->waitfunc = pxa3xx_nand_waitfunc; |
1002 | chip->select_chip = pxa3xx_nand_select_chip; | 1027 | chip->select_chip = pxa3xx_nand_select_chip; |
1003 | chip->dev_ready = pxa3xx_nand_dev_ready; | ||
1004 | chip->cmdfunc = pxa3xx_nand_cmdfunc; | 1028 | chip->cmdfunc = pxa3xx_nand_cmdfunc; |
1005 | chip->read_word = pxa3xx_nand_read_word; | 1029 | chip->read_word = pxa3xx_nand_read_word; |
1006 | chip->read_byte = pxa3xx_nand_read_byte; | 1030 | chip->read_byte = pxa3xx_nand_read_byte; |
@@ -1079,13 +1103,13 @@ struct pxa3xx_nand_info *alloc_nand_resource(struct platform_device *pdev) | |||
1079 | 1103 | ||
1080 | platform_set_drvdata(pdev, info); | 1104 | platform_set_drvdata(pdev, info); |
1081 | 1105 | ||
1082 | return info; | 1106 | return 0; |
1083 | 1107 | ||
1084 | fail_free_buf: | 1108 | fail_free_buf: |
1085 | free_irq(irq, info); | 1109 | free_irq(irq, info); |
1086 | if (use_dma) { | 1110 | if (use_dma) { |
1087 | pxa_free_dma(info->data_dma_ch); | 1111 | pxa_free_dma(info->data_dma_ch); |
1088 | dma_free_coherent(&pdev->dev, info->data_buff_size, | 1112 | dma_free_coherent(&pdev->dev, MAX_BUFF_SIZE, |
1089 | info->data_buff, info->data_buff_phys); | 1113 | info->data_buff, info->data_buff_phys); |
1090 | } else | 1114 | } else |
1091 | kfree(info->data_buff); | 1115 | kfree(info->data_buff); |
@@ -1097,17 +1121,19 @@ fail_put_clk: | |||
1097 | clk_disable(info->clk); | 1121 | clk_disable(info->clk); |
1098 | clk_put(info->clk); | 1122 | clk_put(info->clk); |
1099 | fail_free_mtd: | 1123 | fail_free_mtd: |
1100 | kfree(mtd); | 1124 | kfree(info); |
1101 | return NULL; | 1125 | return ret; |
1102 | } | 1126 | } |
1103 | 1127 | ||
1104 | static int pxa3xx_nand_remove(struct platform_device *pdev) | 1128 | static int pxa3xx_nand_remove(struct platform_device *pdev) |
1105 | { | 1129 | { |
1106 | struct pxa3xx_nand_info *info = platform_get_drvdata(pdev); | 1130 | struct pxa3xx_nand_info *info = platform_get_drvdata(pdev); |
1107 | struct mtd_info *mtd = info->mtd; | ||
1108 | struct resource *r; | 1131 | struct resource *r; |
1109 | int irq; | 1132 | int irq; |
1110 | 1133 | ||
1134 | if (!info) | ||
1135 | return 0; | ||
1136 | |||
1111 | platform_set_drvdata(pdev, NULL); | 1137 | platform_set_drvdata(pdev, NULL); |
1112 | 1138 | ||
1113 | irq = platform_get_irq(pdev, 0); | 1139 | irq = platform_get_irq(pdev, 0); |
@@ -1115,7 +1141,7 @@ static int pxa3xx_nand_remove(struct platform_device *pdev) | |||
1115 | free_irq(irq, info); | 1141 | free_irq(irq, info); |
1116 | if (use_dma) { | 1142 | if (use_dma) { |
1117 | pxa_free_dma(info->data_dma_ch); | 1143 | pxa_free_dma(info->data_dma_ch); |
1118 | dma_free_writecombine(&pdev->dev, info->data_buff_size, | 1144 | dma_free_writecombine(&pdev->dev, MAX_BUFF_SIZE, |
1119 | info->data_buff, info->data_buff_phys); | 1145 | info->data_buff, info->data_buff_phys); |
1120 | } else | 1146 | } else |
1121 | kfree(info->data_buff); | 1147 | kfree(info->data_buff); |
@@ -1127,10 +1153,8 @@ static int pxa3xx_nand_remove(struct platform_device *pdev) | |||
1127 | clk_disable(info->clk); | 1153 | clk_disable(info->clk); |
1128 | clk_put(info->clk); | 1154 | clk_put(info->clk); |
1129 | 1155 | ||
1130 | if (mtd) { | 1156 | nand_release(info->host->mtd); |
1131 | nand_release(mtd); | 1157 | kfree(info); |
1132 | kfree(mtd); | ||
1133 | } | ||
1134 | return 0; | 1158 | return 0; |
1135 | } | 1159 | } |
1136 | 1160 | ||
@@ -1138,6 +1162,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) | |||
1138 | { | 1162 | { |
1139 | struct pxa3xx_nand_platform_data *pdata; | 1163 | struct pxa3xx_nand_platform_data *pdata; |
1140 | struct pxa3xx_nand_info *info; | 1164 | struct pxa3xx_nand_info *info; |
1165 | int ret; | ||
1141 | 1166 | ||
1142 | pdata = pdev->dev.platform_data; | 1167 | pdata = pdev->dev.platform_data; |
1143 | if (!pdata) { | 1168 | if (!pdata) { |
@@ -1145,17 +1170,20 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) | |||
1145 | return -ENODEV; | 1170 | return -ENODEV; |
1146 | } | 1171 | } |
1147 | 1172 | ||
1148 | info = alloc_nand_resource(pdev); | 1173 | ret = alloc_nand_resource(pdev); |
1149 | if (info == NULL) | 1174 | if (ret) { |
1150 | return -ENOMEM; | 1175 | dev_err(&pdev->dev, "alloc nand resource failed\n"); |
1176 | return ret; | ||
1177 | } | ||
1151 | 1178 | ||
1152 | if (pxa3xx_nand_scan(info->mtd)) { | 1179 | info = platform_get_drvdata(pdev); |
1180 | if (pxa3xx_nand_scan(info->host->mtd)) { | ||
1153 | dev_err(&pdev->dev, "failed to scan nand\n"); | 1181 | dev_err(&pdev->dev, "failed to scan nand\n"); |
1154 | pxa3xx_nand_remove(pdev); | 1182 | pxa3xx_nand_remove(pdev); |
1155 | return -ENODEV; | 1183 | return -ENODEV; |
1156 | } | 1184 | } |
1157 | 1185 | ||
1158 | return mtd_device_parse_register(info->mtd, NULL, 0, | 1186 | return mtd_device_parse_register(info->host->mtd, NULL, 0, |
1159 | pdata->parts, pdata->nr_parts); | 1187 | pdata->parts, pdata->nr_parts); |
1160 | } | 1188 | } |
1161 | 1189 | ||
@@ -1182,8 +1210,8 @@ static int pxa3xx_nand_resume(struct platform_device *pdev) | |||
1182 | /* We don't want to handle interrupt without calling mtd routine */ | 1210 | /* We don't want to handle interrupt without calling mtd routine */ |
1183 | disable_int(info, NDCR_INT_MASK); | 1211 | disable_int(info, NDCR_INT_MASK); |
1184 | 1212 | ||
1185 | nand_writel(info, NDTR0CS0, info->ndtr0cs0); | 1213 | nand_writel(info, NDTR0CS0, info->host->ndtr0cs0); |
1186 | nand_writel(info, NDTR1CS0, info->ndtr1cs0); | 1214 | nand_writel(info, NDTR1CS0, info->host->ndtr1cs0); |
1187 | 1215 | ||
1188 | /* | 1216 | /* |
1189 | * As the spec says, the NDSR would be updated to 0x1800 when | 1217 | * As the spec says, the NDSR would be updated to 0x1800 when |