diff options
Diffstat (limited to 'drivers/mtd/nand/pxa3xx_nand.c')
-rw-r--r-- | drivers/mtd/nand/pxa3xx_nand.c | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 10b1f7a4fe50..a4615fcc3d00 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -38,8 +38,8 @@ | |||
38 | 38 | ||
39 | #include <linux/platform_data/mtd-nand-pxa3xx.h> | 39 | #include <linux/platform_data/mtd-nand-pxa3xx.h> |
40 | 40 | ||
41 | #define CHIP_DELAY_TIMEOUT (2 * HZ/10) | 41 | #define CHIP_DELAY_TIMEOUT msecs_to_jiffies(200) |
42 | #define NAND_STOP_DELAY (2 * HZ/50) | 42 | #define NAND_STOP_DELAY msecs_to_jiffies(40) |
43 | #define PAGE_CHUNK_SIZE (2048) | 43 | #define PAGE_CHUNK_SIZE (2048) |
44 | 44 | ||
45 | /* | 45 | /* |
@@ -605,11 +605,24 @@ static void start_data_dma(struct pxa3xx_nand_info *info) | |||
605 | {} | 605 | {} |
606 | #endif | 606 | #endif |
607 | 607 | ||
608 | static irqreturn_t pxa3xx_nand_irq_thread(int irq, void *data) | ||
609 | { | ||
610 | struct pxa3xx_nand_info *info = data; | ||
611 | |||
612 | handle_data_pio(info); | ||
613 | |||
614 | info->state = STATE_CMD_DONE; | ||
615 | nand_writel(info, NDSR, NDSR_WRDREQ | NDSR_RDDREQ); | ||
616 | |||
617 | return IRQ_HANDLED; | ||
618 | } | ||
619 | |||
608 | static irqreturn_t pxa3xx_nand_irq(int irq, void *devid) | 620 | static irqreturn_t pxa3xx_nand_irq(int irq, void *devid) |
609 | { | 621 | { |
610 | struct pxa3xx_nand_info *info = devid; | 622 | struct pxa3xx_nand_info *info = devid; |
611 | unsigned int status, is_completed = 0, is_ready = 0; | 623 | unsigned int status, is_completed = 0, is_ready = 0; |
612 | unsigned int ready, cmd_done; | 624 | unsigned int ready, cmd_done; |
625 | irqreturn_t ret = IRQ_HANDLED; | ||
613 | 626 | ||
614 | if (info->cs == 0) { | 627 | if (info->cs == 0) { |
615 | ready = NDSR_FLASH_RDY; | 628 | ready = NDSR_FLASH_RDY; |
@@ -651,7 +664,8 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid) | |||
651 | } else { | 664 | } else { |
652 | info->state = (status & NDSR_RDDREQ) ? | 665 | info->state = (status & NDSR_RDDREQ) ? |
653 | STATE_PIO_READING : STATE_PIO_WRITING; | 666 | STATE_PIO_READING : STATE_PIO_WRITING; |
654 | handle_data_pio(info); | 667 | ret = IRQ_WAKE_THREAD; |
668 | goto NORMAL_IRQ_EXIT; | ||
655 | } | 669 | } |
656 | } | 670 | } |
657 | if (status & cmd_done) { | 671 | if (status & cmd_done) { |
@@ -692,7 +706,7 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid) | |||
692 | if (is_ready) | 706 | if (is_ready) |
693 | complete(&info->dev_ready); | 707 | complete(&info->dev_ready); |
694 | NORMAL_IRQ_EXIT: | 708 | NORMAL_IRQ_EXIT: |
695 | return IRQ_HANDLED; | 709 | return ret; |
696 | } | 710 | } |
697 | 711 | ||
698 | static inline int is_buf_blank(uint8_t *buf, size_t len) | 712 | static inline int is_buf_blank(uint8_t *buf, size_t len) |
@@ -951,7 +965,7 @@ static void nand_cmdfunc(struct mtd_info *mtd, unsigned command, | |||
951 | { | 965 | { |
952 | struct pxa3xx_nand_host *host = mtd->priv; | 966 | struct pxa3xx_nand_host *host = mtd->priv; |
953 | struct pxa3xx_nand_info *info = host->info_data; | 967 | struct pxa3xx_nand_info *info = host->info_data; |
954 | int ret, exec_cmd; | 968 | int exec_cmd; |
955 | 969 | ||
956 | /* | 970 | /* |
957 | * if this is a x16 device ,then convert the input | 971 | * if this is a x16 device ,then convert the input |
@@ -983,9 +997,8 @@ static void nand_cmdfunc(struct mtd_info *mtd, unsigned command, | |||
983 | info->need_wait = 1; | 997 | info->need_wait = 1; |
984 | pxa3xx_nand_start(info); | 998 | pxa3xx_nand_start(info); |
985 | 999 | ||
986 | ret = wait_for_completion_timeout(&info->cmd_complete, | 1000 | if (!wait_for_completion_timeout(&info->cmd_complete, |
987 | CHIP_DELAY_TIMEOUT); | 1001 | CHIP_DELAY_TIMEOUT)) { |
988 | if (!ret) { | ||
989 | dev_err(&info->pdev->dev, "Wait time out!!!\n"); | 1002 | dev_err(&info->pdev->dev, "Wait time out!!!\n"); |
990 | /* Stop State Machine for next command cycle */ | 1003 | /* Stop State Machine for next command cycle */ |
991 | pxa3xx_nand_stop(info); | 1004 | pxa3xx_nand_stop(info); |
@@ -1000,7 +1013,7 @@ static void nand_cmdfunc_extended(struct mtd_info *mtd, | |||
1000 | { | 1013 | { |
1001 | struct pxa3xx_nand_host *host = mtd->priv; | 1014 | struct pxa3xx_nand_host *host = mtd->priv; |
1002 | struct pxa3xx_nand_info *info = host->info_data; | 1015 | struct pxa3xx_nand_info *info = host->info_data; |
1003 | int ret, exec_cmd, ext_cmd_type; | 1016 | int exec_cmd, ext_cmd_type; |
1004 | 1017 | ||
1005 | /* | 1018 | /* |
1006 | * if this is a x16 device then convert the input | 1019 | * if this is a x16 device then convert the input |
@@ -1063,9 +1076,8 @@ static void nand_cmdfunc_extended(struct mtd_info *mtd, | |||
1063 | init_completion(&info->cmd_complete); | 1076 | init_completion(&info->cmd_complete); |
1064 | pxa3xx_nand_start(info); | 1077 | pxa3xx_nand_start(info); |
1065 | 1078 | ||
1066 | ret = wait_for_completion_timeout(&info->cmd_complete, | 1079 | if (!wait_for_completion_timeout(&info->cmd_complete, |
1067 | CHIP_DELAY_TIMEOUT); | 1080 | CHIP_DELAY_TIMEOUT)) { |
1068 | if (!ret) { | ||
1069 | dev_err(&info->pdev->dev, "Wait time out!!!\n"); | 1081 | dev_err(&info->pdev->dev, "Wait time out!!!\n"); |
1070 | /* Stop State Machine for next command cycle */ | 1082 | /* Stop State Machine for next command cycle */ |
1071 | pxa3xx_nand_stop(info); | 1083 | pxa3xx_nand_stop(info); |
@@ -1198,13 +1210,11 @@ static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) | |||
1198 | { | 1210 | { |
1199 | struct pxa3xx_nand_host *host = mtd->priv; | 1211 | struct pxa3xx_nand_host *host = mtd->priv; |
1200 | struct pxa3xx_nand_info *info = host->info_data; | 1212 | struct pxa3xx_nand_info *info = host->info_data; |
1201 | int ret; | ||
1202 | 1213 | ||
1203 | if (info->need_wait) { | 1214 | if (info->need_wait) { |
1204 | ret = wait_for_completion_timeout(&info->dev_ready, | ||
1205 | CHIP_DELAY_TIMEOUT); | ||
1206 | info->need_wait = 0; | 1215 | info->need_wait = 0; |
1207 | if (!ret) { | 1216 | if (!wait_for_completion_timeout(&info->dev_ready, |
1217 | CHIP_DELAY_TIMEOUT)) { | ||
1208 | dev_err(&info->pdev->dev, "Ready time out!!!\n"); | 1218 | dev_err(&info->pdev->dev, "Ready time out!!!\n"); |
1209 | return NAND_STATUS_FAIL; | 1219 | return NAND_STATUS_FAIL; |
1210 | } | 1220 | } |
@@ -1508,6 +1518,8 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) | |||
1508 | return ret; | 1518 | return ret; |
1509 | } | 1519 | } |
1510 | 1520 | ||
1521 | memset(pxa3xx_flash_ids, 0, sizeof(pxa3xx_flash_ids)); | ||
1522 | |||
1511 | pxa3xx_flash_ids[0].name = f->name; | 1523 | pxa3xx_flash_ids[0].name = f->name; |
1512 | pxa3xx_flash_ids[0].dev_id = (f->chip_id >> 8) & 0xffff; | 1524 | pxa3xx_flash_ids[0].dev_id = (f->chip_id >> 8) & 0xffff; |
1513 | pxa3xx_flash_ids[0].pagesize = f->page_size; | 1525 | pxa3xx_flash_ids[0].pagesize = f->page_size; |
@@ -1710,7 +1722,9 @@ static int alloc_nand_resource(struct platform_device *pdev) | |||
1710 | /* initialize all interrupts to be disabled */ | 1722 | /* initialize all interrupts to be disabled */ |
1711 | disable_int(info, NDSR_MASK); | 1723 | disable_int(info, NDSR_MASK); |
1712 | 1724 | ||
1713 | ret = request_irq(irq, pxa3xx_nand_irq, 0, pdev->name, info); | 1725 | ret = request_threaded_irq(irq, pxa3xx_nand_irq, |
1726 | pxa3xx_nand_irq_thread, IRQF_ONESHOT, | ||
1727 | pdev->name, info); | ||
1714 | if (ret < 0) { | 1728 | if (ret < 0) { |
1715 | dev_err(&pdev->dev, "failed to request IRQ\n"); | 1729 | dev_err(&pdev->dev, "failed to request IRQ\n"); |
1716 | goto fail_free_buf; | 1730 | goto fail_free_buf; |